Skip to content

Commit

Permalink
Merge pull request #39 from macosui/issue_37
Browse files Browse the repository at this point in the history
Issue #37
  • Loading branch information
Adrian-Samoticha authored Sep 27, 2023
2 parents 024b48e + 152e12a commit 740f7bb
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 32 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.4.0

- Add methods to retrieve or manipulate the window’s size and position.

## 1.3.0

- Add `overrideStandardWindowButtonPosition` and `getStandardWindowButtonPosition` to `WindowManipulator` to allow getting and setting the position of standard window buttons.
Expand Down
19 changes: 14 additions & 5 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:appkit_ui_element_colors/appkit_ui_element_colors.dart';
import 'package:example/main_area/main_area.dart';
import 'package:example/sidebar_content.dart';
import 'package:example/util/transparent_sidebar_and_content.dart';
Expand Down Expand Up @@ -90,12 +91,20 @@ class _MyHomePageState extends State<MyHomePage> {
middle: const Text('macos_window_utils demo'),
leading: CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(
CupertinoIcons.sidebar_left,
child: UiElementColorBuilder(
uiElementColorContainerInstanceProvider:
OwnedUiElementColorContainerInstanceProvider(),
builder: (context, colorContainer) {
return Icon(
CupertinoIcons.sidebar_left,
color: colorContainer.controlAccentColor,
);
}),
onPressed: () => setState(
() {
_isSidebarOpen = !_isSidebarOpen;
},
),
onPressed: () => setState(() {
_isSidebarOpen = !_isSidebarOpen;
}),
),
),
child: DefaultTextStyle(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:appkit_ui_element_colors/appkit_ui_element_colors.dart';
import 'package:flutter/cupertino.dart';

import 'command.dart';
Expand Down Expand Up @@ -41,24 +42,32 @@ class CommandList extends StatelessWidget {
}

Widget _buildScrollView() {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: commands
.asMap()
.map((int index, Command command) {
final widget = CommandListEntry(
index: index,
selectedIndex: selectedIndex,
command: command,
select: () => setIndex(index),
);
return UiElementColorBuilder(
uiElementColorContainerInstanceProvider:
OwnedUiElementColorContainerInstanceProvider(),
builder: (context, colorContainer) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: commands
.asMap()
.map((int index, Command command) {
final widget = CommandListEntry(
index: index,
selectedIndex: selectedIndex,
command: command,
select: () => setIndex(index),
selectedColor:
colorContainer.selectedContentBackgroundColor,
);

return MapEntry(index, widget);
})
.values
.toList(),
),
return MapEntry(index, widget);
})
.values
.toList(),
),
);
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import 'package:flutter/cupertino.dart';
import 'command.dart';

class CommandListEntry extends StatefulWidget {
const CommandListEntry(
{super.key,
required this.index,
required this.selectedIndex,
required this.command,
required this.select});
const CommandListEntry({
super.key,
required this.index,
required this.selectedIndex,
required this.command,
required this.select,
this.selectedColor = const Color.fromRGBO(42, 98, 217, 1.0),
});

final int index;
final int selectedIndex;
final Command command;
final void Function() select;
final Color selectedColor;

@override
State<CommandListEntry> createState() => _CommandListEntryState();
Expand All @@ -37,7 +40,7 @@ class _CommandListEntryState extends State<CommandListEntry> {
}

Color _getBackgroundColor({required bool isIndexOdd}) {
if (_isSelected) return const Color.fromRGBO(42, 98, 217, 1.0);
if (_isSelected) return widget.selectedColor;
if (isIndexOdd) return const Color.fromRGBO(128, 128, 128, 0.15);
return const Color.fromRGBO(128, 128, 128, 0.0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,35 @@ class CommandListProvider {
buttonType: NSWindowButtonType.closeButton))
.toString()),
),
Command(
name: 'WindowManipulator.centerWindow()',
description: 'Sets the window’s location to the center of the screen.'
'\n\nThe window is placed exactly in the center horizontally and '
'somewhat above center vertically. Such a placement carries a '
'certain visual immediacy and importance.\n\n'
'You typically use this method to place a window—most likely an '
'alert dialog—where the user can’t miss it.',
function: () => WindowManipulator.centerWindow(),
),
Command(
name: 'WindowManipulator.getWindowFrame()',
description: 'Returns the window’s window’s frame rectangle in screen '
'coordinates, including the title bar.\n\n'
'Keep in mind that the y-coordinate returned is measured from the '
'*bottom* of the screen.',
function: () async =>
debugPrint((await WindowManipulator.getWindowFrame()).toString()),
),
Command(
name: 'WindowManipulator.setWindowFrame('
'const Offset(64, 32) & const Size(512, 512),'
'animate: true)',
description: 'Sets the window’s frame rectangle in screen coordinates, '
'including the title bar.',
function: () => WindowManipulator.setWindowFrame(
const Offset(64, 32) & const Size(512, 512),
animate: true),
),
];
}
}
2 changes: 2 additions & 0 deletions example/macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import FlutterMacOS
import Foundation

import appkit_ui_element_colors
import macos_window_utils

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AppkitUiElementColorsPlugin.register(with: registry.registrar(forPlugin: "AppkitUiElementColorsPlugin"))
MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin"))
}
6 changes: 6 additions & 0 deletions example/macos/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
PODS:
- appkit_ui_element_colors (1.0.0):
- FlutterMacOS
- FlutterMacOS (1.0.0)
- macos_window_utils (1.0.0):
- FlutterMacOS

