Skip to content

Commit 94cb774

Browse files
committed
Refactor Placement and positioning strategy handling
Moved Placement enum and related documentation from geometry.h to a new placement.h file. Updated includes across the codebase to reference placement.h and positioning_strategy.h from their new locations. Added support for window-relative positioning strategies, including new API functions and logic to dynamically obtain window bounds for positioning. Renamed and relocated positioning_strategy files for improved organization.
1 parent 03938a1 commit 94cb774

File tree

10 files changed

+196
-103
lines changed

10 files changed

+196
-103
lines changed

src/capi/menu_c.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
#include <map>
66
#include <memory>
77
#include <optional>
8-
#include "../foundation/positioning_strategy.h"
8+
#include "../placement.h"
9+
#include "../positioning_strategy.h"
910
#include "../global_registry.h"
1011
#include "../image.h"
1112
#include "../menu.h"

src/capi/positioning_strategy_c.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "positioning_strategy_c.h"
2-
#include "../foundation/positioning_strategy.h"
2+
#include "../positioning_strategy.h"
3+
#include "../window.h"
34

45
using namespace nativeapi;
56

@@ -37,6 +38,23 @@ native_positioning_strategy_t native_positioning_strategy_relative(const native_
3738
return static_cast<native_positioning_strategy_t>(strategy);
3839
}
3940

