Add menus to seek backward and forward buttons. (#1889)

This commit is contained in:
karliss 2019-12-10 09:34:21 +02:00 committed by xarkes
parent c7e7685314
commit c255fd1cfd
6 changed files with 125 additions and 4 deletions

@ -1 +1 @@
Subproject commit 521ac7c28f42a24586bc0b02f10feb75900a066c
Subproject commit cb60b5e8fd8dc76d847d9935d2ded4df2e05b63e

View File

@ -87,6 +87,7 @@
#include <QPropertyAnimation>
#include <QSysInfo>
#include <QJsonObject>
#include <QJsonArray>
#include <QScrollBar>
#include <QSettings>
@ -188,6 +189,8 @@ void MainWindow::initUI()
ui->actionBackward->setShortcut(QKeySequence::Back);
ui->actionForward->setShortcut(QKeySequence::Forward);
initBackForwardMenu();
/* Setup plugins interfaces */
for (auto plugin : Plugins()->getPlugins()) {
plugin->setupInterface(this);
@ -985,6 +988,106 @@ void MainWindow::initCorners()
setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
}
void MainWindow::initBackForwardMenu()
{
auto prepareButtonMenu = [this](QAction *action) -> QMenu* {
QToolButton *button = qobject_cast<QToolButton *>(ui->mainToolBar->widgetForAction(action));
if (!button) {
return nullptr;
}
QMenu *menu = new QMenu(button);
button->setMenu(menu);
button->setPopupMode(QToolButton::DelayedPopup);
button->setContextMenuPolicy(Qt::CustomContextMenu);
connect(button, &QWidget::customContextMenuRequested, button,
[menu, button] (const QPoint &pos) {
menu->exec(button->mapToGlobal(pos));
});
QFontMetrics metrics(fontMetrics());
// Roughly 10-16 lines depending on padding size, no need to calculate more precisely
menu->setMaximumHeight(metrics.lineSpacing() * 20);
menu->setToolTipsVisible(true);
return menu;
};
if (auto menu = prepareButtonMenu(ui->actionBackward)) {
menu->setObjectName("historyMenu");
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() {
updateHistoryMenu(menu, false);
});
}
if (auto menu = prepareButtonMenu(ui->actionForward)) {
menu->setObjectName("forwardHistoryMenu");
connect(menu, &QMenu::aboutToShow, menu, [this, menu]() {
updateHistoryMenu(menu, true);
});
}
}
void MainWindow::updateHistoryMenu(QMenu *menu, bool redo)
{
// Not too long so that whole screen doesn't get covered,
// not too short so that reasonable length c++ names can be seen most of the time
const int MAX_NAME_LENGTH = 64;
auto hist = Core()->cmdj("sj");
bool history = true;
QList<QAction *> actions;
for (auto item : Core()->cmdj("sj").array()) {
QJsonObject obj = item.toObject();
QString name = obj["name"].toString();
RVA offset = obj["offset"].toVariant().toULongLong();
bool current = obj["current"].toBool(false);
if (current) {
history = false;
}
if (history != redo || current) { // Include current in both directions
QString addressString = RAddressString(offset);
QString toolTip = QString("%1 %2").arg(addressString, name); // show non truncated name in tooltip
name.truncate(MAX_NAME_LENGTH); // TODO:#1904 use common name shortening function
QString label = QString("%1 (%2)").arg(name, addressString);
if (current) {
label = QString("current position (%1)").arg(addressString);
}
QAction *action = new QAction(label, menu);
action->setToolTip(toolTip);
actions.push_back(action);
if (current) {
QFont font;
font.setBold(true);
action->setFont(font);
}
}
}
if (!redo) {
std::reverse(actions.begin(), actions.end());
}
menu->clear();
menu->addActions(actions);
int steps = 0;
for (QAction *item : menu->actions()) {
if (redo) {
connect(item, &QAction::triggered, item, [steps]() {
for (int i = 0; i < steps; i++) {
Core()->seekNext();
}
});
} else {
connect(item, &QAction::triggered, item, [steps]() {
for (int i = 0; i < steps; i++) {
Core()->seekPrev();
}
});
}
++steps;
}
}
void MainWindow::addWidget(QDockWidget* widget)
{
dockWidgets.push_back(widget);

View File

@ -261,6 +261,7 @@ private:
void initDocks();
void initLayout();
void initCorners();
void initBackForwardMenu();
void displayInitialOptionsDialog(const InitialOptions &options = InitialOptions(), bool skipOptionsDialog = false);
void resetToDefaultLayout();
@ -274,6 +275,12 @@ private:
void showZenDocks();
void showDebugDocks();
void enableDebugWidgetsMenu(bool enable);
/**
* @brief Fill menu with seek history entries.
* @param menu
* @param redo set to false for undo history, true for redo.
*/
void updateHistoryMenu(QMenu *menu, bool redo = false);
void toggleDockWidget(QDockWidget *dock_widget, bool show);

View File

@ -397,7 +397,7 @@ QToolButton::menu-button {
QToolButton::menu-indicator
{
image:url(:/qss_icons/rc/down_arrow.png);
top:-7px;
top:-2px;
left:-2px;
}
@ -755,3 +755,6 @@ QLineEdit, QLineEdit[text=""] {
color: #00304d;
}
QMenu#historyMenu, QMenu#forwardHistoryMenu {
menu-scrollable: true;
}

View File

@ -24,3 +24,7 @@ CutterTreeView::item
padding-top: 1px;
padding-bottom: 1px;
}
QMenu#historyMenu, QMenu#forwardHistoryMenu {
menu-scrollable: true;
}

View File

@ -1010,7 +1010,7 @@ QToolButton::menu-button:pressed {
QToolButton::menu-indicator {
image: url(:/qss_icons/rc/down_arrow.png);
top: -7px;
top: -2px;
left: -2px;
/* shift it a bit */
}
@ -1222,4 +1222,8 @@ QDateEdit::down-arrow:on,
QDateEdit::down-arrow:hover,
QDateEdit::down-arrow:focus {
image: url(:/qss_icons/rc/down_arrow.png);
}
}
QMenu#historyMenu, QMenu#forwardHistoryMenu {
menu-scrollable: true;
}