├── .gitignore ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md ├── examples ├── form.rs ├── grid_in_grid.rs └── simple.rs └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [0.4] - Unreleased 2 | - Use FLTK's new grid implementation. 3 | - Change debug() to show_grid(). 4 | - Change insert and insert_ext to set_widget and set_widget_ext. 5 | - Add set_layout_ext which takes a margin and a gap. 6 | - Require the call to Grid::end(). 7 | - set_widget and set_widget_ext no longer add the passed widgets as children automatically. 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fltk-grid" 3 | version = "0.4.1" 4 | edition = "2021" 5 | description = "A grid widget for fltk-rs" 6 | repository = "https://github.com/fltk-rs/fltk-grid" 7 | documentation = "https://docs.rs/fltk-grid" 8 | keywords = ["gui", "ui", "widgets", "bindings", "graphics"] 9 | categories = ["gui"] 10 | readme = "README.md" 11 | license = "MIT" 12 | 13 | [dependencies] 14 | fltk = "1.5.0" 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fltk-grid 2 | 3 | A grid widget for fltk-rs. This crate exists for backwards compatibility, since fltk 1.5 provides a Grid widget (under `fltk::group::Grid`). 4 | 5 | ## Usage 6 | ```toml 7 | [dependencies] 8 | fltk = "1.5.0" 9 | fltk-grid = "0.4" 10 | ``` 11 | 12 | Basically, the crate contains a single type Grid which has 4 main non-constructor methods: 13 | - set_layout(): specifies the number of rows and columns of the grid. 14 | - set_widget(): specifies the widget to be placed, along with in which cell (row, column). The values can be a range (0..1). 15 | - set_widget_ext(): adds to set_widget the row span and column span, in addition to the Grid Alignment. 16 | - resize(): determines how the grid is resized. 17 | - debug(): shows the cell outline and their numbering, useful for prototyping. 18 | 19 | 20 | ```rust 21 | use fltk::{prelude::*, *}; 22 | use fltk_grid::Grid; 23 | 24 | fn main() { 25 | let a = app::App::default().with_scheme(app::Scheme::Gtk); 26 | let mut win = window::Window::default().with_size(500, 300); 27 | let mut grid = Grid::default_fill(); 28 | grid.show_grid(false); // set to true to show cell outlines and numbers 29 | grid.set_layout(5, 5); // 5 rows, 5 columns 30 | grid.set_widget(&mut button::Button::default(), 0, 1); // widget, row, col 31 | grid.set_widget(&mut button::Button::default(), 2..3, 1..4); // widget, row range, col range 32 | // or 33 | // grid.set_widget_ext(&mut button::Button::default(), 2, 1, 1, 3, GridAlign::FILL); // widget, row, col, row_span, col_span 34 | grid.end(); 35 | win.end(); 36 | win.show(); 37 | a.run().unwrap(); 38 | } 39 | ``` 40 | 41 | ## Example 42 | Run `cargo run --example form` 43 | 44 | - [Form example](https://github.com/fltk-rs/fltk-grid/blob/main/examples/form.rs) 45 | 46 | ![image](https://user-images.githubusercontent.com/37966791/160347418-b8b54408-3dc9-4fc4-93e8-fb6c1c0282e9.png) 47 | 48 | Setting Grid::debug(true): 49 | 50 | ![image](https://user-images.githubusercontent.com/37966791/160346084-f3b0dad7-bd14-41da-99a0-768f7327ab2c.png) 51 | -------------------------------------------------------------------------------- /examples/form.rs: -------------------------------------------------------------------------------- 1 | use fltk::{prelude::*, *}; 2 | use fltk_grid::Grid; 3 | 4 | struct Form { 5 | grid: Grid, 6 | name: input::Input, 7 | age: input::IntInput, 8 | occupation: input::Input, 9 | btn: button::Button, 10 | } 11 | 12 | impl Form { 13 | pub fn default() -> Self { 14 | let mut grid = Grid::default_fill(); 15 | grid.set_layout(10, 5); // construct a new grid 16 | let name = input::Input::default(); 17 | let age = input::IntInput::default(); 18 | let occupation = input::Input::default(); 19 | let btn = button::Button::default().with_label("Submit"); 20 | let mut g = Self { 21 | grid, 22 | name, 23 | age, 24 | occupation, 25 | btn, 26 | }; 27 | g.fill(); 28 | g 29 | } 30 | 31 | fn fill(&mut self) { 32 | let grid = &mut self.grid; 33 | grid.show_grid(false); // set to true to see cell outlines 34 | let mut title = frame::Frame::default().with_label("Employee Form"); 35 | title.set_frame(enums::FrameType::FlatBox); 36 | title.set_color(enums::Color::Red); 37 | title.set_label_color(enums::Color::White); 38 | grid.set_widget( 39 | &mut title, 40 | 0, 41 | 1..4, 42 | ).unwrap(); 43 | grid.set_widget(&mut frame::Frame::default().with_label("Name"), 2, 1).unwrap(); 44 | grid.set_widget(&mut self.name, 2, 3).unwrap(); 45 | grid.set_widget(&mut frame::Frame::default().with_label("Age"), 4, 1).unwrap(); 46 | grid.set_widget(&mut self.age, 4, 3).unwrap(); 47 | grid.set_widget(&mut frame::Frame::default().with_label("Occupation"), 6, 1).unwrap(); 48 | grid.set_widget(&mut self.occupation, 6, 3).unwrap(); 49 | grid.set_widget(&mut self.btn, 8, 2).unwrap(); 50 | } 51 | 52 | fn register_default_callback(&mut self) { 53 | self.btn.set_callback({ 54 | let name = self.name.clone(); 55 | let age = self.age.clone(); 56 | let occupation = self.occupation.clone(); 57 | move |_| { 58 | println!("Name: {}", name.value()); 59 | println!("Age: {}", age.value()); 60 | println!("Occupation: {}", occupation.value()); 61 | } 62 | }); 63 | } 64 | 65 | pub fn resize(&mut self, x: i32, y: i32, w: i32, h: i32) { 66 | self.grid.resize(x, y, w, h); // determine how it's resized 67 | } 68 | } 69 | 70 | fn main() { 71 | let a = app::App::default().with_scheme(app::Scheme::Gtk); 72 | let mut win = window::Window::default().with_size(500, 300); 73 | let mut form = Form::default(); 74 | form.register_default_callback(); 75 | win.end(); 76 | win.make_resizable(true); 77 | win.show(); 78 | 79 | win.resize_callback(move |_, _, _, w, h| form.resize(0, 0, w, h)); 80 | 81 | a.run().unwrap(); 82 | } 83 | -------------------------------------------------------------------------------- /examples/grid_in_grid.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use fltk::{prelude::*, *}; 4 | use fltk_grid::Grid; 5 | 6 | struct Panel { 7 | grid: Grid, 8 | label: frame::Frame, 9 | cb1: button::CheckButton, 10 | cb2: button::CheckButton, 11 | btn: button::Button, 12 | } 13 | impl Panel { 14 | pub fn default() -> Self { 15 | let mut grid = Grid::default(); 16 | grid.show_grid(true); 17 | grid.set_layout(6, 1); 18 | let mut label = frame::Frame::default().with_label("ARTERY:"); 19 | 20 | let mut cb1 = button::CheckButton::default().with_label("Normal"); 21 | let mut cb2 = button::CheckButton::default().with_label("Normal"); 22 | 23 | let cbvec = vec![cb1.clone(), cb2.clone()]; 24 | 25 | let mut btn = button::Button::default().with_label("Submit"); 26 | grid.set_widget(&mut label, 0, 0).unwrap(); 27 | grid.set_widget(&mut cb1, 1, 0).unwrap(); 28 | grid.set_widget(&mut cb2, 2, 0).unwrap(); 29 | grid.set_widget(&mut btn, 5, 0).unwrap(); 30 | btn.set_callback(move |_btn| { 31 | for cb in cbvec.clone() { 32 | println!( 33 | "CB status: {}", 34 | if cb.is_checked() { 35 | "Checked" 36 | } else { 37 | "Not_checked" 38 | } 39 | ); 40 | } 41 | println!("--------------"); 42 | }); 43 | grid.end(); 44 | Panel { 45 | grid, 46 | label, 47 | cb1, 48 | cb2, 49 | btn, 50 | } 51 | } // end default fn; 52 | } // end impl Panel; 53 | 54 | fltk::widget_extends!(Panel, Grid, grid); 55 | 56 | fn main() { 57 | let a = app::App::default(); 58 | let mut win = window::Window::default().with_size(800, 600); 59 | let mut grid = Grid::default_fill(); 60 | grid.show_grid(true); 61 | grid.set_layout(1, 2); 62 | let mut panel1 = Panel::default(); 63 | let mut panel2 = Panel::default(); 64 | grid.set_widget(&mut *panel1, 0, 0).unwrap(); 65 | grid.set_widget(&mut *panel2, 0, 1).unwrap(); 66 | grid.end(); 67 | win.end(); 68 | win.make_resizable(true); 69 | win.show(); 70 | 71 | a.run().unwrap(); 72 | } 73 | -------------------------------------------------------------------------------- /examples/simple.rs: -------------------------------------------------------------------------------- 1 | use fltk::{prelude::*, *}; 2 | use fltk_grid::Grid; 3 | 4 | fn main() { 5 | let a = app::App::default().with_scheme(app::Scheme::Gtk); 6 | let mut win = window::Window::default().with_size(500, 300); 7 | let mut grid = Grid::default_fill(); 8 | grid.show_grid(false); // set to true to show cell outlines and numbers 9 | grid.set_layout(5, 5); // 5 rows, 5 columns 10 | grid.set_widget(&mut button::Button::default(), 0, 1).unwrap(); // widget, row, col 11 | grid.set_widget(&mut button::Button::default(), 2..3, 1..4).unwrap(); // widget, row range, col range 12 | // or 13 | // grid.set_widget_ext(&mut button::Button::default(), 2, 1, 1, 3, GridAlign::FILL).unwrap(); // widget, row, col, row_span, col_span 14 | grid.end(); 15 | win.end(); 16 | win.show(); 17 | a.run().unwrap(); 18 | dbg!(grid.children()); 19 | } 20 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::needless_doctest_main)] 2 | #![doc = include_str!("../README.md")] 3 | 4 | pub use fltk::group::Grid; 5 | --------------------------------------------------------------------------------