[calligra/calligra/2.9] krita: FEATURE: Show the tool options in a popup

Boudewijn Rempt boud at valdyas.org
Fri Jun 26 10:01:14 UTC 2015


Git commit 9fe05579967da30f0e3b66e7f06fbb438fb0ca01 by Boudewijn Rempt.
Committed on 26/06/2015 at 10:00.
Pushed by rempt into branch 'calligra/2.9'.

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 at kde.org

M  +1    -0    krita/krita.action
M  +1    -0    krita/ui/CMakeLists.txt
M  +14   -4    krita/ui/KisMainWindow.cpp
M  +0    -1    krita/ui/KisMainWindow.h
M  +8    -0    krita/ui/dialogs/kis_dlg_preferences.cc
M  +1    -0    krita/ui/dialogs/kis_dlg_preferences.h
M  +52   -24   krita/ui/forms/wdggeneralsettings.ui
M  +21   -0    krita/ui/kis_config.cc
M  +6    -0    krita/ui/kis_config.h
M  +77   -42   krita/ui/kis_paintop_box.cc
M  +25   -19   krita/ui/kis_paintop_box.h
A  +197  -0    krita/ui/widgets/kis_tool_options_popup.cpp     [License: LGPL (v2+)]
A  +53   -0    krita/ui/widgets/kis_tool_options_popup.h     [License: LGPL (v2+)]

http://commits.kde.org/calligra/9fe05579967da30f0e3b66e7f06fbb438fb0ca01

diff --git a/krita/krita.action b/krita/krita.action
index fa13df6..69d6c11 100644
--- a/krita/krita.action
+++ b/krita/krita.action
@@ -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>
diff --git a/krita/ui/CMakeLists.txt b/krita/ui/CMakeLists.txt
index f1dfdb1..4fd61f7 100644
--- a/krita/ui/CMakeLists.txt
+++ b/krita/ui/CMakeLists.txt
@@ -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
diff --git a/krita/ui/KisMainWindow.cpp b/krita/ui/KisMainWindow.cpp
index 1cdb355..c10169e 100644
--- a/krita/ui/KisMainWindow.cpp
+++ b/krita/ui/KisMainWindow.cpp
@@ -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) {
diff --git a/krita/ui/KisMainWindow.h b/krita/ui/KisMainWindow.h
index 5165145..20a2d9d 100644
--- a/krita/ui/KisMainWindow.h
+++ b/krita/ui/KisMainWindow.h
@@ -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.
      */
diff --git a/krita/ui/dialogs/kis_dlg_preferences.cc b/krita/ui/dialogs/kis_dlg_preferences.cc
index ae388fd..10a423a 100644
--- a/krita/ui/dialogs/kis_dlg_preferences.cc
+++ b/krita/ui/dialogs/kis_dlg_preferences.cc
@@ -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()) {
diff --git a/krita/ui/dialogs/kis_dlg_preferences.h b/krita/ui/dialogs/kis_dlg_preferences.h
index 97058d1..59f41b8 100644
--- a/krita/ui/dialogs/kis_dlg_preferences.h
+++ b/krita/ui/dialogs/kis_dlg_preferences.h
@@ -77,6 +77,7 @@ public:
     int favoritePresets();
     bool showCanvasMessages();
     bool compressKra();
+    bool toolOptionsInDocker();
 private Q_SLOTS:
     void getBackgroundImage();
     void clearBackgroundImage();
diff --git a/krita/ui/forms/wdggeneralsettings.ui b/krita/ui/forms/wdggeneralsettings.ui
index acf0398..cb52d02 100644
--- a/krita/ui/forms/wdggeneralsettings.ui
+++ b/krita/ui/forms/wdggeneralsettings.ui
@@ -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>
diff --git a/krita/ui/kis_config.cc b/krita/ui/kis_config.cc
index db2da91..1865ba8 100644
--- a/krita/ui/kis_config.cc
+++ b/krita/ui/kis_config.cc
@@ -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;
diff --git a/krita/ui/kis_config.h b/krita/ui/kis_config.h
index d21848a..c0ce02b 100644
--- a/krita/ui/kis_config.h
+++ b/krita/ui/kis_config.h
@@ -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);
diff --git a/krita/ui/kis_paintop_box.cc b/krita/ui/kis_paintop_box.cc
index a6968e3..231a151 100644
--- a/krita/ui/kis_paintop_box.cc
+++ b/krita/ui/kis_paintop_box.cc
@@ -65,7 +65,9 @@
 #include "kis_config.h"
 
 #include "widgets/kis_popup_button.h"
