From cd5f32121967eea2976c6d64ea7250e5a3d4e0cd Mon Sep 17 00:00:00 2001 From: quangnd Date: Fri, 28 Oct 2022 11:07:20 +0700 Subject: [PATCH 1/3] - Add arrow border --- .dart_tool/package_config.json | 134 +++++++++++++++++ .dart_tool/package_config_subset | 85 +++++++++++ .dart_tool/version | 1 + example/android/app/build.gradle | 4 +- .../android/app/src/main/AndroidManifest.xml | 6 +- .../plugins/GeneratedPluginRegistrant.java | 2 + example/android/build.gradle | 4 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/android/local.properties | 4 +- .../ios/Runner/GeneratedPluginRegistrant.h | 2 + .../ios/Runner/GeneratedPluginRegistrant.m | 2 + example/lib/main.dart | 11 +- lib/src/custom_pop_up_menu.dart | 67 +++++++-- pubspec.lock | 139 ++++++++++++++++++ 14 files changed, 435 insertions(+), 28 deletions(-) create mode 100644 .dart_tool/package_config.json create mode 100644 .dart_tool/package_config_subset create mode 100644 .dart_tool/version create mode 100644 pubspec.lock diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json new file mode 100644 index 0000000..bbf6795 --- /dev/null +++ b/.dart_tool/package_config.json @@ -0,0 +1,134 @@ +{ + "configVersion": 2, + "packages": [ + { + "name": "async", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.9.0", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "boolean_selector", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "characters", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "clock", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "collection", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "fake_async", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "flutter", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/packages/flutter", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "flutter_test", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/packages/flutter_test", + "packageUri": "lib/", + "languageVersion": "2.17" + }, + { + "name": "matcher", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "material_color_utilities", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.5", + "packageUri": "lib/", + "languageVersion": "2.13" + }, + { + "name": "meta", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "path", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.2", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "sky_engine", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/bin/cache/pkg/sky_engine", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "source_span", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "stack_trace", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "stream_channel", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "string_scanner", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "term_glyph", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "test_api", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12", + "packageUri": "lib/", + "languageVersion": "2.12" + }, + { + "name": "vector_math", + "rootUri": "file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2", + "packageUri": "lib/", + "languageVersion": "2.14" + }, + { + "name": "custom_pop_up_menu", + "rootUri": "../", + "packageUri": "lib/", + "languageVersion": "2.17" + } + ], + "generated": "2022-10-28T02:05:49.748624Z", + "generator": "pub", + "generatorVersion": "2.18.2" +} diff --git a/.dart_tool/package_config_subset b/.dart_tool/package_config_subset new file mode 100644 index 0000000..c6e33c0 --- /dev/null +++ b/.dart_tool/package_config_subset @@ -0,0 +1,85 @@ +async +2.14 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib/ +boolean_selector +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib/ +characters +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1/lib/ +clock +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.1/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.1/lib/ +collection +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib/ +fake_async +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.1/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.1/lib/ +matcher +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib/ +material_color_utilities +2.13 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.5/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.5/lib/ +meta +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0/lib/ +path +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.2/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.2/lib/ +source_span +2.14 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0/lib/ +stack_trace +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/ +stream_channel +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib/ +string_scanner +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib/ +term_glyph +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib/ +test_api +2.12 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib/ +vector_math +2.14 +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/ +file:///Users/quangnguyen2203/development/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib/ +sky_engine +2.12 +file:///Users/quangnguyen2203/development/flutter/bin/cache/pkg/sky_engine/ +file:///Users/quangnguyen2203/development/flutter/bin/cache/pkg/sky_engine/lib/ +flutter +2.17 +file:///Users/quangnguyen2203/development/flutter/packages/flutter/ +file:///Users/quangnguyen2203/development/flutter/packages/flutter/lib/ +flutter_test +2.17 +file:///Users/quangnguyen2203/development/flutter/packages/flutter_test/ +file:///Users/quangnguyen2203/development/flutter/packages/flutter_test/lib/ +custom_pop_up_menu +2.17 +file:///Users/quangnguyen2203/project/flutter_packages/custom_pop_up_menu/ +file:///Users/quangnguyen2203/project/flutter_packages/custom_pop_up_menu/lib/ +2 diff --git a/.dart_tool/version b/.dart_tool/version new file mode 100644 index 0000000..0163af7 --- /dev/null +++ b/.dart_tool/version @@ -0,0 +1 @@ +3.3.5 \ No newline at end of file diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 5d7794b..75536d6 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -40,7 +40,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.custom_pop_up_menu" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 2968754..574d28e 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -6,11 +6,12 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> + { title: Text('CustomPopupMenu'), actions: [ CustomPopupMenu( + arrowColor: Colors.white, + arrowSize: 20, child: Container( child: Icon(Icons.add_circle_outline, color: Colors.white), padding: EdgeInsets.all(20), ), menuBuilder: () => ClipRRect( - borderRadius: BorderRadius.circular(5), child: Container( - color: const Color(0xFF4C4C4C), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(), + borderRadius: BorderRadius.circular(5), + ), child: IntrinsicWidth( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -108,7 +113,6 @@ class _MyHomePageState extends State { Icon( item.icon, size: 15, - color: Colors.white, ), Expanded( child: Container( @@ -118,7 +122,6 @@ class _MyHomePageState extends State { child: Text( item.title, style: TextStyle( - color: Colors.white, fontSize: 12, ), ), diff --git a/lib/src/custom_pop_up_menu.dart b/lib/src/custom_pop_up_menu.dart index 1a449ad..b7c64a3 100644 --- a/lib/src/custom_pop_up_menu.dart +++ b/lib/src/custom_pop_up_menu.dart @@ -49,6 +49,7 @@ class CustomPopupMenu extends StatefulWidget { this.position, this.menuOnChange, this.enablePassEvent = true, + this.arrowBorder, }); final Widget child; @@ -63,6 +64,7 @@ class CustomPopupMenu extends StatefulWidget { final Widget Function() menuBuilder; final PreferredPosition? position; final void Function(bool)? menuOnChange; + final BorderSide? arrowBorder; /// Pass tap event to the widgets below the mask. /// It only works when [barrierColor] is transparent. @@ -85,6 +87,11 @@ class _CustomPopupMenuState extends State { width: widget.arrowSize, height: widget.arrowSize, color: widget.arrowColor, + child: CustomPaint( + painter: ClipperBorderPainter( + border: widget.arrowBorder, + ), + ), ), clipper: _ArrowClipper(), ); @@ -101,12 +108,24 @@ class _CustomPopupMenuState extends State { delegate: _MenuLayoutDelegate( anchorSize: _childBox!.size, anchorOffset: _childBox!.localToGlobal( - Offset(-widget.horizontalMargin, 0), + Offset(-widget.horizontalMargin, -10), ), verticalMargin: widget.verticalMargin, position: widget.position, ), children: [ + LayoutId( + id: _MenuLayoutId.content, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Material( + child: widget.menuBuilder(), + color: Colors.transparent, + ), + ], + ), + ), if (widget.showArrow) LayoutId( id: _MenuLayoutId.arrow, @@ -120,18 +139,6 @@ class _CustomPopupMenuState extends State { child: arrow, ), ), - LayoutId( - id: _MenuLayoutId.content, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Material( - child: widget.menuBuilder(), - color: Colors.transparent, - ), - ], - ), - ), ], ), ), @@ -318,7 +325,7 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate { menuPosition = isTop ? _MenuPosition.topCenter : _MenuPosition.bottomCenter; } - + print(menuPosition); switch (menuPosition) { case _MenuPosition.bottomCenter: arrowOffset = Offset( @@ -396,7 +403,7 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate { positionChild( _MenuLayoutId.arrow, isBottom - ? Offset(arrowOffset.dx, arrowOffset.dy + 0.1) + ? Offset(arrowOffset.dx, arrowOffset.dy + 1.1) : Offset(-100, 0), ); } @@ -404,7 +411,7 @@ class _MenuLayoutDelegate extends MultiChildLayoutDelegate { positionChild( _MenuLayoutId.downArrow, !isBottom - ? Offset(arrowOffset.dx, arrowOffset.dy - 0.1) + ? Offset(arrowOffset.dx, arrowOffset.dy - 1.1) : Offset(-100, 0), ); } @@ -429,3 +436,31 @@ class _ArrowClipper extends CustomClipper { return true; } } + +class ClipperBorderPainter extends CustomPainter { + final BorderSide? border; + + ClipperBorderPainter({this.border}); + + + @override + void paint(Canvas canvas, Size size) { + Path path = Path(); + path.moveTo(0, size.height); + path.lineTo(size.width / 2, size.height / 2); + path.lineTo(size.width, size.height); + if(border != null){ + Paint paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth =border!.width + ..color = border!.color; + canvas.drawPath(path, paint); + } + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) { + // TODO: implement shouldRepaint + return true; + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..757cf34 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,139 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.9.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.0" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.12" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.12" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" +sdks: + dart: ">=2.17.0 <3.0.0" From f625e0d1a51fd04ca5b0eb43b51ab73813cc6a7b Mon Sep 17 00:00:00 2001 From: quangnd Date: Fri, 28 Oct 2022 11:24:07 +0700 Subject: [PATCH 2/3] no message --- lib/src/custom_pop_up_menu.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/custom_pop_up_menu.dart b/lib/src/custom_pop_up_menu.dart index b7c64a3..82b3cf8 100644 --- a/lib/src/custom_pop_up_menu.dart +++ b/lib/src/custom_pop_up_menu.dart @@ -108,7 +108,7 @@ class _CustomPopupMenuState extends State { delegate: _MenuLayoutDelegate( anchorSize: _childBox!.size, anchorOffset: _childBox!.localToGlobal( - Offset(-widget.horizontalMargin, -10), + Offset(-widget.horizontalMargin, -13), ), verticalMargin: widget.verticalMargin, position: widget.position, From 20a6bb95234609c0ed9c063cfeb5ac59bcc01684 Mon Sep 17 00:00:00 2001 From: quangnd Date: Fri, 28 Oct 2022 11:28:20 +0700 Subject: [PATCH 3/3] no message --- lib/src/custom_pop_up_menu.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/custom_pop_up_menu.dart b/lib/src/custom_pop_up_menu.dart index 82b3cf8..7e58a84 100644 --- a/lib/src/custom_pop_up_menu.dart +++ b/lib/src/custom_pop_up_menu.dart @@ -108,7 +108,7 @@ class _CustomPopupMenuState extends State { delegate: _MenuLayoutDelegate( anchorSize: _childBox!.size, anchorOffset: _childBox!.localToGlobal( - Offset(-widget.horizontalMargin, -13), + Offset(-widget.horizontalMargin, 0), ), verticalMargin: widget.verticalMargin, position: widget.position,