Commit fb706906 authored by Felix Ernst's avatar Felix Ernst Committed by Nate Graham
Browse files

Change default toolbar actions

Based on a newly proposed update to the default Gwenview
appearance this commit changes the actions that are placed on the
toolbar by default.

A class is added that is used to align toolbar contents with the
sidebar whenever it is visible.

This partially implements the mockups at
graphics/gwenview#5
parent 35b46560
......@@ -9,6 +9,7 @@ include_directories(
set(gwenview_SRCS
abstractcontextmanageritem.cpp
alignwithsidebarwidgetaction.cpp
configdialog.cpp
gvcore.cpp
documentinfoprovider.cpp
......
/*
This file is part of the KDE project
SPDX-FileCopyrightText: 2021 Felix Ernst <fe.a.ernst@gmail.com>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "alignwithsidebarwidgetaction.h"
#include <lib/gwenviewconfig.h>
#include <KLocalizedString>
#include <QApplication>
#include <QEvent>
#include <QStyle>
#include <cmath>
AlignWithSideBarWidgetAction::AlignWithSideBarWidgetAction(QObject *parent)
: QWidgetAction(parent)
{
setText(i18nc("@action:inmenu a spacer that aligns toolbar buttons with the sidebar",
"Sidebar Alignment Spacer"));
}
void AlignWithSideBarWidgetAction::setSideBar(QWidget *sideBar)
{
mSideBar = sideBar;
const QList<QWidget *> widgets = createdWidgets();
for (auto widget : widgets) {
static_cast<AligningSpacer *>(widget)->setSideBar(sideBar);
}
}
QWidget *AlignWithSideBarWidgetAction::createWidget(QWidget *parent)
{
auto aligningSpacer = new AligningSpacer(parent);
aligningSpacer->setSideBar(mSideBar);
return aligningSpacer;
}
AligningSpacer::AligningSpacer(QWidget *parent)
: QWidget{parent}
{
if ((mToolbar = qobject_cast<QToolBar *>(parent))) {
connect (mToolbar, &QToolBar::orientationChanged,
this, &AligningSpacer::update);
}
}
void AligningSpacer::setSideBar(QWidget *sideBar)
{
if (mSideBar) {
mSideBar->removeEventFilter(this);
}
mSideBar = sideBar;
if (mSideBar) {
mSideBar->installEventFilter(this);
}
update();
}
bool AligningSpacer::eventFilter(QObject * /* watched */, QEvent *event)
{
switch (event->type()) {
case QEvent::Show:
case QEvent::Hide:
case QEvent::Resize:
update();
return false;
default:
return false;
}
}
QSize AligningSpacer::sizeHint() const
{
if (!mSideBar
|| (mToolbar && mToolbar->orientation() == Qt::Vertical)
) {
return QSize(0, 0);
}
int sideBarWidth = mSideBar->geometry().width();
if (sideBarWidth <= 0) {
if (!Gwenview::GwenviewConfig::sideBarSplitterSizes().isEmpty()) {
sideBarWidth = Gwenview::GwenviewConfig::sideBarSplitterSizes().constFirst();
} else {
// We get to this code when gwenview.rc was deleted or when this is the first run.
// There doesn't seem to be an easy way to get the width the sideBar is going
// to have at this point in time so we set it to some value that leads to
// a nice default appearance on the first run.
sideBarWidth = 242;
}
}
int newWidth;
if (QApplication::layoutDirection() != Qt::RightToLeft) {
newWidth = sideBarWidth - mapTo(window(), QPoint(0,0)).x();
} else {
newWidth = sideBarWidth - window()->width() + mapTo(window(), QPoint(width(), 0)).x();
}
const float separatorWidth = static_cast<float>(
style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, nullptr, this));
if (!mWasSeparatorRemoved) {
// Make it so a potentially following separator looks aligned with the sidebar.
newWidth -= std::ceil(separatorWidth * 0.3);
} else {
// Make it so removing the separator doesn't change the toolbutton positions.
newWidth += std::floor(separatorWidth * 0.7);
}
// Make sure nothing weird can happen.
if (newWidth < 0 || newWidth > sideBarWidth) {
newWidth = 0;
}
return QSize(newWidth, 0);
}
void AligningSpacer::moveEvent(QMoveEvent * /* moved */)
{
update();
}
void AligningSpacer::setFollowingSeparatorVisible(bool visible)
{
if (!mToolbar) {
return;
}
if (mToolbar->orientation() == Qt::Vertical) {
visible = true;
}
const QList<QAction *> toolbarActions = mToolbar->actions();
bool actionForThisSpacerFound = false; // If this is true, the next action in the iteration
// is what we are interested in.
for (auto action : toolbarActions) {
if (actionForThisSpacerFound) {
if (visible && mWasSeparatorRemoved) {
mToolbar->insertSeparator(action);
mWasSeparatorRemoved = false;
} else if (!visible && action->isSeparator()) {
mToolbar->removeAction(action);
mWasSeparatorRemoved = true;
}
return;
}
if (mToolbar->widgetForAction(action) == this) {
actionForThisSpacerFound = true;
}
}
}
void AligningSpacer::update()
{
if (sizeHint().width() < 8) {
// Because the spacer is so small the separator should be visible to serve its purpose.
if (mWasSeparatorRemoved) {
setFollowingSeparatorVisible(true);
}
} else if (mSideBar) {
setFollowingSeparatorVisible(mSideBar->isVisible());
}
setFixedWidth(sizeHint().width());
}
/*
This file is part of the KDE project
SPDX-FileCopyrightText: 2021 Felix Ernst <fe.a.ernst@gmail.com>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef ALIGNWITHSIDEBARWIDGETACTION_H
#define ALIGNWITHSIDEBARWIDGETACTION_H
#include <QPointer>
#include <QToolBar>
#include <QWidgetAction>
/**
* A spacer used to align actions in the toolbar with the sidebar.
*/
class AlignWithSideBarWidgetAction : public QWidgetAction
{
Q_OBJECT
public:
AlignWithSideBarWidgetAction(QObject *parent = nullptr);
/**
* @param sideBar the QWidget this spacer will base its width on to facilitate alignment.
* Can be nullptr.
*/
void setSideBar(QWidget *sideBar);
protected:
/** @see QWidgetAction::createWidget() */
QWidget *createWidget(QWidget *parent) override;
private:
/** The sideBar to align with. */
QPointer<QWidget> mSideBar;
};
/**
* The widget of AlignWithSideBarWidgetAction.
* This class is not meant to be used from outside AlignWithSideBarWidgetAction.
*/
class AligningSpacer : public QWidget
{
Q_OBJECT
public:
AligningSpacer(QWidget *parent);
/** @see AlignWithSideBarWidgetAction::setSideBar() */
void setSideBar(QWidget *sideBar);
/**
* Used to trigger updateWidth() whenever mSideBar's width changes.
*/
bool eventFilter(QObject * /* watched */, QEvent *event) override;
/** @see QWidget::sizeHint() */
QSize sizeHint() const override;
protected:
/**
* Used to trigger updateWidth() when the containing toolbar is locked/unlocked.
*/
void moveEvent(QMoveEvent * /* moved */) override;
private:
/**
* Having a separator directly after an empty space looks bad unless the separator
* is aligned with a sidebar. This method is used to remove or re-add the separator
* so everything looks nice.
* @param visible Wether a potential separator after this widget should be visible.
* This will always be changed to true if the parent toolbar is vertical.
*/
void setFollowingSeparatorVisible(bool visible);
/**
* Updates the width of the spacer depending on the sizeHint() and sets the visibility
* of a potentially following separator.
*/
void update();
private:
/** The SideBar to align with. */
QPointer<QWidget> mSideBar;
/** The parentWidget() of this widget or nullptr when the parent isn't a QToolBar. */
QPointer<QToolBar> mToolbar;
/** This spacer removes following separators if they would look bad/pointless. */
bool mWasSeparatorRemoved = false;
};
#endif // ALIGNWITHSIDEBARWIDGETACTION_H
<?xml version="1.0"?>
<!DOCTYPE gui SYSTEM "kpartgui.dtd">
<gui name="gwenview" version="61">
<gui name="gwenview" version="62">
<MenuBar>
<Menu name="file" >
......@@ -98,16 +98,16 @@
<Separator/>
<Action name="browse" />
<Action name="view" />
<Separator/>
<Action name="fullscreen" />
<Action name="align_with_sidebar" />
<Separator/>
<Action name="go_previous" />
<Action name="go_next" />
<Separator/>
<Action name="rotate_left" />
<Action name="rotate_right" />
<Separator/>
<Action name="toggle_operations_sidebar" />
<Action name="share" />
<Spacer/>
<Action name="fullscreen" />
</ToolBar>
<ActionProperties scheme="Default">
<Action priority="0" name="fullscreen"/>
</ActionProperties>
</gui>
......@@ -69,6 +69,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// Local
#include "gwenview_app_debug.h"
#include "dialogguard.h"
#include "alignwithsidebarwidgetaction.h"
#include "configdialog.h"
#include "documentinfoprovider.h"
#include "viewmainpage.h"
......@@ -202,6 +203,7 @@ struct MainWindow::Private
QAction * mGoToFirstAction;
QAction * mGoToLastAction;
KToggleAction* mToggleSideBarAction;
KToggleAction* mToggleOperationsSideBarAction;
QAction* mFullScreenAction;
QAction * mToggleSlideShowAction;
KToggleAction* mShowMenuBarAction;
......@@ -499,6 +501,18 @@ struct MainWindow::Private
connect(mViewMainPage->toggleSideBarButton(), &QAbstractButton::clicked,
mToggleSideBarAction, &QAction::trigger);
mToggleOperationsSideBarAction = view->add<KToggleAction>("toggle_operations_sidebar");
mToggleOperationsSideBarAction->setText(i18nc("@action opens crop, rename, etc.",
"Show Editing Tools"));
mToggleOperationsSideBarAction->setIcon(QIcon::fromTheme("document-edit"));
connect(mToggleOperationsSideBarAction, &KToggleAction::triggered,
q, &MainWindow::toggleOperationsSideBar);
connect(mSideBar, &QTabWidget::currentChanged,
mToggleOperationsSideBarAction, [=](){
mToggleOperationsSideBarAction->setChecked(
mSideBar->isVisible() && mSideBar->currentPage() == QLatin1String("operations"));
});
mToggleSlideShowAction = view->addAction("toggle_slideshow", q, SLOT(toggleSlideShow()));
q->updateSlideShowAction();
connect(mSlideShow, &SlideShow::stateChanged,
......@@ -551,6 +565,10 @@ struct MainWindow::Private
}
});
#endif
auto alignWithSideBarWidgetAction = new AlignWithSideBarWidgetAction();
alignWithSideBarWidgetAction->setSideBar(mSideBar);
actionCollection->addAction("align_with_sidebar", alignWithSideBarWidgetAction);
}
void setupUndoActions()
......@@ -730,6 +748,7 @@ struct MainWindow::Private
mBrowseAction->setEnabled(enabled);
mViewAction->setEnabled(enabled);
mToggleSideBarAction->setEnabled(enabled);
mToggleOperationsSideBarAction->setEnabled(enabled);
mShowStatusBarAction->setEnabled(enabled);
mFullScreenAction->setEnabled(enabled);
mToggleSlideShowAction->setEnabled(enabled);
......@@ -1212,6 +1231,8 @@ void MainWindow::toggleSideBar(bool visible)
{
d->saveSplitterConfig();
d->mToggleSideBarAction->setChecked(visible);
d->mToggleOperationsSideBarAction->setChecked(visible
&& d->mSideBar->currentPage() == QLatin1String("operations"));
d->saveSideBarVisibility(visible);
d->mSideBar->setVisible(visible);
......@@ -1232,6 +1253,14 @@ void MainWindow::toggleSideBar(bool visible)
}
}
void MainWindow::toggleOperationsSideBar(bool visible)
{
if (visible) {
d->mSideBar->setCurrentPage(QLatin1String("operations"));
}
toggleSideBar(visible);
}
void MainWindow::toggleStatusBar(bool visible)
{
d->mShowStatusBarAction->setChecked(visible);
......
......@@ -93,6 +93,7 @@ private Q_SLOTS:
void goUp();
void toggleSideBar(bool visible);
void toggleOperationsSideBar(bool visible);
void slotModifiedDocumentListChanged();
void slotUpdateCaption(const QString& caption);
void slotPartCompleted();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment