xref: /haiku/headers/os/interface/Menu.h (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
1 /*
2  * Copyright 2007-2013 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _MENU_H
6 #define _MENU_H
7 
8 
9 #include <InterfaceDefs.h>
10 #include <List.h>
11 #include <View.h>
12 
13 
14 class BMenu;
15 class BMenuBar;
16 class BMenuItem;
17 
18 
19 namespace BPrivate {
20 	class BMenuWindow;
21 	class ExtraMenuData;
22 	class TriggerList;
23 	class MenuPrivate;
24 }
25 
26 enum menu_layout {
27 	B_ITEMS_IN_ROW = 0,
28 	B_ITEMS_IN_COLUMN,
29 	B_ITEMS_IN_MATRIX
30 };
31 
32 struct menu_info {
33 	float		font_size;
34 	font_family	f_family;
35 	font_style	f_style;
36 	rgb_color	background_color;
37 	int32		separator;
38 	bool		click_to_open;
39 	bool		triggers_always_shown;
40 };
41 
42 status_t get_menu_info(menu_info* info);
43 status_t set_menu_info(menu_info* info);
44 
45 typedef bool (*menu_tracking_hook)(BMenu* menu, void* state);
46 
47 
48 class BMenu : public BView {
49 public:
50 								BMenu(const char* name,
51 									menu_layout layout = B_ITEMS_IN_COLUMN);
52 								BMenu(const char* name, float width,
53 									float height);
54 								BMenu(BMessage* archive);
55 
56 	virtual						~BMenu();
57 
58 	static	BArchivable*		Instantiate(BMessage* archive);
59 	virtual	status_t			Archive(BMessage* archive,
60 									bool deep = true) const;
61 
62 	virtual void				AttachedToWindow();
63 	virtual void				DetachedFromWindow();
64 	virtual void				AllAttached();
65 	virtual void				AllDetached();
66 
67 	virtual void				Draw(BRect updateRect);
68 
69 	virtual void				MessageReceived(BMessage* message);
70 	virtual	void				KeyDown(const char* bytes, int32 numBytes);
71 
72 	virtual	BSize				MinSize();
73 	virtual	BSize				MaxSize();
74 	virtual	BSize				PreferredSize();
75 	virtual void				GetPreferredSize(float* _width,
76 									float* _height);
77 	virtual void				ResizeToPreferred();
78 	virtual	void				DoLayout();
79 	virtual	void				FrameMoved(BPoint where);
80 	virtual	void				FrameResized(float width, float height);
81 
82 			void				InvalidateLayout();
83 
84 	virtual void				MakeFocus(bool focus = true);
85 
86 			bool				AddItem(BMenuItem* item);
87 			bool				AddItem(BMenuItem* item, int32 index);
88 			bool				AddItem(BMenuItem* item, BRect frame);
89 			bool				AddItem(BMenu* menu);
90 			bool				AddItem(BMenu* menu, int32 index);
91 			bool				AddItem(BMenu* menu, BRect frame);
92 			bool				AddList(BList* list, int32 index);
93 
94 			bool				AddSeparatorItem();
95 
96 			bool				RemoveItem(BMenuItem* item);
97 			BMenuItem*			RemoveItem(int32 index);
98 			bool				RemoveItems(int32 index, int32 count,
99 									bool deleteItems = false);
100 			bool				RemoveItem(BMenu* menu);
101 
102 			BMenuItem*			ItemAt(int32 index) const;
103 			BMenu*				SubmenuAt(int32 index) const;
104 			int32				CountItems() const;
105 			int32				IndexOf(BMenuItem* item) const;
106 			int32				IndexOf(BMenu* menu) const;
107 			BMenuItem*			FindItem(uint32 command) const;
108 			BMenuItem*			FindItem(const char* name) const;
109 
110 	virtual	status_t			SetTargetForItems(BHandler* target);
111 	virtual	status_t			SetTargetForItems(BMessenger messenger);
112 	virtual	void				SetEnabled(bool enable);
113 	virtual	void				SetRadioMode(bool on);
114 	virtual	void				SetTriggersEnabled(bool enable);
115 	virtual	void				SetMaxContentWidth(float maxWidth);
116 
117 			void				SetLabelFromMarked(bool on);
118 			bool				IsLabelFromMarked();
119 			bool				IsEnabled() const;
120 			bool				IsRadioMode() const;
121 			bool				AreTriggersEnabled() const;
122 			bool				IsRedrawAfterSticky() const;
123 			float				MaxContentWidth() const;
124 
125 			BMenuItem*			FindMarked();
126 			int32				FindMarkedIndex();
127 
128 			BMenu*				Supermenu() const;
129 			BMenuItem*			Superitem() const;
130 
131 
132 	virtual BHandler*			ResolveSpecifier(BMessage* message,
133 									int32 index, BMessage* specifier,
134 									int32 form, const char* property);
135 	virtual status_t			GetSupportedSuites(BMessage* data);
136 
137 	virtual status_t			Perform(perform_code d, void* arg);
138 
139 protected:
140 								BMenu(BRect frame, const char* name,
141 									uint32 resizeMask, uint32 flags,
142 									menu_layout layout, bool resizeToFit);
143 
144 	virtual	void				LayoutInvalidated(bool descendants);
145 
146 	virtual	BPoint				ScreenLocation();
147 
148 			void				SetItemMargins(float left, float top,
149 									float right, float bottom);
150 			void				GetItemMargins(float* _left, float* _top,
151 									float* _right, float* _bottom) const;
152 
153 			menu_layout			Layout() const;
154 
155 	virtual	void				Show();
156 			void				Show(bool selectFirstItem);
157 			void				Hide();
158 			BMenuItem*			Track(bool startOpened = false,
159 									BRect* specialRect = NULL);
160 
161 public:
162 	enum add_state {
163 		B_INITIAL_ADD,
164 		B_PROCESSING,
165 		B_ABORT
166 	};
167 	virtual	bool				AddDynamicItem(add_state state);
168 	virtual	void				DrawBackground(BRect updateRect);
169 
170 			void				SetTrackingHook(menu_tracking_hook hook,
171 									void* state);
172 
173 private:
174 	friend class BMenuBar;
175 	friend class BSeparatorItem;
176 	friend class BPrivate::MenuPrivate;
177 	friend status_t _init_interface_kit_();
178 	friend status_t	set_menu_info(menu_info* info);
179 	friend status_t	get_menu_info(menu_info* info);
180 
181 	struct LayoutData;
182 
183 	virtual	void				_ReservedMenu3();
184 	virtual	void				_ReservedMenu4();
185 	virtual	void				_ReservedMenu5();
186 	virtual	void				_ReservedMenu6();
187 
188 			BMenu&				operator=(const BMenu& other);
189 
190 			void				_InitData(BMessage* archive);
191 			bool				_Show(bool selectFirstItem = false,
192 									bool keyDown = false);
193 			void				_Hide();
194 			BMenuItem*			_Track(int* action, long start = -1);
195 			void				_ScriptReceived(BMessage* message);
196 			void				_ItemScriptReceived(BMessage* message,
197 									BMenuItem* item);
198 			status_t			_ResolveItemSpecifier(const BMessage& specifier,
199 									int32 what, BMenuItem*& item,
200 									int32 *index = NULL);
201 			status_t			_InsertItemAtSpecifier(
202 									const BMessage& specifier, int32 what,
203 									BMenuItem* item);
204 
205 			void				_UpdateNavigationArea(BPoint position,
206 									BRect& navAreaRectAbove,
207 									BRect& navAreaBelow);
208 
209 			void				_UpdateStateOpenSelect(BMenuItem* item,
210 									BPoint position, BRect& navAreaRectAbove,
211 									BRect& navAreaBelow,
212 									bigtime_t& selectedTime,
213 									bigtime_t& navigationAreaTime);
214 			void				_UpdateStateClose(BMenuItem* item,
215 									const BPoint& where,
216 									const uint32& buttons);
217 
218 			bool				_AddItem(BMenuItem* item, int32 index);
219 			bool				_RemoveItems(int32 index, int32 count,
220 									BMenuItem* item, bool deleteItems = false);
221 			bool				_RelayoutIfNeeded();
222 			void				_LayoutItems(int32 index);
223 			BSize				_ValidatePreferredSize();
224 			void				_ComputeLayout(int32 index, bool bestFit,
225 									bool moveItems, float* width,
226 									float* height);
227 			void				_ComputeColumnLayout(int32 index, bool bestFit,
228 									bool moveItems, BRect* override, BRect& outRect);
229 			void				_ComputeRowLayout(int32 index, bool bestFit,
230 									bool moveItems, BRect& outRect);
231 			void				_ComputeMatrixLayout(BRect& outRect);
232 
233 			BRect				_CalcFrame(BPoint where, bool* scrollOn);
234 
235 protected:
236 			void				DrawItems(BRect updateRect);
237 
238 private:
239 			bool				_OverSuper(BPoint loc);
240 			bool				_OverSubmenu(BMenuItem* item, BPoint loc);
241 			BPrivate::BMenuWindow* _MenuWindow();
242 			void				_DeleteMenuWindow();
243 			BMenuItem*			_HitTestItems(BPoint where,
244 									BPoint slop = B_ORIGIN) const;
245 			BRect				_Superbounds() const;
246 			void				_CacheFontInfo();
247 
248 			void				_ItemMarked(BMenuItem* item);
249 			void				_Install(BWindow* target);
250 			void				_Uninstall();
251 			void				_SelectItem(BMenuItem* item,
252 									bool showSubmenu = true,
253 									bool selectFirstItem = false,
254 									bool keyDown = false);
255 			bool				_SelectNextItem(BMenuItem* item, bool forward);
256 			BMenuItem*			_NextItem(BMenuItem* item, bool forward) const;
257 			void				_SetIgnoreHidden(bool ignoreHidden)
258 									{ fIgnoreHidden = ignoreHidden; }
259 			void				_SetStickyMode(bool on);
260 			bool				_IsStickyMode() const;
261 
262 			// Methods to get the current modifier keycode
263 			void				_GetShiftKey(uint32 &value) const;
264 			void				_GetControlKey(uint32 &value) const;
265 			void				_GetCommandKey(uint32 &value) const;
266 			void				_GetOptionKey(uint32 &value) const;
267 			void				_GetMenuKey(uint32 &value) const;
268 
269 			void				_CalcTriggers();
270 			bool				_ChooseTrigger(const char* title, int32& index,
271 									uint32& trigger,
272 									BPrivate::TriggerList& triggers);
273 			void				_UpdateWindowViewSize(const bool &updatePosition);
274 			bool				_AddDynamicItems(bool keyDown = false);
275 			bool				_OkToProceed(BMenuItem* item,
276 									bool keyDown = false);
277 
278 			bool				_CustomTrackingWantsToQuit();
279 
280 			int					_State(BMenuItem** _item = NULL) const;
281 			void				_InvokeItem(BMenuItem* item, bool now = false);
282 			void				_QuitTracking(bool onlyThis = true);
283 
284 	static	menu_info			sMenuInfo;
285 
286 			// Variables to keep track of what code is currently assigned to
287 			// each modifier key
288 	static	uint32				sShiftKey;
289 	static	uint32				sControlKey;
290 	static	uint32				sOptionKey;
291 	static	uint32				sCommandKey;
292 	static	uint32				sMenuKey;
293 
294 			BMenuItem*			fChosenItem;
295 			BList				fItems;
296 			BRect				fPad;
297 			BMenuItem*			fSelected;
298 			BPrivate::BMenuWindow* fCachedMenuWindow;
299 			BMenu*				fSuper;
300 			BMenuItem*			fSuperitem;
301 			BRect				fSuperbounds;
302 			float				fAscent;
303 			float				fDescent;
304 			float				fFontHeight;
305 			uint32				fState;
306 			menu_layout			fLayout;
307 			BRect*				fExtraRect;
308 			float				fMaxContentWidth;
309 			BPoint*				fInitMatrixSize;
310 			BPrivate::ExtraMenuData* fExtraMenuData;
311 
312 			LayoutData*			fLayoutData;
313 
314 			int32				_reserved;
315 
316 			char				fTrigger;
317 			bool				fResizeToFit;
318 			bool				fUseCachedMenuLayout;
319 			bool				fEnabled;
320 			bool				fDynamicName;
321 			bool				fRadioMode;
322 			bool				fTrackNewBounds;
323 			bool				fStickyMode;
324 			bool				fIgnoreHidden;
325 			bool				fTriggerEnabled;
326 			bool				fHasSubmenus;
327 			bool				fAttachAborted;
328 };
329 
330 #endif // _MENU_H
331