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