|
1 | 1 | # Menu Example |
2 | 2 |
|
3 | | -This is a sample application demonstrating the nativeapi menu functionality. |
| 3 | +A comprehensive Flutter application demonstrating all menu functionality provided by the `nativeapi` package. This example covers all test cases from the Menu test plan. |
4 | 4 |
|
5 | | -## Features |
| 5 | +## Features Demonstrated |
6 | 6 |
|
7 | | -- **Native Menu**: Uses nativeapi package to create native system menus |
8 | | -- **Right-click Context Menu**: Right-click on specified areas to display menus |
9 | | -- **Menu Item Types**: Supports normal menu items, separators, menu items with icons, and menu items with tooltips |
10 | | -- **Event Handling**: Listens to menu open/close events and menu item click events |
11 | | -- **Real-time Status Display**: Shows current menu status and operation history |
| 7 | +### 1. Menu Creation & Display (Section 3.1) |
12 | 8 |
|
13 | | -## Usage |
| 9 | +#### Basic Menu Functionality |
| 10 | +- ✅ Create menu objects |
| 11 | +- ✅ Display context menu on right-click |
| 12 | +- ✅ Display menu at specific positions using buttons |
| 13 | +- ✅ Verify menu positioning accuracy |
14 | 14 |
|
15 | | -1. **Right-click Menu**: Right-click on the blue menu demo area to show native context menu |
16 | | -2. **Button Trigger**: Click "Show Menu" button to display menu at specified position |
17 | | -3. **View Status**: Right panel shows menu item count and last executed action |
18 | | -4. **Action History**: View detailed history of all menu operations |
19 | | -5. **Clear History**: Click the clear button in the app bar to clear operation history |
| 15 | +#### Menu Item Types |
| 16 | +- ✅ **Normal** - Standard clickable menu items |
| 17 | +- ✅ **Separator** - Visual dividers between menu items |
| 18 | +- ✅ **Checkbox** - Toggle items with checked/unchecked states |
| 19 | +- ✅ **Radio** - Mutually exclusive selection items |
| 20 | +- ✅ **Submenu** - Nested menus with multiple levels |
20 | 21 |
|
21 | | -## Menu Item Description |
| 22 | +### 2. Menu Item Properties (Section 3.2) |
22 | 23 |
|
23 | | -- **Normal Menu Item**: Basic menu item that records clicks in history |
24 | | -- **Separator**: Used to separate different groups of menu items |
25 | | -- **Menu Item with Icon**: Menu item that supports setting icons (requires icon resources) |
26 | | -- **Menu Item with Tooltip**: Menu item that supports setting tooltips |
| 24 | +#### Labels |
| 25 | +- ✅ Display menu item labels correctly |
| 26 | +- ✅ Dynamically modify labels at runtime |
| 27 | +- ✅ Support multi-language characters (Chinese, Japanese) |
| 28 | +- ✅ Support special characters and symbols (emojis, @#$%) |
27 | 29 |
|
28 | | -## Technical Implementation |
| 30 | +#### Icons |
| 31 | +- ✅ Set icons on menu items |
| 32 | +- ✅ Display icons correctly |
| 33 | +- ✅ Dynamically change icons |
| 34 | +- ✅ Remove icons and restore normal display |
29 | 35 |
|
30 | | -- Uses `Menu` class to create menus |
31 | | -- Uses `MenuItem` class to create menu items |
32 | | -- Uses `ContextMenuRegion` wrapper to implement right-click menus |
33 | | -- Uses event listeners to handle menu events |
34 | | -- Uses `MenuOpenedEvent` and `MenuClosedEvent` to listen to menu status |
35 | | -- Uses `MenuItemClickedEvent` to listen to menu item clicks |
| 36 | +#### Tooltips |
| 37 | +- ✅ Set tooltips on menu items |
| 38 | +- ✅ Display tooltips on hover (platform-dependent) |
| 39 | +- ✅ Show correct tooltip text |
36 | 40 |
|
37 | | -## Requirements |
| 41 | +### 3. Menu Events (Section 3.3) |
38 | 42 |
|
39 | | -- Flutter SDK 3.9.2+ |
40 | | -- macOS platform (native menu functionality) |
41 | | -- nativeapi package dependency |
| 43 | +#### Menu Events |
| 44 | +- ✅ `MenuOpenedEvent` - Triggered when menu opens |
| 45 | +- ✅ `MenuClosedEvent` - Triggered when menu closes |
| 46 | +- ✅ Event listeners receive events correctly |
| 47 | +- ✅ Event history displays all events |
42 | 48 |
|
43 | | -## Run Command |
| 49 | +#### Menu Item Click Events |
| 50 | +- ✅ `MenuItemClickedEvent` - Triggered on normal item clicks |
| 51 | +- ✅ Checkbox items toggle state on click |
| 52 | +- ✅ Radio items toggle state on click |
| 53 | +- ✅ Events contain correct menu item IDs |
| 54 | +- ✅ Multiple clicks trigger events correctly |
| 55 | + |
| 56 | +#### Submenu Events |
| 57 | +- ✅ `MenuItemSubmenuOpenedEvent` - Triggered when submenu opens |
| 58 | +- ✅ `MenuItemSubmenuClosedEvent` - Triggered when submenu closes |
| 59 | + |
| 60 | +### 4. Menu Operations (Section 3.4) |
| 61 | + |
| 62 | +#### Adding Menu Items |
| 63 | +- ✅ Add items to menu end |
| 64 | +- ✅ Insert items at specific positions |
| 65 | +- ✅ Add separators |
| 66 | +- ✅ Insert separators at specific positions |
| 67 | +- ✅ Track item count (`itemCount`) |
| 68 | + |
| 69 | +#### Positioning Strategy |
| 70 | +- ✅ **Absolute** - Display at specific coordinates |
| 71 | +- ✅ **Cursor Position** - Display at mouse cursor |
| 72 | +- ✅ **Relative** - Display relative to a region |
| 73 | + |
| 74 | +#### Menu Placement |
| 75 | +- ✅ Test all placement options: |
| 76 | + - `topStart`, `topEnd` |
| 77 | + - `bottomStart`, `bottomEnd` |
| 78 | + - `leftStart`, `leftEnd` |
| 79 | + - `rightStart`, `rightEnd` |
| 80 | +- ✅ Auto-adjust when menu exceeds screen boundaries |
| 81 | + |
| 82 | +### 5. ContextMenuRegion Widget (Section 3.5) |
| 83 | + |
| 84 | +- ✅ Right-click region displays context menu |
| 85 | +- ✅ Menu displays at correct position |
| 86 | +- ✅ Multiple regions work independently |
| 87 | + |
| 88 | +### 6. Edge Cases (Section 3.6) |
| 89 | + |
| 90 | +- ✅ Handle empty menus (no items) |
| 91 | +- ✅ Display and scroll with many menu items |
| 92 | +- ✅ Rapid open/close operations don't crash |
| 93 | +- ✅ Handle focus changes while menu is open |
| 94 | +- ✅ Clear event history functionality |
| 95 | + |
| 96 | +## UI Layout |
| 97 | + |
| 98 | +The application is divided into two main sections: |
| 99 | + |
| 100 | +### Left Panel - Test Controls |
| 101 | +Contains multiple test sections organized in cards: |
| 102 | + |
| 103 | +1. **Menu Creation & Display** |
| 104 | + - Shows current menu state (item count, checkbox/radio states) |
| 105 | + - Context menu region for right-click testing |
| 106 | + |
| 107 | +2. **Menu Item Operations** |
| 108 | + - Change dynamic label |
| 109 | + - Add new menu items |
| 110 | + - Insert items at specific positions |
| 111 | + - Insert separators at specific positions |
| 112 | + |
| 113 | +3. **Positioning Strategy Tests** |
| 114 | + - Absolute positioning at different coordinates |
| 115 | + - Cursor position testing |
| 116 | + |
| 117 | +4. **Placement Tests** |
| 118 | + - Buttons for all 8 placement options |
| 119 | + - Visual feedback for each placement |
| 120 | + |
| 121 | +5. **Edge Cases & Stress Tests** |
| 122 | + - Add multiple items at once |
| 123 | + - Rapid open/close testing |
| 124 | + - Screen edge boundary testing |
| 125 | + |
| 126 | +### Right Panel - Event History |
| 127 | +- Real-time event log with timestamps |
| 128 | +- Shows all menu and menu item events |
| 129 | +- Displays event IDs for verification |
| 130 | +- Scrollable history (keeps last 50 events) |
| 131 | +- Clear button in app bar |
| 132 | + |
| 133 | +## How to Run |
44 | 134 |
|
45 | 135 | ```bash |
| 136 | +# Navigate to the example directory |
| 137 | +cd examples/menu_example |
| 138 | + |
| 139 | +# Get dependencies |
| 140 | +flutter pub get |
| 141 | + |
| 142 | +# Run on macOS |
46 | 143 | flutter run -d macos |
| 144 | + |
| 145 | +# Run on Windows |
| 146 | +flutter run -d windows |
| 147 | + |
| 148 | +# Run on Linux |
| 149 | +flutter run -d linux |
47 | 150 | ``` |
48 | 151 |
|
49 | | -## Notes |
| 152 | +## Testing Guide |
| 153 | + |
| 154 | +### Basic Testing |
| 155 | +1. **Right-click** on the blue context menu region |
| 156 | +2. Verify all menu item types display correctly |
| 157 | +3. Click different items and observe events in the history |
| 158 | + |
| 159 | +### Menu Item Types Testing |
| 160 | +1. Click **Normal Menu Item** - should log click event |
| 161 | +2. Click **Checkbox Item** - should toggle state and log event |
| 162 | +3. Click **Radio Options** - should switch selection and log event |
| 163 | +4. Hover over **Submenu** - should expand and log open event |
| 164 | +5. Click items in submenu - should log submenu item clicks |
| 165 | + |
| 166 | +### Dynamic Operations Testing |
| 167 | +1. Click **Change Dynamic Label** - label should update with timestamp |
| 168 | +2. Click **Add New Menu Item** - item count should increase |
| 169 | +3. Click **Insert Item at Position 2** - new item appears at position 2 |
| 170 | +4. Click **Insert Separator at Position 3** - separator appears at position 3 |
| 171 | + |
| 172 | +### Positioning Testing |
| 173 | +1. Click **Absolute (100, 100)** - menu appears at top-left |
| 174 | +2. Click **Absolute (300, 200)** - menu appears at center-left |
| 175 | +3. Click **Cursor Position** - menu appears at mouse location |
| 176 | + |
| 177 | +### Placement Testing |
| 178 | +1. Click each placement button (topStart, bottomEnd, etc.) |
| 179 | +2. Verify menu appears in correct position relative to anchor point |
| 180 | +3. Test near screen edges to verify auto-adjustment |
| 181 | + |
| 182 | +### Edge Cases Testing |
| 183 | +1. Click **Add 10 Items** - verify menu handles many items |
| 184 | +2. Click **Rapid Open/Close Test** - verify stability |
| 185 | +3. Click **Test Screen Edge** buttons - verify boundary handling |
| 186 | +4. Open menu, switch window focus, return - verify menu state |
| 187 | + |
| 188 | +### Event Verification |
| 189 | +- All interactions should log events with timestamps |
| 190 | +- Event IDs should be consistent for same menu items |
| 191 | +- Event history should update in real-time |
| 192 | +- Clear button should remove all history entries |
| 193 | + |
| 194 | +## Expected Behavior |
| 195 | + |
| 196 | +### Menu Display |
| 197 | +- Context menu appears on right-click |
| 198 | +- Menus appear at correct positions |
| 199 | +- Separators display as horizontal lines |
| 200 | +- Checkboxes show check marks when selected |
| 201 | +- Radio buttons show selection indicator |
| 202 | +- Submenus show arrow indicator and expand on hover |
| 203 | + |
| 204 | +### Event Flow |
| 205 | +``` |
| 206 | +1. Right-click → MenuOpenedEvent |
| 207 | +2. Click item → MenuItemClickedEvent |
| 208 | +3. Menu closes → MenuClosedEvent |
| 209 | +4. Hover submenu → MenuItemSubmenuOpenedEvent |
| 210 | +5. Leave submenu → MenuItemSubmenuClosedEvent |
| 211 | +``` |
| 212 | + |
| 213 | +### State Management |
| 214 | +- Checkbox state persists between menu opens |
| 215 | +- Radio selection persists and is mutually exclusive |
| 216 | +- Dynamic label changes reflect immediately |
| 217 | +- Item count updates when items are added/removed |
| 218 | + |
| 219 | +## Platform-Specific Notes |
| 220 | + |
| 221 | +### macOS |
| 222 | +- Native NSMenu used for rendering |
| 223 | +- Tooltips may not display (macOS limitation) |
| 224 | +- Keyboard shortcuts can be added to menu items |
| 225 | + |
| 226 | +### Windows |
| 227 | +- Native Win32 menus used |
| 228 | +- Full tooltip support |
| 229 | +- Menu animations follow system settings |
| 230 | + |
| 231 | +### Linux |
| 232 | +- GTK menus used for rendering |
| 233 | +- Appearance follows GTK theme |
| 234 | +- Tooltip support depends on GTK version |
| 235 | + |
| 236 | +## Troubleshooting |
| 237 | + |
| 238 | +### Menu doesn't appear |
| 239 | +- Ensure you're right-clicking on the blue region |
| 240 | +- Try using the button-based menu triggers |
| 241 | +- Check event history for error messages |
| 242 | + |
| 243 | +### Events not logging |
| 244 | +- Verify event listeners are set up correctly |
| 245 | +- Check console for any error messages |
| 246 | +- Ensure menu items are properly initialized |
| 247 | + |
| 248 | +### Items not updating |
| 249 | +- Dynamic changes require menu to be closed and reopened |
| 250 | +- Some platforms cache menu state |
| 251 | +- Try recreating the menu if issues persist |
| 252 | + |
| 253 | +## Code Structure |
| 254 | + |
| 255 | +``` |
| 256 | +main.dart |
| 257 | +├── MyApp - Root application widget |
| 258 | +└── MenuExamplePage - Main example page |
| 259 | + ├── _setupContextMenu() - Creates main context menu |
| 260 | + ├── _setupPositioningMenu() - Creates positioning test menu |
| 261 | + ├── _setupPlacementMenu() - Creates placement test menu |
| 262 | + ├── _addToHistory() - Logs events to history |
| 263 | + └── UI Sections |
| 264 | + ├── Menu Creation & Display |
| 265 | + ├── Menu Item Operations |
| 266 | + ├── Positioning Strategy Tests |
| 267 | + ├── Placement Tests |
| 268 | + ├── Edge Cases & Stress Tests |
| 269 | + └── Event History Panel |
| 270 | +``` |
| 271 | + |
| 272 | +## Related Documentation |
| 273 | + |
| 274 | +- [Menu API Documentation](../../packages/nativeapi/lib/src/menu.dart) |
| 275 | +- [Menu Events Documentation](../../packages/nativeapi/lib/src/menu_event.dart) |
| 276 | +- [Test Plan](../../TEST_PLAN.md#3-menu菜单) |
| 277 | + |
| 278 | +## License |
50 | 279 |
|
51 | | -- This example is primarily targeted at macOS platform's native menu functionality |
52 | | -- Menu item state management (such as checkboxes, radio buttons) needs to be implemented according to actual requirements |
53 | | -- Icon resources need to be properly configured in the project |
| 280 | +This example is part of the nativeapi package and follows the same license. |
0 commit comments