xref: /haiku/headers/os/interface/Menu.h (revision d2e1e872611179c9cfaa43ce11bd58b1e3554e4b)
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 	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, float height);
52 	virtual					~BMenu();
53 
54 							BMenu(BMessage* archive);
55 	static	BArchivable*	Instantiate(BMessage* archive);
56 	virtual	status_t		Archive(BMessage* archive, bool deep = true) const;
57 
58 	virtual void			AttachedToWindow();
59 	virtual void			DetachedFromWindow();
60 
61 			bool			AddItem(BMenuItem* item);
62 			bool			AddItem(BMenuItem* item, int32 index);
63 			bool			AddItem(BMenuItem* item, BRect frame);
64 			bool			AddItem(BMenu* menu);
65 			bool			AddItem(BMenu* menu, int32 index);
66 			bool			AddItem(BMenu* menu, BRect frame);
67 			bool			AddList(BList* list, int32 index);
68 
69 			bool			AddSeparatorItem();
70 
71 			bool			RemoveItem(BMenuItem* item);
72 			BMenuItem*		RemoveItem(int32 index);
73 			bool			RemoveItems(int32 index, int32 count,
74 								bool deleteItems = false);
75 			bool			RemoveItem(BMenu* menu);
76 
77 			BMenuItem*		ItemAt(int32 index) const;
78 			BMenu*			SubmenuAt(int32 index) const;
79 			int32			CountItems() const;
80 			int32			IndexOf(BMenuItem* item) const;
81 			int32			IndexOf(BMenu* menu) const;
82 			BMenuItem*		FindItem(uint32 command) const;
83 			BMenuItem*		FindItem(const char* name) const;
84 
85 	virtual	status_t		SetTargetForItems(BHandler* target);
86 	virtual	status_t		SetTargetForItems(BMessenger messenger);
87 	virtual	void			SetEnabled(bool state);
88 	virtual	void			SetRadioMode(bool state);
89 	virtual	void			SetTriggersEnabled(bool state);
90 	virtual	void			SetMaxContentWidth(float maxWidth);
91 
92 			void			SetLabelFromMarked(bool state);
93 			bool			IsLabelFromMarked();
94 			bool			IsEnabled() const;
95 			bool			IsRadioMode() const;
96 			bool			AreTriggersEnabled() const;
97 			bool			IsRedrawAfterSticky() const;
98 			float			MaxContentWidth() const;
99 
100 			BMenuItem*		FindMarked();
101 
102 			BMenu*			Supermenu() const;
103 			BMenuItem*		Superitem() const;
104 
105 	virtual void			MessageReceived(BMessage* message);
106 	virtual	void			KeyDown(const char* bytes, int32 numBytes);
107 	virtual void			Draw(BRect updateRect);
108 	virtual	BSize			MinSize();
109 	virtual	BSize			MaxSize();
110 	virtual	BSize			PreferredSize();
111 	virtual void			GetPreferredSize(float* _width, float* _height);
112 	virtual void			ResizeToPreferred();
113 	virtual	void			DoLayout();
114 	virtual	void			FrameMoved(BPoint newPosition);
115 	virtual	void			FrameResized(float newWidth, float newHeight);
116 			void			InvalidateLayout();
117 	virtual	void			InvalidateLayout(bool descendants);
118 
119 	virtual BHandler*		ResolveSpecifier(BMessage* message, int32 index,
120 								BMessage* specifier, int32 form,
121 								const char* property);
122 	virtual status_t		GetSupportedSuites(BMessage* data);
123 
124 	virtual status_t		Perform(perform_code d, void* arg);
125 
126 	virtual void			MakeFocus(bool focus = true);
127 	virtual void			AllAttached();
128 	virtual void			AllDetached();
129 
130 protected:
131 							BMenu(BRect frame, const char* name,
132 								uint32 resizeMask, uint32 flags,
133 								menu_layout layout, bool resizeToFit);
134 
135 	virtual	BPoint			ScreenLocation();
136 
137 			void			SetItemMargins(float left, float top, float right,
138 								float bottom);
139 			void			GetItemMargins(float* left, float* top,
140 								float* right, float* bottom) const;
141 
142 			menu_layout		Layout() const;
143 
144 	virtual	void			Show();
145 			void			Show(bool selectFirstItem);
146 			void			Hide();
147 			BMenuItem*		Track(bool startOpened = false,
148 								BRect* specialRect = NULL);
149 
150 public:
151 	enum add_state {
152 		B_INITIAL_ADD,
153 		B_PROCESSING,
154 		B_ABORT
155 	};
156 	virtual	bool			AddDynamicItem(add_state state);
157 	virtual void			DrawBackground(BRect update);
158 
159 			void			SetTrackingHook(menu_tracking_hook hook,
160 								void* state);
161 
162 private:
163 	friend class BMenuBar;
164 	friend class BPrivate::MenuPrivate;
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 			int				_State(BMenuItem** _item = NULL) const;
240 			void			_InvokeItem(BMenuItem* item, bool now = false);
241 			void			_QuitTracking(bool onlyThis = true);
242 
243 	static	menu_info		sMenuInfo;
244 	static	bool			sAltAsCommandKey;
245 
246 			BMenuItem*		fChosenItem;
247 			BList			fItems;
248 			BRect			fPad;
249 			BMenuItem*		fSelected;
250 			BPrivate::BMenuWindow* fCachedMenuWindow;
251 			BMenu*			fSuper;
252 			BMenuItem*		fSuperitem;
253 			BRect			fSuperbounds;
254 			float			fAscent;
255 			float			fDescent;
256 			float			fFontHeight;
257 			uint32			fState;
258 			menu_layout		fLayout;
259 			BRect*			fExtraRect;
260 			float			fMaxContentWidth;
261 			BPoint*			fInitMatrixSize;
262 			BPrivate::ExtraMenuData* fExtraMenuData;
263 
264 			LayoutData*		fLayoutData;
265 
266 			int32			_reserved;
267 
268 			char			fTrigger;
269 			bool			fResizeToFit;
270 			bool			fUseCachedMenuLayout;
271 			bool			fEnabled;
272 			bool			fDynamicName;
273 			bool			fRadioMode;
274 			bool			fTrackNewBounds;
275 			bool			fStickyMode;
276 			bool			fIgnoreHidden;
277 			bool			fTriggerEnabled;
278 			bool			fRedrawAfterSticky;
279 			bool			fAttachAborted;
280 };
281 
282 #endif	// _MENU_H
283