Struct Pack

Source
pub struct Pack { /* private fields */ }
Expand description

Creates a widget pack

Implementations§

Source§

impl Pack

Source

pub fn new<'a, T: Into<Option<&'a str>>>( x: i32, y: i32, width: i32, height: i32, title: T, ) -> Pack

Creates a new widget, takes an x, y coordinates, as well as a width and height, plus a title

§Arguments
  • x - The x coordinate in the screen
  • y - The y coordinate in the screen
  • width - The width of the widget
  • heigth - The height of the widget
  • title - The title or label of the widget

To use dynamic strings use with_label(self, &str) or set_label(&mut self, &str). labels support special symbols preceded by an @ sign and for the associated formatting.

Examples found in repository?
examples/closable_tabs2.rs (line 47)
44        pub fn new(x: i32, y: i32, w: i32, h: i32, snd: &'a app::Sender<Message>) -> Self {
45            let current = None;
46            let parent_grp = group::Group::new(x, y, w, h, None);
47            let mut tab_labels = group::Pack::new(x + 5, y, w - 10, 40, None);
48            tab_labels.set_spacing(3);
49            tab_labels.set_type(group::PackType::Horizontal);
50            tab_labels.end();
51            let mut contents = group::Group::new(x, y + 40, w, h - 40, None);
52            contents.set_frame(FrameType::NoBox);
53            contents.end();
54            parent_grp.end();
55            Self {
56                current,
57                snd,
58                contents,
59                tab_labels,
60            }
61        }
More examples
Hide additional examples
examples/custom_choice.rs (line 61)
55    pub fn new(choices: &[&str]) -> Self {
56        let val = Rc::from(RefCell::from(String::from("")));
57        let idx = RefCell::from(0);
58        let mut win = window::Window::default().with_size(120, choices.len() as i32 * 25);
59        win.set_color(Color::White);
60        win.set_frame(FrameType::BorderBox);
61        let mut pack = group::Pack::new(1, 1, win.w() - 2, win.h() - 2, None);
62        win.set_border(false);
63        win.end();
64        for (i, choice) in choices.iter().enumerate() {
65            let mut but = PopupButton::new(choice);
66            but.clear_visible_focus();
67            but.set_callback({
68                let mut win = win.clone();
69                let val = val.clone();
70                let idx = idx.clone();
71                move |b| {
72                    *val.borrow_mut() = b.label().unwrap();
73                    *idx.borrow_mut() = i as i32;
74                    win.hide();
75                }
76            });
77            pack.add(&*but);
78        }
79        pack.auto_layout();
80        Self { win, val, idx }
81    }
examples/calculator.rs (line 111)
89fn main() {
90    let app = app::App::default();
91    let win_w = 400;
92    let win_h = 500;
93    let border = 20;
94    let but_row = 180;
95
96    let mut operation = Ops::None;
97    let mut txt = String::from("0");
98    let mut old_val = String::from("0");
99    let mut new_val: String;
100
101    let mut wind = Window::default()
102        .with_label("FLTK Calc")
103        .with_size(win_w, win_h);
104    wind.set_center_screen();
105    wind.set_color(Color::Light3);
106
107    let mut out = Output::new(border, border, win_w - 40, 140, "");
108    out.set_text_size(36);
109    out.set_value("0");
110
111    let vpack = Pack::new(border, but_row, win_w - 40, 300, "");
112
113    let mut hpack = Pack::new(0, 0, win_w - 40, 60, "");
114    let but_ce = MyButton::new("CE");
115    let but_c = MyButton::new("C");
116    let but_back = MyButton::new("@<-");
117    let but_div = MyButton::new("/");
118    hpack.end();
119    hpack.set_type(PackType::Horizontal);
120
121    let mut hpack = Pack::new(0, 0, win_w - 40, 60, "");
122    let mut but7 = MyButton::new("7");
123    let mut but8 = MyButton::new("8");
124    let mut but9 = MyButton::new("9");
125    let but_mul = MyButton::new("x");
126    hpack.end();
127    hpack.set_type(PackType::Horizontal);
128
129    let mut hpack = Pack::new(0, 0, win_w - 40, 60, "");
130    let mut but4 = MyButton::new("4");
131    let mut but5 = MyButton::new("5");
132    let mut but6 = MyButton::new("6");
133    let but_sub = MyButton::new("-");
134    hpack.end();
135    hpack.set_type(PackType::Horizontal);
136
137    let mut hpack = Pack::new(0, 0, win_w - 40, 60, "");
138    let mut but1 = MyButton::new("1");
139    let mut but2 = MyButton::new("2");
140    let mut but3 = MyButton::new("3");
141    let but_add = MyButton::new("+");
142    hpack.end();
143    hpack.set_type(PackType::Horizontal);
144
145    let mut hpack = Pack::new(0, 0, win_w - 40, 60, "");
146    let mut but_dot = MyButton::new(".");
147    let mut but0 = MyButton::new("0");
148    let but_eq = MyButton::new("=");
149    hpack.end();
150    hpack.set_type(PackType::Horizontal);
151
152    vpack.end();
153
154    wind.make_resizable(false);
155    wind.end();
156    wind.show_with_args(&["-scheme", "gtk+", "-nokbd"]);
157
158    app::set_focus(&*but1);
159
160    let but_vec = vec![
161        &mut but1, &mut but2, &mut but3, &mut but4, &mut but5, &mut but6, &mut but7, &mut but8,
162        &mut but9, &mut but0,
163    ];
164
165    let but_op_vec = vec![
166        but_add, but_sub, but_mul, but_div, but_c, but_ce, but_back, but_eq,
167    ];
168
169    let (s, r) = app::channel::<Message>();
170
171    for but in but_vec {
172        let label = but.label().unwrap();
173        but.emit(s, Message::Number(label.parse().unwrap()));
174    }
175
176    for mut but in but_op_vec {
177        let op = match but.label().unwrap().as_str() {
178            "+" => Ops::Add,
179            "-" => Ops::Sub,
180            "x" => Ops::Mul,
181            "/" => Ops::Div,
182            "=" => Ops::Eq,
183            "CE" => Ops::CE,
184            "C" => Ops::C,
185            "@<-" => Ops::Back,
186            _ => Ops::None,
187        };
188        but.emit(s, Message::Op(op));
189    }
190
191    but_dot.emit(s, Message::Dot);
192
193    while app.wait() {
194        if let Some(val) = r.recv() {
195            match val {
196                Message::Number(num) => {
197                    if out.value() == "0" {
198                        txt.clear();
199                    }
200                    txt.push_str(&num.to_string());
201                    out.set_value(txt.as_str());
202                }
203                Message::Dot => {
204                    if operation == Ops::Eq {
205                        txt.clear();
206                        operation = Ops::None;
207                        out.set_value("0.");
208                        txt.push_str("0.");
209                    }
210                    if !txt.contains('.') {
211                        txt.push('.');
212                        out.set_value(txt.as_str());
213                    }
214                }
215                Message::Op(op) => match op {
216                    Ops::Add | Ops::Sub | Ops::Div | Ops::Mul => {
217                        old_val.clear();
218                        old_val.push_str(&out.value());
219                        operation = op;
220                        out.set_value("0");
221                    }
222                    Ops::Back => {
223                        let val = out.value();
224                        txt.pop();
225                        if val.len() > 1 {
226                            out.set_value(txt.as_str());
227                        } else {
228                            out.set_value("0");
229                        }
230                    }
231                    Ops::CE => {
232                        txt.clear();
233                        old_val.clear();
234                        txt.push('0');
235                        out.set_value(txt.as_str());
236                    }
237                    Ops::C => {
238                        txt.clear();
239                        txt.push('0');
240                        out.set_value(txt.as_str());
241                    }
242                    Ops::Eq => {
243                        new_val = out.value();
244                        let old: f64 = old_val.parse().unwrap();
245                        let new: f64 = new_val.parse().unwrap();
246                        let val = match operation {
247                            Ops::Div => old / new,
248                            Ops::Mul => old * new,
249                            Ops::Add => old + new,
250                            Ops::Sub => old - new,
251                            _ => new,
252                        };
253                        operation = Ops::None;
254                        txt = String::from("0");
255                        out.set_value(&val.to_string());
256                    }
257                    _ => (),
258                },
259            }
260        }
261    }
262}
examples/calculator2.rs (line 128)
102fn main() {
103    let app = app::App::default();
104    app::set_visible_focus(false);
105    app::background(0x42, 0x42, 0x42);
106
107    let win_w = 400;
108    let win_h = 500;
109    let but_row = 160;
110
111    let mut operation = Ops::None;
112    let mut txt = String::from("0");
113    let mut old_val = String::from("0");
114    let mut new_val: String;
115
116    let mut wind = Window::default()
117        .with_label("FLTK Calc")
118        .with_size(win_w, win_h);
119    wind.set_center_screen();
120
121    let mut out = Frame::new(0, 0, win_w, 160, "").with_align(Align::Right | Align::Inside);
122    out.set_color(Color::from_hex(0x1b1b1b));
123    out.set_frame(FrameType::FlatBox);
124    out.set_label_color(Color::White);
125    out.set_label_size(36);
126    out.set_label("0");
127
128    let vpack = Pack::new(0, but_row, win_w, win_h - 170, "");
129
130    let mut hpack = Pack::new(0, 0, win_w, 68, "");
131    let but_ce = MyButton::new("CE");
132    let but_c = MyButton::new("C");
133    let but_back = MyButton::new("@<-");
134    let but_div = MyButton::new("/");
135    hpack.end();
136    hpack.set_type(PackType::Horizontal);
137
138    let mut hpack = Pack::new(0, 0, win_w, 68, "");
139    let mut but7 = MyButton::new("7");
140    let mut but8 = MyButton::new("8");
141    let mut but9 = MyButton::new("9");
142    let but_mul = MyButton::new("x");
143    hpack.end();
144    hpack.set_type(PackType::Horizontal);
145
146    let mut hpack = Pack::new(0, 0, win_w, 68, "");
147    let mut but4 = MyButton::new("4");
148    let mut but5 = MyButton::new("5");
149    let mut but6 = MyButton::new("6");
150    let but_sub = MyButton::new("-");
151    hpack.end();
152    hpack.set_type(PackType::Horizontal);
153
154    let mut hpack = Pack::new(0, 0, win_w, 68, "");
155    let mut but1 = MyButton::new("1");
156    let mut but2 = MyButton::new("2");
157    let mut but3 = MyButton::new("3");
158    let but_add = MyButton::new("+");
159    hpack.end();
160    hpack.set_type(PackType::Horizontal);
161
162    let mut hpack = Pack::new(0, 0, win_w, 68, "");
163    let mut but_dot = MyButton::new(".");
164    let mut but0 = MyButton::new("0");
165    let but_eq = MyButton::new("=");
166    hpack.end();
167    hpack.set_type(PackType::Horizontal);
168
169    vpack.end();
170
171    wind.make_resizable(false);
172    wind.end();
173    wind.show();
174
175    app::set_focus(&*but1);
176    app::get_system_colors();
177
178    let but_vec = vec![
179        &mut but1, &mut but2, &mut but3, &mut but4, &mut but5, &mut but6, &mut but7, &mut but8,
180        &mut but9, &mut but0,
181    ];
182
183    let but_op_vec = vec![
184        but_add, but_sub, but_mul, but_div, but_c, but_ce, but_back, but_eq,
185    ];
186
187    let (s, r) = app::channel::<Message>();
188
189    for but in but_vec {
190        let label = but.label().unwrap();
191        but.emit(s, Message::Number(label.parse().unwrap()));
192    }
193
194    for mut but in but_op_vec {
195        let op = match but.label().unwrap().as_str() {
196            "+" => Ops::Add,
197            "-" => Ops::Sub,
198            "x" => Ops::Mul,
199            "/" => Ops::Div,
200            "=" => Ops::Eq,
201            "CE" => Ops::CE,
202            "C" => Ops::C,
203            "@<-" => Ops::Back,
204            _ => Ops::None,
205        };
206        but.emit(s, Message::Op(op));
207    }
208
209    but_dot.emit(s, Message::Dot);
210
211    while app.wait() {
212        if let Some(val) = r.recv() {
213            match val {
214                Message::Number(num) => {
215                    if out.label().unwrap() == "0" {
216                        txt.clear();
217                    }
218                    txt.push_str(&num.to_string());
219                    out.set_label(txt.as_str());
220                }
221                Message::Dot => {
222                    if operation == Ops::Eq {
223                        txt.clear();
224                        operation = Ops::None;
225                        out.set_label("0.");
226                        txt.push_str("0.");
227                    }
228                    if !txt.contains('.') {
229                        txt.push('.');
230                        out.set_label(txt.as_str());
231                    }
232                }
233                Message::Op(op) => match op {
234                    Ops::Add | Ops::Sub | Ops::Div | Ops::Mul => {
235                        old_val.clear();
236                        old_val.push_str(&out.label().unwrap());
237                        operation = op;
238                        out.set_label("0");
239                    }
240                    Ops::Back => {
241                        let val = out.label().unwrap();
242                        txt.pop();
243                        if val.len() > 1 {
244                            out.set_label(txt.as_str());
245                        } else {
246                            out.set_label("0");
247                        }
248                    }
249                    Ops::CE => {
250                        txt.clear();
251                        old_val.clear();
252                        txt.push('0');
253                        out.set_label(txt.as_str());
254                    }
255                    Ops::C => {
256                        txt.clear();
257                        txt.push('0');
258                        out.set_label(txt.as_str());
259                    }
260                    Ops::Eq => {
261                        new_val = out.label().unwrap();
262                        let old: f64 = old_val.parse().unwrap();
263                        let new: f64 = new_val.parse().unwrap();
264                        let val = match operation {
265                            Ops::Div => old / new,
266                            Ops::Mul => old * new,
267                            Ops::Add => old + new,
268                            Ops::Sub => old - new,
269                            _ => new,
270                        };
271                        operation = Ops::None;
272                        txt = String::from("0");
273                        out.set_label(&val.to_string());
274                    }
275                    _ => (),
276                },
277            }
278        }
279    }
280}
examples/format_text.rs (line 129)
122fn main() {
123    let style = Rc::from(RefCell::from(Style::new()));
124
125    let app = App::default().with_scheme(Scheme::Gleam);
126    let mut wind = Window::default()
127        .with_size(500, 200)
128        .with_label("Highlight");
129    let mut vpack = Pack::new(4, 4, 492, 192, "");
130    vpack.set_spacing(4);
131    let mut text_editor = TextEditor::default().with_size(492, 163);
132
133    let mut hpack = Pack::new(4, 4, 492, 25, "").with_type(PackType::Horizontal);
134    hpack.set_spacing(8);
135    let mut font = Choice::default().with_size(130, 25);
136    let mut choice = Choice::default().with_size(130, 25);
137    let mut size = Spinner::default().with_size(60, 25);
138
139    let mut color = Choice::default().with_size(100, 25);
140    let mut btn_clear = Button::default().with_size(40, 25).with_label("X");
141    hpack.end();
142
143    vpack.end();
144    wind.end();
145    wind.show();
146
147    text_editor.wrap_mode(fltk::text::WrapMode::AtBounds, 0);
148    text_editor.set_buffer(TextBuffer::default());
149
150    font.add_choice("Courier|Helvetica|Times");
151    font.set_value(0);
152    font.set_tooltip("Font");
153
154    choice.add_choice("Normal|Underline|Strike");
155    choice.set_value(0);
156
157    size.set_value(18.0);
158    size.set_step(1.0);
159    size.set_range(12.0, 28.0);
160    size.set_tooltip("Size");
161
162    color.set_tooltip("Color");
163    color.add_choice("#000000|#ff0000|#00ff00|#0000ff|#ffff00|#00ffff");
164    color.set_value(0);
165
166    btn_clear.set_label_color(Color::Red);
167    btn_clear.set_tooltip("Clear style");
168
169    // set colors
170    for mut item in color.clone() {
171        if let Some(lbl) = item.label() {
172            item.set_label_color(Color::from_u32(
173                u32::from_str_radix(lbl.trim().strip_prefix('#').unwrap(), 16)
174                    .ok()
175                    .unwrap(),
176            ));
177        }
178    }
179
180    let style_rc1 = Rc::clone(&style);
181
182    text_editor.buffer().unwrap().add_modify_callback({
183        let mut text_editor1 = text_editor.clone();
184        let font1 = font.clone();
185        let size1 = size.clone();
186        let color1 = color.clone();
187        let choice1 = choice.clone();
188        move |_buf, pos: i32, ins_items: i32, del_items: i32, _: i32, _: Option<&str>| {
189            let attr = if choice1.value() == 1 {
190                TextAttr::Underline
191            } else if choice1.value() == 2 {
192                TextAttr::StrikeThrough
193            } else {
194                TextAttr::None
195            };
196            if ins_items > 0 || del_items > 0 {
197                let mut style = style_rc1.borrow_mut();
198                let color = Color::from_u32(
199                    u32::from_str_radix(
200                        color1
201                            .text(color1.value())
202                            .unwrap()
203                            .trim()
204                            .strip_prefix('#')
205                            .unwrap(),
206                        16,
207                    )
208                    .ok()
209                    .unwrap(),
210                );
211                style.apply_style(
212                    Some(pos),
213                    Some(ins_items),
214                    Some(del_items),
215                    None,
216                    None,
217                    Font::by_name(font1.text(font1.value()).unwrap().trim()),
218                    size1.value() as i32,
219                    color,
220                    attr,
221                    &mut text_editor1,
222                );
223            }
224        }
225    });
226
227    color.set_callback({
228        let size = size.clone();
229        let font = font.clone();
230        let choice = choice.clone();
231        let mut text_editor = text_editor.clone();
232        let style_rc1 = Rc::clone(&style);
233        move |color| {
234            let attr = match choice.value() {
235                0 => TextAttr::None,
236                1 => TextAttr::Underline,
237                2 => TextAttr::StrikeThrough,
238                _ => unreachable!(),
239            };
240            if let Some(buf) = text_editor.buffer() {
241                if let Some((s, e)) = buf.selection_position() {
242                    let mut style = style_rc1.borrow_mut();
243                    let color = Color::from_u32(
244                        u32::from_str_radix(
245                            color
246                                .text(color.value())
247                                .unwrap()
248                                .trim()
249                                .strip_prefix('#')
250                                .unwrap(),
251                            16,
252                        )
253                        .ok()
254                        .unwrap(),
255                    );
256                    style.apply_style(
257                        None,
258                        None,
259                        None,
260                        Some(s),
261                        Some(e),
262                        Font::by_name(font.text(font.value()).unwrap().trim()),
263                        size.value() as i32,
264                        color,
265                        attr,
266                        &mut text_editor,
267                    );
268                }
269            }
270        }
271    });
272
273    // get the style from the current cursor position
274    text_editor.handle({
275        let style_rc1 = Rc::clone(&style);
276        let mut font1 = font.clone();
277        let mut size1 = size.clone();
278        let mut color1 = color.clone();
279        move |te, e| match e {
280            Event::KeyUp | Event::Released => {
281                if let Some(buff) = te.style_buffer() {
282                    let i = te.insert_position();
283                    if let Some(t) = buff.text_range(i, i + 1) {
284                        if !t.is_empty() {
285                            let style = style_rc1.borrow_mut();
286                            if let Some(i) = t.chars().next().map(|c| (c as usize - 65)) {
287                                if let Some(style) = style.style_table.get(i) {
288                                    if let Some(mn) = font1.find_item(&format!("{:?}", style.font))
289                                    {
290                                        font1.set_item(&mn);
291                                    }
292                                    size1.set_value(style.size as f64);
293                                    let (r, g, b) = style.color.to_rgb();
294                                    if let Some(mn) =
295                                        color1.find_item(format!("{r:02x}{g:02x}{b:02x}").as_str())
296                                    {
297                                        color1.set_item(&mn);
298                                    }
299                                }
300                            }
301                        }
302                    }
303                }
304                true
305            }
306            _ => false,
307        }
308    });
309
310    choice.set_callback({
311        let mut color1 = color.clone();
312        move |_| color1.do_callback()
313    });
314
315    font.set_callback({
316        let mut color1 = color.clone();
317        move |_| color1.do_callback()
318    });
319
320    size.set_callback({
321        let mut color1 = color.clone();
322        move |_| color1.do_callback()
323    });
324
325    // clear style of the current selection or, if no text is selected, clear all text style
326    btn_clear.set_callback({
327        let style_rc1 = Rc::clone(&style);
328        let text_editor1 = text_editor.clone();
329        move |_| {
330            match text_editor1.buffer().unwrap().selection_position() {
331                Some((_, _)) => {
332                    font.set_value(0);
333                    size.set_value(18.0);
334                    color.set_value(0);
335                    choice.set_value(0);
336                    color.do_callback();
337                }
338                None => {
339                    font.set_value(0);
340                    size.set_value(18.0);
341                    color.set_value(0);
342                    style_rc1.borrow_mut().apply_style(
343                        None,
344                        None,
345                        None,
346                        Some(0),
347                        Some(text_editor1.buffer().unwrap().length()),
348                        Font::Courier,
349                        16,
350                        Color::Black,
351                        TextAttr::None,
352                        &mut text_editor,
353                    );
354                }
355            };
356        }
357    });
358
359    app.run().unwrap();
360}
Source

