diff --git a/fluid/nodes/Menu_Node.cxx b/fluid/nodes/Menu_Node.cxx index b29fb8293..ba949b514 100644 --- a/fluid/nodes/Menu_Node.cxx +++ b/fluid/nodes/Menu_Node.cxx @@ -323,8 +323,9 @@ void Menu_Item_Node::write_static(fld::io::Code_Writer& f) { f.write_h_once("#include "); } if (callback() && is_name(callback()) && !user_defined(callback())) - f.write_h_once("extern void %s(Fl_Menu_*, %s);", callback(), - user_data_type() ? user_data_type() : "void*"); + f.write_h_once("extern void %s(Fl_Menu_*, %s);", + callback(), + user_data_type_or_voidp().c_str()); for (int n=0; n < NUM_EXTRA_CODE; n++) { if (!extra_code(n).empty() && isdeclare(extra_code(n).c_str())) f.write_h_once("%s", extra_code(n).c_str()); @@ -348,8 +349,8 @@ void Menu_Item_Node::write_static(fld::io::Code_Writer& f) { f.write_c("\nstatic void %s(Fl_Menu_*", cn); } if (use_o) f.write_c(" o"); - const char* ut = user_data_type() ? user_data_type() : "void*"; - f.write_c(", %s", ut); + std::string ut = user_data_type_or_voidp(); + f.write_c(", %s", ut.c_str()); if (use_v) f.write_c(" v"); f.write_c(") {\n"); f.tag(Mergeback::Tag::GENERIC, Mergeback::Tag::MENU_CALLBACK, 0); @@ -372,7 +373,7 @@ void Menu_Item_Node::write_static(fld::io::Code_Writer& f) { // k is the name of the enclosing class (or classes) if (k) { // Implement the callback as a static member function - f.write_c("void %s::%s(Fl_Menu_* o, %s v) {\n", k, cn, ut); + f.write_c("void %s::%s(Fl_Menu_* o, %s v) {\n", k, cn, ut.c_str()); // Find the Fl_Menu_ container for this menu item Node* t = parent; while (t->is_a(Type::Menu_Item)) t = t->parent; if (t) { @@ -582,10 +583,10 @@ void Menu_Item_Node::write_code1(fld::io::Code_Writer& f) { if (callback()) { if (!is_name(callback()) && (callback()[0] != '[') && class_name(1)) { const char* cn = callback_name(f); - const char* ut = user_data_type() ? user_data_type() : "void*"; + std::string ut = user_data_type_or_voidp(); f.write_public(0); - f.write_h("%sinline void %s_i(Fl_Menu_*, %s);\n", f.indent(1), cn, ut); - f.write_h("%sstatic void %s(Fl_Menu_*, %s);\n", f.indent(1), cn, ut); + f.write_h("%sinline void %s_i(Fl_Menu_*, %s);\n", f.indent(1), cn, ut.c_str()); + f.write_h("%sstatic void %s(Fl_Menu_*, %s);\n", f.indent(1), cn, ut.c_str()); } } diff --git a/fluid/nodes/Node.cxx b/fluid/nodes/Node.cxx index 61d736f83..5a5ba75d3 100644 --- a/fluid/nodes/Node.cxx +++ b/fluid/nodes/Node.cxx @@ -513,7 +513,6 @@ Node::Node() : label_(nullptr), callback_(nullptr), user_data_(nullptr), - user_data_type_(nullptr), comment_(nullptr), uid_(0), parent(nullptr), @@ -557,7 +556,6 @@ Node::~Node() { if (label_) free((void*)label_); if (callback_) free((void*)callback_); if (user_data_) free((void*)user_data_); - if (user_data_type_) free((void*)user_data_type_); if (comment_) free((void*)comment_); } @@ -852,8 +850,8 @@ void Node::user_data(const char *n) { storestring(n,user_data_); } -void Node::user_data_type(const char *n) { - storestring(n,user_data_type_); +void Node::user_data_type(const std::string& n) { + storestring(n, user_data_type_); } void Node::comment(const char *n) { @@ -943,7 +941,7 @@ void Node::write_properties(fld::io::Project_Writer &f) { f.write_word("user_data"); f.write_word(user_data()); } - if (user_data_type()) { + if (!user_data_type().empty()) { f.write_word("user_data_type"); f.write_word(user_data_type()); } diff --git a/fluid/nodes/Node.h b/fluid/nodes/Node.h index 900addc6b..6a59b8224 100644 --- a/fluid/nodes/Node.h +++ b/fluid/nodes/Node.h @@ -170,7 +170,7 @@ protected: /** Widget user data field as C++ text. */ const char *user_data_; /** Widget user data type as C++ text, usually `void*` or `long`. */ - const char *user_data_type_; + std::string user_data_type_; /** Optional comment for every node in the graph. Visible in browser and panels, and will also be copied to the source code. */ const char *comment_; @@ -236,8 +236,9 @@ public: void callback(const char *); const char *user_data() const {return user_data_;} void user_data(const char *); - const char *user_data_type() const {return user_data_type_;} - void user_data_type(const char *); + std::string user_data_type() const { return user_data_type_; } + std::string user_data_type_or_voidp() const { return user_data_type_.empty() ? "void*" : user_data_type_; } + void user_data_type(const std::string&); const char *comment() { return comment_; } void comment(const char *); diff --git a/fluid/nodes/Widget_Node.cxx b/fluid/nodes/Widget_Node.cxx index 5b51db75e..867360f3f 100644 --- a/fluid/nodes/Widget_Node.cxx +++ b/fluid/nodes/Widget_Node.cxx @@ -1528,8 +1528,10 @@ void Widget_Node::write_static(fld::io::Code_Writer& f) { write_extern_declaration = 0; } if (write_extern_declaration) - f.write_h_once("extern void %s(%s*, %s);", callback(), t.c_str(), - user_data_type() ? user_data_type() : "void*"); + f.write_h_once("extern void %s(%s*, %s);", + callback(), + t.c_str(), + user_data_type_or_voidp().c_str()); } const char* k = class_name(1); const char* c = array_name(this); @@ -1558,8 +1560,8 @@ void Widget_Node::write_static(fld::io::Code_Writer& f) { f.write_c("\nstatic void %s(%s*", cn, t.c_str()); } if (use_o) f.write_c(" o"); - const char* ut = user_data_type() ? user_data_type() : "void*"; - f.write_c(", %s", ut); + std::string ut = user_data_type_or_voidp(); + f.write_c(", %s", ut.c_str()); if (use_v) f.write_c(" v"); f.write_c(") {\n"); f.tag(Mergeback::Tag::GENERIC, Mergeback::Tag::WIDGET_CALLBACK, 0); @@ -1576,7 +1578,7 @@ void Widget_Node::write_static(fld::io::Code_Writer& f) { f.tag(Mergeback::Tag::WIDGET_CALLBACK, Mergeback::Tag::GENERIC, get_uid()); f.write_c("}\n"); if (k) { - f.write_c("void %s::%s(%s* o, %s v) {\n", k, cn, t.c_str(), ut); + f.write_c("void %s::%s(%s* o, %s v) {\n", k, cn, t.c_str(), ut.c_str()); f.write_c("%s((%s*)(o", f.indent(1), k); Node* q = nullptr; for (Node* p = parent; p && p->is_widget(); q = p, p = p->parent) @@ -1607,10 +1609,10 @@ void Widget_Node::write_code1(fld::io::Code_Writer& f) { } if (class_name(1) && callback() && !is_name(callback())) { const char* cn = callback_name(f); - const char* ut = user_data_type() ? user_data_type() : "void*"; + std::string ut = user_data_type_or_voidp(); f.write_public(0); - f.write_h("%sinline void %s_i(%s*, %s);\n", f.indent(1), cn, t.c_str(), ut); - f.write_h("%sstatic void %s(%s*, %s);\n", f.indent(1), cn, t.c_str(), ut); + f.write_h("%sinline void %s_i(%s*, %s);\n", f.indent(1), cn, t.c_str(), ut.c_str()); + f.write_h("%sstatic void %s(%s*, %s);\n", f.indent(1), cn, t.c_str(), ut.c_str()); } // figure out if local variable will be used (prevent compiler warnings): int wused = !name() && is_a(Type::Window); diff --git a/fluid/panels/widget_panel.cxx b/fluid/panels/widget_panel.cxx index a6f4129ae..e44bdbd6a 100644 --- a/fluid/panels/widget_panel.cxx +++ b/fluid/panels/widget_panel.cxx @@ -2445,27 +2445,38 @@ static void cb_14(Fl_Input_Choice* o, void* v) { //fl ▼ ---------------------- callback ~~---~-~~~~=~~-~~=~~~~ ▼ fl// static const char *dflt = "void*"; if (v == LOAD) { - const char *c = current_widget->user_data_type(); - if (!c) c = dflt; - o->value(c); + std::string c = current_widget->user_data_type(); + if (c.empty()) c = dflt; + o->value(c.c_str()); } else { int mod = 0; const char *c = o->value(); const char *d = c_check(c); - if (!*c) o->value(dflt); - else if (!strcmp(c,dflt)) c = nullptr; + if (!*c) { + o->value(dflt); + } else if (!strcmp(c,dflt)) { + c = nullptr; + } if (!d) { if (c && *c && c[strlen(c)-1] != '*' && strcmp(c,"long")) d = "must be pointer or long"; } - if (d) {fl_message("Error in type: %s",d); haderror = 1; return;} + if (d) { + fl_message("Error in type: %s",d); + o->value("void*"); + haderror = 1; + // return; // Don't return. A good value must still be set. + } for (Node *q: Fluid.proj.tree.all_selected_nodes()) { - q->user_data_type(c); + if (c) + q->user_data_type(c); + else + q->user_data_type(""); mod = 1; } if (mod) Fluid.proj.set_modflag(1); } -//fl ▲ ----------~=~~=~~~=--~--------------=~~-~-~~~~-=~-~=-- ▲ fl// +//fl ▲ ----------~=~~=~~~=--~----------~~-~=~---~=~--~=----=~ ▲ fl// } Fl_Menu_Item menu_4[] = { diff --git a/fluid/panels/widget_panel.fl b/fluid/panels/widget_panel.fl index 03c08272b..c93adb9c7 100644 --- a/fluid/panels/widget_panel.fl +++ b/fluid/panels/widget_panel.fl @@ -528,13 +528,13 @@ Function {make_widget_panel()} {uid 9310 } { Fl_Tabs widget_tabs {uid ce20 callback {if (current_widget) - propagate_load((Fl_Group *)o,v);} + propagate_load((Fl_Group *)o,v);} open xywh {10 10 400 350} selection_color 12 labelsize 11 labelcolor 7 when 0 code0 {o->show();} } { Fl_Group wp_gui_tab {uid b76b label GUI - callback propagate_load open selected + callback propagate_load open xywh {10 30 400 330} labelsize 11 when 0 resizable } { Fl_Group {} {uid d70c @@ -1562,7 +1562,7 @@ Use 'Backspace' key to clear.} xywh {95 210 310 20} box DOWN_BOX color 7 selecti } Fl_Group wp_gui_xclass {uid ccce label {X Class:} - callback propagate_load + callback propagate_load open xywh {95 235 300 20} labelfont 1 labelsize 11 align 4 } { Fl_Input {} {uid f009 @@ -1784,7 +1784,7 @@ unselectable, but not grayed out} xywh {225 260 75 20} selection_color 1 labelsi mod = 1; } if (mod) Fluid.proj.set_modflag(1); -}} +}} selected tooltip {The tooltip text for the widget. Use Ctrl-J for newlines.} xywh {95 285 310 20} labelfont 1 labelsize 11 textsize 11 } @@ -2560,22 +2560,33 @@ wCallback->do_callback(wCallback, v);} open Fl_Input_Choice {} {uid 3ee9 callback {static const char *dflt = "void*"; if (v == LOAD) { - const char *c = current_widget->user_data_type(); - if (!c) c = dflt; - o->value(c); + std::string c = current_widget->user_data_type(); + if (c.empty()) c = dflt; + o->value(c.c_str()); } else { int mod = 0; const char *c = o->value(); const char *d = c_check(c); - if (!*c) o->value(dflt); - else if (!strcmp(c,dflt)) c = nullptr; + if (!*c) { + o->value(dflt); + } else if (!strcmp(c,dflt)) { + c = nullptr; + } if (!d) { if (c && *c && c[strlen(c)-1] != '*' && strcmp(c,"long")) d = "must be pointer or long"; } - if (d) {fl_message("Error in type: %s",d); haderror = 1; return;} + if (d) { + fl_message("Error in type: %s",d); + o->value("void*"); + haderror = 1; + // return; // Don't return. A good value must still be set. + } for (Node *q: Fluid.proj.tree.all_selected_nodes()) { - q->user_data_type(c); + if (c) + q->user_data_type(c); + else + q->user_data_type(""); mod = 1; } if (mod) Fluid.proj.set_modflag(1);