+#include "widgets/kis_tool_options_popup.h"
 #include "widgets/kis_paintop_presets_popup.h"
+#include "widgets/kis_tool_options_popup.h"
 #include "widgets/kis_paintop_presets_chooser_popup.h"
 #include "widgets/kis_workspace_chooser.h"
 #include "widgets/kis_paintop_list_widget.h"
@@ -84,9 +86,10 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
     : QWidget(parent)
     , m_resourceProvider(view->resourceProvider())
     , m_optionWidget(0)
-    , m_settingsWidget(0)
-    , m_presetWidget(0)
-    , m_brushChooser(0)
+    , m_toolOptionsPopupButton(0)
+    , m_brushEditorPopupButton(0)
+    , m_presetSelectorPopupButton(0)
+    , m_toolOptionsPopup(0)
     , m_viewManager(view)
     , m_previousNode(0)
     , m_currTabletToolID(KoInputDevice::invalid())
@@ -108,18 +111,28 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
 
     setWindowTitle(i18n("Painter's Toolchest"));
 
-    m_settingsWidget = new KisPopupButton(this);
-    m_settingsWidget->setIcon(koIcon("paintop_settings_02"));
-    m_settingsWidget->setToolTip(i18n("Edit brush settings"));
-    m_settingsWidget->setFixedSize(32, 32);
+    KConfigGroup grp = KGlobal::config()->group("krita").group("Toolbar BrushesAndStuff");
+    int iconsize = grp.readEntry("IconSize", 32);
 
-    m_presetWidget = new KisPopupButton(this);
-    m_presetWidget->setIcon(koIcon("paintop_settings_01"));
-    m_presetWidget->setToolTip(i18n("Choose brush preset"));
-    m_presetWidget->setFixedSize(32, 32);
+    if (!cfg.toolOptionsInDocker()) {
+        m_toolOptionsPopupButton = new KisPopupButton(this);
+        m_toolOptionsPopupButton->setIcon(koIcon("configure"));
+        m_toolOptionsPopupButton->setToolTip(i18n("Tool Settings"));
+        m_toolOptionsPopupButton->setFixedSize(iconsize, iconsize);
+    }
+
+    m_brushEditorPopupButton = new KisPopupButton(this);
+    m_brushEditorPopupButton->setIcon(koIcon("paintop_settings_02"));
+    m_brushEditorPopupButton->setToolTip(i18n("Edit brush settings"));
+    m_brushEditorPopupButton->setFixedSize(iconsize, iconsize);
+
+    m_presetSelectorPopupButton = new KisPopupButton(this);
+    m_presetSelectorPopupButton->setIcon(koIcon("paintop_settings_01"));
+    m_presetSelectorPopupButton->setToolTip(i18n("Choose brush preset"));
+    m_presetSelectorPopupButton->setFixedSize(iconsize, iconsize);
 
     m_eraseModeButton = new QToolButton(this);
-    m_eraseModeButton->setFixedSize(32, 32);
+    m_eraseModeButton->setFixedSize(iconsize, iconsize);
     m_eraseModeButton->setCheckable(true);
 
     KisAction* eraseAction = new KisAction(i18n("Set eraser mode"), m_eraseModeButton);
@@ -133,7 +146,7 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
     eraserBrushSize = 0; // brush size changed when using erase mode
 
     m_reloadButton = new QToolButton(this);
-    m_reloadButton->setFixedSize(32, 32);
+    m_reloadButton->setFixedSize(iconsize, iconsize);
     m_reloadButton->setCheckable(true);
 
     KisAction* reloadAction = new KisAction(i18n("Reload Original Preset"), m_reloadButton);
@@ -142,9 +155,8 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
     m_reloadButton->setDefaultAction(reloadAction);
     m_viewManager->actionCollection()->addAction("reload_preset_action", reloadAction);
 
-
     m_alphaLockButton = new QToolButton(this);
