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
// // Copyright (C) 2019 Robert Gill <locke@sdf.org> // // This file is a part of newt-rs. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License version 2.1 as published by the Free Software Foundation. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // use std::os::raw::c_void; use std::marker::PhantomData; use std::ptr; use crate::component::Component; use crate::widgets::{Form,VerticalScrollbar}; use crate::intern::funcs::*; use newt_sys::*; /// /// A callback called when `F1` is pressed while a `Form` is running. /// /// A new `Form` is initalized along with the callback associating the two /// together. The [`Form::new_with_help_callback()`][form] could also be used /// in lieu of `HelpCallback::new()`. /// /// [form]: ../widgets/form/struct.Form.html#method.new_with_help_callback /// /// ## Example /// ```rust no_run /// extern crate newt; /// use newt::prelude::*; /// /// pub fn main() { /// newt::init().unwrap(); /// newt::cls(); /// newt::centered_window(20, 6, Some("Help Test")).unwrap(); /// /// // Closure that will display a new window when `F1` is pressed. /// let f = |_form: &Form, data: Option<&&str>| { /// let string = data.unwrap_or(&"None"); /// let len = string.len(); /// /// let width = (len + 18) as u32; /// newt::centered_window(width, 5, Some("Help")).unwrap(); /// /// let text = format!("Help Text Data: {}", string); /// let label = Label::new(1, 1, &text); /// /// let pos = (width / 2 - 3) as i32; /// let ok = CompactButton::new(pos, 3, "Ok"); /// /// let mut form = Form::new(None, 0); /// form.add_component(&label).unwrap(); /// form.add_component(&ok).unwrap(); /// form.run().unwrap(); /// newt::pop_window(); /// }; /// /// // `Form` is allocated with the callback and both are associated. /// let label = Label::new(1, 1, "Press F1 for help!"); /// let ok = CompactButton::new(7, 4, "Ok"); /// /// let (mut form, _cb) = /// Form::new_with_help_callback(None, 0, f, Some("This is help text.")); /// form.add_components(&[&label, &ok]).unwrap(); /// /// form.run().unwrap(); /// newt::finished(); /// } /// ``` pub struct HelpCallback<'a, FN, T> where FN: FnMut(&Form, Option<&T>) { function: FN, data: Option<T>, form: PhantomData<Form<'a>> } impl<'a, FN, T> HelpCallback<'a, FN, T> where FN: FnMut(&Form, Option<&T>) { /// /// Initialize a new `Form` and associate the function or closure /// `function` as a HelpCallback. The callback will be executed /// when `F1` is pressed while the `Form` is running. The new `Form` /// and `HelpCallback` are returned as a tuple pair. /// /// * `scrollbar` - A `VerticalScrollbar` to be attached to the created /// form. /// * `form_flags` - The flags the form is to be initialized with. /// * `function` - The function or closure to associate with the `Form`. /// * `data` - The optional user data to pass to the function. /// pub fn new(scrollbar: Option<&VerticalScrollbar>, form_flags: i32, function: FN, data: Option<T>) -> (Form<'a>, Box<HelpCallback<'a, FN, T>>) { let cb = Box::new(HelpCallback { function, data, form: PhantomData }); newt_init_help_callback(cb.as_ref()); let scrollbar = if let Some(scrollbar) = scrollbar { scrollbar.co() } else { ptr::null_mut() }; let c_ptr = cb.as_ref() as *const _ as *mut c_void; let co = unsafe { newtForm(scrollbar, c_ptr, form_flags) }; let form = Form::new_co(co); (form, cb) } pub(crate) fn call(&mut self, form: &Form<'a>) { (self.function)(form, self.data.as_ref()) } }