mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-24 03:41:29 +11:00
Merge menu-api-rework -> master
Rewrote Menu API
This commit is contained in:
parent
1dbcf2dee1
commit
b5f3cf1ca3
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
This project follows semantic versioning.
|
This project follows semantic versioning.
|
||||||
|
|
||||||
|
### v0.7.0 (2016-05-12)
|
||||||
|
|
||||||
|
- [changed] - Fully rewrote the Menu API. See the documentation/menu example for the changes.
|
||||||
|
- [added] - Added ```Window::get_unix_menus``` to get data access to menus on Linux/x11
|
||||||
|
|
||||||
### v0.6.0 (2016-05-01)
|
### v0.6.0 (2016-05-01)
|
||||||
|
|
||||||
- [added] added ```get_size()``` to retrive the size of the window.
|
- [added] added ```get_size()``` to retrive the size of the window.
|
||||||
|
|
|
@ -14,7 +14,7 @@ Usage
|
||||||
```toml
|
```toml
|
||||||
# Cargo.toml
|
# Cargo.toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
minifb = "0.6.0"
|
minifb = "0.7.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
Example
|
Example
|
||||||
|
|
|
@ -44,6 +44,10 @@ fn main() {
|
||||||
|
|
||||||
let menu_handle = window.add_menu(&menu);
|
let menu_handle = window.add_menu(&menu);
|
||||||
|
|
||||||
|
window.get_unix_menus().map(|menus| {
|
||||||
|
println!("Menus {:?}", menus);
|
||||||
|
});
|
||||||
|
|
||||||
let mut color_mul = 1;
|
let mut color_mul = 1;
|
||||||
|
|
||||||
while window.is_open() && !window.is_key_down(Key::Escape) {
|
while window.is_open() && !window.is_key_down(Key::Escape) {
|
||||||
|
|
175
src/lib.rs
175
src/lib.rs
|
@ -1,3 +1,11 @@
|
||||||
|
//! minifb is a cross platform library written in [Rust](https://www.rust-lang.org) that makes to
|
||||||
|
//! open windows (usually native to the running operating system) and can optionally show a 32-bit
|
||||||
|
//! buffer. minifb also support keyboard, mouse input and menus on selected operating systems.
|
||||||
|
//!
|
||||||
|
extern crate libc;
|
||||||
|
|
||||||
|
use std::os::raw;
|
||||||
|
|
||||||
/// Scale will scale the frame buffer and the window that is being sent in when calling the update
|
/// Scale will scale the frame buffer and the window that is being sent in when calling the update
|
||||||
/// function. This is useful if you for example want to display a 320 x 256 window on a screen with
|
/// function. This is useful if you for example want to display a 320 x 256 window on a screen with
|
||||||
/// much higher resolution which would result in that the window is very small.
|
/// much higher resolution which would result in that the window is very small.
|
||||||
|
@ -60,17 +68,19 @@ pub trait InputCallback {
|
||||||
fn add_char(&mut self, uni_char: u32);
|
fn add_char(&mut self, uni_char: u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern crate libc;
|
|
||||||
|
|
||||||
use std::os::raw;
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
mod error;
|
mod error;
|
||||||
pub use self::error::Error;
|
pub use self::error::Error;
|
||||||
|
#[doc(hidden)]
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
pub mod key;
|
pub mod key;
|
||||||
|
#[doc(hidden)]
|
||||||
pub use key::Key as Key;
|
pub use key::Key as Key;
|
||||||
|
#[doc(hidden)]
|
||||||
pub mod os;
|
pub mod os;
|
||||||
mod mouse_handler;
|
mod mouse_handler;
|
||||||
mod key_handler;
|
mod key_handler;
|
||||||
|
@ -95,6 +105,10 @@ use self::os::windows as imp;
|
||||||
target_os="openbsd"))]
|
target_os="openbsd"))]
|
||||||
use self::os::unix as imp;
|
use self::os::unix as imp;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Window is used to open up a window. It's possible to optionally display a 32-bit buffer when
|
||||||
|
/// the widow is set as non-resizable.
|
||||||
|
///
|
||||||
pub struct Window(imp::Window);
|
pub struct Window(imp::Window);
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -112,31 +126,6 @@ pub struct WindowOptions {
|
||||||
pub scale: Scale
|
pub scale: Scale
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// Window is used to open up a window. It's possible to optionally display a 32-bit buffer when
|
|
||||||
/// the widow is set as non-resizable.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Open up a window and display a 32-bit RGB buffer (without error checking)
|
|
||||||
///
|
|
||||||
/// ```ignore
|
|
||||||
/// const WIDTH: usize = 640;
|
|
||||||
/// const HEIGHT: usize = 360;
|
|
||||||
///
|
|
||||||
/// let mut buffer: Vec<u32> = vec![0; WIDTH * HEIGHT];
|
|
||||||
///
|
|
||||||
/// let mut window = match Window::new("Test - Press ESC to exit", WIDTH, HEIGHT,
|
|
||||||
/// WindowOptions::default()).unwrap()
|
|
||||||
///
|
|
||||||
/// while window.is_open() && !window.is_key_down(Key::Escape) {
|
|
||||||
/// for i in buffer.iter_mut() {
|
|
||||||
/// *i = 0; // write something interesting here
|
|
||||||
/// }
|
|
||||||
/// window.update_with_buffer(&buffer);
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
impl Window {
|
impl Window {
|
||||||
///
|
///
|
||||||
/// Opens up a new window
|
/// Opens up a new window
|
||||||
|
@ -449,7 +438,7 @@ impl Window {
|
||||||
|
|
||||||
///
|
///
|
||||||
/// This allows adding menus to your windows. As menus behaves a bit diffrently depending on
|
/// This allows adding menus to your windows. As menus behaves a bit diffrently depending on
|
||||||
/// Operating system here is how it works. See [Menu] for description on each field.
|
/// Operating system here is how it works.
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// Windows:
|
/// Windows:
|
||||||
|
@ -459,33 +448,41 @@ impl Window {
|
||||||
/// on which window you have active.
|
/// on which window you have active.
|
||||||
/// Linux/BSD/etc:
|
/// Linux/BSD/etc:
|
||||||
/// Menus aren't supported as they depend on each WindowManager and is outside of the
|
/// Menus aren't supported as they depend on each WindowManager and is outside of the
|
||||||
/// scope for this library to support.
|
/// scope for this library to support. Use [get_unix_menus] to get a structure
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_menu(&mut self, menu: &Menu) -> MenuHandle {
|
pub fn add_menu(&mut self, menu: &Menu) -> MenuHandle {
|
||||||
self.0.add_menu(&menu.0)
|
self.0.add_menu(&menu.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Updates an existing menu created with [add_menu]
|
/// Remove a menu that has been added with [#add_menu]
|
||||||
///
|
|
||||||
/*
|
|
||||||
#[inline]
|
|
||||||
pub fn update_menu(&mut self, menu_name: &str, menu: &Vec<Menu>) -> Result<()> {
|
|
||||||
self.0.update_menu(menu_name, menu)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Remove a menu that has been added with [add_menu]
|
|
||||||
///
|
///
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn remove_menu(&mut self, handle: MenuHandle) {
|
pub fn remove_menu(&mut self, handle: MenuHandle) {
|
||||||
self.0.remove_menu(handle)
|
self.0.remove_menu(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get Unix menu. Will only return menus on Unix class OSes
|
||||||
|
/// otherwise ```None```
|
||||||
|
///
|
||||||
|
#[cfg(any(target_os="macos",
|
||||||
|
target_os="windows"))]
|
||||||
|
pub fn get_unix_menus(&self) -> Option<&Vec<UnixMenu>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_os="linux",
|
||||||
|
target_os="freebsd",
|
||||||
|
target_os="dragonfly",
|
||||||
|
target_os="netbsd",
|
||||||
|
target_os="openbsd"))]
|
||||||
|
pub fn get_unix_menus(&self) -> Option<&Vec<UnixMenu>> {
|
||||||
|
self.0.get_unix_menus()
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Check if a menu item has been pressed
|
/// Check if a menu item has been pressed
|
||||||
///
|
///
|
||||||
|
@ -509,39 +506,94 @@ pub const MENU_KEY_ALT: usize = 16;
|
||||||
|
|
||||||
const MENU_ID_SEPARATOR:usize = 0xffffffff;
|
const MENU_ID_SEPARATOR:usize = 0xffffffff;
|
||||||
|
|
||||||
pub struct Menu(imp::Menu);
|
///
|
||||||
|
/// Used on Unix (Linux, FreeBSD, etc) as menus aren't supported in a native where there.
|
||||||
|
/// This structure can be used by calling [#get_unix_menus] on Window.
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct UnixMenu {
|
||||||
|
/// Name of the menu
|
||||||
|
pub name: String,
|
||||||
|
/// All items of the menu.
|
||||||
|
pub items: Vec<UnixMenuItem>,
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub handle: MenuHandle,
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub item_counter: MenuItemHandle,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
///
|
||||||
|
/// Used for on Unix (Linux, FreeBSD, etc) as menus aren't supported in a native where there.
|
||||||
|
/// This structure holds info for each item in a #UnixMenu
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct UnixMenuItem {
|
||||||
|
/// Set to a menu if there is a Item is a sub_menu otherwise None
|
||||||
|
pub sub_menu: Option<Box<UnixMenu>>,
|
||||||
|
/// Handle of the MenuItem
|
||||||
|
pub handle: MenuItemHandle,
|
||||||
|
/// Id of the item (set by the user from the outside and should be reported back when pressed)
|
||||||
|
pub id: usize,
|
||||||
|
/// Name of the item
|
||||||
|
pub label: String,
|
||||||
|
/// Set to true if enabled otherwise false
|
||||||
|
pub enabled: bool,
|
||||||
|
/// Shortcut key
|
||||||
|
pub key: Key,
|
||||||
|
/// Modifier for the key (Shift, Ctrl, etc)
|
||||||
|
pub modifier: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
#[doc(hidden)]
|
||||||
pub struct MenuItemHandle(pub u64);
|
pub struct MenuItemHandle(pub u64);
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
#[doc(hidden)]
|
||||||
pub struct MenuHandle(pub u64);
|
pub struct MenuHandle(pub u64);
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Menu holds info for menus
|
||||||
|
///
|
||||||
|
pub struct Menu(imp::Menu);
|
||||||
|
|
||||||
impl Menu {
|
impl Menu {
|
||||||
|
/// Create a new menu. Returns error if failed
|
||||||
pub fn new(name: &str) -> Result<Menu> {
|
pub fn new(name: &str) -> Result<Menu> {
|
||||||
imp::Menu::new(name).map(Menu)
|
imp::Menu::new(name).map(Menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Destroys a menu. Currently not implemented
|
||||||
pub fn destroy_menu(&mut self) {
|
pub fn destroy_menu(&mut self) {
|
||||||
//self.0.destroy_menu()
|
//self.0.destroy_menu()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Adds a sub menu to the current menu
|
||||||
pub fn add_sub_menu(&mut self, name: &str, menu: &Menu) {
|
pub fn add_sub_menu(&mut self, name: &str, menu: &Menu) {
|
||||||
self.0.add_sub_menu(name, &menu.0)
|
self.0.add_sub_menu(name, &menu.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a menu separator
|
||||||
pub fn add_separator(&mut self) {
|
pub fn add_separator(&mut self) {
|
||||||
self.add_menu_item(&MenuItem { id: MENU_ID_SEPARATOR, ..MenuItem::default() });
|
self.add_menu_item(&MenuItem { id: MENU_ID_SEPARATOR, ..MenuItem::default() });
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Adds an item to the menu
|
||||||
pub fn add_menu_item(&mut self, item: &MenuItem) -> MenuItemHandle {
|
pub fn add_menu_item(&mut self, item: &MenuItem) -> MenuItemHandle {
|
||||||
self.0.add_menu_item(item)
|
self.0.add_menu_item(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Adds an item to the menu. Notice that you need to call "build" to finish the add
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// menu.add_item("test", 1).shortcut(Key::A, 0).build()
|
||||||
|
/// ```
|
||||||
pub fn add_item(&mut self, name: &str, id: usize) -> MenuItem {
|
pub fn add_item(&mut self, name: &str, id: usize) -> MenuItem {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
id: id,
|
id: id,
|
||||||
|
@ -552,17 +604,22 @@ impl Menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Removes an item from the menu
|
||||||
pub fn remove_item(&mut self, item: &MenuItemHandle) {
|
pub fn remove_item(&mut self, item: &MenuItemHandle) {
|
||||||
self.0.remove_item(item)
|
self.0.remove_item(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Holds info about each item in a menu
|
||||||
|
///
|
||||||
pub struct MenuItem<'a> {
|
pub struct MenuItem<'a> {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
pub label: String,
|
pub label: String,
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub key: Key,
|
pub key: Key,
|
||||||
pub modifier: usize,
|
pub modifier: usize,
|
||||||
|
#[doc(hidden)]
|
||||||
pub menu: Option<&'a mut Menu>,
|
pub menu: Option<&'a mut Menu>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,6 +650,7 @@ impl<'a> Clone for MenuItem<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MenuItem<'a> {
|
impl<'a> MenuItem<'a> {
|
||||||
|
/// Creates a new menu item
|
||||||
pub fn new(name: &str, id: usize) -> MenuItem {
|
pub fn new(name: &str, id: usize) -> MenuItem {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
id: id,
|
id: id,
|
||||||
|
@ -601,6 +659,13 @@ impl<'a> MenuItem<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Sets a shortcut key and modifer (and returns itself)
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// menu.add_item("test", 1).shortcut(Key::A, 0).build()
|
||||||
|
/// ```
|
||||||
pub fn shortcut(self, key: Key, modifier: usize) -> Self {
|
pub fn shortcut(self, key: Key, modifier: usize) -> Self {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
key: key,
|
key: key,
|
||||||
|
@ -609,6 +674,14 @@ impl<'a> MenuItem<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Sets item to a separator
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// menu.add_item("", 0).separator().build()
|
||||||
|
/// ```
|
||||||
|
/// Notice that it's usually easier to just call ```menu.add_separator()``` directly
|
||||||
pub fn separator(self) -> Self {
|
pub fn separator(self) -> Self {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
id: MENU_ID_SEPARATOR,
|
id: MENU_ID_SEPARATOR,
|
||||||
|
@ -616,6 +689,13 @@ impl<'a> MenuItem<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Sets the menu item disabled/or not
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// menu.add_item("test", 1).enabled(false).build()
|
||||||
|
/// ```
|
||||||
pub fn enabled(self, enabled: bool) -> Self {
|
pub fn enabled(self, enabled: bool) -> Self {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
|
@ -623,6 +703,13 @@ impl<'a> MenuItem<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
/// Must be called to finialize building of a menu item when started with ```menu.add_item()```
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// menu.add_item("test", 1).enabled(false).build()
|
||||||
|
/// ```
|
||||||
pub fn build(&mut self) -> MenuItemHandle {
|
pub fn build(&mut self) -> MenuItemHandle {
|
||||||
let t = self.clone();
|
let t = self.clone();
|
||||||
if let Some(ref mut menu) = self.menu {
|
if let Some(ref mut menu) = self.menu {
|
||||||
|
|
|
@ -599,7 +599,7 @@ impl Menu {
|
||||||
item_name.as_ptr(),
|
item_name.as_ptr(),
|
||||||
item.enabled,
|
item.enabled,
|
||||||
conv_key,
|
conv_key,
|
||||||
item.modifier))
|
item.modifier as u32))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,11 @@ extern crate x11_dl;
|
||||||
|
|
||||||
use {MouseMode, MouseButton, Scale, Key, KeyRepeat, WindowOptions, InputCallback};
|
use {MouseMode, MouseButton, Scale, Key, KeyRepeat, WindowOptions, InputCallback};
|
||||||
use key_handler::KeyHandler;
|
use key_handler::KeyHandler;
|
||||||
use menu::Menu;
|
//use menu::Menu;
|
||||||
use self::x11_dl::keysym::*;
|
use self::x11_dl::keysym::*;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use Result;
|
use Result;
|
||||||
|
use {MenuItem, MenuItemHandle, MenuHandle, UnixMenu, UnixMenuItem};
|
||||||
|
|
||||||
use libc::{c_void, c_char, c_uchar};
|
use libc::{c_void, c_char, c_uchar};
|
||||||
use std::ffi::{CString};
|
use std::ffi::{CString};
|
||||||
|
@ -52,6 +53,8 @@ pub struct Window {
|
||||||
window_handle: *mut c_void,
|
window_handle: *mut c_void,
|
||||||
shared_data: SharedData,
|
shared_data: SharedData,
|
||||||
key_handler: KeyHandler,
|
key_handler: KeyHandler,
|
||||||
|
menu_counter: MenuHandle,
|
||||||
|
menus: Vec<UnixMenu>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
|
@ -195,6 +198,8 @@ impl Window {
|
||||||
.. SharedData::default()
|
.. SharedData::default()
|
||||||
},
|
},
|
||||||
key_handler: KeyHandler::new(),
|
key_handler: KeyHandler::new(),
|
||||||
|
menu_counter: MenuHandle(0),
|
||||||
|
menus: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,20 +355,88 @@ impl Window {
|
||||||
return factor;
|
return factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_menu(&mut self, _menu_name: &str, _menu: &Vec<Menu>) -> Result<()> {
|
fn next_menu_handle(&mut self) -> MenuHandle {
|
||||||
Err(Error::MenusNotSupported)
|
let handle = self.menu_counter;
|
||||||
|
self.menu_counter.0 += 1;
|
||||||
|
handle
|
||||||
}
|
}
|
||||||
pub fn update_menu(&mut self, _menu_name: &str, _menu: &Vec<Menu>) -> Result<()> {
|
|
||||||
Err(Error::MenusNotSupported)
|
pub fn add_menu(&mut self, menu: &Menu) -> MenuHandle {
|
||||||
|
let handle = self.next_menu_handle();
|
||||||
|
let mut menu = menu.internal.clone();
|
||||||
|
menu.handle = handle;
|
||||||
|
self.menus.push(menu);
|
||||||
|
handle
|
||||||
}
|
}
|
||||||
pub fn remove_menu(&mut self, _menu_name: &str) -> Result<()> {
|
|
||||||
Err(Error::MenusNotSupported)
|
pub fn get_unix_menus(&self) -> Option<&Vec<UnixMenu>> {
|
||||||
|
Some(&self.menus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_menu(&mut self, handle: MenuHandle) {
|
||||||
|
self.menus.retain(|ref menu| menu.handle != handle);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_menu_pressed(&mut self) -> Option<usize> {
|
pub fn is_menu_pressed(&mut self) -> Option<usize> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Menu {
|
||||||
|
pub internal: UnixMenu,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Menu {
|
||||||
|
pub fn new(name: &str) -> Result<Menu> {
|
||||||
|
Ok(Menu {
|
||||||
|
internal: UnixMenu {
|
||||||
|
handle: MenuHandle(0),
|
||||||
|
item_counter: MenuItemHandle(0),
|
||||||
|
name: name.to_owned(),
|
||||||
|
items: Vec::new(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_sub_menu(&mut self, name: &str, sub_menu: &Menu) {
|
||||||
|
let handle = self.next_item_handle();
|
||||||
|
self.internal.items.push(UnixMenuItem {
|
||||||
|
label: name.to_owned(),
|
||||||
|
handle: handle,
|
||||||
|
sub_menu: Some(Box::new(sub_menu.internal.clone())),
|
||||||
|
id: 0,
|
||||||
|
enabled: true,
|
||||||
|
key: Key::Unknown,
|
||||||
|
modifier: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_item_handle(&mut self) -> MenuItemHandle {
|
||||||
|
let handle = self.internal.item_counter;
|
||||||
|
self.internal.item_counter.0 += 1;
|
||||||
|
handle
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_menu_item(&mut self, item: &MenuItem) -> MenuItemHandle {
|
||||||
|
let item_handle = self.next_item_handle();
|
||||||
|
self.internal.items.push(UnixMenuItem {
|
||||||
|
sub_menu: None,
|
||||||
|
handle: self.internal.item_counter,
|
||||||
|
id: item.id,
|
||||||
|
label: item.label.clone(),
|
||||||
|
enabled: item.enabled,
|
||||||
|
key: item.key,
|
||||||
|
modifier: item.modifier,
|
||||||
|
});
|
||||||
|
item_handle
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_item(&mut self, handle: &MenuItemHandle) {
|
||||||
|
self.internal.items.retain(|ref item| item.handle.0 != handle.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
Loading…
Reference in a new issue