1 /* 2 Open Tracker License 3 4 Terms and Conditions 5 6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy of 9 this software and associated documentation files (the "Software"), to deal in 10 the Software without restriction, including without limitation the rights to 11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 of the Software, and to permit persons to whom the Software is furnished to do 13 so, subject to the following conditions: 14 15 The above copyright notice and this permission notice applies to all licensees 16 and shall be included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 Except as contained in this notice, the name of Be Incorporated shall not be 26 used in advertising or otherwise to promote the sale, use or other dealings in 27 this Software without prior written authorization from Be Incorporated. 28 29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered 30 trademarks of Be Incorporated in the United States and other countries. Other 31 brand product names are registered trademarks or trademarks of their respective 32 holders. 33 All rights reserved. 34 */ 35 36 37 #include "BarMenuBar.h" 38 39 #include <Bitmap.h> 40 #include <ControlLook.h> 41 #include <Debug.h> 42 #include <NodeInfo.h> 43 44 #include "icons.h" 45 46 #include "BarMenuTitle.h" 47 #include "BarView.h" 48 #include "BarWindow.h" 49 #include "DeskbarMenu.h" 50 #include "DeskbarUtils.h" 51 #include "ResourceSet.h" 52 #include "TeamMenu.h" 53 54 55 const float kSepItemWidth = 5.0f; 56 57 58 // #pragma mark - TSeparatorItem 59 60 61 TSeparatorItem::TSeparatorItem() 62 : 63 BSeparatorItem() 64 { 65 } 66 67 68 void 69 TSeparatorItem::Draw() 70 { 71 BMenu* menu = Menu(); 72 if (menu == NULL) 73 return; 74 75 BRect frame(Frame()); 76 frame.right = frame.left + kSepItemWidth; 77 rgb_color base = menu->LowColor(); 78 79 menu->PushState(); 80 81 menu->SetHighColor(tint_color(base, 1.22)); 82 frame.top--; 83 // need to expand the frame for some reason 84 85 // stroke a darker line on the left edge 86 menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()); 87 frame.left++; 88 89 // fill in background 90 be_control_look->DrawButtonBackground(menu, frame, frame, base); 91 92 menu->PopState(); 93 } 94 95 96 // #pragma mark - TBarMenuBar 97 98 99 TBarMenuBar::TBarMenuBar(BRect frame, const char* name, TBarView* barView) 100 : 101 BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false), 102 fBarView(barView), 103 fAppListMenuItem(NULL), 104 fSeparatorItem(NULL) 105 { 106 SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f); 107 108 TDeskbarMenu* beMenu = new TDeskbarMenu(barView); 109 TBarWindow::SetDeskbarMenu(beMenu); 110 111 fDeskbarMenuItem = new TBarMenuTitle(0.0f, 0.0f, 112 AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_LeafLogoBitmap), beMenu); 113 AddItem(fDeskbarMenuItem); 114 } 115 116 117 TBarMenuBar::~TBarMenuBar() 118 { 119 } 120 121 122 void 123 TBarMenuBar::SmartResize(float width, float height) 124 { 125 if (width == -1.0f && height == -1.0f) { 126 BRect frame = Frame(); 127 width = frame.Width(); 128 height = frame.Height(); 129 } else 130 ResizeTo(width, height); 131 132 width -= 1; 133 134 if (fSeparatorItem != NULL) 135 fDeskbarMenuItem->SetContentSize(width - kSepItemWidth, height); 136 else { 137 int32 count = CountItems(); 138 if (fDeskbarMenuItem) 139 fDeskbarMenuItem->SetContentSize(width / count, height); 140 if (fAppListMenuItem) 141 fAppListMenuItem->SetContentSize(width / count, height); 142 } 143 144 InvalidateLayout(); 145 } 146 147 148 bool 149 TBarMenuBar::AddTeamMenu() 150 { 151 if (CountItems() > 1) 152 return false; 153 154 BRect frame(Frame()); 155 156 delete fAppListMenuItem; 157 fAppListMenuItem = new TBarMenuTitle(0.0f, 0.0f, 158 AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_TeamIcon), new TTeamMenu()); 159 160 bool added = AddItem(fAppListMenuItem); 161 162 if (added) 163 SmartResize(frame.Width() - 1.0f, frame.Height()); 164 else 165 SmartResize(frame.Width(), frame.Height()); 166 167 return added; 168 } 169 170 171 bool 172 TBarMenuBar::RemoveTeamMenu() 173 { 174 if (CountItems() < 2) 175 return false; 176 177 bool removed = false; 178 179 if (fAppListMenuItem != NULL && RemoveItem(fAppListMenuItem)) { 180 delete fAppListMenuItem; 181 fAppListMenuItem = NULL; 182 SmartResize(-1, -1); 183 removed = true; 184 } 185 186 return removed; 187 } 188 189 190 bool 191 TBarMenuBar::AddSeparatorItem() 192 { 193 if (CountItems() > 1) 194 return false; 195 196 BRect frame(Frame()); 197 198 delete fSeparatorItem; 199 fSeparatorItem = new TSeparatorItem(); 200 201 bool added = AddItem(fSeparatorItem); 202 203 if (added) 204 SmartResize(frame.Width() - 1.0f, frame.Height()); 205 else 206 SmartResize(frame.Width(), frame.Height()); 207 208 return added; 209 } 210 211 212 bool 213 TBarMenuBar::RemoveSeperatorItem() 214 { 215 if (CountItems() < 2) 216 return false; 217 218 bool removed = false; 219 220 if (fSeparatorItem != NULL && RemoveItem(fSeparatorItem)) { 221 delete fSeparatorItem; 222 fSeparatorItem = NULL; 223 SmartResize(-1, -1); 224 removed = true; 225 } 226 227 return removed; 228 } 229 230 231 void 232 TBarMenuBar::Draw(BRect updateRect) 233 { 234 // skip the fancy BMenuBar drawing code 235 BMenu::Draw(updateRect); 236 } 237 238 239 void 240 TBarMenuBar::DrawBackground(BRect updateRect) 241 { 242 BMenu::DrawBackground(updateRect); 243 } 244 245 246 void 247 TBarMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) 248 { 249 // the following code parallels that in ExpandoMenuBar for DnD tracking 250 251 if (!message) { 252 // force a cleanup 253 fBarView->DragStop(true); 254 BMenuBar::MouseMoved(where, code, message); 255 return; 256 } 257 258 switch (code) { 259 case B_ENTERED_VIEW: 260 { 261 BPoint loc; 262 uint32 buttons; 263 GetMouse(&loc, &buttons); 264 if (message != NULL && buttons != 0) { 265 // attempt to start DnD tracking 266 fBarView->CacheDragData(const_cast<BMessage*>(message)); 267 MouseDown(loc); 268 } 269 break; 270 } 271 } 272 273 BMenuBar::MouseMoved(where, code, message); 274 } 275 276 277 static void 278 init_tracking_hook(BMenuItem* item, bool (*hookFunction)(BMenu*, void*), 279 void* state) 280 { 281 if (!item) 282 return; 283 284 BMenu* windowMenu = item->Submenu(); 285 if (windowMenu) { 286 // have a menu, set the tracking hook 287 windowMenu->SetTrackingHook(hookFunction, state); 288 } 289 } 290 291 292 void 293 TBarMenuBar::InitTrackingHook(bool (*hookFunction)(BMenu*, void*), 294 void* state, bool both) 295 { 296 BPoint loc; 297 uint32 buttons; 298 GetMouse(&loc, &buttons); 299 // set the hook functions for the two menus 300 // will always have the deskbar menu 301 // may have the app menu as well (mini mode) 302 if (fDeskbarMenuItem->Frame().Contains(loc) || both) 303 init_tracking_hook(fDeskbarMenuItem, hookFunction, state); 304 305 if (fAppListMenuItem && (fAppListMenuItem->Frame().Contains(loc) || both)) 306 init_tracking_hook(fAppListMenuItem, hookFunction, state); 307 } 308