pub fn default_fill() -> Self

Constructs a widget with the size of its parent

Source§

impl Pack

Source

pub fn spacing(&self) -> i32

Get the spacing of the pack

Source

pub fn set_spacing(&mut self, spacing: i32)

Set the spacing of the pack

Examples found in repository?
examples/closable_tabs2.rs (line 48)
44        pub fn new(x: i32, y: i32, w: i32, h: i32, snd: &'a app::Sender<Message>) -> Self {
45            let current = None;
46            let parent_grp = group::Group::new(x, y, w, h, None);
47            let mut tab_labels = group::Pack::new(x + 5, y, w - 10, 40, None);
48            tab_labels.set_spacing(3);
49            tab_labels.set_type(group::PackType::Horizontal);
50            tab_labels.end();
51            let mut contents = group::Group::new(x, y + 40, w, h - 40, None);
52            contents.set_frame(FrameType::NoBox);
53            contents.end();
54            parent_grp.end();
55            Self {
56                current,
57                snd,
58                contents,
59                tab_labels,
60            }
61        }
More examples
Hide additional examples
examples/format_text.rs (line 130)
122fn main() {
123    let style = Rc::from(RefCell::from(Style::new()));
124
125    let app = App::default().with_scheme(Scheme::Gleam);
126    let mut wind = Window::default()
127        .with_size(500, 200)
128        .with_label("Highlight");
129    let mut vpack = Pack::new(4, 4, 492, 192, "");
130    vpack.set_spacing(4);
131    let mut text_editor = TextEditor::default().with_size(492, 163);
132
133    let mut hpack = Pack::new(4, 4, 492, 25, "").with_type(PackType::Horizontal);
134    hpack.set_spacing(8);
135    let mut font = Choice::default().with_size(130, 25);
136    let mut choice = Choice::default().with_size(130, 25);
137    let mut size = Spinner::default().with_size(60, 25);
138
139    let mut color = Choice::default().with_size(100, 25);
140    let mut btn_clear = Button::default().with_size(40, 25).with_label("X");
141    hpack.end();
142
143    vpack.end();
144    wind.end();
145    wind.show();
146
147    text_editor.wrap_mode(fltk::text::WrapMode::AtBounds, 0);
148    text_editor.set_buffer(TextBuffer::default());
149
150    font.add_choice("Courier|Helvetica|Times");
151    font.set_value(0);
152    font.set_tooltip("Font");
153
154    choice.add_choice("Normal|Underline|Strike");
155    choice.set_value(0);
156
157    size.set_value(18.0);
158    size.set_step(1.0);
159    size.set_range(12.0, 28.0);
160    size.set_tooltip("Size");
161
162    color.set_tooltip("Color");
163    color.add_choice("#000000|#ff0000|#00ff00|#0000ff|#ffff00|#00ffff");
164    color.set_value(0);
165
166    btn_clear.set_label_color(Color::Red);
167    btn_clear.set_tooltip("Clear style");
168
169    // set colors
170    for mut item in color.clone() {
171        if let Some(lbl) = item.label() {
172            item.set_label_color(Color::from_u32(
173                u32::from_str_radix(lbl.trim().strip_prefix('#').unwrap(), 16)
174                    .ok()
175                    .unwrap(),
176            ));
177        }
178    }
179
180    let style_rc1 = Rc::clone(&style);
181
182    text_editor.buffer().unwrap().add_modify_callback({
183        let mut text_editor1 = text_editor.clone();
184        let font1 = font.clone();
185        let size1 = size.clone();
186        let color1 = color.clone();
187        let choice1 = choice.clone();
188        move |_buf, pos: i32, ins_items: i32, del_items: i32, _: i32, _: Option<&str>| {
189            let attr = if choice1.value() == 1 {
190                TextAttr::Underline
191            } else if choice1.value() == 2 {
192                TextAttr::StrikeThrough
193            } else {
194                TextAttr::None
195            };
196            if ins_items > 0 || del_items > 0 {
197                let mut style = style_rc1.borrow_mut();
198                let color = Color::from_u32(
199                    u32::from_str_radix(
200                        color1
201                            .text(color1.value())
202                            .unwrap()
203                            .trim()
204                            .strip_prefix('#')
205                            .unwrap(),
206                        16,
207                    )
208                    .ok()
209                    .unwrap(),
210                );
211                style.apply_style(
212                    Some(pos),
213                    Some(ins_items),
214                    Some(del_items),
215                    None,
216                    None,
217                    Font::by_name(font1.text(font1.value()).unwrap().trim()),
218                    size1.value() as i32,
219                    color,
220                    attr,
221                    &mut text_editor1,
222                );
223            }
224        }
225    });
226
227    color.set_callback({
228        let size = size.clone();
229        let font = font.clone();
230        let choice = choice.clone();
231        let mut text_editor = text_editor.clone();
232        let style_rc1 = Rc::clone(&style);
233        move |color| {
234            let attr = match choice.value() {
235                0 => TextAttr::None,
236                1 => TextAttr::Underline,
237                2 => TextAttr::StrikeThrough,
238                _ => unreachable!(),
239            };
240            if let Some(buf) = text_editor.buffer() {
241                if let Some((s, e)) = buf.selection_position() {
242                    let mut style = style_rc1.borrow_mut();
243                    let color = Color::from_u32(
244                        u32::from_str_radix(
245                            color
246                                .text(color.value())
247                                .unwrap()
248                                .trim()
249                                .strip_prefix('#')
250                                .unwrap(),
251                            16,
252                        )
253                        .ok()
254                        .unwrap(),
255                    );
256                    style.apply_style(
257                        None,
258                        None,
259                        None,
260                        Some(s),
261                        Some(e),
262                        Font::by_name(font.text(font.value()).unwrap().trim()),
263                        size.value() as i32,
264                        color,
265                        attr,
266                        &mut text_editor,
267                    );
268                }
269            }
270        }
271    });
272
273    // get the style from the current cursor position
274    text_editor.handle({
275        let style_rc1 = Rc::clone(&style);
276        let mut font1 = font.clone();
277        let mut size1 = size.clone();
278        let mut color1 = color.clone();
279        move |te, e| match e {
280            Event::KeyUp | Event::Released => {
281                if let Some(buff) = te.style_buffer() {
282                    let i = te.insert_position();
283                    if let Some(t) = buff.text_range(i, i + 1) {
284                        if !t.is_empty() {
285                            let style = style_rc1.borrow_mut();
286                            if let Some(i) = t.chars().next().map(|c| (c as usize - 65)) {
287                                if let Some(style) = style.style_table.get(i) {
288                                    if let Some(mn) = font1.find_item(&format!("{:?}", style.font))
289                                    {
290                                        font1.set_item(&mn);
291                                    }
292                                    size1.set_value(style.size as f64);
293                                    let (r, g, b) = style.color.to_rgb();
294                                    if let Some(mn) =
295                                        color1.find_item(format!("{r:02x}{g:02x}{b:02x}").as_str())
296                                    {
297                                        color1.set_item(&mn);
298                                    }
299                                }
300                            }
301                        }
302                    }
303                }
304                true
305            }
306            _ => false,
307        }
308    });
309
310    choice.set_callback({
311        let mut color1 = color.clone();
312        move |_| color1.do_callback()
313    });
314
315    font.set_callback({
316        let mut color1 = color.clone();
317        move |_| color1.do_callback()
318    });
319
320    size.set_callback({
321        let mut color1 = color.clone();
322        move |_| color1.do_callback()
323    });
324
325    // clear style of the current selection or, if no text is selected, clear all text style
326    btn_clear.set_callback({
327        let style_rc1 = Rc::clone(&style);
328        let text_editor1 = text_editor.clone();
329        move |_| {
330            match text_editor1.buffer().unwrap().selection_position() {
331                Some((_, _)) => {
332                    font.set_value(0);
333                    size.set_value(18.0);
334                    color.set_value(0);
335                    choice.set_value(0);
336                    color.do_callback();
337                }
338                None => {
339                    font.set_value(0);
340                    size.set_value(18.0);
341                    color.set_value(0);
342                    style_rc1.borrow_mut().apply_style(
343                        None,
344                        None,
345                        None,
346                        Some(0),
347                        Some(text_editor1.buffer().unwrap().length()),
348                        Font::Courier,
349                        16,
350                        Color::Black,
351                        TextAttr::None,
352                        &mut text_editor,
353                    );
354                }
355            };
356        }
357    });
358
359    app.run().unwrap();
360}
Source

