Commit 69077091 authored by Silvio Heinrich's avatar Silvio Heinrich

Replaced the old composite op ComboBox with a new one.

* also added a paintOpOption to save the blending mode into a preset.
* cleaning up kis_paintop_box a bit
* created a subfolder for UI forms in krita/plugind/paintops/libpaintop
parent 71b24f06
......@@ -52,7 +52,8 @@
#include <kicon.h>
#include <KoDocumentSectionView.h>
#include "KoColorSpace.h"
#include <KoColorSpace.h>
#include <KoCompositeOp.h>
#include <kis_types.h>
#include <kis_image.h>
......@@ -61,6 +62,7 @@
#include <kis_group_layer.h>
#include <kis_mask.h>
#include <kis_node.h>
#include <kis_composite_ops_model.h>
#include "widgets/kis_cmb_composite.h"
#include "widgets/kis_slider_spin_box.h"
......@@ -143,7 +145,7 @@ KisLayerBox::KisLayerBox()
connect(m_wdgLayerBox->doubleOpacity, SIGNAL(valueChanged(qreal)), SLOT(slotOpacitySliderMoved(qreal)));
connect(&m_delayTimer, SIGNAL(timeout()), SLOT(slotOpacityChanged()));
connect(m_wdgLayerBox->cmbComposite, SIGNAL(activated(const QString&)), SLOT(slotCompositeOpChanged(const QString&)));
connect(m_wdgLayerBox->cmbComposite, SIGNAL(activated(int)), SLOT(slotCompositeOpChanged(int)));
m_newLayerMenu = new KMenu(this);
......@@ -274,16 +276,17 @@ void KisLayerBox::setCurrentNode(KisNodeSP node)
void KisLayerBox::slotSetCompositeOp(const KoCompositeOp* compositeOp)
{
KoID cmpOp = KoCompositeOpRegistry::instance().getKoID(compositeOp->id());
int index = m_wdgLayerBox->cmbComposite->getModel()->getIndex(cmpOp);
m_wdgLayerBox->cmbComposite->blockSignals(true);
m_wdgLayerBox->cmbComposite->setCurrent(compositeOp);
m_wdgLayerBox->cmbComposite->setCurrentIndex(index);
m_wdgLayerBox->cmbComposite->blockSignals(false);
}
void KisLayerBox::slotFillCompositeOps(const KoColorSpace * colorSpace)
void KisLayerBox::slotFillCompositeOps(const KoColorSpace* colorSpace)
{
m_wdgLayerBox->cmbComposite->blockSignals(true);
m_wdgLayerBox->cmbComposite->setCompositeOpList(colorSpace->compositeOps());
m_wdgLayerBox->cmbComposite->blockSignals(false);
m_wdgLayerBox->cmbComposite->getModel()->validateCompositeOps(colorSpace);
}
// range: 0-100
......@@ -434,9 +437,12 @@ void KisLayerBox::slotDuplicateClicked()
m_nodeManager->duplicateActiveNode();
}
void KisLayerBox::slotCompositeOpChanged(const QString& _compositeOp)
void KisLayerBox::slotCompositeOpChanged(int index)
{
m_nodeManager->nodeCompositeOpChanged(m_nodeManager->activeColorSpace()->compositeOp(_compositeOp));
KoID compositeOp;
if(m_wdgLayerBox->cmbComposite->getModel()->getEntry(compositeOp, index))
m_nodeManager->nodeCompositeOpChanged(m_nodeManager->activeColorSpace()->compositeOp(compositeOp.id()));
}
void KisLayerBox::slotOpacityChanged()
......
......@@ -103,7 +103,7 @@ private slots:
void slotNewEffectMask();
void slotNewTransformationMask();
void slotNewSelectionMask();
void slotCompositeOpChanged(const QString&);
void slotCompositeOpChanged(int index);
void slotOpacityChanged();
void slotOpacitySliderMoved(qreal opacity);
......
......@@ -10,48 +10,36 @@
<height>348</height>
</rect>
</property>
<layout class="QGridLayout">
<property name="topMargin">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout">
<item>
<layout class="QHBoxLayout" name="hbox2">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="KisCmbComposite" name="cmbComposite" native="true">
<widget class="KisCompositeOpComboBox" name="cmbComposite"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="hbox3">
<item>
<widget class="KisDoubleSliderSpinBox" name="doubleOpacity" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>10</height>
<width>10</width>
<height>15</height>
</size>
</property>
<property name="toolTip">
<string>Blending mode</string>
</property>
</widget>
</item>
<item>
<widget class="KisDoubleSliderSpinBox" name="doubleOpacity" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
......@@ -59,7 +47,7 @@
</item>
</layout>
</item>
<item row="1" column="0">
<item>
<widget class="KoDocumentSectionView" name="listLayers" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
......@@ -69,8 +57,8 @@
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout">
<item>
<layout class="QHBoxLayout" name="hbox1">
<item>
<widget class="QToolButton" name="bnAdd">
<property name="sizePolicy">
......@@ -259,8 +247,8 @@
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>KisCmbComposite</class>
<extends>QWidget</extends>
<class>KisCompositeOpComboBox</class>
<extends>QComboBox</extends>
<header>widgets/kis_cmb_composite.h</header>
</customwidget>
<customwidget>
......
......@@ -55,21 +55,22 @@ set(kritalibpaintop_LIB_SRCS
)
kde4_add_ui_files(kritalibpaintop_LIB_SRCS
wdgautobrush.ui
wdgBrushSizeOptions.ui
wdgcurveoption.ui
wdgcustombrush.ui
wdgtextbrush.ui
wdgincremental.ui
wdgmultisensorsselector.ui
wdgairbrush.ui
wdgfilteroption.ui
wdgcoloroptions.ui
wdgbrushchooser.ui
forms/wdgautobrush.ui
forms/wdgBrushSizeOptions.ui
forms/wdgcurveoption.ui
forms/wdgcustombrush.ui
forms/wdgtextbrush.ui
forms/wdgincremental.ui
forms/wdgmultisensorsselector.ui
forms/wdgairbrush.ui
forms/wdgfilteroption.ui
forms/wdgcoloroptions.ui
forms/wdgbrushchooser.ui
forms/wdgCompositeOpOption.ui
forms/SensorSelector.ui
sensors/SensorDistanceConfiguration.ui
sensors/SensorTimeConfiguration.ui
sensors/SensorFadeConfiguration.ui
SensorSelector.ui
)
kde4_add_library(kritalibpaintop SHARED ${kritalibpaintop_LIB_SRCS} )
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>wdgCompositeOpOption</class>
<widget class="QWidget" name="wdgCompositeOpOption">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>10</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="bnEraser">
<property name="text">
<string>Eraser</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lbChoosenMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="KisCompositeOpListWidget" name="list"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KisCompositeOpListWidget</class>
<extends>QListView</extends>
<header location="global">kis_cmb_composite.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
......@@ -16,45 +16,92 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_compositeop_option.h"
#include <klocale.h>
#include <kis_categorized_list_view.h>
#include <kicon.h>
#include <kis_cmb_composite.h>
#include <KoCompositeOp.h>
#include <kis_types.h>
#include <KoID.h>
#include <ui_wdgCompositeOpOption.h>
#include <kis_composite_ops_model.h>
KisCompositeOpOption::KisCompositeOpOption(bool creatConfigWidget):
KisPaintOpOption(i18n("Blending Mode"), KisPaintOpOption::brushCategory(), true)
KisPaintOpOption(i18n("Blending Mode"), KisPaintOpOption::brushCategory(), true),
m_createConfigWidget(creatConfigWidget)
{
m_checkable = false;
m_checkable = false;
m_prevCompositeOpID = KoCompositeOpRegistry::instance().getDefaultCompositeOp().id();
m_currCompositeOpID = m_prevCompositeOpID;
if(creatConfigWidget) {
KisCategorizedListModel<QString>* model = new KisCategorizedListModel<QString>();
KisCategorizedListView* view = new KisCategorizedListView();
QWidget* widget = new QWidget();
Ui_wdgCompositeOpOption ui;
ui.setupUi(widget);
ui.bnEraser->setIcon(KIcon("draw-eraser"));
const KoIDList& categories = KoCompositeOpRegistry::instance().getCategories();
m_label = ui.lbChoosenMode;
m_list = ui.list;
m_bnEraser = ui.bnEraser;
for(KoIDList::const_iterator cat=categories.begin(); cat!=categories.end(); ++cat) {
const KoIDList& modes = KoCompositeOpRegistry::instance().getCompositeOps(cat->id());
for(KoIDList::const_iterator mod=modes.begin(); mod!=modes.end(); ++mod)
model->addItem(cat->name(), mod->name());
}
setConfigurationPage(widget);
view->setModel(model);
setConfigurationPage(view);
connect(ui.list , SIGNAL(activated(const QModelIndex&)), this, SLOT(slotCompositeOpChanged(const QModelIndex&)));
connect(ui.bnEraser, SIGNAL(toggled(bool)) , this, SLOT(slotEraserToggled(bool)));
}
}
KisCompositeOpOption::~KisCompositeOpOption()
{
}
void KisCompositeOpOption::writeOptionSetting(KisPropertiesConfiguration* setting) const
{
// setting->setProperty(AIRBRUSH_ENABLED, isChecked());
// setting->setProperty(AIRBRUSH_RATE, m_optionWidget->sliderRate->value());
setting->setProperty("CompositeOp", m_currCompositeOpID);
}
void KisCompositeOpOption::readOptionSetting(const KisPropertiesConfiguration* setting)
{
// setChecked(setting->getBool(AIRBRUSH_ENABLED));
// m_optionWidget->sliderRate->setValue(setting->getInt(AIRBRUSH_RATE,100));
QString ompositeOpID = setting->getString("CompositeOp", KoCompositeOpRegistry::instance().getDefaultCompositeOp().id());
KoID compositeOp = KoCompositeOpRegistry::instance().getKoID(ompositeOpID);
changeCompositeOp(compositeOp);
}
void KisCompositeOpOption::changeCompositeOp(const KoID& compositeOp)
{
if(compositeOp.id() == m_currCompositeOpID)
return;
m_prevCompositeOpID = m_currCompositeOpID;
m_currCompositeOpID = compositeOp.id();
if(m_createConfigWidget) {
m_label->setText(compositeOp.name());
m_list->setDisabled(m_currCompositeOpID == "erase");
m_bnEraser->blockSignals(true);
m_bnEraser->setChecked(m_currCompositeOpID == "erase");
m_bnEraser->blockSignals(false);
}
emit sigSettingChanged();
}
void KisCompositeOpOption::slotCompositeOpChanged(const QModelIndex& index)
{
KoID compositeOp;
if(m_list->getModel()->getEntry(compositeOp, index.row()))
changeCompositeOp(compositeOp);
}
void KisCompositeOpOption::slotEraserToggled(bool toggled)
{
if(toggled)
changeCompositeOp(KoCompositeOpRegistry::instance().getKoID("erase"));
else
changeCompositeOp(KoCompositeOpRegistry::instance().getKoID(m_prevCompositeOpID));
}
......@@ -20,26 +20,42 @@
#include <kis_paintop_option.h>
#include <krita_export.h>
#include <QString>
// const QString AIRBRUSH_ENABLED = "AirbrushOption/isAirbrushing";
// const QString AIRBRUSH_RATE = "AirbrushOption/rate";
class KisAirbrushWidget;
class QLabel;
class QModelIndex;
class QPushButton;
class KisCompositeOpListWidget;
class KoID;
/**
* Allows the user to activate airbrushing of the brush mask (brush is painted at the same position over and over)
* Rate is set in miliseconds.
*/
class PAINTOP_EXPORT KisCompositeOpOption: public KisPaintOpOption
{
Q_OBJECT
public:
KisCompositeOpOption(bool creatConfigWidget=false);
KisCompositeOpOption(bool creatConfigWidget=false);
~KisCompositeOpOption();
virtual void writeOptionSetting(KisPropertiesConfiguration* setting) const;
virtual void readOptionSetting(const KisPropertiesConfiguration* setting);
private slots:
void slotCompositeOpChanged(const QModelIndex& index);
void slotEraserToggled(bool toggled);
private:
void changeCompositeOp(const KoID& compositeOp);
private:
KisAirbrushWidget * m_optionWidget;
QLabel* m_label;
QPushButton* m_bnEraser;
KisCompositeOpListWidget* m_list;
QString m_prevCompositeOpID;
QString m_currCompositeOpID;
bool m_createConfigWidget;
};
......
......@@ -160,7 +160,7 @@ set(kritaui_LIB_SRCS
widgets/kis_scratch_pad.cpp
widgets/kis_tree_view_popup.cc
widgets/kis_slider_spin_box.cpp
widgets/kis_categorized_list_view.cpp
widgets/kis_categorized_list_model.cpp
widgets/kis_wdg_generator.cpp
widgets/kis_workspace_chooser.cpp
widgets/squeezedcombobox.cpp
......
......@@ -36,6 +36,7 @@
#include <KoColorSpaceRegistry.h>
#include <KoChannelInfo.h>
#include <KoColorSpace.h>
#include <KoCompositeOp.h>
#include <kis_debug.h>
#include <kis_global.h>
......@@ -46,6 +47,7 @@
#include "widgets/kis_cmb_idlist.h"
#include "KoColorProfile.h"
#include "widgets/kis_channelflags_widget.h"
#include <kis_composite_ops_model.h>
KisDlgLayerProperties::KisDlgLayerProperties(const QString& deviceName,
qint32 opacity,
......@@ -80,8 +82,8 @@ KisDlgLayerProperties::KisDlgLayerProperties(const QString& deviceName,
m_page->intOpacity->setRange(0, 100);
m_page->intOpacity->setValue(opacity);
m_page->cmbComposite->setCompositeOpList(colorSpace->compositeOps());
m_page->cmbComposite->setCurrent(compositeOp);
m_page->cmbComposite->getModel()->validateCompositeOps(colorSpace);
m_page->cmbComposite->setCurrentIndex(m_page->cmbComposite->getModel()->getIndex(KoID(compositeOp->id())));
slotNameChanged(m_page->editName->text());
......@@ -123,9 +125,14 @@ int KisDlgLayerProperties::getOpacity() const
return opacity;
}
const QString& KisDlgLayerProperties::getCompositeOp() const
QString KisDlgLayerProperties::getCompositeOp() const
{
return m_page->cmbComposite->currentItem();
KoID compositeOp;
if(m_page->cmbComposite->getModel()->getEntry(compositeOp, m_page->cmbComposite->currentIndex()))
return compositeOp.id();
return KoCompositeOpRegistry::instance().getDefaultCompositeOp().id();
}
QBitArray KisDlgLayerProperties::getChannelFlags() const
......
......@@ -58,7 +58,7 @@ public:
QString getName() const;
qint32 getOpacity() const;
const QString& getCompositeOp() const;
QString getCompositeOp() const;
/**
* @return a bit array of channel flags in the order in which the
......
......@@ -46,9 +46,6 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KisCmbComposite" name="cmbComposite" native="true"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblColorSpaces">
<property name="text">
......@@ -83,6 +80,9 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KisCompositeOpComboBox" name="cmbComposite"/>
</item>
</layout>
</item>
<item row="0" column="1">
......@@ -121,16 +121,16 @@
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>KisCmbComposite</class>
<extends>QWidget</extends>
<header>widgets/kis_cmb_composite.h</header>
</customwidget>
<customwidget>
<class>KisSliderSpinBox</class>
<extends>QWidget</extends>
<header>kis_slider_spin_box.h</header>
</customwidget>
<customwidget>
<class>KisCompositeOpComboBox</class>
<extends>QComboBox</extends>
<header>widgets/kis_cmb_composite.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
......
......@@ -25,6 +25,7 @@
/**
* This delegate draw categories using information from a \ref KCategorizedSortFilterProxyModel .
*/
class KRITAUI_EXPORT KisCategorizedItemDelegate : public QAbstractItemDelegate
{
public:
......
......@@ -22,114 +22,18 @@
#include <kcategorizedsortfilterproxymodel.h>
#include "kis_debug.h"
static QStringList opsInOrder;
KisCompositeOpsModel::KisCompositeOpsModel(const QList<KoCompositeOp*>& list, const QList<KoCompositeOp*>& whitelist)
{
foreach(KoCompositeOp* op, list) {
if (op->userVisible()) {
m_list.push_back(CompositeOpInfo(op->id(), op->description(), op->category()));
}
}
foreach(KoCompositeOp* op, whitelist) {
if (!m_list.contains(CompositeOpInfo(op->id(), op->description(), op->category()))) {
m_list.push_back(CompositeOpInfo(op->id(), op->description(), op->category()));
}
}
if (opsInOrder.isEmpty()) {
opsInOrder <<
COMPOSITE_OVER <<
COMPOSITE_ERASE <<
COMPOSITE_COPY <<
COMPOSITE_ALPHA_DARKEN <<
COMPOSITE_IN <<
COMPOSITE_OUT <<
COMPOSITE_XOR <<
COMPOSITE_PLUS <<
COMPOSITE_MINUS <<
COMPOSITE_ADD <<
COMPOSITE_SUBTRACT <<
COMPOSITE_DIFF <<
COMPOSITE_MULT <<
COMPOSITE_DIVIDE <<
COMPOSITE_DODGE <<
COMPOSITE_BURN <<
COMPOSITE_BUMPMAP <<
COMPOSITE_CLEAR <<
COMPOSITE_DISSOLVE <<
COMPOSITE_DISPLACE <<
COMPOSITE_NO <<
COMPOSITE_DARKEN <<
COMPOSITE_LIGHTEN <<
COMPOSITE_HUE <<
COMPOSITE_SATURATION <<
COMPOSITE_VALUE <<
COMPOSITE_COLOR <<
COMPOSITE_COLORIZE <<
COMPOSITE_LUMINIZE <<
COMPOSITE_SCREEN <<
COMPOSITE_OVERLAY <<
COMPOSITE_UNDEF <<
COMPOSITE_COPY_RED <<
COMPOSITE_COPY_GREEN <<
COMPOSITE_COPY_BLUE;
}
}
KisCompositeOpsModel::~KisCompositeOpsModel()
{
}
int KisCompositeOpsModel::rowCount(const QModelIndex & /*parent*/) const
{
return m_list.count();
}
QVariant KisCompositeOpsModel::data(const QModelIndex & index, int role) const
void KisCompositeOpListModel::validateCompositeOps(const KoColorSpace* colorSpace)
{
if (index.isValid()) {
switch (role) {
case Qt::DisplayRole: {
return m_list[index.row()].description;
}
case CompositeOpSortRole: {
int idx = opsInOrder.indexOf(m_list[index.row()].id);
if (idx == -1) return opsInOrder.count();
return idx;
}
case KCategorizedSortFilterProxyModel::CategoryDisplayRole:
case KCategorizedSortFilterProxyModel::CategorySortRole:
return m_list[index.row()].category;
typedef QList<Category>::iterator Itr;
emit layoutAboutToBeChanged();
for(Iterator cat=m_categories.begin(); cat!=m_categories.end(); ++cat) {
for(int i=0; i<cat->entries.size(); ++i) {
bool enable = KoCompositeOpRegistry::instance().colorSpaceHasCompositeOp(colorSpace, cat->entries[i]);
cat->disabled.setBit(i, !enable);
}
}
return QVariant();
}
const QString& KisCompositeOpsModel::itemAt(const QModelIndex & index) const
{
if (!index.isValid()) return COMPOSITE_OVER;
return m_list[index.row()].id;
}
QModelIndex KisCompositeOpsModel::indexOf(const KoCompositeOp* op) const
{
if (!op) return QModelIndex();
return indexOf(op->id());
}
QModelIndex KisCompositeOpsModel::indexOf(const QString& id) const
{
int index = 0;
foreach(const CompositeOpInfo& op2, m_list) {
if (id == op2.id)
break;
++index;
}
if (index < m_list.count()) {
return createIndex(index, 0);
} else {
return QModelIndex();
}