1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2002, OpenBeOS 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: Menubar.cpp 23 // Author: Marc Flerackers (mflerackers@androme.be) 24 // Description: BMenuBar is a menu that's at the root of a menu hierarchy. 25 //------------------------------------------------------------------------------ 26 27 // Standard Includes ----------------------------------------------------------- 28 29 // System Includes ------------------------------------------------------------- 30 #include <MenuBar.h> 31 #include <MenuItem.h> 32 #include <Window.h> 33 34 // Project Includes ------------------------------------------------------------ 35 36 // Local Includes -------------------------------------------------------------- 37 38 // Local Defines --------------------------------------------------------------- 39 40 // Globals --------------------------------------------------------------------- 41 42 //------------------------------------------------------------------------------ 43 BMenuBar::BMenuBar(BRect frame, const char *title, uint32 resizeMask, 44 menu_layout layout, bool resizeToFit) 45 : BMenu(frame, title, resizeMask, 46 B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE, layout, resizeToFit), 47 fBorder(B_BORDER_FRAME), 48 fTrackingPID(-1), 49 fPrevFocusToken(-1), 50 fMenuSem(-1), 51 fLastBounds(NULL), 52 fTracking(false) 53 { 54 // TODO: which flags to pass to BMenu? 55 InitData(layout); 56 } 57 //------------------------------------------------------------------------------ 58 BMenuBar::BMenuBar(BMessage *data) 59 : BMenu(data), 60 fBorder(B_BORDER_FRAME), 61 fTrackingPID(-1), 62 fPrevFocusToken(-1), 63 fMenuSem(-1), 64 fLastBounds(NULL), 65 fTracking(false) 66 { 67 int32 border; 68 69 if (data->FindInt32("_border", &border) == B_OK) 70 SetBorder((menu_bar_border)border); 71 } 72 //------------------------------------------------------------------------------ 73 BMenuBar::~BMenuBar() 74 { 75 } 76 //------------------------------------------------------------------------------ 77 BArchivable *BMenuBar::Instantiate(BMessage *data) 78 { 79 if ( validate_instantiation(data, "BMenuBar")) 80 return new BMenuBar(data); 81 else 82 return NULL; 83 } 84 //------------------------------------------------------------------------------ 85 status_t BMenuBar::Archive(BMessage *data, bool deep) const 86 { 87 status_t err = BMenu::Archive(data, deep); 88 89 if (err != B_OK) 90 return err; 91 92 if (Border() != B_BORDER_FRAME) 93 err = data->AddInt32("_border", Border()); 94 95 return err; 96 } 97 //------------------------------------------------------------------------------ 98 void BMenuBar::SetBorder(menu_bar_border border) 99 { 100 fBorder = border; 101 } 102 //------------------------------------------------------------------------------ 103 menu_bar_border BMenuBar::Border() const 104 { 105 return fBorder; 106 } 107 //------------------------------------------------------------------------------ 108 void BMenuBar::Draw(BRect updateRect) 109 { 110 // TODO: implement additional border styles 111 BRect bounds(Bounds()); 112 113 SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_LIGHTEN_2_TINT)); 114 StrokeLine(BPoint(0.0f, bounds.bottom - 2.0f ), BPoint(0.0f, 0.0f)); 115 StrokeLine(BPoint(bounds.right, 0.0f ) ); 116 117 SetHighColor(tint_color ( ui_color ( B_MENU_BACKGROUND_COLOR ), B_DARKEN_1_TINT)); 118 StrokeLine(BPoint ( 1.0f, bounds.bottom - 1.0f ), 119 BPoint(bounds.right, bounds.bottom - 1.0f ) ); 120 121 SetHighColor(tint_color(ui_color (B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); 122 StrokeLine(BPoint(0.0f, bounds.bottom), BPoint(bounds.right, bounds.bottom)); 123 StrokeLine(BPoint(bounds.right, 0.0f), BPoint(bounds.right, bounds.bottom)); 124 125 DrawItems(updateRect); 126 } 127 //------------------------------------------------------------------------------ 128 void BMenuBar::AttachedToWindow() 129 { 130 Install(Window()); 131 Window()->SetKeyMenuBar(this); 132 133 BMenu::AttachedToWindow(); 134 } 135 //------------------------------------------------------------------------------ 136 void BMenuBar::DetachedFromWindow() 137 { 138 BMenu::DetachedFromWindow(); 139 } 140 //------------------------------------------------------------------------------ 141 void BMenuBar::MessageReceived(BMessage *msg) 142 { 143 BMenu::MessageReceived(msg); 144 } 145 //------------------------------------------------------------------------------ 146 void BMenuBar::MouseDown(BPoint where) 147 { 148 StealFocus(); 149 BMenu::MouseDown(where); 150 151 // TODO: the real code should look like this: 152 /* 153 if (!Window()->IsActive()) 154 { 155 Window()->Activate(); 156 Window()->UpdateIfNeeded(); 157 } 158 159 StartMenuBar(); 160 */ 161 } 162 //------------------------------------------------------------------------------ 163 void BMenuBar::WindowActivated(bool state) 164 { 165 BView::WindowActivated(state); 166 } 167 //------------------------------------------------------------------------------ 168 void BMenuBar::MouseUp(BPoint where) 169 { 170 BMenu::MouseUp(where); 171 RestoreFocus(); 172 173 // BView::MouseUp(where); 174 } 175 //------------------------------------------------------------------------------ 176 void BMenuBar::FrameMoved(BPoint new_position) 177 { 178 BMenu::FrameMoved(new_position); 179 } 180 //------------------------------------------------------------------------------ 181 void BMenuBar::FrameResized(float new_width, float new_height) 182 { 183 BMenu::FrameResized(new_width, new_height); 184 } 185 //------------------------------------------------------------------------------ 186 void BMenuBar::Show() 187 { 188 BView::Show(); 189 } 190 //------------------------------------------------------------------------------ 191 void BMenuBar::Hide() 192 { 193 BView::Hide(); 194 } 195 //------------------------------------------------------------------------------ 196 BHandler *BMenuBar::ResolveSpecifier(BMessage *msg, int32 index, 197 BMessage *specifier, int32 form, 198 const char *property) 199 { 200 return BMenu::ResolveSpecifier(msg, index, specifier, form, property); 201 } 202 //------------------------------------------------------------------------------ 203 status_t BMenuBar::GetSupportedSuites(BMessage *data) 204 { 205 return BMenu::GetSupportedSuites(data); 206 } 207 //------------------------------------------------------------------------------ 208 void BMenuBar::ResizeToPreferred() 209 { 210 BMenu::ResizeToPreferred(); 211 } 212 //------------------------------------------------------------------------------ 213 void BMenuBar::GetPreferredSize(float *width, float *height) 214 { 215 BMenu::GetPreferredSize(width, height); 216 } 217 //------------------------------------------------------------------------------ 218 void BMenuBar::MakeFocus(bool state) 219 { 220 BMenu::MakeFocus(state); 221 } 222 //------------------------------------------------------------------------------ 223 void BMenuBar::AllAttached() 224 { 225 BMenu::AllAttached(); 226 } 227 //------------------------------------------------------------------------------ 228 void BMenuBar::AllDetached() 229 { 230 BMenu::AllDetached(); 231 } 232 //------------------------------------------------------------------------------ 233 status_t BMenuBar::Perform(perform_code d, void *arg) 234 { 235 return BMenu::Perform(d, arg); 236 } 237 //------------------------------------------------------------------------------ 238 void BMenuBar::_ReservedMenuBar1() {} 239 void BMenuBar::_ReservedMenuBar2() {} 240 void BMenuBar::_ReservedMenuBar3() {} 241 void BMenuBar::_ReservedMenuBar4() {} 242 //------------------------------------------------------------------------------ 243 BMenuBar &BMenuBar::operator=(const BMenuBar &) 244 { 245 return *this; 246 } 247 //------------------------------------------------------------------------------ 248 void BMenuBar::StartMenuBar(int32 menuIndex, bool sticky, bool show_menu, 249 BRect *special_rect) 250 { 251 /* 252 if (!Window()) 253 return; 254 255 Window()->Lock(); 256 Window()->MenusBeginning(); 257 sem_id = create_sem(??, ??); 258 set_menu_sem(BWindow, sem); 259 fTrackingPID = spawn_thread(TrackTask, "menu_tracking?", B_NORMAL_PRIORITY, ??); 260 Window()->Unlock(); 261 */ 262 } 263 //------------------------------------------------------------------------------ 264 long BMenuBar::TrackTask(void *arg) 265 { 266 return -1; 267 } 268 //------------------------------------------------------------------------------ 269 BMenuItem *BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu) 270 { 271 return NULL; 272 } 273 //------------------------------------------------------------------------------ 274 void BMenuBar::StealFocus() 275 { 276 //fPrevFocusToken = _get_object_token_(Window()->CurrentFocus()); 277 MakeFocus(); 278 } 279 //------------------------------------------------------------------------------ 280 void BMenuBar::RestoreFocus() 281 { 282 //fPrevFocusToken 283 } 284 //------------------------------------------------------------------------------ 285 void BMenuBar::InitData(menu_layout layout) 286 { 287 SetItemMargins(8, 2, 8, 2); 288 SetIgnoreHidden(true); 289 } 290 //------------------------------------------------------------------------------ 291