pub fn auto_layout(&mut self)

Layout the children of the pack automatically. Must be called on existing children

Examples found in repository?
examples/custom_popup.rs (line 73)
51    pub fn new(choices: &[&str]) -> Self {
52        let val = Rc::from(RefCell::from(String::from("")));
53        let mut win = window::Window::default().with_size(120, choices.len() as i32 * 25);
54        let mut pack = group::Pack::default().size_of_parent();
55        pack.set_frame(FrameType::ThinUpFrame);
56        pack.set_color(Color::Black);
57        win.set_border(false);
58        win.make_modal(true);
59        win.end();
60        for choice in choices {
61            let mut but = PopupButton::new(choice);
62            but.clear_visible_focus();
63            but.set_callback({
64                let mut win = win.clone();
65                let val = val.clone();
66                move |b| {
67                    *val.borrow_mut() = b.label().unwrap();
68                    win.hide();
69                }
70            });
71            pack.add(&*but);
72        }
73        pack.auto_layout();
74        Self { win, val }
75    }
More examples
Hide additional examples
examples/custom_choice.rs (line 79)
55    pub fn new(choices: &[&str]) -> Self {
56        let val = Rc::from(RefCell::from(String::from("")));
57        let idx = RefCell::from(0);
58        let mut win = window::Window::default().with_size(120, choices.len() as i32 * 25);
59        win.set_color(Color::White);
60        win.set_frame(FrameType::BorderBox);
61        let mut pack = group::Pack::new(1, 1, win.w() - 2, win.h() - 2, None);
62        win.set_border(false);
63        win.end();
64        for (i, choice) in choices.iter().enumerate() {
65            let mut but = PopupButton::new(choice);
66            but.clear_visible_focus();
67            but.set_callback({
68                let mut win = win.clone();
69                let val = val.clone();
70                let idx = idx.clone();
71                move |b| {
72                    *val.borrow_mut() = b.label().unwrap();
73                    *idx.borrow_mut() = i as i32;
74                    win.hide();
75                }
76            });
77            pack.add(&*but);
78        }
79        pack.auto_layout();
80        Self { win, val, idx }
81    }

