Skip to content

Commit

Permalink
Added composition mode to layer
Browse files Browse the repository at this point in the history
TODO:

* Serialization in XML, JSON and Lua formats
* Decide which modes to support
* Consider what should happen when set on group layers
  • Loading branch information
bjorn committed Jan 12, 2025
1 parent 4c178f6 commit c60fbae
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 6 deletions.
15 changes: 15 additions & 0 deletions src/libtiled/layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "object.h"
#include "tileset.h"

#include <QPainter>
#include <QPixmap>
#include <QRect>
#include <QSet>
Expand Down Expand Up @@ -192,6 +193,9 @@ class TILEDSHARED_EXPORT Layer : public Object
QPointF parallaxFactor() const;
QPointF effectiveParallaxFactor() const;

QPainter::CompositionMode compositionMode() const;
void setCompositionMode(QPainter::CompositionMode compositionMode);

bool canMergeDown() const;

virtual bool isEmpty() const = 0;
Expand Down Expand Up @@ -263,6 +267,7 @@ class TILEDSHARED_EXPORT Layer : public Object
int mY = 0;
QPointF mOffset;
QPointF mParallaxFactor = { 1.0, 1.0 };
QPainter::CompositionMode mCompositionMode = QPainter::CompositionMode_SourceOver;
qreal mOpacity = 1.0;
QColor mTintColor;
bool mVisible = true;
Expand Down Expand Up @@ -307,6 +312,16 @@ inline QPointF Layer::parallaxFactor() const
return mParallaxFactor;
}

inline QPainter::CompositionMode Layer::compositionMode() const
{
return mCompositionMode;
}

inline void Layer::setCompositionMode(QPainter::CompositionMode compositionMode)
{
mCompositionMode = compositionMode;
}


/**
* An iterator for iterating over the layers of a map, in the order in which
Expand Down
3 changes: 3 additions & 0 deletions src/libtiled/mapwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,9 @@ void MapWriterPrivate::writeLayerAttributes(QXmlStreamWriter &w,
w.writeAttribute(QStringLiteral("parallaxx"), QString::number(parallaxFactor.x()));
if (parallaxFactor.y() != 1.0)
w.writeAttribute(QStringLiteral("parallaxy"), QString::number(parallaxFactor.y()));

if (layer.compositionMode() != QPainter::CompositionMode_SourceOver)
w.writeAttribute(QStringLiteral("blend"), QStringLiteral("TODO: Convert composition mode to/from string"));
}

void MapWriterPrivate::writeObjectGroup(QXmlStreamWriter &w,
Expand Down
3 changes: 2 additions & 1 deletion src/tiled/changeevents.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ class LayerChangeEvent : public ChangeEvent
LockedProperty = 1 << 3,
OffsetProperty = 1 << 4,
ParallaxFactorProperty = 1 << 5,
TintColorProperty = 1 << 6,
CompositionModeProperty = 1 << 6,
TintColorProperty = 1 << 7,
PositionProperties = OffsetProperty | ParallaxFactorProperty,
AllProperties = 0xFF
};
Expand Down
22 changes: 22 additions & 0 deletions src/tiled/changelayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,28 @@ void SetLayerParallaxFactor::setValue(Layer *layer, const QPointF &value) const
}


SetLayerCompositionMode::SetLayerCompositionMode(Document *document,
QList<Layer *> layers,
QPainter::CompositionMode compositionMode,
QUndoCommand *parent)
: ChangeValue<Layer, QPainter::CompositionMode>(document, std::move(layers), compositionMode, parent)
{
setText(QCoreApplication::translate("Undo Commands",
"Change Layer Composition Mode"));
}

QPainter::CompositionMode SetLayerCompositionMode::getValue(const Layer *layer) const
{
return layer->compositionMode();
}

void SetLayerCompositionMode::setValue(Layer *layer, const QPainter::CompositionMode &value) const
{
layer->setCompositionMode(value);
emit document()->changed(LayerChangeEvent(layer, LayerChangeEvent::CompositionModeProperty));
}


SetTileLayerSize::SetTileLayerSize(Document *document,
TileLayer *tileLayer,
QSize size,
Expand Down
19 changes: 19 additions & 0 deletions src/tiled/changelayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QPointF>
#include <QSize>
#include <QColor>
#include <QPainter>

namespace Tiled {

Expand Down Expand Up @@ -153,6 +154,24 @@ class SetLayerParallaxFactor : public ChangeValue<Layer, QPointF>
void setValue(Layer *layer, const QPointF &value) const override;
};

/**
* Used for changing the layer parallax factor.
*/
class SetLayerCompositionMode : public ChangeValue<Layer, QPainter::CompositionMode>
{
public:
SetLayerCompositionMode(Document *document,
QList<Layer *> layers,
QPainter::CompositionMode compositionMode,
QUndoCommand *parent = nullptr);

int id() const override { return Cmd_ChangeLayerCompositionMode; }

private:
QPainter::CompositionMode getValue(const Layer *layer) const override;
void setValue(Layer *layer, const QPainter::CompositionMode &value) const override;
};

