diff options
Diffstat (limited to 'chrome/views/bitmap_scroll_bar.h')
-rw-r--r-- | chrome/views/bitmap_scroll_bar.h | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/chrome/views/bitmap_scroll_bar.h b/chrome/views/bitmap_scroll_bar.h new file mode 100644 index 0000000..f5e7610 --- /dev/null +++ b/chrome/views/bitmap_scroll_bar.h @@ -0,0 +1,209 @@ +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "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 THE COPYRIGHT +// OWNER 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 CHROME_VIEWS_BITMAP_SCROLL_BAR_H__ +#define CHROME_VIEWS_BITMAP_SCROLL_BAR_H__ + +#include "chrome/views/button.h" +#include "chrome/views/menu.h" +#include "chrome/views/repeat_controller.h" +#include "chrome/views/scroll_bar.h" + +namespace ChromeViews { + +namespace { +class BitmapScrollBarThumb; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// BitmapScrollBar +// +// A ScrollBar subclass that implements a scroll bar rendered using bitmaps +// that the user provides. There are bitmaps for the up and down buttons, as +// well as for the thumb and track. This is intended for creating UIs that +// have customized, non-native appearances, like floating HUDs etc. +// +// Maybe TODO(beng): (Cleanup) If we need to, we may want to factor rendering +// out of this altogether and have the user supply +// Background impls for each component, and just use those +// to render, so that for example we get native theme +// rendering. +// +/////////////////////////////////////////////////////////////////////////////// +class BitmapScrollBar : public ScrollBar, + public BaseButton::ButtonListener, + public ContextMenuController, + public Menu::Delegate { + public: + BitmapScrollBar(bool horizontal, bool show_scroll_buttons); + virtual ~BitmapScrollBar() { } + + // Get the bounds of the "track" area that the thumb is free to slide within. + gfx::Rect GetTrackBounds() const; + + // A list of parts that the user may supply bitmaps for. + enum ScrollBarPart { + PREV_BUTTON = 0, // The button used to represent scrolling up/left by 1 line. + NEXT_BUTTON, // The button used to represent scrolling down/right by 1 line. + // IMPORTANT: The code assumes the prev and next + // buttons have equal width and equal height. + THUMB_START_CAP, // The top/left segment of the thumb on the scrollbar. + THUMB_MIDDLE, // The tiled background image of the thumb. + THUMB_END_CAP, // The bottom/right segment of the thumb on the scrollbar. + THUMB_GRIPPY, // The grippy that is rendered in the center of the thumb. + THUMB_TRACK, // The tiled background image of the thumb track. + PART_COUNT + }; + + // Sets the bitmap to be rendered for the specified part and state. + void SetImage(ScrollBarPart part, + BaseButton::ButtonState state, + SkBitmap* bitmap); + + // An enumeration of different amounts of incremental scroll, representing + // events sent from different parts of the UI/keyboard. + enum ScrollAmount { + SCROLL_NONE = 0, + SCROLL_START, + SCROLL_END, + SCROLL_PREV_LINE, + SCROLL_NEXT_LINE, + SCROLL_PREV_PAGE, + SCROLL_NEXT_PAGE, + }; + + // Scroll the contents by the specified type (see ScrollAmount above). + void ScrollByAmount(ScrollAmount amount); + + // Scroll the contents to the appropriate position given the supplied + // position of the thumb (thumb track coordinates). If |scroll_to_middle| is + // true, then the conversion assumes |thumb_position| is in the middle of the + // thumb rather than the top. + void ScrollToThumbPosition(int thumb_position, bool scroll_to_middle); + + // Scroll the contents by the specified offset (contents coordinates). + void ScrollByContentsOffset(int contents_offset); + + // View overrides: + virtual void GetPreferredSize(CSize* preferred_size); + virtual void Paint(ChromeCanvas* canvas); + virtual void Layout(); + virtual void DidChangeBounds(const CRect& previous, const CRect& current); + virtual bool OnMousePressed(const MouseEvent& event); + virtual void OnMouseReleased(const MouseEvent& event, bool canceled); + virtual bool OnMouseWheel(const MouseWheelEvent& event); + virtual bool OnKeyPressed(const KeyEvent& event); + + // BaseButton::ButtonListener overrides: + virtual void ButtonPressed(BaseButton* sender); + + // ScrollBar overrides: + virtual void Update(int viewport_size, + int content_size, + int contents_scroll_offset); + virtual int GetLayoutSize() const; + virtual int GetPosition() const; + + // ContextMenuController overrides. + virtual void ShowContextMenu(View* source, int x, int y, + bool is_mouse_gesture); + + // Menu::Delegate overrides: + virtual std::wstring GetLabel(int id) const; + virtual bool IsCommandEnabled(int id) const; + virtual void ExecuteCommand(int id); + + private: + // Called when the mouse is pressed down in the track area. + void TrackClicked(); + + // Responsible for scrolling the contents and also updating the UI to the + // current value of the Scroll Offset. + void ScrollContentsToOffset(); + + // Returns the size (width or height) of the track area of the ScrollBar. + int GetTrackSize() const; + + // Calculate the position of the thumb within the track based on the + // specified scroll offset of the contents. + int CalculateThumbPosition(int contents_scroll_offset) const; + + // Calculates the current value of the contents offset (contents coordinates) + // based on the current thumb position (thumb track coordinates). See + // |ScrollToThumbPosition| for an explanation of |scroll_to_middle|. + int CalculateContentsOffset(int thumb_position, + bool scroll_to_middle) const; + + // Called when the state of the thumb track changes (e.g. by the user + // pressing the mouse button down in it). + void SetThumbTrackState(BaseButton::ButtonState state); + + // The thumb needs to be able to access the part images. + friend BitmapScrollBarThumb; + SkBitmap* images_[PART_COUNT][BaseButton::kButtonStateCount]; + + // The size of the scrolled contents, in pixels. + int contents_size_; + + // The current amount the contents is offset by in the viewport. + int contents_scroll_offset_; + + // Up/Down/Left/Right buttons and the Thumb. + Button* prev_button_; + Button* next_button_; + BitmapScrollBarThumb* thumb_; + + // The state of the scrollbar track. Typically, the track will highlight when + // the user presses the mouse on them (during page scrolling). + BaseButton::ButtonState thumb_track_state_; + + // The last amount of incremental scroll that this scrollbar performed. This + // is accessed by the callbacks for the auto-repeat up/down buttons to know + // what direction to repeatedly scroll in. + ScrollAmount last_scroll_amount_; + + // An instance of a RepeatController which scrolls the scrollbar continuously + // as the user presses the mouse button down on the up/down buttons or the + // track. + RepeatController repeater_; + + // The position of the mouse within the scroll bar when the context menu + // was invoked. + int context_menu_mouse_position_; + + // True if the scroll buttons at each end of the scroll bar should be shown. + bool show_scroll_buttons_; + + DISALLOW_EVIL_CONSTRUCTORS(BitmapScrollBar); +}; + +} + +#endif // #ifndef CHROME_VIEWS_BITMAP_SCROLL_BAR_H__ |