Trait Implementations§

Source§

impl Clone for Pack

Source§

fn clone(&self) -> Pack

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Pack

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Pack

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl GroupExt for Pack

Source§

fn begin(&self)

Begins a group, used for widgets implementing the group trait
Source§

fn end(&self)

Ends a group, used for widgets implementing the group trait
Source§

fn clear(&mut self)

Clear a group from all widgets
Source§

fn children(&self) -> i32

Return the number of children in a group
Source§

fn child(&self, idx: i32) -> Option<Widget>

Return child widget by index
Source§

fn find<W: WidgetExt>(&self, widget: &W) -> i32

Find a widget within a group and return its index
Source§

fn add<W: WidgetExt>(&mut self, widget: &W)

Add a widget to a group
Source§

fn insert<W: WidgetExt>(&mut self, widget: &W, index: i32)

Insert a widget to a group at a certain index
Source§

fn remove<W: WidgetExt>(&mut self, widget: &W)

Remove a widget from a group, but does not delete it
Source§

fn remove_by_index(&mut self, idx: i32)

Remove a child widget by its index
Source§

fn resizable<W: WidgetExt>(&self, widget: &W)

The resizable widget defines both the resizing frame and the resizing behavior of the group and its children.
Source§

fn make_resizable(&mut self, val: bool)

