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 <algorithm> 40 41 #include <Bitmap.h> 42 #include <ControlLook.h> 43 #include <Debug.h> 44 #include <IconUtils.h> 45 #include <NodeInfo.h> 46 47 #include "icons.h" 48 49 #include "BarMenuTitle.h" 50 #include "BarView.h" 51 #include "BarWindow.h" 52 #include "DeskbarMenu.h" 53 #include "DeskbarUtils.h" 54 #include "ResourceSet.h" 55 #include "TeamMenu.h" 56 57 58 const float kSepItemWidth = 5.0f; 59 60 61 // #pragma mark - TSeparatorItem 62 63 64 TSeparatorItem::TSeparatorItem() 65 : 66 BSeparatorItem() 67 { 68 } 69 70 71 void 72 TSeparatorItem::Draw() 73 { 74 BMenu* menu = Menu(); 75 if (menu == NULL) 76 return; 77 78 BRect frame(Frame()); 79 frame.right = frame.left + kSepItemWidth; 80 rgb_color base = ui_color(B_MENU_BACKGROUND_COLOR); 81 82 menu->PushState(); 83 84 menu->SetHighColor(tint_color(base, 1.22)); 85 frame.top--; 86 // need to expand the frame for some reason 87 88 // stroke a darker line on the left edge 89 menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()); 90 frame.left++; 91 92 // fill in background 93 be_control_look->DrawButtonBackground(menu, frame, frame, base); 94 95 menu->PopState(); 96 } 97 98 99 // #pragma mark - TBarMenuBar 100 101 102 TBarMenuBar::TBarMenuBar(BRect frame, const char* name, TBarView* barView) 103 : 104 BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false), 105 fBarView(barView), 106 fAppListMenuItem(NULL), 107 fSeparatorItem(NULL) 108 { 109 SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f); 110 111 TDeskbarMenu* beMenu = new TDeskbarMenu(barView); 112 TBarWindow::SetDeskbarMenu(beMenu); 113 114 BBitmap* icon = NULL; 115 size_t dataSize; 116 const void* data = AppResSet()->FindResource(B_VECTOR_ICON_TYPE, 117 R_LeafLogoBitmap, &dataSize); 118 if (data != NULL) { 119 // Scale bitmap according to font size 120 float width = std::max(63.f, ceilf(63 * be_plain_font->Size() / 12.f)); 121 float height = std::max(22.f, ceilf(22 * be_plain_font->Size() / 12.f)); 122 icon = new BBitmap(BRect(0, 0, width - 1, height - 1), B_RGBA32); 123 if (icon->InitCheck() != B_OK 124 || BIconUtils::GetVectorIcon((const uint8*)data, dataSize, icon) 125 != B_OK) { 126 delete icon; 127 icon = NULL; 128 } 129 } 130 131 fDeskbarMenuItem = new TBarMenuTitle(0.0f, 0.0f, icon, beMenu); 132 AddItem(fDeskbarMenuItem); 133 } 134 135 136 TBarMenuBar::~TBarMenuBar() 137 { 138 } 139 140 141 void 142 TBarMenuBar::SmartResize(float width, float height) 143 { 144 if (width == -1.0f && height == -1.0f) { 145 BRect frame = Frame(); 146 width = frame.Width(); 147 height = frame.Height(); 148 } else 149 ResizeTo(width, height); 150 151 width -= 1; 152 153 if (fSeparatorItem != NULL) 154 fDeskbarMenuItem->SetContentSize(width - kSepItemWidth, height); 155 else { 156 int32 count = CountItems(); 157 if (fDeskbarMenuItem) 158 fDeskbarMenuItem->SetContentSize(width / count, height); 159 if (fAppListMenuItem) 160 fAppListMenuItem->SetContentSize(width / count, height); 161 } 162 163 InvalidateLayout(); 164 } 165 166 167 bool 168 TBarMenuBar::AddTeamMenu() 169 { 170 if (CountItems() > 1) 171 return false; 172 173 BRect frame(Frame()); 174 175 delete fAppListMenuItem; 176 fAppListMenuItem = new TBarMenuTitle(0.0f, 0.0f, 177 AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_TeamIcon), new TTeamMenu()); 178 179 bool added = AddItem(fAppListMenuItem); 180 181 if (added) 182 SmartResize(frame.Width() - 1.0f, frame.Height()); 183 else 184 SmartResize(frame.Width(), frame.Height()); 185 186 return added; 187 } 188 189 190 bool 191 TBarMenuBar::RemoveTeamMenu() 192 { 193 if (CountItems() < 2) 194 return false; 195 196 bool removed = false; 197 198 if (fAppListMenuItem != NULL && RemoveItem(fAppListMenuItem)) { 199 delete fAppListMenuItem; 200 fAppListMenuItem = NULL; 201 SmartResize(-1, -1); 202 removed = true; 203 } 204 205 return removed; 206 } 207 208 209 bool 210 TBarMenuBar::AddSeparatorItem() 211 { 212 if (CountItems() > 1) 213 return false; 214 215 BRect frame(Frame()); 216 217 delete fSeparatorItem; 218 fSeparatorItem = new TSeparatorItem(); 219 220 bool added = AddItem(fSeparatorItem); 221 222 if (added) 223 SmartResize(frame.Width() - 1.0f, frame.Height()); 224 else 225 SmartResize(frame.Width(), frame.Height()); 226 227 return added; 228 } 229 230 231 bool 232 TBarMenuBar::RemoveSeperatorItem() 233 { 234 if (CountItems() < 2) 235 return false; 236 237 bool removed = false; 238 239 if (fSeparatorItem != NULL && RemoveItem(fSeparatorItem)) { 240 delete fSeparatorItem; 241 fSeparatorItem = NULL; 242 SmartResize(-1, -1); 243 removed = true; 244 } 245 246 return removed; 247 } 248 249 250 void 251 TBarMenuBar::Draw(BRect updateRect) 252 { 253 // skip the fancy BMenuBar drawing code 254 BMenu::Draw(updateRect); 255 } 256 257 258 void 259 TBarMenuBar::DrawBackground(BRect updateRect) 260 { 261 BMenu::DrawBackground(updateRect); 262 } 263 264 265 void 266 TBarMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) 267 { 268 // the following code parallels that in ExpandoMenuBar for DnD tracking 269 270 if (!message) { 271 // force a cleanup 272 fBarView->DragStop(true); 273 BMenuBar::MouseMoved(where, code, message); 274 return; 275 } 276 277 switch (code) { 278 case B_ENTERED_VIEW: 279 { 280 BPoint loc; 281 uint32 buttons; 282 GetMouse(&loc, &buttons); 283 if (message != NULL && buttons != 0) { 284 // attempt to start DnD tracking 285 fBarView->CacheDragData(const_cast<BMessage*>(message)); 286 MouseDown(loc); 287 } 288 break; 289 } 290 } 291 292 BMenuBar::MouseMoved(where, code, message); 293 } 294 295 296 static void 297 init_tracking_hook(BMenuItem* item, bool (*hookFunction)(BMenu*, void*), 298 void* state) 299 { 300 if (!item) 301 return; 302 303 BMenu* windowMenu = item->Submenu(); 304 if (windowMenu) { 305 // have a menu, set the tracking hook 306 windowMenu->SetTrackingHook(hookFunction, state); 307 } 308 } 309 310 311 void 312 TBarMenuBar::InitTrackingHook(bool (*hookFunction)(BMenu*, void*), 313 void* state, bool both) 314 { 315 BPoint loc; 316 uint32 buttons; 317 GetMouse(&loc, &buttons); 318 // set the hook functions for the two menus 319 // will always have the deskbar menu 320 // may have the app menu as well (mini mode) 321 if (fDeskbarMenuItem->Frame().Contains(loc) || both) 322 init_tracking_hook(fDeskbarMenuItem, hookFunction, state); 323 324 if (fAppListMenuItem && (fAppListMenuItem->Frame().Contains(loc) || both)) 325 init_tracking_hook(fAppListMenuItem, hookFunction, state); 326 } 327