diff --git a/css/icons.css b/css/icons.css index 2cc159e..411bd75 100644 --- a/css/icons.css +++ b/css/icons.css @@ -46,6 +46,12 @@ mask-image: url("../res/icons/file-plus.svg"); } +.ui.inline-icon.icon-flip-horizontal::after, +.ui.icon > .icon-flip-horizontal { + -webkit-mask-image: url("../res/icons/flip-horizontal.svg"); + mask-image: url("../res/icons/flip-horizontal.svg"); +} + .ui.icon > .icon-file-x { -webkit-mask-image: url("../res/icons/file-x.svg"); mask-image: url("../res/icons/file-x.svg"); diff --git a/js/lib/toolbar.js b/js/lib/toolbar.js index 6706410..32d1f56 100644 --- a/js/lib/toolbar.js +++ b/js/lib/toolbar.js @@ -173,7 +173,16 @@ const _toolbar_input = { label.appendChild(checkbox); label.appendChild(new Text(text)); - return {checkbox, label}; + return { + checkbox, + label, + setValue(v) { + checkbox.checked = v; + state[dataKey] = checkbox.checked; + cb && cb(); + return checkbox.checked; + }, + }; }, slider: (state, dataKey, text, options = {}) => { diff --git a/js/ui/tool/stamp.js b/js/ui/tool/stamp.js index a7a5220..87829d6 100644 --- a/js/ui/tool/stamp.js +++ b/js/ui/tool/stamp.js @@ -57,6 +57,7 @@ const stampTool = () => mouse.listen.world.btn.left.ondragend.on(state.dragendcb); mouse.listen.world.onwheel.on(state.onwheelcb); + keyboard.onShortcut({key: "Equal"}, state.togglemirror); // For calls from other tools to paste image if (opt && opt.image) { @@ -90,6 +91,7 @@ const stampTool = () => mouse.listen.world.btn.left.ondragend.clear(state.dragendcb); mouse.listen.world.onwheel.clear(state.onwheelcb); + keyboard.deleteShortcut(state.togglemirror, "Delete"); ovLayer.clear(); }, @@ -110,11 +112,18 @@ const stampTool = () => // Current Scale state.scale = 1; + state.togglemirror = () => { + state.mirrorSetValue(!state.mirrorStamp); + state.redraw(); + }; + state.selectResource = (resource, nolock = true, deselect = true) => { rotation = 0; state.setScale(1); if (nolock && state.ctxmenu.uploadButton.disabled) return; + state.mirrorSetValue(false); + console.debug( `[stamp] Selecting Resource '${resource && resource.name}'[${ resource && resource.id @@ -394,8 +403,11 @@ const stampTool = () => if (state.selected) { ovCtx.save(); ovCtx.translate(px, py); - ovCtx.scale(state.scale, state.scale); - ovCtx.rotate(rotation); + ovCtx.scale( + state.scale * (state.mirrorStamp ? -1 : 1), + state.scale + ); + ovCtx.rotate(rotation * (state.mirrorStamp ? -1 : 1)); ovCtx.drawImage(state.selected.image, 0, 0); ovCtx.restore(); @@ -488,7 +500,19 @@ const stampTool = () => "icon-grid" ).checkbox ); - state.ctxmenu.snapToGridLabel = array; + + // Mirror Stamp Checkbox + const {checkbox: mirrorCheckbox, setValue: mirrorSetValue} = + _toolbar_input.checkbox( + state, + "mirrorStamp", + "Mirror Stamp", + "icon-flip-horizontal" + ); + array.appendChild(mirrorCheckbox); + state.mirrorSetValue = mirrorSetValue; + + state.ctxmenu.buttonArray = array; // Scale Slider const scaleSlider = _toolbar_input.slider(state, "scale", "Scale", { @@ -624,7 +648,7 @@ const stampTool = () => } }, populateContextMenu: (menu, state) => { - menu.appendChild(state.ctxmenu.snapToGridLabel); + menu.appendChild(state.ctxmenu.buttonArray); menu.appendChild(state.ctxmenu.scaleSlider); menu.appendChild(state.ctxmenu.resourceManager); }, diff --git a/res/icons/flip-horizontal.svg b/res/icons/flip-horizontal.svg new file mode 100644 index 0000000..5248d1c --- /dev/null +++ b/res/icons/flip-horizontal.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file