From 34ed30fe1a710f6294e23003aa385bd6da6cb326 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sat, 25 Nov 2023 18:20:02 +0100 Subject: [PATCH] Adds `linespacing()` to `Fl_Browser_` and all derived widgets --- FL/Fl_Browser_.H | 12 ++++++++++++ FL/Fl_File_Browser.H | 2 +- fltk-options/fltk-options.cxx | 1 + fluid/widget_browser.cxx | 8 ++++---- src/Fl_Browser.cxx | 16 ++++++++-------- src/Fl_Browser_.cxx | 33 +++++++++++++++++---------------- src/Fl_Check_Browser.cxx | 3 ++- src/Fl_File_Browser.cxx | 28 +++++++++++++--------------- test/grid_dialog.cxx | 2 +- test/unittests.cxx | 1 + 10 files changed, 60 insertions(+), 46 deletions(-) diff --git a/FL/Fl_Browser_.H b/FL/Fl_Browser_.H index d83f94ee0..37ae59c5e 100644 --- a/FL/Fl_Browser_.H +++ b/FL/Fl_Browser_.H @@ -96,6 +96,7 @@ class FL_EXPORT Fl_Browser_ : public Fl_Group { void *redraw1,*redraw2; // minimal update pointers void* max_width_item; // which item has max_width_ int scrollbar_size_; // size of scrollbar trough + int linespacing_; void update_top(); @@ -400,6 +401,17 @@ public: */ void scrollbar_left() { scrollbar.align(FL_ALIGN_LEFT); } void sort(int flags=0); + + /** + Add some space between browser lines. + \param[in] pixels number of additional pixels between lines. + */ + void linespacing(int pixels) { linespacing_ = pixels; } + + /** Return the height of additional spacing between browser lines. + \return spacing height in pixel units. + */ + int linespacing() const { return linespacing_; } }; #endif diff --git a/FL/Fl_File_Browser.H b/FL/Fl_File_Browser.H index 101add4de..620315c17 100644 --- a/FL/Fl_File_Browser.H +++ b/FL/Fl_File_Browser.H @@ -46,7 +46,7 @@ class FL_EXPORT Fl_File_Browser : public Fl_Browser { int item_height(void *) const FL_OVERRIDE; int item_width(void *) const FL_OVERRIDE; void item_draw(void *, int, int, int, int) const FL_OVERRIDE; - int incr_height() const FL_OVERRIDE { return (item_height(0)); } + int incr_height() const FL_OVERRIDE { return (item_height(0) + linespacing()); } public: enum { FILES, DIRECTORIES }; diff --git a/fltk-options/fltk-options.cxx b/fltk-options/fltk-options.cxx index d7ba73039..0e68a5b13 100644 --- a/fltk-options/fltk-options.cxx +++ b/fltk-options/fltk-options.cxx @@ -644,6 +644,7 @@ Fl_Window* build_ui() { "Groups"); g_headline_browser->align(FL_ALIGN_TOP); g_headline_browser->textsize(FL_NORMAL_SIZE+1); + g_headline_browser->linespacing(4); add_headlines(g_headline_browser); // -- scrollable area for all options inside a group g_option_scroll = new Fl_Scroll(FO_GAP + FO_BROWSER_W + FO_GAP, FO_GAP + FO_TITLE_H, diff --git a/fluid/widget_browser.cxx b/fluid/widget_browser.cxx index 993b564fb..b27d7a664 100644 --- a/fluid/widget_browser.cxx +++ b/fluid/widget_browser.cxx @@ -252,7 +252,7 @@ int Widget_Browser::item_height(void *l) const { \return height in FLTK units */ int Widget_Browser::incr_height() const { - return textsize()+5; + return textsize() + 5 + linespacing(); } /** @@ -552,15 +552,15 @@ void Widget_Browser::display(Fl_Type *inNode) { Fl_Type *p=Fl_Type::first; for ( ; p && p!=inNode; p=p->next) { if (p->visible) - nodeV += item_height(p); + nodeV += item_height(p) + linespacing(); } if (p) { int xx, yy, ww, hh; bbox(xx, yy, ww, hh); int frame_top = xx-x(); int frame_bottom = frame_top + hh; - int node_height = item_height(inNode); - int margin_height = 2 * item_quick_height(inNode); + int node_height = item_height(inNode) + linespacing(); + int margin_height = 2 * (item_quick_height(inNode) + linespacing()); if (margin_height>hh/2) margin_height = hh/2; // is the inNode above the current scroll position? if (nodeVprev; lines--; - full_height_ -= item_height(ttt); + full_height_ -= item_height(ttt) + linespacing(); if (ttt->prev) ttt->prev->next = ttt->next; else first = ttt->next; if (ttt->next) ttt->next->prev = ttt->prev; @@ -264,7 +264,7 @@ void Fl_Browser::insert(int line, FL_BLINE* item) { cacheline = line; cache = item; lines++; - full_height_ += item_height(item); + full_height_ += item_height(item) + linespacing(); redraw_line(item); } @@ -489,7 +489,7 @@ int Fl_Browser::full_height() const { incr_height(), full_height() */ int Fl_Browser::incr_height() const { - return textsize()+2; + return textsize() + 2 + linespacing(); } /** @@ -620,9 +620,9 @@ void Fl_Browser::lineposition(int line, Fl_Line_Position pos) { FL_BLINE* l; for (l=first; l && line>1; l = l->next) { - line--; p += item_height(l); + line--; p += item_height(l) + linespacing(); } - if (l && (pos == BOTTOM)) p += item_height (l); + if (l && (pos == BOTTOM)) p += item_height(l) + linespacing(); int final = p, X, Y, W, H; bbox(X, Y, W, H); @@ -670,7 +670,7 @@ void Fl_Browser::textsize(Fl_Fontsize newSize) { full_height_ = 0; if (lines == 0) return; for (FL_BLINE* itm=(FL_BLINE *)item_first(); itm; itm=(FL_BLINE *)item_next(itm)) { - full_height_ += item_height(itm); + full_height_ += item_height(itm) + linespacing(); } } @@ -769,7 +769,7 @@ void Fl_Browser::show(int line) { FL_BLINE* t = find_line(line); if (t->flags & NOTDISPLAYED) { t->flags &= ~NOTDISPLAYED; - full_height_ += item_height(t); + full_height_ += item_height(t) + linespacing(); if (Fl_Browser_::displayed(t)) redraw(); } } @@ -786,7 +786,7 @@ void Fl_Browser::show(int line) { void Fl_Browser::hide(int line) { FL_BLINE* t = find_line(line); if (!(t->flags & NOTDISPLAYED)) { - full_height_ -= item_height(t); + full_height_ -= item_height(t) + linespacing(); t->flags |= NOTDISPLAYED; if (Fl_Browser_::displayed(t)) redraw(); } diff --git a/src/Fl_Browser_.cxx b/src/Fl_Browser_.cxx index 55cab5a73..b05772aea 100644 --- a/src/Fl_Browser_.cxx +++ b/src/Fl_Browser_.cxx @@ -148,13 +148,13 @@ void Fl_Browser_::update_top() { offset_ = 0; real_position_ = 0; } else { - int hh = item_quick_height(l); + int hh = item_quick_height(l) + linespacing(); // step through list until we find line containing this point: while (ly > yy) { void* l1 = item_prev(l); if (!l1) {ly = 0; break;} // hit the top l = l1; - hh = item_quick_height(l); + hh = item_quick_height(l) + linespacing(); ly -= hh; } while ((ly+hh) <= yy) { @@ -162,16 +162,16 @@ void Fl_Browser_::update_top() { if (!l1) {yy = ly+hh-1; break;} l = l1; ly += hh; - hh = item_quick_height(l); + hh = item_quick_height(l) + linespacing(); } // top item must *really* be visible, use slow height: for (;;) { - hh = item_height(l); + hh = item_height(l) + linespacing(); if ((ly+hh) > yy) break; // it is big enough to see // go up to top of previous item: void* l1 = item_prev(l); if (!l1) {ly = yy = 0; break;} // hit the top - l = l1; yy = position_ = ly = ly-item_quick_height(l); + l = l1; yy = position_ = ly = ly-item_quick_height(l) + linespacing(); } // use it: top_ = l; @@ -229,7 +229,7 @@ int Fl_Browser_::displayed(void* item) const { int yy = H+offset_; for (void* l = top_; l && yy > 0; l = item_next(l)) { if (l == item) return 1; - yy -= item_height(l); + yy -= item_height(l) + linespacing(); } return 0; } @@ -257,7 +257,7 @@ void Fl_Browser_::display(void* item) { // 3rd special case - want to display item just above top of browser? void* lp = item_prev(l); - if (lp == item) { vposition(real_position_+Y-item_quick_height(lp)); return; } + if (lp == item) { vposition(real_position_+Y-item_quick_height(lp)-linespacing()); return; } #ifdef DISPLAY_SEARCH_BOTH_WAYS_AT_ONCE // search for item. We search both up and down the list at the same time, @@ -265,7 +265,7 @@ void Fl_Browser_::display(void* item) { // much slower for going up than for going down. while (l || lp) { if (l) { - h1 = item_quick_height(l); + h1 = item_quick_height(l) + linespacing(); if (l == item) { if (Y <= H) { // it is visible or right at bottom Y = Y+h1-H; // find where bottom edge is @@ -279,7 +279,7 @@ void Fl_Browser_::display(void* item) { l = item_next(l); } if (lp) { - h1 = item_quick_height(lp); + h1 = item_quick_height(lp) + linespacing(); Yp -= h1; if (lp == item) { if ((Yp + h1) >= 0) vposition(real_position_+Yp); @@ -294,7 +294,7 @@ void Fl_Browser_::display(void* item) { // search forward for it: l = top_; for (; l; l = item_next(l)) { - h1 = item_quick_height(l); + h1 = item_quick_height(l) + linespacing(); if (l == item) { if (Y <= H) { // it is visible or right at bottom Y = Y+h1-H; // find where bottom edge is @@ -310,7 +310,7 @@ void Fl_Browser_::display(void* item) { l = lp; Y = -offset_; for (; l; l = item_prev(l)) { - h1 = item_quick_height(l); + h1 = item_quick_height(l) + linespacing(); Y -= h1; if (l == item) { if ((Y + h1) >= 0) position(real_position_+Y); @@ -395,7 +395,7 @@ J1: void* l = top(); int yy = -offset_; for (; l && yy < H; l = item_next(l)) { - int hh = item_height(l); + int hh = item_height(l) + linespacing(); if (hh <= 0) continue; if ((damage()&(FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) || l == redraw1 || l == redraw2) { if (item_selected(l)) { @@ -448,7 +448,7 @@ J1: // update the scrollbars and redraw them: int scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size(); - int dy = top_ ? item_quick_height(top_) : 0; if (dy < 10) dy = 10; + int dy = top_ ? item_quick_height(top_) + linespacing() : 0; if (dy < 10) dy = 10; if (scrollbar.visible()) { scrollbar.damage_resize( scrollbar.align()&FL_ALIGN_LEFT ? X-scrollsize : X+W, @@ -585,7 +585,7 @@ void* Fl_Browser_::find_item(int ypos) { int yy = Y-offset_; for (void *l = top_; l; l = item_next(l)) { int hh = item_height(l); if (hh <= 0) continue; - yy += hh; + yy += hh + linespacing(); if (ypos <= yy || yy>=(Y+H)) return l; } return 0; @@ -954,7 +954,8 @@ J1: Fl_Browser_::Fl_Browser_(int X, int Y, int W, int H, const char* L) : Fl_Group(X, Y, W, H, L), scrollbar(0, 0, 0, 0, 0), // they will be resized by draw() - hscrollbar(0, 0, 0, 0, 0) + hscrollbar(0, 0, 0, 0, 0), + linespacing_(0) { box(FL_NO_BOX); align(FL_ALIGN_BOTTOM); @@ -1053,7 +1054,7 @@ int Fl_Browser_::item_quick_height(void* item) const { \returns The average height of items, in pixels. */ int Fl_Browser_::incr_height() const { - return item_quick_height(item_first()); + return item_quick_height(item_first()) + linespacing(); } /** diff --git a/src/Fl_Check_Browser.cxx b/src/Fl_Check_Browser.cxx index d831c3cb2..e1ed61d7f 100644 --- a/src/Fl_Check_Browser.cxx +++ b/src/Fl_Check_Browser.cxx @@ -176,7 +176,8 @@ int Fl_Check_Browser::item_width(void *v) const { return int(fl_width(((cb_item *)v)->text)) + CHECK_SIZE + 8; } -void Fl_Check_Browser::item_draw(void *v, int X, int Y, int, int) const { +void Fl_Check_Browser::item_draw(void *v, int X, int Y, int, int H) const { + Y += (H - item_height(v)) / 2; cb_item *i = (cb_item *)v; char *s = i->text; int tsize = textsize(); diff --git a/src/Fl_File_Browser.cxx b/src/Fl_File_Browser.cxx index e3a70aa3b..c37ea8aa3 100644 --- a/src/Fl_File_Browser.cxx +++ b/src/Fl_File_Browser.cxx @@ -76,7 +76,7 @@ Fl_File_Browser::full_height() const for (i = 0, th = 0; i < size(); i ++) - th += item_height(find_line(i)); + th += item_height(find_line(i)) + linespacing(); return (th); } @@ -234,7 +234,7 @@ Fl_File_Browser::item_draw(void *p, // I - List item data int X, // I - Upper-lefthand X coordinate int Y, // I - Upper-lefthand Y coordinate int W, // I - Width of item - int) const // I - Height of item + int H) const// I - Height of item { int i; // Looping var FL_BLINE *line; // Pointer to line @@ -271,25 +271,23 @@ Fl_File_Browser::item_draw(void *p, // I - List item data { // Draw the icon if it is set... if (line->data) - ((Fl_File_Icon *)line->data)->draw(X, Y, iconsize_, iconsize_, - (line->flags & SELECTED) ? FL_YELLOW : + ((Fl_File_Icon *)line->data)->draw(X, Y + (H - iconsize_) / 2, + iconsize_, iconsize_, + (line->flags & SELECTED) ? FL_YELLOW : FL_LIGHT2, - active_r()); + active_r()); // Draw the text offset to the right... X += iconsize_ + 9; W -= iconsize_ - 10; - - // Center the text vertically... - height = fl_height(); - - for (t = line->txt; *t != '\0'; t ++) - if (*t == '\n') - height += fl_height(); - - if (height < iconsize_) - Y += (iconsize_ - height) / 2; } + // Center the text vertically... + height = fl_height(); + + for (t = line->txt; *t != '\0'; t ++) + if (*t == '\n') + height += fl_height(); + Y += (H - height) / 2; // Draw the text... line = (FL_BLINE *)p; diff --git a/test/grid_dialog.cxx b/test/grid_dialog.cxx index 72ffe66b4..ae393cb22 100644 --- a/test/grid_dialog.cxx +++ b/test/grid_dialog.cxx @@ -86,7 +86,7 @@ void button_cb(Fl_Widget *w, void *v) { break; case 1: { // Copy const char *text = message_box->label(); - const int len = strlen(text); + const int len = (int)strlen(text); Fl::copy(text, len, 1); } printf("Message copied to clipboard.\n"); diff --git a/test/unittests.cxx b/test/unittests.cxx index 4783c223e..12776d670 100644 --- a/test/unittests.cxx +++ b/test/unittests.cxx @@ -454,6 +454,7 @@ int main(int argc, char** argv) { browser->align(FL_ALIGN_TOP|FL_ALIGN_LEFT); browser->when(FL_WHEN_CHANGED); browser->callback(ui_browser_cb); + browser->linespacing(2); int n = UnitTest::num_tests(); for (i=0; i