Commit 0e92af29 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Implement the style collection/style selector for the layer style dialog

A style collection is a resource that contains styles, the styles them-
selves are not resources. If you select a style from a collection, its
settings should be copied to the current style applied to the layer.

Layers don't share predefined styles, at least not in Photoshop.
parent cd3cff72
......@@ -29,6 +29,9 @@ struct KisPSDLayerStyle::Private
, effects_count(0)
, visible(false)
{}
QString name;
quint16 version;
quint8 effects_count; // Effects count: may be 6 (for the 6 effects in Photoshop 5 and 6) or 7 (for Photoshop 7.0)
bool visible; // common state info, visible: always true
......@@ -78,18 +81,21 @@ void KisPSDLayerStyle::operator=(const KisPSDLayerStyle &rhs)
// XXX copy all the contents of KisPSDLayerStyle::Private
}
bool KisPSDLayerStyle::writeASL(QIODevice *io) const
QString KisPSDLayerStyle::name() const
{
return false;
return d->name;
}
bool KisPSDLayerStyle::readASL(QIODevice *io)
bool KisPSDLayerStyle::writeASL(QIODevice *io, QVector<KisPSDLayerStyle *> )
{
quint32 tag;
return false;
}
QVector<KisPSDLayerStyle *> KisPSDLayerStyle::readASL(QIODevice *io)
{
return QVector<KisPSDLayerStyle*>();
}
bool KisPSDLayerStyle::write(QIODevice *io) const
{
return false;
......
......@@ -20,12 +20,16 @@
class QIODevice;
#include <QVector>
#include <krita_export.h>
/**
* @brief The KisPSDLayerStyle class implements loading, saving and applying
* the PSD layer effects.
*
* See http://www.tonton-pixel.com/Photoshop%20Additional%20File%20Formats/styles-file-format.html
*
*/
class KRITAIMAGE_EXPORT KisPSDLayerStyle
{
......@@ -36,14 +40,24 @@ public:
KisPSDLayerStyle(const KisPSDLayerStyle& rhs);
void operator=(const KisPSDLayerStyle& rhs);
QString name() const;
/// Save the ASL style format. See http://www.tonton-pixel.com/Photoshop%20Additional%20File%20Formats/styles-file-format.html
bool writeASL(QIODevice *io) const;
/**
* Save given styles to the ASL style format. All patterns references in the
* contained styles will also be saved.
*/
static bool writeASL(QIODevice *io, QVector<KisPSDLayerStyle *> styles);
/// Load the ASL style format. See http://www.tonton-pixel.com/Photoshop%20Additional%20File%20Formats/styles-file-format.html
bool readASL(QIODevice *io);
/**
* Load all style objects in the ASL style format. All patterns contained in the
* asl file will be added to the global pattern server.
*/
static QVector<KisPSDLayerStyle *> readASL(QIODevice *io);
/// Save this style object
bool write(QIODevice *io) const;
/// Load this style object
bool read(QIODevice *io);
private:
......
......@@ -36,13 +36,13 @@ void KisPSDLayerStyleTest::testRoundTrip()
f.close();
Q_ASSERT(ba.size() > 0);
QBuffer in(&ba);
res = layerStyle.readASL(&in);
Q_ASSERT(res);
QVector<KisPSDLayerStyle *> styles;
styles = layerStyle.readASL(&in);
QByteArray ba2;
QBuffer out(&ba2);
res = layerStyle.readASL(&out);
res = layerStyle.writeASL(&out, styles);
Q_ASSERT(res);
Q_ASSERT(ba2 == ba);
}
QTEST_KDEMAIN(KisPSDLayerStyleTest, GUI)
......@@ -273,7 +273,6 @@ set(kritaui_LIB_SRCS
processing/fill_processing_visitor.cpp
kis_mirror_axis.cpp
kis_psd_layer_style_resource.cpp
)
if(WIN32)
......@@ -346,7 +345,6 @@ kde4_add_ui_files(kritaui_LIB_SRCS
input/config/kis_wheel_input_editor.ui
input/config/kis_key_input_editor.ui
layerstyles/wdgBevelAndEmboss.ui
layerstyles/wdgblendingoptions.ui
layerstyles/WdgColorOverlay.ui
......
......@@ -20,9 +20,15 @@
#include <QWidget>
#include <QStackedWidget>
#include <QTreeWidget>
#include <QListWidget>
#include <QListWidgetItem>
#include "kis_config.h"
#include "kis_resource_server_provider.h"
#include "kis_psd_layer_style_resource.h"
#include "kis_psd_layer_style.h"
KisDlgLayerStyle::KisDlgLayerStyle(KisPSDLayerStyle *layerStyle, QWidget *parent)
: KDialog(parent)
, m_layerStyle(layerStyle)
......@@ -36,7 +42,9 @@ KisDlgLayerStyle::KisDlgLayerStyle(KisPSDLayerStyle *layerStyle, QWidget *parent
setMainWidget(page);
m_stylesSelector = new StylesSelector(this);
connect(m_stylesSelector, SIGNAL(styleSelected(KisPSDLayerStyle*)), SLOT(setStyle(KisPSDLayerStyle*)));
wdgLayerStyles.stylesStack->addWidget(m_stylesSelector);
m_blendingOptions = new BlendingOptions(this);
wdgLayerStyles.stylesStack->addWidget(m_blendingOptions);
m_dropShadow = new DropShadow(this);
......@@ -72,6 +80,8 @@ KisDlgLayerStyle::KisDlgLayerStyle(KisPSDLayerStyle *layerStyle, QWidget *parent
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
}
void KisDlgLayerStyle::changePage(QListWidgetItem *current, QListWidgetItem *previous)
......@@ -82,7 +92,10 @@ void KisDlgLayerStyle::changePage(QListWidgetItem *current, QListWidgetItem *pre
wdgLayerStyles.stylesStack->setCurrentIndex(wdgLayerStyles.lstStyleSelector->row(current));
}
void KisDlgLayerStyle::setStyle(KisPSDLayerStyle *style)
{
}
BevelAndEmboss::BevelAndEmboss(QWidget *parent)
: QWidget(parent)
......@@ -160,13 +173,48 @@ Stroke::Stroke(QWidget *parent)
ui.setupUi(this);
}
StylesSelector::StylesSelector(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
connect(ui.cmbStyleCollections, SIGNAL(activated(QString)), this, SLOT(loadStyles(QString)));
connect(ui.listStyles, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(selectStyle(QListWidgetItem*,QListWidgetItem*)));
foreach(KoResource *res, KisResourceServerProvider::instance()->layerStyleCollectionServer()->resources()) {
ui.cmbStyleCollections->addItem(res->name());
}
}
class StyleItem : public QListWidgetItem {
public:
StyleItem(KisPSDLayerStyle *style, const QString &name)
: QListWidgetItem(name)
, m_style(style)
{
}
KisPSDLayerStyle *m_style;
};
void StylesSelector::loadStyles(const QString &name)
{
ui.listStyles->clear();
KoResource *res = KisResourceServerProvider::instance()->layerStyleCollectionServer()->resourceByName(name);
KisPSDLayerStyleCollectionResource *collection = dynamic_cast<KisPSDLayerStyleCollectionResource*>(res);
if (collection) {
foreach(KisPSDLayerStyle *style, collection->layerStyles()) {
// XXX: also use the preview image, when we have one
ui.listStyles->addItem(new StyleItem(style, style->name()));
}
}
}
void StylesSelector::selectStyle(QListWidgetItem */*previous*/, QListWidgetItem* current)
{
StyleItem *item = dynamic_cast<StyleItem*>(current);
if (item) {
emit styleSelected(item->m_style);
}
}
Texture::Texture(QWidget *parent)
: QWidget(parent)
......
......@@ -127,8 +127,14 @@ private:
};
class StylesSelector : public QWidget {
Q_OBJECT
public:
StylesSelector(QWidget *parent);
private slots:
void loadStyles(const QString &name);
void selectStyle(QListWidgetItem *previous, QListWidgetItem* current);
signals:
void styleSelected(KisPSDLayerStyle *style);
private:
Ui::WdgStylesSelector ui;
};
......@@ -150,7 +156,7 @@ signals:
public slots:
void changePage(QListWidgetItem *, QListWidgetItem*);
void setStyle(KisPSDLayerStyle *style);
private:
KisPSDLayerStyle *m_layerStyle;
......
......@@ -28,19 +28,19 @@
#include "kis_psd_layer_style.h"
KisPSDLayerStyleResource::KisPSDLayerStyleResource(const QString &filename)
KisPSDLayerStyleCollectionResource::KisPSDLayerStyleCollectionResource(const QString &filename)
: KoResource(filename)
, m_layerStyle(0)
{
}
KisPSDLayerStyleResource::~KisPSDLayerStyleResource()
KisPSDLayerStyleCollectionResource::~KisPSDLayerStyleCollectionResource()
{
delete m_layerStyle;
qDeleteAll(m_layerStyles);
m_layerStyles.clear();
}
bool KisPSDLayerStyleResource::load()
bool KisPSDLayerStyleCollectionResource::load()
{
QFile file(filename());
if (file.size() == 0) return false;
......@@ -54,18 +54,15 @@ bool KisPSDLayerStyleResource::load()
file.close();
return result;
}
bool KisPSDLayerStyleResource::loadFromDevice(QIODevice *dev)
bool KisPSDLayerStyleCollectionResource::loadFromDevice(QIODevice *dev)
{
if (!m_layerStyle) {
m_layerStyle = new KisPSDLayerStyle();
}
return m_layerStyle->readASL(dev);
m_layerStyles = KisPSDLayerStyle::readASL(dev);
return true;
}
bool KisPSDLayerStyleResource::save()
bool KisPSDLayerStyleCollectionResource::save()
{
QFile file(filename());
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
......@@ -74,19 +71,24 @@ bool KisPSDLayerStyleResource::save()
return res;
}
bool KisPSDLayerStyleResource::saveToDevice(QIODevice *dev) const
bool KisPSDLayerStyleCollectionResource::saveToDevice(QIODevice *dev) const
{
return m_layerStyle->writeASL(dev);
return KisPSDLayerStyle::writeASL(dev, m_layerStyles);
}
QString KisPSDLayerStyleResource::defaultFileExtension() const
QString KisPSDLayerStyleCollectionResource::defaultFileExtension() const
{
return QString(".asl");
}
QByteArray KisPSDLayerStyleResource::generateMD5() const
QVector<KisPSDLayerStyle *> KisPSDLayerStyleCollectionResource::layerStyles() const
{
return m_layerStyles;
}
QByteArray KisPSDLayerStyleCollectionResource::generateMD5() const
{
if (m_layerStyle) {
if (m_layerStyles.size() > 0) {
QByteArray ba;
QBuffer buf(&ba);
saveToDevice(&buf);
......
......@@ -19,6 +19,7 @@
#define KIS_PSD_LAYER_STYLE_RESOURCE_H
#include <KoResource.h>
#include <QVector>
#include <krita_export.h>
......@@ -27,11 +28,11 @@ class KisPSDLayerStyle;
/**
* @brief The KisPSDLayerStyleResource class represents and ASL file type resource.
*/
class KRITAUI_EXPORT KisPSDLayerStyleResource : public KoResource
class KRITAUI_EXPORT KisPSDLayerStyleCollectionResource : public KoResource
{
public:
explicit KisPSDLayerStyleResource(const QString &filename);
virtual ~KisPSDLayerStyleResource();
explicit KisPSDLayerStyleCollectionResource(const QString &filename);
virtual ~KisPSDLayerStyleCollectionResource();
virtual bool load();
virtual bool loadFromDevice(QIODevice *dev);
......@@ -41,13 +42,15 @@ public:
virtual QString defaultFileExtension() const;
QVector<KisPSDLayerStyle *> layerStyles() const;
protected:
virtual QByteArray generateMD5() const;
private:
KisPSDLayerStyle *m_layerStyle;
QVector<KisPSDLayerStyle*> m_layerStyles;
};
......
......@@ -49,7 +49,6 @@ typedef KoResourceServerAdapter<KisPaintOpPreset, SharedPointerStroragePolicy<Ki
KisResourceServerProvider::KisResourceServerProvider()
{
KisBrushServer *brushServer = KisBrushServer::instance();
KGlobal::mainComponent().dirs()->addResourceType("kis_paintoppresets", "data", "krita/paintoppresets/");
......@@ -57,7 +56,7 @@ KisResourceServerProvider::KisResourceServerProvider()
KGlobal::mainComponent().dirs()->addResourceType("kis_workspaces", "data", "krita/workspaces/");
KGlobal::mainComponent().dirs()->addResourceType("psd_layer_styles", "data", "krita/asl");
KGlobal::mainComponent().dirs()->addResourceType("psd_layer_style_collections", "data", "krita/asl");
m_paintOpPresetServer = new KisPaintOpPresetResourceServer("kis_paintoppresets", "*.kpp");
if (!QFileInfo(m_paintOpPresetServer->saveLocation()).exists()) {
......@@ -79,16 +78,18 @@ KisResourceServerProvider::KisResourceServerProvider()
m_workspaceThread->barrier();
}
m_layerStyleServer = new KoResourceServer<KisPSDLayerStyleResource>("psd_layer_styles", "*.asl");
if (!QFileInfo(m_layerStyleServer->saveLocation()).exists()) {
QDir().mkpath(m_layerStyleServer->saveLocation());
m_layerStyleCollectionServer = new KoResourceServer<KisPSDLayerStyleCollectionResource>("psd_layer_style_collections", "*.asl");
if (!QFileInfo(m_layerStyleCollectionServer->saveLocation()).exists()) {
QDir().mkpath(m_layerStyleCollectionServer->saveLocation());
}
m_layerStyleThread = new KoResourceLoaderThread(m_layerStyleServer);
m_layerStyleThread->start();
m_layerStyleCollectionThread = new KoResourceLoaderThread(m_layerStyleCollectionServer);
m_layerStyleCollectionThread->start();
if (!qApp->applicationName().toLower().contains("krita")) {
m_layerStyleThread->barrier();
m_layerStyleCollectionThread->barrier();
}
connect(this, SIGNAL(notifyBrushBlacklistCleanup()),
brushServer, SLOT(slotRemoveBlacklistedResources()));
......@@ -98,11 +99,11 @@ KisResourceServerProvider::~KisResourceServerProvider()
{
delete m_paintOpPresetThread;
delete m_workspaceThread;
delete m_layerStyleThread;
delete m_layerStyleCollectionThread;
delete m_paintOpPresetServer;
delete m_workspaceServer;
delete m_layerStyleServer;
delete m_layerStyleCollectionServer;
}
KisResourceServerProvider* KisResourceServerProvider::instance()
......@@ -124,10 +125,10 @@ KoResourceServer< KisWorkspaceResource >* KisResourceServerProvider::workspaceSe
return m_workspaceServer;
}
KoResourceServer<KisPSDLayerStyleResource> *KisResourceServerProvider::layerStyleServer()
KoResourceServer<KisPSDLayerStyleCollectionResource> *KisResourceServerProvider::layerStyleCollectionServer()
{
m_layerStyleThread->barrier();
return m_layerStyleServer;
m_layerStyleCollectionThread->barrier();
return m_layerStyleCollectionServer;
}
void KisResourceServerProvider::brushBlacklistCleanup()
......
......@@ -27,7 +27,6 @@
#include <QStringList>
#include <QList>
#include <KoResource.h>
#include <KoResourceServer.h>
#include <KoResourceServerProvider.h>
......@@ -41,7 +40,7 @@ class KoResource;
class KoResourceLoaderThread;
class KisPaintOpPreset;
class KisWorkspaceResource;
class KisPSDLayerStyleResource;
class KisPSDLayerStyleCollectionResource;
typedef KoResourceServer<KisPaintOpPreset, SharedPointerStroragePolicy<KisPaintOpPresetSP> > KisPaintOpPresetResourceServer;
typedef KoResourceServerAdapter<KisPaintOpPreset, SharedPointerStroragePolicy<KisPaintOpPresetSP> > KisPaintOpPresetResourceServerAdapter;
......@@ -57,9 +56,10 @@ public:
KisPaintOpPresetResourceServer* paintOpPresetServer();
KoResourceServer<KisWorkspaceResource>* workspaceServer();
KoResourceServer<KisPSDLayerStyleResource>* layerStyleServer();
KoResourceServer<KisPSDLayerStyleCollectionResource>* layerStyleCollectionServer();
void brushBlacklistCleanup();
signals:
void notifyBrushBlacklistCleanup();
......@@ -71,13 +71,14 @@ private:
KisPaintOpPresetResourceServer* m_paintOpPresetServer;
KoResourceServer<KisWorkspaceResource>* m_workspaceServer;
KoResourceServer<KisPSDLayerStyleResource>* m_layerStyleServer;
KoResourceServer<KisPSDLayerStyleCollectionResource>* m_layerStyleCollectionServer;
private:
KoResourceLoaderThread *m_paintOpPresetThread;
KoResourceLoaderThread *m_workspaceThread;
KoResourceLoaderThread *m_layerStyleThread;
KoResourceLoaderThread *m_layerStyleCollectionThread;
};
#endif // KIS_RESOURCESERVERPROVIDER_H_
......@@ -20,9 +20,12 @@
<string>Styles</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<item row="1" column="0">
<widget class="QListWidget" name="listStyles"/>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="cmbStyleCollections"/>
</item>
</layout>
</widget>
</item>
......
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