1+ #include < iostream>
2+ #include < memory>
3+ #include < thread>
4+ #include < chrono>
5+
6+ #include " ../../src/tray_icon.h"
7+ #include " ../../src/tray_manager.h"
8+ #include " ../../src/menu.h"
9+
10+ #ifdef __APPLE__
11+ #import < Cocoa/Cocoa.h>
12+ #endif
13+
14+ using namespace nativeapi ;
15+ using nativeapi::Menu;
16+ using nativeapi::MenuItem;
17+ using nativeapi::MenuItemSelectedEvent;
18+ using nativeapi::MenuItemType;
19+
20+ int main () {
21+ std::cout << " Starting TrayIcon Example..." << std::endl;
22+
23+ #ifdef __APPLE__
24+ // Initialize Cocoa application for macOS
25+ [NSApplication sharedApplication];
26+ [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
27+ #endif
28+
29+ // Get TrayManager instance (singleton pattern)
30+ TrayManager& trayManager = TrayManager::GetInstance ();
31+ if (!trayManager.IsSupported ()) {
32+ std::cerr << " Tray icons are not supported on this platform!" << std::endl;
33+ return 1 ;
34+ }
35+
36+ // Create a tray icon
37+ auto trayIcon = trayManager.Create ();
38+ if (!trayIcon) {
39+ std::cerr << " Failed to create tray icon!" << std::endl;
40+ return 1 ;
41+ }
42+
43+ // Set up the tray icon
44+ trayIcon->SetTitle (" Test App" );
45+ trayIcon->SetTooltip (" This is a test tray icon" );
46+
47+ // Try to set a system icon (using a system-provided icon)
48+ trayIcon->SetIcon (" NSImageNameStatusAvailable" );
49+
50+ // Set up click handlers
51+ trayIcon->SetOnLeftClick ([]() {
52+ std::cout << " *** TRAY ICON LEFT CLICKED! ***" << std::endl;
53+ std::cout << " This is the left click handler working!" << std::endl;
54+ });
55+
56+ trayIcon->SetOnRightClick ([&trayIcon]() {
57+ std::cout << " *** TRAY ICON RIGHT CLICKED! ***" << std::endl;
58+ std::cout << " This is the right click handler working!" << std::endl;
59+ // Context menu will be shown automatically
60+ });
61+
62+ trayIcon->SetOnDoubleClick ([]() {
63+ std::cout << " *** TRAY ICON DOUBLE CLICKED! ***" << std::endl;
64+ std::cout << " This is the double click handler working!" << std::endl;
65+ });
66+
67+ // Create context menu
68+ auto context_menu = Menu::Create ();
69+
70+ // Add menu items
71+ auto status_item = MenuItem::Create (" Status: Running" , MenuItemType::Normal);
72+ status_item->SetOnClick ([](const MenuItemSelectedEvent& event) {
73+ std::cout << " Status clicked from context menu" << std::endl;
74+ });
75+ context_menu->AddItem (status_item);
76+
77+ // Add separator
78+ context_menu->AddSeparator ();
79+
80+ // Add settings item
81+ auto settings_item = MenuItem::Create (" Settings..." , MenuItemType::Normal);
82+ settings_item->SetOnClick ([](const MenuItemSelectedEvent& event) {
83+ std::cout << " Settings clicked from context menu" << std::endl;
84+ std::cout << " Opening settings dialog..." << std::endl;
85+ });
86+ context_menu->AddItem (settings_item);
87+
88+ // Add about item
89+ auto about_item = MenuItem::Create (" About" , MenuItemType::Normal);
90+ about_item->SetOnClick ([](const MenuItemSelectedEvent& event) {
91+ std::cout << " About clicked from context menu" << std::endl;
92+ std::cout << " TrayIcon Example v1.0 - Native API Demo" << std::endl;
93+ });
94+ context_menu->AddItem (about_item);
95+
96+ // Add another separator
97+ context_menu->AddSeparator ();
98+
99+ // Add exit item
100+ auto exit_item = MenuItem::Create (" Exit" , MenuItemType::Normal);
101+ bool * should_exit = new bool (false );
102+ exit_item->SetOnClick ([should_exit](const MenuItemSelectedEvent& event) {
103+ std::cout << " Exit clicked from context menu" << std::endl;
104+ *should_exit = true ;
105+ });
106+ context_menu->AddItem (exit_item);
107+
108+ // Set the context menu to the tray icon
109+ trayIcon->SetContextMenu (context_menu);
110+
111+ // Show the tray icon
112+ if (trayIcon->Show ()) {
113+ std::cout << " Tray icon is now visible!" << std::endl;
114+ } else {
115+ std::cerr << " Failed to show tray icon!" << std::endl;
116+ return 1 ;
117+ }
118+
119+ // Get and display bounds
120+ Rectangle bounds = trayIcon->GetBounds ();
121+ std::cout << " Tray icon bounds: x=" << bounds.x
122+ << " , y=" << bounds.y
123+ << " , width=" << bounds.width
124+ << " , height=" << bounds.height << std::endl;
125+
126+ std::cout << " ========================================" << std::endl;
127+ std::cout << " Tray icon example is now running!" << std::endl;
128+ std::cout << " Try clicking on the tray icon:" << std::endl;
129+ std::cout << " - Left click: Single click" << std::endl;
130+ std::cout << " - Right click: Shows context menu" << std::endl;
131+ std::cout << " - Double click: Quick double click" << std::endl;
132+ std::cout << " - Context menu: Right-click to see options including Exit" << std::endl;
133+ std::cout << " The application will run for 60 seconds, or until you click Exit." << std::endl;
134+ std::cout << " ========================================" << std::endl;
135+
136+ // Keep the application running for 60 seconds or until exit is clicked
137+ int countdown = 60 ;
138+ while (countdown > 0 && !*should_exit) {
139+ std::this_thread::sleep_for (std::chrono::seconds (1 ));
140+ countdown--;
141+
142+ // Check if tray icon is still visible
143+ if (!trayIcon->IsVisible ()) {
144+ std::cout << " Tray icon is no longer visible!" << std::endl;
145+ break ;
146+ }
147+
148+ // Print countdown every 10 seconds
149+ if (countdown % 10 == 0 ) {
150+ std::cout << " Application will exit in " << countdown << " seconds..." << std::endl;
151+ }
152+ }
153+
154+ if (*should_exit) {
155+ std::cout << " Exit requested from context menu." << std::endl;
156+ }
157+
158+ // Hide the tray icon before exiting
159+ trayIcon->Hide ();
160+ std::cout << " Exiting TrayIcon Example..." << std::endl;
161+
162+ // Cleanup
163+ delete should_exit;
164+ return 0 ;
165+ }
0 commit comments