xref: /haiku/headers/os/interface/Menu.h (revision 60b39cd7416028e61e3d30bb3ba28bd3526e6001)
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 newPosition);
80 	virtual	void				FrameResized(float newWidth, float newHeight);
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 BPrivate::MenuPrivate;
176 	friend status_t _init_interface_kit_();
177 	friend status_t	set_menu_info(menu_info* info);
178 	friend status_t	get_menu_info(menu_info* info);
179 
180 	struct LayoutData;
181 
182 	virtual	void				_ReservedMenu3();
183 	virtual	void				_ReservedMenu4();
184 	virtual	void				_ReservedMenu5();
185 	virtual	void				_ReservedMenu6();
186 
187 			BMenu&				operator=(const BMenu& other);
188 
189 			void				_InitData(BMessage* archive);
190 			bool				_Show(bool selectFirstItem = false,
191 									bool keyDown = false);
192 			void				_Hide();
193 			BMenuItem*			_Track(int* action, long start = -1);
194 
195 			void				_UpdateNavigationArea(BPoint position,
196 									BRect& navAreaRectAbove,
197 									BRect& navAreaBelow);
198 
199 			void				_UpdateStateOpenSelect(BMenuItem* item,
200 									BPoint position, BRect& navAreaRectAbove,
201 									BRect& navAreaBelow,
202 									bigtime_t& selectedTime,
203 									bigtime_t& navigationAreaTime);
204 			void				_UpdateStateClose(BMenuItem* item,
205 									const BPoint& where,
206 									const uint32& buttons);
207 
208 			bool				_AddItem(BMenuItem* item, int32 index);
209 			bool				_RemoveItems(int32 index, int32 count,
210 									BMenuItem* item, bool deleteItems = false);
211 			bool				_RelayoutIfNeeded();
212 			void				_LayoutItems(int32 index);
213 			BSize				_ValidatePreferredSize();
214 			void				_ComputeLayout(int32 index, bool bestFit,
215 									bool moveItems, float* width,
216 									float* height);
217 			void				_ComputeColumnLayout(int32 index, bool bestFit,
218 									bool moveItems, BRect* override, BRect& outRect);
219 			void				_ComputeRowLayout(int32 index, bool bestFit,
220 									bool moveItems, BRect& outRect);
221 			void				_ComputeMatrixLayout(BRect& outRect);
222 
223 			BRect				_CalcFrame(BPoint where, bool* scrollOn);
224 
225 protected:
226 			void				_DrawItems(BRect updateRect);
227 
228 private:
229 			bool				_OverSuper(BPoint loc);
230 			bool				_OverSubmenu(BMenuItem* item, BPoint loc);
231 			BPrivate::BMenuWindow* _MenuWindow();
232 			void				_DeleteMenuWindow();
233 			BMenuItem*			_HitTestItems(BPoint where,
234 									BPoint slop = B_ORIGIN) const;
235 			BRect				_Superbounds() const;
236 			void				_CacheFontInfo();
237 
238 			void				_ItemMarked(BMenuItem* item);
239 			void				_Install(BWindow* target);
240 			void				_Uninstall();
241 			void				_SelectItem(BMenuItem* item,
242 									bool showSubmenu = true,
243 									bool selectFirstItem = false,
244 									bool keyDown = false);
245 			bool				_SelectNextItem(BMenuItem* item, bool forward);
246 			BMenuItem*			_NextItem(BMenuItem* item, bool forward) const;
247 			void				_SetIgnoreHidden(bool on);
248 			void				_SetStickyMode(bool on);
249 			bool				_IsStickyMode() const;
250 
251 			// Methods to get the current modifier keycode
252 			void				_GetShiftKey(uint32 &value) const;
253 			void				_GetControlKey(uint32 &value) const;
254 			void				_GetCommandKey(uint32 &value) const;
255 			void				_GetOptionKey(uint32 &value) const;
256 			void				_GetMenuKey(uint32 &value) const;
257 
258 			void				_CalcTriggers();
259 			bool				_ChooseTrigger(const char* title, int32& index,
260 									uint32& trigger,
261 									BPrivate::TriggerList& triggers);
262 			void				_UpdateWindowViewSize(const bool &updatePosition);
263 			bool				_AddDynamicItems(bool keyDown = false);
264 			bool				_OkToProceed(BMenuItem* item,
265 									bool keyDown = false);
266 
267 			bool				_CustomTrackingWantsToQuit();
268 
269 			int					_State(BMenuItem** _item = NULL) const;
270 			void				_InvokeItem(BMenuItem* item, bool now = false);
271 			void				_QuitTracking(bool onlyThis = true);
272 
273 	static	menu_info			sMenuInfo;
274 
275 			// Variables to keep track of what code is currently assigned to
276 			// each modifier key
277 	static	uint32				sShiftKey;
278 	static	uint32				sControlKey;
279 	static	uint32				sOptionKey;
280 	static	uint32				sCommandKey;
281 	static	uint32				sMenuKey;
282 
283 			BMenuItem*			fChosenItem;
284 			BList				fItems;
285 			BRect				fPad;
286 			BMenuItem*			fSelected;
287 			BPrivate::BMenuWindow* fCachedMenuWindow;
288 			BMenu*				fSuper;
289 			BMenuItem*			fSuperitem;
290 			BRect				fSuperbounds;
291 			float				fAscent;
292 			float				fDescent;
293 			float				fFontHeight;
294 			uint32				fState;
295 			menu_layout			fLayout;
296 			BRect*				fExtraRect;
297 			float				fMaxContentWidth;
298 			BPoint*				fInitMatrixSize;
299 			BPrivate::ExtraMenuData* fExtraMenuData;
300 
301 			LayoutData*			fLayoutData;
302 
303 			int32				_reserved;
304 
305 			char				fTrigger;
306 			bool				fResizeToFit;
307 			bool				fUseCachedMenuLayout;
308 			bool				fEnabled;
309 			bool				fDynamicName;
310 			bool				fRadioMode;
311 			bool				fTrackNewBounds;
312 			bool				fStickyMode;
313 			bool				fIgnoreHidden;
314 			bool				fTriggerEnabled;
315 			bool				fRedrawAfterSticky;
316 			bool				fAttachAborted;
317 };
318 
319 #endif // _MENU_H
320