Make the group itself resizable, should be called before the widget is shown
Source§

fn add_resizable<W: WidgetExt>(&mut self, widget: &W)

Adds a widget to the group and makes it the resizable widget
Source§

fn set_clip_children(&mut self, flag: bool)

Clips children outside the group boundaries
Source§

fn clip_children(&self) -> bool

Get whether clip_children is set
Source§

fn draw_child<W: WidgetExt>(&self, w: &mut W)

Draw a child widget, the call should be in a WidgetBase::draw method
Source§

fn update_child<W: WidgetExt>(&self, w: &mut W)

Update a child widget, the call should be in a WidgetBase::draw method
Source§

fn draw_outside_label<W: WidgetExt>(&self, w: &mut W)

Draw the outside label, the call should be in a WidgetBase::draw method
Source§

fn draw_children(&mut self)

Draw children, the call should be in a WidgetBase::draw method
Source§

fn init_sizes(&mut self)

Resets the internal array of widget sizes and positions
Source§

fn bounds(&self) -> Vec<(i32, i32, i32, i32)>

Get the bounds of all children widgets (left, upper, right, bottom)
Source§

unsafe fn as_group(&self) -> Group

Converts a widget implementing GroupExt into a Group widget Read more
Source§

impl IntoIterator for Pack

Source§

