marco.pms.mobileapp/lib/widgets/custom_pop_menu.dart
Vaibhav Surve a5dd5e19fc Add Windows runner implementation for Flutter application
- Created CMakeLists.txt for Flutter and runner components.
- Implemented resource script (Runner.rc) for application metadata.
- Developed main entry point (main.cpp) for the Windows application.
- Added FlutterWindow class to manage the Flutter view within a Win32 window.
- Implemented utility functions for console management and command line argument parsing.
- Established Win32Window class for high DPI-aware window handling.
- Included application icon and manifest for proper Windows integration.
- Set up build configurations and dependencies for the Flutter application on Windows.
2025-04-23 09:55:31 +05:30

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,
),
);
},
);
}
}