1 /* 2 * Copyright 2011 Stephan Aßmus <superstippi@gmx.de> 3 * All rights reserved. Distributed under the terms of the MIT license. 4 */ 5 #include "ToolBar.h" 6 7 #include <Button.h> 8 #include <ControlLook.h> 9 #include <Message.h> 10 #include <SeparatorView.h> 11 #include <SpaceLayoutItem.h> 12 13 14 namespace BPrivate { 15 16 17 class LockableButton: public BButton { 18 public: 19 LockableButton(const char* name, const char* label, 20 BMessage* message); 21 22 void MouseDown(BPoint point); 23 }; 24 25 26 LockableButton::LockableButton(const char* name, const char* label, 27 BMessage* message) 28 : 29 BButton(name, label, message) 30 { 31 } 32 33 34 void 35 LockableButton::MouseDown(BPoint point) 36 { 37 if ((modifiers() & B_SHIFT_KEY) != 0 || Value() == B_CONTROL_ON) 38 SetBehavior(B_TOGGLE_BEHAVIOR); 39 else 40 SetBehavior(B_BUTTON_BEHAVIOR); 41 42 Message()->SetInt32("behavior", Behavior()); 43 BButton::MouseDown(point); 44 } 45 46 47 BToolBar::BToolBar(BRect frame, orientation ont) 48 : 49 BGroupView(ont), 50 fOrientation(ont) 51 { 52 _Init(); 53 54 MoveTo(frame.LeftTop()); 55 ResizeTo(frame.Width(), frame.Height()); 56 SetResizingMode(B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); 57 } 58 59 60 BToolBar::BToolBar(orientation ont) 61 : 62 BGroupView(ont), 63 fOrientation(ont) 64 { 65 _Init(); 66 } 67 68 69 BToolBar::~BToolBar() 70 { 71 } 72 73 74 void 75 BToolBar::Hide() 76 { 77 BView::Hide(); 78 // TODO: This could be fixed in BView instead. Looking from the 79 // BButtons, they are not hidden though, only their parent is... 80 _HideToolTips(); 81 } 82 83 84 void 85 BToolBar::AddAction(uint32 command, BHandler* target, const BBitmap* icon, 86 const char* toolTipText, const char* text, bool lockable) 87 { 88 AddAction(new BMessage(command), target, icon, toolTipText, text, lockable); 89 } 90 91 92 void 93 BToolBar::AddAction(BMessage* message, BHandler* target, 94 const BBitmap* icon, const char* toolTipText, const char* text, 95 bool lockable) 96 { 97 BButton* button; 98 if (lockable) 99 button = new LockableButton(NULL, NULL, message); 100 else 101 button = new BButton(NULL, NULL, message); 102 button->SetIcon(icon); 103 button->SetFlat(true); 104 if (toolTipText != NULL) 105 button->SetToolTip(toolTipText); 106 if (text != NULL) 107 button->SetLabel(text); 108 AddView(button); 109 button->SetTarget(target); 110 } 111 112 113 void 114 BToolBar::AddSeparator() 115 { 116 orientation ont = (fOrientation == B_HORIZONTAL) ? 117 B_VERTICAL : B_HORIZONTAL; 118 AddView(new BSeparatorView(ont, B_PLAIN_BORDER)); 119 } 120 121 122 void 123 BToolBar::AddGlue() 124 { 125 GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue()); 126 } 127 128 129 void 130 BToolBar::AddView(BView* view) 131 { 132 GroupLayout()->AddView(view); 133 } 134 135 136 void 137 BToolBar::SetActionEnabled(uint32 command, bool enabled) 138 { 139 if (BButton* button = _FindButton(command)) 140 button->SetEnabled(enabled); 141 } 142 143 144 void 145 BToolBar::SetActionPressed(uint32 command, bool pressed) 146 { 147 if (BButton* button = _FindButton(command)) 148 button->SetValue(pressed); 149 } 150 151 152 void 153 BToolBar::SetActionVisible(uint32 command, bool visible) 154 { 155 BButton* button = _FindButton(command); 156 if (button == NULL) 157 return; 158 for (int32 i = 0; BLayoutItem* item = GroupLayout()->ItemAt(i); i++) { 159 if (item->View() != button) 160 continue; 161 item->SetVisible(visible); 162 break; 163 } 164 } 165 166 167 // #pragma mark - Private methods 168 169 170 void 171 BToolBar::Pulse() 172 { 173 // TODO: Perhaps this could/should be addressed in BView instead. 174 if (IsHidden()) 175 _HideToolTips(); 176 } 177 178 179 void 180 BToolBar::FrameResized(float width, float height) 181 { 182 // TODO: There seems to be a bug in app_server which does not 183 // correctly trigger invalidation of views which are shown, when 184 // the resulting dirty area is somehow already part of an update region. 185 Invalidate(); 186 } 187 188 189 void 190 BToolBar::_Init() 191 { 192 float inset = ceilf(be_control_look->DefaultItemSpacing() / 2); 193 GroupLayout()->SetInsets(inset, 0, inset, 0); 194 GroupLayout()->SetSpacing(1); 195 196 SetFlags(Flags() | B_FRAME_EVENTS | B_PULSE_NEEDED); 197 } 198 199 200 BButton* 201 BToolBar::_FindButton(uint32 command) const 202 { 203 for (int32 i = 0; BView* view = ChildAt(i); i++) { 204 BButton* button = dynamic_cast<BButton*>(view); 205 if (button == NULL) 206 continue; 207 BMessage* message = button->Message(); 208 if (message == NULL) 209 continue; 210 if (message->what == command) { 211 return button; 212 // Assumes there is only one button with this message... 213 break; 214 } 215 } 216 return NULL; 217 } 218 219 220 void 221 BToolBar::_HideToolTips() const 222 { 223 for (int32 i = 0; BView* view = ChildAt(i); i++) 224 view->HideToolTip(); 225 } 226 227 228 } // namespace BPrivate 229