-    m_alphaLockButton->setFixedSize(32, 32);
+    m_alphaLockButton->setFixedSize(iconsize, iconsize);
     m_alphaLockButton->setCheckable(true);
     KisAction* alphaLockAction = new KisAction(i18n("Preserve Alpha"), m_alphaLockButton);
     alphaLockAction->setActivationFlags(KisAction::ACTIVE_DEVICE);
@@ -153,26 +165,26 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
     m_alphaLockButton->setDefaultAction(alphaLockAction);
     m_viewManager->actionCollection()->addAction("preserve_alpha", alphaLockAction);
 
-    hMirrorButton = new QToolButton(this);
-    hMirrorButton->setFixedSize(32, 32);
-    hMirrorButton->setCheckable(true);
+    m_hMirrorButton = new QToolButton(this);
+    m_hMirrorButton->setFixedSize(iconsize, iconsize);
+    m_hMirrorButton->setCheckable(true);
 
-    m_hMirrorAction = new KisAction(i18n("Set horizontal mirror mode"), hMirrorButton);
+    m_hMirrorAction = new KisAction(i18n("Set horizontal mirror mode"), m_hMirrorButton);
     m_hMirrorAction->setIcon(themedIcon("symmetry-horizontal"));
     m_hMirrorAction->setActivationFlags(KisAction::ACTIVE_DEVICE);
     m_hMirrorAction->setCheckable(true);
-    hMirrorButton->setDefaultAction(m_hMirrorAction);
+    m_hMirrorButton->setDefaultAction(m_hMirrorAction);
     m_viewManager->actionCollection()->addAction("hmirror_action", m_hMirrorAction);
 
-    vMirrorButton = new QToolButton(this);
-    vMirrorButton->setFixedSize(32, 32);
-    vMirrorButton->setCheckable(true);
+    m_vMirrorButton = new QToolButton(this);
+    m_vMirrorButton->setFixedSize(iconsize, iconsize);
+    m_vMirrorButton->setCheckable(true);
 
-    m_vMirrorAction = new KisAction(i18n("Set vertical mirror mode"), vMirrorButton);
+    m_vMirrorAction = new KisAction(i18n("Set vertical mirror mode"), m_vMirrorButton);
     m_vMirrorAction->setActivationFlags(KisAction::ACTIVE_DEVICE);
     m_vMirrorAction->setIcon(themedIcon("symmetry-vertical"));
     m_vMirrorAction->setCheckable(true);
-    vMirrorButton->setDefaultAction(m_vMirrorAction);
+    m_vMirrorButton->setDefaultAction(m_vMirrorAction);
     m_viewManager->actionCollection()->addAction("vmirror_action", m_vMirrorAction);
 
     const bool sliderLabels = cfg.sliderLabels();
@@ -208,13 +220,13 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
         slOpacity->setValue(1.0);
         slOpacity->setSingleStep(0.05);
         slOpacity->setMinimumWidth(qMax(sliderWidth, slOpacity->sizeHint().width()));
-        slOpacity->setFixedHeight(32);
+        slOpacity->setFixedHeight(iconsize);
 
         slFlow->setRange(0.0, 1.0, 2);
         slFlow->setValue(1.0);
         slFlow->setSingleStep(0.05);
         slFlow->setMinimumWidth(qMax(sliderWidth, slFlow->sizeHint().width()));
-        slFlow->setFixedHeight(32);
+        slFlow->setFixedHeight(iconsize);
 
         slSize->setRange(0, 1000, 2);
         slSize->setValue(100);
@@ -223,13 +235,13 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
         slSize->setExponentRatio(3.0);
         slSize->setSuffix(" px");
         slSize->setMinimumWidth(qMax(sliderWidth, slSize->sizeHint().width()));
-        slSize->setFixedHeight(32);
+        slSize->setFixedHeight(iconsize);
 
         m_sliderChooser[i]->chooseWidget(cfg.toolbarSlider(i + 1));
     }
 
     m_cmbCompositeOp = new KisCompositeOpComboBox();
-    m_cmbCompositeOp->setFixedHeight(32);
+    m_cmbCompositeOp->setFixedHeight(iconsize);
     foreach(KAction * a, m_cmbCompositeOp->blendmodeActions()) {
         m_viewManager->actionCollection()->addAction(a->text(), a);
     }
