fl_widget_type.cxx
来自「SRI international 发布的OAA框架软件」· CXX 代码 · 共 1,977 行 · 第 1/5 页
CXX
1,977 行
// subtypes:
Fl_Menu_Item *Fl_Widget_Type::subtypes() {return 0;}
void subtype_cb(Fl_Choice* i, void* v) {
if (v == LOAD) {
Fl_Menu_Item* m = current_widget->subtypes();
if (!m) {i->deactivate(); return;}
i->menu(m);
int j;
for (j = 0;; j++) {
if (!m[j].text) {j = 0; break;}
if (m[j].argument() == current_widget->o->type()) break;
}
i->value(j);
i->activate();
i->redraw();
} else {
int n = int(i->mvalue()->argument());
Fl_Menu_Item* m = current_widget->subtypes();
for (Fl_Type *o = Fl_Type::first; o; o = o->next)
if (o->selected && o->is_widget()) {
Fl_Widget_Type* q = (Fl_Widget_Type*)o;
if (q->subtypes()==m) {
q->o->type(n);
q->redraw();
}
}
}
}
////////////////////////////////////////////////////////////////
void propagate_load(Fl_Group* g, void* v) {
if (v == LOAD) {
Fl_Widget*const* a = g->array();
for (int i=g->children(); i--;) {
Fl_Widget* o = *a++;
o->do_callback(o,LOAD);
}
}
}
void set_cb(Fl_Button*, void*) {
haderror = 0;
Fl_Widget*const* a = the_panel->array();
for (int i=the_panel->children(); i--;) {
Fl_Widget* o = *a++;
if (o->changed()) {
o->do_callback();
if (haderror) return;
o->clear_changed();
}
}
}
void ok_cb(Fl_Return_Button* o, void* v) {
set_cb(o,v);
if (!haderror) the_panel->hide();
}
void revert_cb(Fl_Button*, void*) {
// We have to revert all dynamically changing fields:
// but for now only the first label works...
if (numselected == 1) current_widget->label(oldlabel);
propagate_load(the_panel, LOAD);
}
void cancel_cb(Fl_Button* o, void* v) {
revert_cb(o,v);
the_panel->hide();
}
void toggle_overlays(Fl_Widget *,void *); // in Fl_Window_Type.C
void overlay_cb(Fl_Button*o,void *v) {
toggle_overlays(o,v);
}
// update the panel according to current widget set:
static void load_panel() {
if (!the_panel) return;
// find all the Fl_Widget subclasses currently selected:
numselected = 0;
current_widget = 0;
if (Fl_Type::current) {
if (Fl_Type::current->is_widget())
current_widget=(Fl_Widget_Type*)Fl_Type::current;
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
if (o->is_widget() && o->selected) {
numselected++;
if (!current_widget) current_widget = (Fl_Widget_Type*)o;
}
}
}
if (numselected)
propagate_load(the_panel, LOAD);
else
the_panel->hide();
}
// This is called when user double-clicks an item, open or update the panel:
void Fl_Widget_Type::open() {
if (!the_panel) the_panel = make_widget_panel();
load_panel();
if (numselected) the_panel->show();
}
Fl_Type *Fl_Type::current;
extern void redraw_overlays();
extern void redraw_browser();
// Called when ui changes what objects are selected:
// p is selected object, null for all deletions (we must throw away
// old panel in that case, as the object may no longer exist)
void selection_changed(Fl_Type *p) {
// store all changes to the current selected objects:
if (p && the_panel && the_panel->visible()) {
set_cb(0,0);
// if there was an error, we try to leave the selected set unchanged:
if (haderror) {
Fl_Type *q = 0;
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
o->new_selected = o->selected;
if (!q && o->selected) q = o;
}
if (!p || !p->selected) p = q;
Fl_Type::current = p;
redraw_browser();
return;
}
}
// update the selected flags to new set:
Fl_Type *q = 0;
for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
o->selected = o->new_selected;
if (!q && o->selected) q = o;
}
if (!p || !p->selected) p = q;
Fl_Type::current = p;
redraw_overlays();
// load the panel with the new settings:
load_panel();
}
////////////////////////////////////////////////////////////////
// Writing the C code:
// test to see if user named a function, or typed in code:
int is_name(const char *c) {
for (; *c; c++) if (ispunct(*c) && *c!='_' && *c!=':') return 0;
return 1;
}
// Test to see if name() is an array entry. If so, and this is the
// highest number, return name[num+1]. Return null if not the highest
// number or a field or function. Return name() if not an array entry.
const char *array_name(Fl_Widget_Type *o) {
const char *c = o->name();
if (!c) return 0;
const char *d;
for (d = c; *d != '['; d++) {
if (!*d) return c;
if (ispunct(*d) && *d!='_') return 0;
}
int num = atoi(d+1);
int sawthis = 0;
Fl_Type *t = o->prev;
Fl_Type *tp = o;
const char *cn = o->class_name(1);
for (; t && t->class_name(1) == cn; tp = t, t = t->prev);
for (t = tp; t && t->class_name(1) == cn; t = t->next) {
if (t == o) {sawthis=1; continue;}
const char *e = t->name();
if (!e) continue;
if (strncmp(c,e,d-c)) continue;
int n1 = atoi(e+(d-c)+1);
if (n1 > num || n1==num && sawthis) return 0;
}
static char buffer[128];
// MRS: we want strncpy() here...
strncpy(buffer,c,d-c+1);
snprintf(buffer+(d-c+1),sizeof(buffer) - (d-c+1), "%d]",num+1);
return buffer;
}
// Test to see if extra code is a declaration:
int isdeclare(const char *c) {
while (isspace(*c)) c++;
if (*c == '#') return 1;
if (!strncmp(c,"extern",6)) return 1;
if (!strncmp(c,"typedef",7)) return 1;
if (!strncmp(c,"using",5)) return 1;
return 0;
}
void Fl_Widget_Type::write_static() {
const char* t = subclassname(this);
if (!subclass()) write_declare("#include <FL/%s.H>", t);
for (int n=0; n < NUM_EXTRA_CODE; n++) {
if (extra_code(n) && isdeclare(extra_code(n)))
write_declare("%s", extra_code(n));
}
if (callback() && is_name(callback()))
write_declare("extern void %s(%s*, %s);", callback(), t,
user_data_type() ? user_data_type() : "void*");
const char* c = array_name(this);
const char* k = class_name(1);
if (c && !k) {
write_c("\n");
if (!public_) write_c("static ");
else write_h("extern %s *%s;\n", t, c);
if (strchr(c, '[') == NULL) write_c("%s *%s=(%s *)0;\n", t, c, t);
else write_c("%s *%s={(%s *)0};\n", t, c, t);
}
if (callback() && !is_name(callback())) {
// see if 'o' or 'v' used, to prevent unused argument warnings:
int use_o = 0;
int use_v = 0;
const char *d;
for (d = callback(); *d;) {
if (*d == 'o' && !is_id(d[1])) use_o = 1;
if (*d == 'v' && !is_id(d[1])) use_v = 1;
do d++; while (is_id(*d));
while (*d && !is_id(*d)) d++;
}
const char* cn = callback_name();
if (k) {
write_c("\ninline void %s::%s_i(%s*", k, cn, t);
} else {
write_c("\nstatic void %s(%s*", cn, t);
}
if (use_o) write_c(" o");
const char* ut = user_data_type() ? user_data_type() : "void*";
write_c(", %s", ut);
if (use_v) write_c(" v");
write_c(") {\n %s", callback());
if (*(d-1) != ';') {
const char *p = strrchr(callback(), '\n');
if (p) p ++;
else p = callback();
// Only add trailing semicolon if the last line is not a preprocessor
// statement...
if (*p != '#' && *p) write_c(";");
}
write_c("\n}\n");
if (k) {
write_c("void %s::%s(%s* o, %s v) {\n", k, cn, t, ut);
write_c(" ((%s*)(o->", k);
for (Fl_Type* p = parent; p->is_widget(); p = p->parent)
write_c("parent()->");
write_c("user_data()))->%s_i(o,v);\n}\n", cn);
}
}
if (image) {
if (image->written != write_number) {
image->write_static();
image->written = write_number;
}
}
if (inactive) {
if (inactive->written != write_number) {
inactive->write_static();
inactive->written = write_number;
}
}
}
const char *Fl_Type::callback_name() {
if (is_name(callback())) return callback();
return unique_id(this, "cb", name(), label());
}
extern int varused_test, varused;
void Fl_Widget_Type::write_code1() {
const char* t = subclassname(this);
const char *c = array_name(this);
if (c) {
if (class_name(1)) {
write_public(public_);
write_h(" %s *%s;\n", t, c);
}
}
if (class_name(1) && callback() && !is_name(callback())) {
const char* cn = callback_name();
const char* ut = user_data_type() ? user_data_type() : "void*";
write_public(0);
write_h(" inline void %s_i(%s*, %s);\n", cn, t, ut);
write_h(" static void %s(%s*, %s);\n", cn, t, ut);
}
// figure out if local varaible will be used (prevent compiler warnings):
if (is_parent())
varused = 1;
else {
varused_test = 1; varused = 0;
write_widget_code();
varused_test = 0;
for (int n=0; n < NUM_EXTRA_CODE; n++)
if (extra_code(n) && !isdeclare(extra_code(n))) varused = 1;
}
write_c(indent());
if (varused) write_c("{ %s* o = ", t);
if (name()) write_c("%s = ", name());
if (is_window()) {
// Handle special case where user is faking a Fl_Group type as a window,
// there is no 2-argument constructor in that case:
if (!strstr(t, "Window"))
write_c("new %s(0, 0, %d, %d", t, o->w(), o->h());
else
write_c("new %s(%d, %d", t, o->w(), o->h());
} else {
write_c("new %s(%d, %d, %d, %d", t, o->x(), o->y(), o->w(), o->h());
}
if (label() && *label()) {
write_c(", ");
switch (i18n_type) {
case 0 : /* None */
write_cstring(label());
break;
case 1 : /* GNU gettext */
write_c("%s(", i18n_function);
write_cstring(label());
write_c(")");
break;
case 2 : /* POSIX catgets */
write_c("catgets(%s,%s,%d,", i18n_file[0] ? i18n_file : "_catalog",
i18n_set, msgnum());
write_cstring(label());
write_c(")");
break;
}
}
write_c(");\n");
indentation += 2;
if (is_window()) write_c("%sw = o;\n",indent());
if (varused) write_widget_code();
}
// this is split from write_code1() for Fl_Window_Type:
void Fl_Widget_Type::write_widget_code() {
Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
if (tooltip() && *tooltip()) {
write_c("%so->tooltip(",indent());
switch (i18n_type) {
case 0 : /* None */
write_cstring(tooltip());
break;
case 1 : /* GNU gettext */
write_c("%s(", i18n_function);
write_cstring(tooltip());
write_c(")");
break;
case 2 : /* POSIX catgets */
write_c("catgets(%s,%s,%d,", i18n_file[0] ? i18n_file : "_catalog",
i18n_set, msgnum() + 1);
write_cstring(tooltip());
write_c(")");
break;
}
write_c(");\n");
}
if (o->type() != tplate->type() && !is_window())
write_c("%so->type(%d);\n", indent(), o->type());
if (o->box() != tplate->box() || subclass())
write_c("%so->box(FL_%s);\n", indent(), boxname(o->box()));
if (is_button()) {
Fl_Button* b = (Fl_Button*)o;
if (b->down_box()) write_c("%so->down_box(FL_%s);\n", indent(),
boxname(b->down_box()));
if (b->value()) write_c("%so->value(1);\n", indent());
if (b->shortcut())
write_c("%so->shortcut(0x%x);\n", indent(), b->shortcut());
}
if (is_menu_button()) {
Fl_Menu_* b = (Fl_Menu_*)o;
if (b->down_box()) write_c("%so->down_box(FL_%s);\n", indent(),
boxname(b->down_box()));
}
if (o->color() != tplate->color() || subclass())
write_c("%so->color(%d);\n", indent(), o->color());
if (o->selection_color() != tplate->selection_color() || subclass())
write_c("%so->selection_color(%d);\n", indent(), o->selection_color());
if (image) image->write_code();
if (inactive) inactive->write_code(1);
if (o->labeltype() != tplate->labeltype() || subclass())
write_c("%so->labeltype(FL_%s);\n", indent(),
item_name(labeltypemenu, o->labeltype()));
if (o->labelfont() != tplate->labelfont() || subclass())
write_c("%so->labelfont(%d);\n", indent(), o->labelfont());
if (o->labelsize() != tplate->labelsize() || subclass())
write_c("%so->labelsize(%d);\n", indent(), o->labelsize());
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?