type Item = Widget

The type of the elements being iterated over.
Source§

type IntoIter = IntoIter<<Pack as IntoIterator>::Item>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl PartialEq for Pack

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl WidgetBase for Pack

Source§

fn delete(wid: Self)

Deletes widgets and their children.
Source§

unsafe fn from_widget_ptr(ptr: *mut Fl_Widget) -> Self

transforms a widget pointer to a Widget, for internal use Read more
Source§

unsafe fn from_widget<W: WidgetExt>(w: W) -> Self

Get a widget from base widget Read more
Source§

fn handle<F: FnMut(&mut Self, Event) -> bool + 'static>(&mut self, cb: F)

Set a custom handler, where events are managed manually, akin to Fl_Widget::handle(int). Handled or ignored events should return true, unhandled events should return false. takes the widget as a closure argument. The ability to handle an event might depend on handling other events, as explained here
Source§

fn draw<F: FnMut(&mut Self) + 'static>(&mut self, cb: F)

Set a custom draw method. takes the widget as a closure argument. macOS requires that WidgetBase::draw actually calls drawing functions
Source§

fn resize_callback<F: FnMut(&mut Self, i32, i32, i32, i32) + 'static>( &mut self, cb: F, )

Perform a callback on resize. Avoid resizing the parent or the same widget to avoid infinite recursion
Source§

