From 2d0698502b607aa60876b9c8e68502e61818f2da Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Tue, 26 Nov 2024 23:01:16 -0800 Subject: [PATCH] Allow configuration of builtin main menu buttons (#174) --- res/doc | 25 +++++++++--- src/nickelmenu.cc | 101 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 101 insertions(+), 25 deletions(-) diff --git a/res/doc b/res/doc index e7af22b..242dc2a 100644 --- a/res/doc +++ b/res/doc @@ -190,14 +190,27 @@ # Unknown options are ignored. If there are multiple declarations of an # option, only the first one takes effect. # -# the option name, one of: -# menu_main_15505_enabled - controls enablement of the NickelMenu button on 4.23.15505+ -# menu_main_15505_label - sets the label used for the NickelMenu button on 4.23.15505+ -# menu_main_15505_icon - sets the icon used for the NickelMenu button on 4.23.15505+ -# menu_main_15505_icon_active - sets the active icon used for the NickelMenu button on 4.23.15505+ +# the option name: +# main_menu_15505_
- controls the added NickelMenu button +# main_menu_15505__ - controls the main menu button at position n (indexed from 0) +# note that there may be already-hidden buttons in the list: +# on a Kobo Libra Colour running 4.41.23145, the button list is: +# 0 - Home +# 1 - My Books +# 2 - Activity [hidden] +# 3 - My Notebooks +# 4 - Discover +# 5 - More +# +#
one of: +# enabled - controls enablement of the NickelMenu button on 4.23.15505+ +# label - sets the label used for the NickelMenu button on 4.23.15505+ +# icon - sets the icon used for the NickelMenu button on 4.23.15505+ +# icon_active - sets the active icon used for the NickelMenu button on 4.23.15505+ +# # the option value: # menu_main_15505_enabled - 0 or 1 -# menu_main_15505_label - the label to use instead of "NickelMenu" +# menu_main_15505_label - the label to use instead of the default value # menu_main_15505_icon - the path passed to QPixmap # menu_main_15505_icon_active - the path passed to QPixmap # diff --git a/src/nickelmenu.cc b/src/nickelmenu.cc index d6ce549..57b1655 100644 --- a/src/nickelmenu.cc +++ b/src/nickelmenu.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -263,18 +264,51 @@ QString nm_menu_pixmap(const char *custom, const char *custom_temp_out, const ch return QString(custom_temp_out); } +static const char *nm_main_menu_config(int index, const char *option) { + char buf[strlen("menu_main_15505_9_icon_active") + 1]; + if (snprintf(buf, sizeof(buf), "menu_main_15505_%d_%s", index, option) >= static_cast(sizeof(buf))) { + NM_LOG("Failed to create main menu config key for index %d, option %s", index, option); + return nullptr; + } + return nm_global_config_experimental(buf); +} + +static void main_nav_button_configure(MainNavButton *btn, const char *label, const char *icon, const char *icon_fallback, const char *icon_active, const char *icon_active_fallback) { + if (label) { + MainNavButton_setText(btn, label); + } + + if (icon || icon_fallback) { + QString pixmap = nm_menu_pixmap( + icon, + "/tmp/nm_menu.png", + icon_fallback + ); + if (!pixmap.isEmpty()) { + MainNavButton_setPixmap(btn, pixmap); + } + } + + if (icon_active || icon_active_fallback) { + QString pixmap = nm_menu_pixmap( + icon_active, + "/tmp/nm_menu.png", + icon_active_fallback + ); + if (!pixmap.isEmpty()) { + MainNavButton_setActivePixmap(btn, pixmap); + } + } + + if (icon || icon_fallback || icon_active || icon_active_fallback) { + QFile::remove("/tmp/nm_menu.png"); + } +} + extern "C" __attribute__((visibility("default"))) void _nm_menu_hook2(MainNavView *_this, QWidget *parent) { NM_LOG("MainNavView::MainNavView(%p, %p)", _this, parent); MainNavView_MainNavView(_this, parent); - const char *enabled = nm_global_config_experimental("menu_main_15505_enabled"); - if (enabled && strcmp("0", enabled) == 0) { - NM_LOG("Main menu disabled"); - return; - } - - NM_LOG("Adding main menu button in tab bar for firmware 4.23.15505+."); - if (!MainNavButton_MainNavButton || !MainNavButton_setPixmap || !MainNavButton_setActivePixmap || !MainNavButton_setText || !MainNavButton_setText) { NM_LOG("Could not find required MainNavButton symbols, cannot add tab button for NickelMenu main menu."); return; @@ -286,6 +320,41 @@ extern "C" __attribute__((visibility("default"))) void _nm_menu_hook2(MainNavVie return; } + NM_LOG("Default main menu has %d buttons", bl->count()); + for (int i = 0; i < bl->count(); ++i) { + QWidget *widget = bl->itemAt(i)->widget(); + NM_LOG("Main menu button %d = %s", i, widget ->objectName().toUtf8().constData()); + + MainNavButton *btn = qobject_cast(widget); + if (!btn) { + NM_LOG("qobject_cast failed on button %d", i); + continue; + } + + const char *label = nm_main_menu_config(i, "label"); + const char *icon = nm_main_menu_config(i, "icon"); + const char *icon_active = nm_main_menu_config(i, "icon_active"); + + const char *enabled = nm_main_menu_config(i, "enabled"); + main_nav_button_configure(btn, label, icon, nullptr, icon_active, nullptr); + if (enabled) { + if (strcmp("0", enabled) == 0) { + NM_LOG("Main menu button %d disabled", i); + widget->hide(); + } else if (strcmp("1", enabled) == 0) { + NM_LOG("Main menu button %d explicitly enabled", i); + widget->show(); + } + } + } + + const char *enabled = nm_global_config_experimental("menu_main_15505_enabled"); + if (enabled && strcmp("0", enabled) == 0) { + NM_LOG("Main menu NickelMenu button disabled"); + return; + } + + NM_LOG("Adding main menu button in tab bar for firmware 4.23.15505+."); MainNavButton *btn = reinterpret_cast(calloc(1, 256)); if (!btn) { // way larger than a MainNavButton, but better to be safe NM_LOG("Failed to allocate memory for MainNavButton, cannot add tab button for NickelMenu main menu."); @@ -293,19 +362,13 @@ extern "C" __attribute__((visibility("default"))) void _nm_menu_hook2(MainNavVie } MainNavButton_MainNavButton(btn, parent); - MainNavButton_setPixmap(btn, nm_menu_pixmap( + main_nav_button_configure(btn, + nm_global_config_experimental("menu_main_15505_label") ?: "NickelMenu", nm_global_config_experimental("menu_main_15505_icon"), - "/tmp/nm_menu.png", - ":/images/home/main_nav_more.png" - )); - MainNavButton_setActivePixmap(btn, nm_menu_pixmap( - nm_global_config_experimental("menu_main_15505_icon_active") - ?: nm_global_config_experimental("menu_main_15505_icon"), - "/tmp/nm_menu.png", + ":/images/home/main_nav_more.png", + nm_global_config_experimental("menu_main_15505_icon_active"), ":/images/home/main_nav_more_active.png" - )); - QFile::remove("/tmp/nm_menu.png"); - MainNavButton_setText(btn, nm_global_config_experimental("menu_main_15505_label") ?: "NickelMenu"); + ); btn->setObjectName("nmButton"); QPushButton *sh = new QPushButton(_this); // HACK: we use a QPushButton as an adaptor so we can connect an old-style signal with the new-style connect without needing a custom QObject