// // Widget type code for the Fast Light Tool Kit (FLTK). // // Copyright 1998-2021 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 // #include "Fl_Widget_Type.h" #include "fluid.h" #include "Fl_Window_Type.h" #include "Fl_Group_Type.h" #include "Fl_Menu_Type.h" #include "Fl_Function_Type.h" #include "file.h" #include "code.h" #include "Fluid_Image.h" #include "alignment_panel.h" #include "widget_panel.h" #include "undo.h" #include #include #include #include #include #include #include #include #include #include "../src/flstring.h" #include #include // Make an Fl_Widget_Type subclass instance. // It figures out the automatic size and parent of the new widget, // creates the Fl_Widget (by calling the virtual function _make), // adds it to the Fl_Widget hierarchy, creates a new Fl_Type // instance, sets the widget pointers, and makes all the display // update correctly... int Fl_Widget_Type::default_size = FL_NORMAL_SIZE; int Fl_Widget_Type::is_widget() const {return 1;} int Fl_Widget_Type::is_public() const {return public_;} const char* subclassname(Fl_Type* l) { if (l->is_widget()) { Fl_Widget_Type* p = (Fl_Widget_Type*)l; const char* c = p->subclass(); if (c) return c; if (l->is_class()) return "Fl_Group"; if (p->o->type() == FL_WINDOW+1) return "Fl_Double_Window"; if (strcmp(p->type_name(), "Fl_Input") == 0) { if (p->o->type() == FL_FLOAT_INPUT) return "Fl_Float_Input"; if (p->o->type() == FL_INT_INPUT) return "Fl_Int_Input"; } } return l->type_name(); } // Return the ideal widget size... void Fl_Widget_Type::ideal_size(int &w, int &h) { h = o->labelsize(); o->measure_label(w, h); w += Fl::box_dw(o->box()); h += Fl::box_dh(o->box()); if (w < 15) w = 15; if (h < 15) h = 15; } // Return the ideal widget spacing... void Fl_Widget_Type::ideal_spacing(int &x, int &y) { if (o->labelsize() < 10) x = y = 0; else if (o->labelsize() < 14) x = y = 5; else x = y = 10; } /** Make a new Widget node. \param[in] strategy is kAddAsLastChild or kAddAfterCurrent \return new node */ Fl_Type *Fl_Widget_Type::make(Strategy strategy) { // Find the current widget, or widget to copy: Fl_Type *qq = Fl_Type::current; while (qq && (!qq->is_widget() || qq->is_menu_item())) qq = qq->parent; if (!qq) { fl_message("Please select a widget"); return 0; } Fl_Widget_Type* q = (Fl_Widget_Type*)qq; // find the parent widget: Fl_Widget_Type* p = q; if ((force_parent || !p->is_group()) && p->parent && p->parent->is_widget()) p = (Fl_Widget_Type*)(p->parent); force_parent = 0; // Figure out a border between widget and window: int B = p->o->w()/2; if (p->o->h()/2 < B) B = p->o->h()/2; if (B>25) B = 25; int ULX,ULY; // parent's origin in window if (!p->is_window()) { // if it is a group, add corner ULX = p->o->x(); ULY = p->o->y(); } else { ULX = ULY = 0; } // Figure out a position and size for the widget int X,Y,W,H; if (is_group()) { // fill the parent with the widget X = ULX+B; W = p->o->w()-B; Y = ULY+B; H = p->o->h()-B; } else if (q != p) { // copy position and size of current widget W = q->o->w(); H = q->o->h(); X = q->o->x()+W; Y = q->o->y(); if (X+W > ULX+p->o->w()) { X = q->o->x(); Y = q->o->y()+H; if (Y+H > ULY+p->o->h()) Y = ULY+B; } } else { // just make it small and square... X = ULX+B; Y = ULY+B; W = H = B; } // satisfy the grid requirements (otherwise it edits really strangely): if (gridx>1) { X = (X/gridx)*gridx; W = ((W-1)/gridx+1)*gridx; } if (gridy>1) { Y = (Y/gridy)*gridy; H = ((H-1)/gridy+1)*gridy; } // Construct the Fl_Type: Fl_Widget_Type *t = _make(); if (!o) o = widget(0,0,100,100); // create template widget t->factory = this; // Construct the Fl_Widget: t->o = widget(X,Y,W,H); if (reading_file) t->o->label(0); else if (t->o->label()) t->label(t->o->label()); // allow editing t->o->user_data((void*)t); // Put it in the parent: // ((Fl_Group *)(p->o))->add(t->o); (done by Fl_Type::add()) // add to browser: t->add(p, strategy); t->redraw(); return t; } void Fl_Widget_Type::setimage(Fluid_Image *i) { if (i == image || is_window()) return; if (image) image->decrement(); if (i) i->increment(); image = i; if (i) i->image(o); else o->image(0); redraw(); } void Fl_Widget_Type::setinactive(Fluid_Image *i) { if (i == inactive || is_window()) return; if (inactive) inactive->decrement(); if (i) i->increment(); inactive = i; if (i) i->deimage(o); else o->deimage(0); redraw(); } void Fl_Widget_Type::setlabel(const char *n) { o->label(n); redraw(); } Fl_Widget_Type::Fl_Widget_Type() { for (int n=0; nwindow(); delete o; if (win) win->redraw(); } if (subclass_) free((void*)subclass_); if (tooltip_) free((void*)tooltip_); if (image_name_) { free((void*)image_name_); if (image) image->decrement(); } if (inactive_name_) { free((void*)inactive_name_); if (inactive) inactive->decrement(); } for (int n=0; ntooltip(n); } void Fl_Widget_Type::image_name(const char *n) { setimage(Fluid_Image::find(n)); storestring(n,image_name_); } void Fl_Widget_Type::inactive_name(const char *n) { setinactive(Fluid_Image::find(n)); storestring(n,inactive_name_); } void Fl_Widget_Type::redraw() { Fl_Type *t = this; if (is_menu_item()) { // find the menu button that parents this menu: do t = t->parent; while (t && t->is_menu_item()); // kludge to cause build_menu to be called again: if (t) t->add_child(0, 0); } else { while (t->parent && t->parent->is_widget()) t = t->parent; ((Fl_Widget_Type*)t)->o->redraw(); } } // the recursive part sorts all children, returns pointer to next: Fl_Type *sort(Fl_Type *parent) { Fl_Type *f,*n=0; for (f = parent ? parent->next : Fl_Type::first; ; f = n) { if (!f || (parent && f->level <= parent->level)) return f; n = sort(f); if (!f->selected || (!f->is_widget() || f->is_menu_item())) continue; Fl_Widget* fw = ((Fl_Widget_Type*)f)->o; Fl_Type *g; // we will insert before this for (g = parent->next; g != f; g = g->next) { if (!g->selected || g->level > f->level) continue; Fl_Widget* gw = ((Fl_Widget_Type*)g)->o; if (gw->y() > fw->y()) break; if (gw->y() == fw->y() && gw->x() > fw->x()) break; } if (g != f) f->move_before(g); } } //////////////////////////////////////////////////////////////// // The control panels! Fl_Window *the_panel; // All the callbacks use the argument to indicate whether to load or store. // This avoids the need for pointers to all the widgets, and keeps the // code localized in the callbacks. // A value of LOAD means to load. The hope is that this will not collide // with any actual useful values for the argument. I also use this to // initialized parts of the widget that are nyi by fluid. Fl_Widget_Type *current_widget; // one of the selected ones void* const LOAD = (void *)"LOAD"; // "magic" pointer to indicate that we need to load values into the dialog static int numselected; // number selected static int haderror; void name_cb(Fl_Input* o, void *v) { if (v == LOAD) { static char buf[1024]; if (numselected != 1) { snprintf(buf, sizeof(buf), "Widget Properties (%d widgets)", numselected); o->hide(); } else { o->static_value(current_widget->name()); o->show(); snprintf(buf, sizeof(buf), "%s Properties", current_widget->title()); } the_panel->label(buf); } else { if (numselected == 1) { current_widget->name(o->value()); // I don't update window title, as it probably is being closed // and wm2 (a window manager) barfs if you retitle and then // hide a window: // ((Fl_Window*)(o->parent()->parent()->parent()))->label(current_widget->title()); } } } void name_public_member_cb(Fl_Choice* i, void* v) { if (v == LOAD) { i->value(current_widget->public_); if (current_widget->is_in_class()) i->show(); else i->hide(); } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { Fl_Widget_Type *w = ((Fl_Widget_Type*)o); if (w->is_in_class()) { w->public_ = i->value(); } else { // if this is not in a class, it can be only private or public w->public_ = (i->value()>0); } mod = 1; } } if (mod) { set_modflag(1); redraw_browser(); } } } void name_public_cb(Fl_Choice* i, void* v) { if (v == LOAD) { i->value(current_widget->public_>0); if (current_widget->is_in_class()) i->hide(); else i->show(); } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { ((Fl_Widget_Type*)o)->public_ = i->value(); mod = 1; } } if (mod) { set_modflag(1); redraw_browser(); } } } static char* oldlabel; static unsigned oldlabellen; void label_cb(Fl_Input* i, void *v) { if (v == LOAD) { i->static_value(current_widget->label()); if (strlen(i->value()) >= oldlabellen) { oldlabellen = (int)strlen(i->value())+128; oldlabel = (char*)realloc(oldlabel,oldlabellen); } strcpy(oldlabel,i->value()); } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { o->label(i->value()); mod = 1; } } if (mod) set_modflag(1); } } static Fl_Input *image_input; void image_cb(Fl_Input* i, void *v) { if (v == LOAD) { image_input = i; if (current_widget->is_widget() && !current_widget->is_window()) { i->activate(); i->static_value(((Fl_Widget_Type*)current_widget)->image_name()); } else i->deactivate(); } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { ((Fl_Widget_Type*)o)->image_name(i->value()); mod = 1; } } if (mod) set_modflag(1); } } void image_browse_cb(Fl_Button* b, void *v) { if (v == LOAD) { if (current_widget->is_widget() && !current_widget->is_window()) b->activate(); else b->deactivate(); } else { int mod = 0; if (ui_find_image(image_input->value())) { image_input->value(ui_find_image_name); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { ((Fl_Widget_Type*)o)->image_name(ui_find_image_name); mod = 1; } } if (mod) set_modflag(1); } } } static Fl_Input *inactive_input; void inactive_cb(Fl_Input* i, void *v) { if (v == LOAD) { inactive_input = i; if (current_widget->is_widget() && !current_widget->is_window()) { i->activate(); i->static_value(((Fl_Widget_Type*)current_widget)->inactive_name()); } else i->deactivate(); } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { ((Fl_Widget_Type*)o)->inactive_name(i->value()); mod = 1; } } if (mod) set_modflag(1); } } void inactive_browse_cb(Fl_Button* b, void *v) { if (v == LOAD) { if (current_widget->is_widget() && !current_widget->is_window()) b->activate(); else b->deactivate(); } else { int mod = 0; if (ui_find_image(inactive_input->value())) { inactive_input->value(ui_find_image_name); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { ((Fl_Widget_Type*)o)->inactive_name(ui_find_image_name); mod = 1; } } if (mod) set_modflag(1); } } } void tooltip_cb(Fl_Input* i, void *v) { if (v == LOAD) { if (current_widget->is_widget()) { i->activate(); i->static_value(((Fl_Widget_Type*)current_widget)->tooltip()); } else i->deactivate(); } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { ((Fl_Widget_Type*)o)->tooltip(i->value()); mod = 1; } } if (mod) set_modflag(1); } } Fluid_Coord_Input *x_input, *y_input, *w_input, *h_input; static int widget_i = 0; static int vars_i_cb(const Fluid_Coord_Input*, void *v) { return widget_i; } static int vars_x_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = (Fl_Type*)v; if (t->is_widget()) return ((Fl_Widget_Type*)t)->o->x(); return 0; } static int vars_y_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = (Fl_Type*)v; if (t->is_widget()) return ((Fl_Widget_Type*)t)->o->y(); return 0; } static int vars_w_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = (Fl_Type*)v; if (t->is_widget()) return ((Fl_Widget_Type*)t)->o->w(); return 0; } static int vars_h_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = (Fl_Type*)v; if (t->is_widget()) return ((Fl_Widget_Type*)t)->o->h(); return 0; } static int vars_px_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = ((Fl_Type*)v)->parent; if (t && t->is_widget()) return ((Fl_Widget_Type*)t)->o->x(); return 0; } static int vars_py_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = ((Fl_Type*)v)->parent; if (t && t->is_widget()) return ((Fl_Widget_Type*)t)->o->y(); return 0; } static int vars_pw_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = ((Fl_Type*)v)->parent; if (t && t->is_widget()) return ((Fl_Widget_Type*)t)->o->w(); return 0; } static int vars_ph_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = ((Fl_Type*)v)->parent; if (t && t->is_widget()) return ((Fl_Widget_Type*)t)->o->h(); return 0; } static int vars_sx_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = ((Fl_Type*)v)->prev_sibling(); if (t && t->is_widget()) return ((Fl_Widget_Type*)t)->o->x(); return 0; } static int vars_sy_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = ((Fl_Type*)v)->prev_sibling(); if (t && t->is_widget()) return ((Fl_Widget_Type*)t)->o->y(); return 0; } static int vars_sw_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = ((Fl_Type*)v)->prev_sibling(); if (t && t->is_widget()) return ((Fl_Widget_Type*)t)->o->w(); return 0; } static int vars_sh_cb(const Fluid_Coord_Input*, void *v) { Fl_Type *t = ((Fl_Type*)v)->prev_sibling(); if (t && t->is_widget()) return ((Fl_Widget_Type*)t)->o->h(); return 0; } static int bbox_x, bbox_y, bbox_r, bbox_b; static int bbox_min(int a, int b) { return (ab) ? a : b; } static void calculate_bbox(Fl_Type *p) { char first = 1; bbox_x = bbox_y = bbox_r = bbox_b = 0; for (p=p->first_child(); p; p=p->next_sibling()) { if (p->is_widget()) { Fl_Widget *o = ((Fl_Widget_Type*)p)->o; if (first) { bbox_x = o->x(); bbox_y = o->y(); bbox_r = o->x() + o->w(); bbox_b = o->y() + o->h(); first = 0; } else { bbox_x = bbox_min(bbox_x, o->x()); bbox_y = bbox_min(bbox_y, o->y()); bbox_r = bbox_max(bbox_r, o->x() + o->w()); bbox_b = bbox_max(bbox_b, o->y() + o->h()); } } } } static int vars_cx_cb(const Fluid_Coord_Input*, void *v) { calculate_bbox((Fl_Type*)v); return bbox_x; } static int vars_cy_cb(const Fluid_Coord_Input*, void *v) { calculate_bbox((Fl_Type*)v); return bbox_y; } static int vars_cw_cb(const Fluid_Coord_Input*, void *v) { calculate_bbox((Fl_Type*)v); return bbox_r - bbox_x; } static int vars_ch_cb(const Fluid_Coord_Input*, void *v) { calculate_bbox((Fl_Type*)v); return bbox_b - bbox_y; } Fluid_Coord_Input_Vars widget_vars[] = { { "i", vars_i_cb }, // zero based counter of selected widgets { "x", vars_x_cb }, // position and size of current widget { "y", vars_y_cb }, { "w", vars_w_cb }, { "h", vars_h_cb }, { "px", vars_px_cb }, // position and size of parent widget { "py", vars_py_cb }, { "pw", vars_pw_cb }, { "ph", vars_ph_cb }, { "sx", vars_sx_cb }, // position and size of previous sibling { "sy", vars_sy_cb }, { "sw", vars_sw_cb }, { "sh", vars_sh_cb }, { "cx", vars_cx_cb }, // position and size of bounding box of all children { "cy", vars_cy_cb }, { "cw", vars_cw_cb }, { "ch", vars_ch_cb }, { 0 } }; void x_cb(Fluid_Coord_Input *i, void *v) { if (v == LOAD) { x_input = i; if (current_widget->is_widget()) { i->value(((Fl_Widget_Type *)current_widget)->o->x()); x_input->activate(); } else x_input->deactivate(); } else { undo_checkpoint(); widget_i = 0; int mod = 0; int v = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { Fl_Widget *w = ((Fl_Widget_Type *)o)->o; i->variables(widget_vars, o); v = i->value(); w->resize(v, w->y(), w->w(), w->h()); if (w->window()) w->window()->redraw(); widget_i++; mod = 1; } } if (mod) { set_modflag(1); i->value(v); // change the displayed value to the result of the last // calculation. Keep the formula if it was not used. } } } void y_cb(Fluid_Coord_Input *i, void *v) { if (v == LOAD) { y_input = i; if (current_widget->is_widget()) { i->value(((Fl_Widget_Type *)current_widget)->o->y()); y_input->activate(); } else y_input->deactivate(); } else { undo_checkpoint(); widget_i = 0; int mod = 0; int v = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { Fl_Widget *w = ((Fl_Widget_Type *)o)->o; i->variables(widget_vars, o); v = i->value(); w->resize(w->x(), v, w->w(), w->h()); if (w->window()) w->window()->redraw(); widget_i++; mod = 1; } } if (mod) { set_modflag(1); i->value(v); } } } void w_cb(Fluid_Coord_Input *i, void *v) { if (v == LOAD) { w_input = i; if (current_widget->is_widget()) { i->value(((Fl_Widget_Type *)current_widget)->o->w()); w_input->activate(); } else w_input->deactivate(); } else { undo_checkpoint(); widget_i = 0; int mod = 0; int v = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { Fl_Widget *w = ((Fl_Widget_Type *)o)->o; i->variables(widget_vars, o); v = i->value(); w->resize(w->x(), w->y(), v, w->h()); if (w->window()) w->window()->redraw(); widget_i++; mod = 1; } } if (mod) { set_modflag(1); i->value(v); } } } void h_cb(Fluid_Coord_Input *i, void *v) { if (v == LOAD) { h_input = i; if (current_widget->is_widget()) { i->value(((Fl_Widget_Type *)current_widget)->o->h()); h_input->activate(); } else h_input->deactivate(); } else { undo_checkpoint(); widget_i = 0; int mod = 0; int v = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { Fl_Widget *w = ((Fl_Widget_Type *)o)->o; i->variables(widget_vars, o); v = i->value(); w->resize(w->x(), w->y(), w->w(), v); if (w->window()) w->window()->redraw(); widget_i++; mod = 1; } } if (mod) { set_modflag(1); i->value(v); } } } void wc_relative_cb(Fl_Choice *i, void *v) { if (v == LOAD) { if (!strcmp(current_widget->type_name(), "widget_class")) { i->show(); i->value(((Fl_Widget_Class_Type *)current_widget)->wc_relative); } else { i->hide(); } } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && !strcmp(current_widget->type_name(), "widget_class")) { Fl_Widget_Class_Type *t = (Fl_Widget_Class_Type *)o; t->wc_relative = i->value(); mod = 1; } } if (mod) set_modflag(1); } } //////////////////////////////////////////////////////////////// // turn number to string or string to number for saving to file: // does not work for hierarchial menus! const char *item_name(Fl_Menu_Item* m, int i) { if (m) { while (m->label()) { if (m->argument() == i) return m->label(); m++; } } static char buffer[20]; sprintf(buffer, "%d", i); return buffer; } int item_number(Fl_Menu_Item* m, const char* i) { if (!i) return 0; if (m && i) { if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3; while (m->label()) { if (!strcmp(m->label(), i)) return int(m->argument()); m++; } } return atoi(i); } #define ZERO_ENTRY 1000 Fl_Menu_Item boxmenu[] = { {"NO_BOX",0,0,(void *)ZERO_ENTRY}, {"boxes",0,0,0,FL_SUBMENU}, {"UP_BOX",0,0,(void *)FL_UP_BOX}, {"DOWN_BOX",0,0,(void *)FL_DOWN_BOX}, {"FLAT_BOX",0,0,(void *)FL_FLAT_BOX}, {"BORDER_BOX",0,0,(void *)FL_BORDER_BOX}, {"THIN_UP_BOX",0,0,(void *)FL_THIN_UP_BOX}, {"THIN_DOWN_BOX",0,0,(void *)FL_THIN_DOWN_BOX}, {"ENGRAVED_BOX",0,0,(void *)FL_ENGRAVED_BOX}, {"EMBOSSED_BOX",0,0,(void *)FL_EMBOSSED_BOX}, {"ROUND_UP_BOX",0,0,(void *)FL_ROUND_UP_BOX}, {"ROUND_DOWN_BOX",0,0,(void *)FL_ROUND_DOWN_BOX}, {"DIAMOND_UP_BOX",0,0,(void *)FL_DIAMOND_UP_BOX}, {"DIAMOND_DOWN_BOX",0,0,(void *)FL_DIAMOND_DOWN_BOX}, {"SHADOW_BOX",0,0,(void *)FL_SHADOW_BOX}, {"ROUNDED_BOX",0,0,(void *)FL_ROUNDED_BOX}, {"RSHADOW_BOX",0,0,(void *)FL_RSHADOW_BOX}, {"RFLAT_BOX",0,0,(void *)FL_RFLAT_BOX}, {"OVAL_BOX",0,0,(void *)FL_OVAL_BOX}, {"OSHADOW_BOX",0,0,(void *)FL_OSHADOW_BOX}, {"OFLAT_BOX",0,0,(void *)FL_OFLAT_BOX}, {"PLASTIC_UP_BOX",0,0,(void *)FL_PLASTIC_UP_BOX}, {"PLASTIC_DOWN_BOX",0,0,(void *)FL_PLASTIC_DOWN_BOX}, {"PLASTIC_THIN_UP_BOX",0,0,(void *)FL_PLASTIC_THIN_UP_BOX}, {"PLASTIC_THIN_DOWN_BOX",0,0,(void *)FL_PLASTIC_THIN_DOWN_BOX}, {"PLASTIC_ROUND_UP_BOX",0,0,(void *)FL_PLASTIC_ROUND_UP_BOX}, {"PLASTIC_ROUND_DOWN_BOX",0,0,(void *)FL_PLASTIC_ROUND_DOWN_BOX}, {"GTK_UP_BOX",0,0,(void *)FL_GTK_UP_BOX}, {"GTK_DOWN_BOX",0,0,(void *)FL_GTK_DOWN_BOX}, {"GTK_THIN_UP_BOX",0,0,(void *)FL_GTK_THIN_UP_BOX}, {"GTK_THIN_DOWN_BOX",0,0,(void *)FL_GTK_THIN_DOWN_BOX}, {"GTK_ROUND_UP_BOX",0,0,(void *)FL_GTK_ROUND_UP_BOX}, {"GTK_ROUND_DOWN_BOX",0,0,(void *)FL_GTK_ROUND_DOWN_BOX}, {"GLEAM_UP_BOX",0,0,(void *)FL_GLEAM_UP_BOX}, {"GLEAM_DOWN_BOX",0,0,(void *)FL_GLEAM_DOWN_BOX}, {"GLEAM_THIN_UP_BOX",0,0,(void *)FL_GLEAM_THIN_UP_BOX}, {"GLEAM_THIN_DOWN_BOX",0,0,(void *)FL_GLEAM_THIN_DOWN_BOX}, {"GLEAM_ROUND_UP_BOX",0,0,(void *)FL_GLEAM_ROUND_UP_BOX}, {"GLEAM_ROUND_DOWN_BOX",0,0,(void *)FL_GLEAM_ROUND_DOWN_BOX}, {"OXY_UP_BOX",0,0,(void *)FL_OXY_UP_BOX}, {"OXY_DOWN_BOX",0,0,(void *)FL_OXY_DOWN_BOX}, {"OXY_THIN_UP_BOX",0,0,(void *)FL_OXY_THIN_UP_BOX}, {"OXY_THIN_DOWN_BOX",0,0,(void *)FL_OXY_THIN_DOWN_BOX}, {"OXY_ROUND_UP_BOX",0,0,(void *)FL_OXY_ROUND_UP_BOX}, {"OXY_ROUND_DOWN_BOX",0,0,(void *)FL_OXY_ROUND_DOWN_BOX}, {"OXY_BUTTON_UP_BOX",0,0,(void *)FL_OXY_BUTTON_UP_BOX}, {"OXY_BUTTON_DOWN_BOX",0,0,(void *)FL_OXY_BUTTON_DOWN_BOX}, {0}, {"frames",0,0,0,FL_SUBMENU}, {"UP_FRAME",0,0,(void *)FL_UP_FRAME}, {"DOWN_FRAME",0,0,(void *)FL_DOWN_FRAME}, {"THIN_UP_FRAME",0,0,(void *)FL_THIN_UP_FRAME}, {"THIN_DOWN_FRAME",0,0,(void *)FL_THIN_DOWN_FRAME}, {"ENGRAVED_FRAME",0,0,(void *)FL_ENGRAVED_FRAME}, {"EMBOSSED_FRAME",0,0,(void *)FL_EMBOSSED_FRAME}, {"BORDER_FRAME",0,0,(void *)FL_BORDER_FRAME}, {"SHADOW_FRAME",0,0,(void *)FL_SHADOW_FRAME}, {"ROUNDED_FRAME",0,0,(void *)FL_ROUNDED_FRAME}, {"OVAL_FRAME",0,0,(void *)FL_OVAL_FRAME}, {"PLASTIC_UP_FRAME",0,0,(void *)FL_PLASTIC_UP_FRAME}, {"PLASTIC_DOWN_FRAME",0,0,(void *)FL_PLASTIC_DOWN_FRAME}, {"GTK_UP_FRAME",0,0,(void *)FL_GTK_UP_FRAME}, {"GTK_DOWN_FRAME",0,0,(void *)FL_GTK_DOWN_FRAME}, {"GTK_THIN_UP_FRAME",0,0,(void *)FL_GTK_THIN_UP_FRAME}, {"GTK_THIN_DOWN_FRAME",0,0,(void *)FL_GTK_THIN_DOWN_FRAME}, {"GLEAM_UP_FRAME",0,0,(void *)FL_GLEAM_UP_FRAME}, {"GLEAM_DOWN_FRAME",0,0,(void *)FL_GLEAM_DOWN_FRAME}, {"OXY_UP_FRAME",0,0,(void *)FL_OXY_UP_FRAME}, {"OXY_DOWN_FRAME",0,0,(void *)FL_OXY_DOWN_FRAME}, {"OXY_THIN_UP_FRAME",0,0,(void *)FL_OXY_THIN_UP_FRAME}, {"OXY_THIN_DOWN_FRAME",0,0,(void *)FL_OXY_THIN_DOWN_FRAME}, {0}, {0}}; const char *boxname(int i) { if (!i) i = ZERO_ENTRY; for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++) if (boxmenu[j].argument() == i) return boxmenu[j].label(); return 0; } int boxnumber(const char *i) { if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3; for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++) if (boxmenu[j].label() && !strcmp(boxmenu[j].label(), i)) { return int(boxmenu[j].argument()); } return 0; } void box_cb(Fl_Choice* i, void *v) { if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); int n = current_widget->o->box(); if (!n) n = ZERO_ENTRY; for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++) if (boxmenu[j].argument() == n) {i->value(j); break;} } else { int mod = 0; int m = i->value(); int n = int(boxmenu[m].argument()); if (!n) return; // should not happen if (n == ZERO_ENTRY) n = 0; 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; q->o->box((Fl_Boxtype)n); q->redraw(); mod = 1; } } if (mod) set_modflag(1); } } void down_box_cb(Fl_Choice* i, void *v) { if (v == LOAD) { int n; if (current_widget->is_button() && !current_widget->is_menu_item()) n = ((Fl_Button*)(current_widget->o))->down_box(); else if (!strcmp(current_widget->type_name(), "Fl_Input_Choice")) n = ((Fl_Input_Choice*)(current_widget->o))->down_box(); else if (current_widget->is_menu_button()) n = ((Fl_Menu_*)(current_widget->o))->down_box(); else { i->deactivate(); return; } i->activate(); if (!n) n = ZERO_ENTRY; for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++) if (boxmenu[j].argument() == n) {i->value(j); break;} } else { int mod = 0; int m = i->value(); int n = int(boxmenu[m].argument()); if (!n) return; // should not happen if (n == ZERO_ENTRY) n = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected) { if (o->is_button() && !o->is_menu_item()) { Fl_Widget_Type* q = (Fl_Widget_Type*)o; ((Fl_Button*)(q->o))->down_box((Fl_Boxtype)n); if (((Fl_Button*)(q->o))->value()) q->redraw(); } else if (!strcmp(o->type_name(), "Fl_Input_Choice")) { Fl_Widget_Type* q = (Fl_Widget_Type*)o; ((Fl_Input_Choice*)(q->o))->down_box((Fl_Boxtype)n); } else if (o->is_menu_button()) { Fl_Widget_Type* q = (Fl_Widget_Type*)o; ((Fl_Menu_*)(q->o))->down_box((Fl_Boxtype)n); } mod = 1; } } if (mod) set_modflag(1); } } //////////////////////////////////////////////////////////////// Fl_Menu_Item whenmenu[] = { {"Never",0,0,(void*)ZERO_ENTRY}, {"Release",0,0,(void*)FL_WHEN_RELEASE}, {"Changed",0,0,(void*)FL_WHEN_CHANGED}, {"Enter key",0,0,(void*)FL_WHEN_ENTER_KEY}, //{"Release or Enter",0,0,(void*)(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE)}, {0}}; static Fl_Menu_Item whensymbolmenu[] = { {"FL_WHEN_NEVER",0,0,(void*)(FL_WHEN_NEVER)}, {"FL_WHEN_CHANGED",0,0,(void*)(FL_WHEN_CHANGED)}, {"FL_WHEN_RELEASE",0,0,(void*)(FL_WHEN_RELEASE)}, {"FL_WHEN_RELEASE_ALWAYS",0,0,(void*)(FL_WHEN_RELEASE_ALWAYS)}, {"FL_WHEN_ENTER_KEY",0,0,(void*)(FL_WHEN_ENTER_KEY)}, {"FL_WHEN_ENTER_KEY_ALWAYS",0,0,(void*)(FL_WHEN_ENTER_KEY_ALWAYS)}, {0}}; void when_cb(Fl_Choice* i, void *v) { if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); int n = current_widget->o->when() & (~FL_WHEN_NOT_CHANGED); if (!n) n = ZERO_ENTRY; for (int j = 0; j < int(sizeof(whenmenu)/sizeof(*whenmenu)); j++) if (whenmenu[j].argument() == n) {i->value(j); break;} } else { int mod = 0; int m = i->value(); int n = int(whenmenu[m].argument()); if (!n) return; // should not happen if (n == ZERO_ENTRY) n = 0; 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; q->o->when(n|(q->o->when()&FL_WHEN_NOT_CHANGED)); mod = 1; } } if (mod) set_modflag(1); } } void when_button_cb(Fl_Light_Button* i, void *v) { if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); i->value(current_widget->o->when()&FL_WHEN_NOT_CHANGED); } else { int mod = 0; int n = i->value() ? FL_WHEN_NOT_CHANGED : 0; 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; q->o->when(n|(q->o->when()&~FL_WHEN_NOT_CHANGED)); mod = 1; } } if (mod) set_modflag(1); } } uchar Fl_Widget_Type::resizable() const { if (is_window()) return ((Fl_Window*)o)->resizable() != 0; Fl_Group* p = (Fl_Group*)o->parent(); if (p) return p->resizable() == o; else return 0; } void Fl_Widget_Type::resizable(uchar v) { if (v) { if (resizable()) return; if (is_window()) ((Fl_Window*)o)->resizable(o); else { Fl_Group* p = (Fl_Group*)o->parent(); if (p) p->resizable(o); } } else { if (!resizable()) return; if (is_window()) { ((Fl_Window*)o)->resizable(0); } else { Fl_Group* p = (Fl_Group*)o->parent(); if (p) p->resizable(0); } } } void resizable_cb(Fl_Light_Button* i,void* v) { if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} if (numselected > 1) {i->deactivate(); return;} i->activate(); i->value(current_widget->resizable()); } else { current_widget->resizable(i->value()); set_modflag(1); } } void hotspot_cb(Fl_Light_Button* i,void* v) { if (v == LOAD) { if (numselected > 1) {i->deactivate(); return;} if (current_widget->is_menu_item()) i->label("divider"); else i->label("hotspot"); i->activate(); i->value(current_widget->hotspot()); } else { current_widget->hotspot(i->value()); if (current_widget->is_menu_item()) {current_widget->redraw(); return;} if (i->value()) { Fl_Type *p = current_widget->parent; if (!p || !p->is_widget()) return; while (!p->is_window()) p = p->parent; for (Fl_Type *o = p->next; o && o->level > p->level; o = o->next) { if (o->is_widget() && o != current_widget) ((Fl_Widget_Type*)o)->hotspot(0); } } set_modflag(1); } } void visible_cb(Fl_Light_Button* i, void* v) { if (v == LOAD) { i->value(current_widget->o->visible()); if (current_widget->is_window()) i->deactivate(); else i->activate(); } else { int mod = 0; int n = i->value(); 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; n ? q->o->show() : q->o->hide(); q->redraw(); mod = 1; if (n && q->parent && q->parent->type_name()) { if (!strcmp(q->parent->type_name(), "Fl_Tabs")) { ((Fl_Tabs *)q->o->parent())->value(q->o); } else if (!strcmp(q->parent->type_name(), "Fl_Wizard")) { ((Fl_Wizard *)q->o->parent())->value(q->o); } } } } if (mod) { set_modflag(1); redraw_browser(); } } } void active_cb(Fl_Light_Button* i, void* v) { if (v == LOAD) { i->value(current_widget->o->active()); if (current_widget->is_window()) i->deactivate(); else i->activate(); } else { int mod = 0; int n = i->value(); 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; n ? q->o->activate() : q->o->deactivate(); q->redraw(); mod = 1; } } if (mod) set_modflag(1); } } //////////////////////////////////////////////////////////////// Fl_Menu_Item fontmenu[] = { {"Helvetica"}, {"Helvetica bold"}, {"Helvetica italic"}, {"Helvetica bold italic"}, {"Courier"}, {"Courier bold"}, {"Courier italic"}, {"Courier bold italic"}, {"Times"}, {"Times bold"}, {"Times italic"}, {"Times bold italic"}, {"Symbol"}, {"Terminal"}, {"Terminal Bold"}, {"Zapf Dingbats"}, {0}}; void labelfont_cb(Fl_Choice* i, void *v) { if (v == LOAD) { int n = current_widget->o->labelfont(); if (n > 15) n = 0; i->value(n); } else { int mod = 0; int n = i->value(); 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; q->o->labelfont(n); q->redraw(); mod = 1; } } if (mod) set_modflag(1); } } void labelsize_cb(Fl_Value_Input* i, void *v) { int n; if (v == LOAD) { n = current_widget->o->labelsize(); } else { int mod = 0; n = int(i->value()); if (n <= 0) n = Fl_Widget_Type::default_size; 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; q->o->labelsize(n); q->redraw(); mod = 1; } } if (mod) set_modflag(1); } i->value(n); } extern const char *ui_find_image_name; Fl_Menu_Item labeltypemenu[] = { {"NORMAL_LABEL",0,0,(void*)0}, {"SHADOW_LABEL",0,0,(void*)FL_SHADOW_LABEL}, {"ENGRAVED_LABEL",0,0,(void*)FL_ENGRAVED_LABEL}, {"EMBOSSED_LABEL",0,0,(void*)FL_EMBOSSED_LABEL}, {"NO_LABEL",0,0,(void*)(FL_NO_LABEL)}, {0}}; void labeltype_cb(Fl_Choice* i, void *v) { if (v == LOAD) { int n; n = current_widget->o->labeltype(); i->when(FL_WHEN_RELEASE); for (int j = 0; j < int(sizeof(labeltypemenu)/sizeof(*labeltypemenu)); j++) if (labeltypemenu[j].argument() == n) {i->value(j); break;} } else { int mod = 0; int m = i->value(); int n = int(labeltypemenu[m].argument()); if (n<0) return; // should not happen for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { Fl_Widget_Type* p = (Fl_Widget_Type*)o; p->o->labeltype((Fl_Labeltype)n); p->redraw(); mod = 1; } } if (mod) set_modflag(1); } } //////////////////////////////////////////////////////////////// void color_cb(Fl_Button* i, void *v) { Fl_Color c = current_widget->o->color(); if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); } else { int mod = 0; Fl_Color d = fl_show_colormap(c); if (d == c) return; c = d; 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; q->o->color(c); q->o->redraw(); if (q->parent && q->parent->type_name() == tabs_type_name) { if (q->o->parent()) q->o->parent()->redraw(); } mod = 1; } } if (mod) set_modflag(1); } i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw(); } void color2_cb(Fl_Button* i, void *v) { Fl_Color c = current_widget->o->selection_color(); if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); } else { int mod = 0; Fl_Color d = fl_show_colormap(c); if (d == c) return; c = d; 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; q->o->selection_color(c); q->o->redraw(); mod = 1; } } if (mod) set_modflag(1); } i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw(); } void labelcolor_cb(Fl_Button* i, void *v) { Fl_Color c = current_widget->o->labelcolor(); if (v != LOAD) { int mod = 0; Fl_Color d = fl_show_colormap(c); if (d == c) return; c = d; 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; q->o->labelcolor(c); q->redraw(); mod = 1; } } if (mod) set_modflag(1); } i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw(); } static Fl_Button* relative(Fl_Widget* o, int i) { Fl_Group* g = (Fl_Group*)(o->parent()); return (Fl_Button*)(g->child(g->find(*o)+i)); } static Fl_Menu_Item alignmenu[] = { {"FL_ALIGN_CENTER",0,0,(void*)(fl_intptr_t)(FL_ALIGN_CENTER)}, {"FL_ALIGN_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP)}, {"FL_ALIGN_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM)}, {"FL_ALIGN_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT)}, {"FL_ALIGN_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT)}, {"FL_ALIGN_INSIDE",0,0,(void*)(fl_intptr_t)(FL_ALIGN_INSIDE)}, {"FL_ALIGN_CLIP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_CLIP)}, {"FL_ALIGN_WRAP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_WRAP)}, {"FL_ALIGN_TEXT_OVER_IMAGE",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TEXT_OVER_IMAGE)}, {"FL_ALIGN_TOP_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP_LEFT)}, {"FL_ALIGN_TOP_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP_RIGHT)}, {"FL_ALIGN_BOTTOM_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM_LEFT)}, {"FL_ALIGN_BOTTOM_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM_RIGHT)}, {"FL_ALIGN_LEFT_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT_TOP)}, {"FL_ALIGN_RIGHT_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT_TOP)}, {"FL_ALIGN_LEFT_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT_BOTTOM)}, {"FL_ALIGN_RIGHT_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT_BOTTOM)}, {0}}; void align_cb(Fl_Button* i, void *v) { Fl_Align b = Fl_Align(fl_uintptr_t(i->user_data())); if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); i->value(current_widget->o->align() & b); } else { int mod = 0; 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; Fl_Align x = q->o->align(); Fl_Align y; if (i->value()) { y = x | b; if (b == FL_ALIGN_LEFT || b == FL_ALIGN_TOP) { Fl_Button *b1 = relative(i,+1); b1->clear(); y = y & ~(b1->argument()); } if (b == FL_ALIGN_RIGHT || b == FL_ALIGN_BOTTOM) { Fl_Button *b1 = relative(i,-1); b1->clear(); y = y & ~(b1->argument()); } } else { y = x & ~b; } if (x != y) { q->o->align(y); q->redraw(); mod = 1; } } } if (mod) set_modflag(1); } } void align_position_cb(Fl_Choice *i, void *v) { if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); Fl_Menu_Item *mi = (Fl_Menu_Item*)i->menu(); Fl_Align b = current_widget->o->align() & FL_ALIGN_POSITION_MASK; for (;mi->text;mi++) { if ((Fl_Align)(mi->argument())==b) i->value(mi); } } else { const Fl_Menu_Item *mi = i->menu() + i->value(); Fl_Align b = Fl_Align(fl_uintptr_t(mi->user_data())); int mod = 0; 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; Fl_Align x = q->o->align(); Fl_Align y = (x & ~FL_ALIGN_POSITION_MASK) | b; if (x != y) { q->o->align(y); q->redraw(); mod = 1; } } } if (mod) set_modflag(1); } } void align_text_image_cb(Fl_Choice *i, void *v) { if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); Fl_Menu_Item *mi = (Fl_Menu_Item*)i->menu(); Fl_Align b = current_widget->o->align() & FL_ALIGN_IMAGE_MASK; for (;mi->text;mi++) { if ((Fl_Align)(mi->argument())==b) i->value(mi); } } else { const Fl_Menu_Item *mi = i->menu() + i->value(); Fl_Align b = Fl_Align(fl_uintptr_t(mi->user_data())); int mod = 0; 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; Fl_Align x = q->o->align(); Fl_Align y = (x & ~FL_ALIGN_IMAGE_MASK) | b; if (x != y) { q->o->align(y); q->redraw(); mod = 1; } } } if (mod) set_modflag(1); } } //////////////////////////////////////////////////////////////// void callback_cb(CodeEditor* i, void *v) { if (v == LOAD) { const char *cbtext = current_widget->callback(); i->buffer()->text( cbtext ? cbtext : "" ); } else { int mod = 0; char *c = i->buffer()->text(); const char *d = c_check(c); if (d) { fl_message("Error in callback: %s",d); if (i->window()) i->window()->make_current(); haderror = 1; } for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected) { o->callback(c); mod = 1; } } if (mod) set_modflag(1); free(c); } } void comment_cb(Fl_Text_Editor* i, void *v) { if (v == LOAD) { const char *cmttext = current_widget->comment(); i->buffer()->text( cmttext ? cmttext : "" ); } else { int mod = 0; char *c = i->buffer()->text(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected) { o->comment(c); mod = 1; } } if (mod) set_modflag(1); free(c); } } void user_data_cb(Fl_Input *i, void *v) { if (v == LOAD) { i->static_value(current_widget->user_data()); } else { int mod = 0; const char *c = i->value(); const char *d = c_check(c); if (d) {fl_message("Error in user_data: %s",d); haderror = 1; return;} for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected) { o->user_data(c); mod = 1; } } if (mod) set_modflag(1); } } void user_data_type_cb(Fl_Input *i, void *v) { static const char *dflt = "void*"; if (v == LOAD) { const char *c = current_widget->user_data_type(); if (!c) c = dflt; i->static_value(c); } else { int mod = 0; const char *c = i->value(); const char *d = c_check(c); if (!*c) i->value(dflt); else if (!strcmp(c,dflt)) c = 0; if (!d) { if (c && *c && c[strlen(c)-1] != '*' && strcmp(c,"long")) d = "must be pointer or long"; } if (d) {fl_message("Error in type: %s",d); haderror = 1; return;} for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected) { o->user_data_type(c); mod = 1; } } if (mod) set_modflag(1); } } // "v_attributes" let user type in random code for attribute settings: void v_input_cb(Fl_Input* i, void* v) { int n = fl_int(i->user_data()); if (v == LOAD) { i->static_value(current_widget->extra_code(n)); } else { int mod = 0; const char *c = i->value(); const char *d = c_check(c&&c[0]=='#' ? c+1 : c); if (d) {fl_message("Error in %s: %s",i->label(),d); haderror = 1; return;} for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { Fl_Widget_Type *t = (Fl_Widget_Type*)o; t->extra_code(n,c); mod = 1; } } if (mod) set_modflag(1); } } void subclass_cb(Fl_Input* i, void* v) { if (v == LOAD) { if (current_widget->is_menu_item()) {i->deactivate(); return;} else i->activate(); i->static_value(current_widget->subclass()); } else { int mod = 0; const char *c = i->value(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget()) { Fl_Widget_Type *t = (Fl_Widget_Type*)o; t->subclass(c); mod = 1; } } if (mod) set_modflag(1); } } //////////////////////////////////////////////////////////////// // textstuff: set textfont, textsize, textcolor attributes: // default widget returns 0 to indicate not-implemented: int Fl_Widget_Type::textstuff(int, Fl_Font&, int&, Fl_Color&) {return 0;} void textfont_cb(Fl_Choice* i, void* v) { Fl_Font n; int s; Fl_Color c; if (v == LOAD) { if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;} i->activate(); if (n > 15) n = FL_HELVETICA; i->value(n); } else { int mod = 0; n = (Fl_Font)i->value(); 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; q->textstuff(1,n,s,c); q->o->redraw(); mod = 1; } } if (mod) set_modflag(1); } } void textsize_cb(Fl_Value_Input* i, void* v) { Fl_Font n; int s; Fl_Color c; if (v == LOAD) { if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;} i->activate(); } else { int mod = 0; s = int(i->value()); if (s <= 0) s = Fl_Widget_Type::default_size; 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; q->textstuff(2,n,s,c); q->o->redraw(); mod = 1; } } if (mod) set_modflag(1); } i->value(s); } void textcolor_cb(Fl_Button* i, void* v) { Fl_Font n; int s; Fl_Color c; if (v == LOAD) { if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;} i->activate(); } else { int mod = 0; c = i->color(); Fl_Color d = fl_show_colormap(c); if (d == c) return; c = d; 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; q->textstuff(3,n,s,c); q->o->redraw(); mod = 1; } } if (mod) set_modflag(1); } i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw(); } //////////////////////////////////////////////////////////////// // Kludges to the panel for subclasses: void min_w_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (!current_widget->is_window()) return; i->value(((Fl_Window_Type*)current_widget)->sr_min_w); } else { int mod = 0; int n = (int)i->value(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_window()) { ((Fl_Window_Type*)current_widget)->sr_min_w = n; mod = 1; } } if (mod) set_modflag(1); } } void min_h_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (!current_widget->is_window()) return; i->value(((Fl_Window_Type*)current_widget)->sr_min_h); } else { int mod = 0; int n = (int)i->value(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_window()) { ((Fl_Window_Type*)current_widget)->sr_min_h = n; mod = 1; } } if (mod) set_modflag(1); } } void max_w_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (!current_widget->is_window()) return; i->value(((Fl_Window_Type*)current_widget)->sr_max_w); } else { int mod = 0; int n = (int)i->value(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_window()) { ((Fl_Window_Type*)current_widget)->sr_max_w = n; mod = 1; } } if (mod) set_modflag(1); } } void max_h_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (!current_widget->is_window()) return; i->value(((Fl_Window_Type*)current_widget)->sr_max_h); } else { int mod = 0; int n = (int)i->value(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_window()) { ((Fl_Window_Type*)current_widget)->sr_max_h = n; mod = 1; } } if (mod) set_modflag(1); } } void set_min_size_cb(Fl_Button*, void* v) { if (v == LOAD) { } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_window()) { Fl_Window_Type *win = (Fl_Window_Type*)current_widget; win->sr_min_w = win->o->w(); win->sr_min_h = win->o->h(); mod = 1; } } propagate_load(the_panel, LOAD); if (mod) set_modflag(1); } } void set_max_size_cb(Fl_Button*, void* v) { if (v == LOAD) { } else { int mod = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_window()) { Fl_Window_Type *win = (Fl_Window_Type*)current_widget; win->sr_max_w = win->o->w(); win->sr_max_h = win->o->h(); mod = 1; } } propagate_load(the_panel, LOAD); if (mod) set_modflag(1); } } void slider_size_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (current_widget->is_valuator()<2) {i->deactivate(); return;} i->activate(); i->value(((Fl_Slider*)(current_widget->o))->slider_size()); } else { int mod = 0; double n = i->value(); 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->is_valuator()>=2) { ((Fl_Slider*)(q->o))->slider_size(n); q->o->redraw(); mod = 1; } } } if (mod) set_modflag(1); } } void min_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (current_widget->is_valuator()) { i->activate(); i->value(((Fl_Valuator*)(current_widget->o))->minimum()); } else if (current_widget->is_spinner()) { i->activate(); i->value(((Fl_Spinner*)(current_widget->o))->minimum()); } else { i->deactivate(); return; } } else { int mod = 0; double n = i->value(); 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->is_valuator()) { ((Fl_Valuator*)(q->o))->minimum(n); q->o->redraw(); mod = 1; } else if (q->is_spinner()) { ((Fl_Spinner*)(q->o))->minimum(n); q->o->redraw(); mod = 1; } } } if (mod) set_modflag(1); } } void max_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (current_widget->is_valuator()) { i->activate(); i->value(((Fl_Valuator*)(current_widget->o))->maximum()); } else if (current_widget->is_spinner()) { i->activate(); i->value(((Fl_Spinner*)(current_widget->o))->maximum()); } else { i->deactivate(); return; } } else { int mod = 0; double n = i->value(); 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->is_valuator()) { ((Fl_Valuator*)(q->o))->maximum(n); q->o->redraw(); mod = 1; } else if (q->is_spinner()) { ((Fl_Spinner*)(q->o))->maximum(n); q->o->redraw(); mod = 1; } } } if (mod) set_modflag(1); } } void step_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (current_widget->is_valuator()) { i->activate(); i->value(((Fl_Valuator*)(current_widget->o))->step()); } else if (current_widget->is_spinner()) { i->activate(); i->value(((Fl_Spinner*)(current_widget->o))->step()); } else { i->deactivate(); return; } } else { int mod = 0; double n = i->value(); 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->is_valuator()) { ((Fl_Valuator*)(q->o))->step(n); q->o->redraw(); mod = 1; } else if (q->is_spinner()) { ((Fl_Spinner*)(q->o))->step(n); q->o->redraw(); mod = 1; } } } if (mod) set_modflag(1); } } void value_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (current_widget->is_valuator()) { i->activate(); i->value(((Fl_Valuator*)(current_widget->o))->value()); } else if (current_widget->is_button()) { i->activate(); i->value(((Fl_Button*)(current_widget->o))->value()); } else if (current_widget->is_spinner()) { i->activate(); i->value(((Fl_Spinner*)(current_widget->o))->value()); } else i->deactivate(); } else { int mod = 0; double n = i->value(); 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->is_valuator()) { ((Fl_Valuator*)(q->o))->value(n); mod = 1; } else if (q->is_button()) { ((Fl_Button*)(q->o))->value(n != 0); if (q->is_menu_item()) q->redraw(); mod = 1; } else if (q->is_spinner()) { ((Fl_Spinner*)(q->o))->value(n); mod = 1; } } } if (mod) set_modflag(1); } } // The following three callbacks cooperate, showing only one of the groups of // widgets that use the same space in the dialog. void values_group_cb(Fl_Group* g, void* v) { if (v == LOAD) { if (current_widget->is_flex()) { g->hide(); } else if (current_widget->is_window()) { g->hide(); } else { g->show(); } propagate_load(g, v); } } void flex_margin_group_cb(Fl_Group* g, void* v) { if (v == LOAD) { if (current_widget->is_flex()) { g->show(); } else { g->hide(); } propagate_load(g, v); } } void size_range_group_cb(Fl_Group* g, void* v) { if (v == LOAD) { if (current_widget->is_window()) { g->show(); } else { g->hide(); } propagate_load(g, v); } } static void flex_margin_cb(Fl_Value_Input* i, void* v, void (*load_margin)(Fl_Flex*,Fl_Value_Input*), int (*update_margin)(Fl_Flex*,int)) { if (v == LOAD) { if (current_widget->is_flex()) { load_margin((Fl_Flex*)current_widget->o, i); } } else { int mod = 0; int new_value = (int)i->value(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_flex()) { Fl_Flex_Type* q = (Fl_Flex_Type*)o; Fl_Flex* w = (Fl_Flex*)q->o; if (update_margin(w, new_value)) { w->layout(); mod = 1; } } } if (mod) set_modflag(1); } } static void load_left_margin(Fl_Flex *w, Fl_Value_Input* i) { int v; w->margins(&v, NULL, NULL, NULL); i->value((double)v); } static int update_left_margin(Fl_Flex *w, int new_value) { int l, t, r, b; w->margins(&l, &t, &r, &b); if (new_value!=l) { w->margin(new_value, t, r, b); return 1; } else { return 0; } } void flex_margin_left_cb(Fl_Value_Input* i, void* v) { flex_margin_cb(i, v, load_left_margin, update_left_margin); } static void load_top_margin(Fl_Flex *w, Fl_Value_Input* i) { int v; w->margins(NULL, &v, NULL, NULL); i->value((double)v); } static int update_top_margin(Fl_Flex *w, int new_value) { int l, t, r, b; w->margins(&l, &t, &r, &b); if (new_value!=t) { w->margin(l, new_value, r, b); return 1; } else { return 0; } } void flex_margin_top_cb(Fl_Value_Input* i, void* v) { flex_margin_cb(i, v, load_top_margin, update_top_margin); } static void load_right_margin(Fl_Flex *w, Fl_Value_Input* i) { int v; w->margins(NULL, NULL, &v, NULL); i->value((double)v); } static int update_right_margin(Fl_Flex *w, int new_value) { int l, t, r, b; w->margins(&l, &t, &r, &b); if (new_value!=r) { w->margin(l, t, new_value, b); return 1; } else { return 0; } } void flex_margin_right_cb(Fl_Value_Input* i, void* v) { flex_margin_cb(i, v, load_right_margin, update_right_margin); } static void load_bottom_margin(Fl_Flex *w, Fl_Value_Input* i) { int v; w->margins(NULL, NULL, NULL, &v); i->value((double)v); } static int update_bottom_margin(Fl_Flex *w, int new_value) { int l, t, r, b; w->margins(&l, &t, &r, &b); if (new_value!=b) { w->margin(l, t, r, new_value); return 1; } else { return 0; } } void flex_margin_bottom_cb(Fl_Value_Input* i, void* v) { flex_margin_cb(i, v, load_bottom_margin, update_bottom_margin); } static void load_gap(Fl_Flex *w, Fl_Value_Input* i) { int v = w->gap(); i->value((double)v); } static int update_gap(Fl_Flex *w, int new_value) { int g = w->gap(); if (new_value!=g) { w->gap(new_value); return 1; } else { return 0; } } void flex_margin_gap_cb(Fl_Value_Input* i, void* v) { flex_margin_cb(i, v, load_gap, update_gap); } void position_group_cb(Fl_Group* g, void* v) { if (v == LOAD) { if (Fl_Flex_Type::parent_is_flex(current_widget)) { g->hide(); } else { g->show(); } } propagate_load(g, v); } void flex_size_group_cb(Fl_Group* g, void* v) { if (v == LOAD) { if (Fl_Flex_Type::parent_is_flex(current_widget)) { g->show(); } else { g->hide(); } } propagate_load(g, v); } void flex_size_cb(Fl_Value_Input* i, void* v) { if (v == LOAD) { if (Fl_Flex_Type::parent_is_flex(current_widget)) { i->value(Fl_Flex_Type::size(current_widget)); } } else { int mod = 0; int new_size = (int)i->value(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget() && Fl_Flex_Type::parent_is_flex(o)) { Fl_Widget* w = (Fl_Widget*)((Fl_Widget_Type*)o)->o; Fl_Flex* f = (Fl_Flex*)((Fl_Flex_Type*)o->parent)->o; int was_fixed = f->set_size(w); if (new_size==0) { if (was_fixed) { f->set_size(w, 0); f->layout(); widget_flex_fixed->value(0); mod = 1; } } else { int old_size = Fl_Flex_Type::size(o); if (old_size!=new_size || !was_fixed) { f->set_size(w, new_size); f->layout(); widget_flex_fixed->value(1); mod = 1; } } } } if (mod) set_modflag(1); } } void flex_fixed_cb(Fl_Check_Button* i, void* v) { if (v == LOAD) { if (Fl_Flex_Type::parent_is_flex(current_widget)) { i->value(Fl_Flex_Type::is_fixed(current_widget)); } } else { int mod = 0; int new_fixed = (int)i->value(); for (Fl_Type *o = Fl_Type::first; o; o = o->next) { if (o->selected && o->is_widget() && Fl_Flex_Type::parent_is_flex(o)) { Fl_Widget* w = (Fl_Widget*)((Fl_Widget_Type*)o)->o; Fl_Flex* f = (Fl_Flex*)((Fl_Flex_Type*)o->parent)->o; int was_fixed = f->set_size(w); if (new_fixed==0) { if (was_fixed) { f->set_size(w, 0); f->layout(); mod = 1; } } else { if (!was_fixed) { f->set_size(w, Fl_Flex_Type::size(o)); f->layout(); mod = 1; } } } } if (mod) set_modflag(1); } } //////////////////////////////////////////////////////////////// // subtypes: Fl_Menu_Item *Fl_Widget_Type::subtypes() {return 0;} void subtype_cb(Fl_Choice* i, void* v) { static Fl_Menu_Item empty_type_menu[] = { {"Normal",0,0,(void*)0}, {0}}; if (v == LOAD) { Fl_Menu_Item* m = current_widget->subtypes(); if (!m) { i->menu(empty_type_menu); i->value(0); i->deactivate(); } else { i->menu(m); int j; for (j = 0;; j++) { if (!m[j].text) {j = 0; break;} if (current_widget->is_spinner()) { if (m[j].argument() == ((Fl_Spinner*)current_widget->o)->type()) break; } else { if (m[j].argument() == current_widget->o->type()) break; } } i->value(j); i->activate(); } i->redraw(); } else { int mod = 0; 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) { if (q->is_spinner()) ((Fl_Spinner*)q->o)->type(n); else if (q->is_flex()) ((Fl_Flex_Type*)q)->change_subtype_to(n); else q->o->type(n); q->redraw(); mod = 1; } } } if (mod) set_modflag(1); } } //////////////////////////////////////////////////////////////// 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.cxx void overlay_cb(Fl_Button*o,void *v) { toggle_overlays(o,v); } void leave_live_mode_cb(Fl_Widget*, void*); void live_mode_cb(Fl_Button*o,void *) { /// \todo live mode should end gracefully when the application quits /// or when the user closes the live widget static Fl_Type *live_type = 0L; static Fl_Widget *live_widget = 0L; static Fl_Window *live_window = 0L; // if 'o' is 0, we must quit live mode if (!o) { o = wLiveMode; o->value(0); } if (o->value()) { if (numselected == 1) { Fl_Group::current(0L); live_widget = current_widget->enter_live_mode(1); if (live_widget) { live_type = current_widget; Fl_Group::current(0); int w = live_widget->w(); int h = live_widget->h(); live_window = new Fl_Double_Window(w+20, h+55, "Fluid Live Resize"); live_window->box(FL_FLAT_BOX); live_window->color(FL_GREEN); Fl_Group *rsz = new Fl_Group(0, h+20, 130, 35); rsz->box(FL_NO_BOX); Fl_Box *rsz_dummy = new Fl_Box(110, h+20, 1, 25); rsz_dummy->box(FL_NO_BOX); rsz->resizable(rsz_dummy); Fl_Button *btn = new Fl_Button(10, h+20, 100, 25, "Exit Live Resize"); btn->labelsize(12); btn->callback(leave_live_mode_cb); rsz->end(); live_window->add(live_widget); live_widget->position(10, 10); live_window->resizable(live_widget); live_window->set_modal(); // block all other UI live_window->callback(leave_live_mode_cb); if (current_widget->is_window()) { Fl_Window_Type *w = (Fl_Window_Type*)current_widget; int mw = w->sr_min_w; if (mw>0) mw += 20; int mh = w->sr_min_h; if (mh>0) mh += 55; int MW = w->sr_max_w; if (MW>0) MW += 20; int MH = w->sr_max_h; if (MH>2) MH += 55; if (mw || mh || MW || MH) live_window->size_range(mw, mh, MW, MH); } live_window->show(); live_widget->show(); } else o->value(0); } else o->value(0); } else { if (live_type) live_type->leave_live_mode(); if (live_window) { live_window->hide(); Fl::delete_widget(live_window); } live_type = 0L; live_widget = 0L; live_window = 0L; } } // 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(); } extern void redraw_overlays(); extern void check_redraw_corresponding_parent(Fl_Type*); extern void redraw_browser(); extern void update_sourceview_position(); // 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; check_redraw_corresponding_parent(p); redraw_overlays(); // load the panel with the new settings: load_panel(); // update the source viewer to show the code for the selected object update_sourceview_position(); } //////////////////////////////////////////////////////////////// // 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=='\n') && *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) {/*empty*/} 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() || (is_class() && !strncmp(t, "Fl_", 3))) { write_declare("#include "); write_declare("#include ", 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())) { int write_extern_declaration = 1; const Fl_Class_Type *cc = is_in_class(); char buf[1024]; snprintf(buf, 1023, "%s(*)", callback()); if (cc) { if (cc->has_function("static void", buf)) write_extern_declaration = 0; } else { if (has_toplevel_function(0L, buf)) write_extern_declaration = 0; } if (write_extern_declaration) write_declare("extern void %s(%s*, %s);", callback(), t, user_data_type() ? user_data_type() : "void*"); } const char* k = class_name(1); const char* c = array_name(this); if (c && !k && !is_class()) { 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("\nvoid %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"); write_c_indented(callback(), 1, 0); if (*(d-1) != ';' && *(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((%s*)(o", indent(1), k); Fl_Type *q = 0; for (Fl_Type* p = parent; p && p->is_widget(); q = p, p = p->parent) write_c("->parent()"); if (!q || strcmp(q->type_name(), "widget_class")) write_c("->user_data()"); write_c("))->%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; } } } 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 *%s;\n", indent(1), 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("%sinline void %s_i(%s*, %s);\n", indent(1), cn, t, ut); write_h("%sstatic void %s(%s*, %s);\n", indent(1), cn, t, ut); } // figure out if local variable will be used (prevent compiler warnings): int wused = !name() && is_window(); const char *ptr; varused = wused; if (!name() && !varused) { varused |= is_parent(); if (!varused) { varused_test = 1; write_widget_code(); varused_test = 0; } } if (!varused) { for (int n=0; n < NUM_EXTRA_CODE; n++) if (extra_code(n) && !isdeclare(extra_code(n))) { int instring = 0; int inname = 0; for (ptr = extra_code(n); *ptr; ptr ++) { if (instring) { if (*ptr == '\\') ptr++; else if (*ptr == '\"') instring = 0; } else if (inname && !isalnum(*ptr & 255)) inname = 0; else if (*ptr == '\"') instring = 1; else if (isalnum(*ptr & 255) || *ptr == '_') { size_t len = strspn(ptr, "0123456789_" "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); if (!strncmp(ptr, "o", len)) { varused = 1; break; } else ptr += len - 1; } } } } write_c("%s{ ", indent()); write_comment_inline_c(); 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 (P.i18n_type) { case 0 : /* None */ write_cstring(label()); break; case 1 : /* GNU gettext */ write_c("%s(", P.i18n_function.value()); write_cstring(label()); write_c(")"); break; case 2 : /* POSIX catgets */ write_c("catgets(%s,%s,%d,", P.i18n_file[0] ? P.i18n_file.value() : "_catalog", P.i18n_set.value(), msgnum()); write_cstring(label()); write_c(")"); break; } } write_c(");\n"); indentation++; // Avoid compiler warning for unused variable. // Also avoid quality control warnings about incorrect allocation error handling. if (wused) write_c("%sw = o; (void)w;\n", indent()); write_widget_code(); } void Fl_Widget_Type::write_color(const char* field, Fl_Color color) { const char* color_name = 0; switch (color) { case FL_FOREGROUND_COLOR: color_name = "FL_FOREGROUND_COLOR"; break; case FL_BACKGROUND2_COLOR: color_name = "FL_BACKGROUND2_COLOR"; break; case FL_INACTIVE_COLOR: color_name = "FL_INACTIVE_COLOR"; break; case FL_SELECTION_COLOR: color_name = "FL_SELECTION_COLOR"; break; case FL_GRAY0: color_name = "FL_GRAY0"; break; case FL_DARK3: color_name = "FL_DARK3"; break; case FL_DARK2: color_name = "FL_DARK2"; break; case FL_DARK1: color_name = "FL_DARK1"; break; case FL_BACKGROUND_COLOR: color_name = "FL_BACKGROUND_COLOR"; break; case FL_LIGHT1: color_name = "FL_LIGHT1"; break; case FL_LIGHT2: color_name = "FL_LIGHT2"; break; case FL_LIGHT3: color_name = "FL_LIGHT3"; break; case FL_BLACK: color_name = "FL_BLACK"; break; case FL_RED: color_name = "FL_RED"; break; case FL_GREEN: color_name = "FL_GREEN"; break; case FL_YELLOW: color_name = "FL_YELLOW"; break; case FL_BLUE: color_name = "FL_BLUE"; break; case FL_MAGENTA: color_name = "FL_MAGENTA"; break; case FL_CYAN: color_name = "FL_CYAN"; break; case FL_DARK_RED: color_name = "FL_DARK_RED"; break; case FL_DARK_GREEN: color_name = "FL_DARK_GREEN"; break; case FL_DARK_YELLOW: color_name = "FL_DARK_YELLOW"; break; case FL_DARK_BLUE: color_name = "FL_DARK_BLUE"; break; case FL_DARK_MAGENTA: color_name = "FL_DARK_MAGENTA"; break; case FL_DARK_CYAN: color_name = "FL_DARK_CYAN"; break; case FL_WHITE: color_name = "FL_WHITE"; break; } const char *var = is_class() ? "this" : name() ? name() : "o"; if (color_name) { write_c("%s%s->%s(%s);\n", indent(), var, field, color_name); } else { write_c("%s%s->%s((Fl_Color)%d);\n", indent(), var, field, color); } } // 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; const char *var = is_class() ? "this" : name() ? name() : "o"; if (tooltip() && *tooltip()) { write_c("%s%s->tooltip(",indent(), var); switch (P.i18n_type) { case 0 : /* None */ write_cstring(tooltip()); break; case 1 : /* GNU gettext */ write_c("%s(", P.i18n_function.value()); write_cstring(tooltip()); write_c(")"); break; case 2 : /* POSIX catgets */ write_c("catgets(%s,%s,%d,", P.i18n_file[0] ? P.i18n_file.value() : "_catalog", P.i18n_set.value(), msgnum() + 1); write_cstring(tooltip()); write_c(")"); break; } write_c(");\n"); } if (is_spinner() && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type()) write_c("%s%s->type(%d);\n", indent(), var, ((Fl_Spinner*)o)->type()); else if (o->type() != tplate->type() && !is_window()) write_c("%s%s->type(%d);\n", indent(), var, o->type()); if (o->box() != tplate->box() || subclass()) write_c("%s%s->box(FL_%s);\n", indent(), var, boxname(o->box())); // write shortcut command if needed int shortcut = 0; if (is_button()) shortcut = ((Fl_Button*)o)->shortcut(); else if (is_input()) shortcut = ((Fl_Input_*)o)->shortcut(); else if (is_value_input()) shortcut = ((Fl_Value_Input*)o)->shortcut(); else if (is_text_display()) shortcut = ((Fl_Text_Display*)o)->shortcut(); if (shortcut) { if (P.use_FL_COMMAND && (shortcut & (FL_CTRL|FL_META))) { write_c("%s%s->shortcut(FL_COMMAND|0x%x);\n", indent(), var, shortcut & ~(FL_CTRL|FL_META)); } else { write_c("%s%s->shortcut(0x%x);\n", indent(), var, shortcut); } } if (is_button()) { Fl_Button* b = (Fl_Button*)o; if (b->down_box()) write_c("%s%s->down_box(FL_%s);\n", indent(), var, boxname(b->down_box())); if (b->value()) write_c("%s%s->value(1);\n", indent(), var); } else if (!strcmp(type_name(), "Fl_Input_Choice")) { Fl_Input_Choice* b = (Fl_Input_Choice*)o; if (b->down_box()) write_c("%s%s->down_box(FL_%s);\n", indent(), var, boxname(b->down_box())); } else if (is_menu_button()) { Fl_Menu_* b = (Fl_Menu_*)o; if (b->down_box()) write_c("%s%s->down_box(FL_%s);\n", indent(), var, boxname(b->down_box())); } if (o->color() != tplate->color() || subclass()) write_color("color", o->color()); if (o->selection_color() != tplate->selection_color() || subclass()) write_color("selection_color", o->selection_color()); if (image) image->write_code(var); if (inactive) inactive->write_code(var, 1); if (o->labeltype() != tplate->labeltype() || subclass()) write_c("%s%s->labeltype(FL_%s);\n", indent(), var, item_name(labeltypemenu, o->labeltype())); if (o->labelfont() != tplate->labelfont() || subclass()) write_c("%s%s->labelfont(%d);\n", indent(), var, o->labelfont()); if (o->labelsize() != tplate->labelsize() || subclass()) write_c("%s%s->labelsize(%d);\n", indent(), var, o->labelsize()); if (o->labelcolor() != tplate->labelcolor() || subclass()) write_color("labelcolor", o->labelcolor()); if (is_valuator()) { Fl_Valuator* v = (Fl_Valuator*)o; Fl_Valuator* f = (Fl_Valuator*)(tplate); if (v->minimum()!=f->minimum()) write_c("%s%s->minimum(%g);\n", indent(), var, v->minimum()); if (v->maximum()!=f->maximum()) write_c("%s%s->maximum(%g);\n", indent(), var, v->maximum()); if (v->step()!=f->step()) write_c("%s%s->step(%g);\n", indent(), var, v->step()); if (v->value()) { if (is_valuator()==3) { // Fl_Scrollbar::value(double) is nott available write_c("%s%s->Fl_Slider::value(%g);\n", indent(), var, v->value()); } else { write_c("%s%s->value(%g);\n", indent(), var, v->value()); } } if (is_valuator()>=2) { double x = ((Fl_Slider*)v)->slider_size(); double y = ((Fl_Slider*)f)->slider_size(); if (x != y) write_c("%s%s->slider_size(%g);\n", indent(), var, x); } } if (is_spinner()) { Fl_Spinner* v = (Fl_Spinner*)o; Fl_Spinner* f = (Fl_Spinner*)(tplate); if (v->minimum()!=f->minimum()) write_c("%s%s->minimum(%g);\n", indent(), var, v->minimum()); if (v->maximum()!=f->maximum()) write_c("%s%s->maximum(%g);\n", indent(), var, v->maximum()); if (v->step()!=f->step()) write_c("%s%s->step(%g);\n", indent(), var, v->step()); if (v->value()!=1.0f) write_c("%s%s->value(%g);\n", indent(), var, v->value()); } {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) { Fl_Font f; int s; Fl_Color c; textstuff(0,f,s,c); if (f != ff) write_c("%s%s->textfont(%d);\n", indent(), var, f); if (s != fs) write_c("%s%s->textsize(%d);\n", indent(), var, s); if (c != fc) write_color("textcolor", c); }} const char* ud = user_data(); if (class_name(1) && !parent->is_widget()) ud = "this"; if (callback()) { write_c("%s%s->callback((Fl_Callback*)%s", indent(), var, callback_name()); if (ud) write_c(", (void*)(%s));\n", ud); else write_c(");\n"); } else if (ud) { write_c("%s%s->user_data((void*)(%s));\n", indent(), var, ud); } if (o->align() != tplate->align() || subclass()) { int i = o->align(); write_c("%s%s->align(Fl_Align(%s", indent(), var, item_name(alignmenu, i & ~FL_ALIGN_INSIDE)); if (i & FL_ALIGN_INSIDE) write_c("|FL_ALIGN_INSIDE"); write_c("));\n"); } Fl_When ww = o->when(); if (ww==FL_WHEN_NOT_CHANGED) ww = FL_WHEN_NEVER; if (ww != tplate->when() || subclass()) write_c("%s%s->when(%s);\n", indent(), var, item_name(whensymbolmenu, ww)); if (!o->visible() && o->parent()) write_c("%s%s->hide();\n", indent(), var); if (!o->active()) write_c("%s%s->deactivate();\n", indent(), var); if (!is_group() && resizable()) write_c("%sFl_Group::current()->resizable(%s);\n", indent(), var); if (hotspot()) { if (is_class()) write_c("%shotspot(%s);\n", indent(), var); else if (is_window()) write_c("%s%s->hotspot(%s);\n", indent(), var, var); else write_c("%s%s->window()->hotspot(%s);\n", indent(), var, var); } } void Fl_Widget_Type::write_extra_code() { for (int n=0; n < NUM_EXTRA_CODE; n++) if (extra_code(n) && !isdeclare(extra_code(n))) write_c("%s%s\n", indent(), extra_code(n)); } void Fl_Widget_Type::write_block_close() { indentation--; write_c("%s} // %s* %s\n", indent(), subclassname(this), name() ? name() : "o"); } void Fl_Widget_Type::write_code2() { write_extra_code(); write_block_close(); } //////////////////////////////////////////////////////////////// void Fl_Widget_Type::write_properties() { Fl_Type::write_properties(); write_indent(level+1); switch (public_) { case 0: write_string("private"); break; case 1: break; case 2: write_string("protected"); break; } if (tooltip() && *tooltip()) { write_string("tooltip"); write_word(tooltip()); } if (image_name() && *image_name()) { write_string("image"); write_word(image_name()); } if (inactive_name() && *inactive_name()) { write_string("deimage"); write_word(inactive_name()); } write_string("xywh {%d %d %d %d}", o->x(), o->y(), o->w(), o->h()); Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o; if (is_spinner() && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type()) { write_string("type"); write_word(item_name(subtypes(), ((Fl_Spinner*)o)->type())); } else if (subtypes() && (o->type() != tplate->type() || is_window())) { write_string("type"); write_word(item_name(subtypes(), o->type())); } if (o->box() != tplate->box()) { write_string("box"); write_word(boxname(o->box()));} if (is_input()) { Fl_Input_* b = (Fl_Input_*)o; if (b->shortcut()) write_string("shortcut 0x%x", b->shortcut()); } if (is_value_input()) { Fl_Value_Input* b = (Fl_Value_Input*)o; if (b->shortcut()) write_string("shortcut 0x%x", b->shortcut()); } if (is_text_display()) { Fl_Text_Display* b = (Fl_Text_Display*)o; if (b->shortcut()) write_string("shortcut 0x%x", b->shortcut()); } if (is_button()) { Fl_Button* b = (Fl_Button*)o; if (b->down_box()) { write_string("down_box"); write_word(boxname(b->down_box()));} if (b->shortcut()) write_string("shortcut 0x%x", b->shortcut()); if (b->value()) write_string("value 1"); } else if (!strcmp(type_name(), "Fl_Input_Choice")) { Fl_Input_Choice* b = (Fl_Input_Choice*)o; if (b->down_box()) { write_string("down_box"); write_word(boxname(b->down_box()));} } else if (is_menu_button()) { Fl_Menu_* b = (Fl_Menu_*)o; if (b->down_box()) { write_string("down_box"); write_word(boxname(b->down_box()));} } if (o->color()!=tplate->color()) write_string("color %d", o->color()); if (o->selection_color()!=tplate->selection_color()) write_string("selection_color %d", o->selection_color()); if (o->labeltype()!=tplate->labeltype()) { write_string("labeltype"); write_word(item_name(labeltypemenu, o->labeltype())); } if (o->labelfont()!=tplate->labelfont()) write_string("labelfont %d", o->labelfont()); if (o->labelsize()!=tplate->labelsize()) write_string("labelsize %d", o->labelsize()); if (o->labelcolor()!=tplate->labelcolor()) write_string("labelcolor %d", o->labelcolor()); if (o->align()!=tplate->align()) write_string("align %d", o->align()); if (o->when() != tplate->when()) write_string("when %d", o->when()); if (is_valuator()) { Fl_Valuator* v = (Fl_Valuator*)o; Fl_Valuator* f = (Fl_Valuator*)(tplate); if (v->minimum()!=f->minimum()) write_string("minimum %g",v->minimum()); if (v->maximum()!=f->maximum()) write_string("maximum %g",v->maximum()); if (v->step()!=f->step()) write_string("step %g",v->step()); if (v->value()!=0.0) write_string("value %g",v->value()); if (is_valuator()>=2) { double x = ((Fl_Slider*)v)->slider_size(); double y = ((Fl_Slider*)f)->slider_size(); if (x != y) write_string("slider_size %g", x); } } if (is_spinner()) { Fl_Spinner* v = (Fl_Spinner*)o; Fl_Spinner* f = (Fl_Spinner*)(tplate); if (v->minimum()!=f->minimum()) write_string("minimum %g",v->minimum()); if (v->maximum()!=f->maximum()) write_string("maximum %g",v->maximum()); if (v->step()!=f->step()) write_string("step %g",v->step()); if (v->value()!=1.0) write_string("value %g",v->value()); } {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) { Fl_Font f; int s; Fl_Color c; textstuff(0,f,s,c); if (f != ff) write_string("textfont %d", f); if (s != fs) write_string("textsize %d", s); if (c != fc) write_string("textcolor %d", c); }} if (!o->visible()) write_string("hide"); if (!o->active()) write_string("deactivate"); if (resizable()) write_string("resizable"); if (hotspot()) write_string(is_menu_item() ? "divider" : "hotspot"); for (int n=0; n < NUM_EXTRA_CODE; n++) if (extra_code(n)) { write_indent(level+1); write_string("code%d",n); write_word(extra_code(n)); } if (subclass()) { write_indent(level+1); write_string("class"); write_word(subclass()); } } void Fl_Widget_Type::read_property(const char *c) { int x,y,w,h; Fl_Font f; int s; Fl_Color cc; if (!strcmp(c,"private")) { public_ = 0; } else if (!strcmp(c,"protected")) { public_ = 2; } else if (!strcmp(c,"xywh")) { if (sscanf(read_word(),"%d %d %d %d",&x,&y,&w,&h) == 4) { x += pasteoffset; y += pasteoffset; // FIXME temporary change! if (read_version>=2.0 && o->parent() && o->parent()!=o->window()) { x += o->parent()->x(); y += o->parent()->y(); } o->resize(x,y,w,h); } } else if (!strcmp(c,"tooltip")) { tooltip(read_word()); } else if (!strcmp(c,"image")) { image_name(read_word()); } else if (!strcmp(c,"deimage")) { inactive_name(read_word()); } else if (!strcmp(c,"type")) { if (is_spinner()) ((Fl_Spinner*)o)->type(item_number(subtypes(), read_word())); else o->type(item_number(subtypes(), read_word())); } else if (!strcmp(c,"box")) { const char* value = read_word(); if ((x = boxnumber(value))) { if (x == ZERO_ENTRY) x = 0; o->box((Fl_Boxtype)x); } else if (sscanf(value,"%d",&x) == 1) o->box((Fl_Boxtype)x); } else if (is_button() && !strcmp(c,"down_box")) { const char* value = read_word(); if ((x = boxnumber(value))) { if (x == ZERO_ENTRY) x = 0; ((Fl_Button*)o)->down_box((Fl_Boxtype)x); } } else if (!strcmp(type_name(), "Fl_Input_Choice") && !strcmp(c,"down_box")) { const char* value = read_word(); if ((x = boxnumber(value))) { if (x == ZERO_ENTRY) x = 0; ((Fl_Input_Choice*)o)->down_box((Fl_Boxtype)x); } } else if (is_menu_button() && !strcmp(c,"down_box")) { const char* value = read_word(); if ((x = boxnumber(value))) { if (x == ZERO_ENTRY) x = 0; ((Fl_Menu_*)o)->down_box((Fl_Boxtype)x); } } else if (is_button() && !strcmp(c,"value")) { const char* value = read_word(); ((Fl_Button*)o)->value(atoi(value)); } else if (!strcmp(c,"color")) { const char *cw = read_word(); if (cw[0]=='0' && cw[1]=='x') { sscanf(cw,"0x%x",&x); o->color(x); } else { int n = sscanf(cw,"%d %d",&x,&y); if (n == 2) { // back compatibility... if (x != 47) o->color(x); o->selection_color(y); } else { o->color(x); } } } else if (!strcmp(c,"selection_color")) { if (sscanf(read_word(),"%d",&x)) o->selection_color(x); } else if (!strcmp(c,"labeltype")) { c = read_word(); if (!strcmp(c,"image")) { Fluid_Image *i = Fluid_Image::find(label()); if (!i) read_error("Image file '%s' not found", label()); else setimage(i); image_name(label()); label(""); } else { o->labeltype((Fl_Labeltype)item_number(labeltypemenu,c)); } } else if (!strcmp(c,"labelfont")) { if (sscanf(read_word(),"%d",&x) == 1) o->labelfont(x); } else if (!strcmp(c,"labelsize")) { if (sscanf(read_word(),"%d",&x) == 1) o->labelsize(x); } else if (!strcmp(c,"labelcolor")) { if (sscanf(read_word(),"%d",&x) == 1) o->labelcolor(x); } else if (!strcmp(c,"align")) { if (sscanf(read_word(),"%d",&x) == 1) o->align(x); } else if (!strcmp(c,"when")) { if (sscanf(read_word(),"%d",&x) == 1) o->when(x); } else if (!strcmp(c,"minimum")) { if (is_valuator()) ((Fl_Valuator*)o)->minimum(strtod(read_word(),0)); if (is_spinner()) ((Fl_Spinner*)o)->minimum(strtod(read_word(),0)); } else if (!strcmp(c,"maximum")) { if (is_valuator()) ((Fl_Valuator*)o)->maximum(strtod(read_word(),0)); if (is_spinner()) ((Fl_Spinner*)o)->maximum(strtod(read_word(),0)); } else if (!strcmp(c,"step")) { if (is_valuator()) ((Fl_Valuator*)o)->step(strtod(read_word(),0)); if (is_spinner()) ((Fl_Spinner*)o)->step(strtod(read_word(),0)); } else if (!strcmp(c,"value")) { if (is_valuator()) ((Fl_Valuator*)o)->value(strtod(read_word(),0)); if (is_spinner()) ((Fl_Spinner*)o)->value(strtod(read_word(),0)); } else if ((!strcmp(c,"slider_size")||!strcmp(c,"size"))&&is_valuator()==2) { ((Fl_Slider*)o)->slider_size(strtod(read_word(),0)); } else if (!strcmp(c,"textfont")) { if (sscanf(read_word(),"%d",&x) == 1) {f=(Fl_Font)x; textstuff(1,f,s,cc);} } else if (!strcmp(c,"textsize")) { if (sscanf(read_word(),"%d",&x) == 1) {s=x; textstuff(2,f,s,cc);} } else if (!strcmp(c,"textcolor")) { if (sscanf(read_word(),"%d",&x) == 1) {cc=(Fl_Color)x;textstuff(3,f,s,cc);} } else if (!strcmp(c,"hide")) { o->hide(); } else if (!strcmp(c,"deactivate")) { o->deactivate(); } else if (!strcmp(c,"resizable")) { resizable(1); } else if (!strcmp(c,"hotspot") || !strcmp(c, "divider")) { hotspot(1); } else if (!strcmp(c,"class")) { subclass(read_word()); } else if (!strcmp(c,"shortcut")) { int shortcut = strtol(read_word(),0,0); if (is_button()) ((Fl_Button*)o)->shortcut(shortcut); else if (is_input()) ((Fl_Input_*)o)->shortcut(shortcut); else if (is_value_input()) ((Fl_Value_Input*)o)->shortcut(shortcut); else if (is_text_display()) ((Fl_Text_Display*)o)->shortcut(shortcut); } else { if (!strncmp(c,"code",4)) { int n = atoi(c+4); if (n >= 0 && n <= NUM_EXTRA_CODE) { extra_code(n,read_word()); return; } } else if (!strcmp(c,"extra_code")) { extra_code(0,read_word()); return; } Fl_Type::read_property(c); } } Fl_Menu_Item boxmenu1[] = { // these extra ones are for looking up fdesign saved strings: {"NO_FRAME", 0,0,(void *)FL_NO_BOX}, {"ROUNDED3D_UPBOX", 0,0,(void *)_FL_ROUND_UP_BOX}, {"ROUNDED3D_DOWNBOX", 0,0,(void *)_FL_ROUND_DOWN_BOX}, {"OVAL3D_UPBOX", 0,0,(void *)_FL_ROUND_UP_BOX}, {"OVAL3D_DOWNBOX", 0,0,(void *)_FL_ROUND_DOWN_BOX}, {"0", 0,0,(void *)ZERO_ENTRY}, {"1", 0,0,(void *)FL_UP_BOX}, {"2", 0,0,(void *)FL_DOWN_BOX}, {"3", 0,0,(void *)FL_FLAT_BOX}, {"4", 0,0,(void *)FL_BORDER_BOX}, {"5", 0,0,(void *)FL_SHADOW_BOX}, {"6", 0,0,(void *)FL_FRAME_BOX}, {"7", 0,0,(void *)FL_ROUNDED_BOX}, {"8", 0,0,(void *)FL_RFLAT_BOX}, {"9", 0,0,(void *)FL_RSHADOW_BOX}, {"10", 0,0,(void *)FL_UP_FRAME}, {"11", 0,0,(void *)FL_DOWN_FRAME}, {0}}; int lookup_symbol(const char *, int &, int numberok = 0); int Fl_Widget_Type::read_fdesign(const char* propname, const char* value) { int v; if (!strcmp(propname,"box")) { float x,y,w,h; if (sscanf(value,"%f %f %f %f",&x,&y,&w,&h) == 4) { if (fdesign_flip) { Fl_Type *p; for (p = parent; p && !p->is_window(); p = p->parent) {/*empty*/} if (p && p->is_widget()) y = ((Fl_Widget_Type*)p)->o->h()-(y+h); } x += pasteoffset; y += pasteoffset; o->resize(int(x),int(y),int(w),int(h)); } } else if (!strcmp(propname,"label")) { label(value); } else if (!strcmp(propname,"name")) { this->name(value); } else if (!strcmp(propname,"callback")) { callback(value); user_data_type("long"); } else if (!strcmp(propname,"argument")) { user_data(value); } else if (!strcmp(propname,"shortcut")) { if (value[0]) { char buf[128]; sprintf(buf,"o->shortcut(\"%s\");",value); extra_code(0,buf); } } else if (!strcmp(propname,"style")) { if (!strncmp(value,"FL_NORMAL",9)) return 1; if (!lookup_symbol(value,v,1)) return 0; o->labelfont(v); o->labeltype((Fl_Labeltype)(v>>8)); } else if (!strcmp(propname,"size")) { if (!lookup_symbol(value,v,1)) return 0; o->labelsize(v); } else if (!strcmp(propname,"type")) { if (!strncmp(value,"NORMAL",6)) return 1; if (lookup_symbol(value,v,1)) {o->type(v); return 1;} if (!strcmp(value+strlen(value)-5,"FRAME")) goto TRY_BOXTYPE; if (!strcmp(value+strlen(value)-3,"BOX")) goto TRY_BOXTYPE; return 0; } else if (!strcmp(propname,"lcol")) { if (!lookup_symbol(value,v,1)) return 0; o->labelcolor(v); } else if (!strcmp(propname,"return")) { if (!lookup_symbol(value,v,0)) return 0; o->when(v|FL_WHEN_RELEASE); } else if (!strcmp(propname,"alignment")) { if (!lookup_symbol(value,v)) { // convert old numeric values: int v1 = atoi(value); if (v1 <= 0 && strcmp(value,"0")) return 0; v = 0; if (v1 >= 5) {v = FL_ALIGN_INSIDE; v1 -= 5;} switch (v1) { case 0: v += FL_ALIGN_TOP; break; case 1: v += FL_ALIGN_BOTTOM; break; case 2: v += FL_ALIGN_LEFT; break; case 3: v += FL_ALIGN_RIGHT; break; case 4: v += FL_ALIGN_CENTER; break; default: return 0; } } o->align(v); } else if (!strcmp(propname,"resizebox")) { resizable(1); } else if (!strcmp(propname,"colors")) { char* p = (char*)value; while (*p != ' ') {if (!*p) return 0; p++;} *p = 0; int v1; if (!lookup_symbol(value,v,1) || !lookup_symbol(p+1,v1,1)) { *p=' '; return 0;} o->color(v,v1); } else if (!strcmp(propname,"resize")) { return !strcmp(value,"FL_RESIZE_ALL"); } else if (!strcmp(propname,"gravity")) { return !strcmp(value,"FL_NoGravity FL_NoGravity"); } else if (!strcmp(propname,"boxtype")) { TRY_BOXTYPE: int x = boxnumber(value); if (!x) {x = item_number(boxmenu1, value); if (x < 0) return 0;} if (x == ZERO_ENTRY) { x = 0; if (o->box() != ((Fl_Widget_Type*)factory)->o->box()) return 1; // kludge for frame } o->box((Fl_Boxtype)x); } else { return 0; } return 1; } void leave_live_mode_cb(Fl_Widget*, void*) { live_mode_cb(0, 0); } Fl_Widget *Fl_Widget_Type::enter_live_mode(int) { live_widget = widget(o->x(), o->y(), o->w(), o->h()); if (live_widget) copy_properties(); return live_widget; } void Fl_Widget_Type::leave_live_mode() { } /** copy all properties from the edit widget to the live widget */ void Fl_Widget_Type::copy_properties() { if (!live_widget) return; // copy all attributes common to all widget types Fl_Widget *w = live_widget; w->label(o->label()); w->tooltip(tooltip()); w->type(o->type()); w->box(o->box()); w->color(o->color()); w->selection_color(o->selection_color()); w->labeltype(o->labeltype()); w->labelfont(o->labelfont()); w->labelsize(o->labelsize()); w->labelcolor(o->labelcolor()); w->align(o->align()); // copy all attributes specific to widgets derived from Fl_Button if (is_button()) { Fl_Button* d = (Fl_Button*)live_widget, *s = (Fl_Button*)o; d->down_box(s->down_box()); d->shortcut(s->shortcut()); d->value(s->value()); } // copy all attributes specific to widgets derived from Fl_Input_ if (is_input()) { Fl_Input_* d = (Fl_Input_*)live_widget, *s = (Fl_Input_*)o; d->shortcut(s->shortcut()); } // copy all attributes specific to widgets derived from Fl_Value_Input if (is_value_input()) { Fl_Value_Input* d = (Fl_Value_Input*)live_widget, *s = (Fl_Value_Input*)o; d->shortcut(s->shortcut()); } // copy all attributes specific to widgets derived from Fl_Text_Display if (is_text_display()) { Fl_Text_Display* d = (Fl_Text_Display*)live_widget, *s = (Fl_Text_Display*)o; d->shortcut(s->shortcut()); } // copy all attributes specific to Fl_Valuator and derived classes if (is_valuator()) { Fl_Valuator* d = (Fl_Valuator*)live_widget, *s = (Fl_Valuator*)o; d->minimum(s->minimum()); d->maximum(s->maximum()); d->step(s->step()); d->value(s->value()); if (is_valuator()>=2) { Fl_Slider *d = (Fl_Slider*)live_widget, *s = (Fl_Slider*)o; d->slider_size(s->slider_size()); } } // copy all attributes specific to Fl_Spinner and derived classes if (is_spinner()) { Fl_Spinner* d = (Fl_Spinner*)live_widget, *s = (Fl_Spinner*)o; d->minimum(s->minimum()); d->maximum(s->maximum()); d->step(s->step()); d->value(s->value()); } /* TODO: implement this {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) { Fl_Font f; int s; Fl_Color c; textstuff(0,f,s,c); if (f != ff) write_string("textfont %d", f); if (s != fs) write_string("textsize %d", s); if (c != fc) write_string("textcolor %d", c); }}*/ if (!o->visible()) w->hide(); if (!o->active()) w->deactivate(); if (resizable() && w->parent()) w->parent()->resizable(o); }