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