mirror of
https://github.com/fltk/fltk.git
synced 2026-05-30 13:05:35 +08:00
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.
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user