diff options
| author | Michael R Sweet <michael.r.sweet@gmail.com> | 1998-10-06 18:21:25 +0000 |
|---|---|---|
| committer | Michael R Sweet <michael.r.sweet@gmail.com> | 1998-10-06 18:21:25 +0000 |
| commit | f9039b2ae21988783feae9b362818e7923e82d14 (patch) | |
| tree | 6d6fe3679d73448758f9794e7d4d4f6b22a4adad /src/Fl_Widget.cxx | |
| parent | 67e89232f9ba067825a158734a09e0fa21aacbe3 (diff) | |
Initial revision
git-svn-id: file:///fltk/svn/fltk/trunk@2 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Widget.cxx')
| -rw-r--r-- | src/Fl_Widget.cxx | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/Fl_Widget.cxx b/src/Fl_Widget.cxx new file mode 100644 index 000000000..65fda468c --- /dev/null +++ b/src/Fl_Widget.cxx @@ -0,0 +1,164 @@ +// Fl_Widget.C + +// fltk (Fast Light Tool Kit) version 0.99 +// Copyright (C) 1998 Bill Spitzak + +#include <FL/Fl.H> +#include <FL/Fl_Widget.H> +#include <FL/Fl_Group.H> + +//////////////////////////////////////////////////////////////// +// for compatability with Forms, all widgets without callbacks are +// inserted into a "queue" when they are activated, and the forms +// compatability interaction functions (fl_do_events, etc) will +// read one widget at a time from this queue and return it: + +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 compatability 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; + if (obj_head >= QUEUE_SIZE) obj_head = 0; + if (obj_head == obj_tail) { + obj_tail++; + if (obj_tail >= QUEUE_SIZE) obj_tail = 0; + } +} + +Fl_Widget *Fl::readqueue() { + if (obj_tail==obj_head) return 0; + Fl_Widget *o = obj_queue[obj_tail++]; + if (obj_tail >= QUEUE_SIZE) obj_tail = 0; + return o; +} + +//////////////////////////////////////////////////////////////// + +int Fl_Widget::handle(int) {return 0;} + +Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) { + + x_ = X; y_ = Y; w_ = W; h_ = H; + + label_.value = L; + label_.type = FL_NORMAL_LABEL; + label_.font = FL_HELVETICA; + label_.size = FL_NORMAL_SIZE; + label_.color = FL_BLACK; + callback_ = default_callback; + user_data_ = 0; + type_ = 0; + flags_ = 0; + damage_ = 0; + box_ = FL_NO_BOX; + color_ = FL_GRAY; + color2_ = FL_GRAY; + align_ = FL_ALIGN_CENTER; + when_ = FL_WHEN_RELEASE; + + parent_ = 0; + if (Fl_Group::current()) Fl_Group::current()->add(this); +} + +void Fl_Widget::resize(int X, int Y, int W, int H) { + x_ = X; y_ = Y; w_ = W; h_ = H; +} + +// this is useful for parent widgets to call to resize children: +int Fl_Widget::damage_resize(int X, int Y, int W, int H) { + if (x() == X && y() == Y && w() == W && h() == H) return 0; + resize(X, Y, W, H); + redraw(); + return 1; +} + +int Fl_Widget::take_focus() { + if (!takesevents()) return 0; + if (!handle(FL_FOCUS)) return 0; // see if it wants it + if (contains(Fl::focus())) return 1; // it called Fl::focus for us + Fl::focus(this); + return 1; +} + +extern void fl_throw_focus(Fl_Widget*); // in Fl_x.C + +// Destruction does not remove from any parent group! And groups when +// destroyed destroy all their children. This is convienent and fast. +// However, it is only legal to destroy a "root" such as an Fl_Window, +// and automatic destructors may be called. +Fl_Widget::~Fl_Widget() { + parent_ = 0; // kludge to prevent ~Fl_Group from destroying again + fl_throw_focus(this); +} + +// redraw this, plus redraw opaque object if there is an outside label +static void redraw_label(Fl_Widget* w) { + w->redraw(); + if (w->label() && (w->align()&15) && !(w->align() & FL_ALIGN_INSIDE)) { + for (Fl_Widget *p = w->parent(); p; p = p->parent()) + if (p->box() || !p->parent()) {p->redraw(); break;} + } +} + +void Fl_Widget::activate() { + if (active()) return; + clear_flag(INACTIVE); + handle(FL_ACTIVATE); + if (inside(Fl::focus())) Fl::focus()->take_focus(); + redraw_label(this); +} + +void Fl_Widget::deactivate() { + if (!active()) return; + set_flag(INACTIVE); + handle(FL_DEACTIVATE); + fl_throw_focus(this); + redraw_label(this); +} + +int Fl_Widget::active_r() const { + for (const Fl_Widget* o = this; o; o = o->parent()) + if (!o->active()) return 0; + return 1; +} + +void Fl_Widget::show() { + if (visible()) return; + clear_flag(INVISIBLE); + handle(FL_SHOW); + if (inside(Fl::focus())) Fl::focus()->take_focus(); + redraw_label(this); +} + +void Fl_Widget::hide() { + if (!visible()) return; + set_flag(INVISIBLE); + handle(FL_HIDE); + fl_throw_focus(this); + for (Fl_Widget *p = parent(); p; p = p->parent()) + if (p->box() || !p->parent()) {p->redraw(); break;} +} + +int Fl_Widget::visible_r() const { + for (const Fl_Widget* o = this; o; o = o->parent()) + if (!o->visible()) return 0; + return 1; +} + +// return true if widget is inside (or equal to) this: +// Returns false for null widgets. +int Fl_Widget::contains(const Fl_Widget *o) const { + for (; o; o = o->parent_) if (o == this) return 1; + return 0; +} |
