newt/asm/grid/
mod.rs

1//
2// Copyright (C) 2019 Robert Gill <rtgill82@gmail.com>
3//
4// This file is a part of newt-rs.
5//
6// This library is free software; you can redistribute it and/or
7// modify it under the terms of the GNU Lesser General Public
8// License version 2.1 as published by the Free Software Foundation.
9//
10// This library is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13// Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public
16// License along with this library; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18//
19
20use std::cell::Cell;
21use std::ffi::{CString,c_void};
22use std::os::raw::c_char;
23use newt_sys::*;
24
25use crate::component::Component;
26use crate::intern::ComponentPtr;
27use crate::grid::r#trait;
28
29#[doc(hidden)]
30pub mod basic_window;
31#[doc(hidden)]
32pub mod button_bar;
33#[doc(hidden)]
34pub mod horizontal_grid;
35#[doc(hidden)]
36pub mod simple_window;
37#[doc(hidden)]
38pub mod vertical_grid;
39
40#[doc(inline)]
41pub use self::basic_window::BasicWindow;
42#[doc(inline)]
43pub use self::button_bar::ButtonBar;
44#[doc(inline)]
45pub use self::horizontal_grid::HorizontalGrid;
46#[doc(inline)]
47pub use self::simple_window::SimpleWindow;
48#[doc(inline)]
49pub use self::vertical_grid::VerticalGrid;
50
51///
52/// Arrange `Component`s and sub-grids within a two-dimensional grid.
53///
54/// Component screen positions will automatically be calculated based
55/// on their position in the grid.
56///
57#[derive(Grid)]
58pub struct Grid<'a> {
59    grid: Cell<newtGrid>,
60    added_to_parent: Cell<bool>,
61    children: Vec<&'a dyn Component>,
62    cols: i32,
63    rows: i32
64}
65
66impl<'a> Grid<'a> {
67    ///
68    /// Create a new Grid with the specified columns and rows.
69    ///
70    pub fn new(cols: i32, rows: i32) -> Grid<'a> {
71        assert!(cols > 0, "`cols` must be greater than 0");
72        assert!(rows > 0, "`rows` must be greater than 0");
73
74        Grid {
75            grid: unsafe { Cell::new(newtCreateGrid(cols, rows)) },
76            added_to_parent: Cell::new(false),
77            children: Vec::new(),
78            cols, rows
79        }
80    }
81
82    ///
83    /// Add a component or sub-grid to the positon (`col`, `row`) in the grid.
84    ///
85    pub fn set_field(&mut self, col: i32, row: i32, val: &'a dyn Component,
86                     pad_left: i32, pad_top: i32, pad_right: i32,
87                     pad_bottom: i32, anchor: i32, flags: i32) {
88
89        if col >= self.cols || row >= self.rows {
90            panic!("Attempting to set a field at an invalid position ({}, {})", col, row);
91        }
92
93        let r#type = val.grid_element_type();
94        let co = val.co();
95        self.children.push(val);
96
97        unsafe {
98            newtGridSetField(self.grid_ptr(), col, row, r#type,
99                             co as *mut c_void, pad_left, pad_top, pad_right,
100                             pad_bottom, anchor, flags);
101        }
102    }
103}
104
105///
106/// Wrap a `Grid` in a centered window.
107///
108pub fn wrapped_window(grid: &dyn r#trait::Grid, title: &str) {
109    let c_str = CString::new(title).unwrap();
110    unsafe {
111        newtGridWrappedWindow(grid.grid_ptr(), c_str.as_ptr() as *mut c_char);
112    }
113}
114
115///
116/// Wrap a `Grid` in a window at a specified location.
117///
118pub fn wrapped_window_at(grid: &dyn r#trait::Grid, title: &str,
119                         left: i32, top: i32) {
120    let c_str = CString::new(title).unwrap();
121    unsafe {
122        newtGridWrappedWindowAt(grid.grid_ptr(), c_str.as_ptr() as *mut c_char,
123                                left, top);
124    }
125}