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