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