Skip to content

Commit

Permalink
Layer improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
JannisX11 committed Nov 5, 2023
1 parent 3882562 commit 49e251c
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 124 deletions.
1 change: 0 additions & 1 deletion css/general.css
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,6 @@
white-space: pre-line;
cursor: default;
pointer-events: none;
border-radius: 6px;
}
.uv_message_box {
position: absolute;
Expand Down
14 changes: 14 additions & 0 deletions css/panels.css
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,10 @@
.texture_layer.selected {
background-color: var(--color-selected);
}
.texture_layer.in_limbo {
border: 2px dashed var(--color-accent);
font-style: italic;
}
.texture_layer .layer_icon_wrapper {
height: 40px;
width: 40px;
Expand Down Expand Up @@ -2441,6 +2445,16 @@ span.controller_state_section_info {
color: var(--color-close);
float: right;
}
.uv_layer_limbo_options {
position: absolute;
bottom: 52px;
left: 0;
right: 0;
margin: auto;
background-color: var(--color-ui);
padding: 0 4px;
width: fit-content;
}

/*Chat*/
#panel_chat {
Expand Down
10 changes: 10 additions & 0 deletions js/interface/shared_actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ const SharedActions = {
}
return false;
},
find(action_id, event, context) {
let list = this.actions[action_id];
if (!list) return;
for (let handler of list) {
if (Condition(handler.condition, context)) {
return handler;
}
}
return null;
},
actions: {}
};

