--- qt-camels-0.01op/src/qt_stub.cpp 2025-07-01 22:20:13.000000000 +0200 +++ qt-camels-0.02/src/qt_stub.cpp 2025-07-02 22:39:55.000000000 +0200 @@ -1,5 +1,5 @@ /* Copyright (C) 2025 Florent Monnier */ -/* SPDX_License-id: ISC */ +/* SPDX_License-id: "ISC" */ #include #include #include @@ -14,6 +14,9 @@ #include #include #include +#include +#include +#include #include @@ -184,6 +187,38 @@ (*((QTabWidget **) Data_abstract_val(v))) +/* continue using defines */ + +#define Val_WIDGET(Widget) \ +static value Val_##Widget(Widget *p) \ +{ \ + value v = caml_alloc(1, Abstract_tag); \ + *((Widget **) Data_abstract_val(v)) = p; \ + return v; \ +} + +Val_WIDGET(QMainWindow) +Val_WIDGET(QMenuBar) +Val_WIDGET(QMenu) +Val_WIDGET(QAction) +Val_WIDGET(QMessageBox) + +#define QMainWindow_val(v) \ + (*((QMainWindow **) Data_abstract_val(v))) + +#define QMenuBar_val(v) \ + (*((QMenuBar **) Data_abstract_val(v))) + +#define QMenu_val(v) \ + (*((QMenu **) Data_abstract_val(v))) + +#define QAction_val(v) \ + (*((QAction **) Data_abstract_val(v))) + +#define QMessageBox_val(v) \ + (*((QMessageBox **) Data_abstract_val(v))) + + /* declared-scope */ @@ -200,6 +235,7 @@ const value *closure_f = caml_named_value(cb); value op = caml_callback(*closure_f, caml_copy_string(s)); + (void)caml_qt_stub_app_run(op, ref_assoc); } static void caml_qt_connect_combobox(const char *cb, QComboBox *combo, value ref_assoc) @@ -210,6 +246,7 @@ const value *closure_f = caml_named_value(cb); value op = caml_callback(*closure_f, caml_copy_string(s)); + (void)caml_qt_stub_app_run(op, ref_assoc); } static void caml_qt_connect_slider(const char *cb, QSlider *slider, int d, value ref_assoc) @@ -258,6 +295,13 @@ (void)caml_qt_stub_app_run(op, ref_assoc); } +static void caml_qt_connect_action(const char *cb, QAction *action, value ref_assoc) +{ + const value *closure_f = caml_named_value(cb); + value op = caml_callback(*closure_f, Val_unit); + (void)caml_qt_stub_app_run(op, ref_assoc); +} + /* List.assoc() */ @@ -361,7 +405,7 @@ case 4: // Create_checkbox { value s = Field(ho, 1); - QCheckBox *checkbox = new QCheckBox((s == Val_none ? nullptr : String_val(Some_val(s)))); + QCheckBox *checkbox = new QCheckBox( (s == Val_none ? nullptr : String_val(Some_val(s))) ); value c = Val_QCheckBox(checkbox); value id = Field(ho, 0); @@ -659,7 +703,7 @@ value cb = Field(ho, 2); - QObject::connect(button, &QPushButton::clicked, [&]() { + QObject::connect(button, &QPushButton::clicked, [=]() { caml_qt_connect_button(String_val(cb), button, ref_assoc); }); } @@ -845,7 +889,7 @@ value cb = Field(ho, 2); - QObject::connect(editor, &QPlainTextEdit::textChanged, [&]() { + QObject::connect(editor, &QPlainTextEdit::textChanged, [=]() { caml_qt_connect_editor(String_val(cb), editor, ref_assoc); }); } @@ -948,6 +992,147 @@ } break; +#define create_WIDGET(QWidget) \ + { \ + QWidget *widget = new QWidget(); \ + value w = Val_##QWidget(widget); \ + \ + value id = Field(ho, 0); \ + \ + assoc = caml_alloc(2, 0); \ + Store_field(assoc, 0, id); \ + Store_field(assoc, 1, w); \ + \ + cons = caml_alloc(2, 0); \ + Store_field(cons, 0, assoc); \ + Store_field(cons, 1, ref_assoc); \ + ref_assoc = cons; \ + } + + case 44: // Create_mainWindow + create_WIDGET(QMainWindow) + break; + +#define show_WIDGET(QWidget) \ + { \ + value id = Field(ho, 0); \ + value w = List_assoc(id, ref_assoc); \ + \ + QWidget *widget = QWidget##_val(w); \ + \ + widget->show(); \ + } + + case 45: // Show_mainWindow + show_WIDGET(QMainWindow) + break; + + case 46: // Create_menuBar + { + value id0 = Field(ho, 1); + value w = List_assoc(id0, ref_assoc); + + QMainWindow *window = QMainWindow_val(w); + + QMenuBar *menuBar = window->menuBar(); + value m = Val_QMenuBar(menuBar); + + value id = Field(ho, 0); + + assoc = caml_alloc(2, 0); + Store_field(assoc, 0, id); + Store_field(assoc, 1, m); + + cons = caml_alloc(2, 0); + Store_field(cons, 0, assoc); // head + Store_field(cons, 1, ref_assoc); // tail + ref_assoc = cons; + } + break; + + case 47: // Create_menu + { + value id0 = Field(ho, 1); + value b = List_assoc(id0, ref_assoc); + + QMenuBar *menuBar = QMenuBar_val(b); + + value s = Field(ho, 2); + + QMenu *menu = menuBar->addMenu(String_val(s)); + value m = Val_QMenu(menu); + + value id = Field(ho, 0); + + assoc = caml_alloc(2, 0); + Store_field(assoc, 0, id); + Store_field(assoc, 1, m); + + cons = caml_alloc(2, 0); + Store_field(cons, 0, assoc); // head + Store_field(cons, 1, ref_assoc); // tail + ref_assoc = cons; + } + break; + + case 48: // Create_action + { + value id0 = Field(ho, 1); + value m = List_assoc(id0, ref_assoc); + + QMenu *menu = QMenu_val(m); + + value s = Field(ho, 2); + + QAction *action = menu->addAction(String_val(s)); + value a = Val_QAction(action); + + value id = Field(ho, 0); + + assoc = caml_alloc(2, 0); + Store_field(assoc, 0, id); + Store_field(assoc, 1, a); + + cons = caml_alloc(2, 0); + Store_field(cons, 0, assoc); // head + Store_field(cons, 1, ref_assoc); // tail + ref_assoc = cons; + } + break; + + case 49: // Action_connect + { + value id = Field(ho, 0); + value a = List_assoc(id, ref_assoc); + + QAction *action = QAction_val(a); + + value cb = Field(ho, 2); + + QObject::connect(action, &QAction::triggered, [=]() { + caml_qt_connect_action(String_val(cb), action, ref_assoc); + }); + } + break; + + case 50: // MessageBox_information + { + value s1 = Field(ho, 1); + value s2 = Field(ho, 2); + + QMessageBox::information(nullptr, String_val(s1), String_val(s2)); + } + break; + + case 51: // MessageBox_warning + { + value s1 = Field(ho, 1); + value s2 = Field(ho, 2); + + QMessageBox::warning(nullptr, String_val(s1), String_val(s2)); + } + break; + default: caml_failwith("op-failure"); }