Line data Source code
1 : // Copyright 2023 The terCAD team. All rights reserved.
2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
3 :
4 : import 'dart:math';
5 :
6 : import 'package:app_finance/_classes/herald/app_zoom.dart';
7 : import 'package:app_finance/_configs/screen_helper.dart';
8 : import 'package:material_ui/material_ui.dart';
9 :
10 : enum AdaptiveWindowType {
11 : xsmall,
12 : small,
13 : medium,
14 : large,
15 : xlarge,
16 : }
17 :
18 : class _Sizes {
19 : static const half = 4.0;
20 : static const normal = 8.0;
21 : static const double = 16.0;
22 : static const triple = 24.0;
23 : static const quatre = 32.0;
24 : static const sixfold = 48.0;
25 : }
26 :
27 : class ThemeHelper {
28 : static const barHeight = 48.0;
29 : static const menuWidth = 200.0;
30 1 : static late bool isWearable;
31 : static const emptyBox = SizedBox();
32 : static const formEndBox = SizedBox(height: 110);
33 : static const hIndent = SizedBox(height: _Sizes.normal);
34 : static const hIndent2x = SizedBox(height: _Sizes.double);
35 : static const hIndent3x = SizedBox(height: _Sizes.triple);
36 : static const hIndent4x = SizedBox(height: _Sizes.quatre);
37 : static const hIndent6x = SizedBox(height: _Sizes.sixfold);
38 : static const hIndent05 = SizedBox(height: _Sizes.half);
39 : static const wIndent = SizedBox(width: _Sizes.normal);
40 : static const wIndent2x = SizedBox(width: _Sizes.double);
41 : static const wIndent05 = SizedBox(width: _Sizes.half);
42 :
43 4 : static double getIndent([double multiply = 1]) => _Sizes.normal / AppZoom.state * multiply;
44 :
45 1 : static double _env(BuildContext context, BoxConstraints? constraints) =>
46 : (constraints != null &&
47 2 : (isNavRight(context, constraints) || ScreenHelper.state().isRight) &&
48 0 : !(isWearable || ScreenHelper.state().isWearable)
49 : ? barHeight
50 1 : : 0) +
51 2 : (constraints != null && isWideScreen(constraints) || ScreenHelper.state().isWide ? menuWidth : 0);
52 :
53 1 : static double getMaxWidth(BuildContext context, BoxConstraints constraints) =>
54 3 : constraints.maxWidth - _env(context, constraints);
55 :
56 1 : static double getWidth(BuildContext context,
57 : [double multiply = 4, BoxConstraints? constraints, bool withZoom = true]) =>
58 7 : (constraints?.maxWidth ?? (MediaQuery.sizeOf(context).width - MediaQuery.paddingOf(context).horizontal)) /
59 2 : (withZoom ? AppZoom.state : 1) -
60 2 : getIndent(multiply) -
61 1 : _env(context, constraints);
62 :
63 1 : static double getHeight(BuildContext context, [double multiply = 2]) =>
64 6 : MediaQuery.sizeOf(context).height / AppZoom.state - getIndent(multiply);
65 :
66 1 : static double getMinHeight(BuildContext context, [BoxConstraints? constraints]) =>
67 4 : [ThemeHelper.getHeight(context), constraints?.maxHeight ?? double.infinity].reduce(min);
68 :
69 1 : static bool isKeyboardVisible(BuildContext context, [BoxConstraints? constraints]) =>
70 4 : MediaQuery.of(context).viewInsets.bottom > 0 ||
71 4 : constraints != null && ScreenHelper.state().height - 100 > constraints.maxHeight;
72 :
73 0 : static double getMaxHeight(List<dynamic> scope) {
74 : double height = 0;
75 0 : for (int i = 0; i < scope.length; i++) {
76 : double tmpHeight = 0;
77 0 : if (scope[i] is Text) {
78 0 : tmpHeight = ThemeHelper.getTextHeight(scope[i]);
79 0 : } else if (scope[i] is RenderBox) {
80 0 : tmpHeight = (scope[i] as RenderBox).getMaxIntrinsicHeight(double.infinity);
81 : }
82 0 : if (tmpHeight > height) {
83 : height = tmpHeight;
84 : }
85 : }
86 : return height;
87 : }
88 :
89 1 : static double getTextHeight(Text txt) {
90 2 : return _getPainter(txt).height;
91 : }
92 :
93 1 : static double getTextWidth(Text txt) {
94 3 : return _getPainter(txt).width * 1.1;
95 : }
96 :
97 1 : static TextPainter _getPainter(Text txt) {
98 1 : final painter = TextPainter(
99 3 : text: TextSpan(text: txt.data, style: txt.style),
100 : textDirection: TextDirection.ltr,
101 1 : maxLines: txt.maxLines,
102 : );
103 1 : painter.layout();
104 : return painter;
105 : }
106 :
107 1 : static bool isTextExceedWidth(String txt, TextStyle? style, double maxWidth) {
108 1 : final textPainter = TextPainter(
109 1 : text: TextSpan(
110 : text: txt,
111 : style: style,
112 : ),
113 : maxLines: 1,
114 : textDirection: TextDirection.ltr,
115 1 : )..layout(maxWidth: maxWidth);
116 1 : return textPainter.didExceedMaxLines;
117 : }
118 :
119 0 : static bool isVertical(BoxConstraints constraints) => constraints.maxWidth < constraints.maxHeight;
120 :
121 4 : static bool isHorizontal(BoxConstraints constraints) => constraints.maxWidth > constraints.maxHeight;
122 :
123 3 : static bool isNavBottom(BoxConstraints constraints) => getWidthCount(constraints) <= 2;
124 :
125 1 : static bool isNavRight(BuildContext context, BoxConstraints constraints) =>
126 3 : isHorizontal(constraints) && getHeightCount(context, constraints) <= 2;
127 :
128 1 : static int getWidthCount(BoxConstraints? constraints, [BuildContext? context]) {
129 2 : double width = context != null ? getWidth(context, 0, constraints) : constraints?.maxWidth ?? 0;
130 1 : final matrix = {
131 1 : AdaptiveWindowType.xlarge: width >= 1440,
132 1 : AdaptiveWindowType.large: width >= 1024,
133 1 : AdaptiveWindowType.medium: width >= 640,
134 1 : AdaptiveWindowType.small: width >= 320,
135 : AdaptiveWindowType.xsmall: true,
136 : };
137 3 : matrix.removeWhere((_, value) => value == false);
138 2 : return switch (matrix.keys.first) {
139 1 : AdaptiveWindowType.xlarge => 4,
140 1 : AdaptiveWindowType.large => 3,
141 1 : AdaptiveWindowType.medium => 2,
142 : _ => 1,
143 : };
144 : }
145 :
146 1 : static int getHeightCount(BuildContext context, [BoxConstraints? constraints]) {
147 1 : final height = getMinHeight(context, constraints);
148 1 : final matrix = {
149 1 : AdaptiveWindowType.xlarge: height >= 1440,
150 1 : AdaptiveWindowType.large: height >= 800,
151 1 : AdaptiveWindowType.medium: height >= 480,
152 1 : AdaptiveWindowType.small: height >= 240,
153 : AdaptiveWindowType.xsmall: true,
154 : };
155 3 : matrix.removeWhere((_, value) => value == false);
156 2 : return switch (matrix.keys.first) {
157 1 : AdaptiveWindowType.xlarge => 7,
158 1 : AdaptiveWindowType.large => 5,
159 1 : AdaptiveWindowType.medium => 4,
160 0 : AdaptiveWindowType.small => 2,
161 : _ => 1,
162 : };
163 : }
164 :
165 3 : static bool isWideScreen(BoxConstraints constraints) => ThemeHelper.getWidthCount(constraints) >= 4;
166 :
167 1 : static bool isWearableMode(BuildContext context, BoxConstraints constraints) =>
168 4 : isWearable = getWidthCount(constraints) * getHeightCount(context, constraints) == 1;
169 : }
|