1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <string.h>
4+
5+ #ifdef _WIN32
6+ #include <windows.h>
7+ #else
8+ #include <unistd.h>
9+ #endif
10+
11+ // Include individual C API headers instead of the full nativeapi.h
12+ #include "../../src/capi/menu_c.h"
13+ #include "../../src/capi/tray_icon_c.h"
14+ #include "../../src/capi/tray_manager_c.h"
15+
16+ // Callback functions
17+ void on_menu_item_clicked (const native_menu_item_selected_event_t * event , void * user_data ) {
18+ printf ("Menu item clicked: ID=%ld, Text='%s'\n" , event -> item_id , event -> item_text );
19+
20+ if (strcmp (event -> item_text , "Exit" ) == 0 ) {
21+ printf ("Exiting application...\n" );
22+ exit (0 );
23+ } else if (strcmp (event -> item_text , "Show Message" ) == 0 ) {
24+ printf ("Hello from tray menu!\n" );
25+ }
26+ }
27+
28+ void on_checkbox_state_changed (const native_menu_item_state_changed_event_t * event , void * user_data ) {
29+ printf ("Checkbox state changed: ID=%ld, Checked=%s\n" ,
30+ event -> item_id , event -> checked ? "true" : "false" );
31+ }
32+
33+ void on_tray_left_click (void * user_data ) {
34+ printf ("Tray icon left clicked!\n" );
35+ }
36+
37+ void on_tray_right_click (void * user_data ) {
38+ printf ("Tray icon right clicked!\n" );
39+ }
40+
41+ void on_tray_double_click (void * user_data ) {
42+ printf ("Tray icon double clicked!\n" );
43+ }
44+
45+ void on_menu_will_show (native_menu_id_t menu_id , void * user_data ) {
46+ printf ("Menu will show: ID=%ld\n" , menu_id );
47+ }
48+
49+ void on_menu_did_hide (native_menu_id_t menu_id , void * user_data ) {
50+ printf ("Menu did hide: ID=%ld\n" , menu_id );
51+ }
52+
53+ int main () {
54+ printf ("=== Tray Menu C API Example ===\n" );
55+
56+ // Check if system tray is supported
57+ if (!native_tray_manager_is_supported ()) {
58+ printf ("Error: System tray is not supported on this platform!\n" );
59+ return 1 ;
60+ }
61+
62+ printf ("System tray is supported.\n" );
63+
64+ // Create a menu
65+ native_menu_t menu = native_menu_create ();
66+ if (!menu ) {
67+ printf ("Error: Failed to create menu!\n" );
68+ return 1 ;
69+ }
70+
71+ printf ("Created menu with ID: %ld\n" , native_menu_get_id (menu ));
72+
73+ // Create menu items
74+ native_menu_item_t item1 = native_menu_item_create ("Show Message" , NATIVE_MENU_ITEM_TYPE_NORMAL );
75+ native_menu_item_t item2 = native_menu_item_create ("Settings" , NATIVE_MENU_ITEM_TYPE_NORMAL );
76+ native_menu_item_t checkbox = native_menu_item_create ("Enable Notifications" , NATIVE_MENU_ITEM_TYPE_CHECKBOX );
77+ native_menu_item_t separator = native_menu_item_create_separator ();
78+ native_menu_item_t exit_item = native_menu_item_create ("Exit" , NATIVE_MENU_ITEM_TYPE_NORMAL );
79+
80+ if (!item1 || !item2 || !checkbox || !separator || !exit_item ) {
81+ printf ("Error: Failed to create menu items!\n" );
82+ native_menu_destroy (menu );
83+ return 1 ;
84+ }
85+
86+ // Set up menu item properties
87+ native_menu_item_set_enabled (item1 , true);
88+ native_menu_item_set_tooltip (item1 , "Click to show a message" );
89+
90+ // Set up keyboard accelerator for exit item
91+ native_keyboard_accelerator_t exit_accel = {
92+ .modifiers = NATIVE_ACCELERATOR_MODIFIER_CTRL ,
93+ .key = "Q"
94+ };
95+ native_menu_item_set_accelerator (exit_item , & exit_accel );
96+
97+ // Set checkbox state
98+ native_menu_item_set_checked (checkbox , true);
99+
100+ // Set up event handlers
101+ native_menu_item_set_on_click (item1 , on_menu_item_clicked , NULL );
102+ native_menu_item_set_on_click (item2 , on_menu_item_clicked , NULL );
103+ native_menu_item_set_on_click (exit_item , on_menu_item_clicked , NULL );
104+ native_menu_item_set_on_state_changed (checkbox , on_checkbox_state_changed , NULL );
105+
106+ // Add items to menu
107+ native_menu_add_item (menu , item1 );
108+ native_menu_add_item (menu , item2 );
109+ native_menu_add_item (menu , checkbox );
110+ native_menu_add_item (menu , separator );
111+ native_menu_add_item (menu , exit_item );
112+
113+ printf ("Added %zu items to menu\n" , native_menu_get_item_count (menu ));
114+
115+ // Set menu callbacks
116+ native_menu_set_on_will_show (menu , on_menu_will_show , NULL );
117+ native_menu_set_on_did_hide (menu , on_menu_did_hide , NULL );
118+
119+ // Create a submenu example
120+ native_menu_t submenu = native_menu_create ();
121+ if (submenu ) {
122+ native_menu_item_t sub_item1 = native_menu_item_create ("Sub Item 1" , NATIVE_MENU_ITEM_TYPE_NORMAL );
123+ native_menu_item_t sub_item2 = native_menu_item_create ("Sub Item 2" , NATIVE_MENU_ITEM_TYPE_NORMAL );
124+
125+ if (sub_item1 && sub_item2 ) {
126+ native_menu_add_item (submenu , sub_item1 );
127+ native_menu_add_item (submenu , sub_item2 );
128+
129+ // Create submenu item and add to main menu
130+ native_menu_item_t submenu_item = native_menu_create_and_add_submenu (menu , "More Options" , submenu );
131+ if (submenu_item ) {
132+ printf ("Created submenu with %zu items\n" , native_menu_get_item_count (submenu ));
133+ }
134+ }
135+ }
136+
137+ // Create tray icon
138+ native_tray_icon_t tray_icon = native_tray_manager_create ();
139+ if (!tray_icon ) {
140+ printf ("Error: Failed to create tray icon!\n" );
141+ native_menu_destroy (menu );
142+ return 1 ;
143+ }
144+
145+ printf ("Created tray icon with ID: %ld\n" , native_tray_icon_get_id (tray_icon ));
146+
147+ // Set up tray icon properties
148+ native_tray_icon_set_title (tray_icon , "My App" );
149+ native_tray_icon_set_tooltip (tray_icon , "My Application - Right click for menu" );
150+
151+ // Set the context menu
152+ native_tray_icon_set_context_menu (tray_icon , menu );
153+
154+ // Set up tray icon event handlers
155+ native_tray_icon_set_on_left_click (tray_icon , on_tray_left_click , NULL );
156+ native_tray_icon_set_on_right_click (tray_icon , on_tray_right_click , NULL );
157+ native_tray_icon_set_on_double_click (tray_icon , on_tray_double_click , NULL );
158+
159+ // Show the tray icon
160+ if (native_tray_icon_show (tray_icon )) {
161+ printf ("Tray icon is now visible\n" );
162+ } else {
163+ printf ("Warning: Failed to show tray icon\n" );
164+ }
165+
166+ // Get tray icon bounds
167+ native_rectangle_t bounds ;
168+ if (native_tray_icon_get_bounds (tray_icon , & bounds )) {
169+ printf ("Tray icon bounds: x=%.1f, y=%.1f, width=%.1f, height=%.1f\n" ,
170+ bounds .x , bounds .y , bounds .width , bounds .height );
171+ }
172+
173+ // Demonstrate menu item lookup
174+ native_menu_item_t found_item = native_menu_find_item_by_text (menu , "Exit" );
175+ if (found_item ) {
176+ printf ("Found 'Exit' menu item with ID: %ld\n" , native_menu_item_get_id (found_item ));
177+
178+ // Get accelerator info
179+ native_keyboard_accelerator_t accel ;
180+ if (native_menu_item_get_accelerator (found_item , & accel )) {
181+ char accel_str [64 ];
182+ if (native_keyboard_accelerator_to_string (& accel , accel_str , sizeof (accel_str )) > 0 ) {
183+ printf ("Exit item accelerator: %s\n" , accel_str );
184+ }
185+ }
186+ }
187+
188+ // Show all managed tray icons
189+ native_tray_icon_list_t tray_list = native_tray_manager_get_all ();
190+ printf ("Total managed tray icons: %zu\n" , tray_list .count );
191+ native_tray_icon_list_free (tray_list );
192+
193+ printf ("\n=== Tray icon and menu are now active ===\n" );
194+ printf ("- Left click the tray icon to see left click message\n" );
195+ printf ("- Right click the tray icon to open context menu\n" );
196+ printf ("- Double click the tray icon to see double click message\n" );
197+ printf ("- Use menu items to interact with the application\n" );
198+ printf ("- Click 'Exit' to quit\n" );
199+ printf ("\nRunning... (Press Ctrl+C to force quit)\n" );
200+
201+ // Simple event loop (in a real application, you'd use the platform's event loop)
202+ // This is just to keep the program running so the tray icon stays active
203+ while (1 ) {
204+ // In a real application, you would handle events here
205+ // For this demo, we'll just sleep and let the system handle tray events
206+
207+ #ifdef _WIN32
208+ Sleep (1000 ); // Windows - sleep for 1000ms
209+ #else
210+ sleep (1 ); // Unix/Linux/macOS - sleep for 1 second
211+ #endif
212+ }
213+
214+ // Cleanup (this won't be reached due to the infinite loop above)
215+ native_tray_icon_destroy (tray_icon );
216+ native_menu_destroy (menu );
217+ if (submenu ) {
218+ native_menu_destroy (submenu );
219+ }
220+
221+ return 0 ;
222+ }
0 commit comments