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