DEPENDENCIES:
- appkit_ui_element_colors (from `Flutter/ephemeral/.symlinks/plugins/appkit_ui_element_colors/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- macos_window_utils (from `Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos`)

EXTERNAL SOURCES:
appkit_ui_element_colors:
:path: Flutter/ephemeral/.symlinks/plugins/appkit_ui_element_colors/macos
FlutterMacOS:
:path: Flutter/ephemeral
macos_window_utils:
:path: Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos

SPEC CHECKSUMS:
appkit_ui_element_colors: 39bb2d80be3f19b152ccf4c70d5bbe6cba43d74a
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663

Expand Down
2 changes: 1 addition & 1 deletion example/macos/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
33CC10EC2044A3C60003C045 = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
1 change: 1 addition & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
flutter_markdown: ^0.6.13
appkit_ui_element_colors: ^1.0.0

dev_dependencies:
flutter_test:
Expand Down
47 changes: 47 additions & 0 deletions lib/window_manipulator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class WindowManipulator {
static final _completer = Completer<void>();
static final _nsWindowDelegateHandler = NSWindowDelegateHandler();

/// This constructor is private to prevent direct instantiation.
WindowManipulator._();

/// Initializes the [WindowManipulator] class.
///
/// The [enableWindowDelegate] specifies if the window delegate should be
Expand Down Expand Up @@ -695,4 +698,48 @@ class WindowManipulator {

return Offset(map['x'], map['y']) & Size(map['width'], map['height']);
}

/// Sets the window’s location to the center of the screen.
///
/// The window is placed exactly in the center horizontally and somewhat above
/// center vertically. Such a placement carries a certain visual immediacy and
/// importance.
///
/// You typically use this method to place a window—most likely an alert
/// dialog—where the user can’t miss it.
static Future<void> centerWindow() async {
await _completer.future;
await _windowManipulatorMethodChannel.invokeMethod('centerWindow');
}

/// Returns the window’s window’s frame rectangle in screen coordinates,
/// including the title bar.
///
/// Keep in mind that the y-coordinate returned is measured from the *bottom*
/// of the screen.
static Future<Rect> getWindowFrame() async {
await _completer.future;
final map =
await _windowManipulatorMethodChannel.invokeMethod('getWindowFrame');

return Offset(map['x'], map['y']) & Size(map['width'], map['height']);
}

/// Sets the window’s frame rectangle in screen coordinates, including the
/// title bar.
///
/// Optionally, the window frame can be animated to the new position.
///
/// Keep in mind that the y-coordinate returned is measured from the *bottom*
/// of the screen.
static Future<void> setWindowFrame(Rect frame, {bool animate = false}) async {
await _completer.future;
await _windowManipulatorMethodChannel.invokeMethod('setWindowFrame', {
'x': frame.left,
'y': frame.top,
'width': frame.width,
'height': frame.height,
'animate': animate,
});
}
}
30 changes: 30 additions & 0 deletions macos/Classes/MacOSWindowUtilsPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,36 @@ public class MacOSWindowUtilsPlugin: NSObject, FlutterPlugin {
result(dictionary)
break

case "centerWindow":
MainFlutterWindowManipulator.centerWindow()
result(true)
break

case "getWindowFrame":
let windowFrame = MainFlutterWindowManipulator.getWindowFrame()
let dictionary = [
"x": windowFrame.minX,
"y": windowFrame.minY,
"width": windowFrame.width,
"height": windowFrame.height
]
result(dictionary)
break

case "setWindowFrame":
let x = args["x"] as! NSNumber
let y = args["y"] as! NSNumber
let width = args["width"] as! NSNumber
let height = args["height"] as! NSNumber
let animate = args["animate"] as! Bool

let newFrame = NSRect(origin: CGPoint(x: x.doubleValue, y: y.doubleValue), size: CGSize(width: width.doubleValue, height: height.doubleValue))

MainFlutterWindowManipulator.setWindowFrame(newFrame: newFrame, animate: animate)

result(true)
break

default:
result(FlutterMethodNotImplemented)
break
Expand Down
24 changes: 24 additions & 0 deletions macos/Classes/MainFlutterWindowManipulator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -644,4 +644,28 @@ public class MainFlutterWindowManipulator {

return standardWindowButton!.frame
}

public static func centerWindow() {
if (self.mainFlutterWindow == nil) {
start(mainFlutterWindow: nil)
}

mainFlutterWindow!.center()
}

public static func getWindowFrame() -> NSRect {
if (self.mainFlutterWindow == nil) {
start(mainFlutterWindow: nil)
}

return mainFlutterWindow!.frame
}

public static func setWindowFrame(newFrame: NSRect, animate: Bool) {
if (self.mainFlutterWindow == nil) {
start(mainFlutterWindow: nil)
}

mainFlutterWindow!.setFrame(newFrame, display: true, animate: animate)
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: macos_window_utils
description:
macos_window_utils is a Flutter package that provides a set of methods for
modifying the NSWindow of a Flutter application on macOS.
version: 1.3.0
version: 1.4.0
repository: https://github.com/Adrian-Samoticha/macos_window_utils.dart

environment:
Expand Down

0 comments on commit 740f7bb

Please sign in to comment.