3 days ago
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();