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