@@ -237,7 +249,7 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
     m_workspaceWidget = new KisPopupButton(this);
     m_workspaceWidget->setIcon(koIcon("workspace-chooser"));
     m_workspaceWidget->setToolTip(i18n("Choose workspace"));
-    m_workspaceWidget->setFixedSize(32, 32);
+    m_workspaceWidget->setFixedSize(iconsize, iconsize);
     m_workspaceWidget->setPopupWidget(new KisWorkspaceChooser(view));
 
     QHBoxLayout* baseLayout = new QHBoxLayout(this);
@@ -247,8 +259,11 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
     baseLayout->setContentsMargins(0, 0, 0, 0);
 
     m_layout = new QHBoxLayout(m_paintopWidget);
-    m_layout->addWidget(m_settingsWidget);
-    m_layout->addWidget(m_presetWidget);
+    if (!cfg.toolOptionsInDocker()) {
+        m_layout->addWidget(m_toolOptionsPopupButton);
+    }
+    m_layout->addWidget(m_brushEditorPopupButton);
+    m_layout->addWidget(m_presetSelectorPopupButton);
     m_layout->setSpacing(4);
     m_layout->setContentsMargins(0, 0, 0, 0);
 
@@ -299,10 +314,17 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
     action->setShortcut(KShortcut(Qt::Key_Slash));
     connect(action, SIGNAL(triggered()), this, SLOT(slotSwitchToPreviousPreset()));
 
+    if (!cfg.toolOptionsInDocker()) {
+        action = new KAction(i18n("Show Tool Options"), this);
+        view->actionCollection()->addAction("show_tool_options", action);
+        action->setShortcut(Qt::Key_Backslash);
+        connect(action, SIGNAL(triggered()), m_toolOptionsPopupButton, SLOT(showPopupWidget()));
+    }
+
     QWidget* mirrorActions = new QWidget(this);
     QHBoxLayout* mirrorLayout = new QHBoxLayout(mirrorActions);
-    mirrorLayout->addWidget(hMirrorButton);
-    mirrorLayout->addWidget(vMirrorButton);
+    mirrorLayout->addWidget(m_hMirrorButton);
+    mirrorLayout->addWidget(m_vMirrorButton);
     mirrorLayout->setSpacing(4);
     mirrorLayout->setContentsMargins(0, 0, 0, 0);
     action = new KAction(i18n("Mirror"), this);
@@ -313,13 +335,19 @@ KisPaintopBox::KisPaintopBox(KisViewManager *view, QWidget *parent, const char *
     view->actionCollection()->addAction("workspaces", action);
     action->setDefaultWidget(m_workspaceWidget);
 
+    if (!cfg.toolOptionsInDocker()) {
+        m_toolOptionsPopup = new KisToolOptionsPopup();
+        m_toolOptionsPopupButton->setPopupWidget(m_toolOptionsPopup);
+        m_toolOptionsPopup->switchDetached(false);
+    }
+
     m_presetsPopup = new KisPaintOpPresetsPopup(m_resourceProvider);
-    m_settingsWidget->setPopupWidget(m_presetsPopup);
+    m_brushEditorPopupButton->setPopupWidget(m_presetsPopup);
     m_presetsPopup->switchDetached(false);
 
     m_presetsChooserPopup = new KisPaintOpPresetsChooserPopup();
     m_presetsChooserPopup->setFixedSize(500, 600);
-    m_presetWidget->setPopupWidget(m_presetsChooserPopup);
+    m_presetSelectorPopupButton->setPopupWidget(m_presetsChooserPopup);
 
     m_prevCompositeOpID = KoCompositeOpRegistry::instance().getDefaultCompositeOp().id();
     m_currCompositeOpID = KoCompositeOpRegistry::instance().getDefaultCompositeOp().id();
@@ -414,6 +442,13 @@ void KisPaintopBox::restoreResource(KoResource* resource)
     }
 }
 
