1 /* 2 * Copyright 2010-2012 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * DarkWyrm <bpmagic@columbus.rr.com> 7 * John Scipione <jscipione@gmail.com> 8 */ 9 10 11 #include "FakeScrollBar.h" 12 13 #include <Box.h> 14 #include <ControlLook.h> 15 #include <Message.h> 16 #include <ScrollBar.h> 17 #include <Shape.h> 18 #include <Size.h> 19 #include <Window.h> 20 21 22 typedef enum { 23 ARROW_LEFT = 0, 24 ARROW_RIGHT, 25 ARROW_UP, 26 ARROW_DOWN, 27 ARROW_NONE 28 } arrow_direction; 29 30 31 FakeScrollBar::FakeScrollBar(bool drawArrows, bool doubleArrows, 32 BMessage* message) 33 : 34 BControl("FakeScrollBar", NULL, message, B_WILL_DRAW | B_NAVIGABLE), 35 fDrawArrows(drawArrows), 36 fDoubleArrows(doubleArrows) 37 { 38 // add some height to draw the ring around the scroll bar 39 float height = B_H_SCROLL_BAR_HEIGHT + 8; 40 SetExplicitMinSize(BSize(200, height)); 41 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, height)); 42 } 43 44 45 FakeScrollBar::~FakeScrollBar(void) 46 { 47 } 48 49 50 void 51 FakeScrollBar::Draw(BRect updateRect) 52 { 53 BRect rect(Bounds()); 54 55 rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); 56 57 uint32 flags = BControlLook::B_SCROLLABLE; 58 if (IsFocus()) 59 flags |= BControlLook::B_FOCUSED; 60 61 if (Value() == B_CONTROL_ON) 62 SetHighColor(ui_color(B_CONTROL_MARK_COLOR)); 63 else 64 SetHighColor(base); 65 66 // Draw the selected border (2px) 67 StrokeRect(rect); 68 rect.InsetBy(1, 1); 69 StrokeRect(rect); 70 rect.InsetBy(1, 1); 71 72 // draw a 1px gap 73 SetHighColor(base); 74 StrokeRect(rect); 75 rect.InsetBy(1, 1); 76 77 // draw a 1px border around control 78 SetHighColor(tint_color(base, B_DARKEN_1_TINT)); 79 StrokeRect(rect); 80 rect.InsetBy(1, 1); 81 SetHighColor(base); 82 83 be_control_look->DrawScrollBar(this, rect, updateRect, base, 84 flags, B_HORIZONTAL, fDoubleArrows); 85 float less = floorf(rect.Width() / 3); // thumb takes up 1/3 full width 86 BRect thumbRect(rect.left + less, rect.top, rect.right - less, rect.bottom); 87 be_control_look->DrawScrollBarThumb(this, rect, thumbRect, updateRect, base, 88 flags, B_HORIZONTAL, fKnobStyle); 89 } 90 91 92 void 93 FakeScrollBar::MouseDown(BPoint point) 94 { 95 BControl::MouseDown(point); 96 } 97 98 99 void 100 FakeScrollBar::MouseMoved(BPoint point, uint32 transit, 101 const BMessage* message) 102 { 103 BControl::MouseMoved(point, transit, message); 104 } 105 106 107 void 108 FakeScrollBar::MouseUp(BPoint point) 109 { 110 SetValue(B_CONTROL_ON); 111 Invoke(); 112 113 Invalidate(); 114 115 BControl::MouseUp(point); 116 } 117 118 119 void 120 FakeScrollBar::SetValue(int32 value) 121 { 122 if (value != Value()) { 123 BControl::SetValueNoUpdate(value); 124 Invalidate(); 125 } 126 127 if (!value) 128 return; 129 130 BView* parent = Parent(); 131 BView* child = NULL; 132 133 if (parent != NULL) { 134 // If the parent is a BBox, the group parent is the parent of the BBox 135 BBox* box = dynamic_cast<BBox*>(parent); 136 137 if (box && box->LabelView() == this) 138 parent = box->Parent(); 139 140 if (parent != NULL) { 141 BBox* box = dynamic_cast<BBox*>(parent); 142 143 // If the parent is a BBox, skip the label if there is one 144 if (box && box->LabelView()) 145 child = parent->ChildAt(1); 146 else 147 child = parent->ChildAt(0); 148 } else 149 child = Window()->ChildAt(0); 150 } else if (Window()) 151 child = Window()->ChildAt(0); 152 153 while (child) { 154 FakeScrollBar* scrollbar = dynamic_cast<FakeScrollBar*>(child); 155 156 if (scrollbar != NULL && (scrollbar != this)) 157 scrollbar->SetValue(B_CONTROL_OFF); 158 else { 159 // If the child is a BBox, check if the label is a scrollbarbutton 160 BBox* box = dynamic_cast<BBox*>(child); 161 162 if (box && box->LabelView()) { 163 scrollbar = dynamic_cast<FakeScrollBar*>(box->LabelView()); 164 165 if (scrollbar != NULL && (scrollbar != this)) 166 scrollbar->SetValue(B_CONTROL_OFF); 167 } 168 } 169 170 child = child->NextSibling(); 171 } 172 173 //ASSERT(Value() == B_CONTROL_ON); 174 } 175 176 177 // #pragma mark - 178 179 180 void 181 FakeScrollBar::SetDoubleArrows(bool doubleArrows) 182 { 183 fDoubleArrows = doubleArrows; 184 Invalidate(); 185 } 186 187 188 void 189 FakeScrollBar::SetKnobStyle(uint32 knobStyle) 190 { 191 fKnobStyle = knobStyle; 192 Invalidate(); 193 } 194 195 196 void 197 FakeScrollBar::SetFromScrollBarInfo(const scroll_bar_info &info) 198 { 199 fDoubleArrows = info.double_arrows; 200 fKnobStyle = info.knob; 201 Invalidate(); 202 } 203 204 205 // #pragma mark - 206 207 208 void 209 FakeScrollBar::_DrawArrowButton(int32 direction, BRect rect, 210 const BRect& updateRect) 211 { 212 if (!updateRect.Intersects(rect)) 213 return; 214 215 uint32 flags = 0; 216 217 rgb_color baseColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 218 B_LIGHTEN_1_TINT); 219 220 be_control_look->DrawButtonBackground(this, rect, updateRect, baseColor, 221 flags, BControlLook::B_ALL_BORDERS, B_HORIZONTAL); 222 223 rect.InsetBy(-1, -1); 224 be_control_look->DrawArrowShape(this, rect, updateRect, 225 baseColor, direction, flags, B_DARKEN_MAX_TINT); 226 } 227