blob: c649497eff83765397a4817b72c0247f5aeede19 [file] [log] [blame]
DRC2ff39b82011-07-28 08:38:59 +00001//
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
28/* \file
29 Fl_Scroll widget . */
30
31#ifndef Fl_Scroll_H
32#define Fl_Scroll_H
33
34#include "Fl_Group.H"
35#include "Fl_Scrollbar.H"
36
37/**
38 This container widget lets you maneuver around a set of widgets much
39 larger than your window. If the child widgets are larger than the size
40 of this object then scrollbars will appear so that you can scroll over
41 to them:
42 \image html Fl_Scroll.png
43 \image latex Fl_Scroll.png "Fl_Scroll" width=4cm
44
45 If all of the child widgets are packed together into a solid
46 rectangle then you want to set box() to FL_NO_BOX or
47 one of the _FRAME types. This will result in the best output.
48 However, if the child widgets are a sparse arrangement you must
49 set box() to a real _BOX type. This can result in some
50 blinking during redrawing, but that can be solved by using a
51 Fl_Double_Window.
52
53 By default you can scroll in both directions, and the scrollbars
54 disappear if the data will fit in the area of the scroll.
55
56 Use Fl_Scroll::type() to change this as follows :
57 <UL>
58 <LI>0 - No scrollbars </LI>
59 <LI>Fl_Scroll::HORIZONTAL - Only a horizontal scrollbar. </LI>
60 <LI>Fl_Scroll::VERTICAL - Only a vertical scrollbar. </LI>
61 <LI>Fl_Scroll::BOTH - The default is both scrollbars. </LI>
62 <LI>Fl_Scroll::HORIZONTAL_ALWAYS - Horizontal scrollbar always on, vertical always off. </LI>
63 <LI>Fl_Scroll::VERTICAL_ALWAYS - Vertical scrollbar always on, horizontal always off. </LI>
64 <LI>Fl_Scroll::BOTH_ALWAYS - Both always on. </LI>
65 </UL>
66
67 Use <B> scrollbar.align(int) ( see void Fl_Widget::align(Fl_Align) ) :</B>
68 to change what side the scrollbars are drawn on.
69
70 If the FL_ALIGN_LEFT bit is on, the vertical scrollbar is on the left.
71 If the FL_ALIGN_TOP bit is on, the horizontal scrollbar is on
72 the top. Note that only the alignment flags in scrollbar are
73 considered. The flags in hscrollbar however are ignored.
74
75 This widget can also be used to pan around a single child widget
76 "canvas". This child widget should be of your own class, with a
77 draw() method that draws the contents. The scrolling is done by
78 changing the x() and y() of the widget, so this child
79 must use the x() and y() to position its drawing.
80 To speed up drawing it should test fl_push_clip().
81
82 Another very useful child is a single Fl_Pack, which is itself a group
83 that packs its children together and changes size to surround them.
84 Filling the Fl_Pack with Fl_Tabs groups (and then putting
85 normal widgets inside those) gives you a very powerful scrolling list
86 of individually-openable panels.
87
88 Fluid lets you create these, but you can only lay out objects that
89 fit inside the Fl_Scroll without scrolling. Be sure to leave
90 space for the scrollbars, as Fluid won't show these either.
91
92 <I>You cannot use Fl_Window as a child of this since the
93 clipping is not conveyed to it when drawn, and it will draw over the
94 scrollbars and neighboring objects.</I>
95*/
96class FL_EXPORT Fl_Scroll : public Fl_Group {
97
98 int xposition_, yposition_;
99 int oldx, oldy;
100 int scrollbar_size_;
101 static void hscrollbar_cb(Fl_Widget*, void*);
102 static void scrollbar_cb(Fl_Widget*, void*);
103 void fix_scrollbar_order();
104 static void draw_clip(void*,int,int,int,int);
105
106private:
107
108 //
109 // Structure to manage scrollbar and widget interior sizes.
110 //
111 // Private for now -- we'd like to expose some of this at
112 // some point to solve STR#1895.)
113 //
114 typedef struct {
115 int scrollsize; // the scrollsize (global|local)
116 int innerbox_x, innerbox_y, innerbox_w, innerbox_h; // widget's inner box (excludes scrollbars)
117 int innerchild_x, innerchild_y, innerchild_w, innerchild_h; // widget's inner box including scrollbars
118 int child_l, child_r, child_b, child_t; // child bounding box: left/right/bottom/top
119 int hneeded, vneeded; // hor + ver scrollbar visibility
120 int hscroll_x, hscroll_y, hscroll_w, hscroll_h; // hor scrollbar size/position
121 int vscroll_x, vscroll_y, vscroll_w, vscroll_h; // ver scrollbar size/position
122 int hpos, hsize, hfirst, htotal; // hor scrollbar values (pos/size/first/total)
123 int vpos, vsize, vfirst, vtotal; // ver scrollbar values (pos/size/first/total)
124 } ScrollInfo;
125 void recalc_scrollbars(ScrollInfo &si);
126
127protected:
128
129 void bbox(int&,int&,int&,int&);
130 void draw();
131
132public:
133
134 Fl_Scrollbar scrollbar;
135 Fl_Scrollbar hscrollbar;
136
137 void resize(int,int,int,int);
138 int handle(int);
139
140 Fl_Scroll(int X,int Y,int W,int H,const char*l=0);
141
142 enum { // values for type()
143 HORIZONTAL = 1,
144 VERTICAL = 2,
145 BOTH = 3,
146 ALWAYS_ON = 4,
147 HORIZONTAL_ALWAYS = 5,
148 VERTICAL_ALWAYS = 6,
149 BOTH_ALWAYS = 7
150 };
151
152 /** Gets the current horizontal scrolling position. */
153 int xposition() const {return xposition_;}
154 /** Gets the current vertical scrolling position. */
155 int yposition() const {return yposition_;}
156 void scroll_to(int, int);
157 void clear();
158 /**
159 Gets the current size of the scrollbars' troughs, in pixels.
160
161 If this value is zero (default), this widget will use the
162 Fl::scrollbar_size() value as the scrollbar's width.
163
164 \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used.
165 \see Fl::scrollbar_size(int)
166 */
167 int scrollbar_size() const {
168 return(scrollbar_size_);
169 }
170 /**
171 Sets the pixel size of the scrollbars' troughs to the \p size, in pixels.
172
173 Normally you should not need this method, and should use
174 Fl::scrollbar_size(int) instead to manage the size of ALL
175 your widgets' scrollbars. This ensures your application
176 has a consistent UI, is the default behavior, and is normally
177 what you want.
178
179 Only use THIS method if you really need to override the global
180 scrollbar size. The need for this should be rare.
181
182 Setting \p size to the special value of 0 causes the widget to
183 track the global Fl::scrollbar_size(), which is the default.
184
185 \param[in] size Sets the scrollbar size in pixels.\n
186 If 0 (default), scrollbar size tracks the global Fl::scrollbar_size()
187 \see Fl::scrollbar_size()
188 */
189 void scrollbar_size(int size) {
190 if ( size != scrollbar_size_ ) redraw();
191 scrollbar_size_ = size;
192 }
193};
194
195#endif
196
197//
198// End of "$Id: Fl_Scroll.H 7981 2010-12-08 23:53:04Z greg.ercolano $".
199//