From cfc54a3b190dd7e85d6e2a313ab67d3ded4a4ab8 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Wed, 14 Aug 2024 01:45:20 +0200 Subject: [PATCH] Adding Fl_Widget::label_image_spacing() (#1039) - May need a better method name. - This makes the gap between the image in a label and the label text user settable. - Can be tested using test/label app --- FL/Fl_Widget.H | 13 +++++++++++++ FL/fl_draw.H | 4 ++-- src/Fl_Choice.cxx | 1 + src/Fl_Menu.cxx | 2 ++ src/Fl_Widget.cxx | 1 + src/Fl_Window.cxx | 1 + src/fl_draw.cxx | 20 ++++++++++---------- src/fl_labeltype.cxx | 6 +++--- test/label.cxx | 17 +++++++++++++++-- 9 files changed, 48 insertions(+), 17 deletions(-) diff --git a/FL/Fl_Widget.H b/FL/Fl_Widget.H index cc616bcf0..7dc90069c 100644 --- a/FL/Fl_Widget.H +++ b/FL/Fl_Widget.H @@ -63,6 +63,8 @@ struct FL_EXPORT Fl_Label { Fl_Align align_; /** type of label. \see Fl_Labeltype */ uchar type; + /** Spacing between an image and the label text */ + uchar spacing; /** Draws the label aligned to the given box */ void draw(int,int,int,int, Fl_Align) const ; @@ -685,6 +687,17 @@ public: */ void bind_deimage(int f) { if (f) set_flag(DEIMAGE_BOUND); else clear_flag(DEIMAGE_BOUND); } + /** Set the gap between the label and the image in pixels. + This value is limited to 0..255. + \param[in] gap spacing in pixels + */ + void label_image_spacing(int gap) { label_.spacing = (uchar)gap; } + + /** Return the gap size between the label and the image. + \return spacing in pixels + */ + int label_image_spacing() { return label_.spacing; } + /** Gets the current tooltip text. \return a pointer to the tooltip text or NULL \see tooltip(const char*), copy_tooltip(const char*) diff --git a/FL/fl_draw.H b/FL/fl_draw.H index b158f7253..efb0b4d15 100644 --- a/FL/fl_draw.H +++ b/FL/fl_draw.H @@ -977,10 +977,10 @@ inline void fl_rtl_draw(const char *str, int n, int x, int y) { FL_EXPORT void fl_measure(const char *str, int &x, int &y, int draw_symbols = 1); FL_EXPORT void fl_draw(const char *str, int x, int y, int w, int h, Fl_Align align, Fl_Image *img = 0, - int draw_symbols = 1, int gap = 0); + int draw_symbols = 1, int spacing = 0); FL_EXPORT void fl_draw(const char *str, int x, int y, int w, int h, Fl_Align align, void (*callthis)(const char *, int, int, int), - Fl_Image *img = 0, int draw_symbols = 1, int gap = 0); + Fl_Image *img = 0, int draw_symbols = 1, int spacing = 0); // boxtypes: diff --git a/src/Fl_Choice.cxx b/src/Fl_Choice.cxx index a4c6b0a2b..3ba0a2c7d 100644 --- a/src/Fl_Choice.cxx +++ b/src/Fl_Choice.cxx @@ -113,6 +113,7 @@ void Fl_Choice::draw() { l.font = m.labelsize_ || m.labelfont_ ? m.labelfont_ : textfont(); l.size = m.labelsize_ ? m.labelsize_ : textsize(); l.color= m.labelcolor_ ? m.labelcolor_ : textcolor(); + l.spacing = 0; if (!m.active()) l.color = fl_inactive((Fl_Color)l.color); fl_draw_shortcut = 2; // hack value to make '&' disappear l.draw(xx+3, yy, ww>6 ? ww-6 : 0, hh, FL_ALIGN_LEFT); diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx index 1d8ac502a..79228de80 100644 --- a/src/Fl_Menu.cxx +++ b/src/Fl_Menu.cxx @@ -261,6 +261,7 @@ int Fl_Menu_Item::measure(int* hp, const Fl_Menu_* m) const { l.font = labelsize_ || labelfont_ ? labelfont_ : (m ? m->textfont() : FL_HELVETICA); l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE; l.color = FL_FOREGROUND_COLOR; // this makes no difference? + l.spacing = 0; fl_draw_shortcut = 1; int w = 0; int h = 0; l.measure(w, hp ? *hp : h); @@ -280,6 +281,7 @@ void Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_* m, l.font = labelsize_ || labelfont_ ? labelfont_ : (m ? m->textfont() : FL_HELVETICA); l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE; l.color = labelcolor_ ? labelcolor_ : m ? m->textcolor() : int(FL_FOREGROUND_COLOR); + l.spacing = 0; if (!active()) l.color = fl_inactive((Fl_Color)l.color); if (selected) { Fl_Color r = m ? m->selection_color() : FL_SELECTION_COLOR; diff --git a/src/Fl_Widget.cxx b/src/Fl_Widget.cxx index bf2ff03d0..d5adb5a08 100644 --- a/src/Fl_Widget.cxx +++ b/src/Fl_Widget.cxx @@ -118,6 +118,7 @@ Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) { label_.size = FL_NORMAL_SIZE; label_.color = FL_FOREGROUND_COLOR; label_.align_ = FL_ALIGN_CENTER; + label_.spacing = 0; tooltip_ = 0; callback_ = default_callback; user_data_ = 0; diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx index a8912f31f..20a39a68e 100644 --- a/src/Fl_Window.cxx +++ b/src/Fl_Window.cxx @@ -526,6 +526,7 @@ void Fl_Window::draw_backdrop() { l1.image = image(); if (!active_r() && l1.image && l1.deimage) l1.image = l1.deimage; l1.type = labeltype(); + l1.spacing = 0; l1.draw(0,0,w(),h(),align()); } } diff --git a/src/fl_draw.cxx b/src/fl_draw.cxx index 49002aaca..0fb4bd5af 100644 --- a/src/fl_draw.cxx +++ b/src/fl_draw.cxx @@ -209,7 +209,7 @@ void fl_draw( int x, int y, int w, int h, // bounding box Fl_Align align, void (*callthis)(const char*,int,int,int), - Fl_Image* img, int draw_symbols, int gap) + Fl_Image* img, int draw_symbols, int spacing) { char *linebuf = NULL; // Pointer to a buffer managed by expand_text_ const char* p; // Scratch pointer into text, multiple use @@ -258,7 +258,7 @@ void fl_draw( // Width and height of both symbols combined symtotal = symwidth[0] + symwidth[1]; // Image width if image is to the left or right of the text, else 0 - imgtotal = (img && (align&FL_ALIGN_IMAGE_NEXT_TO_TEXT)) ? img->w() + gap : 0; + imgtotal = (img && (align&FL_ALIGN_IMAGE_NEXT_TO_TEXT)) ? img->w() + spacing : 0; int strw = 0; // Width of text only without symbols int strh; // Height of text only without symbols @@ -289,7 +289,7 @@ void fl_draw( // Figure out vertical position of the first element int xpos; // Position of image or text int ypos; // Position of image or text - int imgh = img && imgvert ? img->h() + gap : 0; // Height of image if image is above or below text + int imgh = img && imgvert ? img->h() + spacing : 0; // Height of image if image is above or below text int imgw[2] = {0, 0}; // Width of image on the left and right side of the text symoffset = 0; @@ -316,14 +316,14 @@ void fl_draw( } img->draw(xpos, ypos - height); - ypos += img->h() + gap; + ypos += img->h() + spacing; } // Draw the image if either on the *left* or *right* side of the text if (img && !imgvert) { if (align & FL_ALIGN_TEXT_OVER_IMAGE) { // Image is to the right of the text - imgw[1] = img->w() + gap; + imgw[1] = img->w() + spacing; // Find the horizontal position of the image if (align & FL_ALIGN_LEFT) { xpos = x + symwidth[0] + strw + 1; @@ -332,10 +332,10 @@ void fl_draw( } else { xpos = x + (w - strw - symtotal - imgw[1]) / 2 + symwidth[0] + strw + 1; } - xpos += gap; + xpos += spacing; } else { // Image is to the left of the text - imgw[0] = img->w() + gap; + imgw[0] = img->w() + spacing; // Find the horizontal position of the image if (align & FL_ALIGN_LEFT) { xpos = x + symwidth[0] - 1; @@ -401,7 +401,7 @@ void fl_draw( xpos = x + (w - img->w() - symtotal) / 2 + symwidth[0]; } - img->draw(xpos, ypos + gap); + img->draw(xpos, ypos + spacing); } // Draw the symbols, if any... @@ -476,13 +476,13 @@ void fl_draw( Fl_Align align, Fl_Image* img, int draw_symbols, - int gap) + int spacing) { if ((!str || !*str) && !img) return; if (w && h && !fl_not_clipped(x, y, w, h) && (align & FL_ALIGN_INSIDE)) return; if (align & FL_ALIGN_CLIP) fl_push_clip(x, y, w, h); - fl_draw(str, x, y, w, h, align, fl_draw, img, draw_symbols, gap); + fl_draw(str, x, y, w, h, align, fl_draw, img, draw_symbols, spacing); if (align & FL_ALIGN_CLIP) fl_pop_clip(); } diff --git a/src/fl_labeltype.cxx b/src/fl_labeltype.cxx index 8698c277b..9f5c5f20e 100644 --- a/src/fl_labeltype.cxx +++ b/src/fl_labeltype.cxx @@ -32,7 +32,7 @@ fl_normal_label(const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) { fl_font(o->font, o->size); fl_color((Fl_Color)o->color); - fl_draw(o->value, X, Y, W, H, align, o->image); + fl_draw(o->value, X, Y, W, H, align, o->image, 1, o->spacing); } void @@ -44,11 +44,11 @@ fl_normal_measure(const Fl_Label* o, int& W, int& H) { if (o->align_ & FL_ALIGN_IMAGE_BACKDROP) { // backdrop: ignore // ignore backdrop image for calculation } else if (o->align_ & FL_ALIGN_IMAGE_NEXT_TO_TEXT) { // text and image side by side - W += iw; + W += iw + o->spacing; if (ih > H) H = ih; } else { if (iw > W) W = iw; - H += ih; + H += ih + o->spacing; } } } diff --git a/test/label.cxx b/test/label.cxx index 7ae739bc4..de88b976b 100644 --- a/test/label.cxx +++ b/test/label.cxx @@ -32,6 +32,7 @@ Fl_Box *text; Fl_Input *input; Fl_Hor_Value_Slider *fonts; Fl_Hor_Value_Slider *sizes; +Fl_Hor_Value_Slider *spacing; Fl_Double_Window *window; Fl_Pixmap *img; @@ -64,6 +65,11 @@ void font_cb(Fl_Widget *,void *) { window->redraw(); } +void spacing_cb(Fl_Widget *,void *) { + text->label_image_spacing(int(spacing->value())); + window->redraw(); +} + void size_cb(Fl_Widget *,void *) { text->labelsize(int(sizes->value())); window->redraw(); @@ -114,9 +120,9 @@ Fl_Menu_Item choices[] = { int main(int argc, char **argv) { img = new Fl_Pixmap(blast_xpm); - window = new Fl_Double_Window(440,420); + window = new Fl_Double_Window(440,445); - input = new Fl_Input(70,375,350,25,"Label:"); + input = new Fl_Input(70,400,350,25,"Label:"); input->static_value("The quick brown fox jumped over the lazy dog."); input->when(FL_WHEN_CHANGED); input->callback(input_cb); @@ -136,6 +142,13 @@ int main(int argc, char **argv) { fonts->value(0); fonts->callback(font_cb); + spacing=new Fl_Hor_Value_Slider(70,375,350,25,"Spacing:"); + spacing->align(FL_ALIGN_LEFT); + spacing->bounds(0,100); + spacing->step(1); + spacing->value(0); + spacing->callback(spacing_cb); + Fl_Group *g = new Fl_Group(70,275,350,50); imageb = new Fl_Toggle_Button(70,275,50,25,"image"); imageb->callback(image_cb);