41+
native_positioning_strategy_t native_positioning_strategy_relative_to_window(native_window_t window,
42+
const native_point_t* offset) {
43+
if (!window) {
44+
return nullptr;
45+
}
46+
47+
auto* win = static_cast<nativeapi::Window*>(window);
48+
nativeapi::Point cpp_offset{0, 0};
49+
if (offset) {
50+
cpp_offset = nativeapi::Point{offset->x, offset->y};
51+
}
52+
53+
PositioningStrategy* strategy =
54+
new PositioningStrategy(PositioningStrategy::Relative(*win, cpp_offset));
55+
return static_cast<native_positioning_strategy_t>(strategy);
56+
}
57+
4058
void native_positioning_strategy_free(native_positioning_strategy_t strategy) {
4159
if (strategy) {
4260
delete static_cast<PositioningStrategy*>(strategy);

src/capi/positioning_strategy_c.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <stdbool.h>
44

55
#include "geometry_c.h"
6+
#include "window_c.h"
67

78
#if _WIN32
89
#define FFI_PLUGIN_EXPORT __declspec(dllexport)
@@ -61,6 +62,27 @@ FFI_PLUGIN_EXPORT
6162
native_positioning_strategy_t native_positioning_strategy_relative(const native_rectangle_t* rect,
6263
const native_point_t* offset);
6364

65+
/**
66+
* Create a positioning strategy for positioning relative to a window
67+
* @param window Window to position relative to
68+
* @param offset Offset point to apply to the position, or NULL for no offset
69+
* @return Positioning strategy handle, or NULL if window is invalid
70+
*
71+
* This function obtains the window's bounds using native_window_get_bounds()
72+
* and creates a Relative positioning strategy based on those bounds.
73+
*
74+
* @example
75+
* ```c
76+
* native_window_t window = native_window_manager_create(&options);
77+
* native_point_t offset = {0, 10};
78+
* native_positioning_strategy_t strategy = native_positioning_strategy_relative_to_window(window,
79+
* &offset); native_menu_open(menu, strategy); native_positioning_strategy_free(strategy);
80+
* ```
81+
*/
82+
FFI_PLUGIN_EXPORT
83+
native_positioning_strategy_t native_positioning_strategy_relative_to_window(native_window_t window,
84+
const native_point_t* offset);
85+
6486
/**
6587
* Free a positioning strategy handle
6688
* @param strategy The positioning strategy to free

src/foundation/geometry.h

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -28,99 +28,4 @@ struct Rectangle {
2828
double height;
2929
};
3030

31-
/**
32-
* @brief Placement options for positioning UI elements relative to an anchor.
33-
*
34-
* Defines how a UI element (such as a menu, tooltip, or popover) should be
35-
* positioned relative to an anchor element or point. The placement consists
36-
* of a primary direction (top, right, bottom, left) and an optional alignment
37-
* (start, center, end).
38-
*
39-
* Primary directions:
40-
* - Top: Element appears above the anchor
41-
* - Right: Element appears to the right of the anchor
42-
* - Bottom: Element appears below the anchor
43-
* - Left: Element appears to the left of the anchor
44-
*
45-
* Alignments:
46-
* - Start: Element aligns to the start edge (left for horizontal, top for vertical)
47-
* - Center: Element centers along the anchor (default if not specified)
48-
* - End: Element aligns to the end edge (right for horizontal, bottom for vertical)
49-
*
50-
* @note Use with PositioningStrategy (defined in positioning_strategy.h) to
51-
* specify both where and how to position UI elements.
52-
*
53-
* @example
54-
* ```cpp
55-
* // Position menu below the button, aligned to the left
56-
* menu->Open(PositioningStrategy::Absolute({100, 100}), Placement::BottomStart);
57-
*
58-
* // Position popover to the right, aligned to the top
59-
* popover->Open(PositioningStrategy::CursorPosition(), Placement::RightStart);
60-
* ```
61-
*
62-
* @see PositioningStrategy
63-
*/
64-
enum class Placement {
65-
/**
66-
* Position above the anchor, horizontally centered.
67-
*/
68-
Top,
69-
70-
/**
71-
* Position above the anchor, aligned to the start (left).
72-
*/
73-
TopStart,
74-
75-
/**
76-
* Position above the anchor, aligned to the end (right).
77-
*/
78-
TopEnd,
79-
80-
/**
81-
* Position to the right of the anchor, vertically centered.
82-
*/
83-
Right,
84-
85-
/**
86-
* Position to the right of the anchor, aligned to the start (top).
87-
*/
88-
RightStart,
89-
90-
/**
91-
* Position to the right of the anchor, aligned to the end (bottom).
92-
*/
93-
RightEnd,
94-
95-
/**
96-
* Position below the anchor, horizontally centered.
97-
*/
98-
Bottom,
99-
100-
/**
101-
* Position below the anchor, aligned to the start (left).
102-
*/
103-
BottomStart,
104-
105-
/**
106-
* Position below the anchor, aligned to the end (right).
107-
*/
108-
BottomEnd,
109-
110-
/**
111-
* Position to the left of the anchor, vertically centered.
112-
*/
113-
Left,
114-
115-
/**
116-
* Position to the left of the anchor, aligned to the start (top).
117-
*/
118-
LeftStart,
119-
120-
/**
121-
* Position to the left of the anchor, aligned to the end (bottom).
122-
*/
123-
LeftEnd
124-
};
125-
12631
} // namespace nativeapi

src/menu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
#include "foundation/geometry.h"
1111
#include "foundation/id_allocator.h"
1212
#include "foundation/native_object_provider.h"
13-
#include "foundation/positioning_strategy.h"
13+
#include "placement.h"
14+
#include "positioning_strategy.h"
1415
#include "menu_event.h"
1516

1617
namespace nativeapi {

src/placement.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#pragma once
2+
3+
namespace nativeapi {
4+
5+
/**
6+
* @brief Placement options for positioning UI elements relative to an anchor.
7+
*
8+
* Defines how a UI element (such as a menu, tooltip, or popover) should be
9+
* positioned relative to an anchor element or point. The placement consists
10+
* of a primary direction (top, right, bottom, left) and an optional alignment
11+
* (start, center, end).
12+
*
13+
* Primary directions:
14+
* - Top: Element appears above the anchor
15+
* - Right: Element appears to the right of the anchor
16+
* - Bottom: Element appears below the anchor
17+
* - Left: Element appears to the left of the anchor
18+
*
19+
* Alignments:
20+
* - Start: Element aligns to the start edge (left for horizontal, top for vertical)
21+
* - Center: Element centers along the anchor (default if not specified)
22+
* - End: Element aligns to the end edge (right for horizontal, bottom for vertical)
23+
*
24+
* @example
25+
* ```cpp
26+
* // Position menu below the button, aligned to the left
27+
* menu->Open(PositioningStrategy::Absolute({100, 100}), Placement::BottomStart);
28+
*
29+
* // Position popover to the right, aligned to the top
30+
* popover->Open(PositioningStrategy::CursorPosition(), Placement::RightStart);
31+
* ```
32+
*/
33+
enum class Placement {
34+
/**
35+
* Position above the anchor, horizontally centered.
36+
*/
37+
Top,
38+
39+
/**
40+
* Position above the anchor, aligned to the start (left).
41+
*/
42+
TopStart,
43+
44+
/**
45+
* Position above the anchor, aligned to the end (right).
46+
*/
47+
TopEnd,
48+
49+
/**
50+
* Position to the right of the anchor, vertically centered.
51+
*/
52+
Right,
53+
54+
/**
55+
* Position to the right of the anchor, aligned to the start (top).
56+
*/
57+
RightStart,
58+
59+
/**
60+
* Position to the right of the anchor, aligned to the end (bottom).
61+
*/
62+
RightEnd,
63+
64+
/**
65+
* Position below the anchor, horizontally centered.
66+
*/
67+
Bottom,
68+
69+
/**
70+
* Position below the anchor, aligned to the start (left).
71+
*/
72+
BottomStart,
73+
74+
/**
75+
* Position below the anchor, aligned to the end (right).
76+
*/
77+
BottomEnd,
78+
79+
/**
80+
* Position to the left of the anchor, vertically centered.
81+
*/
82+
Left,
83+
84+
/**
85+
* Position to the left of the anchor, aligned to the start (top).
86+
*/
87+
LeftStart,
88+
89+
/**
90+
* Position to the left of the anchor, aligned to the end (bottom).
91+
*/
92+
LeftEnd
93+
};
94+
95+
} // namespace nativeapi
96+

src/platform/macos/tray_icon_macos.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <optional>
22
#include "../../foundation/geometry.h"
3-
#include "../../foundation/positioning_strategy.h"
3+
#include "../../positioning_strategy.h"
44
#include "../../image.h"
55
#include "../../menu.h"
66
#include "../../tray_icon.h"

src/platform/windows/tray_icon_windows.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include "../../foundation/geometry.h"
1212
#include "../../foundation/id_allocator.h"
13-
#include "../../foundation/positioning_strategy.h"
13+
#include "../../positioning_strategy.h"
1414
#include "../../image.h"
1515
#include "../../menu.h"
1616
#include "../../tray_icon.h"

src/foundation/positioning_strategy.cpp renamed to src/positioning_strategy.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#include "positioning_strategy.h"
2+
#include "window.h"
23

34
namespace nativeapi {
45

56
PositioningStrategy::PositioningStrategy(Type type)
6-
: type_(type), absolute_position_{0, 0}, relative_rect_{0, 0, 0, 0}, relative_offset_{0, 0} {}
7+
: type_(type), absolute_position_{0, 0}, relative_rect_{0, 0, 0, 0}, relative_offset_{0, 0}, relative_window_(nullptr) {}
78

89
PositioningStrategy PositioningStrategy::Absolute(const Point& point) {
910
PositioningStrategy strategy(Type::Absolute);
@@ -19,7 +20,24 @@ PositioningStrategy PositioningStrategy::Relative(const Rectangle& rect, const P
1920
PositioningStrategy strategy(Type::Relative);
2021
strategy.relative_rect_ = rect;
2122
strategy.relative_offset_ = offset;
23+
strategy.relative_window_ = nullptr;
2224
return strategy;
2325
}
2426

27+
PositioningStrategy PositioningStrategy::Relative(const Window& window, const Point& offset) {
28+
PositioningStrategy strategy(Type::Relative);
29+
strategy.relative_window_ = &window;
30+
strategy.relative_offset_ = offset;
31+
// relative_rect_ will be obtained dynamically in GetRelativeRectangle()
32+
return strategy;
33+
}
34+
35+
Rectangle PositioningStrategy::GetRelativeRectangle() const {
36+
if (relative_window_) {
37+
return relative_window_->GetBounds();
38+
}
39+
return relative_rect_;
40+
}
41+
2542
} // namespace nativeapi
43+

0 commit comments

Comments
 (0)