Added blend modes to layers

This commit is contained in:
Yousef Khadadeh 2025-12-25 19:37:41 +03:00
parent c9aba47db1
commit 067abc8553
8 changed files with 130 additions and 6 deletions

View file

@ -3,6 +3,7 @@
#include <cereal/types/string.hpp>
#include "DrawingProgramLayer.hpp"
#include "../../World.hpp"
#include "SerializedBlendMode.hpp"
using namespace NetworkingObjects;
@ -45,7 +46,10 @@ DrawingProgramLayer& DrawingProgramLayerListItem::get_layer() const {
void DrawingProgramLayerListItem::draw(SkCanvas* canvas, const DrawData& drawData) const {
if(displayData->visible) {
canvas->saveLayerAlphaf(nullptr, displayData->alpha);
SkPaint layerPaint;
layerPaint.setAlphaf(displayData->alpha);
layerPaint.setBlendMode(serialized_blend_mode_to_sk_blend_mode(displayData->blendMode));
canvas->saveLayer(nullptr, &layerPaint);
if(folderData)
folderData->draw(canvas, drawData);
else
@ -87,6 +91,17 @@ bool DrawingProgramLayerListItem::get_visible() const {
return displayData->visible;
}
void DrawingProgramLayerListItem::set_blend_mode(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, SerializedBlendMode newBlendMode) const {
if(displayData && displayData->blendMode != newBlendMode) {
displayData->blendMode = newBlendMode;
delayedNetObjMan.send_update_to_all<DisplayData>(displayData, false);
}
}
SerializedBlendMode DrawingProgramLayerListItem::get_blend_mode() const {
return displayData->blendMode;
}
void DrawingProgramLayerListItem::register_class(World& w) {
w.netObjMan.register_class<DrawingProgramLayerListItem, DrawingProgramLayerListItem, DrawingProgramLayerListItem, DrawingProgramLayerListItem>({
.writeConstructorFuncClient = write_constructor_func,

View file

@ -4,6 +4,7 @@
#include <Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp>
#include "DrawingProgramLayerFolder.hpp"
#include "DrawingProgramLayer.hpp"
#include "SerializedBlendMode.hpp"
class DrawingProgramLayerFolder;
class DrawingProgramLayer;
@ -28,6 +29,9 @@ class DrawingProgramLayerListItem {
void set_visible(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, bool newVisible) const;
bool get_visible() const;
void set_blend_mode(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, SerializedBlendMode newBlendMode) const;
SerializedBlendMode get_blend_mode() const;
private:
static void write_constructor_func(const NetworkingObjects::NetObjTemporaryPtr<DrawingProgramLayerListItem>& o, cereal::PortableBinaryOutputArchive& a);
static void read_constructor_func(const NetworkingObjects::NetObjTemporaryPtr<DrawingProgramLayerListItem>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c);
@ -42,8 +46,9 @@ class DrawingProgramLayerListItem {
struct DisplayData {
float alpha = 1.0f;
bool visible = true;
SerializedBlendMode blendMode = SerializedBlendMode::SRC_OVER;
template <typename Archive> void serialize(Archive& a) {
a(alpha, visible);
a(alpha, visible, blendMode);
}
};
NetworkingObjects::NetObjOwnerPtr<NameData> nameData;

View file

@ -3,6 +3,8 @@
#include "../DrawingProgram.hpp"
#include "../../World.hpp"
#include "../../MainProgram.hpp"
#include "Helpers/ConvertVec.hpp"
#include "SerializedBlendMode.hpp"
DrawingProgramLayerManagerGUI::DrawingProgramLayerManagerGUI(DrawingProgramLayerManager& drawLayerMan):
layerMan(drawLayerMan)
@ -14,9 +16,10 @@ void DrawingProgramLayerManagerGUI::refresh_gui_data() {
nameToEdit.clear();
nameForNew.clear();
alphaValToEdit = 0.0f;
blendModeValToEdit = 0;
}
void DrawingProgramLayerManagerGUI::setup_list_gui(const std::string& id) {
void DrawingProgramLayerManagerGUI::setup_list_gui(const std::string& id, bool& hoveringOverDropdown) {
using namespace NetworkingObjects;
auto& world = layerMan.drawP.world;
if(layerMan.layerTreeRoot) {
@ -122,15 +125,18 @@ void DrawingProgramLayerManagerGUI::setup_list_gui(const std::string& id) {
if(tempPtr) {
nameToEdit = tempPtr->get_name();
alphaValToEdit = tempPtr->get_alpha();
blendModeValToEdit = static_cast<size_t>(tempPtr->get_blend_mode());
}
else {
nameToEdit.clear();
alphaValToEdit = 0.0f;
blendModeValToEdit = 0;
}
}
else {
nameToEdit.clear();
alphaValToEdit = 0.0f;
blendModeValToEdit = 0;
}
}
@ -162,6 +168,14 @@ void DrawingProgramLayerManagerGUI::setup_list_gui(const std::string& id) {
tempPtr->set_name(world.delayedUpdateObjectManager, nameToEdit);
gui.slider_scalar_field("input alpha slider", "Alpha", &alphaValToEdit, 0.0f, 1.0f, 2);
tempPtr->set_alpha(world.delayedUpdateObjectManager, alphaValToEdit);
gui.left_to_right_line_layout([&]() {
gui.text_label("Blend Mode");
gui.dropdown_select("input blend mode", &blendModeValToEdit, get_blend_mode_name_list(), 200.0f, [&hoveringOverDropdown]() {
if(Clay_Hovered())
hoveringOverDropdown = true;
});
});
tempPtr->set_blend_mode(world.delayedUpdateObjectManager, static_cast<SerializedBlendMode>(blendModeValToEdit));
}
}

View file

@ -11,7 +11,7 @@ class DrawingProgramLayerManagerGUI {
public:
DrawingProgramLayerManagerGUI(DrawingProgramLayerManager& layerManager);
void refresh_gui_data();
void setup_list_gui(const std::string& id);
void setup_list_gui(const std::string& id, bool& hoveringOverDropdown);
private:
NetworkingObjects::NetObjOrderedListObjectInfoPtr<DrawingProgramLayerListItem> try_to_create_in_proper_position(DrawingProgramLayerListItem* newItem);
NetworkingObjects::NetObjOrderedListObjectInfoPtr<DrawingProgramLayerListItem> create_in_proper_position(DrawingProgramLayerListItem* newItem);
@ -21,6 +21,7 @@ class DrawingProgramLayerManagerGUI {
std::string nameToEdit;
std::string nameForNew;
float alphaValToEdit = 0.0f;
size_t blendModeValToEdit = 0;
DrawingProgramLayerManager& layerMan;
};

View file

@ -0,0 +1,15 @@
#include "SerializedBlendMode.hpp"
SkBlendMode serialized_blend_mode_to_sk_blend_mode(SerializedBlendMode serializedBlendMode) {
int skBlendModeStartVal = static_cast<int>(SkBlendMode::kClear);
return static_cast<SkBlendMode>(skBlendModeStartVal + static_cast<uint8_t>(serializedBlendMode));
}
const std::vector<std::string>& get_blend_mode_name_list() {
static std::vector<std::string> blendModeList;
if(blendModeList.empty()) {
for(uint8_t i = 0; i < static_cast<uint8_t>(SerializedBlendMode::LAST_MODE); i++)
blendModeList.emplace_back(nlohmann::json(static_cast<SerializedBlendMode>(i)));
}
return blendModeList;
}

View file

@ -0,0 +1,72 @@
#pragma once
#include <include/core/SkBlendMode.h>
#include <nlohmann/json.hpp>
enum class SerializedBlendMode : uint8_t {
CLEAR = 0,
SRC,
DST,
SRC_OVER,
DST_OVER,
SRC_IN,
DST_IN,
SRC_OUT,
DST_OUT,
SRC_A_TOP,
DST_A_TOP,
XOR,
PLUS,
MODULATE,
SCREEN,
OVERLAY,
DARKEN,
LIGHTEN,
COLOR_DODGE,
COLOR_BURN,
HARD_LIGHT,
SOFT_LIGHT,
DIFFERENCE,
EXCLUSION,
MULTIPLY,
HUE,
SATURATION,
COLOR,
LUMINOSITY,
LAST_MODE
};
NLOHMANN_JSON_SERIALIZE_ENUM(SerializedBlendMode, {
{SerializedBlendMode::CLEAR, "Clear"},
{SerializedBlendMode::SRC, "Src"},
{SerializedBlendMode::DST, "Dst"},
{SerializedBlendMode::SRC_OVER, "Src Over"},
{SerializedBlendMode::DST_OVER, "Dst Over"},
{SerializedBlendMode::SRC_IN, "Src In"},
{SerializedBlendMode::DST_IN, "Dst In"},
{SerializedBlendMode::SRC_OUT, "Src Out"},
{SerializedBlendMode::DST_OUT, "Dst Out"},
{SerializedBlendMode::SRC_A_TOP, "Src A Top"},
{SerializedBlendMode::DST_A_TOP, "Dst A Top"},
{SerializedBlendMode::XOR, "XOR"},
{SerializedBlendMode::PLUS, "Plus"},
{SerializedBlendMode::MODULATE, "Modulate"},
{SerializedBlendMode::SCREEN, "Screen"},
{SerializedBlendMode::OVERLAY, "Overlay"},
{SerializedBlendMode::DARKEN, "Darken"},
{SerializedBlendMode::LIGHTEN, "Lighten"},
{SerializedBlendMode::COLOR_DODGE, "Color Dodge"},
{SerializedBlendMode::COLOR_BURN, "Color Burn"},
{SerializedBlendMode::HARD_LIGHT, "Hard Light"},
{SerializedBlendMode::SOFT_LIGHT, "Soft Light"},
{SerializedBlendMode::DIFFERENCE, "Difference"},
{SerializedBlendMode::EXCLUSION, "Exclusion"},
{SerializedBlendMode::MULTIPLY, "Multiply"},
{SerializedBlendMode::HUE, "Hue"},
{SerializedBlendMode::SATURATION, "Saturation"},
{SerializedBlendMode::COLOR, "Color"},
{SerializedBlendMode::LUMINOSITY, "Luminosity"}
})
SkBlendMode serialized_blend_mode_to_sk_blend_mode(SerializedBlendMode serializedBlendMode);
const std::vector<std::string>& get_blend_mode_name_list();