summaryrefslogtreecommitdiff
path: root/src/Fl_Browser.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Fl_Browser.cxx')
-rw-r--r--src/Fl_Browser.cxx337
1 files changed, 246 insertions, 91 deletions
diff --git a/src/Fl_Browser.cxx b/src/Fl_Browser.cxx
index 59bf61912..dbc4afd9b 100644
--- a/src/Fl_Browser.cxx
+++ b/src/Fl_Browser.cxx
@@ -53,28 +53,88 @@ struct FL_BLINE { // data is in a linked list of these
char txt[1]; // start of allocated array
};
+/**
+ Returns the very first item in the list.
+ Example of use:
+ \code
+ // Walk the browser from beginning to end
+ for ( void *i=item_first(); i; i=item_next(i) ) {
+ printf("item label='%s'\n", item_text(i));
+ }
+ \endcode
+ \returns The first item, or NULL if list is empty.
+*/
void* Fl_Browser::item_first() const {return first;}
-void* Fl_Browser::item_next(void* l) const {return ((FL_BLINE*)l)->next;}
+/**
+ Returns the next item after \p item.
+ \param[in] item The 'current' item
+ \returns The next item after \p item, or NULL if there are none after this one.
+ \see item_first()
+*/
+void* Fl_Browser::item_next(void* item) const {return ((FL_BLINE*)item)->next;}
-void* Fl_Browser::item_prev(void* l) const {return ((FL_BLINE*)l)->prev;}
+/**
+ Returns the previous item before \p item.
+ \param[in] item The 'current' item
+ \returns The previous item before \p item, or NULL if there none before this one.
+ \see item_last()
+*/
+void* Fl_Browser::item_prev(void* item) const {return ((FL_BLINE*)item)->prev;}
+/**
+ Returns the very last item in the list.
+ Example of use:
+ \code
+ // Walk the browser in reverse, from end to start
+ for ( void *i=item_last(); i; i=item_prev(i) ) {
+ printf("item label='%s'\n", item_text(i));
+ }
+ \endcode
+ \returns The last item, or NULL if list is empty.
+*/
void* Fl_Browser::item_last() const {return last;}
-int Fl_Browser::item_selected(void* l) const {
- return ((FL_BLINE*)l)->flags&SELECTED;}
-
-void Fl_Browser::item_select(void* l, int v) {
- if (v) ((FL_BLINE*)l)->flags |= SELECTED;
- else ((FL_BLINE*)l)->flags &= ~SELECTED;
+/**
+ See if \p item is selected.
+ \param[in] item The item whose selection state is to be checked.
+ \returns 1 if selected, 0 if not.
+*/
+int Fl_Browser::item_selected(void* item) const {
+ return ((FL_BLINE*)item)->flags&SELECTED;
+}
+/**
+ Change the selection state of \p item to the value \p val.
+ \param[in] item The item to be changed.
+ \param[in] v The new selection state: 1 selects, 0 de-selects.
+*/
+void Fl_Browser::item_select(void *item, int val) {
+ if (val) ((FL_BLINE*)item)->flags |= SELECTED;
+ else ((FL_BLINE*)item)->flags &= ~SELECTED;
}
+/**
+ Returns the label text for \p item.
+ \param[in] item The item whose label text is returned.
+ \returns The item's text string. (Can be NULL)
+*/
const char *Fl_Browser::item_text(void *item) const {
return ((FL_BLINE*)item)->txt;
}
/**
- Return entry for line number \a line.
+ Returns the item for specified \p line.
+
+ Note: This call is slow. It's fine for e.g. responding to user
+ clicks, but slow if called often, such as in a tight sorting loop.
+ Finding an item 'by line' involves a linear lookup on the internal
+ linked list. The performance hit can be significant if the browser's
+ contents is large, and the method is called often (e.g. during a sort).
+ If you're writing a subclass, use the protected methods item_first(),
+ item_next(), etc. to access the internal linked list more efficiently.
+
+ \param[in] line The line number of the item to return. (1 based)
+ \returns The returned item.
*/
FL_BLINE* Fl_Browser::find_line(int line) const {
int n; FL_BLINE* l;
@@ -94,11 +154,13 @@ FL_BLINE* Fl_Browser::find_line(int line) const {
}
/**
- Returns line number corresponding to data \a v,
- zero if not found.
+ Returns line number corresponding to \p item, or zero if not found.
+ Caveat: See efficiency note in find_line().
+ \param[in] item The item to be found
+ \returns The line number of the item, or 0 if not found.
*/
-int Fl_Browser::lineno(void* v) const {
- FL_BLINE* l = (FL_BLINE*)v;
+int Fl_Browser::lineno(void *item) const {
+ FL_BLINE* l = (FL_BLINE*)item;
if (!l) return 0;
if (l == cache) return cacheline;
if (l == first) return 1;
@@ -107,7 +169,7 @@ int Fl_Browser::lineno(void* v) const {
((Fl_Browser*)this)->cache = first;
((Fl_Browser*)this)->cacheline = 1;
}
- // assumme it is near cache, search both directions:
+ // assume it is near cache, search both directions:
FL_BLINE* b = cache->prev;
int bnum = cacheline-1;
FL_BLINE* f = cache->next;
@@ -125,9 +187,11 @@ int Fl_Browser::lineno(void* v) const {
}
/**
- Remove entry for given line number.
- \param[in] line line number. Must be in range!
- \returns pointer to browser entry.
+ Removes the item at the specified \p line.
+ Caveat: See efficiency note in find_line().
+ You must call redraw() to make any changes visible.
+ \param[in] line The line number to be removed. (1 based) Must be in range!
+ \returns Pointer to browser item that was removed (and is no longer valid).
*/
FL_BLINE* Fl_Browser::_remove(int line) {
FL_BLINE* ttt = find_line(line);
@@ -146,7 +210,10 @@ FL_BLINE* Fl_Browser::_remove(int line) {
}
/**
- Remove line \a line and make the browser one line shorter.
+ Remove entry for given \p line number, making the browser one line shorter.
+ You must call redraw() to make any changes visible.
+ \param[in] line Line to be removed. (1 based) \n
+ If \p line is out of range, no action is taken.
*/
void Fl_Browser::remove(int line) {
if (line < 1 || line > lines) return;
@@ -154,44 +221,56 @@ void Fl_Browser::remove(int line) {
}
/**
- Insert a new line \a t \e before line \a n.
- If \a n > size() then the line is added to the end.
+ Insert specified \p item above \p line.
+ If \p line > size() then the line is added to the end.
+
+ Caveat: See efficiency note in find_line().
+
+ \param[in] line The new line will be inserted above this line (1 based).
+ \param[in] item The the item to be added.
*/
-void Fl_Browser::insert(int line, FL_BLINE* t) {
+void Fl_Browser::insert(int line, FL_BLINE* item) {
if (!first) {
- t->prev = t->next = 0;
- first = last = t;
+ item->prev = item->next = 0;
+ first = last = item;
} else if (line <= 1) {
- inserting(first, t);
- t->prev = 0;
- t->next = first;
- t->next->prev = t;
- first = t;
+ inserting(first, item);
+ item->prev = 0;
+ item->next = first;
+ item->next->prev = item;
+ first = item;
} else if (line > lines) {
- t->prev = last;
- t->prev->next = t;
- t->next = 0;
- last = t;
+ item->prev = last;
+ item->prev->next = item;
+ item->next = 0;
+ last = item;
} else {
FL_BLINE* n = find_line(line);
- inserting(n, t);
- t->next = n;
- t->prev = n->prev;
- t->prev->next = t;
- n->prev = t;
+ inserting(n, item);
+ item->next = n;
+ item->prev = n->prev;
+ item->prev->next = item;
+ n->prev = item;
}
cacheline = line;
- cache = t;
+ cache = item;
lines++;
- full_height_ += item_height(t);
- redraw_line(t);
+ full_height_ += item_height(item);
+ redraw_line(item);
}
/**
- Insert a new entry \e before given line.
- \param[in] line if \a line > size(), the entry will be added at the end.
- \param[in] newtext text entry for the new line.
- \param[in] d pointer to data associated with the new line.
+ Insert a new entry whose label is \p newtext \e above given \p line, optional data \p d.
+
+ Text may contain format characters; see format_char() for details.
+ \p newtext is copied using the strdup() function, and can be NULL to make a blank line.
+
+ The optional void * argument \p d will be the data() of the new item.
+
+ \param[in] line Line position for insert. (1 based) \n
+ If \p line > size(), the entry will be added at the end.
+ \param[in] newtext The label text for the new line.
+ \param[in] d Optional pointer to user data to be associated with the new line.
*/
void Fl_Browser::insert(int line, const char* newtext, void* d) {
int l = strlen(newtext);
@@ -204,8 +283,10 @@ void Fl_Browser::insert(int line, const char* newtext, void* d) {
}
/**
- Line \a from is removed and reinserted at \a to; \a to
- is calculated after the line is removed.
+ Line \p from is removed and reinserted at \p to.
+ Note: \p to is calculated \e after line \p from gets removed.
+ \param[in] to Destination line number (calculated \e after line \p from is removed)
+ \param[in] from Line number of item to be moved
*/
void Fl_Browser::move(int to, int from) {
if (from < 1 || from > lines) return;
@@ -213,8 +294,15 @@ void Fl_Browser::move(int to, int from) {
}
/**
- Sets the text for line \a line to text \a newtext.
- Does nothing if \a line is out of range.
+ Sets the text for the specified \p line to \p newtext.
+
+ Text may contain format characters; see format_char() for details.
+ \p newtext is copied using the strdup() function, and can be NULL to make a blank line.
+
+ Does nothing if \p line is out of range.
+
+ \param[in] line The line of the item whose text will be changed. (1 based)
+ \param[in] newtext The new string to be assigned to the item.
*/
void Fl_Browser::text(int line, const char* newtext) {
if (line < 1 || line > lines) return;
@@ -239,8 +327,10 @@ void Fl_Browser::text(int line, const char* newtext) {
}
/**
- Sets the data for line \a line to \a d.
- Does nothing if \a line is out of range.
+ Sets the user data for specified \p line to \p d.
+ Does nothing if \p line is out of range.
+ \param[in] line The line of the item whose data() is to be changed. (1 based)
+ \param[in] d The new data to be assigned to the item. (can be NULL)
*/
void Fl_Browser::data(int line, void* d) {
if (line < 1 || line > lines) return;
@@ -248,10 +338,13 @@ void Fl_Browser::data(int line, void* d) {
}
/**
- Returns height of line \p lv.
+ Returns height of \p item in pixels.
+ This takes into account embedded \@ codes within the text() label.
+ \param[in] item The item whose height is returned.
+ \returns The height of the item in pixels.
*/
-int Fl_Browser::item_height(void* lv) const {
- FL_BLINE* l = (FL_BLINE*)lv;
+int Fl_Browser::item_height(void *item) const {
+ FL_BLINE* l = (FL_BLINE*)item;
if (l->flags & NOTDISPLAYED) return 0;
int hmax = 2; // use 2 to insure we don't return a zero!
@@ -300,8 +393,14 @@ int Fl_Browser::item_height(void* lv) const {
return hmax; // previous version returned hmax+2!
}
-int Fl_Browser::item_width(void* v) const {
- char* str = ((FL_BLINE*)v)->txt;
+/**
+ Returns width of \p item in pixels.
+ This takes into account embedded \@ codes within the text() label.
+ \param[in] item The item whose width is returned.
+ \returns The width of the item in pixels.
+*/
+int Fl_Browser::item_width(void *item) const {
+ char* str = ((FL_BLINE*)item)->txt;
const int* i = column_widths();
int ww = 0;
@@ -350,16 +449,34 @@ int Fl_Browser::item_width(void* v) const {
return ww + int(fl_width(str)) + 6;
}
+/**
+ The height of the entire list of all visible() items in pixels.
+ This returns the accumulated height of *all* the items in the browser
+ that are not hidden with hide(), including items scrolled offscreen.
+ \returns The accumulated size of all the visible items in pixels.
+*/
int Fl_Browser::full_height() const {
return full_height_;
}
+/**
+ The default height of items (including spacing in-between) in pixels.
+ This currently returns textsize() + 2.
+ \returns The value in pixels.
+*/
int Fl_Browser::incr_height() const {
return textsize()+2;
}
-void Fl_Browser::item_draw(void* v, int X, int Y, int W, int H) const {
- char* str = ((FL_BLINE*)v)->txt;
+/**
+ Draws \p item at the position specified by \p X \p Y \p W \p H.
+ The \p W and \p H values are used for clipping.
+ Should only be called within the context of an FLTK draw().
+ \param[in] item The item to be drawn
+ \param[in] X,Y,W,H position and size.
+*/
+void Fl_Browser::item_draw(void* item, int X, int Y, int W, int H) const {
+ char* str = ((FL_BLINE*)item)->txt;
const int* i = column_widths();
while (W > 6) { // do each tab-separated field
@@ -388,7 +505,7 @@ void Fl_Browser::item_draw(void* v, int X, int Y, int W, int H) const {
case 'c': talign = FL_ALIGN_CENTER; break;
case 'r': talign = FL_ALIGN_RIGHT; break;
case 'B':
- if (!(((FL_BLINE*)v)->flags & SELECTED)) {
+ if (!(((FL_BLINE*)item)->flags & SELECTED)) {
fl_color((Fl_Color)strtol(str, &str, 10));
fl_rectf(X, Y, w1, H);
} else strtol(str, &str, 10);
@@ -424,7 +541,7 @@ void Fl_Browser::item_draw(void* v, int X, int Y, int W, int H) const {
}
BREAK:
fl_font(font, tsize);
- if (((FL_BLINE*)v)->flags & SELECTED)
+ if (((FL_BLINE*)item)->flags & SELECTED)
lcol = fl_contrast(lcol, selection_color());
if (!active_r()) lcol = fl_inactive(lcol);
fl_color(lcol);
@@ -456,8 +573,8 @@ Fl_Browser::Fl_Browser(int X, int Y, int W, int H, const char *L)
}
/**
- Updates the browser so that \a line is shown at position \a pos.
- \param[in] line line number.
+ Updates the browser so that \p line is shown at position \p pos.
+ \param[in] line line number. (1 based)
\param[in] pos position.
*/
void Fl_Browser::lineposition(int line, Fl_Line_Position pos) {
@@ -485,8 +602,9 @@ void Fl_Browser::lineposition(int line, Fl_Line_Position pos) {
}
/**
- Returns the current top line in the browser. If there
- is no vertical scrollbar then this will always return 1.
+ Returns the line that is currently visible at the top of the browser.
+ If there is no vertical scrollbar then this will always return 1.
+ \returns The lineno() of the top() of the browser.
*/
int Fl_Browser::topline() const {
return lineno(top());
@@ -509,10 +627,15 @@ void Fl_Browser::clear() {
}
/**
- Adds a new line to the end of the browser. The text is copied using
- the strdup() function. It may also be NULL to make a
- blank line. The void * argument \a d is returned as the data()
- of the new item.
+ Adds a new line to the end of the browser.
+
+ The text string newtext may contain format characters; see format_char() for details.
+ \p newtext is copied using the strdup() function, and can be NULL to make a blank line.
+
+ The optional void * argument \p d will be the data() for the new item.
+
+ \param[in] newtext The label text used for the added item
+ \param[in] d Optional user data() for the item (0 if unspecified)
*/
void Fl_Browser::add(const char* newtext, void* d) {
insert(lines+1, newtext, d);
@@ -520,7 +643,11 @@ void Fl_Browser::add(const char* newtext, void* d) {
}
/**
- Returns data entry for line \p line, or NULL if out of range.
+ Returns the label text for the specified \p line.
+ Return value can be NULL if \p line is out of range or unset.
+ The parameter \p line is 1 based.
+ \param[in] line The line number of the item whose text is returned. (1 based)
+ \returns The text string (can be NULL)
*/
const char* Fl_Browser::text(int line) const {
if (line < 1 || line > lines) return 0;
@@ -528,7 +655,12 @@ const char* Fl_Browser::text(int line) const {
}
/**
- Returns the data for line \p line, or NULL if \p line is out of range.
+ Returns the user data() for specified \p line.
+ Return value can be NULL if \p line is out of range or no user data() was defined.
+ The parameter \p line is 1 based (1 will be the first item in the list).
+ \param[in] line The line number of the item whose data() is returned. (1 based)
+ \returns The user data pointer (can be NULL)
+
*/
void* Fl_Browser::data(int line) const {
if (line < 1 || line > lines) return 0;
@@ -536,23 +668,34 @@ void* Fl_Browser::data(int line) const {
}
/**
- Sets the selection state of entry \a line.
- \param[in] line line number.
- \param[in] v new selection state.
+ Sets the selection state of the item at \p line to the value \p val.
+ If \p val is not specified, the default is 1 (selects the item).
+ \param[in] line The line number of the item to be changed. (1 based)
+ \param[in] val The new selection state (1=select, 0=de-select).
\returns 1 if the state changed, 0 if not.
*/
-int Fl_Browser::select(int line, int v) {
+int Fl_Browser::select(int line, int val) {
if (line < 1 || line > lines) return 0;
- return Fl_Browser_::select(find_line(line), v);
+ return Fl_Browser_::select(find_line(line), val);
}
-/** Returns 1 if line \a line is selected, 0 if it is not selected.*/
+/**
+ Returns 1 if specified \p line is selected, 0 if not.
+ \param[in] line The line being checked (1 based)
+ \returns 1 if item selected, 0 if not.
+ */
int Fl_Browser::selected(int line) const {
if (line < 1 || line > lines) return 0;
return find_line(line)->flags & SELECTED;
}
-/** Makes line \a line visible for selection. */
+/**
+ Makes \p line visible, and available for selection by user.
+ Opposite of hide(int).
+ This changes the full_height() if the state was changed.
+ redraw() is called automatically if a change occurred.
+ \param[in] line The line to be shown. (1 based)
+*/
void Fl_Browser::show(int line) {
FL_BLINE* t = find_line(line);
if (t->flags & NOTDISPLAYED) {
@@ -563,8 +706,12 @@ void Fl_Browser::show(int line) {
}
/**
- Makes line \a line invisible, preventing selection by the user.
+ Makes \p line invisible, preventing selection by the user.
The line can still be selected under program control.
+ This changes the full_height() if the state was changed.
+ When a line is made invisible, lines below it are moved up in the display.
+ redraw() is called automatically if a change occurred.
+ \param[in] line The line to be hidden. (1 based)
*/
void Fl_Browser::hide(int line) {
FL_BLINE* t = find_line(line);
@@ -577,17 +724,19 @@ void Fl_Browser::hide(int line) {
/**
For back compatibility.
-
- This calls show(line) if \a v is true, and hide(line) otherwise.
+ This calls show(line) if \p val is true, and hide(line) otherwise.
+ If \p val is not specified, the default is 1 (makes the line visible).
\see show(int line), hide(int line)
*/
-void Fl_Browser::display(int line, int v) {
+void Fl_Browser::display(int line, int val) {
if (line < 1 || line > lines) return;
- if (v) show(line); else hide(line);
+ if (val) show(line); else hide(line);
}
/**
- Returns a non-zero value if line \a line is visible.
+ Returns non-zero if the specified \p line is visible, 0 if hidden.
+ Use show(int), hide(int), or make_visible(int) to change an item's visible state.
+ \param[in] line The line in the browser to be tested. (1 based)
*/
int Fl_Browser::visible(int line) const {
if (line < 1 || line > lines) return 0;
@@ -595,15 +744,17 @@ int Fl_Browser::visible(int line) const {
}
/**
- Gets the browser's value.
- \returns line number of current selection, or 0 if no selection.
+ Returns the line number of the currently selected line, or 0 if none.
+ \returns The line number of current selection, or 0 if none selected.
*/
int Fl_Browser::value() const {
return lineno(selection());
}
/**
- Swap two lines, \p a and \p b
+ Swap the two items \p a and \p b.
+ You must call redraw() to make any changes visible.
+ \param[in] a,b The two items to be swapped.
*/
void Fl_Browser::swap(FL_BLINE *a, FL_BLINE *b) {
@@ -644,12 +795,16 @@ void Fl_Browser::swap(FL_BLINE *a, FL_BLINE *b) {
cache = 0;
}
-/** Swaps two lines in the browser.*/
-void Fl_Browser::swap(int ai, int bi) {
- if (ai < 1 || ai > lines || bi < 1 || bi > lines) return;
- FL_BLINE* a = find_line(ai);
- FL_BLINE* b = find_line(bi);
- swap(a,b);
+/**
+ Swaps two browser lines \p a and \p b.
+ You must call redraw() to make any changes visible.
+ \param[in] a,b The two lines to be swapped. (both 1 based)
+*/
+void Fl_Browser::swap(int a, int b) {
+ if (a < 1 || a > lines || b < 1 || b > lines) return;
+ FL_BLINE* ai = find_line(a);
+ FL_BLINE* bi = find_line(b);
+ swap(ai,bi);
}
//