1998-10-20 00:46:58 +04:00
|
|
|
//
|
|
|
|
// "$Id"
|
|
|
|
//
|
|
|
|
// Base widget class for the Fast Light Tool Kit (FLTK).
|
|
|
|
//
|
|
|
|
// Copyright 1998 by Bill Spitzak and others.
|
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Library General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Library General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Library General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
// USA.
|
|
|
|
//
|
|
|
|
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
|
|
|
//
|
1998-10-06 22:21:25 +04:00
|
|
|
|
|
|
|
#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;
|
|
|
|
}
|
1998-10-20 00:46:58 +04:00
|
|
|
|
|
|
|
//
|
|
|
|
// End of "$Id: Fl_Widget.cxx,v 1.2 1998/10/19 20:46:08 mike Exp $".
|
|
|
|
//
|