Allow configuration of builtin main menu buttons (#174)
This commit is contained in:
25
res/doc
25
res/doc
@@ -190,14 +190,27 @@
|
|||||||
# Unknown options are ignored. If there are multiple declarations of an
|
# Unknown options are ignored. If there are multiple declarations of an
|
||||||
# option, only the first one takes effect.
|
# option, only the first one takes effect.
|
||||||
#
|
#
|
||||||
# <key> the option name, one of:
|
# <key> the option name:
|
||||||
# menu_main_15505_enabled - controls enablement of the NickelMenu button on 4.23.15505+
|
# main_menu_15505_<main menu option> - controls the added NickelMenu button
|
||||||
# menu_main_15505_label - sets the label used for the NickelMenu button on 4.23.15505+
|
# main_menu_15505_<n>_<main_menu_option> - controls the main menu button at position n (indexed from 0)
|
||||||
# menu_main_15505_icon - sets the icon used for the NickelMenu button on 4.23.15505+
|
# note that there may be already-hidden buttons in the list:
|
||||||
# menu_main_15505_icon_active - sets the active icon used for the NickelMenu button on 4.23.15505+
|
# 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
|
||||||
|
#
|
||||||
|
# <main menu option> 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+
|
||||||
|
#
|
||||||
# <val> the option value:
|
# <val> the option value:
|
||||||
# menu_main_15505_enabled - 0 or 1
|
# 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 - the path passed to QPixmap
|
||||||
# menu_main_15505_icon_active - the path passed to QPixmap
|
# menu_main_15505_icon_active - the path passed to QPixmap
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QMetaProperty>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -263,18 +264,51 @@ QString nm_menu_pixmap(const char *custom, const char *custom_temp_out, const ch
|
|||||||
return QString(custom_temp_out);
|
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<ssize_t>(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) {
|
extern "C" __attribute__((visibility("default"))) void _nm_menu_hook2(MainNavView *_this, QWidget *parent) {
|
||||||
NM_LOG("MainNavView::MainNavView(%p, %p)", _this, parent);
|
NM_LOG("MainNavView::MainNavView(%p, %p)", _this, parent);
|
||||||
MainNavView_MainNavView(_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) {
|
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.");
|
NM_LOG("Could not find required MainNavButton symbols, cannot add tab button for NickelMenu main menu.");
|
||||||
return;
|
return;
|
||||||
@@ -286,6 +320,41 @@ extern "C" __attribute__((visibility("default"))) void _nm_menu_hook2(MainNavVie
|
|||||||
return;
|
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<MainNavButton*>(widget);
|
||||||
|
if (!btn) {
|
||||||
|
NM_LOG("qobject_cast<MainNavButton*> 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<MainNavButton*>(calloc(1, 256));
|
MainNavButton *btn = reinterpret_cast<MainNavButton*>(calloc(1, 256));
|
||||||
if (!btn) { // way larger than a MainNavButton, but better to be safe
|
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.");
|
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_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"),
|
nm_global_config_experimental("menu_main_15505_icon"),
|
||||||
"/tmp/nm_menu.png",
|
":/images/home/main_nav_more.png",
|
||||||
":/images/home/main_nav_more.png"
|
nm_global_config_experimental("menu_main_15505_icon_active"),
|
||||||
));
|
|
||||||
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_active.png"
|
":/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");
|
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
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user