1 //
2 // "$Id: Fl_Browser_.H 8275 2011-01-13 22:07:31Z manolo $"
3 //
4 // Common browser 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_Browser_ widget . */
30 
31 // Yes, I know this should be a template...
32 
33 #ifndef Fl_Browser__H
34 #define Fl_Browser__H
35 
36 #ifndef Fl_Group_H
37 #include "Fl_Group.H"
38 #endif
39 #include "Fl_Scrollbar.H"
40 #include <FL/Fl.H>		// Fl::scrollbar_size()
41 
42 #define FL_NORMAL_BROWSER	0	/**< type() of Fl_Browser */
43 #define FL_SELECT_BROWSER	1	/**< type() of FL_Select_Browser */
44 #define FL_HOLD_BROWSER		2	/**< type() of Fl_Hold_Browser */
45 #define FL_MULTI_BROWSER	3	/**< type() of Fl_Multi_Browser */
46 
47 #define FL_SORT_ASCENDING	0	/**< sort browser items in ascending alphabetic order. */
48 #define FL_SORT_DESCENDING	1	/**< sort in descending order */
49 
50 /**
51   This is the base class for browsers.  To be useful it must be
52   subclassed and several virtual functions defined.  The Forms-compatible
53   browser and the file chooser's browser are subclassed off of this.
54 
55   This has been designed so that the subclass has complete control
56   over the storage of the data, although because next() and
57   prev() functions are used to index, it works best as a linked list
58   or as a large block of characters in which the line breaks must be
59   searched for.
60 
61   A great deal of work has been done so that the "height" of a data
62   object does not need to be determined until it is drawn.  This is
63   useful if actually figuring out the size of an object requires
64   accessing image data or doing stat() on a file or doing some
65   other slow operation.
66 */
67 class FL_EXPORT Fl_Browser_ : public Fl_Group {
68   int position_;	// where user wants it scrolled to
69   int real_position_;	// the current vertical scrolling position
70   int hposition_;	// where user wants it panned to
71   int real_hposition_;	// the current horizontal scrolling position
72   int offset_;		// how far down top_ item the real_position is
73   int max_width;	// widest object seen so far
74   uchar has_scrollbar_;	// which scrollbars are enabled
75   Fl_Font textfont_;
76   Fl_Fontsize textsize_;
77   Fl_Color textcolor_;
78   void* top_;		// which item scrolling position is in
79   void* selection_;	// which is selected (except for FL_MULTI_BROWSER)
80   void *redraw1,*redraw2; // minimal update pointers
81   void* max_width_item;	// which item has max_width_
82   int scrollbar_size_;	// size of scrollbar trough
83 
84   void update_top();
85 
86 protected:
87 
88   // All of the following must be supplied by the subclass:
89   /**
90     This method must be provided by the subclass
91     to return the first item in the list.
92     \see item_first(), item_next(), item_last(), item_prev()
93    */
94   virtual void *item_first() const = 0;
95   /**
96     This method must be provided by the subclass
97     to return the item in the list after \p item.
98     \see item_first(), item_next(), item_last(), item_prev()
99    */
100   virtual void *item_next(void *item) const = 0;
101   /**
102     This method must be provided by the subclass
103     to return the item in the list before \p item.
104     \see item_first(), item_next(), item_last(), item_prev()
105    */
106   virtual void *item_prev(void *item) const = 0;
107   /**
108     This method must be provided by the subclass
109     to return the last item in the list.
110     \see item_first(), item_next(), item_last(), item_prev()
111    */
item_last()112   virtual void *item_last() const { return 0L; }
113   /**
114     This method must be provided by the subclass to return
115     the height of \p item in pixels.
116     Allow for two additional pixels for the list selection box.
117     \param[in] item The item whose height is returned.
118     \returns The height of the specified \p item in pixels.
119     \see item_height(), item_width(), item_quick_height()
120   */
121   virtual int item_height(void *item) const = 0;
122   /**
123     This method must be provided by the subclass to return the width of the
124     \p item in pixels.  Allow for two additional pixels for the list
125     selection box.
126     \param[in] item The item whose width is returned.
127     \returns The width of the item in pixels.
128   */
129   virtual int item_width(void *item) const = 0;
130   virtual int item_quick_height(void *item) const ;
131   /**
132     This method must be provided by the subclass to draw the \p item
133     in the area indicated by \p X, \p Y, \p W, \p H.
134   */
135   virtual void item_draw(void *item,int X,int Y,int W,int H) const = 0;
136   /**
137     This optional method returns a string (label) that may be used for sorting.
138     \param[in] item The item whose label text is returned.
139     \returns The item's text label. (Can be NULL if blank)
140    */
item_text(void * item)141   virtual const char *item_text(void *item) const { (void)item; return 0L; }
142   /**
143     This optional method should be provided by the subclass
144     to efficiently swap browser items \p a and \p b, such as for sorting.
145     \param[in] a,b The two items to be swapped.
146    */
item_swap(void * a,void * b)147   virtual void item_swap(void *a,void *b) { (void)a; (void)b; }
148   /**
149     This method must be provided by the subclass
150     to return the item for the specified \p index.
151     \param[in] index The \p index of the item to be returned
152     \returns The item at the specified \p index.
153    */
item_at(int index)154   virtual void *item_at(int index) const { (void)index; return 0L; }
155   // you don't have to provide these but it may help speed it up:
156   // These only need to be done by subclass if you want a multi-browser:
157   virtual void item_select(void *item,int val=1);
158   virtual int item_selected(void *item) const ;
159 
160   // things the subclass may want to call:
161   /**
162     Returns the item that appears at the top of the list.
163    */
top()164   void *top() const { return top_; }
165   /**
166     Returns the item currently selected, or NULL if there is no selection.
167 
168     For multiple selection browsers this call returns the currently focused item,
169     even if it is not selected. To find all selected items, call
170     Fl_Multi_Browser::selected() for every item in question.
171   */
selection()172   void *selection() const { return selection_; }
173   void new_list(); // completely clobber all data, as though list replaced
174   void deleting(void *item); // get rid of any pointers to item
175   void replacing(void *a,void *b); // change a pointers to b
176   void swapping(void *a,void *b); // exchange pointers a and b
177   void inserting(void *a,void *b); // insert b near a
178   int displayed(void *item) const ; // true if this item is visible
179   void redraw_line(void *item); // minimal update, no change in size
180   /**
181     This method will cause the entire list to be redrawn.
182     \see redraw_lines(), redraw_line()
183    */
redraw_lines()184   void redraw_lines() { damage(FL_DAMAGE_SCROLL); } // redraw all of them
185   void bbox(int &X,int &Y,int &W,int &H) const;
186   int leftedge() const;	// x position after scrollbar & border
187   void *find_item(int ypos); // item under mouse
188 
189   void draw();
190   Fl_Browser_(int X,int Y,int W,int H,const char *L=0);
191 
192 public:
193 
194   virtual int full_width() const ;	// current width of all items
195   virtual int full_height() const ;	// current height of all items
196   virtual int incr_height() const ;	// average height of an item
197 
198   /**
199     Vertical scrollbar. Public, so that it can be accessed directly.
200    */
201   Fl_Scrollbar scrollbar;
202   /**
203     Horizontal scrollbar. Public, so that it can be accessed directly.
204    */
205   Fl_Scrollbar hscrollbar;
206 
207   int handle(int event);
208   void resize(int X,int Y,int W,int H);
209 
210   int select(void *item,int val=1,int docallbacks=0);
211   int select_only(void *item,int docallbacks=0);
212   int deselect(int docallbacks=0);
213   /**
214     Gets the vertical scroll position of the list as a pixel position \p pos.
215     The position returned is how many pixels of the list are scrolled off the top edge
216     of the screen.  Example: A position of '3' indicates the top 3 pixels of
217     the list are scrolled off the top edge of the screen.
218     \see position(), hposition()
219   */
position()220   int position() const { return position_; }
221   void position(int pos); // scroll to here
222   /**
223     Gets the horizontal scroll position of the list as a pixel position \p pos.
224     The position returned is how many pixels of the list are scrolled off the left edge
225     of the screen. Example: A position of '18' indicates the left 18 pixels of
226     the list are scrolled off the left edge of the screen.
227     \see position(), hposition()
228   */
hposition()229   int hposition() const { return hposition_; }
230   void hposition(int); // pan to here
231   void display(void *item); // scroll so this item is shown
232 
233   /**
234     Values for has_scrollbar().
235    */
236   /** Anonymous enum bit flags for has_scrollbar().
237      -  bit 0: horizontal
238      -  bit 1: vertical
239      -  bit 2: 'always' (to be combined with bits 0 and 1)
240      -  bit 3-31: reserved for future use
241    */
242   enum { // values for has_scrollbar()
243     HORIZONTAL = 1,		///< Only show horizontal scrollbar.
244     VERTICAL = 2,		///< Only show vertical scrollbar.
245     BOTH = 3,			///< Show both scrollbars. (default)
246     ALWAYS_ON = 4,		///< Specified scrollbar(s) should 'always' be shown (to be used with HORIZONTAL/VERTICAL)
247     HORIZONTAL_ALWAYS = 5,	///< Horizontal scrollbar always on.
248     VERTICAL_ALWAYS = 6,	///< Vertical scrollbar always on.
249     BOTH_ALWAYS = 7		///< Both scrollbars always on.
250   };
251   /**
252     Returns the current scrollbar mode, see Fl_Browser_::has_scrollbar(uchar)
253    */
has_scrollbar()254   uchar has_scrollbar() const { return has_scrollbar_; }
255   /**
256     Sets whether the widget should have scrollbars or not (default Fl_Browser_::BOTH).
257     By default you can scroll in both directions, and the scrollbars
258     disappear if the data will fit in the widget.
259     has_scrollbar() changes this based on the value of \p mode:
260 
261     - 0 - No scrollbars.
262 
263     - Fl_Browser_::HORIZONTAL - Only a horizontal scrollbar.
264 
265     - Fl_Browser_::VERTICAL - Only a vertical scrollbar.
266 
267     - Fl_Browser_::BOTH - The default is both scrollbars.
268 
269     - Fl_Browser_::HORIZONTAL_ALWAYS - Horizontal scrollbar always on,
270       vertical always off.
271 
272     - Fl_Browser_::VERTICAL_ALWAYS - Vertical scrollbar always on,
273       horizontal always off.
274 
275     - Fl_Browser_::BOTH_ALWAYS - Both always on.
276   */
has_scrollbar(uchar mode)277   void has_scrollbar(uchar mode) { has_scrollbar_ = mode; }
278 
279   /**
280     Gets the default text font for the lines in the browser.
281     \see textfont(), textsize(), textcolor()
282   */
textfont()283   Fl_Font textfont() const { return textfont_; }
284   /**
285     Sets the default text font for the lines in the browser to \p font.
286   */
textfont(Fl_Font font)287   void textfont(Fl_Font font) { textfont_ = font; }
288 
289   /**
290     Gets the default text size (in pixels) for the lines in the browser.
291   */
textsize()292   Fl_Fontsize textsize() const { return textsize_; }
293   /**
294     Sets the default text size (in pixels) for the lines in the browser to \p size.
295   */
textsize(Fl_Fontsize size)296   void textsize(Fl_Fontsize size) { textsize_ = size; }
297 
298   /**
299     Gets the default text color for the lines in the browser.
300   */
textcolor()301   Fl_Color textcolor() const { return textcolor_; }
302   /**
303     Sets the default text color for the lines in the browser to color \p col.
304   */
textcolor(Fl_Color col)305   void textcolor(Fl_Color col) { textcolor_ = col; }
306 
307   /**
308     Gets the current size of the scrollbars' troughs, in pixels.
309 
310     If this value is zero (default), this widget will use the
311     Fl::scrollbar_size() value as the scrollbar's width.
312 
313     \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used.
314     \see Fl::scrollbar_size(int)
315   */
scrollbar_size()316   int scrollbar_size() const {
317       return(scrollbar_size_);
318   }
319   /**
320     Sets the pixel size of the scrollbars' troughs to the \p size, in pixels.
321 
322     Normally you should not need this method, and should use
323     Fl::scrollbar_size(int) instead to manage the size of ALL
324     your widgets' scrollbars. This ensures your application
325     has a consistent UI, is the default behavior, and is normally
326     what you want.
327 
328     Only use THIS method if you really need to override the global
329     scrollbar size. The need for this should be rare.
330 
331     Setting \p size to the special value of 0 causes the widget to
332     track the global Fl::scrollbar_size(), which is the default.
333 
334     \param[in] size Sets the scrollbar size in pixels.\n
335                     If 0 (default), scrollbar size tracks the global Fl::scrollbar_size()
336     \see Fl::scrollbar_size()
337   */
scrollbar_size(int size)338   void scrollbar_size(int size) {
339       scrollbar_size_ = size;
340   }
341   /**
342     This method has been deprecated, existing for backwards compatibility only.
343     Use scrollbar_size() instead.
344     This method always returns the global value Fl::scrollbar_size().
345     \returns Always returns the global value Fl::scrollbar_size().
346     \todo This method should eventually be removed in 1.4+
347   */
scrollbar_width()348   int scrollbar_width() const {
349       return(Fl::scrollbar_size());
350   }
351   /**
352     This method has been deprecated, existing for backwards compatibility only.
353     Use scrollbar_size(int) instead.
354     This method sets the global Fl::scrollbar_size(), and forces this
355     instance of the widget to use it.
356     \todo This method should eventually be removed in 1.4+
357   */
scrollbar_width(int width)358   void scrollbar_width(int width) {
359       Fl::scrollbar_size(width);
360       scrollbar_size_ = 0;
361   }
362   /**
363     Moves the vertical scrollbar to the righthand side of the list.
364     For back compatibility.
365   */
scrollbar_right()366   void scrollbar_right() { scrollbar.align(FL_ALIGN_RIGHT); }
367   /**
368     Moves the vertical scrollbar to the lefthand side of the list.
369     For back compatibility.
370   */
scrollbar_left()371   void scrollbar_left() { scrollbar.align(FL_ALIGN_LEFT); }
372   void sort(int flags=0);
373 };
374 
375 #endif
376 
377 //
378 // End of "$Id: Fl_Browser_.H 8275 2011-01-13 22:07:31Z manolo $".
379 //
380