diff options
| author | Matthias Melcher <github@matthiasm.com> | 2025-12-22 23:12:25 +0100 |
|---|---|---|
| committer | Matthias Melcher <github@matthiasm.com> | 2025-12-22 23:12:42 +0100 |
| commit | 33199dab785daaa7c6c5733021ad0cab48e0e1dd (patch) | |
| tree | 7430470aace60b830659ca4d229727aa1f6f6112 /fluid | |
| parent | d0d2e104e9d5303ac897f5d1faca582e619180b2 (diff) | |
FLUID: Add support for lambda callbacks.
Starting the callback text with a '[' assumes that
the rest of the callback is a lambda and generates
inlined code for it.
Diffstat (limited to 'fluid')
| -rw-r--r-- | fluid/documentation/src/page_widget_panel.dox | 15 | ||||
| -rw-r--r-- | fluid/nodes/Menu_Node.cxx | 21 | ||||
| -rw-r--r-- | fluid/nodes/Widget_Node.cxx | 13 |
3 files changed, 36 insertions, 13 deletions
diff --git a/fluid/documentation/src/page_widget_panel.dox b/fluid/documentation/src/page_widget_panel.dox index 7a1261d62..d897037e4 100644 --- a/fluid/documentation/src/page_widget_panel.dox +++ b/fluid/documentation/src/page_widget_panel.dox @@ -369,13 +369,18 @@ \image html wp_cpp_callback.png \image latex wp_cpp_callback.png "" width=7cm - The callback field can be interpreted in two ways. If the callback text is only - a single word, FLUID assumes that this is the name of an external callback - function and declares it in the header as + The callback field can be interpreted in three ways. If the callback text is + only a single word, FLUID assumes that this is the name of an external + callback function and declares it in the header as `extern void my_button_action(Fl_Button*, void*);`. - Otherwise, FLUID assumes that the text is the body of a C++ callback function - and instead creates a local static callback function. The name of the callback + If the first letter of the callback text is a '[', FLUID expects a lambda + function which will be inlined into the widget creation code. The lambda + signature must be `[](Fl_Widget*, void*)->void { ... }`. The widget pointer + can be casted to another type inside the lambda. + + Otherwise, FLUID assumes that the text is the body of a C++ function, + and a local static callback function is created. The name of the callback function is generated by FLUID and guaranteed to be unique within the file. ``` static void cb_input(Fl_Input *o, void *v) { diff --git a/fluid/nodes/Menu_Node.cxx b/fluid/nodes/Menu_Node.cxx index 342fcf014..dcaa2fc55 100644 --- a/fluid/nodes/Menu_Node.cxx +++ b/fluid/nodes/Menu_Node.cxx @@ -329,7 +329,7 @@ void Menu_Item_Node::write_static(fld::io::Code_Writer& f) { if (extra_code(n) && isdeclare(extra_code(n))) f.write_h_once("%s", extra_code(n)); } - if (callback() && !is_name(callback())) { + if (callback() && !is_name(callback()) && (callback()[0] != '[')) { // see if 'o' or 'v' used, to prevent unused argument warnings: int use_o = 0; int use_v = 0; @@ -520,11 +520,20 @@ void Menu_Item_Node::write_item(fld::io::Code_Writer& f) { f.write_c(", 0, "); } if (callback()) { - const char* k = is_name(callback()) ? nullptr : class_name(1); - if (k) { - f.write_c(" (Fl_Callback*)%s::%s,", k, callback_name(f)); + if (callback()[0] == '[') { + f.write_c("\n"); + f.tag(Mergeback::Tag::GENERIC, Mergeback::Tag::WIDGET_CALLBACK, 0); + f.write_c_indented(callback(), 1, 0); + f.write_c("\n"); + f.tag(Mergeback::Tag::WIDGET_CALLBACK, Mergeback::Tag::GENERIC, get_uid()); + f.write_c("%s, ", f.indent_plus(1)); } else { - f.write_c(" (Fl_Callback*)%s,", callback_name(f)); + const char* k = is_name(callback()) ? nullptr : class_name(1); + if (k) { + f.write_c(" (Fl_Callback*)%s::%s,", k, callback_name(f)); + } else { + f.write_c(" (Fl_Callback*)%s,", callback_name(f)); + } } } else f.write_c(" 0,"); @@ -571,7 +580,7 @@ void Menu_Item_Node::write_code1(fld::io::Code_Writer& f) { } if (callback()) { - if (!is_name(callback()) && class_name(1)) { + 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*"; f.write_public(0); diff --git a/fluid/nodes/Widget_Node.cxx b/fluid/nodes/Widget_Node.cxx index e711c03f0..b74560f05 100644 --- a/fluid/nodes/Widget_Node.cxx +++ b/fluid/nodes/Widget_Node.cxx @@ -1499,7 +1499,7 @@ void Widget_Node::write_static(fld::io::Code_Writer& f) { if (strchr(c, '[') == nullptr) f.write_c("%s *%s=(%s *)0;\n", t, c, t); else f.write_c("%s *%s={(%s *)0};\n", t, c, t); } - if (callback() && !is_name(callback())) { + if (callback() && !is_name(callback()) && (callback()[0] != '[')) { // see if 'o' or 'v' used, to prevent unused argument warnings: int use_o = 0; int use_v = 0; @@ -1883,7 +1883,16 @@ void Widget_Node::write_widget_code(fld::io::Code_Writer& f) { const char* ud = user_data(); if (class_name(1) && !parent->is_widget()) ud = "this"; if (callback()) { - f.write_c("%s%s->callback((Fl_Callback*)%s", f.indent(), var, callback_name(f)); + if (callback()[0] == '[') { + f.write_c("%s%s->callback(\n", f.indent(), var); + f.tag(Mergeback::Tag::GENERIC, Mergeback::Tag::WIDGET_CALLBACK, 0); + f.write_c_indented(callback(), 1, 0); + f.write_c("\n"); + f.tag(Mergeback::Tag::WIDGET_CALLBACK, Mergeback::Tag::GENERIC, get_uid()); + f.write_c("%s", f.indent_plus(1)); + } else { + f.write_c("%s%s->callback((Fl_Callback*)%s", f.indent(), var, callback_name(f)); + } if (ud) f.write_c(", (void*)(%s));\n", ud); else |
