summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/pepper_scrollbar_widget.cc
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 02:08:11 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 02:08:11 +0000
commit039a1dad907b8c163532b0597d86bf31dedb9a9b (patch)
treeabb1c24331258269fe61c816e37e3a094248ab42 /chrome/renderer/pepper_scrollbar_widget.cc
parente8d5545b55d44c8b9f05d550dab052fcfe392f2d (diff)
downloadchromium_src-039a1dad907b8c163532b0597d86bf31dedb9a9b.zip
chromium_src-039a1dad907b8c163532b0597d86bf31dedb9a9b.tar.gz
chromium_src-039a1dad907b8c163532b0597d86bf31dedb9a9b.tar.bz2
Update the Pepper scrollbar widget to use the new WebKit Scrollbar interface.
Review URL: http://codereview.chromium.org/2008008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47000 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/pepper_scrollbar_widget.cc')
-rw-r--r--chrome/renderer/pepper_scrollbar_widget.cc732
1 files changed, 199 insertions, 533 deletions
diff --git a/chrome/renderer/pepper_scrollbar_widget.cc b/chrome/renderer/pepper_scrollbar_widget.cc
index 4d45200..16d0eee 100644
--- a/chrome/renderer/pepper_scrollbar_widget.cc
+++ b/chrome/renderer/pepper_scrollbar_widget.cc
@@ -7,82 +7,159 @@
#include "base/basictypes.h"
#include "base/keyboard_codes.h"
#include "base/logging.h"
+#include "base/message_loop.h"
#include "chrome/renderer/pepper_devices.h"
#include "skia/ext/platform_canvas.h"
#include "skia/ext/platform_device.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebScrollBar.h"
#include "webkit/glue/plugins/plugin_instance.h"
-const int PepperScrollbarWidget::kPixelsPerLine = 40;
-const float PepperScrollbarWidget::kMinFractionToStepWhenPaging = 0.875f;
-#if !defined(OS_MACOSX)
-const int PepperScrollbarWidget::kMaxOverlapBetweenPages = kint32max;
-#endif
-const float PepperScrollbarWidget::kInitialAutoscrollTimerDelay = 0.25f;
-const float PepperScrollbarWidget::kAutoscrollTimerDelay = 0.05f;
+using WebKit::WebInputEvent;
+using WebKit::WebKeyboardEvent;
+using WebKit::WebMouseEvent;
+using WebKit::WebMouseWheelEvent;
+using WebKit::WebRect;
+using WebKit::WebScrollbar;
+using WebKit::WebVector;
+
+
+// Anonymous namespace for functions converting NPAPI to WebInputEvents types.
+namespace {
+WebKeyboardEvent BuildKeyEvent(const NPPepperEvent& event) {
+ WebKeyboardEvent key_event;
+ switch (event.type) {
+ case NPEventType_RawKeyDown:
+ key_event.type = WebInputEvent::RawKeyDown;
+ break;
+ case NPEventType_KeyDown:
+ key_event.type = WebInputEvent::KeyDown;
+ break;
+ case NPEventType_KeyUp:
+ key_event.type = WebInputEvent::KeyUp;
+ break;
+ }
+ key_event.timeStampSeconds = event.timeStampSeconds;
+ key_event.modifiers = event.u.key.modifier;
+ key_event.windowsKeyCode = event.u.key.normalizedKeyCode;
+ return key_event;
+}
+
+WebKeyboardEvent BuildCharEvent(const NPPepperEvent& event) {
+ WebKeyboardEvent key_event;
+ key_event.type = WebInputEvent::Char;
+ key_event.timeStampSeconds = event.timeStampSeconds;
+ key_event.modifiers = event.u.character.modifier;
+ // For consistency, check that the sizes of the texts agree.
+ DCHECK(sizeof(event.u.character.text) == sizeof(key_event.text));
+ DCHECK(sizeof(event.u.character.unmodifiedText) ==
+ sizeof(key_event.unmodifiedText));
+ for (size_t i = 0; i < WebKeyboardEvent::textLengthCap; ++i) {
+ key_event.text[i] = event.u.character.text[i];
+ key_event.unmodifiedText[i] = event.u.character.unmodifiedText[i];
+ }
+ return key_event;
+}
+
+WebMouseEvent BuildMouseEvent(const NPPepperEvent& event) {
+ WebMouseEvent mouse_event;
+ switch (event.type) {
+ case NPEventType_MouseDown:
+ mouse_event.type = WebInputEvent::MouseDown;
+ break;
+ case NPEventType_MouseUp:
+ mouse_event.type = WebInputEvent::MouseUp;
+ break;
+ case NPEventType_MouseMove:
+ mouse_event.type = WebInputEvent::MouseMove;
+ break;
+ case NPEventType_MouseEnter:
+ mouse_event.type = WebInputEvent::MouseEnter;
+ break;
+ case NPEventType_MouseLeave:
+ mouse_event.type = WebInputEvent::MouseLeave;
+ break;
+ }
+ mouse_event.timeStampSeconds = event.timeStampSeconds;
+ mouse_event.modifiers = event.u.mouse.modifier;
+ mouse_event.button = static_cast<WebMouseEvent::Button>(event.u.mouse.button);
+ mouse_event.x = event.u.mouse.x;
+ mouse_event.y = event.u.mouse.y;
+ mouse_event.clickCount = event.u.mouse.clickCount;
+ return mouse_event;
+}
+
+WebMouseWheelEvent BuildMouseWheelEvent(const NPPepperEvent& event) {
+ WebMouseWheelEvent mouse_wheel_event;
+ mouse_wheel_event.type = WebInputEvent::MouseWheel;
+ mouse_wheel_event.timeStampSeconds = event.timeStampSeconds;
+ mouse_wheel_event.modifiers = event.u.wheel.modifier;
+ mouse_wheel_event.deltaX = event.u.wheel.deltaX;
+ mouse_wheel_event.deltaY = event.u.wheel.deltaY;
+ mouse_wheel_event.wheelTicksX = event.u.wheel.wheelTicksX;
+ mouse_wheel_event.wheelTicksY = event.u.wheel.wheelTicksY;
+ mouse_wheel_event.scrollByPage = event.u.wheel.scrollByPage;
+ return mouse_wheel_event;
+}
+
+} // namespace
PepperScrollbarWidget::PepperScrollbarWidget(
- const NPScrollbarCreateParams& params)
- : vertical_(params.vertical),
- enabled_(true),
- length_(0),
- total_length_(0),
- pixels_per_page_(0),
- thickness_(0),
- arrow_length_(0),
- hovered_part_(-1),
- pressed_part_(-1),
- thumb_position_(0),
- have_mouse_capture_(false),
- drag_origin_(-1.0),
- pressed_position_(-1) {
- GenerateMeasurements();
+ const NPScrollbarCreateParams& params) {
+ scrollbar_.reset(WebScrollbar::create(
+ static_cast<WebKit::WebScrollbarClient*>(this),
+ params.vertical ? WebScrollbar::Vertical : WebScrollbar::Horizontal));
+ AddRef();
}
PepperScrollbarWidget::~PepperScrollbarWidget() {
- StopTimerIfNeeded();
}
void PepperScrollbarWidget::Destroy() {
- delete this;
+ Release();
+}
+
+void PepperScrollbarWidget::Paint(Graphics2DDeviceContext* context,
+ const NPRect& dirty) {
+ gfx::Rect rect(dirty.left, dirty.top, dirty.right - dirty.left,
+ dirty.bottom - dirty.top);
+#if defined(OS_WIN) || defined(OS_LINUX)
+ scrollbar_->paint(context->canvas(), rect);
+#elif defined(OS_MACOSX)
+ // TODO(port)
+#endif
+ dirty_rect_ = dirty_rect_.Subtract(rect);
}
bool PepperScrollbarWidget::HandleEvent(const NPPepperEvent& event) {
bool rv = false;
+
switch (event.type) {
+ case NPEventType_Undefined:
+ return false;
case NPEventType_MouseDown:
- rv = OnMouseDown(event);
- break;
case NPEventType_MouseUp:
- rv = OnMouseUp(event);
- break;
case NPEventType_MouseMove:
- rv = OnMouseMove(event);
- break;
case NPEventType_MouseEnter:
- break;
case NPEventType_MouseLeave:
- rv = OnMouseLeave(event);
+ rv = scrollbar_->handleInputEvent(BuildMouseEvent(event));
break;
case NPEventType_MouseWheel:
- rv = OnMouseWheel(event);
+ rv = scrollbar_->handleInputEvent(BuildMouseWheelEvent(event));
break;
+ case NPEventType_RawKeyDown:
case NPEventType_KeyDown:
- rv = OnKeyDown(event);
- break;
case NPEventType_KeyUp:
- rv = OnKeyUp(event);
+ rv = scrollbar_->handleInputEvent(BuildKeyEvent(event));
break;
- default:
+ case NPEventType_Char:
+ rv = scrollbar_->handleInputEvent(BuildCharEvent(event));
+ break;
+ case NPEventType_Minimize:
+ case NPEventType_Focus:
+ case NPEventType_Device:
+ // NOTIMPLEMENTED();
break;
- }
-
- if (rv) {
- dirty_rect_ = dirty_rect_.Union(gfx::Rect(
- location_,
- gfx::Size(vertical_ ? thickness_: length_,
- vertical_ ? length_ : thickness_)));
- WidgetPropertyChanged(NPWidgetPropertyDirtyRect);
}
return rv;
@@ -91,23 +168,30 @@ bool PepperScrollbarWidget::HandleEvent(const NPPepperEvent& event) {
void PepperScrollbarWidget::GetProperty(
NPWidgetProperty property, void* value) {
switch (property) {
+ case NPWidgetPropertyLocation: {
+ NPRect* rv = static_cast<NPRect*>(value);
+ rv->left = location_.x();
+ rv->top = location_.y();
+ rv->right = location_.right();
+ rv->bottom = location_.bottom();
+ break;
+ }
case NPWidgetPropertyDirtyRect: {
NPRect* rv = reinterpret_cast<NPRect*>(value);
rv->left = dirty_rect_.x();
rv->top = dirty_rect_.y();
rv->right = dirty_rect_.right();
rv->bottom = dirty_rect_.bottom();
- dirty_rect_ = gfx::Rect();
break;
}
case NPWidgetPropertyScrollbarThickness: {
int32* rv = static_cast<int32*>(value);
- *rv = thickness_;
+ *rv = WebScrollbar::defaultThickness();
break;
}
- case NPWidgetPropertyScrollbarPosition: {
+ case NPWidgetPropertyScrollbarValue: {
int32* rv = static_cast<int32*>(value);
- *rv = GetPosition();
+ *rv = scrollbar_->value();
break;
}
default:
@@ -121,513 +205,95 @@ void PepperScrollbarWidget::SetProperty(
switch (property) {
case NPWidgetPropertyLocation: {
NPRect* r = static_cast<NPRect*>(value);
- gfx::Point location(r->left, r->top);
- gfx::Size size(r->right - r->left, r->bottom - r->top);
- SetLocation(location,
- vertical_ ? size.height() : size.width(),
- total_length_);
+ location_ = gfx::Rect(
+ r->left, r->top, r->right - r->left, r->bottom - r->top);
+ scrollbar_->setLocation(location_);
break;
}
- case NPWidgetPropertyScrollbarPosition: {
+ case NPWidgetPropertyScrollbarValue: {
int32* position = static_cast<int*>(value);
- ScrollTo(*position);
+ scrollbar_->setValue(*position);
break;
}
case NPWidgetPropertyScrollbarDocumentSize: {
int32* total_length = static_cast<int32*>(value);
- SetLocation(location_, length_, *total_length);
- break;
- }
- case NPWidgetPropertyScrollbarTickMarks:
- break;
- case NPWidgetPropertyScrollbarScrollByLine: {
- bool* forward = static_cast<bool*>(value);
- Scroll(!forward, SCROLL_BY_LINE, 0);
- break;
- }
- case NPWidgetPropertyScrollbarScrollByPage: {
- bool* forward = static_cast<bool*>(value);
- Scroll(!forward, SCROLL_BY_PAGE, 0);
+ scrollbar_->setDocumentSize(*total_length);
break;
}
- case NPWidgetPropertyScrollbarScrollByDocument: {
- bool* forward = static_cast<bool*>(value);
- Scroll(!forward, SCROLL_BY_DOCUMENT, 0);
+ case NPWidgetPropertyScrollbarTickMarks: {
+ NPScrollbarTickMarks* tickmarks =
+ static_cast<NPScrollbarTickMarks*>(value);
+ tickmarks_.resize(tickmarks->count);
+ for (uint32 i = 0; i < tickmarks->count; ++i) {
+ WebRect rect(
+ tickmarks->tickmarks[i].left,
+ tickmarks->tickmarks[i].top,
+ tickmarks->tickmarks[i].right - tickmarks->tickmarks[i].left,
+ tickmarks->tickmarks[i].bottom - tickmarks->tickmarks[i].top);
+ tickmarks_[i] = rect;
+ }
+ dirty_rect_ = location_;
+ NotifyInvalidate();
break;
}
+ case NPWidgetPropertyScrollbarScrollByLine:
+ case NPWidgetPropertyScrollbarScrollByPage:
+ case NPWidgetPropertyScrollbarScrollByDocument:
case NPWidgetPropertyScrollbarScrollByPixels: {
- int32 pixels = *static_cast<int32*>(value);
- bool forward = pixels >= 0;
- if (pixels < 0)
- pixels *= -1;
- Scroll(!forward, SCROLL_BY_PIXELS, pixels);
- break;
- }
- default:
- NOTREACHED();
- break;
- }
-}
-
-void PepperScrollbarWidget::SetLocation(
- const gfx::Point& location, int length, int total_length) {
- location_ = location;
- length_ = length;
- total_length_ = total_length;
-
- // As a result of zooming out, the thumb's current position might need to be
- // updated.
- if (thumb_position_ > MaximumThumbPosition())
- SetPosition(static_cast<float>(MaximumThumbPosition()), true);
-
- pixels_per_page_ = std::max<int>(std::max<int>(
- static_cast<int>(length_ * kMinFractionToStepWhenPaging),
- length_ - kMaxOverlapBetweenPages), 1);
-
-
- // did this above tho inside setpositoin...
- dirty_rect_ = dirty_rect_.Union(gfx::Rect(
- location_,
- gfx::Size(vertical_ ? thickness_: length_,
- vertical_ ? length_ : thickness_)));
- WidgetPropertyChanged(NPWidgetPropertyDirtyRect);
-}
-
-gfx::Rect PepperScrollbarWidget::GetLocation() const {
- return gfx::Rect(location_.x(),
- location_.y(),
- vertical_ ? thickness_ : length_,
- vertical_ ? length_ : thickness_);
-}
-
-int PepperScrollbarWidget::GetPosition() const {
- return static_cast<int>(thumb_position_ * (total_length_ - length_) /
- MaximumThumbPosition());
-}
-
-bool PepperScrollbarWidget::OnMouseDown(const NPPepperEvent& event) {
- if (event.u.mouse.button == NPMouseButton_Right)
- return false;
-
- gfx::Point location(event.u.mouse.x, event.u.mouse.y);
- int pressed_part = HitTest(location);
- if (pressed_part == -1)
- return false;
-
- have_mouse_capture_ = true;
-
- pressed_part_ = pressed_part;
- int pressed_position = ThumbPosition(location);
- if (IsThumb(pressed_part_)) {
- pressed_position_ = pressed_position;
- drag_origin_ = thumb_position_;
- return true;
- } else if (IsTrackbar(pressed_part_) && ShouldCenterOnThumb(event)) {
- hovered_part_ = pressed_part_ = vertical_ ?
- VERTICAL_THUMB : HORIZONTAL_THUMB;
- drag_origin_ = thumb_position_;
- // Need to mark the middle of the thumb as the pressed position so that when
- // it's moved, the delta will be from the current pixel position of the
- // thumb to its new position.
- pressed_position_ = static_cast<int>(thumb_position_) + ThumbLength() / 2;
- MoveThumb(pressed_position);
- return true;
- }
-
- pressed_position_ = pressed_position;
- DCHECK(IsArrow(pressed_part_) || IsTrackbar(pressed_part_));
-
- AutoScroll(kInitialAutoscrollTimerDelay);
-
- return true;
-}
-
-bool PepperScrollbarWidget::OnMouseUp(const NPPepperEvent& event) {
- if (event.u.mouse.button != NPMouseButton_Left)
- return false;
-
- pressed_part_ = -1;
- pressed_position_ = -1;
- drag_origin_ = -1.0;
- StopTimerIfNeeded();
-
- gfx::Point location(event.u.mouse.x, event.u.mouse.y);
- return HitTest(location) != -1;
-}
-
-bool PepperScrollbarWidget::OnMouseMove(const NPPepperEvent& event) {
- gfx::Point location(event.u.mouse.x, event.u.mouse.y);
- if (IsThumb(pressed_part_)) {
- if (ShouldSnapBack(location)) {
- SetPosition(drag_origin_, true);
- } else {
- MoveThumb(ThumbPosition(location));
- }
- return true;
- }
-
- if (pressed_part_ != -1)
- pressed_position_ = ThumbPosition(location);
-
- int part = HitTest(location);
- if (part != hovered_part_) {
- if (pressed_part_ != -1) {
- if (part == pressed_part_) {
- // The mouse just moved back over the pressed part. Need to start the
- // timers again.
- StartTimerIfNeeded(kAutoscrollTimerDelay);
- } else if (hovered_part_ == pressed_part_) {
- // The mouse is leaving the pressed part. Stop the timer.
- StopTimerIfNeeded();
+ bool forward;
+ float multiplier = 1.0;
+
+ WebScrollbar::ScrollGranularity granularity;
+ if (property == NPWidgetPropertyScrollbarScrollByLine) {
+ forward = *static_cast<bool*>(value);
+ granularity = WebScrollbar::ScrollByLine;
+ } else if (property == NPWidgetPropertyScrollbarScrollByLine) {
+ forward = *static_cast<bool*>(value);
+ granularity = WebScrollbar::ScrollByPage;
+ } else if (property == NPWidgetPropertyScrollbarScrollByLine) {
+ forward = *static_cast<bool*>(value);
+ granularity = WebScrollbar::ScrollByDocument;
+ } else {
+ multiplier = static_cast<float>(*static_cast<int32*>(value));
+ forward = multiplier >= 0;
+ if (multiplier < 0)
+ multiplier *= -1;
+ granularity = WebScrollbar::ScrollByPixel;
}
+ scrollbar_->scroll(
+ forward ? WebScrollbar::ScrollForward : WebScrollbar::ScrollBackward,
+ granularity, multiplier);
+ break;
}
-
- hovered_part_ = part;
- return true;
}
-
- return false;
}
-bool PepperScrollbarWidget::OnMouseLeave(const NPPepperEvent& event) {
- hovered_part_ = -1;
- return have_mouse_capture_;
+void PepperScrollbarWidget::valueChanged(WebScrollbar*) {
+ WidgetPropertyChanged(NPWidgetPropertyScrollbarValue);
}
-bool PepperScrollbarWidget::OnMouseWheel(const NPPepperEvent& event) {
- // TODO(jabdelmalek): handle middle clicking and moving the mouse diagonaly,
- // which would give both deltaX and deltaY.
- int delta = static_cast<int>(
- vertical_ ? event.u.wheel.deltaY : event.u.wheel.deltaX);
- // Delta is negative for down/right.
- bool backwards = delta > 0;
- if (delta < 0)
- delta = -delta;
- if (delta != 0) {
- if (event.u.wheel.scrollByPage) {
- Scroll(backwards, SCROLL_BY_PAGE, 0);
- } else {
- Scroll(backwards, SCROLL_BY_PIXELS, delta);
- }
- }
-
- return delta != 0;
+void PepperScrollbarWidget::invalidateScrollbarRect(WebScrollbar*,
+ const WebRect& rect) {
+ dirty_rect_ = dirty_rect_.Union(rect);
+ // Can't call into the client to tell them about the invalidate right away,
+ // since the Scrollbar code is still in the middle of updating its internal
+ // state.
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &PepperScrollbarWidget::NotifyInvalidate));
}
-bool PepperScrollbarWidget::OnKeyDown(const NPPepperEvent& event) {
- bool rv = true;
- int key = event.u.key.normalizedKeyCode;
- if ((vertical_ && key == base::VKEY_UP) ||
- (!vertical_ && key == base::VKEY_LEFT)) {
- Scroll(true, SCROLL_BY_LINE, 0);
- } else if ((vertical_ && key == base::VKEY_DOWN) ||
- (!vertical_ && key == base::VKEY_RIGHT)) {
- Scroll(false, SCROLL_BY_LINE, 0);
- } else if (key == base::VKEY_HOME) {
- Scroll(true, SCROLL_BY_DOCUMENT, 0);
- } else if (key == base::VKEY_END) {
- Scroll(false, SCROLL_BY_DOCUMENT, 0);
- } else if (key == base::VKEY_PRIOR) {
- Scroll(true, SCROLL_BY_PAGE, 0);
- } else if (key == base::VKEY_NEXT) {
- Scroll(false, SCROLL_BY_PAGE, 0);
+void PepperScrollbarWidget::getTickmarks(WebKit::WebScrollbar*,
+ WebVector<WebRect>* tickmarks) const {
+ if (tickmarks_.empty()) {
+ WebRect* rects = NULL;
+ tickmarks->assign(rects, 0);
} else {
- rv = false;
+ tickmarks->assign(&tickmarks_[0], tickmarks_.size());
}
-
- return rv;
}
-bool PepperScrollbarWidget::OnKeyUp(const NPPepperEvent& event) {
- return false;
-}
-
-int PepperScrollbarWidget::HitTest(const gfx::Point& location) const {
- if (BackArrowRect().Contains(location)) {
- return vertical_ ? UP_ARROW : LEFT_ARROW;
- } else if (ForwardArrowRect().Contains(location)) {
- return vertical_ ? DOWN_ARROW : RIGHT_ARROW;
- } else if (ThumbRect().Contains(location)) {
- return vertical_ ? VERTICAL_THUMB : HORIZONTAL_THUMB;
- } else if (BackTrackRect().Contains(location)) {
- return vertical_ ? VERTICAL_TRACK : HORIZONTAL_TRACK;
- } else if (ForwardTrackRect().Contains(location)) {
- return vertical_ ? VERTICAL_TRACK : HORIZONTAL_TRACK;
- }
-
- return -1;
-}
-
-int PepperScrollbarWidget::ThumbPosition(const gfx::Point& location) const {
- int position;
- if (vertical_) {
- position = location.y() - location_.y() - arrow_length_;
- } else {
- position = location.x() - location_.x() - arrow_length_;
- }
-
- return position;
-}
-
-void PepperScrollbarWidget::MoveThumb(int new_position) {
- float delta = static_cast<float>(new_position - pressed_position_);
- if (delta > MaximumThumbPosition() - thumb_position_) {
- // Don't want to go beyond max pos.
- delta = MaximumThumbPosition() - thumb_position_;
- } else if (delta < -1 * thumb_position_) {
- // Don't want to go below 0.
- delta = - 1 * thumb_position_;
- }
-
- SetPosition(thumb_position_ + delta, true);
-}
-
-void PepperScrollbarWidget::SetPosition(float position, bool notify_client) {
- float old_thumb_position = thumb_position_;
- thumb_position_ = position;
- if (IsThumb(pressed_part_)) {
- pressed_position_ =
- pressed_position_ + static_cast<int>(position - old_thumb_position);
- }
-
- if (notify_client)
- WidgetPropertyChanged(NPWidgetPropertyScrollbarPosition);
-
- dirty_rect_ = dirty_rect_.Union(gfx::Rect(
- location_,
- gfx::Size(vertical_ ? thickness_: length_,
- vertical_ ? length_ : thickness_)));
- WidgetPropertyChanged(NPWidgetPropertyDirtyRect);
-}
-
-void PepperScrollbarWidget::OnTimerFired() {
- AutoScroll(kAutoscrollTimerDelay);
-}
-
-void PepperScrollbarWidget::AutoScroll(float delay) {
- if (pressed_part_ == -1 || IsThumb(pressed_part_)) {
- NOTREACHED();
- return;
- }
-
- if (DidThumbCatchUpWithMouse())
- return;
-
- ScrollGranularity granularity =
- IsArrow(pressed_part_) ? SCROLL_BY_LINE : SCROLL_BY_PAGE;
- Scroll(IsBackscrolling(), granularity, 0);
-
- StartTimerIfNeeded(delay);
-}
-
-void PepperScrollbarWidget::Scroll(bool backwards,
- ScrollGranularity granularity,
- int pixels) {
- float new_position;
- if (granularity == SCROLL_BY_LINE || granularity == SCROLL_BY_PAGE) {
- int delta =
- granularity == SCROLL_BY_LINE ? kPixelsPerLine : pixels_per_page_;
- if (backwards)
- delta *= -1;
-
- // delta is in document pixels. We want to convert to scrollbar pixels.
- new_position = thumb_position_ + ThumbPixelsFromDocumentPixels(delta);
- } else if (granularity == SCROLL_BY_PIXELS) {
- if (backwards)
- pixels *= -1;
- new_position = thumb_position_ + ThumbPixelsFromDocumentPixels(pixels);
- } else {
- DCHECK(granularity == SCROLL_BY_DOCUMENT);
- new_position =
- backwards ? 0.0f : static_cast<float>(MaximumThumbPosition());
- }
-
- SetPosition(std::max<float>(std::min<float>(
- new_position, static_cast<float>(MaximumThumbPosition())), 0.0), true);
-}
-
-void PepperScrollbarWidget::ScrollTo(int position) {
- if (position > (total_length_ - length_))
- position = total_length_ - length_;
- float thumb_position =
- static_cast<float>(position) * MaximumThumbPosition() /
- (total_length_ - length_);
- SetPosition(thumb_position, false);
-}
-
-void PepperScrollbarWidget::StartTimerIfNeeded(float delay) {
- if (IsThumb(pressed_part_))
- return;
-
- if (DidThumbCatchUpWithMouse())
- return;
-
- if (IsBackscrolling()) {
- if (thumb_position_ == 0)
- return; // Already at beginning.
- } else {
- if (static_cast<int>(thumb_position_) == MaximumThumbPosition())
- return; // Already at end.
- }
-
- DCHECK(!timer_.IsRunning());
- timer_.Start(
- base::TimeDelta::FromMilliseconds(static_cast<int64>(1000 * delay)),
- this,
- &PepperScrollbarWidget::OnTimerFired);
-}
-
-void PepperScrollbarWidget::StopTimerIfNeeded() {
- if (!timer_.IsRunning())
- return;
-
- timer_.Stop();
-}
-
-gfx::Rect PepperScrollbarWidget::BackArrowRect() const {
- int width = vertical_ ? thickness_ : arrow_length_;
- int height = vertical_ ? arrow_length_ : thickness_;
- return gfx::Rect(location_.x(), location_.y(), width, height);
-}
-
-gfx::Rect PepperScrollbarWidget::ForwardArrowRect() const {
- int x = location_.x();
- int y = location_.y();
- if (vertical_) {
- y += length_ - arrow_length_;
- } else {
- x += length_ - arrow_length_;
- }
- int width = vertical_ ? thickness_ : arrow_length_;
- int height = vertical_ ? arrow_length_ : thickness_;
- return gfx::Rect(x, y, width, height);
-}
-
-gfx::Rect PepperScrollbarWidget::BackTrackRect() const {
- int x = location_.x();
- int y = location_.y();
- if (vertical_) {
- y += arrow_length_;
- } else {
- x += arrow_length_;
- }
- int length = static_cast<int>(thumb_position_) + ThumbLength() / 2;
- int width = vertical_ ? thickness_ : length;
- int height = vertical_ ? length : thickness_;
- return gfx::Rect(x, y, width, height);
-}
-
-gfx::Rect PepperScrollbarWidget::ForwardTrackRect() const {
- int track_begin_offset =
- arrow_length_ + static_cast<int>(thumb_position_) + ThumbLength() / 2;
- int track_length =
- TrackLength() - ThumbLength() / 2 - static_cast<int>(thumb_position_);
- int x = location_.x();
- int y = location_.y();
- if (vertical_) {
- y += track_begin_offset;
- } else {
- x += track_begin_offset;
- }
- int width = vertical_ ? thickness_ : track_length;
- int height = vertical_ ? track_length : thickness_;
- return gfx::Rect(x, y, width, height);
-}
-
-gfx::Rect PepperScrollbarWidget::TrackRect() const {
- int x = location_.x();
- int y = location_.y();
- if (vertical_) {
- y += arrow_length_;
- } else {
- x += arrow_length_;
- }
- int width = vertical_ ? thickness_ : TrackLength();
- int height = vertical_ ? TrackLength() : thickness_;
- return gfx::Rect(x, y, width, height);
-}
-
-gfx::Rect PepperScrollbarWidget::ThumbRect() const {
- int thumb_begin_offset = arrow_length_ + static_cast<int>(thumb_position_);
- int x = location_.x();
- int y = location_.y();
- if (vertical_) {
- y += thumb_begin_offset;
- } else {
- x += thumb_begin_offset;
- }
- int width = vertical_ ? thickness_ : ThumbLength();
- int height = vertical_ ? ThumbLength() : thickness_;
- return gfx::Rect(x, y, width, height);
-}
-
-bool PepperScrollbarWidget::IsBackTrackPressed() const {
- return pressed_position_ >= 0 &&
- pressed_position_ < static_cast<int>(thumb_position_);
-}
-
-bool PepperScrollbarWidget::DidThumbCatchUpWithMouse() {
- if (IsTrackbar(pressed_part_) && IsThumbUnderMouse()) {
- hovered_part_ = vertical_ ?
- VERTICAL_THUMB : HORIZONTAL_THUMB;
- return true;
- }
-
- return false;
-}
-
-bool PepperScrollbarWidget::IsThumbUnderMouse() const {
- int thumb_start = static_cast<int>(thumb_position_);
- int thumb_end = thumb_start + ThumbLength();
- return pressed_position_ >= thumb_start &&
- pressed_position_ < thumb_end;
-}
-
-bool PepperScrollbarWidget::IsBackscrolling() const {
- return pressed_part_ == UP_ARROW ||
- pressed_part_ == LEFT_ARROW ||
- ((pressed_part_ == VERTICAL_TRACK ||
- pressed_part_ == HORIZONTAL_TRACK) &&
- IsBackTrackPressed());
-}
-
-int PepperScrollbarWidget::TrackLength() const {
- int rv = length_ - 2 * arrow_length_;
- if (rv < 0)
- rv = 0; // In case there isn't space after we draw the arrows.
- return rv;
-}
-
-int PepperScrollbarWidget::ThumbLength() const {
- float proportion = static_cast<float>(length_) / total_length_;
- int track_length = TrackLength();
- int length = static_cast<int>(proportion * track_length);
- length = std::max(length, MinimumThumbLength());
- if (length > track_length)
- length = 0; // In case there's no space for the thumb.
- return length;
-}
-
-int PepperScrollbarWidget::MaximumThumbPosition() const {
- return TrackLength() - ThumbLength();
-}
-
-float PepperScrollbarWidget::ThumbPixelsFromDocumentPixels(int pixels) const {
- return static_cast<float>(pixels) * MaximumThumbPosition() /
- (total_length_ - length_);
-}
-
-bool PepperScrollbarWidget::IsArrow(int part) {
- return part == DOWN_ARROW ||
- part == LEFT_ARROW ||
- part == RIGHT_ARROW ||
- part == UP_ARROW;
-}
-
-bool PepperScrollbarWidget::IsTrackbar(int part) {
- return part == HORIZONTAL_TRACK || part == VERTICAL_TRACK;
-}
-
-bool PepperScrollbarWidget::IsThumb(int part) {
- return part == HORIZONTAL_THUMB || part == VERTICAL_THUMB;
+void PepperScrollbarWidget::NotifyInvalidate() {
+ if (!dirty_rect_.IsEmpty())
+ WidgetPropertyChanged(NPWidgetPropertyDirtyRect);
}