summaryrefslogtreecommitdiff
path: root/FL/Fl_Widget_Tracker.H
blob: 0af6e0fcdf5020a98168b8a58a9b9b4da5d97c50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//
// 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();

private:
  Fl_Widget_Tracker(const Fl_Widget_Tracker&);
  Fl_Widget_Tracker& operator=(const Fl_Widget_Tracker&);

public:

  /**
   Clear the widget pointer.
   */
  void clear() { wp_ = 0; }

  /**
    Returns a pointer to the watched widget.
    \return 0 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; }

};

#endif // !Fl_Widget_Tracker_H