add QT implementation for menubars, sub-menus and simple menu items

3 days ago

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 30 Mar 2025 12:00:26 +0200 (3 days ago)
changeset 535
ede57f5b6178
parent 534
21f8a7656f6a
child 536
4a1c2eae4bcd

add QT implementation for menubars, sub-menus and simple menu items

application/main.c file | annotate | diff | comparison | revisions
ui/qt/menu.cpp file | annotate | diff | comparison | revisions
ui/qt/menu.h file | annotate | diff | comparison | revisions
ui/qt/qt5.pro file | annotate | diff | comparison | revisions
ui/qt/toolkit.cpp file | annotate | diff | comparison | revisions
ui/qt/toolkit.h file | annotate | diff | comparison | revisions
ui/qt/window.cpp file | annotate | diff | comparison | revisions
--- a/application/main.c	Sun Mar 30 11:28:24 2025 +0200
+++ b/application/main.c	Sun Mar 30 12:00:26 2025 +0200
@@ -793,6 +793,19 @@
 int main(int argc, char **argv) {
     ui_init("app1", 0, NULL);
     ui_onstartup(application_startup, NULL);
+    
+    // menu
+    ui_menu("File") {
+        ui_menuitem(.label = "Test");
+    }
+    
+    ui_menu("Edit") {
+        ui_menuitem(.label = "Undo");
+        ui_menuseparator();
+        ui_menu("Submenu") {
+            ui_menuitem(.label = "Subitem");
+        }
+    }
 
     ui_main();
 
--- a/ui/qt/menu.cpp	Sun Mar 30 11:28:24 2025 +0200
+++ b/ui/qt/menu.cpp	Sun Mar 30 12:00:26 2025 +0200
@@ -35,8 +35,86 @@
 #include "menu.h"
 #include "toolkit.h"
 #include "../common/context.h"
+#include "../common/menu.h"
 #include "../ui/properties.h"
 #include "../ui/window.h"
 #include "stock.h"
 #include "container.h"
 
+
+static ui_menu_add_f createMenuItem[] = {
+    /* UI_MENU                 */ add_menu_widget,
+    /* UI_MENU_ITEM            */ add_menuitem_widget,
+    /* UI_MENU_CHECK_ITEM      */ add_checkitem_widget,
+    /* UI_MENU_RADIO_ITEM      */ add_radioitem_widget,
+    /* UI_MENU_ITEM_LIST       */ add_menuitem_list_widget,
+    /* UI_MENU_CHECKITEM_LIST  */ add_menuitem_list_widget,
+    /* UI_MENU_RADIOITEM_LIST  */ add_menuitem_list_widget,
+    /* UI_MENU_SEPARATOR       */ add_menuseparator_widget
+};
+
+static void add_menu_items(QMenu *parent, int i, UiMenu *menu, UiObject *obj) {
+    UiMenuItemI *it = menu->items_begin;
+    int index = 0;
+    while(it) {
+        createMenuItem[it->type](parent, index, it, obj);
+        it = it->next;
+        index++;
+    }
+}
+
+void add_menu_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+    UiMenu *m = (UiMenu*)item;
+    QMenu *menu = parent->addMenu(m->label);
+    add_menu_items(menu, i, m, obj);
+}
+
+void add_menuitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+    UiMenuItem *it = (UiMenuItem*)item;
+    QString str = QString::fromUtf8(it->label);
+    UiAction *action = new UiAction(obj, str, it->callback, it->userdata);
+    action->setIcon(QIcon::fromTheme(it->icon));
+    action->setIconVisibleInMenu(true);
+    parent->addAction(action);
+    QObject::connect(action, SIGNAL(triggered()), action, SLOT(trigger()));
+}
+
+void add_menuseparator_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+    parent->addSeparator();
+}
+
+void add_checkitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+    
+}
+
+void add_radioitem_widget(QMenu *parent, int index, UiMenuItemI *item, UiObject *obj) {
+    
+}
+
+void add_checkitemnv_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+    
+}
+
+void add_menuitem_list_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj) {
+    
+}
+
+
+void ui_add_menus(UiObject *obj, QMainWindow *window) {
+    UiMenu *menus_begin = uic_get_menu_list();
+    if(menus_begin == NULL) {
+        return;
+    }
+    
+    QMenuBar *mb = window->menuBar();
+    
+    UiMenu *ls = menus_begin;
+    while(ls) {
+        if(ls->item.type == UI_MENU) {
+            QMenu *menu = mb->addMenu(ls->label);
+            add_menu_items(menu, 0, ls, obj);
+        }        
+        ls = (UiMenu*)ls->item.next;
+    }
+}
+
--- a/ui/qt/menu.h	Sun Mar 30 11:28:24 2025 +0200
+++ b/ui/qt/menu.h	Sun Mar 30 12:00:26 2025 +0200
@@ -30,13 +30,24 @@
 #define	MENU_H
 
 #include "../ui/menu.h"
