guru_sdk/guru_ui/packages/design/lib/design_field.dart

175 lines
5.7 KiB
Dart

/// Created by @Haoyi on 2021/7/7
///
part of "design.dart";
abstract class CombinedValue {
double combine(_DeviceMetrics metrics);
}
class SimpleCombinedValue extends CombinedValue {
final DesignField field1;
final DesignField field2;
final double Function(double a, double b) combiner;
SimpleCombinedValue(this.field1, this.field2, this.combiner);
@override
double combine(_DeviceMetrics metrics) {
final a = field1.measure(metrics);
final b = field2.measure(metrics);
return combiner.call(a, b);
}
}
class RatioCombinedValue extends CombinedValue {
final DesignField relative;
final double scale;
RatioCombinedValue(this.relative, this.scale);
@override
double combine(_DeviceMetrics metrics) {
final value = relative.measure(metrics);
return value * scale;
}
}
abstract class DesignObject<T> {
T measure(_DeviceMetrics metrics);
}
class DesignField extends DesignObject<double> {
final _DesignMethod designMethod;
final dynamic designValue;
double? _size;
static double _calculate(_DesignMethod method, _DeviceMetrics metrics, dynamic value) {
switch (method) {
case _DesignMethod.origin:
return value;
case _DesignMethod.width:
return value * metrics.wScale;
case _DesignMethod.height:
return value * metrics.hScale;
case _DesignMethod.widthScale:
return value * metrics.size.width;
case _DesignMethod.heightScale:
return value * metrics.size.height;
case _DesignMethod.combine:
final combinedValue = value as CombinedValue;
return combinedValue.combine(metrics);
case _DesignMethod.statusBarHeight:
final statusBarHeight = Get.statusBarHeight /
(metrics.adaptation?.pixelRatio ??
SystemAdaptation.globalPixelRation ??
Get.pixelRatio);
if (statusBarHeight != 0) {
return statusBarHeight;
}
return value * 1.0 * metrics.hScale;
case _DesignMethod.wrappedInSafeAreaStatusBarHeight:
final statusBarHeight = Get.statusBarHeight /
(metrics.adaptation?.pixelRatio ??
SystemAdaptation.globalPixelRation ??
Get.pixelRatio);
if (statusBarHeight != 0) {
return 0;
}
return value * 1.0 * metrics.hScale;
case _DesignMethod.navigationBarHeight:
final navigationBarHeight = Get.bottomBarHeight /
(metrics.adaptation?.pixelRatio ??
SystemAdaptation.globalPixelRation ??
Get.pixelRatio);
if (navigationBarHeight != 0) {
return navigationBarHeight;
}
return value * 1.0 * metrics.hScale;
case _DesignMethod.wrappedInSafeAreaNavigationBarHeight:
final navigationBarHeight = Get.bottomBarHeight /
(metrics.adaptation?.pixelRatio ??
SystemAdaptation.globalPixelRation ??
Get.pixelRatio);
if (navigationBarHeight != 0) {
return 0;
}
return value * 1.0 * metrics.hScale;
case _DesignMethod.absoluteFontSize:
return ((((value * metrics.hScale) + (value * metrics.wScale)) / 2) /
(metrics.adaptation?.textScaleFactor ??
SystemAdaptation.globalTextScaleFactor ??
Get.textScaleFactor));
// return ((((value * metrics.hScale) + (value * metrics.wScale)) / 2) * Get.textScaleFactor);
case _DesignMethod.average:
default:
return ((value * metrics.hScale) + (value * metrics.wScale)) / 2;
}
}
@override
double measure(_DeviceMetrics metrics) {
_size ??= _calculate(
designMethod,
metrics,
designValue,
);
return _size!;
}
DesignField._origin(this.designValue)
: designMethod = _DesignMethod.origin,
_size = designValue.toDouble();
DesignField._width(this.designValue) : designMethod = _DesignMethod.width;
DesignField._height(this.designValue) : designMethod = _DesignMethod.height;
DesignField._widthScale(this.designValue) : designMethod = _DesignMethod.widthScale;
DesignField._heightScale(this.designValue) : designMethod = _DesignMethod.heightScale;
DesignField._average(this.designValue) : designMethod = _DesignMethod.average;
DesignField._relativeRatio(DesignField relative, double ratio)
: designValue = RatioCombinedValue(relative, ratio),
designMethod = _DesignMethod.combine;
DesignField.statusBarHeight({double defaultHeight = 0})
: designValue = defaultHeight,
designMethod = _DesignMethod.statusBarHeight;
DesignField.wrappedInSafeAreaStatusBarHeight(double fakeHeight)
: designValue = fakeHeight,
designMethod = _DesignMethod.wrappedInSafeAreaStatusBarHeight;
DesignField.navigationBarHeight({double defaultHeight = 0})
: designValue = defaultHeight,
designMethod = _DesignMethod.navigationBarHeight;
DesignField.wrappedInSafeAreaNavigationBarHeight(double fakeHeight)
: designValue = fakeHeight,
designMethod = _DesignMethod.wrappedInSafeAreaNavigationBarHeight;
DesignField._combine(this.designValue) : designMethod = _DesignMethod.combine;
DesignField operator +(DesignField other) {
return DesignField._combine(SimpleCombinedValue(this, other, (a, b) => a + b));
}
DesignField operator -(DesignField other) {
return DesignField._combine(SimpleCombinedValue(this, other, (a, b) => a - b));
}
DesignField operator *(DesignField other) {
return DesignField._combine(SimpleCombinedValue(this, other, (a, b) => a * b));
}
DesignField operator /(DesignField other) {
return DesignField._combine(SimpleCombinedValue(this, other, (a, b) => a / b));
}
double get size => _size!;
}