/// 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 measure(_DeviceMetrics metrics); } class DesignField extends DesignObject { 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 / Get.pixelRatio; if (statusBarHeight != 0) { return statusBarHeight; } return value * 1.0 * metrics.hScale; case _DesignMethod.wrappedInSafeAreaStatusBarHeight: final statusBarHeight = Get.statusBarHeight / Get.pixelRatio; if (statusBarHeight != 0) { return 0; } return value * 1.0 * metrics.hScale; case _DesignMethod.navigationBarHeight: final navigationBarHeight = Get.bottomBarHeight / Get.pixelRatio; if (navigationBarHeight != 0) { return navigationBarHeight; } return value * 1.0 * metrics.hScale; case _DesignMethod.wrappedInSafeAreaNavigationBarHeight: final navigationBarHeight = Get.bottomBarHeight / Get.pixelRatio; if (navigationBarHeight != 0) { return 0; } return value * 1.0 * metrics.hScale; case _DesignMethod.absoluteFontSize: return ((((value * metrics.hScale) + (value * metrics.wScale)) / 2) / 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!; }