refactored keyboard events into their own file, bug fixes

This commit is contained in:
Hugh Bord 2021-08-16 14:10:06 +10:00
rodzic 59a87b661b
commit 7ebeda41bd
6 zmienionych plików z 584 dodań i 920 usunięć

Wyświetl plik

@ -66,7 +66,7 @@ ASCIIBIRD is mostly usable. There are some bugs however to note at the moment.
* Circle brush (works okay for odd width and height numbers)
* Importer could be re-written with regex
* Exporter will default transparent bg to black by default, which wont for some asciis
* Duplicate keyboard listeners, if you close all the ascii tabs and open/load a new ASCII it will double up on keyboard events, you can fix this by refreshing the page at the moment.
* Having more than a few layers depending on ascii size will slow things down, until the `fillNullBlocks` is refactored.
## Focusing on Now
* Modals to add
@ -80,8 +80,6 @@ ASCIIBIRD is mostly usable. There are some bugs however to note at the moment.
## ASCII Editing
Until the keyboard shortcuts are moved out of `Editor.vue` they will only work when the editor is visible.
* Ctrl + Z - Undo
* Ctrl + Y - Redo

Wyświetl plik

@ -4,6 +4,8 @@
<EditAscii />
<PasteAscii />
<KeyboardShortcuts :selected-blocks="selectedBlocks" :text-editing="textEditing" @updatecanvas="updatecanvas" />
<context-menu
:display="showContextMenu"
ref="menu"
@ -114,7 +116,7 @@
:canvas-y="canvasY"
v-if="debugPanelState.visible"
/>
<Editor @coordsupdate="updateCoords" />
<Editor @coordsupdate="updateCoords" @selectedblocks="selectedblocks" @textediting="textediting" :update-canvas="updateCanvas" />
<CharPicker v-if="toolbarState.isChoosingChar" />
<ColourPicker
@ -165,7 +167,7 @@ import PasteAscii from "./components/modals/PasteAscii.vue";
import BrushCanvas from "./components/parts/BrushCanvas.vue";
import BrushPreview from "./components/parts/BrushPreview.vue";
// import KeyboardShortcuts from "./components/parts/KeyboardShortcuts.vue";
import KeyboardShortcuts from "./components/parts/KeyboardShortcuts.vue";
import {
parseMircAscii,
@ -194,7 +196,7 @@ export default {
BrushLibrary,
BrushCanvas,
BrushPreview,
// KeyboardShortcuts
KeyboardShortcuts
},
name: "Dashboard",
data: () => ({
@ -205,6 +207,9 @@ export default {
dashboardY: 0,
importType: null,
showContextMenu: false,
selectedBlocks: null,
textEditing: null,
updateCanvas: false,
}),
computed: {
splashAscii() {
@ -270,6 +275,15 @@ export default {
this.canvasX = value.x;
this.canvasY = value.y;
},
selectedblocks(value) {
this.selectedBlocks = value
},
textediting(value) {
this.textEditing = value
},
updatecanvas() {
this.updateCanvas = !this.updateCanvas
},
async onImport() {
const { files } = this.$refs.asciiInput;
const filename = files[0].name;

Wyświetl plik

@ -10,7 +10,7 @@
<t-input
type="number"
name="width"
v-model="forms.editAscii.width"
v-model="currentAsciiWidth"
min="1"
/>
@ -18,7 +18,7 @@
<t-input
type="number"
name="height"
v-model="forms.editAscii.height"
v-model="currentAsciiHeight"
min="1"
/>
@ -73,9 +73,22 @@ export default {
currentAscii() {
return this.$store.getters.currentAscii;
},
currentAsciiEditingTitle() {
return `Editing ASCII ${this.currentAscii.title}`;
},
currentAsciiLayers() {
return this.$store.getters.currentAsciiLayers;
},
currentSelectedLayer() {
return this.currentAsciiLayers[this.currentAscii.selectedLayer];
},
currentAsciiWidth() {
return this.currentSelectedLayer.width;
},
currentAsciiHeight() {
return this.currentSelectedLayer.height;
},
},
watch: {
showEditAsciiModal(val) {

Wyświetl plik

@ -3,372 +3,357 @@
</template>
<script>
import { mircColours99, toolbarIcons, maxBrushSize } from '../../ascii';
import {
toolbarIcons,
maxBrushSize,
filterNullBlocks,
getBlocksWidth,
emptyBlock,
exportMirc,
downloadFile,
} from "../../ascii";
export default {
name: 'KeyboardShortcuts',
name: "KeyboardShortcuts",
created() {
const thisIs = this;
this.keyListener = function (e) {
// Stop blocking input when modals are open
// Whatever this char "'\0'" is it'd occur even without pressing any keys
// This fixes it
if (this.isModalOpen || e.key === "\0") {
const thisIs = this;
this.keyListener = function (e) {
// Stop blocking input when modals are open
// Whatever this char "'\0'" is it'd occur even without pressing any keys
// This fixes it
if (this.isModalOpen || e.key === "\0") {
return;
}
e.preventDefault();
// When press escape go back to default took
if (e.key === "Escape" && !this.isDefault && this.haveOpenTabs) {
this.clearToolCanvas();
this.$store.commit("changeTool", 0);
return;
}
// Change char when car picker is open
if (this.toolbarState.isChoosingChar && e.key.length === 1 && this.haveOpenTabs) {
this.$store.commit("changeChar", e.key);
return;
}
// Keys without any ctrl, shift or alt are also integrated
// and are available only in their toolbar context
// for example pressing E in default mode will toggle edit ascii
// E in text mode will type the character E
// E in brush mode will flip the brush
// Copy and paste,
const ctrlKey = e.ctrlKey || e.metaKey;
// Files / system related
const shiftKey = e.shiftKey;
// Alt key functions are toolbar related
const altKey = e.altKey;
// Used for text typing
if (this.isTextEditing && this.haveOpenTabs) {
thisIs.canvasKeyDown(e.key);
return;
}
// Show / hide grid view
if (e.key === "g" && altKey) {
this.$store.commit("toggleGridView", !this.gridView && this.haveOpenTabs);
return;
}
// Ctrl Z here
// skg - thanks for mac key suggestion, bro
if (e.key === "z" && ctrlKey && this.haveOpenTabs) {
this.undo();
return;
}
// Ctrl Y here
if (e.key === "y" && ctrlKey && this.haveOpenTabs) {
this.redo();
return;
}
// Change toolbar icon
if (
Number.parseInt(e.key) >= 1 &&
Number.parseInt(e.key) <= 8 &&
!this.toolbarState.isChoosingFg &&
!this.toolbarState.isChoosingBg &&
altKey && this.haveOpenTabs
) {
this.$store.commit("changeTool", Number.parseInt(e.key - 1));
this.clearToolCanvas();
return;
}
// Swap colours
if (e.key === "r" && altKey && this.haveOpenTabs) {
let bg = this.currentBg;
let fg = this.currentFg;
this.$store.commit("changeColourFg", bg);
this.$store.commit("changeColourBg", fg);
return;
}
// Show FG
if (e.key === "f" && altKey && !ctrlKey && this.haveOpenTabs) {
this.$store.commit(
"changeIsUpdatingFg",
!this.toolbarState.isChoosingFg
);
return;
}
// Show BG
if (e.key === "b" && altKey && !ctrlKey && this.haveOpenTabs) {
this.$store.commit(
"changeIsUpdatingBg",
!this.toolbarState.isChoosingBg
);
return;
}
// Show Character select
if (e.key === "c" && altKey && !ctrlKey && this.haveOpenTabs) {
this.$store.commit(
"changeIsUpdatingChar",
!this.toolbarState.isChoosingChar
);
return;
}
// Choose FG or BG with Keyboard
if (
Number.parseInt(e.key) >= 0 &&
Number.parseInt(e.key) <= 9 &&
(this.toolbarState.isChoosingFg || this.toolbarState.isChoosingBg) && this.haveOpenTabs
) {
if (this.toolbarState.isChoosingFg) {
this.$store.commit("changeColourFg", Number.parseInt(e.key));
return;
}
e.preventDefault();
// When press escape go back to default took
if (e.key === "Escape" && !this.isDefault) {
this.clearToolCanvas();
this.$store.commit("changeTool", 0);
if (this.toolbarState.isChoosingBg) {
this.$store.commit("changeColourBg", Number.parseInt(e.key));
return;
}
}
// Change char when car picker is open
if (this.toolbarState.isChoosingChar && e.key.length === 1) {
this.$store.commit("changeChar", e.key);
return;
}
// Keys without any ctrl, shift or alt are also integrated
// and are available only in their toolbar context
// for example pressing E in default mode will toggle edit ascii
// E in text mode will type the character E
// E in brush mode will flip the brush
// Copy and paste,
const ctrlKey = e.ctrlKey || e.metaKey;
// Files / system related
const shiftKey = e.shiftKey;
// Alt key functions are toolbar related
const altKey = e.altKey;
// Used for text typing
if (this.isTextEditing) {
thisIs.canvasKeyDown(e.key);
return;
}
// Show / hide grid view
if (e.key === "g" && altKey) {
this.$store.commit("toggleGridView", !this.gridView);
return;
}
// Ctrl Z here
// skg - thanks for mac key suggestion, bro
if (e.key === "z" && ctrlKey) {
this.undo();
return;
}
// Ctrl Y here
if (e.key === "y" && ctrlKey) {
this.redo();
return;
}
// Change toolbar icon
if (
Number.parseInt(e.key) >= 1 &&
Number.parseInt(e.key) <= 8 &&
!this.toolbarState.isChoosingFg &&
!this.toolbarState.isChoosingBg &&
altKey
) {
this.$store.commit("changeTool", Number.parseInt(e.key - 1));
this.clearToolCanvas();
return;
}
// Swap colours
if (e.key === "r" && altKey) {
let bg = this.currentBg;
let fg = this.currentFg;
this.$store.commit("changeColourFg", bg);
this.$store.commit("changeColourBg", fg);
return;
}
// Show FG
if (e.key === "f" && altKey && !ctrlKey) {
// Ctrl C - copy blocks
if (e.key === "c" && ctrlKey && !shiftKey && this.haveOpenTabs) {
if (this.selectedBlocks.length) {
this.$store.commit(
"changeIsUpdatingFg",
!this.toolbarState.isChoosingFg
"selectBlocks",
filterNullBlocks(this.selectedBlocks)
);
return;
this.$toasted.show("Copied blocks!", {
type: "success",
icon: "fa-check-circle",
});
}
// Show BG
if (e.key === "b" && altKey && !ctrlKey) {
this.$store.commit(
"changeIsUpdatingBg",
!this.toolbarState.isChoosingBg
);
return;
}
return;
}
// Show Character select
if (e.key === "c" && altKey && !ctrlKey) {
this.$store.commit(
"changeIsUpdatingChar",
!this.toolbarState.isChoosingChar
);
return;
}
// Choose FG or BG with Keyboard
if (
Number.parseInt(e.key) >= 0 &&
Number.parseInt(e.key) <= 9 &&
(this.toolbarState.isChoosingFg || this.toolbarState.isChoosingBg)
) {
if (this.toolbarState.isChoosingFg) {
this.$store.commit("changeColourFg", Number.parseInt(e.key));
return;
}
if (this.toolbarState.isChoosingBg) {
this.$store.commit("changeColourBg", Number.parseInt(e.key));
return;
}
}
// Ctrl C - copy blocks
if (e.key === "c" && ctrlKey && !shiftKey) {
if (this.selectedBlocks.length) {
this.$store.commit(
"selectBlocks",
this.filterNullBlocks(this.selectedBlocks)
);
this.$toasted.show("Copied blocks!", {
type: "success",
icon: "fa-check-circle",
});
this.selectedBlocks = [];
// Reset and hide the select after successful copy
this.resetSelect();
this.processSelect();
}
return;
}
// Delte blocks but do not save them when pressing Delete when selected
if (e.key === "Delete" && this.isSelected) {
if (this.selectedBlocks.length) {
for (let y = 0; y < this.selectedBlocks.length + 1; y++) {
for (
let x = 0;
x < getBlocksWidth(this.selectedBlocks) + 1;
x++
) {
if (this.selectedBlocks[y] && this.selectedBlocks[y][x]) {
this.currentAsciiLayerBlocks[y][x] = { ...emptyBlock };
}
// Delte blocks but do not save them when pressing Delete when selected
if (e.key === "Delete" && this.haveOpenTabs) {
console.log(getBlocksWidth(this.selectedBlocks));
if (this.selectedBlocks.length) {
for (let y = 0; y < this.selectedBlocks.length + 1; y++) {
for (let x = 0; x < getBlocksWidth(this.selectedBlocks) + 1; x++) {
if (this.selectedBlocks[y] && this.selectedBlocks[y][x]) {
this.currentAsciiLayerBlocks[y][x] = { ...emptyBlock };
}
}
// Reset and hide the select after successful copy
this.$store.commit(
"updateAsciiBlocks",
this.currentAsciiLayerBlocks
);
this.delayRedrawCanvas();
this.$toasted.show("Deleted blocks!", {
type: "success",
icon: "fa-check-circle",
});
}
return;
// Reset and hide the select after successful copy
this.$store.commit("updateAsciiBlocks", this.currentAsciiLayerBlocks);
this.delayRedrawCanvas();
this.$toasted.show("Deleted blocks!", {
type: "success",
icon: "fa-check-circle",
});
}
// Ctrl X - cut blocks
if (e.key === "x" && ctrlKey && !shiftKey && this.isSelected) {
if (this.selectedBlocks.length) {
for (let y = 0; y < this.selectedBlocks.length + 1; y++) {
for (
let x = 0;
x < getBlocksWidth(this.selectedBlocks) + 1;
x++
) {
if (this.selectedBlocks[y] && this.selectedBlocks[y][x]) {
this.currentAsciiLayerBlocks[y][x] = { ...emptyBlock };
}
return;
}
// Ctrl X - cut blocks
if (e.key === "x" && ctrlKey && !shiftKey && this.haveOpenTabs) {
if (this.selectedBlocks.length) {
for (let y = 0; y < this.selectedBlocks.length + 1; y++) {
for (let x = 0; x < getBlocksWidth(this.selectedBlocks) + 1; x++) {
if (this.selectedBlocks[y] && this.selectedBlocks[y][x]) {
this.currentAsciiLayerBlocks[y][x] = { ...emptyBlock };
}
}
this.$store.commit(
"selectBlocks",
this.filterNullBlocks(this.selectedBlocks)
);
this.selectedBlocks = [];
// Reset and hide the select after successful copy
this.$store.commit(
"updateAsciiBlocks",
this.currentAsciiLayerBlocks
);
// this.delayRedrawCanvas()
this.$toasted.show("Cut blocks!", {
type: "success",
icon: "fa-check-circle",
});
}
return;
}
// Ctrl V - paste blocks
if (e.key === "v" && ctrlKey) {
if (this.haveSelectBlocks) {
this.$store.commit("pushBrushHistory", this.brushBlocks);
this.$store.commit("brushBlocks", this.selectBlocks);
this.$store.commit("changeTool", 4);
}
return;
}
// Show / hide debug panel
if (e.key === "d" && this.isDefault) {
this.$store.commit("toggleDebugPanel", !this.debugPanelState.visible);
return;
}
// Show / hide brush library
if (e.key === "l" && this.isDefault) {
this.$store.commit(
"toggleBrushLibrary",
!this.brushLibraryState.visible
"selectBlocks",
filterNullBlocks(this.selectedBlocks)
);
return;
}
this.selectedBlocks = [];
// New ASCII
// Ctrl N doesn't seem to work in chrome? https://github.com/liftoff/GateOne/issues/290
if (e.key === "n" && this.isDefault && !this.isTextEditing) {
this.$store.commit("openModal", "new-ascii");
// Reset and hide the select after successful copy
return;
}
this.$store.commit("updateAsciiBlocks", this.currentAsciiLayerBlocks);
// this.delayRedrawCanvas()
// Edit ASCII
if (e.key === "e" && this.isDefault && !this.isTextEditing) {
this.$store.commit("openModal", "edit-ascii");
return;
}
// Paste ASCII
if (e.key === "p" && this.isDefault && !this.isTextEditing) {
this.$store.commit("openModal", "paste-ascii");
return;
}
// Export to clipboard
if (e.key === "C" && ctrlKey && shiftKey) {
let ascii = exportMirc();
this.$copyText(ascii.output.join("")).then(
(e) => {
this.$toasted.show("Copied mIRC to clipboard!", {
type: "success",
});
},
(e) => {
this.$toasted.show("Error when copying mIRC to clipboard!", {
type: "error",
});
}
);
return;
}
// Export to txt
if (e.key === "F" && ctrlKey && shiftKey) {
let ascii = exportMirc();
downloadFile(ascii.output.join(""), ascii.filename, "text/plain");
return;
}
if (
e.key === "]" &&
ctrlKey &&
this.brushSizeHeight < this.maxBrushSize &&
this.brushSizeHeight >= 1 &&
this.brushSizeWidth < this.maxBrushSize &&
this.brushSizeWidth >= 1
) {
this.$store.commit("updateBrushSize", {
brushSizeHeight: parseInt(this.brushSizeHeight) + 1,
brushSizeWidth: parseInt(this.brushSizeWidth) + 1,
brushSizeType: this.brushSizeType,
this.$toasted.show("Cut blocks!", {
type: "success",
icon: "fa-check-circle",
});
return;
}
if (
e.key === "[" &&
ctrlKey &&
this.brushSizeHeight <= this.maxBrushSize &&
this.brushSizeHeight > 1 &&
this.brushSizeWidth <= this.maxBrushSize &&
this.brushSizeWidth > 1
) {
this.$store.commit("updateBrushSize", {
brushSizeHeight: parseInt(this.brushSizeHeight) - 1,
brushSizeWidth: parseInt(this.brushSizeWidth) - 1,
brushSizeType: this.brushSizeType,
});
return;
}
return;
// Ctrl V - paste blocks
if (e.key === "v" && ctrlKey && this.haveOpenTabs) {
if (this.haveSelectBlocks) {
this.$store.commit("pushBrushHistory", this.brushBlocks);
this.$store.commit("brushBlocks", this.selectBlocks);
this.$store.commit("changeTool", 4);
}
// Hopefully we can still pick up the previous inputs
// while in brush mode
if (this.isBrushing) {
if (e.key === "e") {
this.$store.commit("flipRotateBlocks", {
type: "flip",
return;
}
// Show / hide debug panel
if (e.key === "d" && this.isDefault && this.haveOpenTabs) {
this.$store.commit("toggleDebugPanel", !this.debugPanelState.visible);
return;
}
// Show / hide brush library
if (e.key === "l" && this.isDefault && this.haveOpenTabs) {
this.$store.commit(
"toggleBrushLibrary",
!this.brushLibraryState.visible
);
return;
}
// New ASCII
// Ctrl N doesn't seem to work in chrome? https://github.com/liftoff/GateOne/issues/290
if (e.key === "n" && this.isDefault && !this.isTextEditing) {
this.$store.commit("openModal", "new-ascii");
return;
}
// Edit ASCII
if (e.key === "e" && this.isDefault && !this.isTextEditing && this.haveOpenTabs) {
this.$store.commit("openModal", "edit-ascii");
return;
}
// Paste ASCII
if (e.key === "p" && this.isDefault && !this.isTextEditing) {
this.$store.commit("openModal", "paste-ascii");
return;
}
// Export to clipboard
if (e.key === "C" && ctrlKey && shiftKey && this.haveOpenTabs) {
let ascii = exportMirc();
this.$copyText(ascii.output.join("")).then(
(e) => {
this.$toasted.show("Copied mIRC to clipboard!", {
type: "success",
});
},
(e) => {
this.$toasted.show("Error when copying mIRC to clipboard!", {
type: "error",
});
}
);
if (e.key === "q") {
this.$store.commit("flipRotateBlocks", {
type: "rotate",
});
}
return;
return;
}
// Export to txt
if (e.key === "F" && ctrlKey && shiftKey && this.haveOpenTabs) {
let ascii = exportMirc();
downloadFile(ascii.output.join(""), ascii.filename, "text/plain");
return;
}
if (
e.key === "]" &&
ctrlKey &&
this.brushSizeHeight < maxBrushSize &&
this.brushSizeHeight >= 1 &&
this.brushSizeWidth < maxBrushSize &&
this.brushSizeWidth >= 1 && this.haveOpenTabs
) {
this.$store.commit("updateBrushSize", {
brushSizeHeight: parseInt(this.brushSizeHeight) + 1,
brushSizeWidth: parseInt(this.brushSizeWidth) + 1,
brushSizeType: this.brushSizeType,
});
return;
}
if (
e.key === "[" &&
ctrlKey &&
this.brushSizeHeight <= maxBrushSize &&
this.brushSizeHeight > 1 &&
this.brushSizeWidth <= maxBrushSize &&
this.brushSizeWidth > 1 && this.haveOpenTabs
) {
this.$store.commit("updateBrushSize", {
brushSizeHeight: parseInt(this.brushSizeHeight) - 1,
brushSizeWidth: parseInt(this.brushSizeWidth) - 1,
brushSizeType: this.brushSizeType,
});
return;
}
// Hopefully we can still pick up the previous inputs
// while in brush mode
if (this.isBrushing && this.haveOpenTabs) {
if (e.key === "e") {
this.$store.commit("flipRotateBlocks", {
type: "flip",
});
}
};
// this.keyListenerUp = function (e) {
// this.canKey = true
// };
if (e.key === "q") {
this.$store.commit("flipRotateBlocks", {
type: "rotate",
});
}
return;
}
};
document.addEventListener("keydown", this.keyListener.bind(this));
// document.addEventListener("keyup", this.keyListenerUp.bind(this));
document.addEventListener("keydown", this.keyListener.bind(this));
},
props: ["selectedBlocks", "textEditing"],
computed: {
isModalOpen() {
return this.$store.getters.isModalOpen;
@ -450,23 +435,238 @@ export default {
haveSelectBlocks() {
return !!this.selectBlocks.length;
},
mircColours() {
return mircColours99;
},
brushLibraryState() {
return this.$store.getters.brushLibraryState;
},
maxBrushSize() {
return maxBrushSize;
currentAsciiLayers() {
return this.$store.getters.currentAsciiLayers;
},
currentSelectedLayer() {
return this.currentAsciiLayers[this.currentAscii.selectedLayer];
},
currentAsciiLayerBlocks() {
return this.currentSelectedLayer.data;
},
currentAsciiWidth() {
return this.currentSelectedLayer.width;
},
currentAsciiHeight() {
return this.currentSelectedLayer.height;
},
haveOpenTabs() {
return this.$store.getters.currentAscii !== false
}
},
methods: {
filterNullBlocks(val) {
return filterNullBlocks(val);
},
undo() {
this.$store.commit("undoBlocks");
},
redo() {
this.$store.commit("redoBlocks");
},
canvasKeyDown(char) {
if (this.isTextEditing) {
if (
this.currentAsciiLayerBlocks[this.textEditing.startY] &&
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
]
) {
let targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
];
switch (char) {
// Remove a character
case "Backspace":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX - 1
]
) {
targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX - 1
];
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX - 1
].char = null;
this.textEditing.startX -= 1;
}
// Remove char as current position, but don't change position after
case "Delete":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
]
) {
targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
];
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
].char = null;
}
// Also remove in mirror mode the other chars
if (this.mirrorX) {
targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.currentAsciiWidth - this.textEditing.startX
];
targetBlock.char = null;
}
if (this.mirrorY) {
targetBlock =
this.currentAsciiLayerBlocks[
this.currentAsciiHeight - this.textEditing.startY
][this.textEditing.startX];
targetBlock.char = null;
}
if (this.mirrorY && this.mirrorX) {
targetBlock =
this.currentAsciiLayerBlocks[
this.currentAsciiHeight - this.textEditing.startY
][this.currentAsciiWidth - this.textEditing.startX];
targetBlock.char = null;
}
break;
// Jump to next line at the 0 X position
case "Enter":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY + 1][0]
) {
this.textEditing.startX = 0;
this.textEditing.startY += 1;
}
break;
// Move the text indicator around with the arrow keys
case "ArrowUp":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY - 1][
this.textEditing.startX
]
) {
this.textEditing.startY -= 1;
}
break;
case "ArrowDown":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY + 1][
this.textEditing.startX
]
) {
this.textEditing.startY += 1;
}
break;
case "ArrowLeft":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX - 1
]
) {
this.textEditing.startX -= 1;
}
break;
case "ArrowRight":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX + 1
]
) {
this.textEditing.startX += 1;
}
break;
// Normal typing
default:
if (char.length === 1) {
if (this.canFg) {
targetBlock.fg = this.currentFg;
}
targetBlock.char = char;
if (this.mirrorX) {
targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.currentAsciiWidth - this.textEditing.startX
];
if (this.canFg) {
targetBlock.fg = this.currentFg;
}
targetBlock.char = char;
}
if (this.mirrorY) {
targetBlock =
this.currentAsciiLayerBlocks[
this.currentAsciiHeight - this.textEditing.startY
][this.textEditing.startX];
if (this.canFg) {
targetBlock.fg = this.currentFg;
}
targetBlock.char = char;
}
if (this.mirrorY && this.mirrorX) {
targetBlock =
this.currentAsciiLayerBlocks[
this.currentAsciiHeight - this.textEditing.startY
][this.currentAsciiWidth - this.textEditing.startX];
if (this.canFg) {
targetBlock.fg = this.currentFg;
}
targetBlock.char = char;
}
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX + 1
]
) {
this.textEditing.startX++;
} else {
this.textEditing.startX = 0;
if (this.textEditing.startY < this.currentAsciiHeight) {
this.textEditing.startY++;
}
}
}
break;
}
}
// Emit back to dashboard then to editor that we need to redraw the canvas
this.$emit("updatecanvas");
}
},
},
};
</script>

Wyświetl plik

@ -50,6 +50,7 @@ export default {
},
mounted() {
this.ctx = this.canvasRef.getContext("2d");
this.delayRedrawCanvas();
},
data: () => ({
ctx: null,

Wyświetl plik

@ -62,8 +62,6 @@
import {
toolbarIcons,
mircColours99,
exportMirc,
downloadFile,
filterNullBlocks,
blockWidth,
blockHeight,
@ -92,366 +90,7 @@ export default {
this.canvas.height = this.currentAsciiHeight * blockHeight;
this.delayRedrawCanvas();
// this.$store.commit("changeTool", 0);
const thisIs = this;
this.keyListener = function (e) {
// Stop blocking input when modals are open
// Whatever this char "'\0'" is it'd occur even without pressing any keys
// This fixes it
if (this.isModalOpen || e.key === "\0") {
return;
}
e.preventDefault();
// When press escape go back to default took
if (e.key === "Escape" && !this.isDefault) {
this.clearToolCanvas();
this.$store.commit("changeTool", 0);
return;
}
// Change char when car picker is open
if (this.toolbarState.isChoosingChar && e.key.length === 1) {
this.$store.commit("changeChar", e.key);
return;
}
// Keys without any ctrl, shift or alt are also integrated
// and are available only in their toolbar context
// for example pressing E in default mode will toggle edit ascii
// E in text mode will type the character E
// E in brush mode will flip the brush
// Copy and paste,
const ctrlKey = e.ctrlKey || e.metaKey;
// Files / system related
const shiftKey = e.shiftKey;
// Alt key functions are toolbar related
const altKey = e.altKey;
// Used for text typing
if (this.isTextEditing) {
thisIs.canvasKeyDown(e.key);
return;
}
// Show / hide grid view
if (e.key === "g" && altKey) {
this.$store.commit("toggleGridView", !this.gridView);
return;
}
// Ctrl Z here
// skg - thanks for mac key suggestion, bro
if (e.key === "z" && ctrlKey) {
this.undo();
return;
}
// Ctrl Y here
if (e.key === "y" && ctrlKey) {
this.redo();
return;
}
// Change toolbar icon
if (
Number.parseInt(e.key) >= 1 &&
Number.parseInt(e.key) <= 8 &&
!this.toolbarState.isChoosingFg &&
!this.toolbarState.isChoosingBg &&
altKey
) {
this.$store.commit("changeTool", Number.parseInt(e.key - 1));
this.clearToolCanvas();
return;
}
// Swap colours
if (e.key === "r" && altKey) {
let bg = this.currentBg;
let fg = this.currentFg;
this.$store.commit("changeColourFg", bg);
this.$store.commit("changeColourBg", fg);
return;
}
// Show FG
if (e.key === "f" && altKey && !ctrlKey) {
this.$store.commit(
"changeIsUpdatingFg",
!this.toolbarState.isChoosingFg
);
return;
}
// Show BG
if (e.key === "b" && altKey && !ctrlKey) {
this.$store.commit(
"changeIsUpdatingBg",
!this.toolbarState.isChoosingBg
);
return;
}
// Show Character select
if (e.key === "c" && altKey && !ctrlKey) {
this.$store.commit(
"changeIsUpdatingChar",
!this.toolbarState.isChoosingChar
);
return;
}
// Choose FG or BG with Keyboard
if (
Number.parseInt(e.key) >= 0 &&
Number.parseInt(e.key) <= 9 &&
(this.toolbarState.isChoosingFg || this.toolbarState.isChoosingBg)
) {
if (this.toolbarState.isChoosingFg) {
this.$store.commit("changeColourFg", Number.parseInt(e.key));
return;
}
if (this.toolbarState.isChoosingBg) {
this.$store.commit("changeColourBg", Number.parseInt(e.key));
return;
}
}
// Ctrl C - copy blocks
if (e.key === "c" && ctrlKey && !shiftKey) {
if (this.selectedBlocks.length) {
this.$store.commit(
"selectBlocks",
this.filterNullBlocks(this.selectedBlocks)
);
this.$toasted.show("Copied blocks!", {
type: "success",
icon: "fa-check-circle",
});
this.selectedBlocks = [];
// Reset and hide the select after successful copy
this.resetSelect();
this.processSelect();
}
return;
}
// Delte blocks but do not save them when pressing Delete when selected
if (e.key === "Delete" && this.isSelected) {
if (this.selectedBlocks.length) {
for (let y = 0; y < this.selectedBlocks.length + 1; y++) {
for (
let x = 0;
x < getBlocksWidth(this.selectedBlocks) + 1;
x++
) {
if (this.selectedBlocks[y] && this.selectedBlocks[y][x]) {
this.currentAsciiLayerBlocks[y][x] = { ...emptyBlock };
}
}
}
// Reset and hide the select after successful copy
this.$store.commit(
"updateAsciiBlocks",
this.currentAsciiLayerBlocks
);
this.delayRedrawCanvas();
this.$toasted.show("Deleted blocks!", {
type: "success",
icon: "fa-check-circle",
});
}
return;
}
// Ctrl X - cut blocks
if (e.key === "x" && ctrlKey && !shiftKey && this.isSelected) {
if (this.selectedBlocks.length) {
for (let y = 0; y < this.selectedBlocks.length + 1; y++) {
for (
let x = 0;
x < getBlocksWidth(this.selectedBlocks) + 1;
x++
) {
if (this.selectedBlocks[y] && this.selectedBlocks[y][x]) {
this.currentAsciiLayerBlocks[y][x] = { ...emptyBlock };
}
}
}
this.$store.commit(
"selectBlocks",
this.filterNullBlocks(this.selectedBlocks)
);
this.selectedBlocks = [];
// Reset and hide the select after successful copy
this.$store.commit(
"updateAsciiBlocks",
this.currentAsciiLayerBlocks
);
// this.delayRedrawCanvas()
this.$toasted.show("Cut blocks!", {
type: "success",
icon: "fa-check-circle",
});
}
return;
}
// Ctrl V - paste blocks
if (e.key === "v" && ctrlKey) {
if (this.haveSelectBlocks) {
this.$store.commit("pushBrushHistory", this.brushBlocks);
this.$store.commit("brushBlocks", this.selectBlocks);
this.$store.commit("changeTool", 4);
}
return;
}
// Show / hide debug panel
if (e.key === "d" && this.isDefault) {
this.$store.commit("toggleDebugPanel", !this.debugPanelState.visible);
return;
}
// Show / hide brush library
if (e.key === "l" && this.isDefault) {
this.$store.commit(
"toggleBrushLibrary",
!this.brushLibraryState.visible
);
return;
}
// New ASCII
// Ctrl N doesn't seem to work in chrome? https://github.com/liftoff/GateOne/issues/290
if (e.key === "n" && this.isDefault && !this.isTextEditing) {
this.$store.commit("openModal", "new-ascii");
return;
}
// Edit ASCII
if (e.key === "e" && this.isDefault && !this.isTextEditing) {
this.$store.commit("openModal", "edit-ascii");
return;
}
// Paste ASCII
if (e.key === "p" && this.isDefault && !this.isTextEditing) {
this.$store.commit("openModal", "paste-ascii");
return;
}
// Export to clipboard
if (e.key === "C" && ctrlKey && shiftKey) {
let ascii = exportMirc();
this.$copyText(ascii.output.join("")).then(
(e) => {
this.$toasted.show("Copied mIRC to clipboard!", {
type: "success",
});
},
(e) => {
this.$toasted.show("Error when copying mIRC to clipboard!", {
type: "error",
});
}
);
return;
}
// Export to txt
if (e.key === "F" && ctrlKey && shiftKey) {
let ascii = exportMirc();
downloadFile(ascii.output.join(""), ascii.filename, "text/plain");
return;
}
if (
e.key === "]" &&
ctrlKey &&
this.brushSizeHeight < this.maxBrushSize &&
this.brushSizeHeight >= 1 &&
this.brushSizeWidth < this.maxBrushSize &&
this.brushSizeWidth >= 1
) {
this.$store.commit("updateBrushSize", {
brushSizeHeight: parseInt(this.brushSizeHeight) + 1,
brushSizeWidth: parseInt(this.brushSizeWidth) + 1,
brushSizeType: this.brushSizeType,
});
return;
}
if (
e.key === "[" &&
ctrlKey &&
this.brushSizeHeight <= this.maxBrushSize &&
this.brushSizeHeight > 1 &&
this.brushSizeWidth <= this.maxBrushSize &&
this.brushSizeWidth > 1
) {
this.$store.commit("updateBrushSize", {
brushSizeHeight: parseInt(this.brushSizeHeight) - 1,
brushSizeWidth: parseInt(this.brushSizeWidth) - 1,
brushSizeType: this.brushSizeType,
});
return;
}
// Hopefully we can still pick up the previous inputs
// while in brush mode
if (this.isBrushing) {
if (e.key === "e") {
this.$store.commit("flipRotateBlocks", {
type: "flip",
});
}
if (e.key === "q") {
this.$store.commit("flipRotateBlocks", {
type: "rotate",
});
}
return;
}
};
// document.removeEventListener("keydown", this.keyListener.bind(this));
// Doesn't do anything to fix the double key listener when editor loads again
document.addEventListener("keydown", this.keyListener.bind(this));
this.$emit("textediting", this.textEditing);
}
},
data: () => ({
@ -480,6 +119,7 @@ export default {
isMouseOnCanvas: false,
selectedBlocks: [],
}),
props: ["updateCanvas"],
computed: {
canvasRef() {
return this.$refs.canvas;
@ -493,24 +133,9 @@ export default {
blockSizeMultiplier() {
return this.$store.getters.blockSizeMultiplier;
},
isModalOpen() {
return this.$store.getters.isModalOpen;
},
brushSizeHeight() {
return this.$store.getters.brushSizeHeight;
},
brushSizeWidth() {
return this.$store.getters.brushSizeWidth;
},
brushSizeType() {
return this.$store.getters.brushSizeType;
},
currentAscii() {
return this.$store.getters.currentAscii;
},
currentAsciiBlocks() {
return this.$store.getters.currentAsciiBlocks;
},
currentAsciiLayers() {
return this.$store.getters.currentAsciiLayers;
},
@ -645,9 +270,12 @@ export default {
currentAsciiLayers() {
this.delayRedrawCanvas();
},
currentSelectedLayer() {
currentSelectedLayer(val, old) {
this.delayRedrawCanvas();
this.warnInvisibleLayer();
if (old.visible) {
this.warnInvisibleLayer();
}
},
currentTool() {
this.warnInvisibleLayer();
@ -692,6 +320,19 @@ export default {
this.$store.commit("updateAsciiBlocks", this.currentAsciiLayerBlocks);
}
},
textEditing(val, old) {
this.$emit("textediting", val);
},
updateCanvas(val, old) {
if (val !== old) {
// This comes from KeyboardShortcuts.vue
this.clearToolCanvas();
this.drawTextIndicator();
this.drawIndicator();
this.delayRedrawCanvas();
}
},
},
methods: {
warnInvisibleLayer() {
@ -801,7 +442,6 @@ export default {
// break;
}
// this.currentAsciiBlocks[y][x] = { ... curBlock}
canvasX = blockWidth * x;
if (this.gridView) {
@ -872,210 +512,6 @@ export default {
this.top = y;
this.delayRedrawCanvas();
},
canvasKeyDown(char) {
if (this.isTextEditing) {
if (
this.currentAsciiLayerBlocks[this.textEditing.startY] &&
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
]
) {
let targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
];
switch (char) {
// Remove a character
case "Backspace":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX - 1
]
) {
targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX - 1
];
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX - 1
].char = null;
this.textEditing.startX -= 1;
}
// Remove char as current position, but don't change position after
case "Delete":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
]
) {
targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
];
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX
].char = null;
}
// Also remove in mirror mode the other chars
if (this.mirrorX) {
targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.currentAsciiWidth - this.textEditing.startX
];
targetBlock.char = null;
}
if (this.mirrorY) {
targetBlock =
this.currentAsciiLayerBlocks[
this.currentAsciiHeight - this.textEditing.startY
][this.textEditing.startX];
targetBlock.char = null;
}
if (this.mirrorY && this.mirrorX) {
targetBlock =
this.currentAsciiLayerBlocks[
this.currentAsciiHeight - this.textEditing.startY
][this.currentAsciiWidth - this.textEditing.startX];
targetBlock.char = null;
}
break;
// Jump to next line at the 0 X position
case "Enter":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY + 1][0]
) {
this.textEditing.startX = 0;
this.textEditing.startY += 1;
}
break;
// Move the text indicator around with the arrow keys
case "ArrowUp":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY - 1][
this.textEditing.startX
]
) {
this.textEditing.startY -= 1;
}
break;
case "ArrowDown":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY + 1][
this.textEditing.startX
]
) {
this.textEditing.startY += 1;
}
break;
case "ArrowLeft":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX - 1
]
) {
this.textEditing.startX -= 1;
}
break;
case "ArrowRight":
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX + 1
]
) {
this.textEditing.startX += 1;
}
break;
// Normal typing
default:
if (char.length === 1) {
if (this.canFg) {
targetBlock.fg = this.currentFg;
}
targetBlock.char = char;
if (this.mirrorX) {
targetBlock =
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.currentAsciiWidth - this.textEditing.startX
];
if (this.canFg) {
targetBlock.fg = this.currentFg;
}
targetBlock.char = char;
}
if (this.mirrorY) {
targetBlock =
this.currentAsciiLayerBlocks[
this.currentAsciiHeight - this.textEditing.startY
][this.textEditing.startX];
if (this.canFg) {
targetBlock.fg = this.currentFg;
}
targetBlock.char = char;
}
if (this.mirrorY && this.mirrorX) {
targetBlock =
this.currentAsciiLayerBlocks[
this.currentAsciiHeight - this.textEditing.startY
][this.currentAsciiWidth - this.textEditing.startX];
if (this.canFg) {
targetBlock.fg = this.currentFg;
}
targetBlock.char = char;
}
if (
this.currentAsciiLayerBlocks[this.textEditing.startY][
this.textEditing.startX + 1
]
) {
this.textEditing.startX++;
} else {
this.textEditing.startX = 0;
if (this.textEditing.startY < this.currentAsciiHeight) {
this.textEditing.startY++;
}
}
}
break;
}
}
this.delayRedrawCanvas();
// It's a bit intense to push this every single keystroke
// this.$store.commit("updateAsciiBlocks", this.currentAsciiLayerBlocks);
this.clearToolCanvas();
this.drawTextIndicator();
this.drawIndicator();
}
},
// Mouse Up, Down and Move
canvasMouseUp() {
if (this.isDefault) return;
@ -1326,6 +762,8 @@ export default {
}
}
}
this.$emit("selectedblocks", this.selectedBlocks);
},
drawRectangleBlock(x, y) {
let indicatorColour = this.asciiBlockAtXy.bg === 0 ? 1 : 0;