Skip to content

Commit c8a68aa

Browse files
committed
feat: Introduce Rectangle struct and expand Window class with comprehensive window management methods for macOS
1 parent 787b96c commit c8a68aa

File tree

3 files changed

+325
-19
lines changed

3 files changed

+325
-19
lines changed

src/geometry.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ struct Point {
1414
* Size is a 2D size in the coordinate system.
1515
*/
1616
struct Size {
17+
double width;
18+
double height;
19+
};
20+
21+
/**
22+
* Rectangle is a 2D rectangle in the coordinate system.
23+
*/
24+
struct Rectangle {
25+
double x;
26+
double y;
1727
double height;
1828
double width;
1929
};

src/window.h

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace nativeapi {
66

7-
typedef int32_t WindowID;
7+
typedef long WindowID;
88

99
class Window {
1010
public:
@@ -14,8 +14,60 @@ class Window {
1414

1515
WindowID id;
1616

17-
void* GetNSWindow() const;
17+
void Focus();
18+
void Blur();
19+
bool IsFocused() const;
20+
void Show();
21+
void Hide();
22+
bool IsVisible() const;
23+
void Maximize();
24+
void Unmaximize();
25+
bool IsMaximized() const;
26+
void Minimize();
27+
void Restore();
28+
bool IsMinimized() const;
29+
void SetFullScreen(bool is_full_screen);
30+
bool IsFullScreen() const;
31+
// void SetBackgroundColor(Color color);
32+
// Color GetBackgroundColor() const;
33+
void SetBounds(Rectangle bounds);
34+
Rectangle GetBounds() const;
35+
void SetSize(Size size);
1836
Size GetSize() const;
37+
void SetContentSize(Size size);
38+
Size GetContentSize() const;
39+
void SetMinimumSize(Size size);
40+
Size GetMinimumSize();
41+
void SetMaximumSize(Size size);
42+
Size GetMaximumSize();
43+
void SetResizable(bool is_resizable);
44+
bool IsResizable() const;
45+
void SetMovable(bool is_movable);
46+
bool IsMovable() const;
47+
void SetMinimizable(bool is_minimizable);
48+
bool IsMinimizable() const;
49+
void SetMaximizable(bool is_maximizable);
50+
bool IsMaximizable() const;
51+
void SetFullScreenable(bool is_full_screenable);
52+
bool IsFullScreenable() const;
53+
void SetClosable(bool is_closable);
54+
bool IsClosable() const;
55+
void SetAlwaysOnTop(bool is_always_on_top);
56+
bool IsAlwaysOnTop();
57+
void SetPosition(Point point);
58+
Point GetPosition();
59+
void SetTitle(std::string title);
60+
std::string GetTitle();
61+
void SetHasShadow(bool has_shadow);
62+
bool HasShadow() const;
63+
void SetOpacity(float opacity);
64+
float GetOpacity() const;
65+
void SetFocusable(bool is_focusable);
66+
bool IsFocusable() const;
67+
void StartDragging();
68+
void StartResizing();
69+
70+
void* GetNSWindow() const;
1971

2072
private:
2173
class Impl;

src/window_macos.mm

Lines changed: 261 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,267 @@
2929
delete pimpl_;
3030
}
3131

32+
void Window::Focus() {
33+
[pimpl_->ns_window_ makeKeyAndOrderFront:nil];
34+
}
35+
36+
void Window::Blur() {
37+
[pimpl_->ns_window_ orderBack:nil];
38+
}
39+
40+
bool Window::IsFocused() const {
41+
return [pimpl_->ns_window_ isKeyWindow];
42+
}
43+
44+
void Window::Show() {
45+
[pimpl_->ns_window_ setIsVisible:YES];
46+
[pimpl_->ns_window_ makeKeyAndOrderFront:nil];
47+
}
48+
49+
void Window::Hide() {
50+
[pimpl_->ns_window_ setIsVisible:NO];
51+
[pimpl_->ns_window_ orderOut:nil];
52+
}
53+
54+
bool Window::IsVisible() const {
55+
return [pimpl_->ns_window_ isVisible];
56+
}
57+
58+
void Window::Maximize() {
59+
if (!IsMaximized()) {
60+
[pimpl_->ns_window_ zoom:nil];
61+
}
62+
}
63+
64+
void Window::Unmaximize() {
65+
if (IsMaximized()) {
66+
[pimpl_->ns_window_ zoom:nil];
67+
}
68+
}
69+
70+
bool Window::IsMaximized() const {
71+
return [pimpl_->ns_window_ isZoomed];
72+
}
73+
74+
void Window::Minimize() {
75+
if (!IsMinimized()) {
76+
[pimpl_->ns_window_ miniaturize:nil];
77+
}
78+
}
79+
80+
void Window::Restore() {
81+
if (IsMinimized()) {
82+
[pimpl_->ns_window_ deminiaturize:nil];
83+
}
84+
}
85+
86+
bool Window::IsMinimized() const {
87+
return [pimpl_->ns_window_ isMiniaturized];
88+
}
89+
90+
void Window::SetFullScreen(bool is_full_screen) {
91+
if (is_full_screen) {
92+
if (!IsFullScreen()) {
93+
[pimpl_->ns_window_ toggleFullScreen:nil];
94+
}
95+
} else {
96+
if (IsFullScreen()) {
97+
[pimpl_->ns_window_ toggleFullScreen:nil];
98+
}
99+
}
100+
}
101+
102+
bool Window::IsFullScreen() const {
103+
return [pimpl_->ns_window_ styleMask] & NSFullScreenWindowMask;
104+
}
105+
106+
//// void Window::SetBackgroundColor(Color color);
107+
//// Color Window::GetBackgroundColor() const;
108+
109+
void Window::SetBounds(Rectangle bounds) {
110+
[pimpl_->ns_window_ setFrame:NSMakeRect(bounds.x, bounds.y, bounds.width, bounds.height)
111+
display:YES];
112+
}
113+
114+
Rectangle Window::GetBounds() const {
115+
NSRect frame = [pimpl_->ns_window_ frame];
116+
Rectangle bounds = {static_cast<double>(frame.origin.x), static_cast<double>(frame.origin.y),
117+
static_cast<double>(frame.size.height),
118+
static_cast<double>(frame.size.width)};
119+
return bounds;
120+
}
121+
122+
void Window::SetSize(Size size) {
123+
[pimpl_->ns_window_ setFrame:NSMakeRect(0, 0, size.width, size.height) display:YES];
124+
}
125+
126+
Size Window::GetSize() const {
127+
NSRect frame = [pimpl_->ns_window_ frame];
128+
Size size = {static_cast<double>(frame.size.width), static_cast<double>(frame.size.height)};
129+
return size;
130+
}
131+
132+
void Window::SetContentSize(Size size) {
133+
[pimpl_->ns_window_ setContentSize:NSMakeSize(size.width, size.height)];
134+
}
135+
136+
Size Window::GetContentSize() const {
137+
NSRect frame = [pimpl_->ns_window_ contentRectForFrameRect:[pimpl_->ns_window_ frame]];
138+
Size size = {static_cast<double>(frame.size.width), static_cast<double>(frame.size.height)};
139+
return size;
140+
}
141+
142+
void Window::SetMinimumSize(Size size) {
143+
[pimpl_->ns_window_ setMinSize:NSMakeSize(size.width, size.height)];
144+
}
145+
146+
Size Window::GetMinimumSize() {
147+
NSSize size = [pimpl_->ns_window_ minSize];
148+
return Size{static_cast<double>(size.width), static_cast<double>(size.height)};
149+
}
150+
151+
void Window::SetMaximumSize(Size size) {
152+
[pimpl_->ns_window_ setMaxSize:NSMakeSize(size.width, size.height)];
153+
}
154+
155+
Size Window::GetMaximumSize() {
156+
NSSize size = [pimpl_->ns_window_ maxSize];
157+
return Size{static_cast<double>(size.width), static_cast<double>(size.height)};
158+
}
159+
160+
void Window::SetResizable(bool is_resizable) {
161+
NSUInteger style_mask = [pimpl_->ns_window_ styleMask];
162+
if (is_resizable) {
163+
style_mask |= NSResizableWindowMask;
164+
} else {
165+
style_mask &= ~NSResizableWindowMask;
166+
}
167+
[pimpl_->ns_window_ setStyleMask:style_mask];
168+
}
169+
170+
bool Window::IsResizable() const {
171+
return [pimpl_->ns_window_ styleMask] & NSResizableWindowMask;
172+
}
173+
174+
void Window::SetMovable(bool is_movable) {
175+
[pimpl_->ns_window_ setMovable:is_movable];
176+
}
177+
178+
bool Window::IsMovable() const {
179+
return [pimpl_->ns_window_ isMovable];
180+
}
181+
182+
void Window::SetMinimizable(bool is_minimizable) {
183+
NSUInteger style_mask = [pimpl_->ns_window_ styleMask];
184+
if (is_minimizable) {
185+
style_mask |= NSWindowStyleMaskMiniaturizable;
186+
} else {
187+
style_mask &= ~NSWindowStyleMaskMiniaturizable;
188+
}
189+
[pimpl_->ns_window_ setStyleMask:style_mask];
190+
}
191+
192+
bool Window::IsMinimizable() const {
193+
return [pimpl_->ns_window_ styleMask] & NSWindowStyleMaskMiniaturizable;
194+
}
195+
196+
void Window::SetMaximizable(bool is_maximizable) {
197+
NSUInteger style_mask = [pimpl_->ns_window_ styleMask];
198+
if (is_maximizable) {
199+
style_mask |= NSWindowStyleMaskResizable;
200+
} else {
201+
style_mask &= ~NSWindowStyleMaskResizable;
202+
}
203+
[pimpl_->ns_window_ setStyleMask:style_mask];
204+
}
205+
206+
bool Window::IsMaximizable() const {
207+
return [pimpl_->ns_window_ styleMask] & NSWindowStyleMaskResizable;
208+
}
209+
210+
void Window::SetFullScreenable(bool is_full_screenable) {
211+
// TODO: Implement this
212+
}
213+
214+
bool Window::IsFullScreenable() const {
215+
return [pimpl_->ns_window_ styleMask] & NSFullScreenWindowMask;
216+
}
217+
218+
void Window::SetClosable(bool is_closable) {
219+
NSUInteger style_mask = [pimpl_->ns_window_ styleMask];
220+
if (is_closable) {
221+
style_mask |= NSClosableWindowMask;
222+
} else {
223+
style_mask &= ~NSClosableWindowMask;
224+
}
225+
[pimpl_->ns_window_ setStyleMask:style_mask];
226+
}
227+
228+
bool Window::IsClosable() const {
229+
return [pimpl_->ns_window_ styleMask] & NSClosableWindowMask;
230+
}
231+
232+
void Window::SetAlwaysOnTop(bool is_always_on_top) {
233+
[pimpl_->ns_window_ setLevel:is_always_on_top ? NSFloatingWindowLevel : NSNormalWindowLevel];
234+
}
235+
236+
bool Window::IsAlwaysOnTop() {
237+
return [pimpl_->ns_window_ level] == NSFloatingWindowLevel;
238+
}
239+
240+
void Window::SetPosition(Point point) {
241+
[pimpl_->ns_window_ setFrameOrigin:NSMakePoint(point.x, point.y)];
242+
}
243+
244+
Point Window::GetPosition() {
245+
NSRect frame = [pimpl_->ns_window_ frame];
246+
Point point = {static_cast<double>(frame.origin.x), static_cast<double>(frame.origin.y)};
247+
return point;
248+
}
249+
250+
void Window::SetTitle(std::string title) {
251+
[pimpl_->ns_window_ setTitle:[NSString stringWithUTF8String:title.c_str()]];
252+
}
253+
254+
std::string Window::GetTitle() {
255+
NSString* title = [pimpl_->ns_window_ title];
256+
return title ? std::string([title UTF8String]) : std::string();
257+
}
258+
259+
void Window::SetHasShadow(bool has_shadow) {
260+
[pimpl_->ns_window_ setHasShadow:has_shadow];
261+
[pimpl_->ns_window_ invalidateShadow];
262+
}
263+
264+
bool Window::HasShadow() const {
265+
return [pimpl_->ns_window_ hasShadow];
266+
}
267+
268+
void Window::SetOpacity(float opacity) {
269+
[pimpl_->ns_window_ setAlphaValue:opacity];
270+
}
271+
272+
float Window::GetOpacity() const {
273+
return [pimpl_->ns_window_ alphaValue];
274+
}
275+
276+
void Window::SetFocusable(bool is_focusable) {
277+
// TODO: Implement this
278+
}
279+
280+
bool Window::IsFocusable() const {
281+
return [pimpl_->ns_window_ canBecomeKeyWindow];
282+
}
283+
284+
void Window::StartDragging() {
285+
NSWindow* window = pimpl_->ns_window_;
286+
if (window.currentEvent) {
287+
[window performWindowDragWithEvent:window.currentEvent];
288+
}
289+
}
290+
291+
void Window::StartResizing() {}
292+
32293
void* Window::GetNSWindow() const {
33294
if (!pimpl_) {
34295
std::cout << "GetNSWindow: pimpl_ is null" << std::endl;
@@ -42,21 +303,4 @@
42303
return (__bridge void*)pimpl_->ns_window_;
43304
}
44305

45-
Size Window::GetSize() const {
46-
Size size = {0, 0};
47-
if (!pimpl_) {
48-
std::cout << "GetSize: pimpl_ is null" << std::endl;
49-
return size;
50-
}
51-
if (!pimpl_->ns_window_) {
52-
std::cout << "GetSize: ns_window_ is null" << std::endl;
53-
return size;
54-
}
55-
NSRect frame = [pimpl_->ns_window_ frame];
56-
size.width = static_cast<int>(frame.size.width);
57-
size.height = static_cast<int>(frame.size.height);
58-
std::cout << "GetSize: window size is " << size.width << "x" << size.height << std::endl;
59-
return size;
60-
}
61-
62306
} // namespace nativeapi

0 commit comments

Comments
 (0)