druid_win_shell/
menu.rs

1// Copyright 2018 The xi-editor Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Safe wrapper for menus.
16
17use std::mem;
18use std::ptr::null;
19
20use winapi::shared::basetsd::*;
21use winapi::shared::windef::*;
22use winapi::um::winuser::*;
23
24use util::ToWide;
25
26/// A menu object, which can be either a top-level menubar or a
27/// submenu.
28pub struct Menu {
29    hmenu: HMENU,
30}
31
32impl Drop for Menu {
33    fn drop(&mut self) {
34        unsafe {
35            DestroyMenu(self.hmenu);
36        }
37    }
38}
39
40impl Menu {
41    pub fn new() -> Menu {
42        unsafe {
43            let hmenu = CreateMenu();
44            Menu { hmenu }
45        }
46    }
47
48    pub fn into_hmenu(self) -> HMENU {
49        let hmenu = self.hmenu;
50        mem::forget(self);
51        hmenu
52    }
53
54    /// Add a dropdown menu. This takes the menu by ownership, but we'll
55    /// probably want to change that so we can manipulate it later.
56    /// 
57    /// The `text` field has all the fun behavior of winapi CreateMenu.
58    pub fn add_dropdown(&mut self, menu: Menu, text: &str) {
59        unsafe {
60            AppendMenuW(self.hmenu, MF_POPUP, menu.into_hmenu() as UINT_PTR,
61                text.to_wide().as_ptr());
62        }
63    }
64
65    /// Add an item to the menu.
66    pub fn add_item(&mut self, id: u32, text: &str) {
67        unsafe {
68            AppendMenuW(self.hmenu, MF_STRING, id as UINT_PTR, text.to_wide().as_ptr());
69        }
70    }
71
72    /// Add a separator to the menu.
73    pub fn add_separator(&mut self) {
74        unsafe {
75            AppendMenuW(self.hmenu, MF_SEPARATOR, 0, null());
76        }
77    }
78}