mirror of https://github.com/fltk/fltk
Improve docs of Fl_Widget::callback() and do_callback().
Clarify that all variants of do_callback() call clear_changed() after the callback and that 'long Fl_Widget::argument()' may truncate the user_data value on some (particularly Windows 64-bit) platforms. Some code has been reformatted and refactored with better variable names, but there are no effective code changes. Obsolete, inactive code was removed. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12345 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
db1f29fdb5
commit
a8c4f77d50
106
FL/Fl_Widget.H
106
FL/Fl_Widget.H
|
@ -549,26 +549,29 @@ public:
|
|||
\param[in] cb new callback
|
||||
\param[in] p user data
|
||||
*/
|
||||
void callback(Fl_Callback* cb, void* p) {callback_=cb; user_data_=p;}
|
||||
void callback(Fl_Callback* cb, void* p) {callback_ = cb; user_data_ = p;}
|
||||
|
||||
/** Sets the current callback function for the widget.
|
||||
Each widget has a single callback.
|
||||
\param[in] cb new callback
|
||||
*/
|
||||
void callback(Fl_Callback* cb) {callback_=cb;}
|
||||
void callback(Fl_Callback* cb) {callback_ = cb;}
|
||||
|
||||
/** Sets the current callback function for the widget.
|
||||
Each widget has a single callback.
|
||||
\param[in] cb new callback
|
||||
*/
|
||||
void callback(Fl_Callback0*cb) {callback_=(Fl_Callback*)cb;}
|
||||
void callback(Fl_Callback0* cb) {callback_ = (Fl_Callback*)cb;}
|
||||
|
||||
/** Sets the current callback function for the widget.
|
||||
Each widget has a single callback.
|
||||
\param[in] cb new callback
|
||||
\param[in] p user data
|
||||
*/
|
||||
void callback(Fl_Callback1*cb, long p=0) {callback_=(Fl_Callback*)cb; user_data_=(void*)(fl_intptr_t)p;}
|
||||
void callback(Fl_Callback1* cb, long p = 0) {
|
||||
callback_ = (Fl_Callback*)cb;
|
||||
user_data_ = (void*)(fl_intptr_t)p;
|
||||
}
|
||||
|
||||
/** Gets the user data for this widget.
|
||||
Gets the current user data (void *) argument that is passed to the callback function.
|
||||
|
@ -583,14 +586,24 @@ public:
|
|||
void user_data(void* v) {user_data_ = v;}
|
||||
|
||||
/** Gets the current user data (long) argument that is passed to the callback function.
|
||||
\todo The user data value must be implemented using \em intptr_t or similar
|
||||
to avoid 64-bit machine incompatibilities.
|
||||
*/
|
||||
|
||||
\note On platforms with <tt>sizeof(long) \< sizeof(void*)</tt>, particularly
|
||||
on Windows 64-bit platforms, this method can truncate stored addresses
|
||||
\p (void*) to the size of a \p long value. Use with care and only
|
||||
if you are sure that the stored user_data value fits in a \p long
|
||||
value because it was stored with argument(long) or another method
|
||||
using only \p long values. You may want to use user_data() instead.
|
||||
|
||||
\see user_data()
|
||||
|
||||
\todo [Internal] The user_data value must be implemented using
|
||||
\p fl_intptr_t or similar to avoid 64-bit platform incompatibilities.
|
||||
*/
|
||||
long argument() const {return (long)(fl_intptr_t)user_data_;}
|
||||
|
||||
/** Sets the current user data (long) argument that is passed to the callback function.
|
||||
\todo The user data value must be implemented using \em intptr_t or similar
|
||||
to avoid 64-bit machine incompatibilities.
|
||||
|
||||
\see argument()
|
||||
*/
|
||||
void argument(long v) {user_data_ = (void*)(fl_intptr_t)v;}
|
||||
|
||||
|
@ -747,22 +760,25 @@ public:
|
|||
*/
|
||||
unsigned int takesevents() const {return !(flags_&(INACTIVE|INVISIBLE|OUTPUT));}
|
||||
|
||||
/**
|
||||
/**
|
||||
Checks if the widget value changed since the last callback.
|
||||
|
||||
"Changed" is a flag that is turned on when the user changes the value
|
||||
stored in the widget. This is only used by subclasses of Fl_Widget that
|
||||
store values, but is in the base class so it is easier to scan all the
|
||||
widgets in a panel and do_callback() on the changed ones in response
|
||||
"Changed" is a flag that is turned on when the user changes the value
|
||||
stored in the widget. This is only used by subclasses of Fl_Widget that
|
||||
store values, but is in the base class so it is easier to scan all the
|
||||
widgets in a panel and do_callback() on the changed ones in response
|
||||
to an "OK" button.
|
||||
|
||||
Most widgets turn this flag off when they do the callback, and when
|
||||
Most widgets turn this flag off when they do the callback, and when
|
||||
the program sets the stored value.
|
||||
|
||||
\retval 0 if the value did not change
|
||||
\see set_changed(), clear_changed()
|
||||
\note do_callback() turns this flag off after the callback.
|
||||
|
||||
\retval 0 if the value did not change
|
||||
\see set_changed(), clear_changed()
|
||||
\see do_callback(Fl_Widget *widget, void *data)
|
||||
*/
|
||||
unsigned int changed() const {return flags_&CHANGED;}
|
||||
unsigned int changed() const {return flags_ & CHANGED;}
|
||||
|
||||
/** Marks the value of the widget as changed.
|
||||
\see changed(), clear_changed()
|
||||
|
@ -819,42 +835,54 @@ public:
|
|||
\retval 0 if this widget has no visible focus.
|
||||
\see visible_focus(int), set_visible_focus(), clear_visible_focus()
|
||||
*/
|
||||
unsigned int visible_focus() { return flags_ & VISIBLE_FOCUS; }
|
||||
unsigned int visible_focus() { return flags_ & VISIBLE_FOCUS; }
|
||||
|
||||
/** The default callback for all widgets that don't set a callback.
|
||||
|
||||
This callback function puts a pointer to the widget on the queue
|
||||
returned by Fl::readqueue().
|
||||
returned by Fl::readqueue(). This is the default for all widgets
|
||||
if you don't set a callback.
|
||||
|
||||
You can avoid the overhead of this default handling if you set the
|
||||
callback to \p NULL explicitly.
|
||||
|
||||
Relying on the default callback and reading the callback queue with
|
||||
Fl::readqueue() is not recommended. If you need a callback, you should
|
||||
set one with Fl_Widget::callback(Fl_Callback *cb, void *data)
|
||||
or one of its variants.
|
||||
|
||||
\param[in] cb the widget given to the callback
|
||||
\param[in] d user data associated with that callback
|
||||
\param[in] widget the Fl_Widget given to the callback
|
||||
\param[in] data user data associated with that callback
|
||||
|
||||
\see callback(), do_callback(), Fl::readqueue()
|
||||
\see callback(), Fl::readqueue()
|
||||
\see do_callback(Fl_Widget *widget, void *data)
|
||||
*/
|
||||
static void default_callback(Fl_Widget *cb, void *d);
|
||||
static void default_callback(Fl_Widget *widget, void *data);
|
||||
|
||||
/** Calls the widget callback.
|
||||
Causes a widget to invoke its callback function with default arguments.
|
||||
\see callback()
|
||||
*/
|
||||
void do_callback() {do_callback(this,user_data_);}
|
||||
/** Calls the widget callback function with default arguments.
|
||||
|
||||
/** Calls the widget callback.
|
||||
Causes a widget to invoke its callback function with arbitrary arguments.
|
||||
\param[in] o call the callback with \p o as the widget argument
|
||||
\param[in] arg call the callback with \p arg as the user data argument
|
||||
\see callback()
|
||||
*/
|
||||
void do_callback(Fl_Widget* o,long arg) {do_callback(o,(void*)(fl_intptr_t)arg);}
|
||||
This is the same as calling
|
||||
\code
|
||||
do_callback(this, user_data());
|
||||
\endcode
|
||||
\see callback()
|
||||
\see do_callback(Fl_Widget *widget, void *data)
|
||||
*/
|
||||
void do_callback() {do_callback(this, user_data_);}
|
||||
|
||||
/** Calls the widget callback function with arbitrary arguments.
|
||||
\param[in] widget call the callback with \p widget as the first argument
|
||||
\param[in] arg call the callback with \p arg as the user data (second) argument
|
||||
\see callback()
|
||||
\see do_callback(Fl_Widget *widget, void *data)
|
||||
*/
|
||||
void do_callback(Fl_Widget *widget, long arg) {
|
||||
do_callback(widget, (void*)(fl_intptr_t)arg);
|
||||
}
|
||||
|
||||
// Causes a widget to invoke its callback function with arbitrary arguments.
|
||||
// Documentation and implementation in Fl_Widget.cxx
|
||||
void do_callback(Fl_Widget* o,void* arg=0);
|
||||
void do_callback(Fl_Widget *widget, void *arg = 0);
|
||||
|
||||
/* Internal use only. */
|
||||
int test_shortcut();
|
||||
|
@ -879,7 +907,7 @@ public:
|
|||
\param[in] wgt the possible parent widget.
|
||||
\see contains()
|
||||
*/
|
||||
int inside(const Fl_Widget* wgt) const {return wgt ? wgt->contains(this) : 0;}
|
||||
int inside(const Fl_Widget *wgt) const {return wgt ? wgt->contains(this) : 0;}
|
||||
|
||||
/** Schedules the drawing of the widget.
|
||||
Marks the widget as needing its draw() routine called.
|
||||
|
@ -957,7 +985,7 @@ public:
|
|||
void my_callback (Fl_Widget *w, void *) {
|
||||
Fl_Group *g = w->as_group();
|
||||
if (g)
|
||||
printf ("This group has %d children\n",g->children());
|
||||
printf ("This group has %d children\n", g->children());
|
||||
else
|
||||
printf ("This widget is not a group!\n");
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// Base widget class for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2017 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
|
||||
|
@ -36,17 +36,8 @@ const int QUEUE_SIZE = 20;
|
|||
static Fl_Widget *obj_queue[QUEUE_SIZE];
|
||||
static int obj_head, obj_tail;
|
||||
|
||||
void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) {
|
||||
#if 0
|
||||
// This is necessary for strict forms compatibility but is confusing.
|
||||
// Use the parent's callback if this widget does not have one.
|
||||
for (Fl_Widget *p = o->parent(); p; p = p->parent())
|
||||
if (p->callback() != default_callback) {
|
||||
p->do_callback(o,v);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
obj_queue[obj_head++] = o;
|
||||
void Fl_Widget::default_callback(Fl_Widget *widget, void * /*v*/) {
|
||||
obj_queue[obj_head++] = widget;
|
||||
if (obj_head >= QUEUE_SIZE) obj_head = 0;
|
||||
if (obj_head == obj_tail) {
|
||||
obj_tail++;
|
||||
|
@ -75,9 +66,9 @@ void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) {
|
|||
*/
|
||||
Fl_Widget *Fl::readqueue() {
|
||||
if (obj_tail==obj_head) return 0;
|
||||
Fl_Widget *o = obj_queue[obj_tail++];
|
||||
Fl_Widget *widget = obj_queue[obj_tail++];
|
||||
if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
|
||||
return o;
|
||||
return widget;
|
||||
}
|
||||
/*
|
||||
This static internal function removes all pending callbacks for a
|
||||
|
@ -89,7 +80,7 @@ Fl_Widget *Fl::readqueue() {
|
|||
static void cleanup_readqueue(Fl_Widget *w) {
|
||||
|
||||
if (obj_tail==obj_head) return;
|
||||
|
||||
|
||||
// Read the entire queue and copy over all valid entries.
|
||||
// The new head will be determined after the last copied entry.
|
||||
|
||||
|
@ -192,9 +183,9 @@ Fl_Widget::~Fl_Widget() {
|
|||
if (callback_ == default_callback) cleanup_readqueue(this);
|
||||
}
|
||||
|
||||
/** Draws a focus box for the widget at the given position and size */
|
||||
void
|
||||
Fl_Widget::draw_focus(Fl_Boxtype B, int X, int Y, int W, int H) const {
|
||||
/** Draws a focus box for the widget at the given position and size. */
|
||||
|
||||
void Fl_Widget::draw_focus(Fl_Boxtype B, int X, int Y, int W, int H) const {
|
||||
if (!Fl::visible_focus()) return;
|
||||
switch (B) {
|
||||
case FL_DOWN_BOX:
|
||||
|
@ -284,8 +275,7 @@ int Fl_Widget::contains(const Fl_Widget *o) const {
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
Fl_Widget::label(const char *a) {
|
||||
void Fl_Widget::label(const char *a) {
|
||||
if (flags() & COPIED_LABEL) {
|
||||
// reassigning a copied label remains the same copied label
|
||||
if (label_.value == a)
|
||||
|
@ -298,8 +288,7 @@ Fl_Widget::label(const char *a) {
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
Fl_Widget::copy_label(const char *a) {
|
||||
void Fl_Widget::copy_label(const char *a) {
|
||||
// reassigning a copied label remains the same copied label
|
||||
if ((flags() & COPIED_LABEL) && (label_.value == a))
|
||||
return;
|
||||
|
@ -311,19 +300,33 @@ Fl_Widget::copy_label(const char *a) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Calls the widget callback.
|
||||
/** Calls the widget callback function with arbitrary arguments.
|
||||
|
||||
Causes a widget to invoke its callback function with arbitrary arguments.
|
||||
All overloads of do_callback() call this method.
|
||||
It does nothing if the widget's callback() is NULL.
|
||||
It clears the widget's \e changed flag \b after the callback was
|
||||
called unless the callback is the default callback. Hence it is not
|
||||
necessary to call clear_changed() after calling do_callback()
|
||||
in your own widget's handle() method.
|
||||
|
||||
\param[in] o call the callback with \p o as the widget argument
|
||||
\param[in] arg use \p arg as the user data argument
|
||||
\note It is legal to delete the widget in the callback (i.e. in user code),
|
||||
but you must not access the widget in the handle() method after
|
||||
calling do_callback() if the widget was deleted in the callback.
|
||||
We recommend to use Fl_Widget_Tracker to check whether the widget
|
||||
was deleted in the callback.
|
||||
|
||||
\param[in] widget call the callback with \p widget as the first argument
|
||||
\param[in] arg use \p arg as the user data (second) argument
|
||||
|
||||
\see default_callback()
|
||||
\see callback()
|
||||
\see class Fl_Widget_Tracker
|
||||
*/
|
||||
void
|
||||
Fl_Widget::do_callback(Fl_Widget* o,void* arg) {
|
||||
|
||||
void Fl_Widget::do_callback(Fl_Widget *widget, void *arg) {
|
||||
if (!callback_) return;
|
||||
Fl_Widget_Tracker wp(this);
|
||||
callback_(o,arg);
|
||||
callback_(widget, arg);
|
||||
if (wp.deleted()) return;
|
||||
if (callback_ != default_callback)
|
||||
clear_changed();
|
||||
|
|
Loading…
Reference in New Issue