Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: views/controls/scrollbar/base_scroll_bar.cc

Issue 7767002: Revert 98434 - Adding a Views scrollbar implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "views/controls/scrollbar/base_scroll_bar.h"
6
7 #if defined(OS_LINUX)
8 #include "ui/gfx/screen.h"
9 #endif
10
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/message_loop.h"
14 #include "base/string16.h"
15 #include "base/utf_string_conversions.h"
16 #include "grit/ui_strings.h"
17 #include "ui/base/keycodes/keyboard_codes.h"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/gfx/canvas.h"
20 #include "views/controls/menu/menu.h"
21 #include "views/controls/scrollbar/base_scroll_bar_thumb.h"
22 #include "views/controls/scroll_view.h"
23 #include "views/widget/widget.h"
24
25 #undef min
26 #undef max
27
28 namespace views {
29
30 ///////////////////////////////////////////////////////////////////////////////
31 // BaseScrollBar, public:
32
33 BaseScrollBar::BaseScrollBar(bool horizontal, BaseScrollBarThumb* thumb)
34 : ScrollBar(horizontal),
35 thumb_(thumb),
36 contents_size_(0),
37 contents_scroll_offset_(0),
38 thumb_track_state_(CustomButton::BS_NORMAL),
39 last_scroll_amount_(SCROLL_NONE),
40 ALLOW_THIS_IN_INITIALIZER_LIST(repeater_(
41 NewCallback<BaseScrollBar>(this,
42 &BaseScrollBar::TrackClicked))),
43 context_menu_mouse_position_(0) {
44 AddChildView(thumb_);
45
46 set_context_menu_controller(this);
47 thumb_->set_context_menu_controller(this);
48 }
49
50 void BaseScrollBar::ScrollByAmount(ScrollAmount amount) {
51 int offset = contents_scroll_offset_;
52 switch (amount) {
53 case SCROLL_START:
54 offset = GetMinPosition();
55 break;
56 case SCROLL_END:
57 offset = GetMaxPosition();
58 break;
59 case SCROLL_PREV_LINE:
60 offset -= GetScrollIncrement(false, false);
61 offset = std::max(GetMinPosition(), offset);
62 break;
63 case SCROLL_NEXT_LINE:
64 offset += GetScrollIncrement(false, true);
65 offset = std::min(GetMaxPosition(), offset);
66 break;
67 case SCROLL_PREV_PAGE:
68 offset -= GetScrollIncrement(true, false);
69 offset = std::max(GetMinPosition(), offset);
70 break;
71 case SCROLL_NEXT_PAGE:
72 offset += GetScrollIncrement(true, true);
73 offset = std::min(GetMaxPosition(), offset);
74 break;
75 default:
76 break;
77 }
78 contents_scroll_offset_ = offset;
79 ScrollContentsToOffset();
80 }
81
82 void BaseScrollBar::ScrollToThumbPosition(int thumb_position,
83 bool scroll_to_middle) {
84 contents_scroll_offset_ =
85 CalculateContentsOffset(thumb_position, scroll_to_middle);
86 if (contents_scroll_offset_ < GetMinPosition()) {
87 contents_scroll_offset_ = GetMinPosition();
88 } else if (contents_scroll_offset_ > GetMaxPosition()) {
89 contents_scroll_offset_ = GetMaxPosition();
90 }
91 ScrollContentsToOffset();
92 SchedulePaint();
93 }
94
95 void BaseScrollBar::ScrollByContentsOffset(int contents_offset) {
96 contents_scroll_offset_ -= contents_offset;
97 if (contents_scroll_offset_ < GetMinPosition()) {
98 contents_scroll_offset_ = GetMinPosition();
99 } else if (contents_scroll_offset_ > GetMaxPosition()) {
100 contents_scroll_offset_ = GetMaxPosition();
101 }
102 ScrollContentsToOffset();
103 }
104
105 ///////////////////////////////////////////////////////////////////////////////
106 // BaseScrollBar, View implementation:
107
108 bool BaseScrollBar::OnMousePressed(const MouseEvent& event) {
109 if (event.IsOnlyLeftMouseButton()) {
110 SetThumbTrackState(CustomButton::BS_PUSHED);
111 gfx::Rect thumb_bounds = thumb_->bounds();
112 if (IsHorizontal()) {
113 if (event.x() < thumb_bounds.x()) {
114 last_scroll_amount_ = SCROLL_PREV_PAGE;
115 } else if (event.x() > thumb_bounds.right()) {
116 last_scroll_amount_ = SCROLL_NEXT_PAGE;
117 }
118 } else {
119 if (event.y() < thumb_bounds.y()) {
120 last_scroll_amount_ = SCROLL_PREV_PAGE;
121 } else if (event.y() > thumb_bounds.bottom()) {
122 last_scroll_amount_ = SCROLL_NEXT_PAGE;
123 }
124 }
125 TrackClicked();
126 repeater_.Start();
127 }
128 return true;
129 }
130
131 void BaseScrollBar::OnMouseReleased(const MouseEvent& event) {
132 OnMouseCaptureLost();
133 }
134
135 void BaseScrollBar::OnMouseCaptureLost() {
136 SetThumbTrackState(CustomButton::BS_NORMAL);
137 repeater_.Stop();
138 }
139
140 bool BaseScrollBar::OnKeyPressed(const KeyEvent& event) {
141 ScrollAmount amount = SCROLL_NONE;
142 switch (event.key_code()) {
143 case ui::VKEY_UP:
144 if (!IsHorizontal())
145 amount = SCROLL_PREV_LINE;
146 break;
147 case ui::VKEY_DOWN:
148 if (!IsHorizontal())
149 amount = SCROLL_NEXT_LINE;
150 break;
151 case ui::VKEY_LEFT:
152 if (IsHorizontal())
153 amount = SCROLL_PREV_LINE;
154 break;
155 case ui::VKEY_RIGHT:
156 if (IsHorizontal())
157 amount = SCROLL_NEXT_LINE;
158 break;
159 case ui::VKEY_PRIOR:
160 amount = SCROLL_PREV_PAGE;
161 break;
162 case ui::VKEY_NEXT:
163 amount = SCROLL_NEXT_PAGE;
164 break;
165 case ui::VKEY_HOME:
166 amount = SCROLL_START;
167 break;
168 case ui::VKEY_END:
169 amount = SCROLL_END;
170 break;
171 default:
172 break;
173 }
174 if (amount != SCROLL_NONE) {
175 ScrollByAmount(amount);
176 return true;
177 }
178 return false;
179 }
180
181 bool BaseScrollBar::OnMouseWheel(const MouseWheelEvent& event) {
182 ScrollByContentsOffset(event.offset());
183 return true;
184 }
185
186 ///////////////////////////////////////////////////////////////////////////////
187 // BaseScrollBar, ContextMenuController implementation:
188
189 enum ScrollBarContextMenuCommands {
190 ScrollBarContextMenuCommand_ScrollHere = 1,
191 ScrollBarContextMenuCommand_ScrollStart,
192 ScrollBarContextMenuCommand_ScrollEnd,
193 ScrollBarContextMenuCommand_ScrollPageUp,
194 ScrollBarContextMenuCommand_ScrollPageDown,
195 ScrollBarContextMenuCommand_ScrollPrev,
196 ScrollBarContextMenuCommand_ScrollNext
197 };
198
199 void BaseScrollBar::ShowContextMenuForView(View* source,
200 const gfx::Point& p,
201 bool is_mouse_gesture) {
202 Widget* widget = GetWidget();
203 gfx::Rect widget_bounds = widget->GetWindowScreenBounds();
204 gfx::Point temp_pt(p.x() - widget_bounds.x(), p.y() - widget_bounds.y());
205 View::ConvertPointFromWidget(this, &temp_pt);
206 context_menu_mouse_position_ = IsHorizontal() ? temp_pt.x() : temp_pt.y();
207
208 scoped_ptr<Menu> menu(
209 Menu::Create(this, Menu::TOPLEFT, GetWidget()->GetNativeView()));
210 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollHere);
211 menu->AppendSeparator();
212 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollStart);
213 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollEnd);
214 menu->AppendSeparator();
215 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageUp);
216 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageDown);
217 menu->AppendSeparator();
218 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPrev);
219 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollNext);
220 menu->RunMenuAt(p.x(), p.y());
221 }
222
223 ///////////////////////////////////////////////////////////////////////////////
224 // BaseScrollBar, Menu::Delegate implementation:
225
226 std::wstring BaseScrollBar::GetLabel(int id) const {
227 int ids_value = 0;
228 switch (id) {
229 case ScrollBarContextMenuCommand_ScrollHere:
230 ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLHERE;
231 break;
232 case ScrollBarContextMenuCommand_ScrollStart:
233 ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFTEDGE
234 : IDS_APP_SCROLLBAR_CXMENU_SCROLLHOME;
235 break;
236 case ScrollBarContextMenuCommand_ScrollEnd:
237 ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHTEDGE
238 : IDS_APP_SCROLLBAR_CXMENU_SCROLLEND;
239 break;
240 case ScrollBarContextMenuCommand_ScrollPageUp:
241 ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEUP;
242 break;
243 case ScrollBarContextMenuCommand_ScrollPageDown:
244 ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEDOWN;
245 break;
246 case ScrollBarContextMenuCommand_ScrollPrev:
247 ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFT
248 : IDS_APP_SCROLLBAR_CXMENU_SCROLLUP;
249 break;
250 case ScrollBarContextMenuCommand_ScrollNext:
251 ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHT
252 : IDS_APP_SCROLLBAR_CXMENU_SCROLLDOWN;
253 break;
254 default:
255 NOTREACHED() << "Invalid BaseScrollBar Context Menu command!";
256 }
257
258 return ids_value ? UTF16ToWide(l10n_util::GetStringUTF16(ids_value)) : L"";
259 }
260
261 bool BaseScrollBar::IsCommandEnabled(int id) const {
262 switch (id) {
263 case ScrollBarContextMenuCommand_ScrollPageUp:
264 case ScrollBarContextMenuCommand_ScrollPageDown:
265 return !IsHorizontal();
266 }
267 return true;
268 }
269
270 void BaseScrollBar::ExecuteCommand(int id) {
271 switch (id) {
272 case ScrollBarContextMenuCommand_ScrollHere:
273 ScrollToThumbPosition(context_menu_mouse_position_, true);
274 break;
275 case ScrollBarContextMenuCommand_ScrollStart:
276 ScrollByAmount(SCROLL_START);
277 break;
278 case ScrollBarContextMenuCommand_ScrollEnd:
279 ScrollByAmount(SCROLL_END);
280 break;
281 case ScrollBarContextMenuCommand_ScrollPageUp:
282 ScrollByAmount(SCROLL_PREV_PAGE);
283 break;
284 case ScrollBarContextMenuCommand_ScrollPageDown:
285 ScrollByAmount(SCROLL_NEXT_PAGE);
286 break;
287 case ScrollBarContextMenuCommand_ScrollPrev:
288 ScrollByAmount(SCROLL_PREV_LINE);
289 break;
290 case ScrollBarContextMenuCommand_ScrollNext:
291 ScrollByAmount(SCROLL_NEXT_LINE);
292 break;
293 }
294 }
295
296 ///////////////////////////////////////////////////////////////////////////////
297 // BaseScrollBar, ScrollBar implementation:
298
299 void BaseScrollBar::Update(int viewport_size, int content_size,
300 int contents_scroll_offset) {
301 ScrollBar::Update(viewport_size, content_size, contents_scroll_offset);
302
303 // Make sure contents_size is always > 0 to avoid divide by zero errors in
304 // calculations throughout this code.
305 contents_size_ = std::max(1, content_size);
306
307 if (content_size < 0)
308 content_size = 0;
309 if (contents_scroll_offset < 0)
310 contents_scroll_offset = 0;
311 if (contents_scroll_offset > content_size)
312 contents_scroll_offset = content_size;
313
314 // Thumb Height and Thumb Pos.
315 // The height of the thumb is the ratio of the Viewport height to the
316 // content size multiplied by the height of the thumb track.
317 double ratio = static_cast<double>(viewport_size) / contents_size_;
318 int thumb_size = static_cast<int>(ratio * GetTrackSize());
319 thumb_->SetSize(thumb_size);
320
321 int thumb_position = CalculateThumbPosition(contents_scroll_offset);
322 thumb_->SetPosition(thumb_position);
323 }
324
325 int BaseScrollBar::GetPosition() const {
326 return thumb_->GetPosition();
327 }
328
329 ///////////////////////////////////////////////////////////////////////////////
330 // BaseScrollBar, protected:
331
332 BaseScrollBarThumb* BaseScrollBar::GetThumb() const {
333 return thumb_;
334 }
335
336 CustomButton::ButtonState BaseScrollBar::GetThumbTrackState() const {
337 return thumb_track_state_;
338 }
339
340 void BaseScrollBar::ScrollToPosition(int position) {
341 GetController()->ScrollToPosition(this, position);
342 }
343
344 int BaseScrollBar::GetScrollIncrement(bool is_page, bool is_positive) {
345 return GetController()->GetScrollIncrement(this, is_page, is_positive);
346 }
347
348
349 ///////////////////////////////////////////////////////////////////////////////
350 // BaseScrollBar, private:
351
352 void BaseScrollBar::TrackClicked() {
353 if (last_scroll_amount_ != SCROLL_NONE)
354 ScrollByAmount(last_scroll_amount_);
355 }
356
357 void BaseScrollBar::ScrollContentsToOffset() {
358 ScrollToPosition(contents_scroll_offset_);
359 thumb_->SetPosition(CalculateThumbPosition(contents_scroll_offset_));
360 }
361
362 int BaseScrollBar::GetTrackSize() const {
363 gfx::Rect track_bounds = GetTrackBounds();
364 return IsHorizontal() ? track_bounds.width() : track_bounds.height();
365 }
366
367 int BaseScrollBar::CalculateThumbPosition(int contents_scroll_offset) const {
368 return (contents_scroll_offset * GetTrackSize()) / contents_size_;
369 }
370
371 int BaseScrollBar::CalculateContentsOffset(int thumb_position,
372 bool scroll_to_middle) const {
373 if (scroll_to_middle)
374 thumb_position = thumb_position - (thumb_->GetSize() / 2);
375 return (thumb_position * contents_size_) / GetTrackSize();
376 }
377
378 void BaseScrollBar::SetThumbTrackState(CustomButton::ButtonState state) {
379 thumb_track_state_ = state;
380 SchedulePaint();
381 }
382
383 } // namespace views
OLDNEW
« no previous file with comments | « views/controls/scrollbar/base_scroll_bar.h ('k') | views/controls/scrollbar/base_scroll_bar_button.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698