unsafe fn assume_derived(&mut self)

Makes the widget derived Read more
Source§

fn from_dyn_widget<W: WidgetExt>(w: &W) -> Option<Self>

Cast a type-erased widget back to its original widget
Source§

fn from_dyn_widget_ptr(w: *mut Fl_Widget) -> Option<Self>

Cast a type-erased widget pointer back to its original widget
Source§

impl WidgetExt for Pack

Source§

fn set_label(&mut self, title: &str)

Sets the widget’s label. labels support special symbols preceded by an @ sign. and for the associated formatting.
Source§

fn unset_label(&mut self)

Unset a widget’s label
Source§

fn redraw(&mut self)

Redraws a widget, necessary for resizing and changing positions
Source§

fn show(&mut self)

Shows the widget
Source§

fn hide(&mut self)

Hides the widget
Source§

fn x(&self) -> i32

Returns the x coordinate of the widget
Source§

fn y(&self) -> i32

Returns the y coordinate of the widget
Source§

fn w(&self) -> i32

Returns the width of the widget
Source§

fn h(&self) -> i32

Returns the height of the widget
Source§

fn label(&self) -> Option<String>

Returns the label of the widget
Source§

fn measure_label(&self) -> (i32, i32)

Measures the label’s width and height
Source§

fn as_widget_ptr(&self) -> *mut Fl_Widget

transforms a widget to a base Fl_Widget, for internal use
Source§

fn activate(&mut self)

Activates the widget
Source§

fn deactivate(&mut self)

Deactivates the widget
Source§

fn redraw_label(&mut self)

Redraws the label of the widget
Source§

fn resize(&mut self, x: i32, y: i32, width: i32, height: i32)

Resizes and/or moves the widget, takes x, y, width and height
Source§

fn widget_resize(&mut self, x: i32, y: i32, width: i32, height: i32)

Does a simple resize ignoring class-specific resize functionality
Source§

fn tooltip(&self) -> Option<String>

Returns the tooltip text
Source§

fn set_tooltip(&mut self, txt: &str)

Sets the tooltip text
Source§

fn color(&self) -> Color

Returns the widget color
Source§

fn set_color(&mut self, color: Color)

Sets the widget’s color
Source§

fn label_color(&self) -> Color

Returns the widget label’s color
Source§

fn set_label_color(&mut self, color: Color)

Sets the widget label’s color
Source§

fn label_font(&self) -> Font

Returns the widget label’s font
Source§

fn set_label_font(&mut self, font: Font)

Sets the widget label’s font
Source§

fn label_size(&self) -> i32

Returns the widget label’s size
Source§

fn set_label_size(&mut self, sz: i32)

Sets the widget label’s size
Source§

fn label_type(&self) -> LabelType

Returns the widget label’s type
Source§

fn set_label_type(&mut self, typ: LabelType)

Sets the widget label’s type
Source§

fn frame(&self) -> FrameType

Returns the widget’s frame type
Source§

fn set_frame(&mut self, typ: FrameType)

Sets the widget’s frame type
Source§

fn changed(&self) -> bool

Returns whether the widget was changed
Source§

fn set_changed(&mut self)

Mark the widget as changed
Source§

fn clear_changed(&mut self)

Clears the changed status of the widget
Source§

fn align(&self) -> Align

Returns the alignment of the widget
Source§

fn set_align(&mut self, align: Align)

Sets the alignment of the widget
Source§

fn set_when(&mut self, trigger: When)

Sets the default callback trigger for a widget, equivalent to when()
Source§

fn when(&self) -> When

Return the callback trigger, equivalent to when()
Source§

fn parent(&self) -> Option<Group>

Returns the parent of the widget
Source§

fn selection_color(&self) -> Color

Gets the selection color of the widget
Source§

fn set_selection_color(&mut self, color: Color)

Sets the selection color of the widget
Source§

fn do_callback(&mut self)

Runs the already registered callback
Source§

fn window(&self) -> Option<Box<dyn WindowExt>>

Returns the direct window holding the widget
Source§

fn top_window(&self) -> Option<Box<dyn WindowExt>>

Returns the topmost window holding the widget
Source§

fn takes_events(&self) -> bool

Checks whether a widget is capable of taking events
Source§

fn take_focus(&mut self) -> Result<(), FltkError>

