Skip to content

Commit 4a57820

Browse files
committed
feat: Integrate BroadcastCenter and DisplayManager with event handling in nswindow_example
1 parent 348eac7 commit 4a57820

File tree

10 files changed

+300
-20
lines changed

10 files changed

+300
-20
lines changed

examples/nswindow_example/main.mm

+41-11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
#include <iostream>
44
#include "nativeapi.h"
55

6+
using nativeapi::BroadcastCenter;
7+
using nativeapi::BroadcastEventHandler;
8+
using nativeapi::Display;
9+
using nativeapi::DisplayEventHandler;
10+
using nativeapi::DisplayManager;
611
using nativeapi::Tray;
712
using nativeapi::TrayManager;
813
using nativeapi::Window;
@@ -36,6 +41,32 @@ - (void)applicationDidFinishLaunching:(NSNotification*)notification {
3641
NSLog(@"所有窗口: %@", NSApp.windows);
3742
});
3843

44+
45+
DisplayManager displayManager = DisplayManager();
46+
47+
DisplayEventHandler displayEventHandler = DisplayEventHandler(
48+
[](const Display& display) {
49+
std::cout << "Display added: " << display.id << std::endl;
50+
},
51+
[](const Display& display) {
52+
std::cout << "Display removed: " << display.id << std::endl;
53+
});
54+
displayManager.AddListener(&displayEventHandler);
55+
56+
std::shared_ptr<BroadcastCenter> broadcastCenter = std::make_shared<BroadcastCenter>();
57+
58+
BroadcastEventHandler broadcastEventHandler =
59+
BroadcastEventHandler([](const std::string& message) {
60+
std::cout << "Received broadcast: " << message << std::endl;
61+
});
62+
63+
broadcastCenter->RegisterReceiver("com.example.myNotification", &broadcastEventHandler);
64+
65+
// broadcastCenter.RegisterReceiver(
66+
// BroadcastEventHandler ([&](const std::string& message) {
67+
// std::cout << "Received broadcast: " << message << std::endl;
68+
// }));
69+
3970
[[NSNotificationCenter defaultCenter]
4071
addObserverForName:NSWindowDidBecomeMainNotification
4172
object:nil
@@ -71,18 +102,17 @@ - (void)applicationDidFinishLaunching:(NSNotification*)notification {
71102
<< std::endl;
72103
}
73104

105+
TrayManager trayManager = TrayManager();
74106

75-
TrayManager trayManager = TrayManager();
76-
77-
std::shared_ptr<Tray> newTrayPtr = trayManager.Create();
78-
if (newTrayPtr != nullptr) {
79-
Tray& newTray = *newTrayPtr;
80-
newTray.SetTitle("Hello, World!");
81-
std::cout << "Tray ID: " << newTray.id << std::endl;
82-
std::cout << "Tray Title: " << newTray.GetTitle() << std::endl;
83-
} else {
84-
std::cerr << "Failed to create tray." << std::endl;
85-
}
107+
std::shared_ptr<Tray> newTrayPtr = trayManager.Create();
108+
if (newTrayPtr != nullptr) {
109+
Tray& newTray = *newTrayPtr;
110+
newTray.SetTitle("Hello, World!");
111+
std::cout << "Tray ID: " << newTray.id << std::endl;
112+
std::cout << "Tray Title: " << newTray.GetTitle() << std::endl;
113+
} else {
114+
std::cerr << "Failed to create tray." << std::endl;
115+
}
86116
}];
87117
}
88118

include/nativeapi.h

+2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#pragma once
22

3+
#include "../src/broadcast_center.h"
34
#include "../src/display.h"
45
#include "../src/display_manager.h"
56
#include "../src/geometry.h"
7+
#include "../src/menu.h"
68
#include "../src/tray.h"
79
#include "../src/tray_manager.h"
810
#include "../src/window.h"

