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
use crate::prelude::*;
use crate::utils::FlString;
use fltk_sys::table::*;
use std::ffi::{CStr, CString};

/// Creates a table
/// For a simpler boilerplate-less table, check the [fltk-table crate](https://crates.io/crates/fltk-table)
#[derive(Debug)]
pub struct Table {
    inner: *mut Fl_Table,
    tracker: *mut fltk_sys::fl::Fl_Widget_Tracker,
    is_derived: bool,
}

crate::macros::widget::impl_widget_ext!(Table, Fl_Table);
crate::macros::widget::impl_widget_base!(Table, Fl_Table);
crate::macros::widget::impl_widget_default!(Table);
crate::macros::group::impl_group_ext!(Table, Fl_Table);
crate::macros::table::impl_table_ext!(Table, Fl_Table);

/// Defines the `TableContext`
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum TableContext {
    /// No context
    None = 0,
    /// start of page context
    StartPage = 0x01,
    /// End of page context
    EndPage = 0x02,
    /// Row header context
    RowHeader = 0x04,
    /// Column header context
    ColHeader = 0x08,
    /// Cell context
    Cell = 0x10,
    /// Table context
    Table = 0x20,
    /// Row-Column resize context
    RcResize = 0x40,
}

/// Defines the `TableResizeFlag`
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum TableResizeFlag {
    /// Non resizable
    None = 0,
    /// Resizes on the left of the column
    ColLeft = 1,
    /// Resizes on the right of the column
    ColRight = 2,
    /// Resizes to above the row
    RowAbove = 3,
    /// Resizes to below the row
    RowBelow = 4,
}

/// Creates a table row
#[derive(Debug)]
pub struct TableRow {
    inner: *mut Fl_Table_Row,
    tracker: *mut fltk_sys::fl::Fl_Widget_Tracker,
    is_derived: bool,
}

crate::macros::widget::impl_widget_ext!(TableRow, Fl_Table_Row);
crate::macros::widget::impl_widget_base!(TableRow, Fl_Table_Row);
crate::macros::widget::impl_widget_default!(TableRow);
crate::macros::group::impl_group_ext!(TableRow, Fl_Table_Row);
crate::macros::table::impl_table_ext!(TableRow, Fl_Table_Row);

/// Defines the table row select mode
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TableRowSelectMode {
    /// Disable select
    None,
    /// Select single elements
    Single,
    /// Select several elements
    Multi,
}

crate::macros::widget::impl_widget_type!(TableRowSelectMode);

/// Defines the table row select flag
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TableRowSelectFlag {
    /// Deselect on click
    Deselect,
    /// Select on click
    Select,
    /// Toggle selection on click
    Toggle,
}

impl TableRow {
    /// Returns whether a row was selected
    pub fn row_selected(&mut self, row: i32) -> bool {
        unsafe {
            assert!(!self.was_deleted());
            Fl_Table_Row_row_selected(self.inner, row) != 0
        }
    }

    /// Selects a row
    /// # Errors
    /// Errors on failure to select row
    pub fn select_row(
        &mut self,
        row: i32,
        selection_flag: TableRowSelectFlag,
    ) -> Result<(), FltkError> {
        unsafe {
            assert!(!self.was_deleted());
            match Fl_Table_Row_select_row(self.inner, row, selection_flag as i32) {
                1 => Ok(()),
                0 | -1 => Err(FltkError::Internal(FltkErrorKind::TableError)),
                _ => unreachable!(),
            }
        }
    }

    /// Selects all rows
    pub fn select_all_rows(&mut self, selection_flag: TableRowSelectFlag) {
        assert!(!self.was_deleted());
        unsafe { Fl_Table_Row_select_all_rows(self.inner, selection_flag as i32) }
    }
}