DRC | 2ff39b8 | 2011-07-28 08:38:59 +0000 | [diff] [blame] | 1 | // |
| 2 | // "$Id: Fl_Browser.H 8623 2011-04-24 17:09:41Z AlbrechtS $" |
| 3 | // |
| 4 | // Browser header file for the Fast Light Tool Kit (FLTK). |
| 5 | // |
| 6 | // Copyright 1998-2011 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 | // Forms-compatible browser. Probably useful for other |
| 32 | // lists of textual data. Notice that the line numbers |
| 33 | // start from 1, and 0 means "no line". |
| 34 | |
| 35 | #ifndef Fl_Browser_H |
| 36 | #define Fl_Browser_H |
| 37 | |
| 38 | #include "Fl_Browser_.H" |
| 39 | #include "Fl_Image.H" |
| 40 | |
| 41 | struct FL_BLINE; |
| 42 | |
| 43 | /** |
| 44 | The Fl_Browser widget displays a scrolling list of text |
| 45 | lines, and manages all the storage for the text. This is not a text |
| 46 | editor or spreadsheet! But it is useful for showing a vertical list of |
| 47 | named objects to the user. |
| 48 | |
| 49 | Each line in the browser is identified by number. <I>The numbers |
| 50 | start at one</I> (this is so that zero can be reserved for "no line" in |
| 51 | the selective browsers). <I>Unless otherwise noted, the methods do not |
| 52 | check to see if the passed line number is in range and legal. It must |
| 53 | always be greater than zero and <= size().</I> |
| 54 | |
| 55 | Each line contains a null-terminated string of text and a void * |
| 56 | data pointer. The text string is displayed, the void * |
| 57 | pointer can be used by the callbacks to reference the object the text |
| 58 | describes. |
| 59 | |
| 60 | The base class does nothing when the user clicks on it. The |
| 61 | subclasses |
| 62 | Fl_Select_Browser, |
| 63 | Fl_Hold_Browser, and |
| 64 | Fl_Multi_Browser react to user clicks to select lines in |
| 65 | the browser and do callbacks. |
| 66 | |
| 67 | The base class |
| 68 | Fl_Browser_ provides the scrolling and selection mechanisms of |
| 69 | this and all the subclasses, but the dimensions and appearance of each |
| 70 | item are determined by the subclass. You can use Fl_Browser_ |
| 71 | to display information other than text, or text that is dynamically |
| 72 | produced from your own data structures. If you find that loading the |
| 73 | browser is a lot of work or is inefficient, you may want to make a |
| 74 | subclass of Fl_Browser_. |
| 75 | |
| 76 | Some common coding patterns used for working with Fl_Browser: |
| 77 | \code |
| 78 | // How to loop through all the items in the browser |
| 79 | for ( int t=1; t<=browser->size(); t++ ) { // index 1 based..! |
| 80 | printf("item #%d, label='%s'\n", t, browser->text(t)); |
| 81 | } |
| 82 | \endcode |
| 83 | |
| 84 | Note: If you are <I>subclassing</I> Fl_Browser, it's more efficient |
| 85 | to use the protected methods item_first() and item_next(), since |
| 86 | Fl_Browser internally uses linked lists to manage the browser's items. |
| 87 | For more info, see find_item(int). |
| 88 | */ |
| 89 | class FL_EXPORT Fl_Browser : public Fl_Browser_ { |
| 90 | |
| 91 | FL_BLINE *first; // the array of lines |
| 92 | FL_BLINE *last; |
| 93 | FL_BLINE *cache; |
| 94 | int cacheline; // line number of cache |
| 95 | int lines; // Number of lines |
| 96 | int full_height_; |
| 97 | const int* column_widths_; |
| 98 | char format_char_; // alternative to @-sign |
| 99 | char column_char_; // alternative to tab |
| 100 | |
| 101 | protected: |
| 102 | |
| 103 | // required routines for Fl_Browser_ subclass: |
| 104 | void* item_first() const ; |
| 105 | void* item_next(void* item) const ; |
| 106 | void* item_prev(void* item) const ; |
| 107 | void* item_last()const ; |
| 108 | int item_selected(void* item) const ; |
| 109 | void item_select(void* item, int val); |
| 110 | int item_height(void* item) const ; |
| 111 | int item_width(void* item) const ; |
| 112 | void item_draw(void* item, int X, int Y, int W, int H) const ; |
| 113 | int full_height() const ; |
| 114 | int incr_height() const ; |
| 115 | const char *item_text(void *item) const; |
| 116 | /** Swap the items \p a and \p b. |
| 117 | You must call redraw() to make any changes visible. |
| 118 | \param[in] a,b the items to be swapped. |
| 119 | \see swap(int,int), item_swap() |
| 120 | */ |
| 121 | void item_swap(void *a, void *b) { swap((FL_BLINE*)a, (FL_BLINE*)b); } |
| 122 | /** Return the item at specified \p line. |
| 123 | \param[in] line The line of the item to return. (1 based) |
| 124 | \returns The item, or NULL if line out of range. |
| 125 | \see item_at(), find_line(), lineno() |
| 126 | */ |
| 127 | void *item_at(int line) const { return (void*)find_line(line); } |
| 128 | |
| 129 | FL_BLINE* find_line(int line) const ; |
| 130 | FL_BLINE* _remove(int line) ; |
| 131 | void insert(int line, FL_BLINE* item); |
| 132 | int lineno(void *item) const ; |
| 133 | void swap(FL_BLINE *a, FL_BLINE *b); |
| 134 | |
| 135 | public: |
| 136 | |
| 137 | void remove(int line); |
| 138 | void add(const char* newtext, void* d = 0); |
| 139 | void insert(int line, const char* newtext, void* d = 0); |
| 140 | void move(int to, int from); |
| 141 | int load(const char* filename); |
| 142 | void swap(int a, int b); |
| 143 | void clear(); |
| 144 | |
| 145 | /** |
| 146 | Returns how many lines are in the browser. |
| 147 | The last line number is equal to this. |
| 148 | Returns 0 if browser is empty. |
| 149 | */ |
| 150 | int size() const { return lines; } |
| 151 | void size(int W, int H) { Fl_Widget::size(W, H); } |
| 152 | |
| 153 | int topline() const ; |
| 154 | /** For internal use only? */ |
| 155 | enum Fl_Line_Position { TOP, BOTTOM, MIDDLE }; |
| 156 | void lineposition(int line, Fl_Line_Position pos); |
| 157 | /** |
| 158 | Scrolls the browser so the top item in the browser |
| 159 | is showing the specified \p line. |
| 160 | \param[in] line The line to be displayed at the top. |
| 161 | \see topline(), middleline(), bottomline(), displayed(), lineposition() |
| 162 | */ |
| 163 | void topline(int line) { lineposition(line, TOP); } |
| 164 | /** |
| 165 | Scrolls the browser so the bottom item in the browser |
| 166 | is showing the specified \p line. |
| 167 | \param[in] line The line to be displayed at the bottom. |
| 168 | \see topline(), middleline(), bottomline(), displayed(), lineposition() |
| 169 | */ |
| 170 | void bottomline(int line) { lineposition(line, BOTTOM); } |
| 171 | /** |
| 172 | Scrolls the browser so the middle item in the browser |
| 173 | is showing the specified \p line. |
| 174 | \param[in] line The line to be displayed in the middle. |
| 175 | \see topline(), middleline(), bottomline(), displayed(), lineposition() |
| 176 | */ |
| 177 | void middleline(int line) { lineposition(line, MIDDLE); } |
| 178 | |
| 179 | int select(int line, int val=1); |
| 180 | int selected(int line) const ; |
| 181 | void show(int line); |
| 182 | /** Shows the entire Fl_Browser widget -- opposite of hide(). */ |
| 183 | void show() { Fl_Widget::show(); } |
| 184 | void hide(int line); |
| 185 | /** Hides the entire Fl_Browser widget -- opposite of show(). */ |
| 186 | void hide() { Fl_Widget::hide(); } |
| 187 | int visible(int line) const ; |
| 188 | |
| 189 | int value() const ; |
| 190 | /** |
| 191 | Sets the browser's value(), which selects the specified \p line. |
| 192 | This is the same as calling select(line). |
| 193 | \see select(), selected(), value(), item_select(), item_selected() |
| 194 | */ |
| 195 | void value(int line) { select(line); } |
| 196 | const char* text(int line) const ; |
| 197 | void text(int line, const char* newtext); |
| 198 | void* data(int line) const ; |
| 199 | void data(int line, void* d); |
| 200 | |
| 201 | Fl_Browser(int X, int Y, int W, int H, const char *L = 0); |
| 202 | /** |
| 203 | The destructor deletes all list items and destroys the browser. |
| 204 | */ |
| 205 | ~Fl_Browser() { clear(); } |
| 206 | |
| 207 | /** |
| 208 | Gets the current format code prefix character, which by default is '\@'. |
| 209 | A string of formatting codes at the start of each column are stripped off |
| 210 | and used to modify how the rest of the line is printed: |
| 211 | |
| 212 | \li <tt>'\@.'</tt> Print rest of line, don't look for more '\@' signs |
| 213 | \li <tt>'\@\@'</tt> Print rest of line starting with '\@' |
| 214 | \li <tt>'\@l'</tt> Use a LARGE (24 point) font |
| 215 | \li <tt>'\@m'</tt> Use a medium large (18 point) font |
| 216 | \li <tt>'\@s'</tt> Use a <SMALL>small</SMALL> (11 point) font |
| 217 | \li <tt>'\@b'</tt> Use a <B>bold</B> font (adds FL_BOLD to font) |
| 218 | \li <tt>'\@i'</tt> Use an <I>italic</I> font (adds FL_ITALIC to font) |
| 219 | \li <tt>'\@f' or '\@t'</tt> Use a fixed-pitch |
| 220 | font (sets font to FL_COURIER) |
| 221 | \li <tt>'\@c'</tt> Center the line horizontally |
| 222 | \li <tt>'\@r'</tt> Right-justify the text |
| 223 | \li <tt>'\@B0', '\@B1', ... '\@B255'</tt> Fill the backgound with |
| 224 | fl_color(n) |
| 225 | \li <tt>'\@C0', '\@C1', ... '\@C255'</tt> Use fl_color(n) to draw the text |
| 226 | \li <tt>'\@F0', '\@F1', ...</tt> Use fl_font(n) to draw the text |
| 227 | \li <tt>'\@S1', '\@S2', ...</tt> Use point size n to draw the text |
| 228 | \li <tt>'\@u' or '\@_'</tt> Underline the text. |
| 229 | \li <tt>'\@-'</tt> draw an engraved line through the middle. |
| 230 | |
| 231 | Notice that the '\@.' command can be used to reliably |
| 232 | terminate the parsing. To print a random string in a random color, use |
| 233 | <tt>sprintf("@C%d@.%s", color, string)</tt> and it will work even if the |
| 234 | string starts with a digit or has the format character in it. |
| 235 | */ |
| 236 | char format_char() const { return format_char_; } |
| 237 | /** |
| 238 | Sets the current format code prefix character to \p c. |
| 239 | The default prefix is '\@'. Set the prefix to 0 to disable formatting. |
| 240 | \see format_char() for list of '\@' codes |
| 241 | */ |
| 242 | void format_char(char c) { format_char_ = c; } |
| 243 | /** |
| 244 | Gets the current column separator character. |
| 245 | The default is '\\t' (tab). |
| 246 | \see column_char(), column_widths() |
| 247 | */ |
| 248 | char column_char() const { return column_char_; } |
| 249 | /** |
| 250 | Sets the column separator to c. |
| 251 | This will only have an effect if you also set column_widths(). |
| 252 | The default is '\\t' (tab). |
| 253 | \see column_char(), column_widths() |
| 254 | */ |
| 255 | void column_char(char c) { column_char_ = c; } |
| 256 | /** |
| 257 | Gets the current column width array. |
| 258 | This array is zero-terminated and specifies the widths in pixels of |
| 259 | each column. The text is split at each column_char() and each part is |
| 260 | formatted into it's own column. After the last column any remaining |
| 261 | text is formatted into the space between the last column and the |
| 262 | right edge of the browser, even if the text contains instances of |
| 263 | column_char() . The default value is a one-element array of just |
| 264 | a zero, which means there are no columns. |
| 265 | |
| 266 | Example: |
| 267 | \code |
| 268 | Fl_Browser *b = new Fl_Browser(..); |
| 269 | int widths[] = { 50, 50, 50, 70, 70, 40, 40, 70, 70, 50, 0 }; // widths for each column |
| 270 | b->column_widths(widths); // assign array to widget |
| 271 | b->column_char('\t'); // use tab as the column character |
| 272 | b->add("USER\tPID\tCPU\tMEM\tVSZ\tRSS\tTTY\tSTAT\tSTART\tTIME\tCOMMAND"); |
| 273 | b->add("root\t2888\t0.0\t0.0\t1352\t0\ttty3\tSW\tAug15\t0:00\t@b@f/sbin/mingetty tty3"); |
| 274 | b->add("root\t13115\t0.0\t0.0\t1352\t0\ttty2\tSW\tAug30\t0:00\t@b@f/sbin/mingetty tty2"); |
| 275 | [..] |
| 276 | \endcode |
| 277 | \see column_char(), column_widths() |
| 278 | */ |
| 279 | const int* column_widths() const { return column_widths_; } |
| 280 | /** |
| 281 | Sets the current array to \p arr. Make sure the last entry is zero. |
| 282 | \see column_char(), column_widths() |
| 283 | */ |
| 284 | void column_widths(const int* arr) { column_widths_ = arr; } |
| 285 | |
| 286 | /** |
| 287 | Returns non-zero if \p line has been scrolled to a position where it is being displayed. |
| 288 | Checks to see if the item's vertical position is within the top and bottom |
| 289 | edges of the display window. This does NOT take into account the hide()/show() |
| 290 | status of the widget or item. |
| 291 | \param[in] line The line to be checked |
| 292 | \returns 1 if visible, 0 if not visible. |
| 293 | \see topline(), middleline(), bottomline(), displayed(), lineposition() |
| 294 | */ |
| 295 | int displayed(int line) const { return Fl_Browser_::displayed(find_line(line)); } |
| 296 | |
| 297 | /** |
| 298 | Make the item at the specified \p line visible(). |
| 299 | Functionally similar to show(int line). |
| 300 | If \p line is out of range, redisplay top or bottom of list as appropriate. |
| 301 | \param[in] line The line to be made visible. |
| 302 | \see show(int), hide(int), display(), visible(), make_visible() |
| 303 | */ |
| 304 | void make_visible(int line) { |
| 305 | if (line < 1) Fl_Browser_::display(find_line(1)); |
| 306 | else if (line > lines) Fl_Browser_::display(find_line(lines)); |
| 307 | else Fl_Browser_::display(find_line(line)); |
| 308 | } |
| 309 | |
| 310 | // icon support |
| 311 | void icon(int line, Fl_Image* icon); |
| 312 | Fl_Image* icon(int line) const; |
| 313 | void remove_icon(int line); |
| 314 | |
| 315 | /** For back compatibility only. */ |
| 316 | void replace(int a, const char* b) { text(a, b); } |
| 317 | void display(int line, int val=1); |
| 318 | }; |
| 319 | |
| 320 | #endif |
| 321 | |
| 322 | // |
| 323 | // End of "$Id: Fl_Browser.H 8623 2011-04-24 17:09:41Z AlbrechtS $". |
| 324 | // |