ui: Improved code view UI

* reduced minimized file state to one-colored block
* added hover states to file buttons
* show hover state when hovering title bar
* fixed file button use for overview stats snippet
This commit is contained in:
Eberhard Graether
2017-06-05 23:46:50 +02:00
parent 71b3bdb26b
commit fc36cc25ca
6 changed files with 328 additions and 50 deletions
+6 -27
View File
@@ -82,8 +82,6 @@
background-color: <color:code/snippet/background>;
border: 2px solid <color:code/file/background>;
border-radius: 12px;
border-top-left-radius: 14px;
border-top-right-radius: 14px;
font-size: <setting:font_size>px;
padding-bottom: 7px;
}
@@ -93,7 +91,6 @@
border-top-left-radius: 7px;
border-top-right-radius: 7px;
font-size: <setting:font_size>px;
padding-right: 5px;
}
#code_file #title_label, #single_file_title_bar #file_title {
@@ -106,7 +103,7 @@
}
#code_file #title_label {
margin: 1px 8px 3px;
margin: 1px 8px;
}
#single_file_title_bar #file_title {
@@ -181,34 +178,16 @@
selection-background-color: <color:code/snippet/selection/background>;
}
#code_file #maximize_button, #code_file #snippet_button, #code_file #minimize_button {
#code_file #file_button {
background: transparent;
border: none;
margin: 3px;
max-height: 16px;
max-width: 16px;
}
#code_file #maximize_button {
border-image: url(<setting:gui_path>code_view/images/maximize_inactive.png);
}
#code_file #maximize_button:enabled {
border-image: url(<setting:gui_path>code_view/images/maximize_active.png);
}
#code_file #snippet_button {
border-image: url(<setting:gui_path>code_view/images/snippet_inactive.png);
}
#code_file #snippet_button:enabled {
border-image: url(<setting:gui_path>code_view/images/snippet_active.png);
}
#code_file #minimize_button {
border-image: url(<setting:gui_path>code_view/images/minimize_inactive.png);
}
#code_file #minimize_button:enabled {
border-image: url(<setting:gui_path>code_view/images/minimize_active.png);
#code_file #file_button:enabled {
border-image: url(<setting:gui_path>code_view/images/button_background.png);
}
#single_file_title_bar {
Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

