1- import 'package:flet_view/utils/user_fonts.dart' ;
21import 'package:flutter/material.dart' ;
32import 'package:flutter_redux/flutter_redux.dart' ;
43
@@ -13,12 +12,14 @@ import '../utils/desktop.dart';
1312import '../utils/edge_insets.dart' ;
1413import '../utils/theme.dart' ;
1514import '../utils/uri.dart' ;
15+ import '../utils/user_fonts.dart' ;
1616import '../widgets/page_media.dart' ;
17+ import '../widgets/window_media.dart' ;
1718import 'app_bar.dart' ;
1819import 'create_control.dart' ;
1920import 'scrollable_control.dart' ;
2021
21- class PageControl extends StatelessWidget {
22+ class PageControl extends StatefulWidget {
2223 final Control ? parent;
2324 final Control control;
2425 final List <Control > children;
@@ -27,34 +28,42 @@ class PageControl extends StatelessWidget {
2728 {Key ? key, this .parent, required this .control, required this .children})
2829 : super (key: key);
2930
31+ @override
32+ State <PageControl > createState () => _PageControlState ();
33+ }
34+
35+ class _PageControlState extends State <PageControl > {
36+ String ? _windowCenter;
37+
3038 @override
3139 Widget build (BuildContext context) {
32- debugPrint ("Page build: ${control .id }" );
40+ debugPrint ("Page build: ${widget . control .id }" );
3341
34- bool disabled = control.isDisabled;
42+ bool disabled = widget. control.isDisabled;
3543
36- final spacing = control.attrDouble ("spacing" , 10 )! ;
44+ final spacing = widget. control.attrDouble ("spacing" , 10 )! ;
3745 final mainAlignment = parseMainAxisAlignment (
38- control, "verticalAlignment" , MainAxisAlignment .start);
46+ widget. control, "verticalAlignment" , MainAxisAlignment .start);
3947 final crossAlignment = parseCrossAxisAlignment (
40- control, "horizontalAlignment" , CrossAxisAlignment .start);
48+ widget. control, "horizontalAlignment" , CrossAxisAlignment .start);
4149
4250 ScrollMode scrollMode = ScrollMode .values.firstWhere (
4351 (m) =>
4452 m.name.toLowerCase () ==
45- control.attrString ("scroll" , "" )! .toLowerCase (),
53+ widget. control.attrString ("scroll" , "" )! .toLowerCase (),
4654 orElse: () => ScrollMode .none);
4755
48- final autoScroll = control.attrBool ("autoScroll" , false )! ;
49- final textDirection =
50- control.attrBool ("rtl" , false )! ? TextDirection .rtl : TextDirection .ltr;
56+ final autoScroll = widget.control.attrBool ("autoScroll" , false )! ;
57+ final textDirection = widget.control.attrBool ("rtl" , false )!
58+ ? TextDirection .rtl
59+ : TextDirection .ltr;
5160
5261 Control ? offstage;
5362 Control ? appBar;
5463 List <Widget > controls = [];
5564 bool firstControl = true ;
5665
57- for (var ctrl in children.where ((c) => c.isVisible)) {
66+ for (var ctrl in widget. children.where ((c) => c.isVisible)) {
5867 // offstage control
5968 if (ctrl.type == ControlType .offstage) {
6069 offstage = ctrl;
@@ -74,11 +83,11 @@ class PageControl extends StatelessWidget {
7483 firstControl = false ;
7584
7685 // displayed control
77- controls.add (createControl (control, ctrl.id, disabled));
86+ controls.add (createControl (widget. control, ctrl.id, disabled));
7887 }
7988
8089 // theme
81- var lightTheme = parseTheme (control, "theme" ) ??
90+ var lightTheme = parseTheme (widget. control, "theme" ) ??
8291 ThemeData (
8392 colorSchemeSeed: Colors .blue,
8493 brightness: Brightness .light,
@@ -88,7 +97,7 @@ class PageControl extends StatelessWidget {
8897 // : null,
8998 visualDensity: VisualDensity .adaptivePlatformDensity);
9099
91- var darkTheme = parseTheme (control, "darkTheme" ) ??
100+ var darkTheme = parseTheme (widget. control, "darkTheme" ) ??
92101 ThemeData (
93102 colorSchemeSeed: Colors .blue,
94103 brightness: Brightness .dark,
@@ -98,14 +107,130 @@ class PageControl extends StatelessWidget {
98107 var themeMode = ThemeMode .values.firstWhere (
99108 (t) =>
100109 t.name.toLowerCase () ==
101- control.attrString ("themeMode" , "" )! .toLowerCase (),
110+ widget. control.attrString ("themeMode" , "" )! .toLowerCase (),
102111 orElse: () => ThemeMode .system);
103112
104113 debugPrint ("Page theme: $themeMode " );
105114
106- String title = control.attrString ("title" , "" )! ;
115+ // window title
116+ String title = widget.control.attrString ("title" , "" )! ;
107117 setWindowTitle (title);
108118
119+ // window params
120+ var windowCenter = widget.control.attrString ("windowCenter" );
121+ var fullScreen = widget.control.attrBool ("windowFullScreen" );
122+
123+ // window size
124+ var windowWidth = widget.control.attrDouble ("windowWidth" );
125+ var windowHeight = widget.control.attrDouble ("windowHeight" );
126+ if ((windowWidth != null || windowHeight != null ) && fullScreen != true ) {
127+ debugPrint ("setWindowSize: $windowWidth , $windowHeight " );
128+ setWindowSize (windowWidth, windowHeight);
129+ }
130+
131+ // window min size
132+ var windowMinWidth = widget.control.attrDouble ("windowMinWidth" );
133+ var windowMinHeight = widget.control.attrDouble ("windowMinHeight" );
134+ if (windowMinWidth != null || windowMinHeight != null ) {
135+ debugPrint ("setWindowMinSize: $windowMinWidth , $windowMinHeight " );
136+ setWindowMinSize (windowMinWidth, windowMinHeight);
137+ }
138+
139+ // window max size
140+ var windowMaxWidth = widget.control.attrDouble ("windowMaxWidth" );
141+ var windowMaxHeight = widget.control.attrDouble ("windowMaxHeight" );
142+ if (windowMaxWidth != null || windowMaxHeight != null ) {
143+ debugPrint ("setWindowMaxSize: $windowMaxWidth , $windowMaxHeight " );
144+ setWindowMaxSize (windowMaxWidth, windowMaxHeight);
145+ }
146+
147+ // window position
148+ var windowTop = widget.control.attrDouble ("windowTop" );
149+ var windowLeft = widget.control.attrDouble ("windowLeft" );
150+ if ((windowTop != null || windowLeft != null ) &&
151+ fullScreen != true &&
152+ (windowCenter == null || windowCenter == "" )) {
153+ debugPrint ("setWindowPosition: $windowTop , $windowLeft " );
154+ setWindowPosition (windowTop, windowLeft);
155+ }
156+
157+ // window opacity
158+ var opacity = widget.control.attrDouble ("windowOpacity" );
159+ if (opacity != null ) {
160+ setWindowOpacity (opacity);
161+ }
162+
163+ // window minimizable
164+ var minimizable = widget.control.attrBool ("windowMinimizable" );
165+ if (minimizable != null ) {
166+ setWindowMinimizability (minimizable);
167+ }
168+
169+ // window minimize
170+ var minimized = widget.control.attrBool ("windowMinimized" );
171+ if (minimized == true ) {
172+ minimizeWindow ();
173+ } else if (minimized == false ) {
174+ restoreWindow ();
175+ }
176+
177+ // window maximize
178+ var maximized = widget.control.attrBool ("windowMaximized" );
179+ if (maximized == true ) {
180+ maximizeWindow ();
181+ } else if (maximized == false ) {
182+ unmaximizeWindow ();
183+ }
184+
185+ // window resizable
186+ var resizable = widget.control.attrBool ("windowResizable" );
187+ if (resizable != null ) {
188+ setWindowResizability (resizable);
189+ }
190+
191+ // window movable
192+ var movable = widget.control.attrBool ("windowMovable" );
193+ if (movable != null ) {
194+ setWindowMovability (movable);
195+ }
196+
197+ // window fullScreen
198+ if (fullScreen != null ) {
199+ setWindowFullScreen (fullScreen);
200+ }
201+
202+ // window alwaysOnTop
203+ var alwaysOnTop = widget.control.attrBool ("windowAlwaysOnTop" );
204+ if (alwaysOnTop != null ) {
205+ setWindowAlwaysOnTop (alwaysOnTop);
206+ }
207+
208+ // window preventClose
209+ var preventClose = widget.control.attrBool ("windowPreventClose" );
210+ if (preventClose != null ) {
211+ setWindowPreventClose (preventClose);
212+ }
213+
214+ // window focus
215+ var focused = widget.control.attrBool ("windowFocused" );
216+ if (focused == true ) {
217+ focusWindow ();
218+ } else if (focused == false ) {
219+ blurWindow ();
220+ }
221+
222+ // window center
223+ if (windowCenter != _windowCenter) {
224+ centerWindow ();
225+ _windowCenter = windowCenter;
226+ }
227+
228+ // window destroy
229+ var destroy = widget.control.attrBool ("windowDestroy" );
230+ if (destroy == true ) {
231+ destroyWindow ();
232+ }
233+
109234 List <String > childIds = [];
110235 if (offstage != null ) {
111236 childIds.add (offstage.id);
@@ -119,7 +244,7 @@ class PageControl extends StatelessWidget {
119244 converter: (store) => store.state.pageUri,
120245 builder: (context, pageUri) {
121246 // load custom fonts
122- parseFonts (control, "fonts" ).forEach ((fontFamily, fontUrl) {
247+ parseFonts (widget. control, "fonts" ).forEach ((fontFamily, fontUrl) {
123248 var fontUri = Uri .parse (fontUrl);
124249 if (! fontUri.hasAuthority) {
125250 fontUri = getAssetUri (pageUri! , fontUrl);
@@ -156,6 +281,11 @@ class PageControl extends StatelessWidget {
156281 .toList ()
157282 : [];
158283
284+ List <Widget > mediaWidgets = [const PageMedia ()];
285+ if (isDesktop ()) {
286+ mediaWidgets.add (const WindowMedia ());
287+ }
288+
159289 List <Control > fab = offstage != null
160290 ? childrenViews.controlViews.first.children
161291 .where ((c) =>
@@ -183,7 +313,7 @@ class PageControl extends StatelessWidget {
183313 child: Scaffold (
184314 appBar: appBarView != null
185315 ? AppBarControl (
186- parent: control,
316+ parent: widget. control,
187317 control: appBarView.control,
188318 children: appBarView.children,
189319 parentDisabled: disabled,
@@ -195,12 +325,12 @@ class PageControl extends StatelessWidget {
195325 SizedBox .expand (
196326 child: Container (
197327 padding: parseEdgeInsets (
198- control, "padding" ) ??
328+ widget. control, "padding" ) ??
199329 const EdgeInsets .all (10 ),
200330 decoration: BoxDecoration (
201331 color: HexColor .fromString (
202332 theme,
203- control.attrString (
333+ widget. control.attrString (
204334 "bgcolor" , "" )! )),
205335 child: scrollMode != ScrollMode .none
206336 ? ScrollableControl (
@@ -211,7 +341,7 @@ class PageControl extends StatelessWidget {
211341 )
212342 : column)),
213343 ...offstageWidgets,
214- const PageMedia ()
344+ ...mediaWidgets
215345 ]),
216346 floatingActionButton: fab.isNotEmpty
217347 ? createControl (
0 commit comments