1928ffe6dSJohn Scipione /* 2928ffe6dSJohn Scipione * Copyright 2010-2012 Haiku, Inc. All rights reserved. 3928ffe6dSJohn Scipione * Distributed under the terms of the MIT license. 4928ffe6dSJohn Scipione * 5928ffe6dSJohn Scipione * Authors: 6928ffe6dSJohn Scipione * DarkWyrm <bpmagic@columbus.rr.com> 7928ffe6dSJohn Scipione * John Scipione <jscipione@gmail.com> 8928ffe6dSJohn Scipione */ 9928ffe6dSJohn Scipione 10928ffe6dSJohn Scipione 11928ffe6dSJohn Scipione #include "FakeScrollBar.h" 12928ffe6dSJohn Scipione 13928ffe6dSJohn Scipione #include <Box.h> 14928ffe6dSJohn Scipione #include <ControlLook.h> 15928ffe6dSJohn Scipione #include <Message.h> 16928ffe6dSJohn Scipione #include <ScrollBar.h> 17928ffe6dSJohn Scipione #include <Shape.h> 18928ffe6dSJohn Scipione #include <Size.h> 19928ffe6dSJohn Scipione #include <Window.h> 20928ffe6dSJohn Scipione 21928ffe6dSJohn Scipione 22928ffe6dSJohn Scipione typedef enum { 23928ffe6dSJohn Scipione ARROW_LEFT = 0, 24928ffe6dSJohn Scipione ARROW_RIGHT, 25928ffe6dSJohn Scipione ARROW_UP, 26928ffe6dSJohn Scipione ARROW_DOWN, 27928ffe6dSJohn Scipione ARROW_NONE 28928ffe6dSJohn Scipione } arrow_direction; 29928ffe6dSJohn Scipione 30928ffe6dSJohn Scipione 31928ffe6dSJohn Scipione FakeScrollBar::FakeScrollBar(bool drawArrows, bool doubleArrows, 32b5446310SJohn Scipione BMessage* message) 33928ffe6dSJohn Scipione : 3412a7abb6SJohn Scipione BControl("FakeScrollBar", NULL, message, B_WILL_DRAW | B_NAVIGABLE), 35928ffe6dSJohn Scipione fDrawArrows(drawArrows), 36b5446310SJohn Scipione fDoubleArrows(doubleArrows) 37928ffe6dSJohn Scipione { 38928ffe6dSJohn Scipione SetExplicitMinSize(BSize(160, 20)); 39928ffe6dSJohn Scipione SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 20)); 40928ffe6dSJohn Scipione } 41928ffe6dSJohn Scipione 42928ffe6dSJohn Scipione 43928ffe6dSJohn Scipione FakeScrollBar::~FakeScrollBar(void) 44928ffe6dSJohn Scipione { 45928ffe6dSJohn Scipione } 46928ffe6dSJohn Scipione 47928ffe6dSJohn Scipione 48928ffe6dSJohn Scipione void 49928ffe6dSJohn Scipione FakeScrollBar::Draw(BRect updateRect) 50928ffe6dSJohn Scipione { 51928ffe6dSJohn Scipione BRect bounds = Bounds(); 52928ffe6dSJohn Scipione 53928ffe6dSJohn Scipione rgb_color normal = ui_color(B_PANEL_BACKGROUND_COLOR); 54928ffe6dSJohn Scipione 5512a7abb6SJohn Scipione if (IsFocus()) { 5612a7abb6SJohn Scipione // draw the focus indicator 5712a7abb6SJohn Scipione SetHighColor(ui_color(B_NAVIGATION_BASE_COLOR)); 5812a7abb6SJohn Scipione StrokeRect(bounds); 5912a7abb6SJohn Scipione bounds.InsetBy(1.0, 1.0); 6012a7abb6SJohn Scipione 6112a7abb6SJohn Scipione // Draw the selected border (1px) 62928ffe6dSJohn Scipione if (Value() == B_CONTROL_ON) 63928ffe6dSJohn Scipione SetHighColor(ui_color(B_CONTROL_MARK_COLOR)); 64928ffe6dSJohn Scipione else 65928ffe6dSJohn Scipione SetHighColor(normal); 66928ffe6dSJohn Scipione 6712a7abb6SJohn Scipione StrokeRect(bounds); 6812a7abb6SJohn Scipione bounds.InsetBy(1.0, 1.0); 6912a7abb6SJohn Scipione } else { 70928ffe6dSJohn Scipione // Draw the selected border (2px) 7112a7abb6SJohn Scipione if (Value() == B_CONTROL_ON) 7212a7abb6SJohn Scipione SetHighColor(ui_color(B_CONTROL_MARK_COLOR)); 7312a7abb6SJohn Scipione else 7412a7abb6SJohn Scipione SetHighColor(normal); 7512a7abb6SJohn Scipione 76928ffe6dSJohn Scipione StrokeRect(bounds); 77928ffe6dSJohn Scipione bounds.InsetBy(1.0, 1.0); 78928ffe6dSJohn Scipione StrokeRect(bounds); 79928ffe6dSJohn Scipione bounds.InsetBy(1.0, 1.0); 8012a7abb6SJohn Scipione } 81928ffe6dSJohn Scipione 82928ffe6dSJohn Scipione // draw a gap (1px) 83928ffe6dSJohn Scipione SetHighColor(normal); 84928ffe6dSJohn Scipione StrokeRect(bounds); 85928ffe6dSJohn Scipione bounds.InsetBy(1.0, 1.0); 86928ffe6dSJohn Scipione 87928ffe6dSJohn Scipione // draw a border around control (1px) 88928ffe6dSJohn Scipione SetHighColor(tint_color(normal, B_DARKEN_1_TINT)); 89928ffe6dSJohn Scipione StrokeRect(bounds); 90928ffe6dSJohn Scipione bounds.InsetBy(1.0, 1.0); 91928ffe6dSJohn Scipione 92928ffe6dSJohn Scipione BRect thumbBG = bounds; 93928ffe6dSJohn Scipione BRect bgRect = bounds; 94928ffe6dSJohn Scipione 95928ffe6dSJohn Scipione if (fDrawArrows) { 96928ffe6dSJohn Scipione // draw arrows 97928ffe6dSJohn Scipione SetDrawingMode(B_OP_OVER); 98928ffe6dSJohn Scipione 99928ffe6dSJohn Scipione BRect buttonFrame(bounds.left, bounds.top, 100928ffe6dSJohn Scipione bounds.left + bounds.Height(), bounds.bottom); 101928ffe6dSJohn Scipione 102*f9b1a47fSRyan Leavengood _DrawArrowButton(ARROW_LEFT, buttonFrame, updateRect); 103928ffe6dSJohn Scipione 104928ffe6dSJohn Scipione if (fDoubleArrows) { 105928ffe6dSJohn Scipione buttonFrame.OffsetBy(bounds.Height() + 1, 0.0); 106*f9b1a47fSRyan Leavengood _DrawArrowButton(ARROW_RIGHT, buttonFrame, 107928ffe6dSJohn Scipione updateRect); 108928ffe6dSJohn Scipione 109928ffe6dSJohn Scipione buttonFrame.OffsetTo(bounds.right - ((bounds.Height() * 2) + 1), 110928ffe6dSJohn Scipione bounds.top); 111*f9b1a47fSRyan Leavengood _DrawArrowButton(ARROW_LEFT, buttonFrame, 112928ffe6dSJohn Scipione updateRect); 113928ffe6dSJohn Scipione 114928ffe6dSJohn Scipione thumbBG.left += bounds.Height() * 2 + 2; 115928ffe6dSJohn Scipione thumbBG.right -= bounds.Height() * 2 + 2; 116928ffe6dSJohn Scipione } else { 117928ffe6dSJohn Scipione thumbBG.left += bounds.Height() + 1; 118928ffe6dSJohn Scipione thumbBG.right -= bounds.Height() + 1; 119928ffe6dSJohn Scipione } 120928ffe6dSJohn Scipione 121928ffe6dSJohn Scipione buttonFrame.OffsetTo(bounds.right - bounds.Height(), bounds.top); 122*f9b1a47fSRyan Leavengood _DrawArrowButton(ARROW_RIGHT, buttonFrame, updateRect); 123928ffe6dSJohn Scipione 124928ffe6dSJohn Scipione SetDrawingMode(B_OP_COPY); 125928ffe6dSJohn Scipione 126928ffe6dSJohn Scipione bgRect = bounds.InsetByCopy(48, 0); 127928ffe6dSJohn Scipione } else 128928ffe6dSJohn Scipione bgRect = bounds.InsetByCopy(16, 0); 129928ffe6dSJohn Scipione 130928ffe6dSJohn Scipione // fill background besides the thumb 131928ffe6dSJohn Scipione BRect leftOfThumb(thumbBG.left, thumbBG.top, bgRect.left - 1, 132928ffe6dSJohn Scipione thumbBG.bottom); 133928ffe6dSJohn Scipione BRect rightOfThumb(bgRect.right + 1, thumbBG.top, thumbBG.right, 134928ffe6dSJohn Scipione thumbBG.bottom); 135928ffe6dSJohn Scipione 136928ffe6dSJohn Scipione be_control_look->DrawScrollBarBackground(this, leftOfThumb, 137928ffe6dSJohn Scipione rightOfThumb, updateRect, normal, 0, B_HORIZONTAL); 138928ffe6dSJohn Scipione 139928ffe6dSJohn Scipione // Draw scroll thumb 140928ffe6dSJohn Scipione 141928ffe6dSJohn Scipione // fill the clickable surface of the thumb 142928ffe6dSJohn Scipione be_control_look->DrawButtonBackground(this, bgRect, updateRect, 143928ffe6dSJohn Scipione normal, 0, BControlLook::B_ALL_BORDERS, B_HORIZONTAL); 144928ffe6dSJohn Scipione } 145928ffe6dSJohn Scipione 146928ffe6dSJohn Scipione 147928ffe6dSJohn Scipione void 148928ffe6dSJohn Scipione FakeScrollBar::MouseDown(BPoint point) 149928ffe6dSJohn Scipione { 150928ffe6dSJohn Scipione BControl::MouseDown(point); 151928ffe6dSJohn Scipione } 152928ffe6dSJohn Scipione 153928ffe6dSJohn Scipione 154928ffe6dSJohn Scipione void 155928ffe6dSJohn Scipione FakeScrollBar::MouseMoved(BPoint point, uint32 transit, 156928ffe6dSJohn Scipione const BMessage* message) 157928ffe6dSJohn Scipione { 158928ffe6dSJohn Scipione BControl::MouseMoved(point, transit, message); 159928ffe6dSJohn Scipione } 160928ffe6dSJohn Scipione 161928ffe6dSJohn Scipione 162928ffe6dSJohn Scipione void 163928ffe6dSJohn Scipione FakeScrollBar::MouseUp(BPoint point) 164928ffe6dSJohn Scipione { 165928ffe6dSJohn Scipione SetValue(B_CONTROL_ON); 166928ffe6dSJohn Scipione Invoke(); 167928ffe6dSJohn Scipione 168928ffe6dSJohn Scipione Invalidate(); 169928ffe6dSJohn Scipione 170928ffe6dSJohn Scipione BControl::MouseUp(point); 171928ffe6dSJohn Scipione } 172928ffe6dSJohn Scipione 173928ffe6dSJohn Scipione 174928ffe6dSJohn Scipione void 175928ffe6dSJohn Scipione FakeScrollBar::SetValue(int32 value) 176928ffe6dSJohn Scipione { 177928ffe6dSJohn Scipione if (value != Value()) { 178928ffe6dSJohn Scipione BControl::SetValueNoUpdate(value); 179928ffe6dSJohn Scipione Invalidate(); 180928ffe6dSJohn Scipione } 181928ffe6dSJohn Scipione 182928ffe6dSJohn Scipione if (!value) 183928ffe6dSJohn Scipione return; 184928ffe6dSJohn Scipione 185928ffe6dSJohn Scipione BView* parent = Parent(); 186928ffe6dSJohn Scipione BView* child = NULL; 187928ffe6dSJohn Scipione 188928ffe6dSJohn Scipione if (parent != NULL) { 189928ffe6dSJohn Scipione // If the parent is a BBox, the group parent is the parent of the BBox 190928ffe6dSJohn Scipione BBox* box = dynamic_cast<BBox*>(parent); 191928ffe6dSJohn Scipione 192928ffe6dSJohn Scipione if (box && box->LabelView() == this) 193928ffe6dSJohn Scipione parent = box->Parent(); 194928ffe6dSJohn Scipione 195928ffe6dSJohn Scipione if (parent != NULL) { 196928ffe6dSJohn Scipione BBox* box = dynamic_cast<BBox*>(parent); 197928ffe6dSJohn Scipione 198928ffe6dSJohn Scipione // If the parent is a BBox, skip the label if there is one 199928ffe6dSJohn Scipione if (box && box->LabelView()) 200928ffe6dSJohn Scipione child = parent->ChildAt(1); 201928ffe6dSJohn Scipione else 202928ffe6dSJohn Scipione child = parent->ChildAt(0); 203928ffe6dSJohn Scipione } else 204928ffe6dSJohn Scipione child = Window()->ChildAt(0); 205928ffe6dSJohn Scipione } else if (Window()) 206928ffe6dSJohn Scipione child = Window()->ChildAt(0); 207928ffe6dSJohn Scipione 208928ffe6dSJohn Scipione while (child) { 209928ffe6dSJohn Scipione FakeScrollBar* scrollbar = dynamic_cast<FakeScrollBar*>(child); 210928ffe6dSJohn Scipione 211928ffe6dSJohn Scipione if (scrollbar != NULL && (scrollbar != this)) 212928ffe6dSJohn Scipione scrollbar->SetValue(B_CONTROL_OFF); 213928ffe6dSJohn Scipione else { 214928ffe6dSJohn Scipione // If the child is a BBox, check if the label is a scrollbarbutton 215928ffe6dSJohn Scipione BBox* box = dynamic_cast<BBox*>(child); 216928ffe6dSJohn Scipione 217928ffe6dSJohn Scipione if (box && box->LabelView()) { 218928ffe6dSJohn Scipione scrollbar = dynamic_cast<FakeScrollBar*>(box->LabelView()); 219928ffe6dSJohn Scipione 220928ffe6dSJohn Scipione if (scrollbar != NULL && (scrollbar != this)) 221928ffe6dSJohn Scipione scrollbar->SetValue(B_CONTROL_OFF); 222928ffe6dSJohn Scipione } 223928ffe6dSJohn Scipione } 224928ffe6dSJohn Scipione 225928ffe6dSJohn Scipione child = child->NextSibling(); 226928ffe6dSJohn Scipione } 227928ffe6dSJohn Scipione 228928ffe6dSJohn Scipione //ASSERT(Value() == B_CONTROL_ON); 229928ffe6dSJohn Scipione } 230928ffe6dSJohn Scipione 231928ffe6dSJohn Scipione 232928ffe6dSJohn Scipione // #pragma mark - 233928ffe6dSJohn Scipione 234928ffe6dSJohn Scipione 235928ffe6dSJohn Scipione void 23668c70f9bSJohn Scipione FakeScrollBar::SetDoubleArrows(bool doubleArrows) 237928ffe6dSJohn Scipione { 23868c70f9bSJohn Scipione fDoubleArrows = doubleArrows; 239928ffe6dSJohn Scipione Invalidate(); 240928ffe6dSJohn Scipione } 241928ffe6dSJohn Scipione 242928ffe6dSJohn Scipione 243928ffe6dSJohn Scipione void 24468c70f9bSJohn Scipione FakeScrollBar::SetKnobStyle(uint32 knobStyle) 245928ffe6dSJohn Scipione { 24668c70f9bSJohn Scipione fKnobStyle = knobStyle; 247928ffe6dSJohn Scipione Invalidate(); 248928ffe6dSJohn Scipione } 249928ffe6dSJohn Scipione 250928ffe6dSJohn Scipione 251928ffe6dSJohn Scipione void 252928ffe6dSJohn Scipione FakeScrollBar::SetFromScrollBarInfo(const scroll_bar_info &info) 253928ffe6dSJohn Scipione { 254928ffe6dSJohn Scipione fDoubleArrows = info.double_arrows; 255928ffe6dSJohn Scipione fKnobStyle = info.knob; 256928ffe6dSJohn Scipione Invalidate(); 257928ffe6dSJohn Scipione } 258928ffe6dSJohn Scipione 259928ffe6dSJohn Scipione 260928ffe6dSJohn Scipione // #pragma mark - 261928ffe6dSJohn Scipione 262928ffe6dSJohn Scipione 263928ffe6dSJohn Scipione void 264*f9b1a47fSRyan Leavengood FakeScrollBar::_DrawArrowButton(int32 direction, BRect rect, 265928ffe6dSJohn Scipione const BRect& updateRect) 266928ffe6dSJohn Scipione { 267*f9b1a47fSRyan Leavengood if (!updateRect.Intersects(rect)) 268928ffe6dSJohn Scipione return; 269928ffe6dSJohn Scipione 270*f9b1a47fSRyan Leavengood uint32 flags = 0; 271928ffe6dSJohn Scipione 272*f9b1a47fSRyan Leavengood rgb_color baseColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 273*f9b1a47fSRyan Leavengood B_LIGHTEN_1_TINT); 274928ffe6dSJohn Scipione 275*f9b1a47fSRyan Leavengood be_control_look->DrawButtonBackground(this, rect, updateRect, baseColor, 276*f9b1a47fSRyan Leavengood flags, BControlLook::B_ALL_BORDERS, B_HORIZONTAL); 277928ffe6dSJohn Scipione 278*f9b1a47fSRyan Leavengood rect.InsetBy(-1, -1); 279*f9b1a47fSRyan Leavengood be_control_look->DrawArrowShape(this, rect, updateRect, 280*f9b1a47fSRyan Leavengood baseColor, direction, flags, B_DARKEN_MAX_TINT); 281928ffe6dSJohn Scipione } 282