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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//!
//! wxStaticBox wrapper
//!
use crate::geometry::{Point, Size};
use crate::id::Id;
use crate::window::{WindowHandle, WxWidget};
// Window is used by XRC support for backwards compatibility
use crate::event::WxEvtHandler;
#[allow(unused_imports)]
use crate::window::Window;
use std::ffi::CString;
use std::os::raw::c_int;
use wxdragon_sys as ffi;
widget_style_enum!(
name: StaticBoxStyle,
doc: "Style flags for the StaticBox widget.",
variants: {
Default: 0, "Default style with no special behavior."
},
default_variant: Default
);
/// Represents the wxStaticBox widget.
///
/// StaticBox uses `WindowHandle` internally for safe memory management.
/// When the underlying window is destroyed (by calling `destroy()` or when
/// its parent is destroyed), the handle becomes invalid and all operations
/// become safe no-ops.
///
/// # Example
/// ```ignore
/// let staticbox = StaticBox::builder(&frame).label("Group").build();
///
/// // StaticBox is Copy - no clone needed for closures!
/// // After parent destruction, staticbox operations are safe no-ops
/// frame.destroy();
/// assert!(!staticbox.is_valid());
/// ```
#[derive(Clone, Copy)]
pub struct StaticBox {
/// Safe handle to the underlying wxStaticBox - automatically invalidated on destroy
handle: WindowHandle,
}
impl StaticBox {
/// Creates a new StaticBox builder.
pub fn builder<W: WxWidget>(parent: &W) -> StaticBoxBuilder<'_> {
StaticBoxBuilder::new(parent)
}
/// Creates a new StaticBox from a raw pointer.
/// This is intended for internal use by other widget wrappers.
#[allow(dead_code)]
pub(crate) unsafe fn from_ptr(ptr: *mut ffi::wxd_StaticBox_t) -> Self {
StaticBox {
handle: WindowHandle::new(ptr as *mut ffi::wxd_Window_t),
}
}
/// Returns the underlying WindowHandle for this staticbox.
pub fn window_handle(&self) -> WindowHandle {
self.handle
}
}
// Manual WxWidget implementation for StaticBox (using WindowHandle)
impl WxWidget for StaticBox {
fn handle_ptr(&self) -> *mut ffi::wxd_Window_t {
self.handle.get_ptr().unwrap_or(std::ptr::null_mut())
}
fn is_valid(&self) -> bool {
self.handle.is_valid()
}
}
// Implement WxEvtHandler for event binding
impl WxEvtHandler for StaticBox {
unsafe fn get_event_handler_ptr(&self) -> *mut ffi::wxd_EvtHandler_t {
self.handle.get_ptr().unwrap_or(std::ptr::null_mut()) as *mut ffi::wxd_EvtHandler_t
}
}
// Implement common event traits that all Window-based widgets support
impl crate::event::WindowEvents for StaticBox {}
widget_builder!(
name: StaticBox,
parent_type: &'a dyn WxWidget,
style_type: StaticBoxStyle,
fields: {
label: String = String::new()
},
build_impl: |slf| {
let c_label = CString::new(&slf.label[..]).unwrap_or_default();
let ptr = unsafe {
ffi::wxd_StaticBox_Create(
slf.parent.handle_ptr(),
slf.id as c_int,
c_label.as_ptr(),
slf.pos.into(),
slf.size.into(),
slf.style.bits() as ffi::wxd_Style_t,
)
};
if ptr.is_null() {
panic!("Failed to create StaticBox");
}
// Create a WindowHandle which automatically registers for destroy events
StaticBox {
handle: WindowHandle::new(ptr as *mut ffi::wxd_Window_t),
}
}
);
// XRC Support - enables StaticBox to be created from XRC-managed pointers
#[cfg(feature = "xrc")]
impl crate::xrc::XrcSupport for StaticBox {
unsafe fn from_xrc_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
StaticBox {
handle: WindowHandle::new(ptr),
}
}
}
// Enable widget casting for StaticBox
impl crate::window::FromWindowWithClassName for StaticBox {
fn class_name() -> &'static str {
"wxStaticBox"
}
unsafe fn from_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
StaticBox {
handle: WindowHandle::new(ptr),
}
}
}