Skip to content

Commit 1b7b1a3

Browse files
committed
Implement custom window
1 parent 69549a8 commit 1b7b1a3

15 files changed

+169
-10
lines changed

lib/main.dart

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:io';
22

3+
import 'package:bitsdojo_window/bitsdojo_window.dart';
34
import 'package:flutter/material.dart';
45
import 'package:flutter_acrylic/flutter_acrylic.dart';
56
import 'package:flutter_localizations/flutter_localizations.dart';
@@ -43,13 +44,20 @@ void main() async {
4344
print('There was an issue opening the DB');
4445
}
4546

46-
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
47-
setWindowTitle(kAppTitle);
48-
setWindowMinSize(const Size(800, 500));
49-
setWindowMaxSize(Size.infinite);
47+
if (!(Platform.isWindows || Platform.isLinux || Platform.isMacOS)) {
48+
print('Sidekick is not supported on your platform');
49+
exit(0);
5050
}
5151

5252
runApp(ProviderScope(child: FvmApp()));
53+
54+
doWhenWindowReady(() {
55+
final initialSize = Size(800, 500);
56+
appWindow.minSize = initialSize;
57+
appWindow.size = initialSize;
58+
appWindow.alignment = Alignment.center;
59+
appWindow.show();
60+
});
5361
}
5462

5563
/// Fvm App

lib/src/components/molecules/top_app_bar.dart

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:io';
22

3+
import 'package:bitsdojo_window/bitsdojo_window.dart';
34
import 'package:flutter/material.dart';
45
import 'package:hooks_riverpod/hooks_riverpod.dart';
56
import 'package:sidekick/src/components/atoms/typography.dart';
@@ -9,6 +10,7 @@ import 'package:sidekick/src/modules/settings/settings.screen.dart';
910
import 'package:sidekick/src/modules/updater/components/update_button.dart';
1011
import 'package:sidekick/src/theme.dart';
1112
import 'package:sidekick/src/version.dart';
13+
import 'package:sidekick/src/windowBorder.dart';
1214