/**
* Used for changing the tile layer size.
*
Expand Down
1 change: 1 addition & 0 deletions src/tiled/imagelayeritem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ void ImageLayerItem::paint(QPainter *painter,
{
// TODO: Display a border around the layer when selected
MapRenderer *renderer = mMapDocument->renderer();
painter->setCompositionMode(layer()->compositionMode());
renderer->drawImageLayer(painter, imageLayer(), option->exposedRect);
}
10 changes: 6 additions & 4 deletions src/tiled/mapitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,10 @@ void MapItem::layerChanged(const LayerChangeEvent &change)
QGraphicsItem *layerItem = mLayerItems.value(layer);
Q_ASSERT(layerItem);

if (change.properties & LayerChangeEvent::TintColorProperty)
layerTintColorChanged(layer);
if (change.properties & (LayerChangeEvent::TintColorProperty |
LayerChangeEvent::CompositionModeProperty)) {
updateLayerItems(layer);
}

layerItem->setVisible(layer->isVisible());

Expand Down Expand Up @@ -584,7 +586,7 @@ void MapItem::layerChanged(const LayerChangeEvent &change)
updateBoundingRect(); // possible layer offset change
}

void MapItem::layerTintColorChanged(Layer *layer)
void MapItem::updateLayerItems(Layer *layer)
{
switch (layer->layerType()) {
case Layer::TileLayerType:
Expand All @@ -600,7 +602,7 @@ void MapItem::layerTintColorChanged(Layer *layer)
case Layer::GroupLayerType:
// Recurse into group layers since tint color is inherited
for (auto childLayer : static_cast<GroupLayer*>(layer)->layers())
layerTintColorChanged(childLayer);
updateLayerItems(childLayer);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/tiled/mapitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class MapItem : public QGraphicsObject
void layerAboutToBeRemoved(GroupLayer *parentLayer, int index);
void layerRemoved(Layer *layer);
void layerChanged(const LayerChangeEvent &change);
void layerTintColorChanged(Layer *layer);
void updateLayerItems(Layer *layer);

void imageLayerChanged(ImageLayer *imageLayer);

Expand Down
2 changes: 2 additions & 0 deletions src/tiled/mapobjectitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ void MapObjectItem::paint(QPainter *painter,
const QPointF pixelPos = renderer->pixelToScreenCoords(mObject->position());

painter->translate(-pixelPos);
if (ObjectGroup *objectGroup = mObject->objectGroup())
painter->setCompositionMode(objectGroup->compositionMode());
renderer->drawMapObject(painter, mObject, mColors);
painter->translate(pixelPos);

Expand Down
43 changes: 43 additions & 0 deletions src/tiled/propertieswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,38 @@ template<> EnumData enumData<WangSet::Type>()
return { names, {}, icons };
}

template<> EnumData enumData<QPainter::CompositionMode>()
{
const QStringList names {
QStringLiteral("SourceOver"),
QStringLiteral("DestinationOver"),
QStringLiteral("Clear"),
QStringLiteral("Source"),
QStringLiteral("Destination"),
QStringLiteral("SourceIn"),
QStringLiteral("DestinationIn"),
QStringLiteral("SourceOut"),
QStringLiteral("DestinationOut"),
QStringLiteral("SourceAtop"),
QStringLiteral("DestinationAtop"),
QStringLiteral("Xor"),
QStringLiteral("Plus"),
QStringLiteral("Multiply"),
QStringLiteral("Screen"),
QStringLiteral("Overlay"),
QStringLiteral("Darken"),
QStringLiteral("Lighten"),
QStringLiteral("ColorDodge"),
QStringLiteral("ColorBurn"),
QStringLiteral("HardLight"),
QStringLiteral("SoftLight"),
QStringLiteral("Difference"),
QStringLiteral("Exclusion"),
};

return { names };
}


class FlippingProperty : public IntProperty
{
Expand Down Expand Up @@ -1037,6 +1069,15 @@ class LayerProperties : public ObjectProperties
});
mParallaxFactorProperty->setSingleStep(0.1);

mCompositionModeProperty = new EnumProperty<QPainter::CompositionMode>(
tr("Composition Mode"),
[this] { return layer()->compositionMode(); },
[this](QPainter::CompositionMode mode) {
push(new SetLayerCompositionMode(mapDocument(),
mapDocument()->selectedLayers(),
mode));
});

mLayerProperties = new GroupProperty(tr("Layer"));
mLayerProperties->addProperty(mIdProperty);
mLayerProperties->addProperty(mNameProperty);
Expand All @@ -1048,6 +1089,7 @@ class LayerProperties : public ObjectProperties
mLayerProperties->addProperty(mTintColorProperty);
mLayerProperties->addProperty(mOffsetProperty);
mLayerProperties->addProperty(mParallaxFactorProperty);
mLayerProperties->addProperty(mCompositionModeProperty);

addProperty(mLayerProperties);

Expand Down Expand Up @@ -1114,6 +1156,7 @@ class LayerProperties : public ObjectProperties
Property *mTintColorProperty;
Property *mOffsetProperty;
PointFProperty *mParallaxFactorProperty;
BaseEnumProperty *mCompositionModeProperty;
};

class ImageLayerProperties : public LayerProperties
Expand Down
1 change: 1 addition & 0 deletions src/tiled/tilelayeritem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@ void TileLayerItem::paint(QPainter *painter,
{
MapRenderer *renderer = mMapDocument->renderer();
// TODO: Display a border around the layer when selected
painter->setCompositionMode(layer()->compositionMode());
renderer->drawTileLayer(painter, tileLayer(), option->exposedRect);
}
1 change: 1 addition & 0 deletions src/tiled/undocommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum UndoCommands {
Cmd_ChangeClassName,
Cmd_ChangeImageLayerRepeatX,
Cmd_ChangeImageLayerRepeatY,
Cmd_ChangeLayerCompositionMode,
Cmd_ChangeLayerLocked,
Cmd_ChangeLayerName,
Cmd_ChangeLayerOffset,
Expand Down

0 comments on commit c60fbae

Please sign in to comment.