Skip to content

Commit c13b3b3

Browse files
committed
Add ability to change the window state in the reference app and updated the API slightly
1 parent 3f3e74a commit c13b3b3

File tree

5 files changed

+162
-58
lines changed

5 files changed

+162
-58
lines changed

examples/multi_window_ref_app/lib/app/main_window.dart

Lines changed: 69 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import 'regular_window_edit_dialog.dart';
1313

1414
class MainWindow extends StatefulWidget {
1515
MainWindow({super.key, required WindowController mainController}) {
16-
_windowManagerModel.add(
17-
KeyedWindowController(isMainWindow: true, key: UniqueKey(), controller: mainController));
16+
_windowManagerModel.add(KeyedWindowController(
17+
isMainWindow: true, key: UniqueKey(), controller: mainController));
1818
}
1919

2020
final WindowManagerModel _windowManagerModel = WindowManagerModel();
@@ -38,7 +38,8 @@ class _MainWindowState extends State<MainWindow> {
3838
flex: 60,
3939
child: SingleChildScrollView(
4040
scrollDirection: Axis.vertical,
41-
child: _ActiveWindowsTable(windowManagerModel: widget._windowManagerModel),
41+
child: _ActiveWindowsTable(
42+
windowManagerModel: widget._windowManagerModel),
4243
),
4344
),
4445
Expanded(
@@ -66,15 +67,18 @@ class _MainWindowState extends State<MainWindow> {
6667
listenable: widget._windowManagerModel,
6768
builder: (BuildContext context, Widget? _) {
6869
final List<Widget> childViews = <Widget>[];
69-
for (final KeyedWindowController controller in widget._windowManagerModel.windows) {
70+
for (final KeyedWindowController controller
71+
in widget._windowManagerModel.windows) {
7072
if (controller.parent == null && !controller.isMainWindow) {
7173
childViews.add(WindowControllerRender(
7274
controller: controller.controller,
7375
key: controller.key,
7476
windowSettings: widget._settings,
7577
windowManagerModel: widget._windowManagerModel,
76-
onDestroyed: () => widget._windowManagerModel.remove(controller.key),
77-
onError: () => widget._windowManagerModel.remove(controller.key),
78+
onDestroyed: () =>
79+
widget._windowManagerModel.remove(controller.key),
80+
onError: () =>
81+
widget._windowManagerModel.remove(controller.key),
7882
));
7983
}
8084
}
@@ -130,7 +134,8 @@ class _ActiveWindowsTable extends StatelessWidget {
130134
),
131135
numeric: true),
132136
],
133-
rows: (windowManagerModel.windows).map<DataRow>((KeyedWindowController controller) {
137+
rows: (windowManagerModel.windows)
138+
.map<DataRow>((KeyedWindowController controller) {
134139
return DataRow(
135140
key: controller.key,
136141
color: WidgetStateColor.resolveWith((states) {
@@ -142,49 +147,30 @@ class _ActiveWindowsTable extends StatelessWidget {
142147
selected: controller.controller == windowManagerModel.selected,
143148
onSelectChanged: (selected) {
144149
if (selected != null) {
145-
windowManagerModel
146-
.select(selected ? controller.controller.rootView.viewId : null);
150+
windowManagerModel.select(selected
151+
? controller.controller.rootView.viewId
152+
: null);
147153
}
148154
},
149155
cells: [
150156
DataCell(Text('${controller.controller.rootView.viewId}')),
151157
DataCell(
152158
ListenableBuilder(
153159
listenable: controller.controller,
154-
builder: (BuildContext context, Widget? _) => Text(controller
155-
.controller.type
156-
.toString()
157-
.replaceFirst('WindowArchetype.', ''))),
160+
builder: (BuildContext context, Widget? _) => Text(
161+
controller.controller.type
162+
.toString()
163+
.replaceFirst('WindowArchetype.', ''))),
158164
),
159165
DataCell(
160166
ListenableBuilder(
161167
listenable: controller.controller,
162-
builder: (BuildContext context, Widget? _) => Row(children: [
168+
builder: (BuildContext context, Widget? _) =>
169+
Row(children: [
163170
IconButton(
164-
icon: const Icon(Icons.edit_outlined),
165-
onPressed: () {
166-
if (controller.controller.type == WindowArchetype.regular) {
167-
showRegularWindowEditDialog(
168-
context,
169-
initialWidth: controller.controller.contentSize.width,
170-
initialHeight: controller.controller.contentSize.height,
171-
initialTitle: "",
172-
onSave: (double? width, double? height, String? title) {
173-
final regularController =
174-
controller.controller as RegularWindowController;
175-
if (width != null && height != null) {
176-
regularController.updateContentSize(
177-
WindowSizing(preferredSize: Size(width, height)),
178-
);
179-
}
180-
if (title != null) {
181-
regularController.setTitle(title);
182-
}
183-
},
184-
);
185-
}
186-
},
187-
),
171+
icon: const Icon(Icons.edit_outlined),
172+
onPressed: () => _showWindowEditDialog(
173+
controller, context)),
188174
IconButton(
189175
icon: const Icon(Icons.delete_outlined),
190176
onPressed: () async {
@@ -199,6 +185,49 @@ class _ActiveWindowsTable extends StatelessWidget {
199185
);
200186
});
201187
}
188+
189+
void _showWindowEditDialog(
190+
KeyedWindowController controller, BuildContext context) {
191+
if (controller.controller.type != WindowArchetype.regular) {
192+
return;
193+
}
194+
195+
final regularController = controller.controller as RegularWindowController;
196+
showRegularWindowEditDialog(
197+
context: context,
198+
initialWidth: controller.controller.contentSize.width,
199+
initialHeight: controller.controller.contentSize.height,
200+
initialTitle: "",
201+
isFullscreen: regularController.isFullscreen(),
202+
isMaximized: regularController.isMaximized(),
203+
isMinimized: regularController.isMinimized(),
204+
onSave: (EditResult result) {
205+
if (result.width != null && result.height != null) {
206+
regularController.updateContentSize(
207+
WindowSizing(preferredSize: Size(result.width!, result.height!)),
208+
);
209+
}
210+
if (result.title != null) {
211+
regularController.setTitle(result.title!);
212+
}
213+
if (result.fullscreen != null) {
214+
if (regularController.isFullscreen() != result.fullscreen!) {
215+
regularController.setFullscreen(result.fullscreen!);
216+
}
217+
}
218+
if (result.maximized != null) {
219+
if (regularController.isMaximized() != result.maximized!) {
220+
regularController.setMaximized(result.maximized!);
221+
}
222+
}
223+
if (result.minimized != null) {
224+
if (regularController.isMinimized() != result.minimized!) {
225+
regularController.setMinimized(result.minimized!);
226+
}
227+
}
228+
},
229+
);
230+
}
202231
}
203232

204233
class _WindowCreatorCard extends StatelessWidget {
@@ -243,7 +272,8 @@ class _WindowCreatorCard extends StatelessWidget {
243272
onDestroyed: () => windowManagerModel.remove(key),
244273
),
245274
title: "Regular",
246-
contentSize: WindowSizing(preferredSize: windowSettings.regularSize),
275+
contentSize: WindowSizing(
276+
preferredSize: windowSettings.regularSize),
247277
)));
248278
},
249279
child: const Text('Regular'),

examples/multi_window_ref_app/lib/app/regular_window_edit_dialog.dart

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,39 @@
44

55
import 'package:flutter/material.dart';
66

7-
void showRegularWindowEditDialog(
8-
BuildContext context, {
9-
double? initialWidth,
10-
double? initialHeight,
11-
String? initialTitle,
12-
Function(double?, double?, String?)? onSave,
7+
class EditResult {
8+
EditResult(
9+
{this.height,
10+
this.width,
11+
this.title,
12+
this.maximized,
13+
this.minimized,
14+
this.fullscreen});
15+
16+
final double? width;
17+
final double? height;
18+
final String? title;
19+
final bool? maximized;
20+
final bool? minimized;
21+
final bool? fullscreen;
22+
}
23+
24+
void showRegularWindowEditDialog({
25+
required BuildContext context,
26+
required double initialWidth,
27+
required double initialHeight,
28+
required String initialTitle,
29+
required bool isMaximized,
30+
required bool isMinimized,
31+
required bool isFullscreen,
32+
required Function(EditResult) onSave,
1333
}) {
1434
final TextEditingController widthController =
1535
TextEditingController(text: initialWidth?.toString() ?? '');
1636
final TextEditingController heightController =
1737
TextEditingController(text: initialHeight?.toString() ?? '');
18-
final TextEditingController titleController = TextEditingController(text: initialTitle ?? '');
38+
final TextEditingController titleController =
39+
TextEditingController(text: initialTitle ?? '');
1940

2041
showDialog(
2142
context: context,
@@ -41,6 +62,30 @@ void showRegularWindowEditDialog(
4162
controller: titleController,
4263
decoration: InputDecoration(labelText: "Title"),
4364
),
65+
CheckboxListTile(
66+
title: const Text('Fullscreen'),
67+
value: isFullscreen,
68+
onChanged: (bool? value) {
69+
if (value != null) {
70+
setState(() => isFullscreen = value);
71+
}
72+
}),
73+
CheckboxListTile(
74+
title: const Text('Maximized'),
75+
value: isMaximized,
76+
onChanged: (bool? value) {
77+
if (value != null) {
78+
setState(() => isMaximized = value);
79+
}
80+
}),
81+
CheckboxListTile(
82+
title: const Text('Minimized'),
83+
value: isMinimized,
84+
onChanged: (bool? value) {
85+
if (value != null) {
86+
setState(() => isMinimized = value);
87+
}
88+
})
4489
],
4590
);
4691
},
@@ -54,9 +99,16 @@ void showRegularWindowEditDialog(
5499
onPressed: () {
55100
double? width = double.tryParse(widthController.text);
56101
double? height = double.tryParse(heightController.text);
57-
String? title = titleController.text.isEmpty ? null : titleController.text;
102+
String? title =
103+
titleController.text.isEmpty ? null : titleController.text;
58104

59-
onSave?.call(width, height, title);
105+
onSave(EditResult(
106+
width: width,
107+
height: height,
108+
title: title,
109+
fullscreen: isFullscreen,
110+
maximized: isMaximized,
111+
minimized: isMinimized));
60112
Navigator.of(context).pop();
61113
},
62114
child: Text("Save"),

packages/flutter/lib/src/widgets/window.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,12 @@ abstract class RegularWindowController extends WindowController {
165165
/// [title] new title of the window.
166166
void setTitle(String title);
167167

168-
/// Requests the window to be maximized. This has not effect
168+
/// Requests that the window be displayed in its current size and position.
169+
/// If the window is minimized or maximized, the window returns to the size
170+
/// and position that it had before that state was applied.
171+
void activate();
172+
173+
/// Requests the window to be maximized. This has no effect
169174
/// if the window is currently full screen or minimized, but may
170175
/// affect the window size upon restoring it from minimized or
171176
/// full screen state.
@@ -175,7 +180,7 @@ abstract class RegularWindowController extends WindowController {
175180
bool isMaximized();
176181

177182
/// Requests window to be minimized.
178-
void minimize();
183+
void setMinimized(bool minimized);
179184

180185
/// Returns whether window is currently minimized.
181186
bool isMinimized();

packages/flutter/lib/src/widgets/window_macos.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ class RegularWindowControllerMacOS extends RegularWindowController {
137137
return Size(size.width, size.height);
138138
}
139139

140+
@override
141+
void activate() {
142+
// TODO: Implement
143+
}
144+
140145
@override
141146
void setMaximized(bool maximized) {
142147
_ensureNotDestroyed();
@@ -150,9 +155,13 @@ class RegularWindowControllerMacOS extends RegularWindowController {
150155
}
151156

152157
@override
153-
void minimize() {
158+
void setMinimized(bool minimized) {
154159
_ensureNotDestroyed();
155-
_minimize(getWindowHandle());
160+
if (minimized) {
161+
_minimize(getWindowHandle());
162+
} else {
163+
// TODO: Unminimize
164+
}
156165
}
157166

158167
@override

packages/flutter/lib/src/widgets/window_win32.dart

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,19 @@ class RegularWindowControllerWin32 extends RegularWindowController
143143
ffi.calloc.free(ffiSizing);
144144
}
145145

146+
@override
147+
void activate() {
148+
_ensureNotDestroyed();
149+
_showWindow(getWindowHandle(), SW_RESTORE);
150+
}
151+
146152
@override
147153
bool isFullscreen() {
148154
return false;
149155
}
150156

151-
@override
152-
void setFullscreen(bool fullscreen, {int? displayId}) {
153-
154-
}
157+
@override
158+
void setFullscreen(bool fullscreen, {int? displayId}) {}
155159

156160
@override
157161
bool isMaximized() {
@@ -166,9 +170,13 @@ class RegularWindowControllerWin32 extends RegularWindowController
166170
}
167171

168172
@override
169-
void minimize() {
173+
void setMinimized(bool minimized) {
170174
_ensureNotDestroyed();
171-
_showWindow(getWindowHandle(), SW_MINIMIZE);
175+
if (minimized) {
176+
_showWindow(getWindowHandle(), SW_MINIMIZE);
177+
} else {
178+
_showWindow(getWindowHandle(), SW_RESTORE);
179+
}
172180
}
173181

174182
@override

0 commit comments

Comments
 (0)