fix VOpenedListMenu with new theme

This commit is contained in:
Le Tan 2017-12-04 20:37:36 +08:00
parent 23cae5a68c
commit 24349f4cc7
7 changed files with 150 additions and 123 deletions

View File

@ -412,6 +412,15 @@ QLabel[ColorTealLabel="true"] {
border-radius: 2px; border-radius: 2px;
background-color: #00796B; background-color: #00796B;
} }
QLabel[MenuSeparator="true"] {
padding-top: 5px;
padding-bottom: 5px;
margin-top: 3px;
font: italic;
border-top: 1px solid @menu_separator_bg
}
/* End QLabel */ /* End QLabel */
/* QLineEdit */ /* QLineEdit */

View File

@ -851,6 +851,7 @@ void VEditUtils::insertTitleMark(QTextCursor &p_cursor,
// Remove all the prefix. // Remove all the prefix.
QRegExp prefixReg(VUtils::c_headerPrefixRegExp); QRegExp prefixReg(VUtils::c_headerPrefixRegExp);
bool preMatched = prefixReg.exactMatch(text); bool preMatched = prefixReg.exactMatch(text);
Q_UNUSED(preMatched);
Q_ASSERT(preMatched); Q_ASSERT(preMatched);
length = prefixReg.cap(1).length(); length = prefixReg.cap(1).length();
} }

View File

@ -1,15 +1,36 @@
#include "vbuttonmenuitem.h" #include "vbuttonmenuitem.h"
#include <QAction> #include <QAction>
#include <QPaintEvent>
#include <QFontMetrics>
#include <QPainter>
#include <QRect>
VButtonMenuItem::VButtonMenuItem(QAction *p_action, QWidget *p_parent) VButtonMenuItem::VButtonMenuItem(QAction *p_action, QWidget *p_parent)
: QPushButton(p_parent), m_action(p_action) : QPushButton(p_parent),
m_action(p_action),
m_decorationWidth(0)
{ {
init(); init();
} }
VButtonMenuItem::VButtonMenuItem(QAction *p_action, const QString &p_text, QWidget *p_parent) VButtonMenuItem::VButtonMenuItem(QAction *p_action, const QString &p_text, QWidget *p_parent)
: QPushButton(p_text, p_parent), m_action(p_action) : QPushButton(p_text, p_parent),
m_action(p_action),
m_decorationWidth(0)
{
init();
}
VButtonMenuItem::VButtonMenuItem(QAction *p_action,
const QIcon &p_icon,
const QString &p_text,
const QString &p_decorationText,
QWidget *p_parent)
: QPushButton(p_icon, p_text, p_parent),
m_action(p_action),
m_decorationText(p_decorationText),
m_decorationWidth(0)
{ {
init(); init();
} }
@ -19,3 +40,32 @@ void VButtonMenuItem::init()
connect(this, &QPushButton::clicked, connect(this, &QPushButton::clicked,
m_action, &QAction::triggered); m_action, &QAction::triggered);
} }
void VButtonMenuItem::paintEvent(QPaintEvent *p_event)
{
QPushButton::paintEvent(p_event);
if (m_decorationWidth > 0) {
Q_ASSERT(!m_decorationText.isEmpty());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QFont font = painter.font();
font.setItalic(true);
painter.setFont(font);
QRect re = rect();
re.adjust(re.width() - m_decorationWidth, 0, 0, 0);
painter.drawText(re, Qt::AlignCenter, m_decorationText);
}
}
QSize VButtonMenuItem::sizeHint() const
{
QSize size = QPushButton::sizeHint();
if (!m_decorationText.isEmpty()) {
const_cast<VButtonMenuItem *>(this)->m_decorationWidth = 5 + fontMetrics().width(m_decorationText);
size.rwidth() += m_decorationWidth;
}
return size;
}

View File

@ -4,6 +4,7 @@
#include <QPushButton> #include <QPushButton>
class QAction; class QAction;
class QPaintEvent;
class VButtonMenuItem : public QPushButton class VButtonMenuItem : public QPushButton
@ -14,10 +15,27 @@ public:
VButtonMenuItem(QAction *p_action, const QString &p_text, QWidget *p_parent = nullptr); VButtonMenuItem(QAction *p_action, const QString &p_text, QWidget *p_parent = nullptr);
VButtonMenuItem(QAction *p_action,
const QIcon &p_icon,
const QString &p_text,
const QString &p_decorationText = QString(),
QWidget *p_parent = nullptr);
QSize sizeHint() const Q_DECL_OVERRIDE;
protected:
void paintEvent(QPaintEvent *p_event) Q_DECL_OVERRIDE;
private: private:
void init(); void init();
QAction *m_action; QAction *m_action;
// Decoration text drawn at the right end.
QString m_decorationText;
// Width in pixels of the decoration text.
int m_decorationWidth;
}; };
#endif // VBUTTONMENUITEM_H #endif // VBUTTONMENUITEM_H

View File

