Commit 94d1a277 authored by Boudewijn Rempt's avatar Boudewijn Rempt

FEATURE: Show the tool options in a popup

This can be set in the general settings tab: either we show
the tool options in a docker or in a popup that can be shown
using a button in the toolbar. The popup is detachable.

We need a nice icon for the tool button!

The tool option panels pops up when clicked with by pressing
(by default) the backslash key.

CCMAIL:kimageshop@kde.org
parent 50fd8465
......@@ -333,4 +333,5 @@
<Action name="show_common_colors" icon="" text="Show common colors" whatsThis="" toolTip="Show common colors" iconText="Show common colors" shortcut="U" defaultShortcut="U" isCheckable="false" statusTip=""/>
<Action name="toggle_assistant" icon="" text="Toggle Assistant" whatsThis="" toolTip="Toggle Assistant" iconText="ToggleAssistant" shortcut="Ctrl+Shift+L" defaultShortcut="Ctrl+Shift+L" isCheckable="true" statusTip=""/>
<Action name="undo_polygon_selection" icon="" text="Undo Polygon Selection Points" whatsThis="" toolTip="Undo Polygon Selection Points" iconText="Undo Polygon Selection Points" shortcut="Shift+Z" defaultShortcut="Shift+Z" isCheckable="false" statusTip=""/>
<Action name="" icon="show_tool_options" text="Show Tool Options" whatsThis="" toolTip="Show Tool Options" iconText="Show Tool Options" shortcut="" defaultShortcut="" isCheckable="false" statusTip=""/>
</Actions>
......@@ -210,6 +210,7 @@ set(kritaui_LIB_SRCS
widgets/kis_multi_integer_filter_widget.cc
widgets/kis_multipliers_double_slider_spinbox.cpp
widgets/kis_paintop_presets_popup.cpp
widgets/kis_tool_options_popup.cpp
widgets/kis_paintop_presets_chooser_popup.cpp
widgets/kis_pattern_chooser.cc
widgets/kis_popup_button.cc
......
......@@ -279,6 +279,8 @@ KisMainWindow::KisMainWindow()
setComponentData(KisFactory::componentData());
KGlobal::setActiveComponent(KisFactory::componentData());
KisConfig cfg;
d->viewManager = new KisViewManager(this, actionCollection());
d->themeManager = new Digikam::ThemeManager(this);
......@@ -309,12 +311,14 @@ KisMainWindow::KisMainWindow()
QMetaObject::invokeMethod(this, "initializeGeometry", Qt::QueuedConnection);
ToolDockerFactory toolDockerFactory;
d->toolOptionsDocker = qobject_cast<KoToolDocker*>(createDockWidget(&toolDockerFactory));
KoToolBoxFactory toolBoxFactory;
createDockWidget(&toolBoxFactory);
if (cfg.toolOptionsInDocker()) {
ToolDockerFactory toolDockerFactory;
d->toolOptionsDocker = qobject_cast<KoToolDocker*>(createDockWidget(&toolDockerFactory));
}
foreach(const QString & docker, KoDockRegistry::instance()->keys()) {
KoDockFactoryBase *factory = KoDockRegistry::instance()->value(docker);
createDockWidget(factory);
......@@ -1995,7 +1999,6 @@ QPointer<KisView>KisMainWindow::activeKisView()
void KisMainWindow::newOptionWidgets(const QList<QPointer<QWidget> > &optionWidgetList)
{
d->toolOptionsDocker->setOptionWidgets(optionWidgetList);
KConfigGroup group(KGlobal::config(), "GUI");
QFont dockWidgetFont = KGlobalSettings::generalFont();
......@@ -2009,6 +2012,13 @@ void KisMainWindow::newOptionWidgets(const QList<QPointer<QWidget> > &optionWidg
#endif
w->setFont(dockWidgetFont);
}
if (d->toolOptionsDocker) {
d->toolOptionsDocker->setOptionWidgets(optionWidgetList);
}
else {
d->viewManager->paintOpBox()->newOptionWidgets(optionWidgetList);
}
}
void KisMainWindow::applyDefaultSettings(QPrinter &printer) {
......
......@@ -234,7 +234,6 @@ public Q_SLOTS:
*/
bool saveDocument(KisDocument *document, bool saveas = false, bool silent = false, int specialOutputFlag = 0);
/**
* Update the option widgets to the argument ones, removing the currently set widgets.
*/
......
......@@ -123,6 +123,7 @@ GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
m_backgroundimage->setText(cfg.getMDIBackgroundImage());
m_chkCanvasMessages->setChecked(cfg.showCanvasMessages());
m_chkCompressKra->setChecked(cfg.compressKra());
m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker());
connect(m_bnFileName, SIGNAL(clicked()), SLOT(getBackgroundImage()));
connect(clearBgImageButton, SIGNAL(clicked()), SLOT(clearBackgroundImage()));
......@@ -149,6 +150,7 @@ void GeneralTab::setDefault()
m_backgroundimage->setText(cfg.getMDIBackgroundImage(true));
m_chkCanvasMessages->setChecked(cfg.showCanvasMessages(true));
m_chkCompressKra->setChecked(cfg.compressKra(true));
m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker(true));
}
CursorStyle GeneralTab::cursorStyle()
......@@ -207,6 +209,11 @@ bool GeneralTab::compressKra()
return m_chkCompressKra->isChecked();
}
bool GeneralTab::toolOptionsInDocker()
{
return m_radioToolOptionsInDocker->isChecked();
}
void GeneralTab::getBackgroundImage()
{
KoFileDialog dialog(this, KoFileDialog::OpenFile, "BackgroundImages");
......@@ -1025,6 +1032,7 @@ bool KisDlgPreferences::editPreferences()
cfg.setBackupFile(dialog->m_general->m_backupFileCheckBox->isChecked());
cfg.setShowCanvasMessages(dialog->m_general->showCanvasMessages());
cfg.setCompressKra(dialog->m_general->compressKra());
cfg.setToolOptionsInDocker(dialog->m_general->toolOptionsInDocker());
KisPart *part = KisPart::instance();
if (part) {
foreach(QPointer<KisDocument> doc, part->documents()) {
......
......@@ -77,6 +77,7 @@ public:
int favoritePresets();
bool showCanvasMessages();
bool compressKra();
bool toolOptionsInDocker();
private Q_SLOTS:
void getBackgroundImage();
void clearBackgroundImage();
......
......@@ -76,6 +76,9 @@
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
......@@ -153,19 +156,26 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Window Background:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KColorButton" name="m_mdiColor">
<property name="text">
<string/>
</property>
<property name="color" stdset="0">
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="defaultColor" stdset="0">
<property name="defaultColor">
<color>
<red>0</red>
<green>0</green>
......@@ -174,13 +184,6 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Window Background:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="m_chkRubberBand">
<property name="text">
......@@ -198,7 +201,32 @@
</layout>
</item>
</layout>
<zorder></zorder>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Tool Options (needs restart)</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QRadioButton" name="m_radioToolOptionsInDocker">
<property name="text">
<string>In Docker</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_radioToolOptionsInToolbar">
<property name="text">
<string>In Toolbar</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
......@@ -245,7 +273,7 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
......@@ -261,7 +289,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="3" column="1">
<widget class="QSpinBox" name="m_undoStackSize">
<property name="minimum">
<number>0</number>
......@@ -277,7 +305,7 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
......@@ -293,7 +321,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="4" column="1">
<widget class="QSpinBox" name="m_favoritePresetsSpinBox">
<property name="minimum">
<number>10</number>
......@@ -303,34 +331,34 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="5" column="1">
<widget class="QCheckBox" name="chkShowRootLayer">
<property name="text">
<string>Show root layer</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="m_backupFileCheckBox">
<property name="text">
<string>Create backup file </string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="7" column="1">
<widget class="QCheckBox" name="m_hideSplashScreen">
<property name="text">
<string>Hide splash screen on startup</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="1" column="1">
<widget class="QCheckBox" name="m_chkCompressKra">
<property name="text">
<string>Compress .kra files more (slows loading/saving)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="m_backupFileCheckBox">
<property name="text">
<string>Create backup file </string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
......
......@@ -991,6 +991,17 @@ void KisConfig::setCanvasState(const QString& state) const
}
}
bool KisConfig::toolOptionsPopupDetached(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ToolOptionsPopupDetached", false));
}
void KisConfig::setToolOptionsPopupDetached(bool detached) const
{
m_cfg.writeEntry("ToolOptionsPopupDetached", detached);
}
bool KisConfig::paintopPopupDetached(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("PaintopPopupDetached", false));
......@@ -1537,6 +1548,16 @@ void KisConfig::setCompressKra(bool compress)
m_cfg.writeEntry("compressLayersInKra", compress);
}
bool KisConfig::toolOptionsInDocker(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ToolOptionsInDocker", false));
}
void KisConfig::setToolOptionsInDocker(bool inDocker)
{
m_cfg.writeEntry("ToolOptionsInDocker", inDocker);
}
const KoColorSpace* KisConfig::customColorSelectorColorSpace(bool defaultValue) const
{
const KoColorSpace *cs = 0;
......
......@@ -264,6 +264,9 @@ public:
QString canvasState(bool defaultValue = false) const;
void setCanvasState(const QString& state) const;
bool toolOptionsPopupDetached(bool defaultValue = false) const;
void setToolOptionsPopupDetached(bool detached) const;
bool paintopPopupDetached(bool defaultValue = false) const;
void setPaintopPopupDetached(bool detached) const;
......@@ -451,6 +454,9 @@ public:
bool compressKra(bool defaultValue = false) const;
void setCompressKra(bool compress);
bool toolOptionsInDocker(bool defaultValue = false) const;
void setToolOptionsInDocker(bool inDocker);
template<class T>
void writeEntry(const QString& name, const T& value) {
m_cfg.writeEntry(name, value);
......
This diff is collapsed.
......@@ -51,6 +51,7 @@ class KoCanvasController;
class KisViewManager;
class KisCanvasResourceProvider;
class KisPopupButton;
class KisToolOptionsPopup;
class KisPaintOpPresetsPopup;
class KisPaintOpPresetsChooserPopup;
class KisPaintOpConfigWidget;
......@@ -106,6 +107,10 @@ public:
~KisPaintopBox();
void restoreResource(KoResource* resource);
/**
* Update the option widgets to the argument ones, removing the currently set widgets.
*/
void newOptionWidgets(const QList<QPointer<QWidget> > & optionWidgetList);
public Q_SLOTS:
......@@ -165,26 +170,27 @@ private Q_SLOTS:
void slotUpdateSelectionIcon();
private:
KisCanvasResourceProvider* m_resourceProvider;
QHBoxLayout* m_layout;
QWidget* m_paintopWidget;
KisPaintOpConfigWidget* m_optionWidget;
KisPopupButton* m_settingsWidget;
KisPopupButton* m_presetWidget;
KisPopupButton* m_brushChooser;
KisCompositeOpComboBox* m_cmbCompositeOp;
QToolButton* m_eraseModeButton;
QToolButton* m_alphaLockButton;
QToolButton* hMirrorButton;
QToolButton* vMirrorButton;
KisPaintOpPresetsPopup* m_presetsPopup;
KisPaintOpPresetsChooserPopup* m_presetsChooserPopup;
KisViewManager* m_viewManager;
KisPopupButton* m_workspaceWidget;
KisWidgetChooser* m_sliderChooser[3];
KisCanvasResourceProvider* m_resourceProvider;
QHBoxLayout* m_layout;
QWidget* m_paintopWidget;
KisPaintOpConfigWidget* m_optionWidget;
KisPopupButton* m_toolOptionsPopupButton;
KisPopupButton* m_brushEditorPopupButton;
KisPopupButton* m_presetSelectorPopupButton;
KisCompositeOpComboBox* m_cmbCompositeOp;
QToolButton* m_eraseModeButton;
QToolButton* m_alphaLockButton;
QToolButton* m_hMirrorButton;
QToolButton* m_vMirrorButton;
KisToolOptionsPopup* m_toolOptionsPopup;
KisPaintOpPresetsPopup* m_presetsPopup;
KisPaintOpPresetsChooserPopup* m_presetsChooserPopup;
KisViewManager* m_viewManager;
KisPopupButton* m_workspaceWidget;
KisWidgetChooser* m_sliderChooser[3];
QMap<KoID, KisPaintOpConfigWidget*> m_paintopOptionWidgets;
KisFavoriteResourceManager* m_favoriteResourceManager;
QToolButton* m_reloadButton;
KisFavoriteResourceManager* m_favoriteResourceManager;
QToolButton* m_reloadButton;
QString m_prevCompositeOpID;
......
/* This file is part of the KDE project
* Copyright (C) 2015 Boudewijn Rempt <boud@valdyas.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "widgets/kis_tool_options_popup.h"
#include <QList>
#include <QFont>
#include <QMenu>
#include <QAction>
#include <QShowEvent>
#include <QPointer>
#include <QGridLayout>
#include <QFrame>
#include <QLabel>
#include <QPointer>
#include <QApplication>
#include <kglobal.h>
#include <kconfig.h>
#include <kglobalsettings.h>
#include <klocale.h>
#include "kis_config.h"
struct KisToolOptionsPopup::Private
{
public:
QFont smallFont;
bool detached;
bool ignoreHideEvents;
QRect detachedGeometry;
QList<QPointer<QWidget> > currentWidgetList;
QSet<QWidget *> currentAuxWidgets;
QWidget *hiderWidget; // non current widgets are hidden by being children of this
QGridLayout *housekeeperLayout;
void recreateLayout(const QList<QPointer<QWidget> > &optionWidgetList)
{
foreach(QPointer<QWidget> widget, currentWidgetList) {
if (!widget.isNull() && widget && hiderWidget) {
widget->setParent(hiderWidget);
}
}
qDeleteAll(currentAuxWidgets);
currentAuxWidgets.clear();
currentWidgetList = optionWidgetList;
// need to unstretch row that have previously been stretched
housekeeperLayout->setRowStretch(housekeeperLayout->rowCount()-1, 0);
int cnt = 0;
QFrame *s;
QLabel *l;
housekeeperLayout->setHorizontalSpacing(0);
housekeeperLayout->setVerticalSpacing(2);
int specialCount = 0;
foreach(QPointer<QWidget> widget, currentWidgetList) {
if (widget.isNull() || widget->objectName().isEmpty()) {
continue; // skip this docker in release build when assert don't crash
}
if (!widget->windowTitle().isEmpty()) {
housekeeperLayout->addWidget(l = new QLabel(widget->windowTitle()), cnt++, 0);
currentAuxWidgets.insert(l);
}
housekeeperLayout->addWidget(widget, cnt++, 0);
QLayout *subLayout = widget->layout();
if (subLayout) {
for (int i = 0; i < subLayout->count(); ++i) {
QWidget *spacerWidget = subLayout->itemAt(i)->widget();
if (spacerWidget && spacerWidget->objectName().contains("SpecialSpacer")) {
specialCount++;
}
}
}
widget->show();
if (widget != currentWidgetList.last()) {
housekeeperLayout->addWidget(s = new QFrame(), cnt++, 0);
s->setFrameShape(QFrame::HLine);
currentAuxWidgets.insert(s);
}
}
if (specialCount == currentWidgetList.count() || qApp->applicationName().contains("krita")) {
housekeeperLayout->setRowStretch(cnt, 10000);
}
housekeeperLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
housekeeperLayout->invalidate();
}
};
KisToolOptionsPopup::KisToolOptionsPopup(QWidget *parent)
: QWidget(parent)
, d(new Private())
{
setObjectName("KisToolOptionsPopup");
KConfigGroup group(KGlobal::config(), "GUI");
d->smallFont = KGlobalSettings::generalFont();
qreal pointSize = group.readEntry("palettefontsize", d->smallFont.pointSize() * 0.75);
pointSize = qMax(pointSize, KGlobalSettings::smallestReadableFont().pointSizeF());
d->smallFont.setPointSizeF(pointSize);
setFont(d->smallFont);
KisConfig cfg;
d->detached = !cfg.paintopPopupDetached();
d->ignoreHideEvents = false;
d->housekeeperLayout = new QGridLayout();
d->housekeeperLayout->setContentsMargins(4,4,4,0);
setLayout(d->housekeeperLayout);
d->housekeeperLayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
d->hiderWidget = new QWidget(this);
d->hiderWidget->setVisible(false);
}
KisToolOptionsPopup::~KisToolOptionsPopup()
{
delete d;
}
void KisToolOptionsPopup::newOptionWidgets(const QList<QPointer<QWidget> > &optionWidgetList)
{
d->recreateLayout(optionWidgetList);
}
void KisToolOptionsPopup::contextMenuEvent(QContextMenuEvent *e) {
QMenu menu(this);
QAction* action = menu.addAction(d->detached ? i18n("Attach to Toolbar") : i18n("Detach from Toolbar"));
connect(action, SIGNAL(triggered()), this, SLOT(switchDetached()));
menu.exec(e->globalPos());
}
void KisToolOptionsPopup::hideEvent(QHideEvent *event)
{
if (d->ignoreHideEvents) {
return;
}
if (d->detached) {
d->detachedGeometry = window()->geometry();
}
QWidget::hideEvent(event);
}
void KisToolOptionsPopup::showEvent(QShowEvent *)
{
if (d->detached) {
window()->setGeometry(d->detachedGeometry);
}
}
void KisToolOptionsPopup::switchDetached(bool show)
{
if (parentWidget()) {
d->detached = !d->detached;
if (d->detached) {
d->ignoreHideEvents = true;
parentWidget()->setWindowFlags(Qt::Tool);
if (show) {
parentWidget()->show();
}
d->ignoreHideEvents = false;
}
else {
parentWidget()->setWindowFlags(Qt::Popup);
KisConfig cfg;
parentWidget()->hide();
}
KisConfig cfg;
cfg.setToolOptionsPopupDetached(d->detached);
}
}
/* This file is part of the KDE project
* Copyright (C) 2015 Boudewijn Rempt <boud@valdyas.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KIS_TOOL_OPTIONS_POPUP_H
#define KIS_TOOL_OPTIONS_POPUP_H
#include <QWidget>
#include <QPointer>
class KisToolOptionsPopup : public QWidget
{
Q_OBJECT
public:
explicit KisToolOptionsPopup(QWidget *parent = 0);
virtual ~KisToolOptionsPopup();
bool detached() const;
void newOptionWidgets(const QList<QPointer<QWidget> > &optionWidgetList);
Q_SIGNALS:
public Q_SLOTS:
void switchDetached(bool show = true);
protected:
void contextMenuEvent(QContextMenuEvent *);
void hideEvent(QHideEvent *);
void showEvent(QShowEvent *);
private:
struct Private;
Private *const d;
};
#endif // KIS_TOOL_OPTIONS_POPUP_H
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