+void KisPaintopBox::newOptionWidgets(const QList<QPointer<QWidget> > &optionWidgetList)
+{
+    if (m_toolOptionsPopup) {
+        m_toolOptionsPopup->newOptionWidgets(optionWidgetList);
+    }
+}
+
 void KisPaintopBox::resourceSelected(KoResource* resource)
 {
     KisPaintOpPreset* preset = dynamic_cast<KisPaintOpPreset*>(resource);
@@ -488,7 +523,7 @@ void KisPaintopBox::setCurrentPaintop(const KoID& paintop, KisPaintOpPresetSP pr
 
     m_presetsPopup->setPaintOpSettingsWidget(m_optionWidget);
 
-    Q_ASSERT(m_optionWidget && m_presetWidget);
+    Q_ASSERT(m_optionWidget && m_presetSelectorPopupButton);
     connect(m_optionWidget, SIGNAL(sigConfigurationUpdated()), this, SLOT(slotUpdatePreset()));
     connect(m_optionWidget, SIGNAL(sigSaveLockedConfig(KisPropertiesConfiguration*)), this, SLOT(slotSaveLockedOptionToPreset(KisPropertiesConfiguration*)));
     connect(m_optionWidget, SIGNAL(sigDropLockedConfig(KisPropertiesConfiguration*)), this, SLOT(slotDropLockedOption(KisPropertiesConfiguration*)));
@@ -498,7 +533,7 @@ void KisPaintopBox::setCurrentPaintop(const KoID& paintop, KisPaintOpPresetSP pr
     KisPaintOpFactory* paintOp = KisPaintOpRegistry::instance()->get(paintop.id());
     QString pixFilename = KisFactory::componentData().dirs()->findResource("kis_images", paintOp->pixmap());
 
-    m_settingsWidget->setIcon(QIcon(pixFilename));
+    m_brushEditorPopupButton->setIcon(QIcon(pixFilename));
     m_resourceProvider->setPaintOpPreset(preset);
     m_presetsPopup->setCurrentPaintOp(paintop.id());
 
@@ -588,8 +623,8 @@ void KisPaintopBox::setWidgetState(int flags)
     }
 
     if (flags & (ENABLE_PRESETS | DISABLE_PRESETS)) {
-        m_presetWidget->setEnabled(flags & ENABLE_PRESETS);
-        m_settingsWidget->setEnabled(flags & ENABLE_PRESETS);
+        m_presetSelectorPopupButton->setEnabled(flags & ENABLE_PRESETS);
+        m_brushEditorPopupButton->setEnabled(flags & ENABLE_PRESETS);
     }
 
     for (int i = 0; i < 3; ++i) {
@@ -842,13 +877,13 @@ void KisPaintopBox::slotSetCompositeMode(int index)
 void KisPaintopBox::slotHorizontalMirrorChanged(bool value)
 {
     m_resourceProvider->setMirrorHorizontal(value);
-    toggleHighlightedButton(hMirrorButton);
+    toggleHighlightedButton(m_hMirrorButton);
 }
 
 void KisPaintopBox::slotVerticalMirrorChanged(bool value)
 {
     m_resourceProvider->setMirrorVertical(value);
-    toggleHighlightedButton(vMirrorButton);
+    toggleHighlightedButton(m_vMirrorButton);
 }
 
 void KisPaintopBox::sliderChanged(int n)
diff --git a/krita/ui/kis_paintop_box.h b/krita/ui/kis_paintop_box.h
index b446016..5eb3f01 100644
--- a/krita/ui/kis_paintop_box.h
+++ b/krita/ui/kis_paintop_box.h
@@ -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;
diff --git a/krita/ui/widgets/kis_tool_options_popup.cpp b/krita/ui/widgets/kis_tool_options_popup.cpp
new file mode 100644
index 0000000..d553549
--- /dev/null
+++ b/krita/ui/widgets/kis_tool_options_popup.cpp
@@ -0,0 +1,197 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2015 Boudewijn Rempt <boud at 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);
+    }
+}
+
diff --git a/krita/ui/widgets/kis_tool_options_popup.h b/krita/ui/widgets/kis_tool_options_popup.h
new file mode 100644
index 0000000..6053719
--- /dev/null
+++ b/krita/ui/widgets/kis_tool_options_popup.h
@@ -0,0 +1,53 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2015 Boudewijn Rempt <boud at 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


More information about the kimageshop mailing list