asset editor undo w/ ctrl+z; working on editor tools

This commit is contained in:
Steven Hugg 2019-03-27 16:19:16 -04:00
parent c794a43004
commit f4f0e607eb
5 changed files with 75 additions and 21 deletions

View File

@ -102,15 +102,13 @@ TODO:
- landscape mode for arcade ports
- pixel editor
- edit sprites and tiles at same time (multiple views)
- persist palette selections
- persist palette/tilemap selections
- more tools for editing
- map editor
- metasprites
- update nested data, palette/tile refs properly
- throw errors when bad/no refs
- careful with mouse capture out of frame
- capture so we get mouseUp() out of frame
- per-View keyboard shortcuts
- global undo
WEB WORKER FORMAT

View File

@ -2,6 +2,7 @@
import { hex, rgb2bgr, rle_unpack } from "../util";
import { ProjectWindows } from "../windows";
declare var Mousetrap;
export type UintArray = number[] | Uint8Array | Uint16Array | Uint32Array; //{[i:number]:number};
@ -892,6 +893,7 @@ class PixEditor extends Viewer {
curpalcol : number = -1;
currgba : number;
palbtns : JQuery[];
offscreen : Map<string, number> = new Map();
getPositionFromEvent(e) {
var x = Math.floor(e.offsetX * this.width / $(this.canvas).width());
@ -938,6 +940,16 @@ class PixEditor extends Viewer {
this.commit();
// TODO: pixcanvas.releaseCapture();
});
/*
Mousetrap.bind('ctrl+shift+h', this.flipX.bind(this));
Mousetrap.bind('ctrl+shift+v', this.flipY.bind(this));
Mousetrap.bind('ctrl+shift+9', this.rotate90.bind(this));
Mousetrap.bind('ctrl+shift+left', this.translate.bind(this, -1, 0));
Mousetrap.bind('ctrl+shift+right', this.translate.bind(this, 1, 0));
Mousetrap.bind('ctrl+shift+up', this.translate.bind(this, 0, -1));
Mousetrap.bind('ctrl+shift+down', this.translate.bind(this, 0, 1));
*/
// TODO: remove when unbound
aeditor.empty();
aeditor.append(this.canvas);
@ -945,18 +957,29 @@ class PixEditor extends Viewer {
this.setPaletteColor(1);
}
getPixel(x, y) {
var ofs = x+y*this.width;
return this.rgbdata[ofs];
getPixel(x:number, y:number) : number {
x = Math.round(x);
y = Math.round(y);
if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
return this.offscreen[x+','+y] | this.palette[0];
} else {
var ofs = x+y*this.width;
return this.rgbdata[ofs];
}
}
setPixel(x, y, rgba) {
if (x < 0 || x >= this.width || y < 0 || y >= this.height) return;
var ofs = x+y*this.width;
var oldrgba = this.rgbdata[ofs];
if (oldrgba != rgba) {
this.rgbdata[ofs] = rgba;
this.updateImage();
setPixel(x:number, y:number, rgba:number) : void {
x = Math.round(x);
y = Math.round(y);
if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
this.offscreen[x+','+y] = rgba;
} else {
var ofs = x+y*this.width;
var oldrgba = this.rgbdata[ofs];
if (oldrgba != rgba) {
this.rgbdata[ofs] = rgba;
this.updateImage();
}
}
}
@ -977,6 +1000,7 @@ class PixEditor extends Viewer {
}
commit() {
this.updateImage();
this.left.refreshLeft();
}
@ -1004,15 +1028,23 @@ class PixEditor extends Viewer {
return this.getPixel(xx, yy);
});
}
flipx() {
rotate90() {
this.rotate(90);
}
flipX() {
this.remapPixels((x,y) => {
return this.getPixel(this.width-1-x, y);
});
}
flipy() {
flipY() {
this.remapPixels((x,y) => {
return this.getPixel(x, this.height-1-y);
});
}
translate(dx:number, dy:number) {
this.remapPixels((x,y) => {
return this.getPixel(x+dx, y+dy);
});
}
}

View File

@ -8,6 +8,7 @@ import { hex, lpad, rpad, safeident, rgb2bgr } from "./util";
import { CodeAnalyzer } from "./analysis";
import { platform, platform_id, compparams, current_project, lastDebugState, projectWindows } from "./ui";
import * as pixed from "./pixed/pixeleditor";
declare var Mousetrap;
export interface ProjectView {
createDiv(parent:HTMLElement, text:string) : HTMLElement;
@ -25,6 +26,7 @@ export interface ProjectView {
clearErrors?() : void;
setTimingResult?(result:CodeAnalyzer) : void;
recreateOnResize? : boolean;
undoStep?() : void;
};
declare var CodeMirror;
@ -146,8 +148,8 @@ export class SourceEditor implements ProjectView {
var oldtext = this.editor.getValue();
if (oldtext != text) {
// find minimum range to undo
for (var i=0; i<oldtext.length && i<text.length && text[i] == oldtext[i]; i++) { }
for (var j=0; j<oldtext.length && j<text.length && text[text.length-1-j] == oldtext[oldtext.length-1-j]; j++) { }
for (i=0; i<oldtext.length && i<text.length && text[i] == oldtext[i]; i++) { }
for (j=0; j<oldtext.length && j<text.length && text[text.length-1-j] == oldtext[oldtext.length-1-j]; j++) { }
//console.log(i,j,oldtext.substring(i,oldtext.length-j));
this.replaceSelection(i, oldtext.length-j, text.substring(i, text.length-j)); // calls setCode()
// clear history if setting empty editor
@ -366,6 +368,9 @@ export class SourceEditor implements ProjectView {
return -1;
}
undoStep() {
this.editor.execCommand('undo');
}
}
///
@ -1203,7 +1208,7 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
var divid = this.getFileDivId(id);
var filediv = newDiv(this.maindiv, 'asset_file');
var header = newDiv(filediv, 'asset_file_header').text(id);
var body = newDiv(filediv).attr('id',divid);
var body = newDiv(filediv).attr('id',divid).addClass('disable-select');
try {
var nassets = this.refreshAssetsInFile(id, data);
if (nassets == 0) filediv.hide();
@ -1222,6 +1227,12 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
}
}
// TODO: scroll editors into view
setVisible?(showing : boolean) : void {
if (showing) {
Mousetrap.bind('ctrl+z', projectWindows.undoStep.bind(projectWindows));
} else {
Mousetrap.unbind('ctrl+z');
}
}
}

View File

@ -17,10 +17,12 @@ export class ProjectWindows {
activewnd : ProjectView;
activediv : HTMLElement;
lasterrors : WorkerError[];
undofiles : string[];
constructor(containerdiv:HTMLElement, project:CodeProject) {
this.containerdiv = containerdiv;
this.project = project;
this.undofiles = [];
}
// TODO: delete windows ever?
@ -123,6 +125,17 @@ export class ProjectWindows {
wnd.refresh(false);
}
}
this.undofiles.push(fileid);
}
undoStep() {
var fileid = this.undofiles.pop();
var wnd = this.id2window[fileid];
if (wnd && wnd.undoStep) {
wnd.undoStep();
} else {
alert("No more steps to undo.");
}
}
};

2
tss

@ -1 +1 @@
Subproject commit 61a1691a1de05dca3b694bf603db49ffbaf572cf
Subproject commit 5b5ee67fc06956bc7dce51726e98812d2d897eaa