src/broadcast_center.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <iostream>
2+
3+
#include "broadcast_center.h"
4+
5+
namespace nativeapi {
6+
7+
BroadcastCenter::BroadcastCenter() {
8+
std::cout << "BroadcastCenter::BroadcastCenter()" << std::endl;
9+
};
10+
11+
BroadcastCenter::~BroadcastCenter() {
12+
std::cout << "BroadcastCenter::~BroadcastCenter()" << std::endl;
13+
};
14+
15+
void BroadcastCenter::NotifyReceivers(
16+
const std::string& topic,
17+
std::function<void(BroadcastReceiver*)> callback) {
18+
for (const auto& receiver : receivers_) {
19+
callback(receiver);
20+
}
21+
}
22+
23+
BroadcastEventHandler::BroadcastEventHandler(
24+
std::function<void(const std::string& message)> onBroadcastReceivedCallback)
25+
: onBroadcastReceivedCallback_(std::move(onBroadcastReceivedCallback)) {}
26+
27+
void BroadcastEventHandler::OnBroadcastReceived(const std::string& message) {
28+
if (onBroadcastReceivedCallback_) {
29+
onBroadcastReceivedCallback_(message);
30+
}
31+
}
32+
33+
} // namespace nativeapi

src/broadcast_center.h

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <functional>
5+
#include <map>
6+
#include <vector>
7+
8+
#include "display.h"
9+
#include "geometry.h"
10+
11+
namespace nativeapi {
12+
13+
// BroadcastReceiver is an interface that can be implemented by classes that
14+
// want to listen for broadcasts.
15+
class BroadcastReceiver {
16+
public:
17+
virtual void OnBroadcastReceived(const std::string& message) = 0;
18+
};
19+
20+
// BroadcastCenter is a singleton that manages all broadcasts on the system.
21+
class BroadcastCenter {
22+
public:
23+
BroadcastCenter();
24+
virtual ~BroadcastCenter();
25+
26+
// Register a receiver to the broadcast center
27+
void RegisterReceiver(const std::string& topic, BroadcastReceiver* receiver);
28+
29+
// Unregister a receiver from the broadcast center
30+
void UnregisterReceiver(const std::string& topic,
31+
BroadcastReceiver* receiver);
32+
33+
// Notify all receivers of a given topic
34+
void NotifyReceivers(const std::string& topic,
35+
std::function<void(BroadcastReceiver*)> callback);
36+
37+
private:
38+
std::vector<BroadcastReceiver*> receivers_;
39+
};
40+
41+
// BroadcastEventHandler is an implementation of BroadcastReceiver that uses
42+
// callbacks to handle broadcast events.
43+
class BroadcastEventHandler : public BroadcastReceiver {
44+
public:
45+
// Constructor that takes callbacks for broadcast events
46+
BroadcastEventHandler(std::function<void(const std::string& message)>
47+
onBroadcastReceivedCallback);
48+
49+
// Implementation of OnBroadcastReceive from BroadcastReceiver interface
50+
void OnBroadcastReceived(const std::string& message) override;
51+
52+
private:
53+
std::function<void(const std::string&)> onBroadcastReceivedCallback_;
54+
};
55+
56+
} // namespace nativeapi

src/broadcast_center_macos.mm

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <map>
2+
#include <memory>
3+
#include <string>
4+
#include <vector>
5+
6+
#include "broadcast_center.h"
7+
8+
// Import Cocoa headers
9+
#import <Cocoa/Cocoa.h>
10+
11+
namespace nativeapi {
12+
13+
// Static map to store BroadcastCenter instances
14+
static std::map<BroadcastCenter*, std::string> g_broadcast_centers;
15+
16+
void BroadcastCenter::RegisterReceiver(const std::string& topic, BroadcastReceiver* receiver) {
17+
receivers_.push_back(receiver);
18+
19+
NSDistributedNotificationCenter* center = [NSDistributedNotificationCenter defaultCenter];
20+
[center addObserverForName:[NSString stringWithUTF8String:topic.c_str()]
21+
object:nil
22+
queue:[NSOperationQueue mainQueue]
23+
usingBlock:^(NSNotification* notification) {
24+
std::string message = [notification.userInfo[@"message"] UTF8String];
25+
receiver->OnBroadcastReceived(message);
26+
}];
27+
}
28+
29+
void BroadcastCenter::UnregisterReceiver(const std::string& topic, BroadcastReceiver* receiver) {}
30+
31+
} // namespace nativeapi

src/menu.h

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
#include <string>
3+
#include "geometry.h"
4+
5+
namespace nativeapi {
6+
7+
typedef long MenuItemID;
8+
9+
class MenuItem {
10+
public:
11+
MenuItem();
12+
MenuItem(void* menu_item);
13+
virtual ~MenuItem();
14+
15+
MenuItemID id;
16+
17+
void SetIcon(std::string icon);
18+
std::string GetIcon();
19+
20+
void SetTitle(std::string title);
21+
std::string GetTitle();
22+
23+
void SetTooltip(std::string tooltip);
24+
std::string GetTooltip();
25+
26+
private:
27+
class Impl;
28+
Impl* pimpl_;
29+
};
30+
31+
typedef long MenuID;
32+
33+
class Menu {
34+
public:
35+
Menu();
36+
Menu(void* menu);
37+
virtual ~Menu();
38+
39+
MenuID id;
40+
41+
void AddItem(MenuItem item);
42+
void RemoveItem(MenuItem item);
43+
44+
private:
45+
class Impl;
46+
Impl* pimpl_;
47+
};
48+
49+
} // namespace nativeapi

