Skip to content

Commit a01b254

Browse files
committed
Add icon and removal features to menu example
Introduces icon management for menu items, including setting icons from assets and Flutter Icon widgets (converted to base64), and removing icons. Adds menu item removal methods (by reference, index, or ID) to the Menu API and exposes them in the example app. Updates UI to support these features and documents them in the README. Also adds asset image support in pubspec.yaml and improves ContextMenuRegion to support placement.
1 parent 32b27b2 commit a01b254

6 files changed

Lines changed: 513 additions & 286 deletions

File tree

examples/menu_example/README.md

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ A comprehensive Flutter application demonstrating all menu functionality provide
2828
- ✅ Support special characters and symbols (emojis, @#$%)
2929

3030
#### Icons
31-
- ✅ Set icons on menu items
31+
- ✅ Set icons on menu items (from assets)
32+
- ✅ Set icons from Flutter Icon widgets (converted to base64)
3233
- ✅ Display icons correctly
3334
- ✅ Dynamically change icons
3435
- ✅ Remove icons and restore normal display
36+
- ✅ Load icons from Flutter assets
37+
- ✅ Convert Material Icons to native menu icons
3538

3639
#### Tooltips
3740
- ✅ Set tooltips on menu items
@@ -66,6 +69,12 @@ A comprehensive Flutter application demonstrating all menu functionality provide
6669
- ✅ Insert separators at specific positions
6770
- ✅ Track item count (`itemCount`)
6871

72+
#### Removing Menu Items
73+
- ✅ Remove items by reference (`removeItem`)
74+
- ✅ Remove items by ID (`removeItemById`)
75+
- ✅ Remove items by index (`removeItemAt`)
76+
- ✅ Update item count after removal
77+
6978
#### Positioning Strategy
7079
-**Absolute** - Display at specific coordinates
7180
-**Cursor Position** - Display at mouse cursor
@@ -110,15 +119,25 @@ Contains multiple test sections organized in cards:
110119
- Insert items at specific positions
111120
- Insert separators at specific positions
112121

113-
3. **Positioning Strategy Tests**
122+
3. **Icon Management**
123+
- Set icon from asset file
124+
- Set icon from Flutter Icon widget (Material Icons)
125+
- Remove icon from menu item
126+
127+
4. **Menu Item Removal**
128+
- Remove first menu item
129+
- Remove item at specific position
130+
- Remove last menu item
131+
132+
5. **Positioning Strategy Tests**
114133
- Absolute positioning at different coordinates
115134
- Cursor position testing
116135

117-
4. **Placement Tests**
136+
6. **Placement Tests**
118137
- Buttons for all 8 placement options
119138
- Visual feedback for each placement
120139

121-
5. **Edge Cases & Stress Tests**
140+
7. **Edge Cases & Stress Tests**
122141
- Add multiple items at once
123142
- Rapid open/close testing
124143
- Screen edge boundary testing
@@ -169,6 +188,23 @@ flutter run -d linux
169188
3. Click **Insert Item at Position 2** - new item appears at position 2
170189
4. Click **Insert Separator at Position 3** - separator appears at position 3
171190

191+
### Icon Management Testing
192+
1. Click **Set Icon from Asset** - first menu item displays icon from asset file
193+
2. Right-click the context menu region to verify icon appears
194+
3. Click **Set Icon from Widget** - first menu item displays a star icon (converted from Material Icons)
195+
4. Right-click to verify the widget-based icon appears
196+
5. Click **Remove Icon from First Item** - icon should disappear
197+
6. Right-click again to verify icon is removed
198+
199+
**Note:** The "Set Icon from Widget" feature demonstrates converting Flutter's Material Icons to native menu icons using base64 encoding.
200+
201+
### Menu Item Removal Testing
202+
1. Click **Remove First Menu Item** - first item should be removed, count decreases
203+
2. Click **Remove Item at Position 2** - item at position 2 removed
204+
3. Click **Remove Last Menu Item** - last item removed
205+
4. Verify item count updates correctly after each removal
206+
5. Right-click to verify items are actually removed from menu
207+
172208
### Positioning Testing
173209
1. Click **Absolute (100, 100)** - menu appears at top-left
174210
2. Click **Absolute (300, 200)** - menu appears at center-left
@@ -216,22 +252,69 @@ flutter run -d linux
216252
- Dynamic label changes reflect immediately
217253
- Item count updates when items are added/removed
218254

255+
## Technical Features
256+
257+
### Icon Conversion from Flutter Widgets
258+
259+
The example demonstrates converting Flutter Icon widgets (like Material Icons) to native menu icons:
260+
261+
```dart
262+
Future<Image?> _iconToImage(IconData iconData, {
263+
double size = 24.0,
264+
Color color = Colors.black,
265+
}) async {
266+
// 1. Create a picture recorder to draw the icon
267+
final recorder = ui.PictureRecorder();
268+
final canvas = Canvas(recorder);
269+
270+
// 2. Use TextPainter to render the icon glyph
271+
final textPainter = TextPainter(textDirection: TextDirection.ltr);
272+
textPainter.text = TextSpan(
273+
text: String.fromCharCode(iconData.codePoint),
274+
style: TextStyle(
275+
fontSize: size,
276+
fontFamily: iconData.fontFamily,
277+
package: iconData.fontPackage,
278+
color: color,
279+
),
280+
);
281+
282+
textPainter.layout();
283+
textPainter.paint(canvas, Offset.zero);
284+
285+
// 3. Convert to PNG image
286+
final picture = recorder.endRecording();
287+
final img = await picture.toImage(size.toInt(), size.toInt());
288+
final byteData = await img.toByteData(format: ui.ImageByteFormat.png);
289+
290+
// 4. Encode to base64 and create nativeapi Image
291+
final pngBytes = byteData.buffer.asUint8List();
292+
final base64String = 'data:image/png;base64,${base64Encode(pngBytes)}';
293+
return Image.fromBase64(base64String);
294+
}
295+
```
296+
297+
This allows you to use any Flutter Icon (Material Icons, Cupertino Icons, custom icon fonts) as native menu icons.
298+
219299
## Platform-Specific Notes
220300

221301
### macOS
222302
- Native NSMenu used for rendering
223303
- Tooltips may not display (macOS limitation)
224304
- Keyboard shortcuts can be added to menu items
305+
- Icon rendering supports base64 PNG images
225306

226307
### Windows
227308
- Native Win32 menus used
228309
- Full tooltip support
229310
- Menu animations follow system settings
311+
- Icon rendering supports base64 PNG images
230312

231313
### Linux
232314
- GTK menus used for rendering
233315
- Appearance follows GTK theme
234316
- Tooltip support depends on GTK version
317+
- Icon rendering supports base64 PNG images
235318

236319
## Troubleshooting
237320

@@ -256,13 +339,25 @@ flutter run -d linux
256339
main.dart
257340
├── MyApp - Root application widget
258341
└── MenuExamplePage - Main example page
342+
├── _loadTestIcon() - Loads test icon from assets
343+
├── _iconToImage() - Converts Flutter Icon widget to base64 image
259344
├── _setupContextMenu() - Creates main context menu
260345
├── _setupPositioningMenu() - Creates positioning test menu
261346
├── _setupPlacementMenu() - Creates placement test menu
262347
├── _addToHistory() - Logs events to history
348+
├── Icon Management Methods
349+
│ ├── _setIconOnFirstItem() - Sets icon from asset file
350+
│ ├── _setIconFromWidget() - Sets icon from Flutter Icon widget
351+
│ └── _removeIconFromFirstItem() - Removes icon from first item
352+
├── Menu Item Removal Methods
353+
│ ├── _removeFirstMenuItem() - Removes first item
354+
│ ├── _removeMenuItemAtPosition() - Removes item at position 2
355+
│ └── _removeLastMenuItem() - Removes last item
263356
└── UI Sections
264357
├── Menu Creation & Display
265358
├── Menu Item Operations
359+
├── Icon Management
360+
├── Menu Item Removal
266361
├── Positioning Strategy Tests
267362
├── Placement Tests
268363
├── Edge Cases & Stress Tests
1.24 KB
Loading

0 commit comments

Comments
 (0)