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}