- Created generated_plugin_registrant.cc and generated_plugin_registrant.h to manage plugin registration. - Added generated_plugins.cmake for plugin configuration in CMake. - Implemented CMakeLists.txt for the Windows runner, defining build settings and dependencies. - Created Runner.rc for application resources including versioning and icons. - Developed flutter_window.cpp and flutter_window.h to manage the Flutter window lifecycle. - Implemented main.cpp as the entry point for the Windows application. - Added resource.h for resource definitions. - Included app icon in resources. - Created runner.exe.manifest for application settings. - Developed utils.cpp and utils.h for console management and command line argument handling. - Implemented win32_window.cpp and win32_window.h for high DPI-aware window management.
140 lines
3.6 KiB
Dart
140 lines
3.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
|
|
|
enum CustomPopupMenuPlacement { left, right, top, bottom }
|
|
|
|
typedef HideFn = void Function(Function hideFn);
|
|
|
|
class CustomPopupMenu extends StatefulWidget {
|
|
final Widget menu;
|
|
final ValueChanged<bool> onChange;
|
|
final WidgetBuilder menuBuilder;
|
|
final int selectedIndex;
|
|
final CustomPopupMenuPlacement placement;
|
|
final double offsetX, offsetY;
|
|
final bool backdrop;
|
|
final bool show;
|
|
final HideFn? hideFn;
|
|
|
|
const CustomPopupMenu(
|
|
{super.key,
|
|
required this.menu,
|
|
required this.onChange,
|
|
required this.menuBuilder,
|
|
this.selectedIndex = 0,
|
|
this.backdrop = false,
|
|
this.show = true,
|
|
this.placement = CustomPopupMenuPlacement.bottom,
|
|
this.offsetX = 0,
|
|
this.hideFn,
|
|
this.offsetY = 0});
|
|
|
|
@override
|
|
_CustomPopupMenuState createState() => _CustomPopupMenuState();
|
|
}
|
|
|
|
class _CustomPopupMenuState extends State<CustomPopupMenu>
|
|
with SingleTickerProviderStateMixin, UIMixin {
|
|
late GlobalKey _key;
|
|
bool isMenuOpen = false;
|
|
late Offset buttonPosition;
|
|
late Size buttonSize;
|
|
OverlayEntry? _overlayEntry;
|
|
OverlayEntry? _overlayEntry1;
|
|
|
|
@override
|
|
void initState() {
|
|
_key = LabeledGlobalKey("popup-button");
|
|
super.initState();
|
|
if (widget.hideFn != null) {
|
|
widget.hideFn!(closeMenu);
|
|
}
|
|
}
|
|
|
|
findButton() {
|
|
RenderBox? renderBox =
|
|
_key.currentContext!.findRenderObject() as RenderBox?;
|
|
buttonSize = renderBox!.size;
|
|
buttonPosition = renderBox.localToGlobal(Offset.zero);
|
|
}
|
|
|
|
closeMenu() {
|
|
_overlayEntry?.remove();
|
|
_overlayEntry1?.remove();
|
|
// if(_animationController.)
|
|
// _animationController.reverse();
|
|
isMenuOpen = false;
|
|
}
|
|
|
|
openMenu() {
|
|
findButton();
|
|
_overlayEntry = _overlayEntryBuilder();
|
|
_overlayEntry1 = _overlayEntryBuilder1();
|
|
Overlay.of(context).insert(_overlayEntry1!);
|
|
Overlay.of(context).insert(
|
|
_overlayEntry!,
|
|
);
|
|
isMenuOpen = true;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
key: _key,
|
|
child: MouseRegion(
|
|
cursor: SystemMouseCursors.click,
|
|
child: GestureDetector(
|
|
behavior: HitTestBehavior.translucent,
|
|
onTap: () {
|
|
if (isMenuOpen) {
|
|
closeMenu();
|
|
widget.onChange(false);
|
|
} else {
|
|
openMenu();
|
|
widget.onChange(true);
|
|
}
|
|
},
|
|
child: widget.menu),
|
|
),
|
|
);
|
|
}
|
|
|
|
OverlayEntry _overlayEntryBuilder() {
|
|
double left = 0, top = 0;
|
|
if (widget.placement == CustomPopupMenuPlacement.bottom) {
|
|
top = buttonPosition.dy + buttonSize.height + widget.offsetY;
|
|
left = buttonPosition.dx + widget.offsetX;
|
|
} else if (widget.placement == CustomPopupMenuPlacement.right) {
|
|
top = buttonPosition.dy + widget.offsetY;
|
|
left = buttonPosition.dx + buttonSize.width + widget.offsetX;
|
|
}
|
|
|
|
return OverlayEntry(
|
|
builder: (context) {
|
|
return Positioned(
|
|
top: top,
|
|
left: left,
|
|
child: widget.menuBuilder(context),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
OverlayEntry _overlayEntryBuilder1() {
|
|
return OverlayEntry(
|
|
builder: (context) {
|
|
return GestureDetector(
|
|
onTap: () => {closeMenu()},
|
|
child: Container(
|
|
height: MediaQuery.of(context).size.height,
|
|
width: MediaQuery.of(context).size.width,
|
|
color: widget.backdrop
|
|
? colorScheme.onSurface.withAlpha(12)
|
|
: Colors.transparent,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|