Skip to content

Commit

Permalink
feat: platform window title bar button add
Browse files Browse the repository at this point in the history
  • Loading branch information
KRTirtho committed Nov 7, 2022
1 parent 79bf43a commit 56706d2
Show file tree
Hide file tree
Showing 7 changed files with 456 additions and 55 deletions.
25 changes: 14 additions & 11 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,19 @@ class _MyHomePageState extends State<MyHomePage> {
print(value);
},
child: const Icon(Icons.more_vert_rounded),
)
),
PlatformWindowButtons(
isMaximized: false,
onClose: () {
print("Close");
},
onMinimize: () {
print("Minimize");
},
onMaximize: () {
print("Maximize");
},
),
],
),
body: PlatformSidebar(
Expand Down Expand Up @@ -324,16 +336,7 @@ class _MyHomePageState extends State<MyHomePage> {
android: (context, parent) {
return PlatformFilledButton(
isSecondary: true,
style: ButtonStyle(
backgroundColor:
MaterialStatePropertyAll(
Colors.grey[300],
),
),
child: const PlatformText(
"No",
style: TextStyle(color: Colors.black),
),
child: const PlatformText("No"),
onPressed: () {
Navigator.of(context).pop(false);
},
Expand Down
1 change: 1 addition & 0 deletions lib/platform_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export 'src/platform_checkbox.dart';
export 'src/tools/platform_builder.dart';
export 'src/platform_back_button.dart';
export 'src/platform_bottom_navigation_bar.dart';
export 'src/platform_window_buttons.dart';
97 changes: 53 additions & 44 deletions lib/src/platform_filled_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -225,55 +225,64 @@ class PlatformFilledButton extends StatelessWidget with PlatformMixin<Widget> {

@override
Widget windows(context) {
final themedStyle = this.themedStyle(context);
final buttonStyle = FluentUI.ButtonStyle(
backgroundColor: Utils.resolveMaterialPropertyAsAllButtonState<Color?>(
allStates,
style?.backgroundColor,
),
elevation: Utils.resolveMaterialPropertyAsAllButtonState<double?>(
allStates,
style?.elevation,
),
foregroundColor: Utils.resolveMaterialPropertyAsAllButtonState<Color?>(
allStates,
style?.foregroundColor,
),
padding: Utils.resolveMaterialPropertyAsAllButtonState(
allStates,
style?.padding,
),
shadowColor: Utils.resolveMaterialPropertyAsAllButtonState<Color?>(
allStates,
style?.shadowColor,
),
textStyle: Utils.resolveMaterialPropertyAsAllButtonState(
allStates,
style?.textStyle,
),
shape: Utils.resolveMaterialPropertyAsAllButtonState(
allStates,
style?.shape,
),
border: Utils.resolveMaterialPropertyAsAllButtonState(
allStates,
style?.side,
),
);

return ClipRect(
clipBehavior: clipBehavior,
child: MouseRegion(
cursor: mouseCursor,
onHover: onHover,
child: FluentUI.FilledButton(
onPressed: onPressed,
onLongPress: onLongPress,
autofocus: autofocus,
focusNode: focusNode,
style: FluentUI.ButtonStyle(
backgroundColor:
Utils.resolveMaterialPropertyAsAllButtonState<Color?>(
allStates,
themedStyle?.backgroundColor,
),
elevation: Utils.resolveMaterialPropertyAsAllButtonState<double?>(
allStates,
style?.elevation,
),
foregroundColor:
Utils.resolveMaterialPropertyAsAllButtonState<Color?>(
allStates,
themedStyle?.foregroundColor,
),
padding: Utils.resolveMaterialPropertyAsAllButtonState(
allStates,
style?.padding,
),
shadowColor: Utils.resolveMaterialPropertyAsAllButtonState<Color?>(
allStates,
style?.shadowColor,
),
textStyle: Utils.resolveMaterialPropertyAsAllButtonState(
allStates,
style?.textStyle,
),
shape: Utils.resolveMaterialPropertyAsAllButtonState(
allStates,
style?.shape,
),
border: Utils.resolveMaterialPropertyAsAllButtonState(
allStates,
style?.side,
),
),
child: child,
),
child: isSecondary != true
? FluentUI.FilledButton(
onPressed: onPressed,
onLongPress: onLongPress,
autofocus: autofocus,
focusNode: focusNode,
style: buttonStyle,
child: child,
)
: FluentUI.Button(
onPressed: onPressed,
onLongPress: onLongPress,
autofocus: autofocus,
focusNode: focusNode,
style: buttonStyle,
focusable: true,
child: child,
),
),
);
}
Expand Down
168 changes: 168 additions & 0 deletions lib/src/platform_window_buttons.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import 'package:flutter/material.dart';
import 'package:platform_ui/platform_ui.dart';
import 'package:fluent_ui/fluent_ui.dart' as FluentUI;
import 'package:platform_ui/src/specific/linux_window_button.dart';
import 'package:platform_ui/src/specific/windows_title_bar_icons.dart';
import 'package:platform_ui/src/tools/gesture_builder.dart';

class PlatformWindowButtons extends StatelessWidget
with PlatformMixin<Widget>
implements PreferredSizeWidget {
final VoidCallback onClose;
final VoidCallback onMinimize;
final VoidCallback onMaximize;
final bool isMaximized;
const PlatformWindowButtons({
Key? key,
required this.onClose,
required this.onMinimize,
required this.onMaximize,
required this.isMaximized,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return SizedBox(
height: preferredSize.height,
child: getPlatformType(context),
);
}

@override
Size get preferredSize => const Size(110, 30);

@override
Widget android(BuildContext context) {
return linux(context);
}

@override
Widget ios(BuildContext context) {
return macos(context);
}

@override
Widget linux(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
AdwWindowButton(
buttonType: WindowButtonType.minimize,
onPressed: onMinimize,
),
AdwWindowButton(
buttonType: WindowButtonType.maximize,
onPressed: onMaximize,
),
AdwWindowButton(
buttonType: WindowButtonType.close,
onPressed: onClose,
),
],
);
}

@override
Widget macos(BuildContext context) {
final decoration = BoxDecoration(
color: Colors.red[400],
borderRadius: BorderRadius.circular(18),
);
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureBuilder(
builder: (context, states) {
return Container(
height: 18,
width: 18,
decoration: states.isPressing
? decoration.copyWith(
color: Colors.red[800],
)
: decoration,
);
},
),
const SizedBox(width: 4),
GestureBuilder(builder: (context, states) {
return Container(
height: 18,
width: 18,
decoration: decoration.copyWith(
color:
states.isPressing ? Colors.orange[400] : Colors.orange[200],
),
);
}),
const SizedBox(width: 4),
GestureBuilder(builder: (context, states) {
return Container(
height: 18,
width: 18,
decoration: decoration.copyWith(
color: states.isPressing ? Colors.green[800] : Colors.green[400],
),
);
}),
],
);
}

@override
Widget windows(BuildContext context) {
var buttonStyle = FluentUI.ButtonStyle(
backgroundColor: FluentUI.ButtonState.resolveWith(
(states) {
if (states.contains(FluentUI.ButtonStates.focused) ||
states.contains(FluentUI.ButtonStates.focused)) {
return Colors.black26;
} else if (states.contains(FluentUI.ButtonStates.hovering)) {
return Colors.black12;
}
return Colors.transparent;
},
),
shape: FluentUI.ButtonState.all(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
),
border: FluentUI.ButtonState.all(BorderSide.none),
);
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FluentUI.Button(
style: buttonStyle,
onPressed: onMinimize,
child:
MinimizeIcon(color: PlatformTextTheme.of(context).body!.color!),
),
FluentUI.Button(
style: buttonStyle,
onPressed: onMaximize,
child: isMaximized
? RestoreIcon(color: PlatformTextTheme.of(context).body!.color!)
: MaximizeIcon(color: PlatformTextTheme.of(context).body!.color!),
),
FluentUI.Button(
style: buttonStyle.copyWith(
backgroundColor: FluentUI.ButtonState.resolveWith(
(states) {
if (states.contains(FluentUI.ButtonStates.hovering)) {
return Colors.red;
}
return Colors.transparent;
},
),
),
onPressed: onMinimize,
child: CloseIcon(color: PlatformTextTheme.of(context).body!.color!),
),
],
);
}
}
38 changes: 38 additions & 0 deletions lib/src/specific/linux_window_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:libadwaita/libadwaita.dart';

enum WindowButtonType { close, maximize, minimize }

class AdwWindowButton extends StatelessWidget {
const AdwWindowButton({
Key? key,
required this.buttonType,
required this.onPressed,
}) : super(key: key);

/// Executed when this button is pressed
final VoidCallback? onPressed;

/// The WindowButtonType for this window
final WindowButtonType buttonType;

@override
Widget build(BuildContext context) {
return onPressed != null
? AdwButton.circular(
size: 24,
margin: const EdgeInsets.all(4),
onPressed: onPressed,
child: Center(
child: SvgPicture.asset(
'packages/libadwaita/assets/icons/${buttonType.name}.svg',
width: 16,
height: 16,
color: context.textColor,
),
),
)
: const SizedBox();
}
}
Loading

0 comments on commit 56706d2

Please sign in to comment.