@ -702,6 +702,7 @@ void VEditWindow::tabListJump(VFile *p_file)
int idx = findTabByFile(p_file); int idx = findTabByFile(p_file);
Q_ASSERT(idx >= 0); Q_ASSERT(idx >= 0);
setCurrentIndex(idx); setCurrentIndex(idx);
focusWindow();
updateTabStatus(idx); updateTabStatus(idx);
} }
@ -1004,8 +1005,10 @@ bool VEditWindow::showOpenedFileList()
if (count() == 0) { if (count() == 0) {
return false; return false;
} }
leftBtn->showMenu(); leftBtn->showMenu();
return true; VOpenedListMenu *menu = dynamic_cast<VOpenedListMenu *>(leftBtn->menu());
return menu->isAccepted();
} }
bool VEditWindow::activateTab(int p_sequence) bool VEditWindow::activateTab(int p_sequence)

View File

@ -6,12 +6,16 @@
#include <QTimer> #include <QTimer>
#include <QString> #include <QString>
#include <QStyleFactory> #include <QStyleFactory>
#include <QWidgetAction>
#include <QLabel>
#include "veditwindow.h" #include "veditwindow.h"
#include "vnotefile.h" #include "vnotefile.h"
#include "vedittab.h" #include "vedittab.h"
#include "vdirectory.h" #include "vdirectory.h"
#include "utils/vutils.h" #include "utils/vutils.h"
#include "vbuttonmenuitem.h"
#include "utils/vimnavigationforwidget.h"
static const int c_cmdTime = 1 * 1000; static const int c_cmdTime = 1 * 1000;
@ -51,14 +55,11 @@ static bool fileComp(const VOpenedListMenu::ItemInfo &a,
} }
VOpenedListMenu::VOpenedListMenu(VEditWindow *p_editWin) VOpenedListMenu::VOpenedListMenu(VEditWindow *p_editWin)
: QMenu(p_editWin), m_editWin(p_editWin), m_cmdNum(0) : QMenu(p_editWin),
m_editWin(p_editWin),
m_cmdNum(0),
m_accepted(false)
{ {
// Force to display separator text on Windows and macOS.
setStyle(QStyleFactory::create("Fusion"));
int separatorHeight = 20 * VUtils::calculateScaleFactor();
QString style = QString("::separator { color: #009688; height: %1px; padding-top: 3px; }").arg(separatorHeight);
setStyleSheet(style);
setToolTipsVisible(true); setToolTipsVisible(true);
m_cmdTimer = new QTimer(this); m_cmdTimer = new QTimer(this);
@ -78,6 +79,7 @@ void VOpenedListMenu::updateOpenedList()
// Regenerate the opened list. // Regenerate the opened list.
m_seqActionMap.clear(); m_seqActionMap.clear();
clear(); clear();
m_accepted = false;
int curTab = m_editWin->currentIndex(); int curTab = m_editWin->currentIndex();
int nrTab = m_editWin->count(); int nrTab = m_editWin->count();
@ -87,12 +89,12 @@ void VOpenedListMenu::updateOpenedList()
files[i].index = i; files[i].index = i;
} }
Q_ASSERT(!files.isEmpty());
std::sort(files.begin(), files.end(), fileComp); std::sort(files.begin(), files.end(), fileComp);
QString notebook; QString notebook;
const VDirectory *directory = NULL; const VDirectory *directory = NULL;
QFont sepFont;
sepFont.setItalic(true);
for (int i = 0; i < nrTab; ++i) { for (int i = 0; i < nrTab; ++i) {
QPointer<VFile> file = files[i].file; QPointer<VFile> file = files[i].file;
int index = files[i].index; int index = files[i].index;
@ -108,6 +110,7 @@ void VOpenedListMenu::updateOpenedList()
curNotebook = "EXTERNAL_FILES"; curNotebook = "EXTERNAL_FILES";
} }
QString separatorText;
if (curNotebook != notebook if (curNotebook != notebook
|| curDirectory != directory) { || curDirectory != directory) {
notebook = curNotebook; notebook = curNotebook;
@ -117,28 +120,42 @@ void VOpenedListMenu::updateOpenedList()
dirName = directory->getName(); dirName = directory->getName();
} }
QString text;
if (dirName.isEmpty()) { if (dirName.isEmpty()) {
text = QString("[%1]").arg(notebook); separatorText = QString("[%1]").arg(notebook);
} else { } else {
text = QString("[%1] %2").arg(notebook).arg(dirName); separatorText = QString("[%1] %2").arg(notebook).arg(dirName);
} }
QAction *sepAct = addSection(text); // Add label as separator.
sepAct->setFont(sepFont); QWidgetAction *wact = new QWidgetAction(this);
QLabel *label = new QLabel(separatorText);
label->setProperty("MenuSeparator", true);
wact->setDefaultWidget(label);
wact->setSeparator(true);
addAction(wact);
} }
QAction *action = new QAction(m_editWin->tabIcon(index), // Append the separator text to the end of the first item as well.
m_editWin->tabText(index)); QWidgetAction *wact = new QWidgetAction(this);
action->setToolTip(generateDescription(file)); wact->setData(QVariant::fromValue(file));
action->setData(QVariant::fromValue(file)); VButtonMenuItem *w = new VButtonMenuItem(wact,
m_editWin->tabIcon(index),
m_editWin->tabText(index),
separatorText,
this);
w->setToolTip(generateDescription(file));
wact->setDefaultWidget(w);
if (index == curTab) { if (index == curTab) {
QFont boldFont; QFont boldFont = w->font();
boldFont.setBold(true); boldFont.setBold(true);
action->setFont(boldFont); w->setFont(boldFont);
w->setFocus();
} }
addAction(action);
m_seqActionMap[index + c_tabSequenceBase] = action; addAction(wact);
m_seqActionMap[index + c_tabSequenceBase] = wact;
} }
} }
@ -159,17 +176,27 @@ QString VOpenedListMenu::generateDescription(const VFile *p_file) const
void VOpenedListMenu::handleItemTriggered(QAction *p_action) void VOpenedListMenu::handleItemTriggered(QAction *p_action)
{ {
if (!p_action) { if (p_action) {
return;
}
QPointer<VFile> file = p_action->data().value<QPointer<VFile>>(); QPointer<VFile> file = p_action->data().value<QPointer<VFile>>();
if (file) {
m_accepted = true;
emit fileTriggered(file); emit fileTriggered(file);
} }
}
hide();
}
void VOpenedListMenu::keyPressEvent(QKeyEvent *p_event) void VOpenedListMenu::keyPressEvent(QKeyEvent *p_event)
{ {
if (VimNavigationForWidget::injectKeyPressEventForVim(this,
p_event)) {
m_cmdTimer->stop();
m_cmdNum = 0;
return;
}
int key = p_event->key(); int key = p_event->key();
int modifiers = p_event->modifiers();
switch (key) { switch (key) {
case Qt::Key_0: case Qt::Key_0:
case Qt::Key_1: case Qt::Key_1:
@ -186,93 +213,6 @@ void VOpenedListMenu::keyPressEvent(QKeyEvent *p_event)
return; return;
} }
case Qt::Key_BracketLeft:
{
m_cmdTimer->stop();
m_cmdNum = 0;
if (modifiers == Qt::ControlModifier) {
hide();
return;
}
break;
}
case Qt::Key_J:
{
m_cmdTimer->stop();
m_cmdNum = 0;
if (VUtils::isControlModifierForVim(modifiers)) {
QList<QAction *> acts = actions();
if (acts.size() == 0) {
return;
}
int idx = 0;
QAction *act = activeAction();
if (act) {
for (int i = 0; i < acts.size(); ++i) {
if (acts.at(i) == act) {
idx = i + 1;
break;
}
}
}
while (true) {
if (idx >= acts.size()) {
idx = 0;
}
act = acts.at(idx);
if (act->isSeparator() || !act->isVisible()) {
++idx;
} else {
break;
}
}
setActiveAction(act);
return;
}
break;
}
case Qt::Key_K:
{
m_cmdTimer->stop();
m_cmdNum = 0;
if (VUtils::isControlModifierForVim(modifiers)) {
QList<QAction *> acts = actions();
if (acts.size() == 0) {
return;
}
int idx = acts.size() - 1;
QAction *act = activeAction();
if (act) {
for (int i = 0; i < acts.size(); ++i) {
if (acts.at(i) == act) {
idx = i - 1;
break;
}
}
}
while (true) {
if (idx < 0) {
idx = acts.size() - 1;
}
act = acts.at(idx);
if (act->isSeparator() || !act->isVisible()) {
--idx;
} else {
break;
}
}
setActiveAction(act);
return;
}
break;
}
default: default:
m_cmdTimer->stop(); m_cmdTimer->stop();
m_cmdNum = 0; m_cmdNum = 0;
@ -304,13 +244,8 @@ void VOpenedListMenu::addDigit(int p_digit)
m_cmdNum = 0; m_cmdNum = 0;
return; return;
} }
// Set active action to the candidate.
auto it = m_seqActionMap.find(m_cmdNum);
if (it != m_seqActionMap.end()) {
QAction *act = it.value();
setActiveAction(act);
}
} }
m_cmdTimer->start(); m_cmdTimer->start();
} }

View File

@ -21,6 +21,8 @@ public:
explicit VOpenedListMenu(VEditWindow *p_editWin); explicit VOpenedListMenu(VEditWindow *p_editWin);
bool isAccepted() const;
protected: protected:
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
@ -39,10 +41,19 @@ private:
void triggerItem(int p_seq); void triggerItem(int p_seq);
VEditWindow *m_editWin; VEditWindow *m_editWin;
// The number user pressed. // The number user pressed.
int m_cmdNum; int m_cmdNum;
QTimer *m_cmdTimer; QTimer *m_cmdTimer;
QMap<int, QAction*> m_seqActionMap; QMap<int, QAction*> m_seqActionMap;
// Whether the menu is accepted or rejected.
bool m_accepted;
}; };
inline bool VOpenedListMenu::isAccepted() const
{
return m_accepted;
}
#endif // VOPENEDLISTMENU_H #endif // VOPENEDLISTMENU_H