From a5adbd99ca073ecb9d6153b089543b23a673c9b5 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sat, 10 Dec 2022 23:22:24 +0100 Subject: [PATCH] Add option to bind images to a widget (#589) Adding image binding to FLUID as well --- FL/Fl_Widget.H | 87 +++++++++++++++++++++++++++++++++++----- fluid/Fl_Menu_Type.cxx | 2 +- fluid/Fl_Widget_Type.cxx | 52 +++++++++++++++++++++++- fluid/Fl_Widget_Type.h | 2 + fluid/Fluid_Image.cxx | 4 +- fluid/Fluid_Image.h | 2 +- fluid/README_fl.txt | 2 + fluid/pixmaps.cxx | 3 ++ fluid/pixmaps.h | 1 + fluid/pixmaps/bind.xpm | 45 +++++++++++++++++++++ fluid/widget_panel.cxx | 20 +++++++-- fluid/widget_panel.fl | 26 ++++++++---- fluid/widget_panel.h | 3 ++ src/Fl_Widget.cxx | 40 ++++++++++++++++++ 14 files changed, 261 insertions(+), 28 deletions(-) create mode 100644 fluid/pixmaps/bind.xpm diff --git a/FL/Fl_Widget.H b/FL/Fl_Widget.H index 1c90848de..a49da922b 100644 --- a/FL/Fl_Widget.H +++ b/FL/Fl_Widget.H @@ -158,8 +158,9 @@ protected: COPIED_TOOLTIP = 1<<17, ///< the widget tooltip is internally copied, its destruction is handled by the widget FULLSCREEN = 1<<18, ///< a fullscreen window (Fl_Window) MAC_USE_ACCENTS_MENU = 1<<19, ///< On the Mac OS platform, pressing and holding a key on the keyboard opens an accented-character menu window (Fl_Input_, Fl_Text_Editor) - // (space for more flags) NEEDS_KEYBOARD = 1<<20, ///< set this on touch screen devices if a widget needs a keyboard when it gets Focus. @see Fl_Screen_Driver::request_keyboard() + IMAGE_BOUND = 1<<21, ///< binding the image to the widget will transfer ownership, so that the widget will delete the image when it is no longer needed + DEIMAGE_BOUND = 1<<22, ///< bind the inactive image to the widget, so the widget deletes the image when it no longer needed // a tiny bit more space for new flags... USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions USERFLAG2 = 1<<30, ///< reserved for 3rd party extensions @@ -518,45 +519,109 @@ public: \return the current image */ Fl_Image* image() {return label_.image;} + /** Gets the image that is used as part of the widget label when in the active state. \return the current image */ const Fl_Image* image() const {return label_.image;} /** Sets the image to use as part of the widget label when in the active state. - \param[in] img the new image for the label - \note The caller is responsible for making sure \p img is not deleted while it's used by the widget, + + The caller is responsible for making sure \p img is not deleted while it's used by the widget, and, if appropriate, for deleting it after the widget's deletion. + + Calling image() with a new image will delete the old image if it + was bound, and set the new image without binding it. If old and new are + the same, the image will not be deleted, but it will be unbound. + + Calling image() with NULL will delete the old image if + it was bound and not set a new image. + + \param[in] img the new image for the label + \see bind_image(Fl_Image* img) */ - void image(Fl_Image* img) {label_.image=img;} + void image(Fl_Image* img); /** Sets the image to use as part of the widget label when in the active state. - \param[in] img the new image for the label + \param[in] img the new image for the label \see void image(Fl_Image* img) */ - void image(Fl_Image& img) {label_.image=&img;} + void image(Fl_Image& img); + + /** Sets the image to use as part of the widget label when in the active state. + + The image will be bound to the widget. When the widget is deleted, the + image will be deleted as well. + + Calling bind_image() with a new image will delete the old image if it + was bound, and then set the new image, and bind that. If old and new image + are the same, nothing happens. + + Calling bind_image() with NULL will delete the old image if + it was bound and not set a new image. + + \param[in] img the new image for the label + \see void image(Fl_Image* img) + */ + void bind_image(Fl_Image* img); + + /** Bind the image to the widget, so the widget will delete the image when it is no longer needed. + \param f 1: mark the image as bound, 0: mark the image as managed by the user + \see image_bound(), bind_deimage() + */ + void bind_image(int f) { if (f) set_flag(IMAGE_BOUND); else clear_flag(IMAGE_BOUND); } + + /** Returns whether the image is managed by the widget. + \retval 0 if the image is not bound to the widget + \retval 1 if the image will be deleted when the widget is deleted + \see deimage_bound(), bind_image() + */ + int image_bound() const {return ((flags_ & IMAGE_BOUND) ? 1 : 0);} /** Gets the image that is used as part of the widget label when in the inactive state. \return the current image for the deactivated widget */ Fl_Image* deimage() {return label_.deimage;} + /** Gets the image that is used as part of the widget label when in the inactive state. \return the current image for the deactivated widget */ const Fl_Image* deimage() const {return label_.deimage;} /** Sets the image to use as part of the widget label when in the inactive state. - \param[in] img the new image for the deactivated widget - \note The caller is responsible for making sure \p img is not deleted while it's used by the widget, + \param[in] img the new image for the deactivated widget + \note The caller is responsible for making sure \p img is not deleted while it's used by the widget, and, if appropriate, for deleting it after the widget's deletion. + \see void bind_deimage(Fl_Image* img) */ - void deimage(Fl_Image* img) {label_.deimage=img;} + void deimage(Fl_Image* img); /** Sets the image to use as part of the widget label when in the inactive state. - \param[in] img the new image for the deactivated widget + \param[in] img the new image for the deactivated widget \see void deimage(Fl_Image* img) */ - void deimage(Fl_Image& img) {label_.deimage=&img;} + void deimage(Fl_Image& img); + + /** Sets the image to use as part of the widget label when in the inactive state. + \param[in] img the new image for the deactivated widget + \note The image will be bound to the widget. When the widget is deleted, the + image will be deleted as well. + \see void deimage(Fl_Image* img) + */ + void bind_deimage(Fl_Image* img); + + /** Returns whether the inactive image is managed by the widget. + \retval 0 if the image is not bound to the widget + \retval 1 if the image will be deleted when the widget is deleted + \see image_bound(), bind_deimage() + */ + int deimage_bound() const {return ((flags_ & DEIMAGE_BOUND) ? 1 : 0);} + + /** Bind the inactive image to the widget, so the widget will delete the image when it is no longer needed. + \param f 1: mark the image as bound, 0: mark the image as managed by the user + \see deimage_bound(), bind_image() + */ + void bind_deimage(int f) { if (f) set_flag(DEIMAGE_BOUND); else clear_flag(DEIMAGE_BOUND); } /** Gets the current tooltip text. \return a pointer to the tooltip text or NULL diff --git a/fluid/Fl_Menu_Type.cxx b/fluid/Fl_Menu_Type.cxx index ad2a9e088..6d71bce85 100644 --- a/fluid/Fl_Menu_Type.cxx +++ b/fluid/Fl_Menu_Type.cxx @@ -488,7 +488,7 @@ void Fl_Menu_Item_Type::write_code1() { write_c("%sml->typeb = FL_NORMAL_LABEL;\n", indent()); write_c("%sml->label(o);\n", indent()); } else { - image->write_code("o"); + image->write_code(0, "o"); } } if (P.i18n_type && label() && label()[0]) { diff --git a/fluid/Fl_Widget_Type.cxx b/fluid/Fl_Widget_Type.cxx index cafd56ea4..ffa9b1803 100644 --- a/fluid/Fl_Widget_Type.cxx +++ b/fluid/Fl_Widget_Type.cxx @@ -210,6 +210,8 @@ Fl_Widget_Type::Fl_Widget_Type() { xclass = 0; o = 0; public_ = 1; + bind_image_ = 0; + bind_deimage_ = 0; } Fl_Widget_Type::~Fl_Widget_Type() { @@ -475,6 +477,26 @@ void image_browse_cb(Fl_Button* b, void *v) { } } +void bind_image_cb(Fl_Button* b, void *v) { + if (v == LOAD) { + if (current_widget->is_widget() && !current_widget->is_window()) { + b->activate(); + b->value(current_widget->bind_image_); + } else { + b->deactivate(); + } + } else { + int mod = 0; + for (Fl_Type *o = Fl_Type::first; o; o = o->next) { + if (o->selected && o->is_widget()) { + ((Fl_Widget_Type*)o)->bind_image_ = b->value(); + mod = 1; + } + } + if (mod) set_modflag(1); + } +} + static Fl_Input *inactive_input; void inactive_cb(Fl_Input* i, void *v) { @@ -517,6 +539,26 @@ void inactive_browse_cb(Fl_Button* b, void *v) { } } +void bind_deimage_cb(Fl_Button* b, void *v) { + if (v == LOAD) { + if (current_widget->is_widget() && !current_widget->is_window()) { + b->activate(); + b->value(current_widget->bind_deimage_); + } else { + b->deactivate(); + } + } else { + int mod = 0; + for (Fl_Type *o = Fl_Type::first; o; o = o->next) { + if (o->selected && o->is_widget()) { + ((Fl_Widget_Type*)o)->bind_deimage_ = b->value(); + mod = 1; + } + } + if (mod) set_modflag(1); + } +} + void tooltip_cb(Fl_Input* i, void *v) { if (v == LOAD) { if (current_widget->is_widget()) { @@ -2917,8 +2959,8 @@ void Fl_Widget_Type::write_widget_code() { write_color("color", o->color()); if (o->selection_color() != tplate->selection_color() || subclass()) write_color("selection_color", o->selection_color()); - if (image) image->write_code(var); - if (inactive) inactive->write_code(var, 1); + if (image) image->write_code(bind_image_, var); + if (inactive) inactive->write_code(bind_deimage_, var, 1); if (o->labeltype() != tplate->labeltype() || subclass()) write_c("%s%s->labeltype(FL_%s);\n", indent(), var, item_name(labeltypemenu, o->labeltype())); @@ -3044,10 +3086,12 @@ void Fl_Widget_Type::write_properties() { write_string("image"); write_word(image_name()); } + if (bind_image_) write_string("bind_image 1"); if (inactive_name() && *inactive_name()) { write_string("deimage"); write_word(inactive_name()); } + if (bind_deimage_) write_string("bind_deimage 1"); write_string("xywh {%d %d %d %d}", o->x(), o->y(), o->w(), o->h()); Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o; if (is_spinner() && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type()) { @@ -3168,8 +3212,12 @@ void Fl_Widget_Type::read_property(const char *c) { tooltip(read_word()); } else if (!strcmp(c,"image")) { image_name(read_word()); + } else if (!strcmp(c,"bind_image")) { + bind_image_ = (int)atol(read_word()); } else if (!strcmp(c,"deimage")) { inactive_name(read_word()); + } else if (!strcmp(c,"bind_deimage")) { + bind_deimage_ = (int)atol(read_word()); } else if (!strcmp(c,"type")) { if (is_spinner()) ((Fl_Spinner*)o)->type(item_number(subtypes(), read_word())); diff --git a/fluid/Fl_Widget_Type.h b/fluid/Fl_Widget_Type.h index 8325dcc56..9a8555c3f 100644 --- a/fluid/Fl_Widget_Type.h +++ b/fluid/Fl_Widget_Type.h @@ -66,6 +66,8 @@ public: const char *xclass; // junk string, used for shortcut Fl_Widget *o; int public_; + int bind_image_; + int bind_deimage_; Fluid_Image *image; void setimage(Fluid_Image *); diff --git a/fluid/Fluid_Image.cxx b/fluid/Fluid_Image.cxx index e7fcbc253..604ec80a1 100644 --- a/fluid/Fluid_Image.cxx +++ b/fluid/Fluid_Image.cxx @@ -200,10 +200,10 @@ void Fluid_Image::write_initializer(const char *type_name, const char *format, . va_end(ap); } -void Fluid_Image::write_code(const char *var, int inactive) { +void Fluid_Image::write_code(int bind, const char *var, int inactive) { /* Outputs code that attaches an image to an Fl_Widget or Fl_Menu_Item. This code calls a function output before by Fluid_Image::write_initializer() */ - if (img) write_c("%s%s->%s( %s() );\n", indent(), var, inactive ? "deimage" : "image", function_name_); + if (img) write_c("%s%s->%s%s( %s() );\n", indent(), var, bind ? "bind_" : "", inactive ? "deimage" : "image", function_name_); } void Fluid_Image::write_inline(int inactive) { diff --git a/fluid/Fluid_Image.h b/fluid/Fluid_Image.h index 8dc33c3c0..738789223 100644 --- a/fluid/Fluid_Image.h +++ b/fluid/Fluid_Image.h @@ -40,7 +40,7 @@ public: void deimage(Fl_Widget *); // set the deimage of this widget void write_static(); void write_initializer(const char *type_name, const char *format, ...); - void write_code(const char *var, int inactive = 0); + void write_code(int bind, const char *var, int inactive = 0); void write_inline(int inactive = 0); void write_file_error(const char *fmt); const char *name() const {return name_;} diff --git a/fluid/README_fl.txt b/fluid/README_fl.txt index 3b65360ae..a4d509f1a 100644 --- a/fluid/README_fl.txt +++ b/fluid/README_fl.txt @@ -380,7 +380,9 @@ Type "Fl_Widget" : C++ variable name "xywh" : "{%d %d %d %d}" x, y, w, h "tooltip" : tooltip text "image" : image name + "bind_image" : integer (1.4 and up) "deimage" : deactivated image name + "bind_deimage" : integer (1.4 and up) "type" : integer "box" : text or integer (see FLTK boxtypes) "down_box" : (is_button() or Fl_Input_choice" or is_menu_button()) diff --git a/fluid/pixmaps.cxx b/fluid/pixmaps.cxx index b79314e36..358dd2c24 100644 --- a/fluid/pixmaps.cxx +++ b/fluid/pixmaps.cxx @@ -18,6 +18,7 @@ #include +#include "pixmaps/bind.xpm" #include "pixmaps/lock.xpm" #include "pixmaps/protected.xpm" #include "pixmaps/invisible.xpm" @@ -79,6 +80,7 @@ #include "pixmaps/flRadioMenuitem.xpm" #include "pixmaps/flFlex.xpm" +Fl_Pixmap *bind_pixmap; Fl_Pixmap *lock_pixmap; Fl_Pixmap *protected_pixmap; Fl_Pixmap *invisible_pixmap; @@ -144,6 +146,7 @@ Fl_Pixmap *pixmap[57]; void loadPixmaps() { + bind_pixmap = new Fl_Pixmap(bind_xpm); bind_pixmap->scale(16, 16); lock_pixmap = new Fl_Pixmap(lock_xpm); lock_pixmap->scale(16, 16); protected_pixmap = new Fl_Pixmap(protected_xpm); protected_pixmap->scale(16, 16); invisible_pixmap = new Fl_Pixmap(invisible_xpm); invisible_pixmap->scale(16, 16); diff --git a/fluid/pixmaps.h b/fluid/pixmaps.h index 29bb1667e..0fafec78a 100644 --- a/fluid/pixmaps.h +++ b/fluid/pixmaps.h @@ -19,6 +19,7 @@ class Fl_Pixmap; +extern Fl_Pixmap *bind_pixmap; extern Fl_Pixmap *lock_pixmap; extern Fl_Pixmap *protected_pixmap; extern Fl_Pixmap *invisible_pixmap; diff --git a/fluid/pixmaps/bind.xpm b/fluid/pixmaps/bind.xpm new file mode 100644 index 000000000..7d98189ac --- /dev/null +++ b/fluid/pixmaps/bind.xpm @@ -0,0 +1,45 @@ +/* cPM */ +static const char * const bind_xpm[] = { +/* width height ncolors chars_per_picel */ +"32 32 6 1", +/* colors */ +"- c #aaaaaa", +"= c #666666", +"c c none", +"d c #cccccc", +". c #000000", +", c #222222", +/* pixels */ +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccc,,,,,,,,,,,,,,cccccc", +"cccccccccc,,................cccc", +"ccccccccc,...................ccc", +"ccccccccc======..............ccc", +"cccccccc------cccccccccc......cc", +"cccccccc-----cccccccccccc.....cc", +"cccccc,,,,,,,,,,,,,,cccccc....cc", +"cccc,,................cccc....cc", +"ccc,...................ccc....cc", +"cc,...............=====ccc....cc", +"cc......-----cccccc-----c,....cc", +"cc.....c-----cccccc-----,.....cc", +"cc....ccc=====,,,,,,,,,,.....ccc", +"cc....ccc....................ccc", +"cc....cccc..................cccc", +"cc....cccccc..............cccccc", +"cc.....cccccccccccc-----cccccccc", +"cc......cccccccccc------cccccccc", +"ccc.....,,,,,,,,=======ccccccccc", +"ccc....................ccccccccc", +"cccc..................cccccccccc", +"cccccc..............cccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc", +"cccccccccccccccccccccccccccccccc" +}; diff --git a/fluid/widget_panel.cxx b/fluid/widget_panel.cxx index 488d94476..1a6b825a3 100644 --- a/fluid/widget_panel.cxx +++ b/fluid/widget_panel.cxx @@ -165,7 +165,7 @@ Fl_Double_Window* make_widget_panel() { o->labelsize(11); o->callback((Fl_Callback*)propagate_load); o->align(Fl_Align(FL_ALIGN_LEFT)); - { Fl_Input* o = new Fl_Input(95, 65, 240, 20); + { Fl_Input* o = new Fl_Input(95, 65, 220, 20); o->tooltip("The active image for the widget."); o->labelfont(1); o->labelsize(11); @@ -173,11 +173,17 @@ Fl_Double_Window* make_widget_panel() { o->callback((Fl_Callback*)image_cb); Fl_Group::current()->resizable(o); } // Fl_Input* o - { Fl_Button* o = new Fl_Button(334, 65, 70, 20, "Browse..."); + { Fl_Button* o = new Fl_Button(314, 65, 70, 20, "Browse..."); o->tooltip("Click to choose the active image."); o->labelsize(11); o->callback((Fl_Callback*)image_browse_cb); } // Fl_Button* o + { Fl_Button* o = new Fl_Button(384, 65, 20, 20); + o->tooltip("bind the image to the widget, so it will be deleted automatically"); + o->type(1); + o->callback((Fl_Callback*)bind_image_cb); + o->image(bind_pixmap); + } // Fl_Button* o o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(95, 90, 309, 20, "Inactive:"); @@ -185,7 +191,7 @@ Fl_Double_Window* make_widget_panel() { o->labelsize(11); o->callback((Fl_Callback*)propagate_load); o->align(Fl_Align(FL_ALIGN_LEFT)); - { Fl_Input* o = new Fl_Input(95, 90, 240, 20); + { Fl_Input* o = new Fl_Input(95, 90, 220, 20); o->tooltip("The inactive image for the widget."); o->labelfont(1); o->labelsize(11); @@ -193,11 +199,17 @@ Fl_Double_Window* make_widget_panel() { o->callback((Fl_Callback*)inactive_cb); Fl_Group::current()->resizable(o); } // Fl_Input* o - { Fl_Button* o = new Fl_Button(334, 90, 70, 20, "Browse..."); + { Fl_Button* o = new Fl_Button(314, 90, 70, 20, "Browse..."); o->tooltip("Click to choose the inactive image."); o->labelsize(11); o->callback((Fl_Callback*)inactive_browse_cb); } // Fl_Button* o + { Fl_Button* o = new Fl_Button(384, 90, 20, 20); + o->tooltip("bind the image to the widget, so it will be deleted automatically"); + o->type(1); + o->callback((Fl_Callback*)bind_deimage_cb); + o->image(bind_pixmap); + } // Fl_Button* o o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(95, 115, 310, 20, "Alignment:"); diff --git a/fluid/widget_panel.fl b/fluid/widget_panel.fl index 9c306abd2..a88aa09c4 100644 --- a/fluid/widget_panel.fl +++ b/fluid/widget_panel.fl @@ -49,7 +49,7 @@ Function {make_widget_panel()} { xywh {95 40 309 20} labelfont 1 labelsize 11 align 4 } { Fl_Input {} { - callback label_cb selected + callback label_cb tooltip {The label text for the widget. Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 15 textsize 11 resizable } @@ -62,32 +62,44 @@ Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 15 t } Fl_Group {} { label {Image:} - callback propagate_load + callback propagate_load open xywh {95 65 309 20} labelfont 1 labelsize 11 align 4 } { Fl_Input {} { callback image_cb - tooltip {The active image for the widget.} xywh {95 65 240 20} labelfont 1 labelsize 11 textsize 11 resizable + tooltip {The active image for the widget.} xywh {95 65 220 20} labelfont 1 labelsize 11 textsize 11 resizable } Fl_Button {} { label {Browse...} callback image_browse_cb - tooltip {Click to choose the active image.} xywh {334 65 70 20} labelsize 11 + tooltip {Click to choose the active image.} xywh {314 65 70 20} labelsize 11 + } + Fl_Button {} { + callback bind_image_cb selected + tooltip {bind the image to the widget, so it will be deleted automatically} xywh {384 65 20 20} type Toggle + code0 {o->image(bind_pixmap);} + code3 {\#include "pixmaps.h"} } } Fl_Group {} { label {Inactive:} - callback propagate_load + callback propagate_load open xywh {95 90 309 20} labelfont 1 labelsize 11 align 4 } { Fl_Input {} { callback inactive_cb - tooltip {The inactive image for the widget.} xywh {95 90 240 20} labelfont 1 labelsize 11 textsize 11 resizable + tooltip {The inactive image for the widget.} xywh {95 90 220 20} labelfont 1 labelsize 11 textsize 11 resizable } Fl_Button {} { label {Browse...} callback inactive_browse_cb - tooltip {Click to choose the inactive image.} xywh {334 90 70 20} labelsize 11 + tooltip {Click to choose the inactive image.} xywh {314 90 70 20} labelsize 11 + } + Fl_Button {} { + callback bind_deimage_cb + tooltip {bind the image to the widget, so it will be deleted automatically} xywh {384 90 20 20} type Toggle + code0 {o->image(bind_pixmap);} + code3 {\#include "pixmaps.h"} } } Fl_Group {} { diff --git a/fluid/widget_panel.h b/fluid/widget_panel.h index 6325b64c6..35ef3c622 100644 --- a/fluid/widget_panel.h +++ b/fluid/widget_panel.h @@ -32,8 +32,11 @@ extern void labeltype_cb(Fl_Choice*, void*); extern void image_cb(Fl_Input*, void*); #include extern void image_browse_cb(Fl_Button*, void*); +#include "pixmaps.h" +extern void bind_image_cb(Fl_Button*, void*); extern void inactive_cb(Fl_Input*, void*); extern void inactive_browse_cb(Fl_Button*, void*); +extern void bind_deimage_cb(Fl_Button*, void*); extern void align_cb(Fl_Button*, void*); extern void align_text_image_cb(Fl_Choice*, void*); extern void align_position_cb(Fl_Choice*, void*); diff --git a/src/Fl_Widget.cxx b/src/Fl_Widget.cxx index 2289dcf0b..1d1b71dc4 100644 --- a/src/Fl_Widget.cxx +++ b/src/Fl_Widget.cxx @@ -165,6 +165,8 @@ Fl_Widget::~Fl_Widget() { Fl::clear_widget_pointer(this); if (flags() & COPIED_LABEL) free((void *)(label_.value)); if (flags() & COPIED_TOOLTIP) free((void *)(tooltip_)); + image(NULL); + deimage(NULL); // remove from parent group if (parent_) parent_->remove(this); #ifdef DEBUG_DELETE @@ -323,6 +325,44 @@ void Fl_Widget::copy_label(const char *a) { } } +void Fl_Widget::image(Fl_Image* img) { + if (image_bound()) { + if (label_.image && (label_.image != img)) { + label_.image->release(); + } + bind_image(0); + } + label_.image = img; +} + +void Fl_Widget::image(Fl_Image& img) { + image(&img); +} + +void Fl_Widget::bind_image(Fl_Image* img) { + image(img); + bind_image( (img != NULL) ); +} + +void Fl_Widget::deimage(Fl_Image* img) { + if (deimage_bound()) { + if (label_.deimage && (label_.deimage != img)) { + label_.deimage->release(); + } + bind_deimage(0); + } + label_.deimage = img; +} + +void Fl_Widget::deimage(Fl_Image& img) { + deimage(&img); +} + +void Fl_Widget::bind_deimage(Fl_Image* img) { + deimage(img); + bind_deimage( (img != NULL) ); +} + /** Calls the widget callback function with arbitrary arguments. All overloads of do_callback() call this method.