src/menu_macos.mm

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include <iostream>
2+
#include "menu.h"
3+
4+
// Import Cocoa headers
5+
#import <Cocoa/Cocoa.h>
6+
7+
namespace nativeapi {
8+
9+
// Private implementation class
10+
class MenuItem::Impl {
11+
public:
12+
Impl(NSMenuItem* menu_item) : ns_menu_item_(menu_item) {}
13+
NSMenuItem* ns_menu_item_;
14+
};
15+
16+
MenuItem::MenuItem() : pimpl_(new Impl(nil)) {
17+
id = -1;
18+
}
19+
20+
MenuItem::MenuItem(void* menu_item) : pimpl_(new Impl((__bridge NSMenuItem*)menu_item)) {
21+
id = 0;
22+
}
23+
24+
MenuItem::~MenuItem() {
25+
delete pimpl_;
26+
}
27+
28+
void MenuItem::SetTitle(std::string title) {
29+
[pimpl_->ns_menu_item_ setTitle:[NSString stringWithUTF8String:title.c_str()]];
30+
}
31+
32+
std::string MenuItem::GetTitle() {
33+
return [[pimpl_->ns_menu_item_ title] UTF8String];
34+
}
35+
36+
// Private implementation class
37+
class Menu::Impl {
38+
public:
39+
Impl(NSMenu* menu) : ns_menu_(menu) {}
40+
NSMenu* ns_menu_;
41+
};
42+
43+
Menu::Menu() : pimpl_(new Impl(nil)) {
44+
id = -1;
45+
}
46+
47+
Menu::Menu(void* menu) : pimpl_(new Impl((__bridge NSMenu*)menu)) {
48+
id = 0;
49+
}
50+
51+
Menu::~Menu() {
52+
delete pimpl_;
53+
}
54+
55+
void Menu::AddItem(MenuItem item) {
56+
// NSMenuItem* ns_menu_item = (__bridge NSMenuItem*)item.GetNativeMenuItem();
57+
// [pimpl_->ns_menu_ addItem:ns_menu_item];
58+
}
59+
60+
void Menu::RemoveItem(MenuItem item) {
61+
// NSMenuItem* ns_menu_item = (__bridge NSMenuItem*)item.GetNativeMenuItem();
62+
// [pimpl_->ns_menu_ removeItem:ns_menu_item];
63+
}
64+
65+
66+
} // namespace nativeapi

src/tray.h

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
#include <string>
33
#include "geometry.h"
4+
#include "menu.h"
45

56
namespace nativeapi {
67

@@ -22,6 +23,9 @@ class Tray {
2223
void SetTooltip(std::string tooltip);
2324
std::string GetTooltip();
2425

26+
void SetContextMenu(Menu menu);
27+
// Menu GetContextMenu();
28+
2529
Rectangle GetBounds();
2630

2731
private:

src/tray_macos.mm

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <iostream>
2+
#include "menu.h"
23
#include "tray.h"
34

45
// Import Cocoa headers
@@ -62,7 +63,7 @@
6263
}
6364

6465
std::string Tray::GetTitle() {
65-
return [pimpl_->ns_status_item_.title UTF8String];
66+
return [[pimpl_->ns_status_item_.button title] UTF8String];
6667
}
6768

6869
void Tray::SetTooltip(std::string tooltip) {
@@ -73,4 +74,12 @@
7374
return [[pimpl_->ns_status_item_.button toolTip] UTF8String];
7475
}
7576

77+
void Tray::SetContextMenu(Menu menu) {
78+
// NSMenu* ns_menu = (__bridge NSMenu*)menu.GetNativeMenu();
79+
// [pimpl_->ns_status_item_.button setMenu:ns_menu];
80+
}
81+
82+
// Menu Tray::GetContextMenu() {
83+
// return Menu((__bridge void*)pimpl_->ns_status_item_.button.menu);
84+
// }
7685
} // namespace nativeapi

0 commit comments

Comments
 (0)