1928ffe6dSJohn Scipione /* 2*49c29fa9Swaddlesplash * Copyright 2010-2012 Haiku, Inc. All rights reserved. 3928ffe6dSJohn Scipione * Distributed under the terms of the MIT license. 4928ffe6dSJohn Scipione * 5928ffe6dSJohn Scipione * Authors: 6*49c29fa9Swaddlesplash * DarkWyrm <bpmagic@columbus.rr.com> 7*49c29fa9Swaddlesplash * 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, 32*49c29fa9Swaddlesplash BMessage* message) 33928ffe6dSJohn Scipione : 3412a7abb6SJohn Scipione BControl("FakeScrollBar", NULL, message, B_WILL_DRAW | B_NAVIGABLE), 35928ffe6dSJohn Scipione fDrawArrows(drawArrows), 36*49c29fa9Swaddlesplash fDoubleArrows(doubleArrows) 37928ffe6dSJohn Scipione { 38ec1b18c5SJohn Scipione // add some height to draw the ring around the scroll bar 39ec1b18c5SJohn Scipione float height = B_H_SCROLL_BAR_HEIGHT + 8; 40ec1b18c5SJohn Scipione SetExplicitMinSize(BSize(200, height)); 41ec1b18c5SJohn Scipione SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, height)); 42928ffe6dSJohn Scipione } 43928ffe6dSJohn Scipione 44928ffe6dSJohn Scipione 45928ffe6dSJohn Scipione FakeScrollBar::~FakeScrollBar(void) 46928ffe6dSJohn Scipione { 47928ffe6dSJohn Scipione } 48928ffe6dSJohn Scipione 49928ffe6dSJohn Scipione 50928ffe6dSJohn Scipione void 51928ffe6dSJohn Scipione FakeScrollBar::Draw(BRect updateRect) 52928ffe6dSJohn Scipione { 53ec1b18c5SJohn Scipione BRect rect(Bounds()); 54928ffe6dSJohn Scipione 55ec1b18c5SJohn Scipione rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); 56928ffe6dSJohn Scipione 57ec1b18c5SJohn Scipione uint32 flags = BControlLook::B_SCROLLABLE; 58ec1b18c5SJohn Scipione if (IsFocus()) 59ec1b18c5SJohn Scipione flags |= BControlLook::B_FOCUSED; 6012a7abb6SJohn Scipione 61928ffe6dSJohn Scipione if (Value() == B_CONTROL_ON) 62928ffe6dSJohn Scipione SetHighColor(ui_color(B_CONTROL_MARK_COLOR)); 63928ffe6dSJohn Scipione else 64ec1b18c5SJohn Scipione SetHighColor(base); 65928ffe6dSJohn Scipione 66928ffe6dSJohn Scipione // Draw the selected border (2px) 67ec1b18c5SJohn Scipione StrokeRect(rect); 68ec1b18c5SJohn Scipione rect.InsetBy(1, 1); 69ec1b18c5SJohn Scipione StrokeRect(rect); 70ec1b18c5SJohn Scipione rect.InsetBy(1, 1); 7112a7abb6SJohn Scipione 72ec1b18c5SJohn Scipione // draw a 1px gap 73ec1b18c5SJohn Scipione SetHighColor(base); 74ec1b18c5SJohn Scipione StrokeRect(rect); 75ec1b18c5SJohn Scipione rect.InsetBy(1, 1); 76928ffe6dSJohn Scipione 77ec1b18c5SJohn Scipione // draw a 1px border around control 78ec1b18c5SJohn Scipione SetHighColor(tint_color(base, B_DARKEN_1_TINT)); 79ec1b18c5SJohn Scipione StrokeRect(rect); 80ec1b18c5SJohn Scipione rect.InsetBy(1, 1); 81*49c29fa9Swaddlesplash SetHighColor(base); 82928ffe6dSJohn Scipione 83ec1b18c5SJohn Scipione be_control_look->DrawScrollBar(this, rect, updateRect, base, 84ec1b18c5SJohn Scipione flags, B_HORIZONTAL, fDoubleArrows); 85*49c29fa9Swaddlesplash float less = floorf(rect.Width() / 3); // thumb takes up 1/3 full width 86ec1b18c5SJohn Scipione BRect thumbRect(rect.left + less, rect.top, rect.right - less, rect.bottom); 87ec1b18c5SJohn Scipione be_control_look->DrawScrollBarThumb(this, rect, thumbRect, updateRect, base, 88ec1b18c5SJohn Scipione flags, B_HORIZONTAL, fKnobStyle); 89928ffe6dSJohn Scipione } 90928ffe6dSJohn Scipione 91928ffe6dSJohn Scipione 92928ffe6dSJohn Scipione void 93*49c29fa9Swaddlesplash FakeScrollBar::MouseDown(BPoint point) 94928ffe6dSJohn Scipione { 95*49c29fa9Swaddlesplash BControl::MouseDown(point); 96928ffe6dSJohn Scipione } 97928ffe6dSJohn Scipione 98928ffe6dSJohn Scipione 99928ffe6dSJohn Scipione void 100*49c29fa9Swaddlesplash FakeScrollBar::MouseMoved(BPoint point, uint32 transit, 101*49c29fa9Swaddlesplash const BMessage* message) 102928ffe6dSJohn Scipione { 103*49c29fa9Swaddlesplash BControl::MouseMoved(point, transit, message); 104928ffe6dSJohn Scipione } 105928ffe6dSJohn Scipione 106928ffe6dSJohn Scipione 107928ffe6dSJohn Scipione void 108*49c29fa9Swaddlesplash FakeScrollBar::MouseUp(BPoint point) 109928ffe6dSJohn Scipione { 110928ffe6dSJohn Scipione SetValue(B_CONTROL_ON); 111928ffe6dSJohn Scipione Invoke(); 112928ffe6dSJohn Scipione 113928ffe6dSJohn Scipione Invalidate(); 114928ffe6dSJohn Scipione 115*49c29fa9Swaddlesplash BControl::MouseUp(point); 116928ffe6dSJohn Scipione } 117928ffe6dSJohn Scipione 118928ffe6dSJohn Scipione 119928ffe6dSJohn Scipione void 120928ffe6dSJohn Scipione FakeScrollBar::SetValue(int32 value) 121928ffe6dSJohn Scipione { 122928ffe6dSJohn Scipione if (value != Value()) { 123928ffe6dSJohn Scipione BControl::SetValueNoUpdate(value); 124928ffe6dSJohn Scipione Invalidate(); 125928ffe6dSJohn Scipione } 126928ffe6dSJohn Scipione 127*49c29fa9Swaddlesplash if (!value) 128928ffe6dSJohn Scipione return; 129928ffe6dSJohn Scipione 130928ffe6dSJohn Scipione BView* parent = Parent(); 131928ffe6dSJohn Scipione BView* child = NULL; 132928ffe6dSJohn Scipione 133928ffe6dSJohn Scipione if (parent != NULL) { 134928ffe6dSJohn Scipione // If the parent is a BBox, the group parent is the parent of the BBox 135928ffe6dSJohn Scipione BBox* box = dynamic_cast<BBox*>(parent); 136928ffe6dSJohn Scipione 137928ffe6dSJohn Scipione if (box && box->LabelView() == this) 138928ffe6dSJohn Scipione parent = box->Parent(); 139928ffe6dSJohn Scipione 140928ffe6dSJohn Scipione if (parent != NULL) { 141928ffe6dSJohn Scipione BBox* box = dynamic_cast<BBox*>(parent); 142928ffe6dSJohn Scipione 143928ffe6dSJohn Scipione // If the parent is a BBox, skip the label if there is one 144928ffe6dSJohn Scipione if (box && box->LabelView()) 145928ffe6dSJohn Scipione child = parent->ChildAt(1); 146928ffe6dSJohn Scipione else 147928ffe6dSJohn Scipione child = parent->ChildAt(0); 148928ffe6dSJohn Scipione } else 149928ffe6dSJohn Scipione child = Window()->ChildAt(0); 150*49c29fa9Swaddlesplash } else if (Window()) 151928ffe6dSJohn Scipione child = Window()->ChildAt(0); 152928ffe6dSJohn Scipione 153*49c29fa9Swaddlesplash while (child) { 154928ffe6dSJohn Scipione FakeScrollBar* scrollbar = dynamic_cast<FakeScrollBar*>(child); 155928ffe6dSJohn Scipione 156928ffe6dSJohn Scipione if (scrollbar != NULL && (scrollbar != this)) 157928ffe6dSJohn Scipione scrollbar->SetValue(B_CONTROL_OFF); 158928ffe6dSJohn Scipione else { 159928ffe6dSJohn Scipione // If the child is a BBox, check if the label is a scrollbarbutton 160928ffe6dSJohn Scipione BBox* box = dynamic_cast<BBox*>(child); 161928ffe6dSJohn Scipione 162928ffe6dSJohn Scipione if (box && box->LabelView()) { 163928ffe6dSJohn Scipione scrollbar = dynamic_cast<FakeScrollBar*>(box->LabelView()); 164928ffe6dSJohn Scipione 165928ffe6dSJohn Scipione if (scrollbar != NULL && (scrollbar != this)) 166928ffe6dSJohn Scipione scrollbar->SetValue(B_CONTROL_OFF); 167928ffe6dSJohn Scipione } 168928ffe6dSJohn Scipione } 169928ffe6dSJohn Scipione 170928ffe6dSJohn Scipione child = child->NextSibling(); 171928ffe6dSJohn Scipione } 172928ffe6dSJohn Scipione 173928ffe6dSJohn Scipione //ASSERT(Value() == B_CONTROL_ON); 174928ffe6dSJohn Scipione } 175928ffe6dSJohn Scipione 176928ffe6dSJohn Scipione 177*49c29fa9Swaddlesplash // #pragma mark - 178*49c29fa9Swaddlesplash 179*49c29fa9Swaddlesplash 180928ffe6dSJohn Scipione void 18168c70f9bSJohn Scipione FakeScrollBar::SetDoubleArrows(bool doubleArrows) 182928ffe6dSJohn Scipione { 18368c70f9bSJohn Scipione fDoubleArrows = doubleArrows; 184928ffe6dSJohn Scipione Invalidate(); 185928ffe6dSJohn Scipione } 186928ffe6dSJohn Scipione 187928ffe6dSJohn Scipione 188928ffe6dSJohn Scipione void 18968c70f9bSJohn Scipione FakeScrollBar::SetKnobStyle(uint32 knobStyle) 190928ffe6dSJohn Scipione { 19168c70f9bSJohn Scipione fKnobStyle = knobStyle; 192928ffe6dSJohn Scipione Invalidate(); 193928ffe6dSJohn Scipione } 194928ffe6dSJohn Scipione 195928ffe6dSJohn Scipione 196928ffe6dSJohn Scipione void 197928ffe6dSJohn Scipione FakeScrollBar::SetFromScrollBarInfo(const scroll_bar_info &info) 198928ffe6dSJohn Scipione { 199928ffe6dSJohn Scipione fDoubleArrows = info.double_arrows; 200928ffe6dSJohn Scipione fKnobStyle = info.knob; 201928ffe6dSJohn Scipione Invalidate(); 202928ffe6dSJohn Scipione } 203928ffe6dSJohn Scipione 204928ffe6dSJohn Scipione 205*49c29fa9Swaddlesplash // #pragma mark - 206928ffe6dSJohn Scipione 207928ffe6dSJohn Scipione 208928ffe6dSJohn Scipione void 209f9b1a47fSRyan Leavengood FakeScrollBar::_DrawArrowButton(int32 direction, BRect rect, 210928ffe6dSJohn Scipione const BRect& updateRect) 211928ffe6dSJohn Scipione { 212f9b1a47fSRyan Leavengood if (!updateRect.Intersects(rect)) 213928ffe6dSJohn Scipione return; 214928ffe6dSJohn Scipione 215f9b1a47fSRyan Leavengood uint32 flags = 0; 216928ffe6dSJohn Scipione 217f9b1a47fSRyan Leavengood rgb_color baseColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 218f9b1a47fSRyan Leavengood B_LIGHTEN_1_TINT); 219928ffe6dSJohn Scipione 220f9b1a47fSRyan Leavengood be_control_look->DrawButtonBackground(this, rect, updateRect, baseColor, 221f9b1a47fSRyan Leavengood flags, BControlLook::B_ALL_BORDERS, B_HORIZONTAL); 222928ffe6dSJohn Scipione 223f9b1a47fSRyan Leavengood rect.InsetBy(-1, -1); 224f9b1a47fSRyan Leavengood be_control_look->DrawArrowShape(this, rect, updateRect, 225f9b1a47fSRyan Leavengood baseColor, direction, flags, B_DARKEN_MAX_TINT); 226928ffe6dSJohn Scipione } 227