diff options
| author | Greg Ercolano <erco@seriss.com> | 2009-09-07 02:25:51 +0000 |
|---|---|---|
| committer | Greg Ercolano <erco@seriss.com> | 2009-09-07 02:25:51 +0000 |
| commit | 89870d011408f52119431bd110789af17854581b (patch) | |
| tree | f0865ef192970eb5c190b2652218b1588cd42996 /src | |
| parent | 184c1092e9851bdb4d2f2dd1227397f05eb58e17 (diff) | |
Solves STR#1739.
This allows icons to be defined for items in Fl_Browser.
In addition to the OP's patch:
o Added doxygen docs
o Fixed redraw handling of icons larger than the items
o Some methods made const
o Conformed indent to FLTK standards
See the STR for a test program that verifies the modifications.
Mods tested on linux,osx,windows.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6850 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl_Browser.cxx | 86 |
1 files changed, 82 insertions, 4 deletions
diff --git a/src/Fl_Browser.cxx b/src/Fl_Browser.cxx index 454db71e9..1933f1d1c 100644 --- a/src/Fl_Browser.cxx +++ b/src/Fl_Browser.cxx @@ -48,6 +48,7 @@ struct FL_BLINE { // data is in a linked list of these FL_BLINE* prev; FL_BLINE* next; void* data; + Fl_Image* icon; short length; // sizeof(txt)-1, may be longer than string char flags; // selected, displayed char txt[1]; // start of allocated array @@ -287,6 +288,7 @@ void Fl_Browser::insert(int line, const char* newtext, void* d) { t->flags = 0; strcpy(t->txt, newtext); t->data = d; + t->icon = 0; insert(line, t); } @@ -321,6 +323,7 @@ void Fl_Browser::text(int line, const char* newtext) { replacing(t, n); cache = n; n->data = t->data; + n->icon = t->icon; n->length = (short)l; n->flags = t->flags; n->prev = t->prev; @@ -400,6 +403,9 @@ int Fl_Browser::item_height(void *item) const { } } + if (l->icon && (l->icon->h()+2)>hmax) { + hmax = l->icon->h() + 2; // leave 2px above/below + } return hmax; // previous version returned hmax+2! } @@ -412,7 +418,8 @@ int Fl_Browser::item_height(void *item) const { incr_height(), full_height() */ int Fl_Browser::item_width(void *item) const { - char* str = ((FL_BLINE*)item)->txt; + FL_BLINE* l=(FL_BLINE*)item; + char* str = l->txt; const int* i = column_widths(); int ww = 0; @@ -457,6 +464,8 @@ int Fl_Browser::item_width(void *item) const { if (*str == format_char_ && str[1]) str ++; + if (ww==0 && l->icon) ww = l->icon->w(); + fl_font(font, tsize); return ww + int(fl_width(str)) + 6; } @@ -492,9 +501,11 @@ int Fl_Browser::incr_height() const { \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; + FL_BLINE* l = (FL_BLINE*)item; + char* str = l->txt; const int* i = column_widths(); + bool first = true; // for icon while (W > 6) { // do each tab-separated field int w1 = W; // width for this field char* e = 0; // pointer to end of field or null if none @@ -502,6 +513,15 @@ void Fl_Browser::item_draw(void* item, int X, int Y, int W, int H) const { e = strchr(str, column_char()); if (e) {*e = 0; w1 = *i++;} } + // Icon drawing code + if (first) { + first = false; + if (l->icon) { + l->icon->draw(X+2,Y+1); // leave 2px left, 1px above + int iconw = l->icon->w()+2; + X += iconw; W -= iconw; w1 -= iconw; + } + } int tsize = textsize(); Fl_Font font = textfont(); Fl_Color lcol = textcolor(); @@ -521,7 +541,7 @@ void Fl_Browser::item_draw(void* item, 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*)item)->flags & SELECTED)) { + if (!(l->flags & SELECTED)) { fl_color((Fl_Color)strtol(str, &str, 10)); fl_rectf(X, Y, w1, H); } else strtol(str, &str, 10); @@ -557,7 +577,7 @@ void Fl_Browser::item_draw(void* item, int X, int Y, int W, int H) const { } BREAK: fl_font(font, tsize); - if (((FL_BLINE*)item)->flags & SELECTED) + if (l->flags & SELECTED) lcol = fl_contrast(lcol, selection_color()); if (!active_r()) lcol = fl_inactive(lcol); fl_color(lcol); @@ -835,6 +855,64 @@ void Fl_Browser::swap(int a, int b) { swap(ai,bi); } +/** + Set the image icon for \p line to the value \p icon. + Caller is responsible for keeping the icon allocated. + The \p line is automatically redrawn. + \param[in] line The line to be modified. If out of range, nothing is done. + \param[in] icon The image icon to be assigned to the \p line. + If NULL, any previous icon is removed. +*/ +void Fl_Browser::icon(int line, Fl_Image* icon) { + if (icon==0) { + remove_icon(line); + } else if (line>0 && line<=lines) { + // Update full_height_ + FL_BLINE* l = find_line(line); + int dh = icon->h() - item_height(l) + 2; // leave 2px above/below + l->icon = icon; // define icon AFTER item_height() check + if (dh>0) { + full_height_ += dh; + redraw(); // icon larger than item? must redraw widget + } else { + redraw_line(l); // icon same or smaller? can redraw just this line + } + } +} + +/** + Returns the icon currently defined for \p line. + If no icon is defined, NULL is returned. + \param[in] line The line whose icon is returned. + \returns The icon defined, or NULL if none. +*/ +Fl_Image* Fl_Browser::icon(int line) const { + FL_BLINE* l = find_line(line); + return(l ? l->icon : NULL); +} + +/** + Removes the icon for \p line. + It's ok to remove an icon if none has been defined. + \param[in] line The line whose icon is to be removed. +*/ +void Fl_Browser::remove_icon(int line) { + if (line>0 && line<=lines) { + FL_BLINE* bl = find_line(line); + if (!bl->icon) return; + int dh = bl->icon->h()+2; // leave 2px above/below + bl->icon=0; + // update_full_height_ + dh -= item_height(bl); + if (dh>0) { + full_height_ -= dh; + redraw(); // if icon was larger, must redraw window + } else { + redraw_line(bl); // if icon same size or smaller, can just redraw line + } + } +} + // // End of "$Id$". // |
