blob: c27387bdc65a0300d1c026b8c0420fa9e5049d4f [file] [log] [blame]
/*
* Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef Scrollbar_h
#define Scrollbar_h
#include "platform/Timer.h"
#include "platform/graphics/paint/DisplayItem.h"
#include "platform/heap/Handle.h"
#include "platform/scroll/ScrollTypes.h"
#include "platform/scroll/ScrollbarThemeClient.h"
#include "platform/wtf/MathExtras.h"
namespace blink {
class CullRect;
class GraphicsContext;
class IntRect;
class PlatformChromeClient;
class ScrollableArea;
class ScrollbarTheme;
class WebGestureEvent;
class WebMouseEvent;
class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>,
public ScrollbarThemeClient,
public DisplayItemClient {
public:
static Scrollbar* Create(ScrollableArea* scrollable_area,
ScrollbarOrientation orientation,
ScrollbarControlSize size,
PlatformChromeClient* chrome_client) {
return new Scrollbar(scrollable_area, orientation, size, chrome_client);
}
// Theme object ownership remains with the caller and it must outlive the
// scrollbar.
static Scrollbar* CreateForTesting(ScrollableArea* scrollable_area,
ScrollbarOrientation orientation,
ScrollbarControlSize size,
ScrollbarTheme* theme) {
return new Scrollbar(scrollable_area, orientation, size, nullptr, theme);
}
~Scrollbar() override;
// ScrollbarThemeClient implementation.
int X() const override { return frame_rect_.X(); }
int Y() const override { return frame_rect_.Y(); }
int Width() const override { return frame_rect_.Width(); }
int Height() const override { return frame_rect_.Height(); }
IntSize Size() const override { return frame_rect_.Size(); }
IntPoint Location() const override { return frame_rect_.Location(); }
void SetFrameRect(const IntRect&);
IntRect FrameRect() const override { return frame_rect_; }
ScrollbarOverlayColorTheme GetScrollbarOverlayColorTheme() const override;
void GetTickmarks(Vector<IntRect>&) const override;
bool IsScrollableAreaActive() const override;
IntPoint ConvertFromRootFrame(const IntPoint&) const override;
bool IsCustomScrollbar() const override { return false; }
ScrollbarOrientation Orientation() const override { return orientation_; }
bool IsLeftSideVerticalScrollbar() const override;
int Value() const override { return lroundf(current_pos_); }
float CurrentPos() const override { return current_pos_; }
int VisibleSize() const override { return visible_size_; }
int TotalSize() const override { return total_size_; }
int Maximum() const override { return total_size_ - visible_size_; }
ScrollbarControlSize GetControlSize() const override { return control_size_; }
ScrollbarPart PressedPart() const override { return pressed_part_; }
ScrollbarPart HoveredPart() const override { return hovered_part_; }
void StyleChanged() override {}
void SetScrollbarsHidden(bool) override;
bool Enabled() const override { return enabled_; }
void SetEnabled(bool) override;
// This returns device-scale-factor-aware pixel value.
// e.g. 15 in dsf=1.0, 30 in dsf=2.0.
// This returns 0 for overlay scrollbars.
// See also ScrolbarTheme::scrollbatThickness().
int ScrollbarThickness() const;
// Called by the ScrollableArea when the scroll offset changes.
// Will trigger paint invalidation if required.
void OffsetDidChange();
virtual void DisconnectFromScrollableArea();
ScrollableArea* GetScrollableArea() const { return scrollable_area_; }
int PressedPos() const { return pressed_pos_; }
virtual void SetHoveredPart(ScrollbarPart);
virtual void SetPressedPart(ScrollbarPart);
void SetProportion(int visible_size, int total_size);
void SetPressedPos(int p) { pressed_pos_ = p; }
void Paint(GraphicsContext&, const CullRect&) const;
bool IsOverlayScrollbar() const override;
bool ShouldParticipateInHitTesting();
bool IsWindowActive() const;
// Return if the gesture event was handled. |shouldUpdateCapture|
// will be set to true if the handler should update the capture
// state for this scrollbar.
bool GestureEvent(const WebGestureEvent&, bool* should_update_capture);
// These methods are used for platform scrollbars to give :hover feedback.
// They will not get called when the mouse went down in a scrollbar, since it
// is assumed the scrollbar will start
// grabbing all events in that case anyway.
void MouseMoved(const WebMouseEvent&);
void MouseEntered();
void MouseExited();
// Used by some platform scrollbars to know when they've been released from
// capture.
void MouseUp(const WebMouseEvent&);
void MouseDown(const WebMouseEvent&);
ScrollbarTheme& GetTheme() const { return theme_; }
IntRect ConvertToContainingEmbeddedContentView(const IntRect&) const;
IntPoint ConvertFromContainingEmbeddedContentView(const IntPoint&) const;
void MoveThumb(int pos, bool dragging_document = false);
float ElasticOverscroll() const override { return elastic_overscroll_; }
void SetElasticOverscroll(float elastic_overscroll) override {
elastic_overscroll_ = elastic_overscroll;
}
// Use setNeedsPaintInvalidation to cause the scrollbar (or parts thereof)
// to repaint.
bool TrackNeedsRepaint() const { return track_needs_repaint_; }
void ClearTrackNeedsRepaint() { track_needs_repaint_ = false; }
bool ThumbNeedsRepaint() const { return thumb_needs_repaint_; }
void ClearThumbNeedsRepaint() { thumb_needs_repaint_ = false; }
// DisplayItemClient methods.
String DebugName() const final {
return orientation_ == kHorizontalScrollbar ? "HorizontalScrollbar"
: "VerticalScrollbar";
}
LayoutRect VisualRect() const final { return visual_rect_; }
virtual void SetVisualRect(const LayoutRect& r) { visual_rect_ = r; }
// Marks the scrollbar as needing to be redrawn.
//
// If invalid parts are provided, then those parts will also be repainted.
// Otherwise, the ScrollableArea may redraw using cached renderings of
// individual parts. For instance, if the scrollbar is composited, the thumb
// may be cached in a GPU texture (and is only guaranteed to be repainted if
// ThumbPart is invalidated).
//
// Even if no parts are invalidated, the scrollbar may need to be redrawn
// if, for instance, the thumb moves without changing the appearance of any
// part.
void SetNeedsPaintInvalidation(ScrollbarPart invalid_parts);
// Promptly unregister from the theme manager + run finalizers of derived
// Scrollbars.
EAGERLY_FINALIZE();
DECLARE_EAGER_FINALIZATION_OPERATOR_NEW();
virtual void Trace(blink::Visitor*);
protected:
Scrollbar(ScrollableArea*,
ScrollbarOrientation,
ScrollbarControlSize,
PlatformChromeClient* = nullptr,
ScrollbarTheme* = nullptr);
void AutoscrollTimerFired(TimerBase*);
void StartTimerIfNeeded(double delay);
void StopTimerIfNeeded();
void AutoscrollPressedPart(double delay);
ScrollDirectionPhysical PressedPartScrollDirectionPhysical();
ScrollGranularity PressedPartScrollGranularity();
Member<ScrollableArea> scrollable_area_;
ScrollbarOrientation orientation_;
ScrollbarControlSize control_size_;
ScrollbarTheme& theme_;
Member<PlatformChromeClient> chrome_client_;
int visible_size_;
int total_size_;
float current_pos_;
float drag_origin_;
ScrollbarPart hovered_part_;
ScrollbarPart pressed_part_;
int pressed_pos_;
float scroll_pos_;
bool dragging_document_;
int document_drag_pos_;
bool enabled_;
TaskRunnerTimer<Scrollbar> scroll_timer_;
float elastic_overscroll_;
private:
void Invalidate() override { SetNeedsPaintInvalidation(kAllParts); }
void InvalidateRect(const IntRect&) override {
SetNeedsPaintInvalidation(kAllParts);
}
float ScrollableAreaCurrentPos() const;
float ScrollableAreaTargetPos() const;
bool ThumbWillBeUnderMouse() const;
int theme_scrollbar_thickness_;
bool track_needs_repaint_;
bool thumb_needs_repaint_;
LayoutRect visual_rect_;
IntRect frame_rect_;
};
} // namespace blink
#endif // Scrollbar_h