diff options
Diffstat (limited to 'FL/Fl_Widget_Tracker.H')
| -rw-r--r-- | FL/Fl_Widget_Tracker.H | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/FL/Fl_Widget_Tracker.H b/FL/Fl_Widget_Tracker.H new file mode 100644 index 000000000..d0aad86c0 --- /dev/null +++ b/FL/Fl_Widget_Tracker.H @@ -0,0 +1,144 @@ +// +// Widget Tracker header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 2025 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +/** \file FL/Fl_Widget_Tracker.H + \brief Track widget deletion. +*/ + +#ifndef Fl_Widget_Tracker_H +#define Fl_Widget_Tracker_H + +#include <FL/fl_config.h> // build configuration +#include <FL/Fl_Export.H> + +class Fl_Widget; + + +/** + This class should be used to control safe widget deletion. + + You can use an Fl_Widget_Tracker object to watch another widget, if you + need to know whether this widget has been deleted during a callback. + + This simplifies the use of the "safe widget deletion" methods + Fl::watch_widget_pointer() and Fl::release_widget_pointer() and + makes their use more reliable, because the destructor automatically + releases the widget pointer from the widget watch list. + + Fl_Widget_Tracker is intended to be used as an automatic (local/stack) + variable, such that its destructor is called when the object's + scope is left. This ensures that no stale widget pointers are + left in the widget watch list (see example below). + + You can also create Fl_Widget_Tracker objects with \c new, but then it + is your responsibility to delete the object (and thus remove the + widget pointer from the watch list) when it is no longer needed. + + Example: + + \code + int MyClass::handle (int event) { + + if (...) { + Fl_Widget_Tracker wp(this); // watch myself + do_callback(); // call the callback + + if (wp.deleted()) return 1; // exit, if deleted + + // Now we are sure that the widget has not been deleted, + // and it is safe to access the widget: + + box(FL_FLAT_BOX); + color(FL_WHITE); + redraw(); + } + } + \endcode + +*/ +class FL_EXPORT Fl_Widget_Tracker { + + Fl_Widget* wp_; + +public: + + Fl_Widget_Tracker(Fl_Widget *wi); + ~Fl_Widget_Tracker(); + + /** + Returns a pointer to the watched widget. + \return nullptr if the widget was deleted. + */ + Fl_Widget *widget() { return wp_; } + + /** + Check if the widget was deleted since the tracker was created. + \return 1 if the watched widget has been deleted, otherwise 0 + */ + int deleted() {return wp_ == 0;} + + /** + Check if the widget exists and was not deleted since the tracker was created. + \return 1 if the watched widget exists, otherwise 0 + */ + int exists() { return wp_ != 0; } + +}; + +namespace Fl { + +/** \defgroup fl_del_widget Safe widget deletion support functions + + These functions, declared in <FL/Fl.H>, support deletion of widgets inside callbacks. + + Fl::delete_widget() should be called when deleting widgets + or complete widget trees (Fl_Group, Fl_Window, ...) inside + callbacks. + + The other functions are intended for internal use. The preferred + way to use them is by using the helper class Fl_Widget_Tracker. + + The following is to show how it works ... + + There are three groups of related methods: + + -# scheduled widget deletion + - Fl::delete_widget() schedules widgets for deletion + - Fl::do_widget_deletion() deletes all scheduled widgets + -# widget watch list ("smart pointers") + - Fl::watch_widget_pointer() adds a widget pointer to the watch list + - Fl::release_widget_pointer() removes a widget pointer from the watch list + - Fl::clear_widget_pointer() clears a widget pointer \e in the watch list + -# the class Fl_Widget_Tracker: + - the constructor calls Fl::watch_widget_pointer() + - the destructor calls Fl::release_widget_pointer() + - the access methods can be used to test, if a widget has been deleted + \see Fl_Widget_Tracker. + + @{ */ + +// Widget deletion: +FL_EXPORT extern void delete_widget(Fl_Widget *w); +FL_EXPORT extern void do_widget_deletion(); +FL_EXPORT extern void watch_widget_pointer(Fl_Widget *&w); +FL_EXPORT extern void release_widget_pointer(Fl_Widget *&w); +FL_EXPORT extern void clear_widget_pointer(Fl_Widget const *w); + +/** @} */ + +} // namespace Fl + +#endif // !Fl_Widget_Tracker_H |