+120 -16
View File
@@ -5,6 +5,7 @@
#include <QVBoxLayout>
#include "utility/messaging/type/MessageChangeFileView.h"
#include "utility/ResourcePaths.h"
#include "data/location/SourceLocationFile.h"
#include "qt/element/QtCodeFileTitleButton.h"
@@ -28,11 +29,14 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeNavigator* navigator)
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
m_titleBar = new QPushButton(this);
m_titleBar = new QtHoverButton(this);
m_titleBar->setObjectName("title_widget");
m_titleBar->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
layout->addWidget(m_titleBar);
connect(dynamic_cast<QtHoverButton*>(m_titleBar), SIGNAL(hoveredIn(QPushButton*)), this, SLOT(enteredTitleBar(QPushButton*)));
connect(dynamic_cast<QtHoverButton*>(m_titleBar), SIGNAL(hoveredOut(QPushButton*)), this, SLOT(leftTitleBar(QPushButton*)));
QHBoxLayout* titleLayout = new QHBoxLayout();
titleLayout->setMargin(0);
titleLayout->setSpacing(0);
@@ -56,24 +60,39 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeNavigator* navigator)
titleLayout->addStretch(3);
m_minimizeButton = new QPushButton(this);
m_minimizeButton->setObjectName("minimize_button");
m_minimizeButton = new QtIconStateButton(this);
m_minimizeButton->addState(QtIconStateButton::STATE_DEFAULT, (ResourcePaths::getGuiPath().str() + "code_view/images/minimize_active.png").c_str());
m_minimizeButton->addState(QtIconStateButton::STATE_HOVERED, (ResourcePaths::getGuiPath().str() + "code_view/images/minimize_inactive.png").c_str(), "#5E5D5D");
m_minimizeButton->addState(QtIconStateButton::STATE_DISABLED, (ResourcePaths::getGuiPath().str() + "code_view/images/minimize_inactive.png").c_str());
m_minimizeButton->setObjectName("file_button");
m_minimizeButton->setToolTip("minimize");
m_minimizeButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
titleLayout->addWidget(m_minimizeButton);
m_snippetButton = new QPushButton(this);
m_snippetButton->setObjectName("snippet_button");
m_snippetButton = new QtIconStateButton(this);
m_snippetButton->addState(QtIconStateButton::STATE_DEFAULT, (ResourcePaths::getGuiPath().str() + "code_view/images/snippet_active.png").c_str());
m_snippetButton->addState(QtIconStateButton::STATE_HOVERED, (ResourcePaths::getGuiPath().str() + "code_view/images/snippet_inactive.png").c_str(), "#5E5D5D");
m_snippetButton->addState(QtIconStateButton::STATE_DISABLED, (ResourcePaths::getGuiPath().str() + "code_view/images/snippet_inactive.png").c_str());
m_snippetButton->setObjectName("file_button");
m_snippetButton->setToolTip("show snippets");
m_snippetButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
titleLayout->addWidget(m_snippetButton);
m_maximizeButton = new QPushButton(this);
m_maximizeButton->setObjectName("maximize_button");
m_maximizeButton = new QtIconStateButton(this);
m_maximizeButton->addState(QtIconStateButton::STATE_DEFAULT, (ResourcePaths::getGuiPath().str() + "code_view/images/maximize_active.png").c_str());
m_maximizeButton->addState(QtIconStateButton::STATE_HOVERED, (ResourcePaths::getGuiPath().str() + "code_view/images/maximize_inactive.png").c_str(), "#5E5D5D");
m_maximizeButton->addState(QtIconStateButton::STATE_DISABLED, (ResourcePaths::getGuiPath().str() + "code_view/images/maximize_inactive.png").c_str());
m_maximizeButton->setObjectName("file_button");
m_maximizeButton->setToolTip("maximize");
m_maximizeButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
titleLayout->addWidget(m_maximizeButton);
connect(m_minimizeButton, SIGNAL(hoveredIn(QPushButton*)), this, SLOT(leftTitleBar(QPushButton*)));
connect(m_minimizeButton, SIGNAL(hoveredOut(QPushButton*)), this, SLOT(enteredTitleBar(QPushButton*)));
connect(m_snippetButton, SIGNAL(hoveredIn(QPushButton*)), this, SLOT(leftTitleBar(QPushButton*)));
connect(m_snippetButton, SIGNAL(hoveredOut(QPushButton*)), this, SLOT(enteredTitleBar(QPushButton*)));
connect(m_maximizeButton, SIGNAL(hoveredIn(QPushButton*)), this, SLOT(leftTitleBar(QPushButton*)));
connect(m_maximizeButton, SIGNAL(hoveredOut(QPushButton*)), this, SLOT(enteredTitleBar(QPushButton*)));
titleLayout->addSpacing(3);
m_minimizeButton->setEnabled(false);
m_snippetButton->setEnabled(false);
m_maximizeButton->setEnabled(false);
@@ -112,13 +131,12 @@ std::string QtCodeFile::getFileName() const
QtCodeSnippet* QtCodeFile::addCodeSnippet(const CodeSnippetParams& params)
{
m_isCollapsed = false;
std::shared_ptr<QtCodeSnippet> snippet(new QtCodeSnippet(params, m_navigator, this));
if (params.reduced)
{
m_title->setProject(params.title);
m_isCollapsed = false;
}
m_snippetLayout->addWidget(snippet.get());
@@ -141,6 +159,10 @@ QtCodeSnippet* QtCodeFile::addCodeSnippet(const CodeSnippetParams& params)
return m_fileSnippet.get();
}
else
{
m_isCollapsed = false;
}
m_snippets.push_back(snippet);
@@ -310,6 +332,12 @@ void QtCodeFile::setMinimized()
m_minimizeButton->setEnabled(false);
m_snippetButton->setEnabled(m_snippets.size() || (isCollapsed() && !m_isWholeFile));
m_maximizeButton->setEnabled(true);
m_minimizeButton->hoverOut();
m_snippetButton->hoverOut();
m_maximizeButton->hoverOut();
setStyleSheet("#code_file { padding-bottom: 0; } #code_file #title_widget { border-radius: 7px; }");
}
void QtCodeFile::setSnippets()
@@ -327,6 +355,12 @@ void QtCodeFile::setSnippets()
m_minimizeButton->setEnabled(true);
m_snippetButton->setEnabled(false);
m_maximizeButton->setEnabled(true);
m_minimizeButton->hoverOut();
m_snippetButton->hoverOut();
m_maximizeButton->hoverOut();
setStyleSheet("");
}
void QtCodeFile::setMaximized()
@@ -342,8 +376,14 @@ void QtCodeFile::setMaximized()
}
m_minimizeButton->setEnabled(true);
m_snippetButton->setEnabled(m_snippets.size());
m_snippetButton->setEnabled(m_snippets.size() || (isCollapsed() && !m_isWholeFile));
m_maximizeButton->setEnabled(false);
m_minimizeButton->hoverOut();
m_snippetButton->hoverOut();
m_maximizeButton->hoverOut();
setStyleSheet("");
}
bool QtCodeFile::hasSnippets() const
@@ -385,8 +425,15 @@ void QtCodeFile::updateTitleBar()
m_title->updateTexts();
}
void QtCodeFile::clickedMinimizeButton() const
void QtCodeFile::clickedMinimizeButton()
{
// overview stats
if (m_filePath.empty())
{
setMinimized();
return;
}
MessageChangeFileView(
m_filePath,
MessageChangeFileView::FILE_MINIMIZED,
@@ -395,7 +442,7 @@ void QtCodeFile::clickedMinimizeButton() const
).dispatch();
}
void QtCodeFile::clickedSnippetButton() const
void QtCodeFile::clickedSnippetButton()
{
MessageChangeFileView(
m_filePath,
@@ -405,8 +452,15 @@ void QtCodeFile::clickedSnippetButton() const
).dispatch();
}
void QtCodeFile::clickedMaximizeButton() const
void QtCodeFile::clickedMaximizeButton()
{
// overview stats
if (m_filePath.empty())
{
setMaximized();
return;
}
MessageChangeFileView(
m_filePath,
MessageChangeFileView::FILE_MAXIMIZED,
@@ -415,6 +469,56 @@ void QtCodeFile::clickedMaximizeButton() const
).dispatch();
}
void QtCodeFile::enteredTitleBar(QPushButton* button)
{
if (m_minimizeButton->isEnabled())
{
if (m_minimizeButton != button)
{
m_minimizeButton->hoverIn();
}
}
else if (m_snippetButton->isEnabled())
{
if (m_snippetButton != button)
{
m_snippetButton->hoverIn();
}
}
else if (m_maximizeButton->isEnabled())
{
if (m_maximizeButton != button)
{
m_maximizeButton->hoverIn();
}
}
}
void QtCodeFile::leftTitleBar(QPushButton* button)
{
if (m_minimizeButton->isEnabled())
{
if (m_minimizeButton != button)
{
m_minimizeButton->hoverOut();
}
}
else if (m_snippetButton->isEnabled())
{
if (m_snippetButton != button)
{
m_snippetButton->hoverOut();
}
}
else if (m_maximizeButton->isEnabled())
{
if (m_maximizeButton != button)
{
m_maximizeButton->hoverOut();
}
}
}
void QtCodeFile::clickedTitleBar()
{
if (m_minimizeButton->isEnabled())
+12 -7
View File
@@ -7,9 +7,11 @@
#include <QFrame>
#include "component/view/helper/CodeSnippetParams.h"
#include "utility/file/FilePath.h"
#include "component/view/helper/CodeSnippetParams.h"
#include "qt/element/QtIconButton.h"
class QLabel;
class QPushButton;
class QtCodeFileTitleButton;
@@ -58,9 +60,12 @@ public:
void updateTitleBar();
public slots:
void clickedMinimizeButton() const;
void clickedSnippetButton() const;
void clickedMaximizeButton() const;
void clickedMinimizeButton();
void clickedSnippetButton();
void clickedMaximizeButton();
void enteredTitleBar(QPushButton* button);
void leftTitleBar(QPushButton* button);
private slots:
void clickedTitleBar();
@@ -74,9 +79,9 @@ private:
QtCodeFileTitleButton* m_title;
QLabel* m_referenceCount;
QPushButton* m_minimizeButton;
QPushButton* m_snippetButton;
QPushButton* m_maximizeButton;
QtIconStateButton* m_minimizeButton;
QtIconStateButton* m_snippetButton;
QtIconStateButton* m_maximizeButton;
QVBoxLayout* m_snippetLayout;
std::vector<std::shared_ptr<QtCodeSnippet>> m_snippets;
+130
View File
@@ -1,7 +1,34 @@
#include "qt/element/QtIconButton.h"
#include <QEvent>
#include "qt/utility/utilityQt.h"
QtHoverButton::QtHoverButton(QWidget* parent)
: QPushButton("", parent)
{
setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
setMouseTracking(true);
}
void QtHoverButton::enterEvent(QEvent *event)
{
if (isEnabled())
{
emit hoveredIn(this);
}
}
void QtHoverButton::leaveEvent(QEvent *event)
{
if (isEnabled())
{
emit hoveredOut(this);
}
}
QtIconButton::QtIconButton(QString iconPath, QString hoveredIconPath, QWidget* parent)
: QPushButton("", parent)
, m_iconPath(iconPath)
@@ -50,3 +77,106 @@ void QtIconButton::setIconFromPath(QString path)
setIcon(QIcon(pixmap));
}
QtIconStateButton::QtIconStateButton(QWidget* parent)
: QPushButton("", parent)
{
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
setMouseTracking(true);
setObjectName("iconStateButton");
leaveEvent(nullptr);
}
void QtIconStateButton::addState(ButtonState buttonState, QString iconPath, QColor color)
{
State state;
state.iconPath = iconPath;
state.color = color;
m_states.emplace(buttonState, state);
if (buttonState == STATE_DEFAULT)
{
leaveEvent(nullptr);
}
}
void QtIconStateButton::hoverIn()
{
enterEvent(nullptr);
}
void QtIconStateButton::hoverOut()
{
leaveEvent(nullptr);
}
void QtIconStateButton::changeEvent(QEvent *event)
{
if (event->type() != QEvent::EnabledChange)
{
return;
}
auto it = m_states.find(isEnabled() ? STATE_DEFAULT : STATE_DISABLED);
if (it != m_states.end())
{
setState(it->second);
}
}
void QtIconStateButton::enterEvent(QEvent *event)
{
if (!isEnabled())
{
return;
}
auto it = m_states.find(STATE_HOVERED);
if (it != m_states.end())
{
setState(it->second);
if (event)
{
emit hoveredIn(this);
}
}
}
void QtIconStateButton::leaveEvent(QEvent *event)
{
if (!isEnabled())
{
return;
}
auto it = m_states.find(STATE_DEFAULT);
if (it != m_states.end())
{
setState(it->second);
if (event)
{
emit hoveredOut(this);
}
}
}
void QtIconStateButton::setState(State state)
{
QPixmap pixmap = QPixmap(state.iconPath);
if (state.color != Qt::transparent)
{
pixmap = utility::colorizePixmap(pixmap, state.color);
}
QIcon icon(pixmap);
icon.addPixmap(pixmap, QIcon::Disabled);
setIcon(icon);
}
+60
View File
@@ -3,6 +3,24 @@
#include <QPushButton>
class QtHoverButton
: public QPushButton
{
Q_OBJECT
public:
QtHoverButton(QWidget* parent = nullptr);
signals:
void hoveredIn(QPushButton*);
void hoveredOut(QPushButton*);
protected:
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
};
class QtIconButton
: public QPushButton
{
@@ -24,4 +42,46 @@ private:
QColor m_color;
};
class QtIconStateButton
: public QPushButton
{
Q_OBJECT
public:
enum ButtonState
{
STATE_DEFAULT,
STATE_HOVERED,
STATE_DISABLED
};
struct State
{
QString iconPath;
QColor color;
};
QtIconStateButton(QWidget* parent = nullptr);
void addState(ButtonState buttonState, QString iconPath, QColor color = Qt::transparent);
void hoverIn();
void hoverOut();
signals:
void hoveredIn(QPushButton*);
void hoveredOut(QPushButton*);
protected:
void changeEvent(QEvent *event);
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
private:
void setState(State state);
std::map<ButtonState, State> m_states;
};
#endif // QT_ICON_BUTTON_H