diff options
| -rw-r--r-- | fluid/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | fluid/Fl_Function_Type.cxx | 52 | ||||
| -rw-r--r-- | fluid/Fl_Function_Type.h | 16 | ||||
| -rw-r--r-- | fluid/Fl_Group_Type.cxx | 13 | ||||
| -rw-r--r-- | fluid/Fl_Group_Type.h | 2 | ||||
| -rw-r--r-- | fluid/Fl_Menu_Type.cxx | 78 | ||||
| -rw-r--r-- | fluid/Fl_Menu_Type.h | 8 | ||||
| -rw-r--r-- | fluid/Fl_Type.cxx | 110 | ||||
| -rw-r--r-- | fluid/Fl_Type.h | 22 | ||||
| -rw-r--r-- | fluid/Fl_Widget_Type.cxx | 14 | ||||
| -rw-r--r-- | fluid/Fl_Widget_Type.h | 2 | ||||
| -rw-r--r-- | fluid/Fl_Window_Type.cxx | 73 | ||||
| -rw-r--r-- | fluid/Fl_Window_Type.h | 4 | ||||
| -rw-r--r-- | fluid/Makefile | 1 | ||||
| -rw-r--r-- | fluid/Shortcut_Button.cxx | 192 | ||||
| -rw-r--r-- | fluid/Shortcut_Button.h | 14 | ||||
| -rw-r--r-- | fluid/factory.cxx | 231 | ||||
| -rw-r--r-- | fluid/factory.h | 9 | ||||
| -rw-r--r-- | fluid/file.cxx | 40 | ||||
| -rw-r--r-- | fluid/file.h | 4 | ||||
| -rw-r--r-- | fluid/fluid.cxx | 17 | ||||
| -rw-r--r-- | fluid/function_panel.cxx | 568 | ||||
| -rw-r--r-- | fluid/function_panel.fl | 69 | ||||
| -rw-r--r-- | fluid/undo.cxx | 9 |
24 files changed, 1256 insertions, 293 deletions
diff --git a/fluid/CMakeLists.txt b/fluid/CMakeLists.txt index d45b7b1b7..a9b3af1a7 100644 --- a/fluid/CMakeLists.txt +++ b/fluid/CMakeLists.txt @@ -24,6 +24,7 @@ set (CPPFILES Fl_Widget_Type.cxx Fl_Window_Type.cxx Fluid_Image.cxx + Shortcut_Button.cxx about_panel.cxx align_widget.cxx alignment_panel.cxx diff --git a/fluid/Fl_Function_Type.cxx b/fluid/Fl_Function_Type.cxx index 2f9a18075..ac367c7b9 100644 --- a/fluid/Fl_Function_Type.cxx +++ b/fluid/Fl_Function_Type.cxx @@ -187,15 +187,16 @@ Fl_Function_Type::~Fl_Function_Type() { /** Create a new function for the widget tree. + \param[in] strategy new function add after current or as last child \return the new node */ -Fl_Type *Fl_Function_Type::make() { +Fl_Type *Fl_Function_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_decl_block()) p = p->parent; Fl_Function_Type *o = new Fl_Function_Type(); o->name("make_window()"); o->return_type = 0; - o->add(p); + o->add(p, strategy); o->factory = this; o->public_ = 1; o->cdecl_ = 0; @@ -556,8 +557,10 @@ Fl_Code_Type::Fl_Code_Type() : Make a new code node. If the parent node is not a function, a message box will pop up and the request will be ignored. + \param[in] strategy add code after current or as last child + \return new Code node */ -Fl_Type *Fl_Code_Type::make() { +Fl_Type *Fl_Code_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_code_block()) p = p->parent; if (!p) { @@ -566,7 +569,7 @@ Fl_Type *Fl_Code_Type::make() { } Fl_Code_Type *o = new Fl_Code_Type(); o->name("printf(\"Hello, World!\\n\");"); - o->add(p); + o->add(p, strategy); o->factory = this; return o; } @@ -726,8 +729,10 @@ Fl_CodeBlock_Type::~Fl_CodeBlock_Type() { Make a new code block. If the parent node is not a function or another codeblock, a message box will pop up and the request will be ignored. + \param[in] strategy add after current or as last child + \return new CodeBlock */ -Fl_Type *Fl_CodeBlock_Type::make() { +Fl_Type *Fl_CodeBlock_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_code_block()) p = p->parent; if (!p) { @@ -737,7 +742,7 @@ Fl_Type *Fl_CodeBlock_Type::make() { Fl_CodeBlock_Type *o = new Fl_CodeBlock_Type(); o->name("if (test())"); o->after = 0; - o->add(p); + o->add(p, strategy); o->factory = this; return o; } @@ -851,15 +856,17 @@ int Fl_Decl_Type::is_public() const /** Make a new declaration. + \param[in] strategy add after current or as last child + \return new Declaration node */ -Fl_Type *Fl_Decl_Type::make() { +Fl_Type *Fl_Decl_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_decl_block()) p = p->parent; Fl_Decl_Type *o = new Fl_Decl_Type(); o->public_ = 0; o->static_ = 1; o->name("int x;"); - o->add(p); + o->add(p, strategy); o->factory = this; return o; } @@ -966,7 +973,7 @@ BREAK2: /** Write the code to the source and header files. \todo There are a lot of side effect in this node depending on the given text - and the parent node which should really be documented. + and the parent node. They need to be understood and documented. */ void Fl_Decl_Type::write_code1() { const char* c = name(); @@ -1063,8 +1070,10 @@ Fl_Data_Type::~Fl_Data_Type() { /** Create an empty inline data node. + \param[in] strategy add after current or as last child + \return new inline data node */ -Fl_Type *Fl_Data_Type::make() { +Fl_Type *Fl_Data_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_decl_block()) p = p->parent; Fl_Data_Type *o = new Fl_Data_Type(); @@ -1073,7 +1082,7 @@ Fl_Type *Fl_Data_Type::make() { o->filename_ = 0; o->text_mode_ = 0; o->name("myInlineData"); - o->add(p); + o->add(p, strategy); o->factory = this; return o; } @@ -1352,15 +1361,17 @@ int Fl_DeclBlock_Type::is_public() const {return public_;} /** Create a new declaration block. + \param[in] strategy add after current or as last child + \return new Declaration Blocknode */ -Fl_Type *Fl_DeclBlock_Type::make() { +Fl_Type *Fl_DeclBlock_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_decl_block()) p = p->parent; Fl_DeclBlock_Type *o = new Fl_DeclBlock_Type(); o->name("#if 1"); o->public_ = 0; o->after = fl_strdup("#endif"); - o->add(p); + o->add(p, strategy); o->factory = this; return o; } @@ -1479,8 +1490,10 @@ Fl_Comment_Type::Fl_Comment_Type() : /** Make a new comment node. + \param[in] strategy add after current or as last child + \return new Comment node */ -Fl_Type *Fl_Comment_Type::make() { +Fl_Type *Fl_Comment_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_code_block()) p = p->parent; Fl_Comment_Type *o = new Fl_Comment_Type(); @@ -1488,7 +1501,7 @@ Fl_Type *Fl_Comment_Type::make() { o->in_h_ = 1; o->style_ = 0; o->name("my comment"); - o->add(p); + o->add(p, strategy); o->factory = this; o->title_buf[0] = 0; return o; @@ -1735,9 +1748,6 @@ void Fl_Comment_Type::write_code1() { /** \class Fl_Class_Type Manage a class declaration and implementation. - - \todo This is pretty complex and needs to be revisited to give - a good description. */ /// Prototype for a class node to be used by the factory. @@ -1780,8 +1790,10 @@ void Fl_Class_Type::prefix(const char*p) { /** Make a new class node. + \param[in] strategy add after current or as last child + \return new Class node */ -Fl_Type *Fl_Class_Type::make() { +Fl_Type *Fl_Class_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_decl_block()) p = p->parent; Fl_Class_Type *o = new Fl_Class_Type(); @@ -1789,7 +1801,7 @@ Fl_Type *Fl_Class_Type::make() { o->class_prefix = NULL; o->subclass_of = NULL; o->public_ = 1; - o->add(p); + o->add(p, strategy); o->factory = this; return o; } diff --git a/fluid/Fl_Function_Type.h b/fluid/Fl_Function_Type.h index 7a6ac818e..2f0892047 100644 --- a/fluid/Fl_Function_Type.h +++ b/fluid/Fl_Function_Type.h @@ -49,7 +49,7 @@ class Fl_Function_Type : public Fl_Type { public: Fl_Function_Type(); ~Fl_Function_Type(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write_code1(); void write_code2(); void open(); @@ -77,7 +77,7 @@ class Fl_Code_Type : public Fl_Type { public: Fl_Code_Type(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write(); void write_code1(); void write_code2() { } @@ -100,7 +100,7 @@ class Fl_CodeBlock_Type : public Fl_Type { public: Fl_CodeBlock_Type(); ~Fl_CodeBlock_Type(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write_code1(); void write_code2(); void open(); @@ -123,7 +123,7 @@ protected: public: Fl_Decl_Type(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write_code1(); void write_code2() { } void open(); @@ -143,7 +143,7 @@ class Fl_Data_Type : public Fl_Decl_Type { public: Fl_Data_Type(); ~Fl_Data_Type(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write_code1(); void write_code2() {} void open(); @@ -162,7 +162,7 @@ class Fl_DeclBlock_Type : public Fl_Type { public: Fl_DeclBlock_Type(); ~Fl_DeclBlock_Type(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write_code1(); void write_code2(); void open(); @@ -183,7 +183,7 @@ class Fl_Comment_Type : public Fl_Type { public: Fl_Comment_Type(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write_code1(); void write_code2() { } void open(); @@ -210,7 +210,7 @@ public: char write_public_state; // true when public: has been printed Fl_Class_Type* parent_class; // save class if nested // - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write_code1(); void write_code2(); void open(); diff --git a/fluid/Fl_Group_Type.cxx b/fluid/Fl_Group_Type.cxx index a2a45a541..d5a832b17 100644 --- a/fluid/Fl_Group_Type.cxx +++ b/fluid/Fl_Group_Type.cxx @@ -42,8 +42,13 @@ void igroup::resize(int X, int Y, int W, int H) { Fl_Group_Type Fl_Group_type; // the "factory" -Fl_Type *Fl_Group_Type::make() { - return Fl_Widget_Type::make(); +/** + Create and add a new Group node. + \param[in] strategy add after current or as last child + \return new Group node + */ +Fl_Type *Fl_Group_Type::make(Strategy strategy) { + return Fl_Widget_Type::make(strategy); } void fix_group_size(Fl_Type *tt) { @@ -74,14 +79,14 @@ void group_cb(Fl_Widget *, void *) { } Fl_Widget_Type* q = (Fl_Widget_Type*)qq; force_parent = 1; - Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make()); + Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make(kAddAsLastChild)); n->move_before(q); n->o->resize(q->o->x(),q->o->y(),q->o->w(),q->o->h()); for (Fl_Type *t = Fl_Type::first; t;) { if (t->level != n->level || t == n || !t->selected) { t = t->next; continue;} Fl_Type *nxt = t->remove(); - t->add(n); + t->add(n, kAddAsLastChild); t = nxt; } fix_group_size(n); diff --git a/fluid/Fl_Group_Type.h b/fluid/Fl_Group_Type.h index a55e0dfd2..581f9ce3a 100644 --- a/fluid/Fl_Group_Type.h +++ b/fluid/Fl_Group_Type.h @@ -54,7 +54,7 @@ public: Fl_Widget *widget(int X,int Y,int W,int H) { igroup *g = new igroup(X,Y,W,H); Fl_Group::current(0); return g;} Fl_Widget_Type *_make() {return new Fl_Group_Type();} - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void write_code1(); void write_code2(); void add_child(Fl_Type*, Fl_Type*); diff --git a/fluid/Fl_Menu_Type.cxx b/fluid/Fl_Menu_Type.cxx index e3d6fec44..7bd55ce15 100644 --- a/fluid/Fl_Menu_Type.cxx +++ b/fluid/Fl_Menu_Type.cxx @@ -100,8 +100,12 @@ void Fl_Input_Choice_Type::build_menu() { o->redraw(); } - -Fl_Type *Fl_Menu_Item_Type::make() { +/** + Create and add a new Menu Item node. + \param[in] strategy add after current or as last child + \return new Menu Item node + */ +Fl_Type *Fl_Menu_Item_Type::make(Strategy strategy) { // Find the current menu item: Fl_Type* q = Fl_Type::current; Fl_Type* p = q; @@ -122,28 +126,43 @@ Fl_Type *Fl_Menu_Item_Type::make() { t->o = new Fl_Button(0,0,100,20); t->o->type(menuitemtype); t->factory = this; - t->add(p); + t->add(p, strategy); if (!reading_file) t->label(submenuflag ? "submenu" : "item"); return t; } -Fl_Type *Fl_Checkbox_Menu_Item_Type::make() { +/** + Create and add a new Checkbox Menu Item node. + \param[in] strategy add after current or as last child + \return new node + */ +Fl_Type *Fl_Checkbox_Menu_Item_Type::make(Strategy strategy) { menuitemtype = FL_MENU_TOGGLE; - Fl_Type* t = Fl_Menu_Item_Type::make(); + Fl_Type* t = Fl_Menu_Item_Type::make(strategy); menuitemtype = 0; return t; } -Fl_Type *Fl_Radio_Menu_Item_Type::make() { +/** + Create and add a new Radio ButtonMenu Item node. + \param[in] strategy add after current or as last child + \return new node + */ +Fl_Type *Fl_Radio_Menu_Item_Type::make(Strategy strategy) { menuitemtype = FL_MENU_RADIO; - Fl_Type* t = Fl_Menu_Item_Type::make(); + Fl_Type* t = Fl_Menu_Item_Type::make(strategy); menuitemtype = 0; return t; } -Fl_Type *Fl_Submenu_Type::make() { +/** + Create and add a new Submenu Item node. + \param[in] strategy add after current or as last child + \return new node + */ +Fl_Type *Fl_Submenu_Type::make(Strategy strategy) { submenuflag = 1; - Fl_Type* t = Fl_Menu_Item_Type::make(); + Fl_Type* t = Fl_Menu_Item_Type::make(strategy); submenuflag = 0; return t; } @@ -584,47 +603,6 @@ Fl_Menu_Bar_Type Fl_Menu_Bar_type; //////////////////////////////////////////////////////////////// // Shortcut entry item in panel: -void Shortcut_Button::draw() { - if (value()) draw_box(FL_DOWN_BOX, (Fl_Color)9); - else draw_box(FL_UP_BOX, FL_WHITE); - fl_font(FL_HELVETICA,14); fl_color(FL_FOREGROUND_COLOR); - if (use_FL_COMMAND && (svalue & (FL_CTRL|FL_META))) { - char buf[1024]; - fl_snprintf(buf, 1023, "Command+%s", fl_shortcut_label(svalue&~(FL_CTRL|FL_META))); - fl_draw(buf,x()+6,y(),w(),h(),FL_ALIGN_LEFT); - } else { - fl_draw(fl_shortcut_label(svalue),x()+6,y(),w(),h(),FL_ALIGN_LEFT); - } -} - -int Shortcut_Button::handle(int e) { - when(0); type(FL_TOGGLE_BUTTON); - if (e == FL_KEYBOARD) { - if (!value()) return 0; - int v = Fl::event_text()[0]; - if ( (v > 32 && v < 0x7f) || (v > 0xa0 && v <= 0xff) ) { - if (isupper(v)) { - v = tolower(v); - v |= FL_SHIFT; - } - v = v | (Fl::event_state()&(FL_META|FL_ALT|FL_CTRL)); - } else { - v = (Fl::event_state()&(FL_META|FL_ALT|FL_CTRL|FL_SHIFT)) | Fl::event_key(); - if (v == FL_BackSpace && svalue) v = 0; - } - if (v != svalue) {svalue = v; set_changed(); redraw(); do_callback(); } - return 1; - } else if (e == FL_UNFOCUS) { - int c = changed(); value(0); if (c) set_changed(); - return 1; - } else if (e == FL_FOCUS) { - return value(); - } else { - int r = Fl_Button::handle(e); - if (e == FL_RELEASE && value() && Fl::focus() != this) take_focus(); - return r; - } -} void shortcut_in_cb(Shortcut_Button* i, void* v) { if (v == LOAD) { diff --git a/fluid/Fl_Menu_Type.h b/fluid/Fl_Menu_Type.h index b42798d61..ddd58efae 100644 --- a/fluid/Fl_Menu_Type.h +++ b/fluid/Fl_Menu_Type.h @@ -36,7 +36,7 @@ public: Fl_Menu_Item* subtypes() {return menu_item_type_menu;} const char* type_name() {return "MenuItem";} const char* alt_type_name() {return "fltk::Item";} - Fl_Type* make(); + Fl_Type* make(Strategy strategy); int is_menu_item() const {return 1;} int is_button() const {return 1;} // this gets shortcut to work Fl_Widget* widget(int,int,int,int) {return 0;} @@ -53,14 +53,14 @@ public: class Fl_Radio_Menu_Item_Type : public Fl_Menu_Item_Type { public: const char* type_name() {return "RadioMenuItem";} - Fl_Type* make(); + Fl_Type* make(Strategy strategy); int pixmapID() { return 55; } }; class Fl_Checkbox_Menu_Item_Type : public Fl_Menu_Item_Type { public: const char* type_name() {return "CheckMenuItem";} - Fl_Type* make(); + Fl_Type* make(Strategy strategy); int pixmapID() { return 54; } }; @@ -71,7 +71,7 @@ public: const char* alt_type_name() {return "fltk::ItemGroup";} int is_parent() const {return 1;} int is_button() const {return 0;} // disable shortcut - Fl_Type* make(); + Fl_Type* make(Strategy strategy); // changes to submenu must propagate up so build_menu is called // on the parent Fl_Menu_Type: void add_child(Fl_Type*a, Fl_Type*b) {parent->add_child(a,b);} diff --git a/fluid/Fl_Type.cxx b/fluid/Fl_Type.cxx index ff6a48cf6..5608969ea 100644 --- a/fluid/Fl_Type.cxx +++ b/fluid/Fl_Type.cxx @@ -14,6 +14,9 @@ // https://www.fltk.org/bugs.php // +/// \defgroup fl_type Basic Node for all Widgets and Functions +/// \{ + /** \class Fl_Type Each object described by Fluid is one of these objects. They are all stored in a double-linked list. @@ -34,6 +37,7 @@ copied or otherwise examined. #include "Fl_Function_Type.h" #include "Fl_Widget_Type.h" #include "Fl_Window_Type.h" +#include "Fl_Group_Type.h" #include "widget_browser.h" #include "file.h" #include "code.h" @@ -53,6 +57,8 @@ copied or otherwise examined. Fl_Type *Fl_Type::first = NULL; Fl_Type *Fl_Type::last = NULL; +Fl_Type *Fl_Type::current = NULL; +Fl_Type *Fl_Type::current_dnd = NULL; Fl_Type *in_this_only; // set if menu popped-up in window @@ -217,6 +223,31 @@ void fixvisible(Fl_Type *p) { // ---- implemenation of Fl_Type +/** \var Fl_Type *Fl_Type::parent + Link to the parent node in the tree structure. + Used for simulating a tree structure via a doubly linked list. + */ +/** \var Fl_Type *Fl_Type::level + Zero based depth of the node within the tree structure. + Level is used to emulate a tree structure: the first node with a lower + level in the prev list would be the parent of this node. If the next member + has a higher level value, it is this nodes first child. At the same level, + it would be the first sibling. + */ +/** \var Fl_Type *Fl_Type::next + Points to the next node in the doubly linked list. + If this is NULL, we are at the end of the list. + Used for simulating a tree structure via a doubly linked list. + */ +/** \var Fl_Type *Fl_Type::prev + Link to the next node in the tree structure. + If this is NULL, we are at the beginning of the list. + Used for simulating a tree structure via a doubly linked list. + */ + +/** + Constructor and base for any node in the widget tree. + */ Fl_Type::Fl_Type() { factory = 0; parent = 0; @@ -235,11 +266,20 @@ Fl_Type::Fl_Type() { code_position_end = header_position_end = -1; } +/** + Destructor for any node in the tree. + + The destructor removes itself from the doubly linked list. This is dangerous, + because the node does not know if it is part of the widget tree, or if it is + in a seperate tree. We try to take care of that as well as possible. + */ Fl_Type::~Fl_Type() { // warning: destructor only works for widgets that have been add()ed. if (widget_browser) widget_browser->deleting(this); if (prev) prev->next = next; else first = next; if (next) next->prev = prev; else last = prev; + if (Fl_Type::last==this) Fl_Type::last = prev; + if (Fl_Type::first==this) Fl_Type::first = next; if (current == this) current = 0; if (parent) parent->remove_child(this); if (name_) free((void*)name_); @@ -259,26 +299,54 @@ const char* Fl_Type::title() { } /** - Add this list/tree of widgets as a new child of p. + Return the window that contains this widget. + \return NULL if this is not a widget. + */ +Fl_Window_Type *Fl_Type::window() { + if (!is_widget()) + return NULL; + for (Fl_Type *t = this; t; t=t->parent) + if (t->is_window()) + return (Fl_Window_Type*)t; + return NULL; +} + +/** + Return the group that contains this widget. + \return NULL if this is not a widget. + */ +Fl_Group_Type *Fl_Type::group() { + if (!is_widget()) + return NULL; + for (Fl_Type *t = this; t; t=t->parent) + if (t->is_group()) + return (Fl_Group_Type*)t; + return NULL; +} - \c this is not part of the widget browser. \c p should be in the +/** + Add this list/tree of widgets as a new last child of p. + + \c this must not be part of the widget browser. \c p however must be in the widget_browser, so \c Fl_Type::first and \c Fl_Type::last are valid for \c p. This methods updates the widget_browser. \param[in] p insert \c this tree as a child of \c p + \param[in] strategy is kAddAsLastChild or kAddAfterCurrent */ -void Fl_Type::add(Fl_Type *p) { +void Fl_Type::add(Fl_Type *p, Strategy strategy) { if (p && parent == p) return; undo_checkpoint(); parent = p; - // p is not in the Widget_Browser, so we must run the linked list to find the last entry + // 'this' is not in the Widget_Browser, so we must run the linked list to find the last entry Fl_Type *end = this; while (end->next) end = end->next; // run the list again to set the future node levels - Fl_Type *q; + Fl_Type *q; // insert 'this' before q int newlevel; if (p) { + // find the last node that is a child or grandchild of p for (q = p->next; q && q->level > p->level; q = q->next) {/*empty*/} newlevel = p->level+1; } else { @@ -287,7 +355,7 @@ void Fl_Type::add(Fl_Type *p) { } for (Fl_Type *t = this->next; t; t = t->next) t->level += (newlevel-level); level = newlevel; - // now link this tree after p + // now link 'this' and its children before 'q', or last, if 'q' is NULL if (q) { prev = q->prev; prev->next = this; @@ -308,6 +376,22 @@ void Fl_Type::add(Fl_Type *p) { open_ = 1; fixvisible(this); set_modflag(1); + + if (strategy==kAddAfterCurrent && current) { + // we have current, t is the new node, p is the parent + // find the next child of the parent after current + //t->add(p); // add as a last child + Fl_Type *cc = current; + for (cc = current->next; cc; cc=cc->next) { + if (cc->level<=this->level) + break; + } + if (cc && cc->level==this->level && cc!=this) { + this->move_before(cc); + } + select(this, 1); + } + // run the p tree a last time to make sure the widget_browser updates correctly Fl_Type *a = p; for (Fl_Type *t = this; t && a != end; a = t, t = t->next) @@ -316,20 +400,20 @@ void Fl_Type::add(Fl_Type *p) { } /** - Add this list/tree of widgets as a new sibling before p. + Add `this` list/tree of widgets as a new sibling before `g`. - \c this is not part of the widget browser. \c g should be in the - widget_browser, so \c Fl_Type::first and \c Fl_Type::last are valid for \c p. + `This` is not part of the widget browser. `g` must be in the + widget_browser, so `Fl_Type::first` and `Fl_Type::last` are valid for `g . This methods updates the widget_browser. - \param[in] g insert \c this tree as a child of \c p + \param[in] g pointer to a node within the tree */ void Fl_Type::insert(Fl_Type *g) { - // p is not in the Widget_Browser, so we must run the linked list to find the last entry + // 'this' is not in the Widget_Browser, so we must run the linked list to find the last entry Fl_Type *end = this; while (end->next) end = end->next; - // this wil get the sam parent as g + // 'this' will get the same parent as 'g' parent = g->parent; // run the list again to set the future node levels int newlevel = g->level; @@ -734,3 +818,5 @@ void Fl_Type::write_code1() { void Fl_Type::write_code2() { } +/// \} + diff --git a/fluid/Fl_Type.h b/fluid/Fl_Type.h index 9027b4fc5..fa3a81ce9 100644 --- a/fluid/Fl_Type.h +++ b/fluid/Fl_Type.h @@ -21,6 +21,13 @@ #include <FL/fl_draw.H> class Fl_Type; +class Fl_Group_Type; +class Fl_Window_Type; + +typedef enum { + kAddAsLastChild = 0, + kAddAfterCurrent +} Strategy; void fixvisible(Fl_Type *p); void delete_all(int selected_only=0); @@ -52,15 +59,15 @@ protected: public: // things that should not be public: - Fl_Type *parent; // parent, which is previous in list + Fl_Type *parent; char new_selected; // browser highlight char selected; // copied here by selection_changed() char open_; // state of triangle in browser char visible; // true if all parents are open char rtti; // hack because I have no rtti, this is 0 for base class int level; // number of parents over this - static Fl_Type *first, *last; // linked list of all objects - Fl_Type *next, *prev; // linked list of all objects + static Fl_Type *first, *last; + Fl_Type *next, *prev; Fl_Type *factory; const char *callback_name(); @@ -74,9 +81,12 @@ protected: public: virtual ~Fl_Type(); - virtual Fl_Type *make() = 0; + virtual Fl_Type *make(Strategy strategy) = 0; + + Fl_Window_Type *window(); + Fl_Group_Type *group(); - void add(Fl_Type *parent); // add as new child + void add(Fl_Type *parent, Strategy strategy); void insert(Fl_Type *n); // insert into list before n Fl_Type* remove(); // remove from list void move_before(Fl_Type*); // move before a sibling @@ -104,6 +114,8 @@ public: virtual void remove_child(Fl_Type*) { } static Fl_Type *current; // most recently picked object + static Fl_Type *current_dnd; + virtual void open(); // what happens when you double-click // read and write data to a saved file: diff --git a/fluid/Fl_Widget_Type.cxx b/fluid/Fl_Widget_Type.cxx index d43832232..9f0d702fa 100644 --- a/fluid/Fl_Widget_Type.cxx +++ b/fluid/Fl_Widget_Type.cxx @@ -92,7 +92,12 @@ Fl_Widget_Type::ideal_spacing(int &x, int &y) { x = y = 10; } -Fl_Type *Fl_Widget_Type::make() { +/** + 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; @@ -162,7 +167,7 @@ Fl_Type *Fl_Widget_Type::make() { // Put it in the parent: // ((Fl_Group *)(p->o))->add(t->o); (done by Fl_Type::add()) // add to browser: - t->add(p); + t->add(p, strategy); t->redraw(); return t; } @@ -1913,8 +1918,6 @@ void Fl_Widget_Type::open() { if (numselected) the_panel->show(); } -Fl_Type *Fl_Type::current; - extern void redraw_overlays(); extern void check_redraw_corresponding_parent(Fl_Type*); extern void redraw_browser(); @@ -2373,9 +2376,6 @@ void Fl_Widget_Type::write_widget_code() { if (i & FL_ALIGN_INSIDE) write_c("|FL_ALIGN_INSIDE"); write_c("));\n"); } - // avoid the unsupported combination of flegs when user sets - // "when" to "FL_WHEN_NEVER", but keeps the "no change" set. - // FIXME: This could be reflected in the GUI by graying out the button. Fl_When ww = o->when(); if (ww==FL_WHEN_NOT_CHANGED) ww = FL_WHEN_NEVER; diff --git a/fluid/Fl_Widget_Type.h b/fluid/Fl_Widget_Type.h index 6d39fb9f4..8325dcc56 100644 --- a/fluid/Fl_Widget_Type.h +++ b/fluid/Fl_Widget_Type.h @@ -73,7 +73,7 @@ public: void setinactive(Fluid_Image *); Fl_Widget_Type(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); void open(); const char *extra_code(int n) const {return extra_code_[n];} diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index 8f718ff05..21eefe868 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -27,6 +27,7 @@ #include "file.h" #include "code.h" #include "widget_panel.h" +#include "factory.h" #include <FL/Fl.H> #include <FL/Fl_Overlay_Window.H> @@ -349,7 +350,12 @@ int Overlay_Window::handle(int e) { return ret; } -Fl_Type *Fl_Window_Type::make() { +/** + Make and add a new WIndow node. + \param[in] strategy is kAddAsLastChild or kAddAfterCurrent + \return new node + */ +Fl_Type *Fl_Window_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && !p->is_code_block()) p = p->parent; if (!p) { @@ -372,7 +378,7 @@ Fl_Type *Fl_Window_Type::make() { Overlay_Window *w = new Overlay_Window(100,100); w->window = myo; myo->o = w; - myo->add(p); + myo->add(p, strategy); myo->modal = 0; myo->non_modal = 0; return myo; @@ -1181,8 +1187,60 @@ int Fl_Window_Type::popupx = 0x7FFFFFFF; // mark as invalid (MAXINT) int Fl_Window_Type::popupy = 0x7FFFFFFF; int Fl_Window_Type::handle(int event) { - static Fl_Type* selection; + static Fl_Type* selection = NULL; switch (event) { + case FL_DND_ENTER: + Fl::belowmouse(o); + case FL_DND_DRAG: + { + // find the innermost item clicked on: + selection = this; + for (Fl_Type* i=next; i && i->level>level; i=i->next) + if (i->is_group()) { + Fl_Widget_Type* myo = (Fl_Widget_Type*)i; + for (Fl_Widget *o1 = myo->o; o1; o1 = o1->parent()) + if (!o1->visible()) goto CONTINUE_DND; + if (Fl::event_inside(myo->o)) { + selection = myo; + if (Fl::event_clicks()==1) + reveal_in_browser(myo); + } + } + CONTINUE_DND: + if (selection && !selection->selected) { + select_only(selection); + ((Overlay_Window *)o)->redraw_overlay(); + } + } + case FL_DND_RELEASE: + return 1; + case FL_PASTE: + { Fl_Type *prototype = typename_to_prototype(Fl::event_text()); + if (prototype==NULL) + return 0; + + in_this_only = this; + popupx = Fl::event_x(); + popupy = Fl::event_y(); + // If the selected widget at dnd start and the drop target are the same, + // or in the same group, add after selection. Otherwise, just add + // at the end of the selected group. + if ( Fl_Type::current_dnd->group() + && selection->group() + && Fl_Type::current_dnd->group()==selection->group()) + { + Fl_Type *cc = Fl_Type::current; + Fl_Type::current = Fl_Type::current_dnd; + add_new_widget_from_user(prototype, kAddAfterCurrent); + Fl_Type::current = cc; + } else { + add_new_widget_from_user(prototype, kAddAsLastChild); + } + popupx = 0x7FFFFFFF; + popupy = 0x7FFFFFFF; // mark as invalid (MAXINT) + in_this_only = NULL; + return 1; + } case FL_PUSH: x1 = mx = Fl::event_x(); y1 = my = Fl::event_y(); @@ -1439,7 +1497,12 @@ int Fl_Window_Type::read_fdesign(const char* propname, const char* value) { Fl_Widget_Class_Type Fl_Widget_Class_type; Fl_Widget_Class_Type *current_widget_class = 0; -Fl_Type *Fl_Widget_Class_Type::make() { +/** + Create and add a new Widget Class node. + \param[in] strategy add after current or as last child + \return new node + */ +Fl_Type *Fl_Widget_Class_Type::make(Strategy strategy) { Fl_Type *p = Fl_Type::current; while (p && (!p->is_decl_block() || (p->is_widget() && p->is_class()))) p = p->parent; Fl_Widget_Class_Type *myo = new Fl_Widget_Class_Type(); @@ -1460,7 +1523,7 @@ Fl_Type *Fl_Widget_Class_Type::make() { Overlay_Window *w = new Overlay_Window(100,100); w->window = myo; myo->o = w; - myo->add(p); + myo->add(p, strategy); myo->modal = 0; myo->non_modal = 0; myo->wc_relative = 0; diff --git a/fluid/Fl_Window_Type.h b/fluid/Fl_Window_Type.h index 5868e2576..97d5779aa 100644 --- a/fluid/Fl_Window_Type.h +++ b/fluid/Fl_Window_Type.h @@ -68,7 +68,7 @@ public: Fl_Window_Type() { drag = dx = dy = 0; sr_min_w = sr_min_h = sr_max_w = sr_max_h = 0; } uchar modal, non_modal; - Fl_Type *make(); + Fl_Type *make(Strategy strategy); virtual const char *type_name() {return "Fl_Window";} virtual const char *alt_type_name() {return "fltk::Window";} @@ -116,7 +116,7 @@ public: void write_code1(); void write_code2(); - Fl_Type *make(); + Fl_Type *make(Strategy strategy); virtual const char *type_name() {return "widget_class";} int pixmapID() { return 48; } int is_parent() const {return 1;} diff --git a/fluid/Makefile b/fluid/Makefile index c87c05719..8fd23d3bf 100644 --- a/fluid/Makefile +++ b/fluid/Makefile @@ -26,6 +26,7 @@ CPPFILES = \ Fl_Widget_Type.cxx \ Fl_Window_Type.cxx \ Fluid_Image.cxx \ + Shortcut_Button.cxx \ about_panel.cxx \ align_widget.cxx \ alignment_panel.cxx \ diff --git a/fluid/Shortcut_Button.cxx b/fluid/Shortcut_Button.cxx new file mode 100644 index 000000000..bc65fe8e9 --- /dev/null +++ b/fluid/Shortcut_Button.cxx @@ -0,0 +1,192 @@ +// +// 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 +// + +/// \defgroup fl_type Basic Node for all Widgets and Functions +/// \{ + +/** \class Fl_Type +Each object described by Fluid is one of these objects. They +are all stored in a double-linked list. + +The "type" of the object is covered by the virtual functions. +There will probably be a lot of these virtual functions. + +The type browser is also a list of these objects, but they +are "factory" instances, not "real" ones. These objects exist +only so the "make" method can be called on them. They are +not in the linked list and are not written to files or +copied or otherwise examined. +*/ + +#include "Shortcut_Button.h" + +#include "fluid.h" +#include "Fl_Window_Type.h" +#include "factory.h" +#include "widget_panel.h" + +#include <FL/platform.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Window.H> +#include <FL/fl_draw.H> +#include <FL/Fl_Menu_.H> +#include "../src/flstring.h" + +/** \class Shortcut_Button + A button that allows the user to type a key combination to create shortcuts. + After clicked once, the button catches the following keyboard events and + records the pressed keys and all modifiers. It draws a text representation of + the shortcut. The backspace key deletes the current shortcut. + */ + +/** + Draw the textual representation of the shortcut. + */ +void Shortcut_Button::draw() { + if (value()) draw_box(FL_DOWN_BOX, (Fl_Color)9); + else draw_box(FL_UP_BOX, FL_WHITE); + fl_font(FL_HELVETICA,14); fl_color(FL_FOREGROUND_COLOR); + if (use_FL_COMMAND && (svalue & (FL_CTRL|FL_META))) { + char buf[1024]; + fl_snprintf(buf, 1023, "Command+%s", fl_shortcut_label(svalue&~(FL_CTRL|FL_META))); + fl_draw(buf,x()+6,y(),w(),h(),FL_ALIGN_LEFT); + } else { + fl_draw(fl_shortcut_label(svalue),x()+6,y(),w(),h(),FL_ALIGN_LEFT); + } +} + +/** + Handle keystrokes to catch the user's shortcut. + */ +int Shortcut_Button::handle(int e) { + when(0); type(FL_TOGGLE_BUTTON); + if (e == FL_KEYBOARD) { + if (!value()) return 0; + int v = Fl::event_text()[0]; + if ( (v > 32 && v < 0x7f) || (v > 0xa0 && v <= 0xff) ) { + if (isupper(v)) { + v = tolower(v); + v |= FL_SHIFT; + } + v = v | (Fl::event_state()&(FL_META|FL_ALT|FL_CTRL)); + } else { + v = (Fl::event_state()&(FL_META|FL_ALT|FL_CTRL|FL_SHIFT)) | Fl::event_key(); + if (v == FL_BackSpace && svalue) v = 0; + } + if (v != svalue) {svalue = v; set_changed(); redraw(); do_callback(); } + return 1; + } else if (e == FL_UNFOCUS) { + int c = changed(); value(0); if (c) set_changed(); + return 1; + } else if (e == FL_FOCUS) { + return value(); + } else { + int r = Fl_Button::handle(e); + if (e == FL_RELEASE && value() && Fl::focus() != this) take_focus(); + return r; + } +} + +/** \class Widget_Bin_Button + A button for the widget bin that allows the user to drag widgets into a window. + Dragging and dropping a new widget makes it easy for the user to position + a widget inside a window or group. + */ + +/** + Convert mouse dragging into a drag and drop event. + */ +int Widget_Bin_Button::handle(int inEvent) +{ + int ret = 0; + switch (inEvent) { + case FL_PUSH: + Fl_Button::handle(inEvent); + return 1; // make sure that we get drag events + case FL_DRAG: + ret = Fl_Button::handle(inEvent); + if (!user_data()) + return ret; + if (!Fl::event_is_click()) { // make it a dnd event + // fake a drag outside of the widget + Fl::e_x = x()-1; + Fl_Button::handle(inEvent); + // fake a buttton release + Fl_Button::handle(FL_RELEASE); + // make it into a dnd event + const char *type_name = (const char*)user_data(); + Fl_Type::current_dnd = Fl_Type::current; + Fl::copy(type_name, strlen(type_name)+1, 0); + Fl::dnd(); + return 1; + } + return ret; + } + return Fl_Button::handle(inEvent); +} + +/** \class Widget_Bin_Window_Button + This button is used by the widget bin to create new windows by drag'n'drop. + The new window will be created wherever the user drops it on the desktop. + */ + +/** + Convert mouse dragging into a drag and drop event. + */ +int Widget_Bin_Window_Button::handle(int inEvent) +{ + static Fl_Window *drag_win = NULL; + int ret = 0; + switch (inEvent) { + case FL_PUSH: + Fl_Button::handle(inEvent); + return 1; // make sure that we get drag events + case FL_DRAG: + ret = Fl_Button::handle(inEvent); + if (!user_data()) + return ret; + if (!Fl::event_is_click()) { + if (!drag_win) { + drag_win = new Fl_Window(0, 0, 100, 100); + drag_win->border(0); + drag_win->set_non_modal(); + } + if (drag_win) { + drag_win->position(Fl::event_x_root()+1, Fl::event_y_root()+1); + drag_win->show(); + } + // Does not work outside window: fl_cursor(FL_CURSOR_HAND); + } + return ret; + case FL_RELEASE: + if (drag_win) { + Fl::delete_widget(drag_win); + drag_win = NULL; + // create a new window here + Fl_Type *prototype = typename_to_prototype((char*)user_data()); + if (prototype) { + Fl_Type *new_type = add_new_widget_from_user(prototype, kAddAfterCurrent); + if (new_type && new_type->is_window()) { + Fl_Window_Type *new_window = (Fl_Window_Type*)new_type; + Fl_Window *w = (Fl_Window *)new_window->o; + w->position(Fl::event_x_root(), Fl::event_y_root()); + } + } + } + return Fl_Button::handle(inEvent); + } + return Fl_Button::handle(inEvent); +} diff --git a/fluid/Shortcut_Button.h b/fluid/Shortcut_Button.h index 790415158..1c46b8afc 100644 --- a/fluid/Shortcut_Button.h +++ b/fluid/Shortcut_Button.h @@ -28,5 +28,19 @@ public: Fl_Button(X,Y,W,H,l) {svalue = 0;} }; +class Widget_Bin_Button : public Fl_Button { +public: + int handle(int); + Widget_Bin_Button(int X,int Y,int W,int H, const char* l = 0) : + Fl_Button(X,Y,W,H,l) { } +}; + +class Widget_Bin_Window_Button : public Fl_Button { +public: + int handle(int); + Widget_Bin_Window_Button(int X,int Y,int W,int H, const char* l = 0) : + Fl_Button(X,Y,W,H,l) { } +}; + #endif diff --git a/fluid/factory.cxx b/fluid/factory.cxx index d1b1b664d..dfc75d930 100644 --- a/fluid/factory.cxx +++ b/fluid/factory.cxx @@ -26,9 +26,11 @@ #include "fluid.h" #include "Fl_Window_Type.h" +#include "pixmaps.h" #include "undo.h" #include <FL/Fl.H> +#include <FL/Fl_Window.H> #include <FL/Fl_Group.H> #include <FL/Fl_Menu_Item.H> #include <FL/Fl_Pixmap.H> @@ -36,8 +38,7 @@ #include "../src/flstring.h" #include <stdio.h> - -extern Fl_Pixmap *pixmap[]; +#include <stdlib.h> //////////////////////////////////////////////////////////////// @@ -169,8 +170,6 @@ static Fl_Round_Button_Type Fl_Round_Button_type; //////////////////////////////////////////////////////////////// -extern int batch_mode; - #include <FL/Fl_Browser.H> #include <FL/Fl_Check_Browser.H> #include <FL/Fl_File_Browser.H> @@ -956,12 +955,106 @@ extern class Fl_Wizard_Type Fl_Wizard_type; extern void select(Fl_Type *,int); extern void select_only(Fl_Type *); -#include <FL/Fl_Window.H> +/** + List all known types. + This is used to convert a type name into a pointer to the prototype. + This list may contain types that are supported in .fl files, but not + available in the *New* menu. + */ +static Fl_Type *known_types[] = { + // functions + (Fl_Type*)&Fl_Function_type, + (Fl_Type*)&Fl_Code_type, + (Fl_Type*)&Fl_CodeBlock_type, + (Fl_Type*)&Fl_Decl_type, + (Fl_Type*)&Fl_DeclBlock_type, + (Fl_Type*)&Fl_Class_type, + (Fl_Type*)&Fl_Widget_Class_type, + (Fl_Type*)&Fl_Comment_type, + (Fl_Type*)&Fl_Data_type, + // groups + (Fl_Type*)&Fl_Window_type, + (Fl_Type*)&Fl_Group_type, + (Fl_Type*)&Fl_Pack_type, + (Fl_Type*)&Fl_Tabs_type, + (Fl_Type*)&Fl_Scroll_type, + (Fl_Type*)&Fl_Tile_type, + (Fl_Type*)&Fl_Wizard_type, + // buttons + (Fl_Type*)&Fl_Button_type, + (Fl_Type*)&Fl_Return_Button_type, + (Fl_Type*)&Fl_Light_Button_type, + (Fl_Type*)&Fl_Check_Button_type, + (Fl_Type*)&Fl_Repeat_Button_type, + (Fl_Type*)&Fl_Round_Button_type, + // valuators + (Fl_Type*)&Fl_Slider_type, + (Fl_Type*)&Fl_Scrollbar_type, + (Fl_Type*)&Fl_Value_Slider_type, + (Fl_Type*)&Fl_Adjuster_type, + (Fl_Type*)&Fl_Counter_type, + (Fl_Type*)&Fl_Spinner_type, + (Fl_Type*)&Fl_Dial_type, + (Fl_Type*)&Fl_Roller_type, + (Fl_Type*)&Fl_Value_Input_type, + (Fl_Type*)&Fl_Value_Output_type, + // text + (Fl_Type*)&Fl_Input_type, + (Fl_Type*)&Fl_Output_type, + (Fl_Type*)&Fl_Text_Editor_type, + (Fl_Type*)&Fl_Text_Display_type, + (Fl_Type*)&Fl_File_Input_type, + (Fl_Type*)&Fl_Simple_Terminal_type, + // menus + (Fl_Type*)&Fl_Menu_Bar_type, + (Fl_Type*)&Fl_Menu_Button_type, + (Fl_Type*)&Fl_Choice_type, + (Fl_Type*)&Fl_Input_Choice_type, + (Fl_Type*)&Fl_Submenu_type, + (Fl_Type*)&Fl_Menu_Item_type, + (Fl_Type*)&Fl_Checkbox_Menu_Item_type, + (Fl_Type*)&Fl_Radio_Menu_Item_type, + // browsers + (Fl_Type*)&Fl_Browser_type, + (Fl_Type*)&Fl_Check_Browser_type, + (Fl_Type*)&Fl_File_Browser_type, + (Fl_Type*)&Fl_Tree_type, + (Fl_Type*)&Fl_Help_View_type, + (Fl_Type*)&Fl_Table_type, + // misc + (Fl_Type*)&Fl_Box_type, + (Fl_Type*)&Fl_Clock_type, + (Fl_Type*)&Fl_Progress_type, +}; -static void cb(Fl_Widget *, void *v) { +/** + Create and add a new widget to the widget tree. + + Fluid will try to set a default postion for widgets to the user's expectation. + Using the context menu will put new widgets at the position of the mouse click. + Pulldown menu and bin actions will generate widgets no too far from previously + added widgets in the same group. + + Widgets can be added by dragging them from the widget bin to the + desired location. + + By setting the strategy, widgets are added as the last child of a group (this + is done when reading them from a file), or close to the current widget, which + the user would expect in interactive mode. + + \param[in] inPrototype pointer to one of the FL_..._type prototype; note the + lower case 't' in type. + \param[in] strategy add after current or as last child + + \see add_new_widget_from_file(const char*, int) + add_new_widget_from_user(Fl_Type*, int) + add_new_widget_from_user(const char*, int) + */ +Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) { undo_checkpoint(); undo_suspend(); - Fl_Type *t = ((Fl_Type*)v)->make(); + Fl_Type *ins = Fl_Type::current; + Fl_Type *t = ((Fl_Type*)inPrototype)->make(strategy); if (t) { if (t->is_widget() && !t->is_window()) { Fl_Widget_Type *wt = (Fl_Widget_Type *)t; @@ -994,6 +1087,23 @@ static void cb(Fl_Widget *, void *v) { } } } +#if 0 + // Fluid inserts widgets always as the last child of a matching group. + // This is great when reading a file, but if users do thins interactively, + // they expect the new widget close to where they worked previously. + if (ins) { + // if the new and current widget are siblings, just move it here. + if (ins->level==t->level) { + Fl_Type *c; + for (c=t; c && c!=ins && c->level>=t->level; c=c->prev) { } + if (c==ins) { + t->move_before(ins); // together the same as 'move_after' + ins->move_before(t); + } + } + } +#endif + // make the new widget visible select_only(t); set_modflag(1); t->open(); @@ -1002,6 +1112,36 @@ static void cb(Fl_Widget *, void *v) { undo_last --; } undo_resume(); + return t; +} + +/** + Create and add a new widget to the widget tree. + \param[in] inName find the right prototype by this name + \param[in] strategy where to add the node + \return the newly created node + \see add_new_widget_from_file(const char*, int) + add_new_widget_from_user(Fl_Type*, int) + add_new_widget_from_user(const char*, int) + */ +Fl_Type *add_new_widget_from_user(const char *inName, Strategy strategy) { + Fl_Type *prototype = typename_to_prototype(inName); + if (prototype) + return add_new_widget_from_user(prototype, strategy); + else + return NULL; +} + +/** + Callback for all menu items. + */ +static void cb(Fl_Widget *, void *v) { + Fl_Type *t = NULL; + if (Fl_Type::current && Fl_Type::current->is_group()) + t = ((Fl_Type*)v)->make(kAddAsLastChild); + else + t = ((Fl_Type*)v)->make(kAddAfterCurrent); + select_only(t); } Fl_Menu_Item New_Menu[] = { @@ -1080,10 +1220,15 @@ Fl_Menu_Item New_Menu[] = { #include <FL/Fl_Multi_Label.H> -// Modify a menuitem to display an icon in front of the label. This is -// implemented using Fl_Multi_Label as the labeltype (FL_MULTI_LABEL). -// The icon (ic) may be null. If ic is null only the text (txt) is assigned -// to the label - Fl_Multi_Label is not used. txt must not be null. +/** + Modify a menuitem to display an icon in front of the label. + This is implemented using Fl_Multi_Label as the labeltype (FL_MULTI_LABEL). + The icon may be null. If ic is null only the text (is assigned + to the label and Fl_Multi_Label is not used. + \param[in] mi pointer to tme menu item that will be modified + \param[in] ic icon for the menu, may be NULL + \param[in] txt new label text, may *not* be NULL, will not be copied + */ static void make_iconlabel(Fl_Menu_Item *mi, Fl_Image *ic, const char *txt) { if (ic) { @@ -1097,9 +1242,10 @@ static void make_iconlabel(Fl_Menu_Item *mi, Fl_Image *ic, const char *txt) ml->typea = FL_IMAGE_LABEL; ml->typeb = FL_NORMAL_LABEL; ml->label(mi); + } else { + if (txt != mi->text) + mi->label(txt); } - else if (txt != mi->text) - mi->label(txt); } void fill_in_New_Menu() { @@ -1119,25 +1265,48 @@ void fill_in_New_Menu() { } } -// use keyword to pick the type, this is used to parse files: -Fl_Type *Fl_Type_make(const char *tn) { - reading_file = 1; // makes labels be null - Fl_Type *r = 0; - for (unsigned i = 0; i < sizeof(New_Menu)/sizeof(*New_Menu); i++) { - Fl_Menu_Item *m = New_Menu+i; - if (!m->user_data()) continue; - Fl_Type *t = (Fl_Type*)(m->user_data()); - if (!fl_ascii_strcasecmp(tn,t->type_name())) { - r = t->make(); - break; - } - if (!fl_ascii_strcasecmp(tn,t->alt_type_name())) { - r = t->make(); - break; - } +/** + Find the correct prototype for a given type name. + \param[in] inName a C string that must match type_name() or alt_type_name() of + one of the known Fl_Type classes. + \return the matching prototype or NULL + */ +Fl_Type *typename_to_prototype(const char *inName) +{ + if (inName==NULL || *inName==0) + return NULL; + for (unsigned i = 0; i < sizeof(known_types)/sizeof(*known_types); i++) { + Fl_Type *prototype = known_types[i]; + if (fl_ascii_strcasecmp(inName, prototype->type_name())==0) + return prototype; + if (fl_ascii_strcasecmp(inName, prototype->alt_type_name())==0) + return prototype; } + return NULL; +} + +/** + Create and add a new type node to the widget tree. + + This is used by the .fl file reader. New types are always created as + the last child of the first compatible parent. New widgets have a default + setup. Their position, sizem and label will be read next in the file. + + \param[in] inName a C string that described the type we want + \param[in] strategy add after current or as last child + \return the type node that was created or NULL + \see add_new_widget_from_file(const char*, int) + add_new_widget_from_user(Fl_Type*, int) + add_new_widget_from_user(const char*, int) +*/ +Fl_Type *add_new_widget_from_file(const char *inName, Strategy strategy) { + reading_file = 1; // makes labels be null + Fl_Type *prototype = typename_to_prototype(inName); + if (!prototype) + return NULL; + Fl_Type *new_node = prototype->make(strategy); reading_file = 0; - return r; + return new_node; } //////////////////////////////////////////////////////////////// @@ -1269,8 +1438,6 @@ static symbol table[] = { {"HOR_NICE_SLIDER", FL_HOR_NICE_SLIDER}, }; -#include <stdlib.h> - int lookup_symbol(const char *name, int &v, int numberok) { if (name[0]=='F' && name[1]=='L' && name[2]=='_') name += 3; for (int i=0; i < int(sizeof(table)/sizeof(*table)); i++) diff --git a/fluid/factory.h b/fluid/factory.h index aaed57b20..7bd09eb05 100644 --- a/fluid/factory.h +++ b/fluid/factory.h @@ -17,13 +17,18 @@ #ifndef _FLUID_FACTORY_H #define _FLUID_FACTORY_H +#include "Fl_Type.h" + struct Fl_Menu_Item; -class Fl_Type; extern Fl_Menu_Item New_Menu[]; void fill_in_New_Menu(); -Fl_Type *Fl_Type_make(const char *tn); +Fl_Type *typename_to_prototype(const char *inName); + +Fl_Type *add_new_widget_from_file(const char *inName, Strategy strategy); +Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy); +Fl_Type *add_new_widget_from_user(const char *inName, Strategy strategy); #endif // _FLUID_FACTORY_H diff --git a/fluid/file.cxx b/fluid/file.cxx index 37227d8b0..2732ae26b 100644 --- a/fluid/file.cxx +++ b/fluid/file.cxx @@ -45,7 +45,8 @@ /// \{ // This file contains code to read and write .fl file. -// TODO: there is a name confusion with routines that write to the C and Header files which must be fixed. +// TODO: there is a name confusion with routines that write to the C and Header +// TODO: files vs. thos the write to th fl file which should be fixed. static FILE *fout; static FILE *fin; @@ -434,10 +435,11 @@ int write_file(const char *filename, int selected_only) { \param[in] p parent node or NULL \param[in] paste if set, merge into existing design, else replace design - \param[in] options_read this is set if the options were already found in - a previous call + \param[in] strategy add nodes after current or as last child + \param[in] skip_options this is set if the options were already found in + a previous call, and there is no need to waste time searchingg for them. */ -static void read_children(Fl_Type *p, int paste, char options_read=0) { +static void read_children(Fl_Type *p, int paste, Strategy strategy, char skip_options=0) { Fl_Type::current = p; for (;;) { const char *c = read_word(); @@ -453,7 +455,7 @@ static void read_children(Fl_Type *p, int paste, char options_read=0) { } // Make sure that we don;t go through the list of options for child nodes - if (!options_read) { + if (!skip_options) { // this is the first word in a .fd file: if (!strcmp(c,"Magic:")) { read_fdesign(); @@ -470,7 +472,7 @@ static void read_children(Fl_Type *p, int paste, char options_read=0) { // back compatibility with Vincent Penne's original class code: if (!p && !strcmp(c,"define_in_struct")) { - Fl_Type *t = Fl_Type_make("class"); + Fl_Type *t = add_new_widget_from_file("class", kAddAsLastChild); t->name(read_word()); Fl_Type::current = p = t; paste = 1; // stops "missing }" error @@ -560,15 +562,15 @@ static void read_children(Fl_Type *p, int paste, char options_read=0) { } } { - Fl_Type *t = Fl_Type_make(c); + Fl_Type *t = add_new_widget_from_file(c, strategy); if (!t) { read_error("Unknown word \"%s\"", c); continue; } - t->name(read_word()); - // After reading the first widget, we no longer need to look for options - options_read = 1; + skip_options = 1; + + t->name(read_word()); c = read_word(1); if (strcmp(c,"{") && t->is_class()) { // <prefix> <name> @@ -595,7 +597,7 @@ static void read_children(Fl_Type *p, int paste, char options_read=0) { read_error("Missing child list for %s\n",t->title()); goto REUSE_C; } - read_children(t, 0, options_read); + read_children(t, 0, strategy, skip_options); } Fl_Type::current = p; @@ -608,9 +610,11 @@ static void read_children(Fl_Type *p, int paste, char options_read=0) { Read a .fl design file. \param[in] filename read this file \param[in] merge if this is set, merge the file into an existing design + at Fl_Type::current + \param[in] strategy add new nodes after current or as last child \return 0 if the operation failed, 1 if it succeeded */ -int read_file(const char *filename, int merge) { +int read_file(const char *filename, int merge, Strategy strategy) { Fl_Type *o; read_version = 0.0; if (!open_read(filename)) @@ -619,7 +623,7 @@ int read_file(const char *filename, int merge) { deselect(); else delete_all(); - read_children(Fl_Type::current, merge); + read_children(Fl_Type::current, merge, strategy); Fl_Type::current = 0; // Force menu items to be rebuilt... for (o = Fl_Type::first; o; o = o->next) @@ -720,7 +724,7 @@ void read_fdesign() { Fl_Widget_Type *group = 0; Fl_Widget_Type *widget = 0; if (!Fl_Type::current) { - Fl_Type *t = Fl_Type_make("Function"); + Fl_Type *t = add_new_widget_from_file("Function", kAddAsLastChild); t->name("create_the_forms()"); Fl_Type::current = t; } @@ -731,7 +735,7 @@ void read_fdesign() { if (!strcmp(name,"Name")) { - window = (Fl_Widget_Type*)Fl_Type_make("Fl_Window"); + window = (Fl_Widget_Type*)add_new_widget_from_file("Fl_Window", kAddAsLastChild); window->name(value); window->label(value); Fl_Type::current = widget = window; @@ -739,7 +743,7 @@ void read_fdesign() { } else if (!strcmp(name,"class")) { if (!strcmp(value,"FL_BEGIN_GROUP")) { - group = widget = (Fl_Widget_Type*)Fl_Type_make("Fl_Group"); + group = widget = (Fl_Widget_Type*)add_new_widget_from_file("Fl_Group", kAddAsLastChild); Fl_Type::current = group; } else if (!strcmp(value,"FL_END_GROUP")) { if (group) { @@ -754,10 +758,10 @@ void read_fdesign() { for (int i = 0; class_matcher[i]; i += 2) if (!strcmp(value,class_matcher[i])) { value = class_matcher[i+1]; break;} - widget = (Fl_Widget_Type*)Fl_Type_make(value); + widget = (Fl_Widget_Type*)add_new_widget_from_file(value, kAddAsLastChild); if (!widget) { printf("class %s not found, using Fl_Button\n", value); - widget = (Fl_Widget_Type*)Fl_Type_make("Fl_Button"); + widget = (Fl_Widget_Type*)add_new_widget_from_file("Fl_Button", kAddAsLastChild); } } diff --git a/fluid/file.h b/fluid/file.h index 18b96492e..5470d1b26 100644 --- a/fluid/file.h +++ b/fluid/file.h @@ -17,6 +17,8 @@ #ifndef _FLUID_FILE_H #define _FLUID_FILE_H +#include "Fl_Type.h" + #include <FL/fl_attr.h> extern double read_version; @@ -34,7 +36,7 @@ const char *read_word(int wantbrace = 0); int write_file(const char *, int selected_only = 0); -int read_file(const char *, int merge); +int read_file(const char *, int merge, Strategy strategy=kAddAsLastChild); void read_fdesign(); #endif // _FLUID_FILE_H diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx index 0f049b880..f584e182d 100644 --- a/fluid/fluid.cxx +++ b/fluid/fluid.cxx @@ -99,7 +99,9 @@ int G_debug = 0; char G_external_editor_command[512]; -/// \todo Functionality unclear. +/// If set, if the `current` node is a group, and a new group is added, it will +/// be added as sibling to the first group instead of inside the group. +/// \todo Needs to be verified. int force_parent = 0; /// This is set to create different labels when creating new widgets. @@ -197,10 +199,10 @@ const char* i18n_set = ""; /// \todo document me char i18n_program[FL_PATH_MAX] = ""; -/// \todo document me +/// Offset in pixels when adding widgets from an .fl file. int pasteoffset = 0; -/// \todo document me +/// Paste offset incrementing at every paste command. static int ipasteoffset = 0; @@ -999,11 +1001,16 @@ void delete_cb(Fl_Widget *, void *) { void paste_cb(Fl_Widget*, void*) { //if (ipasteoffset) force_parent = 1; pasteoffset = ipasteoffset; + // TODO: make the paste offset more predictable, if any at all. + // TODO: Don't use the grid if the user switched it off. if (gridx>1) pasteoffset = ((pasteoffset-1)/gridx+1)*gridx; if (gridy>1) pasteoffset = ((pasteoffset-1)/gridy+1)*gridy; undo_checkpoint(); undo_suspend(); - if (!read_file(cutfname(), 1)) { + Strategy strategy = kAddAfterCurrent; + if (Fl_Type::current && Fl_Type::current->is_group()) + strategy = kAddAsLastChild; + if (!read_file(cutfname(), 1, strategy)) { fl_message("Can't read %s: %s", cutfname(), strerror(errno)); } undo_resume(); @@ -1031,7 +1038,7 @@ void duplicate_cb(Fl_Widget*, void*) { undo_checkpoint(); undo_suspend(); - if (!read_file(cutfname(1), 1)) { + if (!read_file(cutfname(1), 1, kAddAfterCurrent)) { fl_message("Can't read %s: %s", cutfname(1), strerror(errno)); } fl_unlink(cutfname(1)); diff --git a/fluid/function_panel.cxx b/fluid/function_panel.cxx index 65326ae10..80762df28 100644 --- a/fluid/function_panel.cxx +++ b/fluid/function_panel.cxx @@ -18,6 +18,7 @@ #include "function_panel.h" #include "fluid.h" +#include "Shortcut_Button.h" #include "pixmaps.h" #include "factory.h" #include "Fl_Type.h" @@ -704,16 +705,11 @@ Fl_Double_Window* make_comment_panel() { } void type_make_cb(Fl_Widget*,void*d) { - undo_checkpoint(); - Fl_Type *t = Fl_Type_make((char*)d); - if (t) { - select_only(t); - set_modflag(1); - t->open(); - } else { - undo_current --; - undo_last --; - } + const char *type_name = (const char*)d; + if (Fl_Type::current && Fl_Type::current->is_group()) + add_new_widget_from_user(type_name, kAddAsLastChild); + else + add_new_widget_from_user(type_name, kAddAfterCurrent); } Fl_Window *widgetbin_panel=(Fl_Window *)0; @@ -789,306 +785,674 @@ Fl_Window* make_widgetbin() { } // Fl_Group* o { Fl_Group* o = new Fl_Group(87, 19, 79, 79, "Groups"); o->labelsize(12); - { Fl_Button* o = new Fl_Button(89, 21, 24, 24); + { Widget_Bin_Window_Button* o = new Widget_Bin_Window_Button(89, 21, 24, 24); o->tooltip("Window"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Window")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[1]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(114, 21, 24, 24); + } // Widget_Bin_Window_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(114, 21, 24, 24); o->tooltip("Group"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Group")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[6]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(139, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(139, 21, 24, 24); o->tooltip("Pack"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Pack")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[22]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(89, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(89, 46, 24, 24); o->tooltip("Tabs"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Tabs")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[13]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(114, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(114, 46, 24, 24); o->tooltip("Scroll"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Scroll")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[19]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(89, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(89, 71, 24, 24); o->tooltip("Tile"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Tile")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[20]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(114, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(114, 71, 24, 24); o->tooltip("Wizard"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Wizard")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[21]); - } // Fl_Button* o + } // Widget_Bin_Button* o o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(171, 19, 54, 79, "Buttons"); o->labelsize(12); - { Fl_Button* o = new Fl_Button(173, 21, 24, 24); + { Widget_Bin_Button* o = new Widget_Bin_Button(173, 21, 24, 24); o->tooltip("Button"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Button")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[2]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(198, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(198, 21, 24, 24); o->tooltip("Return Button"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Return_Button")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[23]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(173, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(173, 46, 24, 24); o->tooltip("Light Button"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Light_Button")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[24]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(198, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(198, 46, 24, 24); o->tooltip("Repeat Button"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Repeat_Button")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[25]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(173, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(173, 71, 24, 24); o->tooltip("Check Button"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Check_Button")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[3]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(198, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(198, 71, 24, 24); o->tooltip("Round Button"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Round_Button")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[4]); - } // Fl_Button* o + } // Widget_Bin_Button* o o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(230, 19, 104, 79, "Valuators"); o->labelsize(12); - { Fl_Button* o = new Fl_Button(232, 21, 24, 24); + { Widget_Bin_Button* o = new Widget_Bin_Button(232, 21, 24, 24); o->tooltip("Slider"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Slider")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[37]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(257, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(257, 21, 24, 24); o->tooltip("Scroll Bar"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Scrollbar")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[38]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(282, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(282, 21, 24, 24); o->tooltip("Value Slider"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Value_Slider")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[39]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(307, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(307, 21, 24, 24); o->tooltip("Value Output"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Value_Output")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[45]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(232, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(232, 46, 24, 24); o->tooltip("Adjuster"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Adjuster")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[40]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(257, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(257, 46, 24, 24); o->tooltip("Counter"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Counter")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[41]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(282, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(282, 46, 24, 24); o->tooltip("Dial"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Dial")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[42]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(232, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(232, 71, 24, 24); o->tooltip("Roller"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Roller")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[43]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(257, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(257, 71, 24, 24); o->tooltip("Spinner"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Spinner")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[47]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(282, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(282, 71, 24, 24); o->tooltip("Value Input"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Value_Input")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[44]); - } // Fl_Button* o + } // Widget_Bin_Button* o o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(339, 19, 54, 79, "Text"); o->labelsize(12); - { Fl_Button* o = new Fl_Button(341, 21, 24, 24); + { Widget_Bin_Button* o = new Widget_Bin_Button(341, 21, 24, 24); o->tooltip("Input"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Input")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[14]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(366, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(366, 21, 24, 24); o->tooltip("Output"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Output")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[27]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(341, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(341, 46, 24, 24); o->tooltip("Text Edit"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Text_Editor")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[29]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(366, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(366, 46, 24, 24); o->tooltip("Text Display"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Text_Display")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[28]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(341, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(341, 71, 24, 24); o->tooltip("File Input"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_File_Input")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[30]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(366, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(366, 71, 24, 24); o->tooltip("Simple Terminal"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Simple_Terminal")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[52]); - } // Fl_Button* o + } // Widget_Bin_Button* o o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(398, 19, 79, 79, "Menus"); o->labelsize(12); - { Fl_Button* o = new Fl_Button(400, 21, 24, 24); + { Widget_Bin_Button* o = new Widget_Bin_Button(400, 21, 24, 24); o->tooltip("Input Choice"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Input_Choice")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[53]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(425, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(425, 21, 24, 24); o->tooltip("Menu Item"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("menuitem")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[16]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(450, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(450, 21, 24, 24); o->tooltip("Menu Bar"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Menu_Bar")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[17]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(400, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(400, 46, 24, 24); o->tooltip("Menu Button"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Menu_Button")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[26]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(425, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(425, 46, 24, 24); o->tooltip("Checkbox Menu Item"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("checkmenuitem")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[54]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(450, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(450, 46, 24, 24); o->tooltip("Sub Menu"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("submenu")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[18]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(400, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(400, 71, 24, 24); o->tooltip("Choice"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Choice")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[15]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(425, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(425, 71, 24, 24); o->tooltip("Radio Menu Item"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("radiomenuitem")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[55]); - } // Fl_Button* o + } // Widget_Bin_Button* o o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(482, 19, 54, 79, "Browsers"); o->labelsize(12); - { Fl_Button* o = new Fl_Button(484, 21, 24, 24); + { Widget_Bin_Button* o = new Widget_Bin_Button(484, 21, 24, 24); o->tooltip("Browser"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Browser")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[31]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(509, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(509, 21, 24, 24); o->tooltip("Tree"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Tree")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[50]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(484, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(484, 46, 24, 24); o->tooltip("Check Browser"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Check_Browser")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[32]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(509, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(509, 46, 24, 24); o->tooltip("Help Browser"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Help_View")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[35]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(484, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(484, 71, 24, 24); o->tooltip("File Browser"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_File_Browser")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[33]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(509, 71, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(509, 71, 24, 24); o->tooltip("Table"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Table")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[51]); - } // Fl_Button* o + } // Widget_Bin_Button* o o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(540, 19, 55, 79, "Misc"); o->labelsize(12); - { Fl_Button* o = new Fl_Button(542, 21, 24, 24); + { Widget_Bin_Button* o = new Widget_Bin_Button(542, 21, 24, 24); o->tooltip("Box"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Box")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[5]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(567, 21, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(567, 21, 24, 24); o->tooltip("Clock"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Clock")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[34]); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(542, 46, 24, 24); + } // Widget_Bin_Button* o + { Widget_Bin_Button* o = new Widget_Bin_Button(542, 46, 24, 24); o->tooltip("Progress"); o->box(FL_THIN_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); o->callback((Fl_Callback*)type_make_cb, (void*)("Fl_Progress")); + o->align(Fl_Align(FL_ALIGN_CENTER)); + o->when(FL_WHEN_RELEASE); o->image(pixmap[36]); - } // Fl_Button* o + } // Widget_Bin_Button* o o->end(); } // Fl_Group* o widgetbin_panel->set_non_modal(); diff --git a/fluid/function_panel.fl b/fluid/function_panel.fl index df0e307b2..e3f4d76de 100644 --- a/fluid/function_panel.fl +++ b/fluid/function_panel.fl @@ -25,6 +25,9 @@ comment {// decl {\#include "fluid.h"} {private local } +decl {\#include "Shortcut_Button.h"} {private global +} + decl {\#include "pixmaps.h"} {private local } @@ -84,7 +87,7 @@ Function {make_function_panel()} {open } MenuItem {} { label global - user_data 1 user_data_type long selected + user_data 1 user_data_type long xywh {15 15 100 20} labelsize 11 } } @@ -522,18 +525,10 @@ Function {make_comment_panel()} {} { } } -Function {type_make_cb(Fl_Widget*,void*d)} {return_type void +Function {type_make_cb(Fl_Widget*,void*d)} {open return_type void } { - code {undo_checkpoint(); - Fl_Type *t = Fl_Type_make((char*)d); - if (t) { - select_only(t); - set_modflag(1); - t->open(); - } else { - undo_current --; - undo_last --; - }} {} + code {const char *type_name = (const char*)d; +add_new_widget_from_user(type_name);} {} } Function {make_widgetbin()} {open @@ -543,7 +538,7 @@ Function {make_widgetbin()} {open callback {if (Fl::event()==FL_SHORTCUT && Fl::event_key()==FL_Escape) exit_cb((Fl_Widget*)o, v); else - toggle_widgetbin_cb((Fl_Widget*)o, v);} + toggle_widgetbin_cb((Fl_Widget*)o, v);} open xywh {449 206 600 102} type Single align 80 non_modal visible } { Fl_Group {} { @@ -611,45 +606,52 @@ else } { Fl_Button {} { user_data {"Fl_Window"} - callback type_make_cb + callback type_make_cb selected tooltip Window xywh {89 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[1]);} + class Widget_Bin_Window_Button } Fl_Button {} { user_data {"Fl_Group"} callback type_make_cb tooltip Group xywh {114 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[6]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Pack"} callback type_make_cb tooltip Pack xywh {139 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[22]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Tabs"} callback type_make_cb tooltip Tabs xywh {89 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[13]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Scroll"} callback type_make_cb tooltip Scroll xywh {114 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[19]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Tile"} callback type_make_cb tooltip Tile xywh {89 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[20]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Wizard"} callback type_make_cb tooltip Wizard xywh {114 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[21]);} + class Widget_Bin_Button } } Fl_Group {} { @@ -661,36 +663,42 @@ else callback type_make_cb tooltip Button xywh {173 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[2]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Return_Button"} callback type_make_cb tooltip {Return Button} xywh {198 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[23]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Light_Button"} callback type_make_cb tooltip {Light Button} xywh {173 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[24]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Repeat_Button"} callback type_make_cb tooltip {Repeat Button} xywh {198 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[25]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Check_Button"} callback type_make_cb tooltip {Check Button} xywh {173 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[3]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Round_Button"} callback type_make_cb tooltip {Round Button} xywh {198 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[4]);} + class Widget_Bin_Button } } Fl_Group {} { @@ -702,60 +710,70 @@ else callback type_make_cb tooltip Slider xywh {232 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[37]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Scrollbar"} callback type_make_cb tooltip {Scroll Bar} xywh {257 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[38]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Value_Slider"} callback type_make_cb tooltip {Value Slider} xywh {282 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[39]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Value_Output"} callback type_make_cb tooltip {Value Output} xywh {307 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[45]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Adjuster"} callback type_make_cb tooltip Adjuster xywh {232 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[40]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Counter"} callback type_make_cb tooltip Counter xywh {257 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[41]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Dial"} callback type_make_cb tooltip Dial xywh {282 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[42]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Roller"} callback type_make_cb tooltip Roller xywh {232 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[43]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Spinner"} callback type_make_cb tooltip Spinner xywh {257 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[47]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Value_Input"} callback type_make_cb tooltip {Value Input} xywh {282 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[44]);} + class Widget_Bin_Button } } Fl_Group {} { @@ -767,36 +785,42 @@ else callback type_make_cb tooltip Input xywh {341 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[14]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Output"} callback type_make_cb tooltip Output xywh {366 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[27]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Text_Editor"} callback type_make_cb tooltip {Text Edit} xywh {341 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[29]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Text_Display"} callback type_make_cb tooltip {Text Display} xywh {366 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[28]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_File_Input"} callback type_make_cb tooltip {File Input} xywh {341 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[30]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Simple_Terminal"} callback type_make_cb tooltip {Simple Terminal} xywh {366 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[52]);} + class Widget_Bin_Button } } Fl_Group {} { @@ -808,48 +832,56 @@ else callback type_make_cb tooltip {Input Choice} xywh {400 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[53]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"menuitem"} callback type_make_cb tooltip {Menu Item} xywh {425 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[16]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Menu_Bar"} callback type_make_cb tooltip {Menu Bar} xywh {450 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[17]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Menu_Button"} callback type_make_cb tooltip {Menu Button} xywh {400 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[26]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"checkmenuitem"} callback type_make_cb tooltip {Checkbox Menu Item} xywh {425 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[54]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"submenu"} callback type_make_cb tooltip {Sub Menu} xywh {450 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[18]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Choice"} callback type_make_cb tooltip Choice xywh {400 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[15]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"radiomenuitem"} callback type_make_cb tooltip {Radio Menu Item} xywh {425 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[55]);} + class Widget_Bin_Button } } Fl_Group {} { @@ -861,36 +893,42 @@ else callback type_make_cb tooltip Browser xywh {484 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[31]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Tree"} callback type_make_cb tooltip Tree xywh {509 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[50]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Check_Browser"} callback type_make_cb tooltip {Check Browser} xywh {484 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[32]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Help_View"} callback type_make_cb tooltip {Help Browser} xywh {509 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[35]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_File_Browser"} callback type_make_cb tooltip {File Browser} xywh {484 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[33]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Table"} callback type_make_cb tooltip Table xywh {509 71 24 24} box THIN_UP_BOX code0 {o->image(pixmap[51]);} + class Widget_Bin_Button } } Fl_Group {} { @@ -902,18 +940,21 @@ else callback type_make_cb tooltip Box xywh {542 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[5]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Clock"} callback type_make_cb tooltip Clock xywh {567 21 24 24} box THIN_UP_BOX code0 {o->image(pixmap[34]);} + class Widget_Bin_Button } Fl_Button {} { user_data {"Fl_Progress"} callback type_make_cb tooltip Progress xywh {542 46 24 24} box THIN_UP_BOX code0 {o->image(pixmap[36]);} + class Widget_Bin_Button } } } diff --git a/fluid/undo.cxx b/fluid/undo.cxx index 38d70c2e1..09f2867d9 100644 --- a/fluid/undo.cxx +++ b/fluid/undo.cxx @@ -19,6 +19,7 @@ #include "fluid.h" #include "file.h" #include "Fl_Type.h" +#include "widget_browser.h" #include <FL/Fl.H> #include <FL/Fl_Preferences.H> @@ -107,11 +108,19 @@ void undo_cb(Fl_Widget *, void *) { } undo_suspend(); + // Undo first deletes all widgets which resets the widget_tree browser. + // Save the current scroll position, so we don;t scroll back to 0 at undo. + int x = widget_browser->hposition(); + int y = widget_browser->position(); if (!read_file(undo_filename(undo_current - 1), 0)) { // Unable to read checkpoint file, don't undo... undo_resume(); return; } + // Restore old browser position. + // Ideally, we would save the browser position insied the undo file. + widget_browser->hposition(x); + widget_browser->position(y); undo_current --; |
