You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
7.3KB

  1. //
  2. // "$Id: Fl_Scroll.H 7981 2010-12-08 23:53:04Z greg.ercolano $"
  3. //
  4. // Scroll header file for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-2010 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems on the following page:
  24. //
  25. // http://www.fltk.org/str.php
  26. //
  27. /* \file
  28. Fl_Scroll widget . */
  29. #ifndef Fl_Scroll_H
  30. #define Fl_Scroll_H
  31. #include "Fl_Group.H"
  32. #include "Fl_Scrollbar.H"
  33. /**
  34. This container widget lets you maneuver around a set of widgets much
  35. larger than your window. If the child widgets are larger than the size
  36. of this object then scrollbars will appear so that you can scroll over
  37. to them:
  38. \image html Fl_Scroll.png
  39. \image latex Fl_Scroll.png "Fl_Scroll" width=4cm
  40. If all of the child widgets are packed together into a solid
  41. rectangle then you want to set box() to FL_NO_BOX or
  42. one of the _FRAME types. This will result in the best output.
  43. However, if the child widgets are a sparse arrangement you must
  44. set box() to a real _BOX type. This can result in some
  45. blinking during redrawing, but that can be solved by using a
  46. Fl_Double_Window.
  47. By default you can scroll in both directions, and the scrollbars
  48. disappear if the data will fit in the area of the scroll.
  49. Use Fl_Scroll::type() to change this as follows :
  50. <UL>
  51. <LI>0 - No scrollbars </LI>
  52. <LI>Fl_Scroll::HORIZONTAL - Only a horizontal scrollbar. </LI>
  53. <LI>Fl_Scroll::VERTICAL - Only a vertical scrollbar. </LI>
  54. <LI>Fl_Scroll::BOTH - The default is both scrollbars. </LI>
  55. <LI>Fl_Scroll::HORIZONTAL_ALWAYS - Horizontal scrollbar always on, vertical always off. </LI>
  56. <LI>Fl_Scroll::VERTICAL_ALWAYS - Vertical scrollbar always on, horizontal always off. </LI>
  57. <LI>Fl_Scroll::BOTH_ALWAYS - Both always on. </LI>
  58. </UL>
  59. Use <B> scrollbar.align(int) ( see void Fl_Widget::align(Fl_Align) ) :</B>
  60. to change what side the scrollbars are drawn on.
  61. If the FL_ALIGN_LEFT bit is on, the vertical scrollbar is on the left.
  62. If the FL_ALIGN_TOP bit is on, the horizontal scrollbar is on
  63. the top. Note that only the alignment flags in scrollbar are
  64. considered. The flags in hscrollbar however are ignored.
  65. This widget can also be used to pan around a single child widget
  66. "canvas". This child widget should be of your own class, with a
  67. draw() method that draws the contents. The scrolling is done by
  68. changing the x() and y() of the widget, so this child
  69. must use the x() and y() to position its drawing.
  70. To speed up drawing it should test fl_push_clip().
  71. Another very useful child is a single Fl_Pack, which is itself a group
  72. that packs its children together and changes size to surround them.
  73. Filling the Fl_Pack with Fl_Tabs groups (and then putting
  74. normal widgets inside those) gives you a very powerful scrolling list
  75. of individually-openable panels.
  76. Fluid lets you create these, but you can only lay out objects that
  77. fit inside the Fl_Scroll without scrolling. Be sure to leave
  78. space for the scrollbars, as Fluid won't show these either.
  79. <I>You cannot use Fl_Window as a child of this since the
  80. clipping is not conveyed to it when drawn, and it will draw over the
  81. scrollbars and neighboring objects.</I>
  82. */
  83. class FL_EXPORT Fl_Scroll : public Fl_Group {
  84. int xposition_, yposition_;
  85. int oldx, oldy;
  86. int scrollbar_size_;
  87. static void hscrollbar_cb(Fl_Widget*, void*);
  88. static void scrollbar_cb(Fl_Widget*, void*);
  89. void fix_scrollbar_order();
  90. static void draw_clip(void*,int,int,int,int);
  91. private:
  92. //
  93. // Structure to manage scrollbar and widget interior sizes.
  94. //
  95. // Private for now -- we'd like to expose some of this at
  96. // some point to solve STR#1895.)
  97. //
  98. typedef struct {
  99. int scrollsize; // the scrollsize (global|local)
  100. int innerbox_x, innerbox_y, innerbox_w, innerbox_h; // widget's inner box (excludes scrollbars)
  101. int innerchild_x, innerchild_y, innerchild_w, innerchild_h; // widget's inner box including scrollbars
  102. int child_l, child_r, child_b, child_t; // child bounding box: left/right/bottom/top
  103. int hneeded, vneeded; // hor + ver scrollbar visibility
  104. int hscroll_x, hscroll_y, hscroll_w, hscroll_h; // hor scrollbar size/position
  105. int vscroll_x, vscroll_y, vscroll_w, vscroll_h; // ver scrollbar size/position
  106. int hpos, hsize, hfirst, htotal; // hor scrollbar values (pos/size/first/total)
  107. int vpos, vsize, vfirst, vtotal; // ver scrollbar values (pos/size/first/total)
  108. } ScrollInfo;
  109. void recalc_scrollbars(ScrollInfo &si);
  110. protected:
  111. void bbox(int&,int&,int&,int&);
  112. void draw();
  113. public:
  114. Fl_Scrollbar scrollbar;
  115. Fl_Scrollbar hscrollbar;
  116. void resize(int,int,int,int);
  117. int handle(int);
  118. Fl_Scroll(int X,int Y,int W,int H,const char*l=0);
  119. enum { // values for type()
  120. HORIZONTAL = 1,
  121. VERTICAL = 2,
  122. BOTH = 3,
  123. ALWAYS_ON = 4,
  124. HORIZONTAL_ALWAYS = 5,
  125. VERTICAL_ALWAYS = 6,
  126. BOTH_ALWAYS = 7
  127. };
  128. /** Gets the current horizontal scrolling position. */
  129. int xposition() const {return xposition_;}
  130. /** Gets the current vertical scrolling position. */
  131. int yposition() const {return yposition_;}
  132. void scroll_to(int, int);
  133. void clear();
  134. /**
  135. Gets the current size of the scrollbars' troughs, in pixels.
  136. If this value is zero (default), this widget will use the
  137. Fl::scrollbar_size() value as the scrollbar's width.
  138. \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used.
  139. \see Fl::scrollbar_size(int)
  140. */
  141. int scrollbar_size() const {
  142. return(scrollbar_size_);
  143. }
  144. /**
  145. Sets the pixel size of the scrollbars' troughs to the \p size, in pixels.
  146. Normally you should not need this method, and should use
  147. Fl::scrollbar_size(int) instead to manage the size of ALL
  148. your widgets' scrollbars. This ensures your application
  149. has a consistent UI, is the default behavior, and is normally
  150. what you want.
  151. Only use THIS method if you really need to override the global
  152. scrollbar size. The need for this should be rare.
  153. Setting \p size to the special value of 0 causes the widget to
  154. track the global Fl::scrollbar_size(), which is the default.
  155. \param[in] size Sets the scrollbar size in pixels.\n
  156. If 0 (default), scrollbar size tracks the global Fl::scrollbar_size()
  157. \see Fl::scrollbar_size()
  158. */
  159. void scrollbar_size(int size) {
  160. if ( size != scrollbar_size_ ) redraw();
  161. scrollbar_size_ = size;
  162. }
  163. };
  164. #endif
  165. //
  166. // End of "$Id: Fl_Scroll.H 7981 2010-12-08 23:53:04Z greg.ercolano $".
  167. //