Make the widget take focus Read more
Source§

fn set_visible_focus(&mut self)

Set the widget to have visible focus
Source§

fn clear_visible_focus(&mut self)

Clear visible focus
Source§

fn visible_focus(&mut self, v: bool)

Set the visible focus using a flag
Source§

fn has_visible_focus(&self) -> bool

Return whether the widget has visible focus
Source§

fn has_focus(&self) -> bool

Return whether the widget has focus
Source§

fn was_deleted(&self) -> bool

Check if a widget was deleted
Source§

fn damage(&self) -> bool

Return whether the widget was damaged
Source§

fn set_damage(&mut self, flag: bool)

Signal the widget as damaged and it should be redrawn in the next event loop cycle
Source§

fn damage_type(&self) -> Damage

Return the damage mask
Source§

fn set_damage_type(&mut self, mask: Damage)

Signal the type of damage a widget received
Source§

fn set_damage_area(&mut self, mask: Damage, x: i32, y: i32, w: i32, h: i32)

Signal damage for an area inside the widget
Source§

fn clear_damage(&mut self)

Clear the damaged flag
Source§

fn as_window(&self) -> Option<Box<dyn WindowExt>>

Return the widget as a window if it’s a window
Source§

fn as_group(&self) -> Option<Group>

Return the widget as a group widget if it’s a group widget
Source§

fn inside<W: WidgetExt>(&self, wid: &W) -> bool

Checks whether the self widget is inside another widget
Source§

fn get_type<T: WidgetType>(&self) -> T

Returns the widget type when applicable
Source§

fn set_type<T: WidgetType>(&mut self, typ: T)

Sets the widget type
Source§

fn set_image<I: ImageExt>(&mut self, image: Option<I>)

Sets the image of the widget
Source§

fn set_image_scaled<I: ImageExt>(&mut self, image: Option<I>)

Sets the image of the widget scaled to the widget’s size
Source§

fn image(&self) -> Option<Box<dyn ImageExt>>

Gets the image associated with the widget
Source§

fn set_deimage<I: ImageExt>(&mut self, image: Option<I>)

Sets the deactivated image of the widget
Source§

fn set_deimage_scaled<I: ImageExt>(&mut self, image: Option<I>)

Sets the deactivated image of the widget scaled to the widget’s size
Source§

fn deimage(&self) -> Option<Box<dyn ImageExt>>

Gets the deactivated image associated with the widget
Source§

fn set_callback<F: FnMut(&mut Self) + 'static>(&mut self, cb: F)

Sets the callback when the widget is triggered (clicks for example) takes the widget as a closure argument
Source§

fn emit<T: 'static + Clone + Send + Sync>(&mut self, sender: Sender<T>, msg: T)

Emits a message on callback using a sender
Source§

unsafe fn as_widget<W: WidgetBase>(&self) -> W

Upcast a WidgetExt to some widget type Read more
Source§

fn visible(&self) -> bool

Returns whether a widget is visible
Source§

fn visible_r(&self) -> bool

Returns whether a widget or any of its parents are visible (recursively)
Source§

fn is_same<W: WidgetExt>(&self, other: &W) -> bool

Return whether two widgets object point to the same widget
Source§

fn active(&self) -> bool

Returns whether a widget is active
Source§

fn active_r(&self) -> bool

Returns whether a widget or any of its parents are active (recursively)
Source§

fn handle_event(&mut self, event: Event) -> bool

Handle a specific event
Source§

fn is_derived(&self) -> bool

Check whether a widget is derived
Source§

fn as_base_widget(&self) -> Widget
where Self: Sized,

Upcast a WidgetExt to a Widget
Source§

impl WidgetProps for Pack

Source§

fn with_pos(self, x: i32, y: i32) -> Self

Initialize to position x, y

Source§

fn with_size(self, width: i32, height: i32) -> Self

Initialize to size width, height

Source§

fn with_label(self, title: &str) -> Self

Initialize with a label

Source§

fn with_align(self, align: Align) -> Self

Initialize with alignment

Source§

fn with_type<T: WidgetType>(self, typ: T) -> Self

Initialize with type

Source§

fn below_of<W: WidgetExt>(self, wid: &W, padding: i32) -> Self

Initialize at bottom of another widget

Source§

fn above_of<W: WidgetExt>(self, wid: &W, padding: i32) -> Self

Initialize above of another widget

Source§

fn right_of<W: WidgetExt>(self, wid: &W, padding: i32) -> Self

Initialize right of another widget

Source§

fn left_of<W: WidgetExt>(self, wid: &W, padding: i32) -> Self

Initialize left of another widget

Source§

fn center_of<W: WidgetExt>(self, w: &W) -> Self

Initialize center of another widget

Source§

fn center_x<W: WidgetExt>(self, w: &W) -> Self

Initialize center of another widget on the x axis

Source§

fn center_y<W: WidgetExt>(self, w: &W) -> Self

Initialize center of another widget on the y axis

Source§

fn center_of_parent(self) -> Self

Initialize center of parent

Source§

fn size_of<W: WidgetExt>(self, w: &W) -> Self

Initialize to the size of another widget

Source§

fn size_of_parent(self) -> Self

Initialize to the size of the parent

Source§

impl Eq for Pack

Source§

impl Send for Pack

Available on non-crate feature single-threaded only.
Source§

impl Sync for Pack

Available on non-crate feature single-threaded only.

Auto Trait Implementations§

§

impl Freeze for Pack

§

impl RefUnwindSafe for Pack

§

impl Unpin for Pack

§

impl UnwindSafe for Pack

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<W> WidgetId<W> for W
where W: WidgetExt + Clone + Send + Sync + 'static,

Source§

fn set_id(&mut self, id: &str)

Set the widget’s Id
Source§

fn with_id(self, id: &str) -> W

Construct a widget with an Id