1 // -*- C++ -*- 2 /* GG is a GUI for OpenGL. 3 Copyright (C) 2003-2008 T. Zachary Laine 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public License 7 as published by the Free Software Foundation; either version 2.1 8 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 02111-1307 USA 19 20 If you do not wish to comply with the terms of the LGPL please 21 contact the author as other terms are available for a fee. 22 23 Zach Laine 24 whatwasthataddress@gmail.com */ 25 26 /** \file Scroll.h \brief Contains the Scroll scrollbar control class. */ 27 28 #ifndef _GG_Scroll_h_ 29 #define _GG_Scroll_h_ 30 31 #include <GG/Control.h> 32 #include <GG/GLClientAndServerBuffer.h> 33 34 #include <boost/signals2/signal.hpp> 35 36 37 namespace GG { 38 39 class Button; 40 41 /** \brief This is a basic scrollbar control. 42 43 The range of the values the scrollbar represents is [m_range_min, 44 m_range_max]. However, m_posn can only range over [m_range_min, 45 m_range_max - m_page_sz], because the tab has a logical width of 46 m_page_sz. So the region of the scrollbar's range being viewed at any one 47 time is [m_posn, m_posn + m_page_sz]. (m_posn + m_page_sz is actually the 48 last + 1 element of the range.) The parent of the control is notified of 49 a scroll via ScrolledSignalType signals; these are emitted from the 50 Scroll*() functions and the UpdatePosn() function. This should cover 51 every instance in which m_posn is altered. The parent can poll the 52 control to get its current view area with a call to GetPosnRange(). An 53 increase in a vertical scroll is down, and a decrease is up; since GG 54 assumes the y-coordinates are downwardly increasing. The rather plain 55 default buttons and tab can be replaced by any Button-derived controls 56 desired. */ 57 class GG_API Scroll : public Control 58 { 59 public: 60 /// the clickable regions of a Scroll 61 GG_CLASS_ENUM(ScrollRegion, 62 SBR_NONE, 63 SBR_PAGE_DN, 64 SBR_PAGE_UP 65 ) 66 67 /** \name Signal Types */ ///@{ 68 /** emitted whenever the scrollbar is moved; the upper and lower extents 69 of the tab and the upper and lower bounds of the scroll's range are 70 indicated, respectively */ 71 typedef boost::signals2::signal<void (int, int, int, int)> ScrolledSignalType; 72 /** emitted when the scrollbar's tab is stopped after being dragged, the 73 scrollbar is adjusted using the keyboard, or the scrollbar is moved 74 programmatically; the upper and lower extents of the tab and the 75 upper and lower bounds of the scroll's range are indicated, 76 respectively */ 77 typedef boost::signals2::signal<void (int, int, int, int)> ScrolledAndStoppedSignalType; 78 //@} 79 80 /** \name Structors */ ///@{ 81 /** Ctor. */ 82 Scroll(Orientation orientation, Clr color, Clr interior); 83 //@} 84 void CompleteConstruction() override; 85 86 /** \name Accessors */ ///@{ 87 Pt MinUsableSize() const override; 88 89 std::pair<int, int> PosnRange() const; ///< range currently being viewed 90 std::pair<int, int> ScrollRange() const; ///< defined possible range of control 91 unsigned int LineSize() const; ///< returns the current line size 92 unsigned int PageSize() const; ///< returns the current page size 93 94 Clr InteriorColor() const; ///< returns the color used to render the interior of the Scroll 95 Orientation ScrollOrientation() const; ///< returns the orientation of the Scroll 96 97 mutable ScrolledSignalType ScrolledSignal; ///< the scrolled signal object for this Scroll 98 mutable ScrolledAndStoppedSignalType ScrolledAndStoppedSignal; ///< the scrolled-and-stopped signal object for this Scroll 99 //@} 100 101 /** \name Mutators */ ///@{ 102 void Render() override; 103 104 void SizeMove(const Pt& ul, const Pt& lr) override; 105 106 void Disable(bool b = true) override; 107 void SetColor(Clr c) override; 108 109 virtual void DoLayout(); 110 111 void SetInteriorColor(Clr c); ///< sets the color painted into the client area of the control 112 void SizeScroll(int min, int max, unsigned int line, unsigned int page); ///< sets the logical ranges of the control, and the logical increment values 113 void SetMax(int max); ///< sets the maximum value of the scroll 114 void SetMin(int min); ///< sets the minimum value of the scroll 115 void SetLineSize(unsigned int line); ///< sets the size of a line in the scroll. This is the number of logical units the tab moves when either of the up or down buttons is pressed. 116 void SetPageSize(unsigned int page); ///< sets the size of a line page in the scroll. This is the number of logical units the tab moves when either of the page-up or page-down areas is clicked. 117 118 void ScrollTo(int p); ///< scrolls the control to a certain spot 119 void ScrollLineIncr(int lines = 1); ///< scrolls the control down (or right) by \a lines lines 120 void ScrollLineDecr(int lines = 1); ///< scrolls the control up (or left) by \a lines lines 121 void ScrollPageIncr(); ///< scrolls the control down (or right) by a page 122 void ScrollPageDecr(); ///< scrolls the control up (or left) by a page 123 //@} 124 125 protected: 126 /** \name Accessors */ ///@{ 127 unsigned int TabSpace() const; ///< returns the space the tab has to move about in (the control's width less the width of the incr & decr buttons) 128 unsigned int TabWidth() const; ///< returns the calculated width of the tab, based on PageSize() and the logical size of the control, in pixels 129 ScrollRegion RegionUnder(const Pt& pt); ///< determines whether a pt is in the incr or decr or tab buttons, or in PgUp/PgDn regions in between 130 131 Button* TabButton() const; ///< returns the button representing the tab 132 Button* IncrButton() const; ///< returns the increase button (line down/line right) 133 Button* DecrButton() const; ///< returns the decrease button (line up/line left) 134 //@} 135 136 /** \name Mutators */ ///@{ 137 void LButtonDown(const Pt& pt, Flags<ModKey> mod_keys) override; 138 void LButtonUp(const Pt& pt, Flags<ModKey> mod_keys) override; 139 void LClick(const Pt& pt, Flags<ModKey> mod_keys) override; 140 void MouseHere(const Pt& pt, Flags<ModKey> mod_keys) override; 141 bool EventFilter(Wnd* w, const WndEvent& event) override; 142 143 virtual void InitBuffer(); 144 //@} 145 146 GG::GL2DVertexBuffer m_buffer; 147 148 private: 149 void UpdatePosn(); ///< adjusts m_posn due to a tab-drag 150 void MoveTabToPosn(); ///< adjusts tab due to a button click, PgUp, etc. 151 void ScrollLineIncrDecrImpl(bool signal, int lines); 152 153 Clr m_int_color; ///< color inside border of slide area 154 const Orientation m_orientation; ///< vertical or horizontal scroll? (use enum for these declared above) 155 int m_posn; ///< current position of tab in logical coords (will be in [m_range_min, m_range_max - m_page_sz]) 156 int m_range_min; ///< lowest value in range of scrollbar 157 int m_range_max; ///< highest value " 158 unsigned int m_line_sz; ///< logical units traversed in a line movement (such as a click on either end button) 159 unsigned int m_page_sz; ///< logical units traversed for a page movement (such as a click in non-tab middle area, or PgUp/PgDn) 160 std::shared_ptr<Button> m_tab; ///< the button representing the tab 161 std::shared_ptr<Button> m_incr; ///< the increase button (line down/line right) 162 std::shared_ptr<Button> m_decr; ///< the decrease button (line up/line left) 163 ScrollRegion m_initial_depressed_region; ///< the part of the scrollbar originally under cursor in LButtonDown msg 164 ScrollRegion m_depressed_region; ///< the part of the scrollbar currently being "depressed" by held-down mouse button 165 bool m_dragging_tab = false; 166 bool m_tab_dragged = false; 167 }; 168 169 /** A convenience function that signals \a scroll's position, via 170 Scroll::ScrolledSignal. If \a stopped is true, the position is 171 additionally signalled on Scroll::ScrolledAndStoppedSignal. */ 172 GG_API void SignalScroll(const Scroll& scroll, bool stopped); 173 174 } // namespace GG 175 176 #endif 177