Fluid: user_data_type_

This commit is contained in:
Matthias Melcher
2026-01-07 13:23:42 +01:00
parent 1be412ab69
commit 5f6a2cbb16
6 changed files with 67 additions and 43 deletions

View File

@@ -323,8 +323,9 @@ void Menu_Item_Node::write_static(fld::io::Code_Writer& f) {
f.write_h_once("#include <FL/Fl_Multi_Label.H>");
}
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());
}
}

View File

@@ -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());
}

View File

@@ -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 *);

View File

@@ -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);

View File

@@ -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[] = {

View File

@@ -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);