1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use windows_sys::Win32::Foundation::HWND;
use windows_sys::Win32::UI::WindowsAndMessaging::{SetWindowPos, SWP_NOZORDER};
/// A zero-cost immediate mode layout helper.
///
/// Designed to eliminate manual pixel calculations in `on_resize`.
/// Optimized for horizontal bars (like ActionPanel).
pub struct LayoutRow {
y: i32,
height: i32,
padding: i32,
current_x: i32,
}
impl LayoutRow {
/// Starts a new horizontal layout row.
pub fn new(x: i32, y: i32, height: i32, padding: i32) -> Self {
Self {
y,
height,
padding,
current_x: x,
}
}
/// Extends the layout from the right side (Right-to-Left), useful for "Cancel/Ok" buttons.
pub fn new_rtl(right: i32, y: i32, height: i32, padding: i32) -> Self {
Self {
y,
height,
padding,
current_x: right,
}
}
/// Adds a fixed-width control to the layout (Left-to-Right).
pub unsafe fn add_fixed(&mut self, hwnd: HWND, width: i32) {
if hwnd.is_null() { return; }
unsafe {
SetWindowPos(
hwnd,
std::ptr::null_mut(),
self.current_x,
self.y,
width,
self.height,
SWP_NOZORDER,
);
}
self.current_x += width + self.padding;
}
/// Adds a fixed-width control to the layout (Right-to-Left).
/// `self.current_x` acts as the right edge.
pub unsafe fn add_fixed_rtl(&mut self, hwnd: HWND, width: i32) {
if hwnd.is_null() { return; }
let left = self.current_x - width;
unsafe {
SetWindowPos(
hwnd,
std::ptr::null_mut(),
left,
self.y,
width,
self.height,
SWP_NOZORDER,
);
}
self.current_x = left - self.padding;
}
/// Positions a label above the current slot (helper for ActionPanel labels).
pub unsafe fn add_label_above(&self, hwnd: HWND, width: i32, label_height: i32, offset_y: i32) {
if hwnd.is_null() { return; }
// Center-ish or left aligned to the current slot?
// ActionPanel uses: label is at the same X as the control below it.
unsafe {
SetWindowPos(
hwnd,
std::ptr::null_mut(),
self.current_x,
self.y + offset_y,
width,
label_height,
SWP_NOZORDER,
);
}
}
/// Returns the current X position.
pub fn cursor(&self) -> i32 {
self.current_x
}
}
/// A zero-cost immediate mode vertical layout helper.
///
/// Designed to satisfy `about.rs` vertical stacking needs.
pub struct LayoutColumn {
x: i32,
y: i32,
width: i32,
padding: i32,
}
impl LayoutColumn {
pub fn new(x: i32, y: i32, width: i32, padding: i32) -> Self {
Self { x, y, width, padding }
}
/// Allocates a new row of the given height.
/// Returns (x, y, width, height).
pub fn row(&mut self, height: i32) -> (i32, i32, i32, i32) {
let y = self.y;
self.y += height + self.padding;
(self.x, y, self.width, height)
}
/// Adds vertical spacing.
pub fn add_space(&mut self, space: i32) {
self.y += space;
}
}