use crate::event::{MenuEvents, ScrollEvents, WindowEvents, WxEvtHandler};
use crate::geometry::{Point, Size};
use crate::id::Id;
use crate::window::{WindowHandle, WxWidget};
use wxdragon_sys as ffi;
widget_style_enum!(
name: ScrolledWindowStyle,
doc: "Style flags for ScrolledWindow",
variants: {
Default: 0, "Default style.",
HScroll: ffi::WXD_HSCROLL, "Includes horizontal scrollbar.",
VScroll: ffi::WXD_VSCROLL, "Includes vertical scrollbar."
},
default_variant: Default
);
pub struct ScrollBarConfig {
pub pixels_per_unit_x: i32,
pub pixels_per_unit_y: i32,
pub no_units_x: i32,
pub no_units_y: i32,
pub x_pos: i32,
pub y_pos: i32,
pub no_refresh: bool,
}
#[derive(Clone, Copy)]
pub struct ScrolledWindow {
handle: WindowHandle,
}
impl ScrolledWindow {
pub fn builder(parent: &dyn WxWidget) -> ScrolledWindowBuilder<'_> {
ScrolledWindowBuilder::new(parent)
}
pub(crate) unsafe fn from_ptr(ptr: *mut ffi::wxd_ScrolledWindow_t) -> Self {
assert!(!ptr.is_null());
ScrolledWindow {
handle: WindowHandle::new(ptr as *mut ffi::wxd_Window_t),
}
}
pub fn as_ptr(&self) -> *mut ffi::wxd_ScrolledWindow_t {
self.handle
.get_ptr()
.map(|p| p as *mut ffi::wxd_ScrolledWindow_t)
.unwrap_or(std::ptr::null_mut())
}
#[inline]
fn scrolled_window_ptr(&self) -> *mut ffi::wxd_ScrolledWindow_t {
self.handle
.get_ptr()
.map(|p| p as *mut ffi::wxd_ScrolledWindow_t)
.unwrap_or(std::ptr::null_mut())
}
pub fn window_handle(&self) -> WindowHandle {
self.handle
}
pub fn set_scroll_rate(&self, x_step: i32, y_step: i32) {
let ptr = self.scrolled_window_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_ScrolledWindow_SetScrollRate(ptr, x_step, y_step) }
}
pub fn set_scrollbars(&self, config: ScrollBarConfig) {
let ptr = self.scrolled_window_ptr();
if ptr.is_null() {
return;
}
unsafe {
ffi::wxd_ScrolledWindow_SetScrollbars(
ptr,
config.pixels_per_unit_x,
config.pixels_per_unit_y,
config.no_units_x,
config.no_units_y,
config.x_pos,
config.y_pos,
config.no_refresh,
)
}
}
pub fn enable_scrolling(&self, x_scrolling: bool, y_scrolling: bool) {
let ptr = self.scrolled_window_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_ScrolledWindow_EnableScrolling(ptr, x_scrolling, y_scrolling) }
}
pub fn scroll_coords(&self, x: i32, y: i32) {
let ptr = self.scrolled_window_ptr();
if ptr.is_null() {
return;
}
unsafe { ffi::wxd_ScrolledWindow_Scroll_Coord(ptr, x, y) }
}
pub fn scroll_point(&self, pt: Point) {
let ptr = self.scrolled_window_ptr();
if ptr.is_null() {
return;
}
let c_pt = ffi::wxd_Point { x: pt.x, y: pt.y };
unsafe { ffi::wxd_ScrolledWindow_Scroll_Point(ptr, c_pt) }
}
pub fn get_virtual_size(&self) -> Size {
let ptr = self.scrolled_window_ptr();
if ptr.is_null() {
return Size { width: 0, height: 0 };
}
let mut w: i32 = 0;
let mut h: i32 = 0;
unsafe { ffi::wxd_ScrolledWindow_GetVirtualSize(ptr, &mut w, &mut h) };
Size { width: w, height: h }
}
pub fn get_scroll_pixels_per_unit(&self) -> (i32, i32) {
let ptr = self.scrolled_window_ptr();
if ptr.is_null() {
return (0, 0);
}
let mut x_unit: i32 = 0;
let mut y_unit: i32 = 0;
unsafe { ffi::wxd_ScrolledWindow_GetScrollPixelsPerUnit(ptr, &mut x_unit, &mut y_unit) };
(x_unit, y_unit)
}
}
impl WxWidget for ScrolledWindow {
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()
}
}
impl WxEvtHandler for ScrolledWindow {
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
}
}
impl WindowEvents for ScrolledWindow {}
impl MenuEvents for ScrolledWindow {}
impl crate::scrollable::WxScrollable for ScrolledWindow {}
widget_builder!(
name: ScrolledWindow,
parent_type: &'a dyn WxWidget,
style_type: ScrolledWindowStyle,
fields: {},
build_impl: |slf| {
let scrolled_window_ptr = unsafe {
ffi::wxd_ScrolledWindow_Create(
slf.parent.handle_ptr(),
slf.id,
slf.pos.into(),
slf.size.into(),
slf.style.bits() as ffi::wxd_Style_t,
)
};
if scrolled_window_ptr.is_null() {
panic!("Failed to create ScrolledWindow: FFI returned null pointer.");
}
unsafe { ScrolledWindow::from_ptr(scrolled_window_ptr) }
}
);
impl ScrollEvents for ScrolledWindow {}
#[cfg(feature = "xrc")]
impl crate::xrc::XrcSupport for ScrolledWindow {
unsafe fn from_xrc_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
ScrolledWindow {
handle: WindowHandle::new(ptr),
}
}
}
impl crate::window::FromWindowWithClassName for ScrolledWindow {
fn class_name() -> &'static str {
"wxScrolledWindow"
}
unsafe fn from_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
ScrolledWindow {
handle: WindowHandle::new(ptr),
}
}
}