+#include "../common/menu.h"
 
 #include <QMainWindow>
 #include <QMenu>
 #include <QMenuBar>
 #include <QContextMenuEvent>
 
+void ui_add_menus(UiObject *obj, QMainWindow *window);
 
+typedef void(*ui_menu_add_f)(QMenu*, int, UiMenuItemI*, UiObject*);
+
+void add_menu_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_menuitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_menuseparator_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_checkitem_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_radioitem_widget(QMenu *parent, int index, UiMenuItemI *item, UiObject *obj);
+void add_checkitemnv_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
+void add_menuitem_list_widget(QMenu *parent, int i, UiMenuItemI *item, UiObject *obj);
 
 #endif	/* MENU_H */
 
--- a/ui/qt/qt5.pro	Sun Mar 30 11:28:24 2025 +0200
+++ b/ui/qt/qt5.pro	Sun Mar 30 12:00:26 2025 +0200
@@ -1,7 +1,7 @@
 #
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 #
-# Copyright 2014 Olaf Wintermann. All rights reserved.
+# Copyright 2025 Olaf Wintermann. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
--- a/ui/qt/toolkit.cpp	Sun Mar 30 11:28:24 2025 +0200
+++ b/ui/qt/toolkit.cpp	Sun Mar 30 12:00:26 2025 +0200
@@ -35,6 +35,8 @@
 
 #include "../common/document.h"
 #include "../common/properties.h"
+#include "../common/menu.h"
+#include "../common/toolbar.h"
 
 static const char *application_name;
 
@@ -59,9 +61,11 @@
     application = new QApplication(app_argc, app_argv);
     
     uic_docmgr_init();
+    uic_menu_init();
+    uic_toolbar_init();
     
     uic_load_app_properties();
-   
+     
 }
 
 const char* ui_appname() {
@@ -115,6 +119,7 @@
 
 
 
+/* --------------------- Implemtation UiEventWrapper --------------------- */
 
 UiEventWrapper::UiEventWrapper(UiObject *obj, ui_callback f, void* userdata) {
     this->obj = obj;
@@ -123,6 +128,10 @@
 }
 
 void UiEventWrapper::slot() {
+    if(!callback) {
+        return;
+    }
+    
     UiEvent e;
     e.obj = obj;
     e.window = obj->window;
@@ -141,3 +150,33 @@
 void UiEventWrapper::destroy() {
     delete this;
 }
+
+
+/* --------------------- Implemtation UiAction --------------------- */
+
+UiAction::UiAction(UiObject *obj, QString &label, ui_callback f, void *userdata) : QAction(label, NULL) {
+    this->obj = obj;
+    this->callback = f;
+    this->userdata = userdata;
+}
+
+UiAction::~UiAction() {
+    
+}
+
+void UiAction::trigger() {
+    if(!callback) {
+        return;
+    }
+    
+    UiEvent e;
+    e.obj = obj;
+    e.window = obj->window;
+    e.document = obj->ctx->document;
+    e.eventdata = NULL;
+    e.intval = 0;
+    e.set = ui_get_setop();
+    callback(&e, userdata);
+    
+    // TODO: notify var observers
+}
--- a/ui/qt/toolkit.h	Sun Mar 30 11:28:24 2025 +0200
+++ b/ui/qt/toolkit.h	Sun Mar 30 12:00:26 2025 +0200
@@ -63,6 +63,23 @@
     void destroy();
 };
 
+class UiAction : public QAction {
+    Q_OBJECT
+            
+    UiObject *obj;
+    ui_callback callback;
+    void *userdata;
+    
+public:
+    UiVar *var;
+    
+    UiAction(UiObject *obj, QString &label, ui_callback f, void *userdata);
+    ~UiAction();
+    
+private slots:
+    void trigger();
+};
+
 
 #endif	/* TOOLKIT_H */
 
--- a/ui/qt/window.cpp	Sun Mar 30 11:28:24 2025 +0200
+++ b/ui/qt/window.cpp	Sun Mar 30 12:00:26 2025 +0200
@@ -49,12 +49,11 @@
     window->setWindowTitle(title);
     obj->widget = window;
     
-    /*
     if(!simple) {
-        QToolBar *toolbar = ui_create_toolbar(obj);
-        window->addToolBar(Qt::TopToolBarArea, toolbar);
+        ui_add_menus(obj, window);
+        //QToolBar *toolbar = ui_create_toolbar(obj);
+        //window->addToolBar(Qt::TopToolBarArea, toolbar);
     }
-    */
     
     QBoxLayout *box = new QVBoxLayout();
     QWidget *boxWidget = new QWidget();

mercurial