1315
/// Sidekick top app bar
1416
class SkAppBar extends StatelessWidget implements PreferredSizeWidget {
@@ -43,9 +45,12 @@ class SkAppBar extends StatelessWidget implements PreferredSizeWidget {
4345
? const Caption(kAppTitle)
4446
: const SizedBox(height: 0, width: 0),
4547
centerTitle: true,
48+
leading: Platform.isMacOS ? WindowButtons() : SizedBox(),
4649
actions: [
4750
const SkUpdateButton(),
48-
const SizedBox(width: 10),
51+
const SizedBox(
52+
width: 10,
53+
),
4954
Center(child: Caption(packageVersion)),
5055
const SizedBox(width: 10),
5156
IconButton(
@@ -61,6 +66,7 @@ class SkAppBar extends StatelessWidget implements PreferredSizeWidget {
6166
onPressed: openSettingsScreen,
6267
),
6368
const SizedBox(width: 10),
69+
if (Platform.isWindows || Platform.isLinux) WindowButtons(),
6470
],
6571
bottom: const PreferredSize(
6672
preferredSize: Size.fromHeight(1),
@@ -72,7 +78,7 @@ class SkAppBar extends StatelessWidget implements PreferredSizeWidget {
7278
automaticallyImplyLeading: false,
7379
// shadowColor: Colors.transparent,
7480
// backgroundColor: Colors.transparent,
75-
// flexibleSpace: const BlurBackground(),
81+
flexibleSpace: MoveWindow(),
7682
);
7783
}
7884
}

lib/src/modules/common/app_shell.dart

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
88
import 'package:hooks_riverpod/hooks_riverpod.dart';
99
import 'package:i18next/i18next.dart';
1010
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
11+
import 'package:sidekick/src/windowBorder.dart';
1112

1213
import '../../components/molecules/top_app_bar.dart';
1314
import '../../components/organisms/app_bottom_bar.dart';

lib/src/theme.dart

+6-2
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,24 @@ Color platformBackgroundColor(BuildContext context) {
136136
final brightnessMatches = themeBrightness == platformBrightness;
137137

138138
// Brightness mathces doesn't work on Windows 10
139-
if (brightnessMatches) {
139+
if (!brightnessMatches) {
140140
if (Platform.isMacOS) {
141141
return Colors.transparent;
142142
} else if (Platform.isWindows) {
143143
if (Platform.operatingSystemVersion.contains('11')) {
144144
Window.setEffect(
145145
effect: WindowEffect.mica,
146+
color: Theme.of(context).cardColor.withAlpha(140),
146147
);
148+
return Colors.transparent;
147149
} else if (Platform.operatingSystemVersion.contains('10')) {
148150
Window.setEffect(
149151
effect: WindowEffect.acrylic,
152+
color: Theme.of(context).cardColor.withAlpha(140),
150153
);
154+
return Colors.transparent;
151155
}
152-
return Colors.transparent;
156+
return Theme.of(context).cardColor;
153157
} else {
154158
return Theme.of(context).cardColor;
155159
}

lib/src/windowBorder.dart

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import 'package:bitsdojo_window/bitsdojo_window.dart';
2+
import 'package:flutter/material.dart';
3+
4+
const sidebarColor = Color(0xFFF6A00C);
5+
6+
class LeftSide extends StatelessWidget {
7+
@override
8+
Widget build(BuildContext context) {
9+
return SizedBox(
10+
width: 200,
11+
child: Container(
12+
color: sidebarColor,
13+
child: Column(
14+
children: [
15+
WindowTitleBarBox(child: MoveWindow()),
16+
Expanded(child: Container())
17+
],
18+
)));
19+
}
20+
}
21+
22+
const backgroundStartColor = Color(0xFFFFD500);
23+
const backgroundEndColor = Color(0xFFF6A00C);
24+
25+
class RightSide extends StatelessWidget {
26+
@override
27+
Widget build(BuildContext context) {
28+
return Expanded(
29+
child: Container(
30+
decoration: BoxDecoration(
31+
gradient: LinearGradient(
32+
begin: Alignment.topCenter,
33+
end: Alignment.bottomCenter,
34+
colors: [backgroundStartColor, backgroundEndColor],
35+
stops: [0.0, 1.0]),
36+
),
37+
child: Column(children: [
38+
WindowTitleBarBox(
39+
child: Row(children: [
40+
Expanded(child: MoveWindow()),
41+
WindowButtons()
42+
])),
43+
])));
44+
}
45+
}
46+
47+
class WindowButtons extends StatelessWidget {
48+
@override
49+
Widget build(BuildContext context) {
50+
final buttonColors = WindowButtonColors(
51+
iconNormal: Theme.of(context).brightness == Brightness.dark
52+
? Colors.white
53+
: Colors.black,
54+
mouseOver: Theme.of(context).brightness == Brightness.dark
55+
? Colors.white
56+
: Colors.grey.shade300,
57+
mouseDown: Theme.of(context).brightness == Brightness.dark
58+
? Colors.white
59+
: Colors.grey.shade400,
60+
iconMouseOver: Theme.of(context).brightness == Brightness.dark
61+
? Colors.white
62+
: Colors.black,
63+
iconMouseDown: Theme.of(context).brightness == Brightness.dark
64+
? Colors.white
65+
: Colors.black);
66+
67+
final closeButtonColors = WindowButtonColors(
68+
mouseOver: Color(0xFFD32F2F),
69+
mouseDown: Color(0xFFB71C1C),
70+
iconNormal: Theme.of(context).brightness == Brightness.dark
71+
? Colors.white
72+
: Colors.black,
73+
iconMouseOver: Colors.white);
74+
return Row(
75+
children: [
76+
MinimizeWindowButton(colors: buttonColors),
77+
MaximizeWindowButton(colors: buttonColors),
78+
CloseWindowButton(colors: closeButtonColors),
79+
],
80+
);
81+
}
82+
}

linux/flutter/generated_plugin_registrant.cc

+4
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66

77
#include "generated_plugin_registrant.h"
88

9+
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
910
#include <file_selector_linux/file_selector_plugin.h>
1011
#include <flutter_acrylic/flutter_acrylic_plugin.h>
1112
#include <url_launcher_linux/url_launcher_plugin.h>
1213
#include <window_size/window_size_plugin.h>
1314

1415
void fl_register_plugins(FlPluginRegistry* registry) {
16+
g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar =
17+
fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin");
18+
bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar);
1519
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
1620
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
1721
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);

linux/flutter/generated_plugins.cmake

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#
44

55
list(APPEND FLUTTER_PLUGIN_LIST
6+
bitsdojo_window_linux
67
file_selector_linux
78
flutter_acrylic
89
url_launcher_linux

linux/my_application.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
2+
13
#include "my_application.h"
24

35
#include <flutter_linux/flutter_linux.h>
@@ -21,7 +23,10 @@ static void my_application_activate(GApplication *application)
2123
gtk_header_bar_set_title(header_bar, "Sidekick");
2224
gtk_header_bar_set_show_close_button(header_bar, TRUE);
2325
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
24-
gtk_window_set_default_size(window, 1280, 720);
26+
27+
auto bdw = bitsdojo_window_from(window);
28+
bdw->setCustomFrame(true);
29+
//gtk_window_set_default_size(window, 1280, 720);
2530
gtk_widget_show(GTK_WIDGET(window));
2631

2732
g_autoptr(FlDartProject) project = fl_dart_project_new();

macos/Flutter/GeneratedPluginRegistrant.swift

+2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import FlutterMacOS
66
import Foundation
77

8+
import bitsdojo_window_macos
89
import file_selector_macos
910
import path_provider_macos
1011
import shared_preferences_macos
1112
import url_launcher_macos
1213
import window_size
1314

1415
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
16+
BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin"))
1517
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
1618
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
1719
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))

macos/Runner/MainFlutterWindow.swift

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import Cocoa
22
import FlutterMacOS
3+
import bitsdojo_window_macos
34

4-
class MainFlutterWindow: NSWindow {
5+
class MainFlutterWindow: BitsdojoWindow {
6+
override func bitsdojo_window_configure() -> UInt {
7+
return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP
8+
}
59
override func awakeFromNib() {
610
let flutterViewController = FlutterViewController.init()
711
let windowFrame = self.frame

pubspec.lock

+35
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,41 @@ packages:
4343
url: "https://pub.dartlang.org"
4444
source: hosted
4545
version: "2.8.2"
46+
bitsdojo_window:
47+
dependency: "direct main"
48+
description:
49+
name: bitsdojo_window
50+
url: "https://pub.dartlang.org"
51+
source: hosted
52+
version: "0.1.1+1"
53+
bitsdojo_window_linux:
54+
dependency: transitive
55+
description:
56+
name: bitsdojo_window_linux
57+
url: "https://pub.dartlang.org"
58+
source: hosted
59+
version: "0.1.1"
60+
bitsdojo_window_macos:
61+
dependency: transitive
62+
description:
63+
name: bitsdojo_window_macos
64+
url: "https://pub.dartlang.org"
65+
source: hosted
66+
version: "0.1.0"
67+
bitsdojo_window_platform_interface:
68+
dependency: transitive
69+
description:
70+
name: bitsdojo_window_platform_interface
71+
url: "https://pub.dartlang.org"
72+
source: hosted
73+
version: "0.1.0"
74+
bitsdojo_window_windows:
75+
dependency: transitive
76+
description:
77+
name: bitsdojo_window_windows
78+
url: "https://pub.dartlang.org"
79+
source: hosted
80+
version: "0.1.0"
4681
boolean_selector:
4782
dependency: transitive
4883
description:

pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ environment:
1111
dependencies:
1212
animations: ^2.0.0
1313
async: ^2.6.1
14+
bitsdojo_window: ^0.1.1+1
1415
date_time_format: ^2.0.1
1516
dio: ^4.0.0
1617
file_selector: ^0.8.2

windows/flutter/generated_plugin_registrant.cc

+3
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66

77
#include "generated_plugin_registrant.h"
88

9+
#include <bitsdojo_window_windows/bitsdojo_window_plugin.h>
910
#include <file_selector_windows/file_selector_plugin.h>
1011
#include <flutter_acrylic/flutter_acrylic_plugin.h>
1112
#include <url_launcher_windows/url_launcher_windows.h>
1213
#include <window_size/window_size_plugin.h>
1314

1415
void RegisterPlugins(flutter::PluginRegistry* registry) {
16+
BitsdojoWindowPluginRegisterWithRegistrar(
17+
registry->GetRegistrarForPlugin("BitsdojoWindowPlugin"));
1518
FileSelectorPluginRegisterWithRegistrar(
1619
registry->GetRegistrarForPlugin("FileSelectorPlugin"));
1720
FlutterAcrylicPluginRegisterWithRegistrar(

windows/flutter/generated_plugins.cmake

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#
44

55
list(APPEND FLUTTER_PLUGIN_LIST
6+
bitsdojo_window_windows
67
file_selector_windows
78
flutter_acrylic
89
url_launcher_windows

windows/runner/main.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "flutter_window.h"
66
#include "utils.h"
7+
#include <bitsdojo_window_windows/bitsdojo_window_plugin.h>
8+
auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP);
79

810
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
911
_In_ wchar_t *command_line, _In_ int show_command) {

0 commit comments

Comments
 (0)