FLTK logo

[master] 160832c - STR 3442: copy/paste now inserts widget as expected.

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 160832c - STR 3442: copy/paste now inserts widget as expected. "Matthias Melcher" Dec 13, 2021  
 
commit 160832ce04f932fbb3df199aa01d1c93148bb292
Author:     Matthias Melcher <git@matthiasm.com>
AuthorDate: Sat Dec 11 19:43:00 2021 +0100
Commit:     Matthias Melcher <github@matthiasm.com>
CommitDate: Mon Dec 13 18:17:07 2021 +0100

    STR 3442: copy/paste now inserts widget as expected.
    
    Fluid would add pasted widgets as the last child of the
    current group, even if they were cut at the beginning
    of the group. This patch adds a 'startegy' to adding
    widgets to allow merging closer to the 'current' widget.
    
    Also added d'n'd for the widget bin and some other
    UI improvements.
    
    STR 3442: some preparation, variable renaming
    
    STR 3442: unifying functions to add widgets.
    
    Adding widgets interactively is merged into one function,
    making undo/redo work as expected and removing
    unexpected differences between adding by menu or bin.
    
    STR 3442: adding drag'n'drop for windows from bin.
    
    Just drag the window symbol out of the tree and drop it anywhere
    on the desktop.
    
    Visual representation of dragged Window.
    
    STR 3442: insert individual nodes after 'current'
    
    STR 3442: adding new widget at expected positions.
    
    The widget bin can finally do drag'n'drop.
    Widgets appear in the tree close to the last selection.
    Duplicating now ads right below.
    Cut and paste inserts after last selection.
    
    Fluid: replaced #define with strict enum type.

 fluid/CMakeLists.txt       |   1 +
 fluid/Fl_Function_Type.cxx |  52 +++--
 fluid/Fl_Function_Type.h   |  16 +-
 fluid/Fl_Group_Type.cxx    |  13 +-
 fluid/Fl_Group_Type.h      |   2 +-
 fluid/Fl_Menu_Type.cxx     |  78 +++----
 fluid/Fl_Menu_Type.h       |   8 +-
 fluid/Fl_Type.cxx          | 110 ++++++++-
 fluid/Fl_Type.h            |  22 +-
 fluid/Fl_Widget_Type.cxx   |  14 +-
 fluid/Fl_Widget_Type.h     |   2 +-
 fluid/Fl_Window_Type.cxx   |  73 +++++-
 fluid/Fl_Window_Type.h     |   4 +-
 fluid/Makefile             |   1 +
 fluid/Shortcut_Button.cxx  | 192 +++++++++++++++
 fluid/Shortcut_Button.h    |  14 ++
 fluid/factory.cxx          | 231 +++++++++++++++---
 fluid/factory.h            |   9 +-
 fluid/file.cxx             |  40 ++--
 fluid/file.h               |   4 +-
 fluid/fluid.cxx            |  17 +-
 fluid/function_panel.cxx   | 568 +++++++++++++++++++++++++++++++++++++--------
 fluid/function_panel.fl    |  69 ++++--
 fluid/undo.cxx             |   9 +
 24 files changed, 1256 insertions(+), 293 deletions(-)

diff --git fluid/CMakeLists.txt fluid/CMakeLists.txt
index d45b7b1..a9b3af1 100644
--- fluid/CMakeLists.txt
+++ 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 fluid/Fl_Function_Type.cxx fluid/Fl_Function_Type.cxx
index 2f9a180..ac367c7 100644
--- fluid/Fl_Function_Type.cxx
+++ 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 fluid/Fl_Function_Type.h fluid/Fl_Function_Type.h
index 7a6ac81..2f08920 100644
--- fluid/Fl_Function_Type.h
+++ 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 fluid/Fl_Group_Type.cxx fluid/Fl_Group_Type.cxx
index a2a45a5..d5a832b 100644
--- fluid/Fl_Group_Type.cxx
+++ 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 fluid/Fl_Group_Type.h fluid/Fl_Group_Type.h
index a55e0df..581f9ce 100644
--- fluid/Fl_Group_Type.h
+++ 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 fluid/Fl_Menu_Type.cxx fluid/Fl_Menu_Type.cxx
index e3d6fec..7bd55ce 100644
--- fluid/Fl_Menu_Type.cxx
+++ 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 fluid/Fl_Menu_Type.h fluid/Fl_Menu_Type.h
index b42798d..ddd58ef 100644
--- fluid/Fl_Menu_Type.h
+++ 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 fluid/Fl_Type.cxx fluid/Fl_Type.cxx
index ff6a48c..5608969 100644
--- fluid/Fl_Type.cxx
+++ 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 fluid/Fl_Type.h fluid/Fl_Type.h
index 9027b4f..fa3a81c 100644
--- fluid/Fl_Type.h
+++ 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 fluid/Fl_Widget_Type.cxx fluid/Fl_Widget_Type.cxx
index d438322..9f0d702 100644
--- fluid/Fl_Widget_Type.cxx
+++ 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 fluid/Fl_Widget_Type.h fluid/Fl_Widget_Type.h
index 6d39fb9..8325dcc 100644
--- fluid/Fl_Widget_Type.h
+++ 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 fluid/Fl_Window_Type.cxx fluid/Fl_Window_Type.cxx
index 8f718ff..21eefe8 100644
--- fluid/Fl_Window_Type.cxx
+++ 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 fluid/Fl_Window_Type.h fluid/Fl_Window_Type.h
index 5868e25..97d5779 100644
--- fluid/Fl_Window_Type.h
+++ 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 fluid/Makefile fluid/Makefile
index c87c057..8fd23d3 100644
--- fluid/Makefile
+++ 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 fluid/Shortcut_Button.cxx fluid/Shortcut_Button.cxx
new file mode 100644
index 0000000..bc65fe8
--- /dev/null
+++ 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 fluid/Shortcut_Button.h fluid/Shortcut_Button.h
index 7904151..1c46b8a 100644
--- fluid/Shortcut_Button.h
+++ 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 fluid/factory.cxx fluid/factory.cxx
index d1b1b66..dfc75d9 100644
--- fluid/factory.cxx
+++ 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 fluid/factory.h fluid/factory.h
index aaed57b..7bd09eb 100644
--- fluid/factory.h
+++ 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 fluid/file.cxx fluid/file.cxx
index 37227d8..2732ae2 100644
--- fluid/file.cxx
+++ 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 fluid/file.h fluid/file.h
index 18b9649..5470d1b 100644
--- fluid/file.h
+++ 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 fluid/fluid.cxx fluid/fluid.cxx
index 0f049b8..f584e18 100644
--- fluid/fluid.cxx
+++ 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 fluid/function_panel.cxx fluid/function_panel.cxx
index 65326ae..80762df 100644
--- fluid/function_panel.cxx
+++ 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 fluid/function_panel.fl fluid/function_panel.fl
index df0e307..e3f4d76 100644
--- fluid/function_panel.fl
+++ 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 fluid/undo.cxx fluid/undo.cxx
index 38d70c2..09f2867 100644
--- fluid/undo.cxx
+++ 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 --;
 
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.