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: BMCPrivate.cpp 23 // Author: Marc Flerackers (mflerackers@androme.be) 24 // Description: The BMCPrivate classes are used by BMenuField. 25 //------------------------------------------------------------------------------ 26 27 // Standard Includes ----------------------------------------------------------- 28 29 // System Includes ------------------------------------------------------------- 30 #include <BMCPrivate.h> 31 #include <MenuField.h> 32 #include <MenuItem.h> 33 #include <Message.h> 34 #include <Region.h> 35 #include <Window.h> 36 37 // Project Includes ------------------------------------------------------------ 38 39 // Local Includes -------------------------------------------------------------- 40 41 // Local Defines --------------------------------------------------------------- 42 43 // Globals --------------------------------------------------------------------- 44 45 //------------------------------------------------------------------------------ 46 _BMCItem_::_BMCItem_(BMenu *menu) 47 : BMenuItem(menu), 48 fShowPopUpMarker(true) 49 { 50 } 51 //------------------------------------------------------------------------------ 52 _BMCItem_::_BMCItem_(BMessage *message) 53 : BMenuItem(message), 54 fShowPopUpMarker(true) 55 { 56 } 57 //------------------------------------------------------------------------------ 58 _BMCItem_::~_BMCItem_() 59 { 60 } 61 //------------------------------------------------------------------------------ 62 BArchivable *_BMCItem_::Instantiate(BMessage *data) 63 { 64 if (validate_instantiation(data, "_BMCItem_")) 65 return new _BMCItem_(data); 66 else 67 return NULL; 68 } 69 //------------------------------------------------------------------------------ 70 void _BMCItem_::Draw() 71 { 72 BMenuItem::Draw(); 73 74 if (!fShowPopUpMarker) 75 return; 76 77 BMenu *menu = Menu(); 78 BRect rect(menu->Bounds()); 79 80 rect.right -= 4; 81 rect.bottom -= 5; 82 rect.left = rect.right - 4; 83 rect.top = rect.bottom - 2; 84 85 if (IsEnabled()) 86 menu->SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), 87 B_DARKEN_4_TINT)); 88 else 89 menu->SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), 90 B_DARKEN_4_TINT)); 91 92 menu->StrokeLine(BPoint(rect.left, rect.top), BPoint(rect.right, rect.top)); 93 menu->StrokeLine(BPoint(rect.left + 1.0f, rect.top + 1.0f), 94 BPoint(rect.right - 1.0f, rect.top + 1.0f)); 95 menu->StrokeLine(BPoint(rect.left + 2.0f, rect.bottom), 96 BPoint(rect.left + 2.0f, rect.bottom)); 97 } 98 //------------------------------------------------------------------------------ 99 void _BMCItem_::GetContentSize(float *width, float *height) 100 { 101 BMenuItem::GetContentSize(width, height); 102 } 103 //------------------------------------------------------------------------------ 104 /*_BMCFilter_::_BMCFilter_(BMenuField *menuField, uint32) 105 { 106 } 107 //------------------------------------------------------------------------------ 108 _BMCFilter_::~_BMCFilter_() 109 { 110 } 111 //------------------------------------------------------------------------------ 112 filter_result _BMCFilter_::Filter(BMessage *message, BHandler **handler) 113 { 114 } 115 //------------------------------------------------------------------------------ 116 _BMCFilter_ &_BMCFilter_::operator=(const _BMCFilter_ &) 117 { 118 return *this; 119 }*/ 120 //------------------------------------------------------------------------------ 121 _BMCMenuBar_::_BMCMenuBar_(BRect frame, bool fixed_size, BMenuField *menuField) 122 : BMenuBar(frame, "_mc_mb_", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_ITEMS_IN_ROW, 123 !fixed_size) 124 { 125 SetFlags(Flags() | B_FRAME_EVENTS); 126 SetBorder(B_BORDER_CONTENTS); 127 128 129 fMenuField = menuField; 130 fFixedSize = fixed_size; 131 fRunner = NULL; 132 133 float left, top, right, bottom; 134 135 GetItemMargins(&left, &top, &right, &bottom); 136 SetItemMargins(left, top, right, bottom); // TODO: 137 138 SetMaxContentWidth(frame.Width() - (left + right)); 139 } 140 //------------------------------------------------------------------------------ 141 _BMCMenuBar_::_BMCMenuBar_(BMessage *data) 142 : BMenuBar(data) 143 { 144 SetFlags(Flags() | B_FRAME_EVENTS); 145 146 bool rsize_to_fit; 147 148 if (data->FindBool("_rsize_to_fit", &rsize_to_fit) == B_OK) 149 fFixedSize = !rsize_to_fit; 150 else 151 fFixedSize = true; 152 } 153 //------------------------------------------------------------------------------ 154 _BMCMenuBar_::~_BMCMenuBar_() 155 { 156 } 157 //------------------------------------------------------------------------------ 158 BArchivable *_BMCMenuBar_::Instantiate(BMessage *data) 159 { 160 if (validate_instantiation(data, "_BMCMenuBar_")) 161 return new _BMCMenuBar_(data); 162 else 163 return NULL; 164 } 165 //------------------------------------------------------------------------------ 166 void _BMCMenuBar_::AttachedToWindow() 167 { 168 fMenuField = (BMenuField*)Parent(); 169 170 BMenuBar *menuBar = Window()->KeyMenuBar(); 171 BMenuBar::AttachedToWindow(); 172 Window()->SetKeyMenuBar(menuBar); 173 } 174 //------------------------------------------------------------------------------ 175 void _BMCMenuBar_::Draw(BRect updateRect) 176 { 177 // TODO: The commented code locks up the 178 // window thread. 179 // draw the right and bottom line here in a darker tint 180 BRegion oldClipping; 181 GetClippingRegion(&oldClipping); 182 183 BRect bounds(Bounds()); 184 bounds.right -= 2.0; 185 bounds.bottom -= 1.0; 186 bounds = bounds & updateRect; 187 BRegion clipping(bounds); 188 ConstrainClippingRegion(&clipping); 189 190 BMenuBar::Draw(updateRect); 191 192 bounds.right += 2.0; 193 bounds.bottom += 1.0; 194 ConstrainClippingRegion(&oldClipping); 195 //BRect bounds(Bounds()); 196 SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_4_TINT)); 197 StrokeLine(BPoint(bounds.left, bounds.bottom), 198 BPoint(bounds.right, bounds.bottom)); 199 StrokeLine(BPoint(bounds.right, bounds.bottom - 1), 200 BPoint(bounds.right, bounds.top)); 201 SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_1_TINT)); 202 StrokeLine(BPoint(bounds.right - 1, bounds.bottom - 2), 203 BPoint(bounds.right - 1, bounds.top + 1)); 204 } 205 //------------------------------------------------------------------------------ 206 void _BMCMenuBar_::FrameResized(float width, float height) 207 { 208 // TODO: 209 BMenuBar::FrameResized(width, height); 210 } 211 //------------------------------------------------------------------------------ 212 void _BMCMenuBar_::MessageReceived(BMessage *msg) 213 { 214 if (msg->what == 'TICK') 215 { 216 BMenuItem *item = ItemAt(0); 217 218 if (item && item->Submenu() && item->Submenu()->Window()) 219 { 220 BMessage message(B_KEY_DOWN); 221 222 message.AddInt8("byte", B_ESCAPE); 223 message.AddInt8("key", B_ESCAPE); 224 message.AddInt32("modifiers", 0); 225 message.AddInt8("raw_char", B_ESCAPE); 226 227 Window()->PostMessage(&message, this, NULL); 228 } 229 } 230 231 BMenuBar::MessageReceived(msg); 232 } 233 //------------------------------------------------------------------------------ 234 void _BMCMenuBar_::MakeFocus(bool focused) 235 { 236 if (IsFocus() == focused) 237 return; 238 239 BMenuBar::MakeFocus(focused); 240 241 if (focused) 242 { 243 BMessage message('TICK'); 244 //fRunner = new BMessageRunner(BMessenger(this, NULL, NULL), &message, 245 // 50000, -1); 246 } 247 else if (fRunner) 248 { 249 //delete fRunner; 250 fRunner = NULL; 251 } 252 253 if (focused) 254 return; 255 256 fMenuField->fSelected = false; 257 fMenuField->fTransition = true; 258 259 BRect bounds(fMenuField->Bounds()); 260 261 fMenuField->Invalidate(BRect(bounds.left, bounds.top, fMenuField->fDivider, 262 bounds.bottom)); 263 } 264 //------------------------------------------------------------------------------ 265 _BMCMenuBar_ &_BMCMenuBar_::operator=(const _BMCMenuBar_ &) 266 { 267 return *this; 268 } 269 //------------------------------------------------------------------------------ 270