use crate::enums::{Align, Color, FrameType};
use crate::prelude::*;
use crate::utils::FlString;
use crate::widget::Widget;
use fltk_sys::group::*;
use std::{
ffi::{CStr, CString},
mem,
ops::Range,
sync::atomic::{AtomicBool, Ordering},
};
static DEBUG: AtomicBool = AtomicBool::new(false);
#[derive(Debug)]
pub struct Group {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(Group, Fl_Group);
crate::macros::widget::impl_widget_base!(Group, Fl_Group);
crate::macros::widget::impl_widget_default!(Group);
crate::macros::group::impl_group_ext!(Group, Fl_Group);
impl Group {
#[deprecated(since = "1.2.18", note = "please use `try_current` instead")]
pub fn current() -> Group {
unsafe {
let ptr = Fl_Group_current();
assert!(!ptr.is_null());
Group::from_widget_ptr(ptr as _)
}
}
pub fn try_current() -> Option<Group> {
unsafe {
let ptr = Fl_Group_current();
if ptr.is_null() {
None
} else {
Some(Group::from_widget_ptr(ptr as _))
}
}
}
pub fn set_current(grp: Option<&impl GroupExt>) {
unsafe {
if let Some(grp) = grp {
Fl_Group_set_current(grp.as_widget_ptr() as _)
} else {
Fl_Group_set_current(std::ptr::null_mut())
}
}
}
}
#[derive(Debug)]
pub struct OverlayGroup {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(OverlayGroup, Fl_Overlay_Group);
crate::macros::widget::impl_widget_base!(OverlayGroup, Fl_Overlay_Group);
crate::macros::widget::impl_widget_default!(OverlayGroup);
crate::macros::group::impl_group_ext!(OverlayGroup, Fl_Overlay_Group);
#[derive(Debug)]
pub struct Pack {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(Pack, Fl_Pack);
crate::macros::widget::impl_widget_base!(Pack, Fl_Pack);
crate::macros::widget::impl_widget_default!(Pack);
crate::macros::group::impl_group_ext!(Pack, Fl_Pack);
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum PackType {
Vertical = 0,
Horizontal = 1,
}
crate::macros::widget::impl_widget_type!(PackType);
impl Pack {
pub fn spacing(&self) -> i32 {
unsafe { Fl_Pack_spacing(self.inner.widget() as _) }
}
pub fn set_spacing(&mut self, spacing: i32) {
unsafe {
Fl_Pack_set_spacing(self.inner.widget() as _, spacing);
}
}
pub fn auto_layout(&mut self) {
let children = self.children();
if children == 0 {
return;
}
let spacing = self.spacing() * (children - 1);
let t = self.get_type::<PackType>();
let w = (self.width() - spacing) / children;
let h = (self.height() - spacing) / children;
for i in 0..children {
let mut c = self.child(i).unwrap();
let c_w = c.width();
let c_h = c.height();
if t == PackType::Vertical {
c.set_size(c_w, h);
} else {
c.set_size(w, c_h);
}
}
}
}
#[derive(Debug)]
pub struct Scroll {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(Scroll, Fl_Scroll);
crate::macros::widget::impl_widget_base!(Scroll, Fl_Scroll);
crate::macros::widget::impl_widget_default!(Scroll);
crate::macros::group::impl_group_ext!(Scroll, Fl_Scroll);
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ScrollType {
None = 0,
Horizontal = 1,
Vertical = 2,
Both = 3,
AlwaysOn = 4,
HorizontalAlways = 5,
VerticalAlways = 6,
BothAlways = 7,
}
crate::macros::widget::impl_widget_type!(ScrollType);
impl Scroll {
pub fn scrollbar(&self) -> crate::valuator::Scrollbar {
unsafe {
let ptr = Fl_Scroll_scrollbar(self.inner.widget() as _);
assert!(!ptr.is_null());
crate::valuator::Scrollbar::from_widget_ptr(ptr as *mut fltk_sys::widget::Fl_Widget)
}
}
pub fn hscrollbar(&self) -> crate::valuator::Scrollbar {
unsafe {
let ptr = Fl_Scroll_hscrollbar(self.inner.widget() as _);
assert!(!ptr.is_null());
crate::valuator::Scrollbar::from_widget_ptr(ptr as *mut fltk_sys::widget::Fl_Widget)
}
}
pub fn xposition(&self) -> i32 {
unsafe { Fl_Scroll_xposition(self.inner.widget() as _) }
}
pub fn yposition(&self) -> i32 {
unsafe { Fl_Scroll_yposition(self.inner.widget() as _) }
}
pub fn scroll_to(&mut self, x: i32, y: i32) {
unsafe { Fl_Scroll_scroll_to(self.inner.widget() as _, x, y) }
}
pub fn scrollbar_size(&self) -> i32 {
unsafe { Fl_Scroll_scrollbar_size(self.inner.widget() as _) }
}
pub fn set_scrollbar_size(&mut self, new_size: i32) {
unsafe { Fl_Scroll_set_scrollbar_size(self.inner.widget() as _, new_size) }
}
pub fn auto_layout(&mut self) {
self.resize_callback(|t, x, y, w, h| {
if t.children() == 1 {
if let Some(mut c) = t.child(0) {
c.resize(x, y, w, h);
}
}
});
}
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum TabsOverflow {
Compress = 0,
Clip,
Pulldown,
Drag,
}
#[derive(Debug)]
pub struct Tabs {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(Tabs, Fl_Tabs);
crate::macros::widget::impl_widget_base!(Tabs, Fl_Tabs);
crate::macros::widget::impl_widget_default!(Tabs);
crate::macros::group::impl_group_ext!(Tabs, Fl_Tabs);
impl Tabs {
pub fn value(&self) -> Option<impl GroupExt> {
unsafe {
let ptr = Fl_Tabs_value(self.inner.widget() as _);
if ptr.is_null() {
None
} else {
Some(Group::from_widget_ptr(
ptr as *mut fltk_sys::widget::Fl_Widget,
))
}
}
}
pub fn set_value<Grp: GroupExt>(&mut self, w: &Grp) -> Result<(), FltkError> {
unsafe {
match Fl_Tabs_set_value(
self.inner.widget() as _,
w.as_widget_ptr() as *mut fltk_sys::group::Fl_Widget,
) {
0 => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
_ => Ok(()),
}
}
}
pub fn push(&self) -> Option<impl GroupExt> {
unsafe {
let ptr = Fl_Tabs_push(self.inner.widget() as _);
if ptr.is_null() {
None
} else {
Some(Group::from_widget_ptr(
ptr as *mut fltk_sys::widget::Fl_Widget,
))
}
}
}
pub fn set_push<Grp: GroupExt>(&mut self, w: &Grp) -> Result<(), FltkError> {
unsafe {
match Fl_Tabs_set_push(
self.inner.widget() as _,
w.as_widget_ptr() as *mut fltk_sys::group::Fl_Widget,
) {
0 => Err(FltkError::Internal(FltkErrorKind::FailedOperation)),
_ => Ok(()),
}
}
}
pub fn client_area(&self) -> (i32, i32, i32, i32) {
unsafe {
fltk_sys::fl::Fl_open_display();
let mut i1 = 0;
let mut i2 = 0;
let mut i3 = 0;
let mut i4 = 0;
Fl_Tabs_client_area(self.inner.widget() as _, &mut i1, &mut i2, &mut i3, &mut i4);
(i1, i2, i3, i4)
}
}
pub fn set_tab_align(&mut self, a: Align) {
unsafe { Fl_Tabs_set_tab_align(self.inner.widget() as _, a.bits()) }
}
pub fn tab_align(&self) -> Align {
unsafe { mem::transmute(Fl_Tabs_tab_align(self.inner.widget() as _)) }
}
pub fn auto_layout(&mut self) {
for c in self.clone().into_iter() {
if let Some(mut c) = c.as_group() {
c.resize(self.x(), self.y() + 30, self.w(), self.h() - 30);
}
}
self.resize_callback(|t, x, y, w, h| {
for c in t.clone().into_iter() {
if let Some(mut c) = c.as_group() {
c.resize(x, y + 30, w, h - 30);
}
}
});
}
pub fn handle_overflow(&mut self, ov: TabsOverflow) {
unsafe { Fl_Tabs_handle_overflow(self.inner.widget() as _, ov as i32) }
}
}
#[derive(Debug)]
pub struct Tile {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(Tile, Fl_Tile);
crate::macros::widget::impl_widget_base!(Tile, Fl_Tile);
crate::macros::widget::impl_widget_default!(Tile);
crate::macros::group::impl_group_ext!(Tile, Fl_Tile);
impl Tile {
pub fn move_intersection(&mut self, oldx: i32, oldy: i32, newx: i32, newy: i32) {
unsafe {
Fl_Tile_move_intersection(self.inner.widget() as _, oldx, oldy, newx, newy);
}
}
pub fn size_range_by_index(&mut self, idx: i32, minw: i32, minh: i32, maxw: i32, maxh: i32) {
unsafe {
Fl_Tile_size_range_by_index(self.inner.widget() as _, idx, minw, minh, maxw, maxh)
}
}
pub fn size_range_by_child<W: WidgetExt>(
&mut self,
w: &W,
minw: i32,
minh: i32,
maxw: i32,
maxh: i32,
) {
unsafe {
Fl_Tile_size_range_by_child(
self.inner.widget() as _,
w.as_widget_ptr() as _,
minw,
minh,
maxw,
maxh,
)
}
}
}
#[derive(Debug)]
pub struct Wizard {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(Wizard, Fl_Wizard);
crate::macros::widget::impl_widget_base!(Wizard, Fl_Wizard);
crate::macros::widget::impl_widget_default!(Wizard);
crate::macros::group::impl_group_ext!(Wizard, Fl_Wizard);
impl Wizard {
pub fn next(&mut self) {
unsafe { Fl_Wizard_next(self.inner.widget() as _) }
}
pub fn prev(&mut self) {
unsafe { Fl_Wizard_prev(self.inner.widget() as _) }
}
#[deprecated(since = "1.2.18", note = "please use `try_current_widget` instead")]
pub fn current_widget(&self) -> Widget {
unsafe {
let ptr = Fl_Wizard_value(self.inner.widget() as _) as *mut fltk_sys::widget::Fl_Widget;
assert!(!ptr.is_null());
Widget::from_widget_ptr(ptr)
}
}
pub fn try_current_widget(&self) -> Option<impl WidgetExt> {
unsafe {
let ptr = Fl_Wizard_value(self.inner.widget() as _) as *mut fltk_sys::widget::Fl_Widget;
if ptr.is_null() {
None
} else {
Some(Widget::from_widget_ptr(ptr))
}
}
}
pub fn set_current_widget<W: WidgetExt>(&mut self, w: &W) {
unsafe {
Fl_Wizard_set_value(
self.inner.widget() as _,
w.as_widget_ptr() as *mut fltk_sys::group::Fl_Widget,
)
}
}
pub fn set_index(&mut self, idx: i32) -> Result<(), FltkError> {
if let Some(w) = self.child(idx) {
self.set_current_widget(&w);
Ok(())
} else {
Err(FltkError::Unknown("Index out of bounds".to_string()))
}
}
pub fn index(&self) -> Option<i32> {
Some(self.find(&self.try_current_widget()?))
}
}
#[derive(Debug)]
pub struct ColorChooser {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(ColorChooser, Fl_Color_Chooser);
crate::macros::widget::impl_widget_base!(ColorChooser, Fl_Color_Chooser);
crate::macros::widget::impl_widget_default!(ColorChooser);
crate::macros::group::impl_group_ext!(ColorChooser, Fl_Color_Chooser);
impl ColorChooser {
pub fn rgb_color(&self) -> (u8, u8, u8) {
unsafe {
let r = (Fl_Color_Chooser_r(self.inner.widget() as _) * 255.0) as u8;
let g = (Fl_Color_Chooser_g(self.inner.widget() as _) * 255.0) as u8;
let b = (Fl_Color_Chooser_b(self.inner.widget() as _) * 255.0) as u8;
(r, g, b)
}
}
pub fn hex_color(&self) -> u32 {
let (r, g, b) = self.rgb_color();
crate::utils::rgb2hex(r, g, b)
}
pub fn set_rgb(&mut self, r: u8, g: u8, b: u8) -> Result<(), FltkError> {
unsafe {
let ret = Fl_Color_Chooser_set_rgb(
self.inner.widget() as _,
r as f64 / 255.0,
g as f64 / 255.0,
b as f64 / 255.0,
);
if ret == 1 {
Ok(())
} else {
Err(FltkError::Internal(FltkErrorKind::FailedOperation))
}
}
}
pub fn set_tuple_rgb(&mut self, (r, g, b): (u8, u8, u8)) -> Result<(), FltkError> {
unsafe {
let ret = Fl_Color_Chooser_set_rgb(
self.inner.widget() as _,
r as f64 / 255.0,
g as f64 / 255.0,
b as f64 / 255.0,
);
if ret == 1 {
Ok(())
} else {
Err(FltkError::Internal(FltkErrorKind::FailedOperation))
}
}
}
}
crate::macros::widget::impl_widget_type!(FlexType);
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FlexType {
Column = 0,
Row,
}
#[derive(Debug)]
pub struct Flex {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(Flex, Fl_Flex);
crate::macros::widget::impl_widget_base!(Flex, Fl_Flex);
crate::macros::widget::impl_widget_default!(Flex);
crate::macros::group::impl_group_ext!(Flex, Fl_Flex);
impl Flex {
fn new<T: Into<Option<&'static str>>>(
x: i32,
y: i32,
width: i32,
height: i32,
title: T,
) -> Self {
let mut f = <Flex as WidgetBase>::new(x, y, width, height, title).row();
f.set_pad(5);
f.debug_();
f
}
pub fn add<W: WidgetExt>(&mut self, widget: &W) {
<Self as GroupExt>::add(self, widget);
self.recalc();
}
pub fn insert<W: WidgetExt>(&mut self, widget: &W, idx: i32) {
<Self as GroupExt>::insert(self, widget, idx);
self.recalc();
}
#[deprecated(since = "1.4.8", note = "please use `fixed` instead")]
pub fn set_size<W: WidgetExt>(&mut self, w: &W, size: i32) {
unsafe { Fl_Flex_set_size(self.inner.widget() as _, w.as_widget_ptr() as _, size) }
}
pub fn fixed<W: WidgetExt>(&mut self, w: &W, size: i32) {
unsafe { Fl_Flex_set_size(self.inner.widget() as _, w.as_widget_ptr() as _, size) }
}
pub fn debug(flag: bool) {
DEBUG.store(flag, Ordering::Release);
}
fn debug_(&mut self) {
if DEBUG.load(Ordering::Relaxed) {
self.set_frame(FrameType::BorderBox);
if self.get_type::<FlexType>() == FlexType::Row {
self.set_color(Color::from_rgb(200, 0, 0));
} else {
self.set_color(Color::from_rgb(0, 0, 200));
}
}
}
pub fn column(mut self) -> Self {
self.set_type(FlexType::Column);
self.debug_();
self
}
pub fn row(mut self) -> Self {
self.set_type(FlexType::Row);
self.debug_();
self
}
pub fn recalc(&self) {
let mut s = self.clone();
s.resize(self.x(), self.y(), self.w(), self.h());
s.redraw();
}
pub fn layout(&self) {
self.recalc();
}
pub fn set_margin(&mut self, m: i32) {
unsafe { Fl_Flex_set_margin(self.inner.widget() as _, m) }
}
pub fn margin(&self) -> i32 {
unsafe { Fl_Flex_margin(self.inner.widget() as _) }
}
pub fn set_pad(&mut self, p: i32) {
unsafe { Fl_Flex_set_pad(self.inner.widget() as _, p) }
}
pub fn pad(&self) -> i32 {
unsafe { Fl_Flex_pad(self.inner.widget() as _) }
}
pub fn set_spacing(&mut self, p: i32) {
unsafe { Fl_Flex_set_pad(self.inner.widget() as _, p) }
}
pub fn spacing(&self) -> i32 {
unsafe { Fl_Flex_pad(self.inner.widget() as _) }
}
pub fn set_margins(&mut self, left: i32, top: i32, right: i32, bottom: i32) {
unsafe { Fl_Flex_set_margins(self.inner.widget() as _, left, top, right, bottom) }
}
pub fn margins(&self) -> (i32, i32, i32, i32) {
let mut left = 0;
let mut top = 0;
let mut right = 0;
let mut bottom = 0;
unsafe {
Fl_Flex_margins(
self.inner.widget() as _,
&mut left,
&mut top,
&mut right,
&mut bottom,
);
}
(left, top, right, bottom)
}
}
#[derive(Debug, Clone)]
pub struct VGrid {
vpack: Pack,
rows: i32,
cols: i32,
current: i32,
}
impl Default for VGrid {
fn default() -> Self {
Self::new(0, 0, 0, 0, None)
}
}
impl VGrid {
pub fn default_fill() -> Self {
Self::default().size_of_parent()
}
pub fn new<T: Into<Option<&'static str>>>(x: i32, y: i32, w: i32, h: i32, label: T) -> VGrid {
let vpack = Pack::new(x, y, w, h, label);
VGrid {
vpack,
rows: 1,
cols: 1,
current: 0,
}
}
pub fn set_params(&mut self, rows: i32, cols: i32, spacing: i32) {
self.vpack.set_spacing(spacing);
let rows = if rows < 1 { 1 } else { rows };
let cols = if cols < 1 { 1 } else { cols };
self.rows = rows;
self.cols = cols;
for _ in 0..rows {
let mut p = Pack::new(0, 0, self.vpack.width(), 0, "");
p.set_type(PackType::Horizontal);
p.set_spacing(spacing);
p.end();
self.vpack.add(&p);
}
}
pub fn add<W: WidgetExt>(&mut self, w: &W) {
debug_assert!(self.current < self.rows * self.cols);
let rem = (self.current - 1) / self.cols;
if rem < self.rows {
let hpack = self.vpack.child(rem).unwrap();
let mut hpack = unsafe { Pack::from_widget_ptr(hpack.as_widget_ptr()) };
hpack.end();
hpack.add(w);
hpack.auto_layout();
self.vpack.auto_layout();
self.current += 1;
}
}
pub fn end(&mut self) {
use std::collections::VecDeque;
let children = self.vpack.children();
self.current = children - self.rows;
debug_assert!(self.current <= self.rows * self.cols);
let mut v = VecDeque::new();
for i in self.rows..children {
let c = self.vpack.child(i).unwrap();
v.push_back(c);
}
for i in 0..self.rows {
let hpack = self.vpack.child(i).unwrap();
let mut hpack = unsafe { Pack::from_widget_ptr(hpack.as_widget_ptr()) };
hpack.end();
for _j in 0..self.cols {
if let Some(w) = v.pop_front() {
self.vpack.remove(&w);
hpack.add(&w);
}
hpack.auto_layout();
}
}
self.vpack.auto_layout();
}
}
crate::widget_extends!(VGrid, Pack, vpack);
#[derive(Debug, Clone)]
pub struct HGrid {
hpack: Pack,
rows: i32,
cols: i32,
current: i32,
}
impl Default for HGrid {
fn default() -> Self {
Self::new(0, 0, 0, 0, None)
}
}
impl HGrid {
pub fn default_fill() -> Self {
Self::default().size_of_parent()
}
pub fn new<T: Into<Option<&'static str>>>(x: i32, y: i32, w: i32, h: i32, label: T) -> HGrid {
let mut hpack = Pack::new(x, y, w, h, label);
hpack.set_type(PackType::Horizontal);
HGrid {
hpack,
rows: 1,
cols: 1,
current: 0,
}
}
pub fn set_params(&mut self, rows: i32, cols: i32, spacing: i32) {
self.hpack.set_spacing(spacing);
let rows = if rows < 1 { 1 } else { rows };
let cols = if cols < 1 { 1 } else { cols };
self.rows = rows;
self.cols = cols;
for _ in 0..cols {
let mut p = Pack::new(0, 0, 0, self.hpack.height(), "");
p.set_spacing(spacing);
p.end();
self.hpack.add(&p);
}
}
pub fn add<W: WidgetExt>(&mut self, w: &W) {
debug_assert!(self.current < self.rows * self.cols);
let rem = (self.current - 1) / self.rows;
if rem < self.cols {
let vpack = self.hpack.child(rem).unwrap();
let mut vpack = unsafe { Pack::from_widget_ptr(vpack.as_widget_ptr()) };
vpack.end();
vpack.add(w);
vpack.auto_layout();
self.hpack.auto_layout();
self.current += 1;
}
}
pub fn end(&mut self) {
use std::collections::VecDeque;
let children = self.hpack.children();
self.current = children - self.cols;
debug_assert!(self.current <= self.rows * self.cols);
let mut v = VecDeque::new();
for i in self.cols..children {
let c = self.hpack.child(i).unwrap();
v.push_back(c);
}
for i in 0..self.cols {
let vpack = self.hpack.child(i).unwrap();
let mut vpack = unsafe { Pack::from_widget_ptr(vpack.as_widget_ptr()) };
vpack.end();
for _j in 0..self.rows {
if let Some(w) = v.pop_front() {
self.hpack.remove(&w);
vpack.add(&w);
}
vpack.auto_layout();
}
}
self.hpack.auto_layout();
}
}
crate::widget_extends!(HGrid, Pack, hpack);
#[derive(Debug, Clone)]
pub struct Column {
p: Flex,
}
impl Default for Column {
fn default() -> Self {
Self::new(0, 0, 0, 0, None)
}
}
impl Column {
pub fn default_fill() -> Self {
Self::default().size_of_parent().center_of_parent()
}
pub fn new<T: Into<Option<&'static str>>>(
x: i32,
y: i32,
width: i32,
height: i32,
label: T,
) -> Column {
let mut p = Flex::new(x, y, width, height, label);
p.set_type(FlexType::Column);
Column { p }
}
pub fn add<W: WidgetExt>(&mut self, w: &W) {
self.p.add(w);
}
}
crate::widget_extends!(Column, Flex, p);
#[derive(Debug, Clone)]
pub struct Row {
p: Flex,
}
impl Default for Row {
fn default() -> Self {
Self::new(0, 0, 0, 0, None)
}
}
impl Row {
pub fn default_fill() -> Self {
Self::default().size_of_parent().center_of_parent()
}
pub fn new<T: Into<Option<&'static str>>>(
x: i32,
y: i32,
width: i32,
height: i32,
label: T,
) -> Row {
let mut p = Flex::new(x, y, width, height, label);
p.set_type(FlexType::Row);
Row { p }
}
pub fn add<W: WidgetExt>(&mut self, w: &W) {
self.p.add(w);
}
}
crate::widget_extends!(Row, Flex, p);
pub struct GridRange {
start: usize,
end: usize,
}
impl GridRange {
pub fn len(&self) -> usize {
self.end - self.start
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl From<Range<usize>> for GridRange {
fn from(val: Range<usize>) -> Self {
Self {
start: val.start,
end: val.end,
}
}
}
impl From<usize> for GridRange {
fn from(val: usize) -> Self {
(val..val + 1).into()
}
}
bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GridAlign: u16 {
const CENTER = 0x0000;
const TOP = 0x0001;
const BOTTOM = 0x0002;
const LEFT = 0x0004;
const RIGHT = 0x0008;
const HORIZONTAL = 0x0010;
const VERTICAL = 0x0020;
const FILL = 0x0030;
const PROPORTIONAL = 0x0040;
const TOP_LEFT = GridAlign::TOP.bits() | GridAlign::LEFT.bits();
const TOP_RIGHT = GridAlign::TOP.bits() | GridAlign::RIGHT.bits();
const BOTTOM_LEFT = GridAlign::BOTTOM.bits() | GridAlign::LEFT.bits();
const BOTTOM_RIGHT = GridAlign::BOTTOM.bits() | GridAlign::RIGHT.bits();
}
}
#[derive(Debug)]
pub struct Grid {
inner: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(Grid, Fl_Grid);
crate::macros::widget::impl_widget_base!(Grid, Fl_Grid);
crate::macros::widget::impl_widget_default!(Grid);
crate::macros::group::impl_group_ext!(Grid, Fl_Grid);
impl Grid {
pub fn set_layout_ext(&mut self, rows: i32, cols: i32, margin: i32, gap: i32) {
unsafe { Fl_Grid_set_layout(self.inner.widget() as _, rows, cols, margin, gap) }
}
pub fn set_layout(&mut self, rows: i32, cols: i32) {
unsafe { Fl_Grid_set_layout(self.inner.widget() as _, rows, cols, -1, -1) }
}
pub fn layout(&mut self) {
unsafe { Fl_Grid_layout(self.inner.widget() as _) }
}
pub fn clear_layout(&mut self) {
unsafe { Fl_Grid_clear_layout(self.inner.widget() as _) }
}
pub fn set_need_layout(&mut self, set: bool) {
unsafe { Fl_Grid_set_need_layout(self.inner.widget() as _, set as _) }
}
pub fn need_layout(&self) -> bool {
unsafe { Fl_Grid_need_layout(self.inner.widget() as _) != 0 }
}
pub fn set_margin(&mut self, left: i32, top: i32, right: i32, bottom: i32) {
unsafe { Fl_Grid_set_margin(self.inner.widget() as _, left, top, right, bottom) }
}
pub fn set_margins(&mut self, left: i32, top: i32, right: i32, bottom: i32) {
unsafe { Fl_Grid_set_margin(self.inner.widget() as _, left, top, right, bottom) }
}
pub fn set_gap(&mut self, row_gap: i32, col_gap: i32) {
unsafe { Fl_Grid_set_gap(self.inner.widget() as _, row_gap, col_gap) }
}
#[allow(dead_code)]
pub fn set_widget_<W: WidgetExt>(
&mut self,
wi: &mut W,
row: i32,
col: i32,
align: GridAlign,
) -> *mut () {
unsafe {
Fl_Grid_set_widget(
self.inner.widget() as _,
wi.as_widget_ptr() as _,
row,
col,
align.bits(),
) as _
}
}
pub fn set_widget<W: 'static + Clone + WidgetExt>(
&mut self,
widget: &mut W,
row: impl Into<GridRange>,
col: impl Into<GridRange>,
) -> Result<(), FltkError> {
let row = row.into();
let col = col.into();
self.set_widget_ext(widget, row, col, GridAlign::FILL)
}
fn set_widget_ext_<W: WidgetExt>(
&mut self,
wi: &mut W,
row: i32,
col: i32,
rowspan: i32,
colspan: i32,
align: GridAlign,
) -> *mut () {
unsafe {
Fl_Grid_set_widget_ext(
self.inner.widget() as _,
wi.as_widget_ptr() as _,
row,
col,
rowspan,
colspan,
align.bits(),
) as _
}
}
pub fn set_widget_ext<W: 'static + Clone + WidgetExt>(
&mut self,
widget: &mut W,
row: impl Into<GridRange>,
col: impl Into<GridRange>,
align: GridAlign,
) -> Result<(), FltkError> {
let row = row.into();
let col = col.into();
let e = self.set_widget_ext_(
widget,
row.start as _,
col.start as _,
row.len() as _,
col.len() as _,
align,
);
if e.is_null() {
Err(FltkError::Internal(FltkErrorKind::FailedGridSetWidget))
} else {
Ok(())
}
}
pub fn set_col_width(&mut self, col: i32, value: i32) {
unsafe { Fl_Grid_set_col_width(self.inner.widget() as _, col, value) }
}
pub fn set_col_weight(&mut self, col: i32, value: i32) {
unsafe { Fl_Grid_set_col_weight(self.inner.widget() as _, col, value) }
}
pub fn set_col_gap(&mut self, col: i32, value: i32) {
unsafe { Fl_Grid_set_col_gap(self.inner.widget() as _, col, value) }
}
pub fn set_row_height(&mut self, row: i32, value: i32) {
unsafe { Fl_Grid_set_row_height(self.inner.widget() as _, row, value) }
}
pub fn set_row_weight(&mut self, row: i32, value: i32) {
unsafe { Fl_Grid_set_row_weight(self.inner.widget() as _, row, value) }
}
pub fn set_row_gap(&mut self, row: i32, value: i32) {
unsafe { Fl_Grid_set_row_gap(self.inner.widget() as _, row, value) }
}
pub fn show_grid(&mut self, set: bool) {
unsafe { Fl_Grid_show_grid(self.inner.widget() as _, set as _) }
}
pub fn show_grid_with_color(&mut self, set: bool, col: Color) {
unsafe { Fl_Grid_show_grid_with_color(self.inner.widget() as _, set as _, col.bits()) }
}
pub fn debug(&mut self, level: i32) {
unsafe { Fl_Grid_debug(self.inner.widget() as _, level) }
}
}
#[allow(missing_docs)]
pub mod experimental {
#[allow(unused_imports)]
use super::*;
}