Expand Down
93 changes: 89 additions & 4 deletions js/texturing/layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class TextureLayer {
this.uuid = (uuid && isUUID(uuid)) ? uuid : guid();
this.texture = texture;
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
this.ctx = this.canvas.getContext('2d', {willReadFrequently: true});
this.in_limbo = false;

this.img = new Image();
Expand All @@ -23,7 +23,7 @@ class TextureLayer {
return this.canvas.width;
}
get height() {
return this.canvas.width;
return this.canvas.height;
}
get size() {
return [this.canvas.width, this.canvas.height];
Expand Down Expand Up @@ -90,18 +90,89 @@ class TextureLayer {
return copy;
}
setLimbo() {
this.texture.layers.forEach(layer => layer.in_limbo = false);
this.in_limbo = true;
}
resolveLimbo(keep_separate) {
if (keep_separate) {
TextureLayer.selected.in_limbo = false;
} else {
TextureLayer.selected.mergeDown(true);
}
Texture.selected.selection.clear();
UVEditor.updateSelectionOutline();
}
setSize(width, height) {
this.canvas.width = width;
this.canvas.height = height;
}
toggleVisibility() {
Undo.initEdit({textures: [this.texture]});
Undo.initEdit({layers: [this]});
this.visible = !this.visible;
this.texture.updateLayerChanges(true);
Undo.finishEdit('Toggle layer visibility');
}
mergeDown(undo = true) {
let down_layer = this.texture.layers[this.texture.layers.indexOf(this) - 1];
if (!down_layer) {
this.in_limbo = false;
return;
}

if (undo) {
Undo.initEdit({textures: [this.texture], bitmap: true});
}
down_layer.ctx.drawImage(this.canvas, this.offset[0], this.offset[1]);

let index = this.texture.layers.indexOf(this);
this.texture.layers.splice(index, 1);
if (this.texture.selected_layer == this) this.texture.selected_layer = this.texture.layers[index-1] || this.texture.layers[index];
if (undo) {
this.texture.updateLayerChanges(true);
Undo.finishEdit('Merge layers');
}
}
flip(axis = 0, undo) {
let temp_canvas = this.canvas.cloneNode();
let temp_canvas_ctx = temp_canvas.getContext('2d');
temp_canvas_ctx.drawImage(this.canvas, 0, 0);

if (undo) Undo.initEdit({layers: [this]});

this.ctx.save();
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.translate(this.canvas.width, 0);
if (axis == 0) {
this.ctx.scale(-1, 1);
this.ctx.drawImage(temp_canvas, this.canvas.width, 0, -this.canvas.width, this.canvas.height);
} else {
this.ctx.scale(1, -1);
this.ctx.drawImage(temp_canvas, this.canvas.width, 0, this.canvas.width, -this.canvas.height);
}
this.ctx.restore();

this.texture.updateLayerChanges(undo);

if (undo) Undo.finishEdit('Flip layer');
}
rotate(angle = 90, undo) {
let temp_canvas = this.canvas.cloneNode();
let temp_canvas_ctx = temp_canvas.getContext('2d');
temp_canvas_ctx.drawImage(this.canvas, 0, 0);

if (undo) Undo.initEdit({layers: [this]});

[this.canvas.width, this.canvas.height] = [this.canvas.height, this.canvas.width];
this.ctx.save();
this.ctx.translate(this.canvas.width/2,this.canvas.height/2);
this.ctx.rotate(Math.degToRad(angle));
this.ctx.drawImage(temp_canvas,-temp_canvas.width/2,-temp_canvas.height/2);
this.ctx.restore();

this.texture.updateLayerChanges(undo);

if (undo) Undo.finishEdit('Rotate layer');
}
propertiesDialog() {
let dialog = new Dialog({
id: 'layer_properties',
Expand Down Expand Up @@ -166,14 +237,28 @@ Object.defineProperty(TextureLayer, 'selected', {
})

SharedActions.add('delete', {
subject: 'layer',
condition: () => Prop.active_panel == 'layers' && Texture.selected?.selected_layer,
run() {
if (Texture.selected.layers.length >= 2) {
Texture.selected?.selected_layer.remove(true);
}
}
})
SharedActions.add('delete', {
subject: 'layer_priority',
condition: () => Texture.selected?.selected_layer.in_limbo,
priority: 2,
run() {
if (Texture.selected.layers.length >= 2) {
Texture.selected?.selected_layer.remove(true);
}
Texture.selected.selection.clear()
UVEditor.updateSelectionOutline()
}
})
SharedActions.add('duplicate', {
subject: 'layer',
condition: () => Prop.active_panel == 'layers' && Texture.selected?.selected_layer,
run() {
let texture = Texture.selected;
Expand Down Expand Up @@ -420,7 +505,7 @@ Interface.definePanels(function() {
>
<li
v-for="layer in layers"
:class="{ selected: layer.selected }"
:class="{ selected: layer.selected, in_limbo: layer.in_limbo }"
:key="layer.uuid"
:layer_id="layer.uuid"
class="texture_layer"
Expand Down
2 changes: 1 addition & 1 deletion js/texturing/painter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2435,7 +2435,7 @@ BARS.defineActions(function() {
onSelect() {
let texture = Texture.selected;
if (texture && texture.selection.is_custom && texture.selection.hasSelection() && (!texture.selected_layer || !texture.selected_layer.in_limbo)) {
Texture.selected.selectionToLayer();
Texture.selected.selectionToLayer(true);
}
}
})
Expand Down
23 changes: 10 additions & 13 deletions js/texturing/textures.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Texture {
this.show_icon = true
this.error = 0;
this.visible = true;
this.display_canvas = false;
this.display_canvas = true;
this.source_overwritten = false;
//Data
this.img = 0;
Expand Down Expand Up @@ -1304,6 +1304,7 @@ class Texture {
}
activateLayers(undo) {
if (undo) Undo.initEdit({textures: [this], bitmap: true});
console.trace('E')
this.layers_enabled = true;
if (!this.layers.length) {
let layer = new TextureLayer({
Expand All @@ -1318,24 +1319,20 @@ class Texture {
updateInterfacePanels();
BARS.updateConditions();
}
selectionToLayer() {



selectionToLayer(undo) {
let texture = this;
let selection = texture.selection;

if (undo) Undo.initEdit({textures: [texture], bitmap: true});
if (!texture.layers_enabled) {
texture.activateLayers(false);
}

let {canvas, ctx} = texture.getActiveCanvas();
let layer = texture.selected_layer;
let offset = layer ? layer.offset.slice() : [0, 0];
let copy_canvas = canvas;

Undo.initEdit({textures: [texture], bitmap: true});

if (!texture.layers_enabled) {
texture.activateLayers(false);
}

if (selection.is_custom) {
let rect = selection.getBoundingRect();
copy_canvas = document.createElement('canvas');
Expand All @@ -1361,7 +1358,7 @@ class Texture {
if (texture.mode === 'link') {
texture.convertToInternal();
}
texture.selection.forEachPixel((x, y, val) => {
selection.forEachPixel((x, y, val) => {
if (val) {
ctx.clearRect(x, y, 1, 1);
}
Expand All @@ -1375,7 +1372,7 @@ class Texture {
new_layer.setLimbo();

texture.updateLayerChanges(true);
Undo.finishEdit('Texture selection to layer');
if (undo) Undo.finishEdit('Texture selection to layer');
updateInterfacePanels();
BARS.updateConditions();
}
Expand Down
Loading

0 comments on commit 49e251c

Please sign in to comment.