mirror of
https://github.com/antos-rde/antosdk-apps.git
synced 2024-11-19 11:48:22 +01:00
update ShaderPlayground
This commit is contained in:
parent
916fd7b418
commit
52e24e9b2b
@ -4,4 +4,7 @@ Playground for working with Open GL shader language, the sharder is rendered
|
|||||||
with the Three.js library
|
with the Three.js library
|
||||||
|
|
||||||
## Change logs
|
## Change logs
|
||||||
|
- v0.0.2-a:
|
||||||
|
- Remove GLSLX, use the default WEBGL API for shader compiling
|
||||||
|
- Allow save/open shader source code to/from file (JSON)
|
||||||
- v0.0.1-a: Initial version
|
- v0.0.1-a: Initial version
|
@ -47,8 +47,7 @@
|
|||||||
"scheme.html",
|
"scheme.html",
|
||||||
"package.json",
|
"package.json",
|
||||||
"README.md",
|
"README.md",
|
||||||
"main.css",
|
"main.css"
|
||||||
"glslx.js"
|
|
||||||
],
|
],
|
||||||
"dest":"build/debug"
|
"dest":"build/debug"
|
||||||
}
|
}
|
||||||
@ -79,6 +78,20 @@
|
|||||||
"build and run": {
|
"build and run": {
|
||||||
"depend": ["clean", "build", "copy", "run"],
|
"depend": ["clean", "build", "copy", "run"],
|
||||||
"jobs": []
|
"jobs": []
|
||||||
|
},
|
||||||
|
"locale": {
|
||||||
|
"require": ["locale"],
|
||||||
|
"jobs": [
|
||||||
|
{
|
||||||
|
"name":"locale-gen",
|
||||||
|
"data": {
|
||||||
|
"src": "",
|
||||||
|
"exclude": ["build/"],
|
||||||
|
"locale": "en_GB",
|
||||||
|
"dest": "package.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,4 +4,7 @@ Playground for working with Open GL shader language, the sharder is rendered
|
|||||||
with the Three.js library
|
with the Three.js library
|
||||||
|
|
||||||
## Change logs
|
## Change logs
|
||||||
|
- v0.0.2-a:
|
||||||
|
- Remove GLSLX, use the default WEBGL API for shader compiling
|
||||||
|
- Allow save/open shader source code to/from file (JSON)
|
||||||
- v0.0.1-a: Initial version
|
- v0.0.1-a: Initial version
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,16 +1,42 @@
|
|||||||
{
|
{
|
||||||
"pkgname": "ShaderPlayground",
|
"pkgname": "ShaderPlayground",
|
||||||
"app":"ShaderPlayground",
|
"app": "ShaderPlayground",
|
||||||
"name":"OpenGL Shader Playground",
|
"name": "OpenGL Shader Playground",
|
||||||
"description":"OpenGL Shader Playground",
|
"description": "OpenGL Shader Playground",
|
||||||
"info":{
|
"info": {
|
||||||
"author": "Xuan Sang LE",
|
"author": "Xuan Sang LE",
|
||||||
"email": "mrsang@iohub.dev"
|
"email": "mrsang@iohub.dev"
|
||||||
},
|
},
|
||||||
"version":"0.0.1-a",
|
"version": "0.0.2-a",
|
||||||
"category":"Development",
|
"category": "Development",
|
||||||
"iconclass":"bi bi-lightbulb-fill",
|
"iconclass": "bi bi-lightbulb-fill",
|
||||||
"mimes":["none"],
|
"mimes": [
|
||||||
"dependencies":["libthreejs@0.0.129-r"],
|
"application/json"
|
||||||
"locale": {}
|
],
|
||||||
|
"dependencies": [
|
||||||
|
"libthreejs@0.0.129-r"
|
||||||
|
],
|
||||||
|
"locale": {},
|
||||||
|
"locales": {
|
||||||
|
"en_GB": {
|
||||||
|
"Name": "Name",
|
||||||
|
"Path/URL": "Path/URL",
|
||||||
|
"Ok": "Ok",
|
||||||
|
"Add texture": "Add texture",
|
||||||
|
"File": "File",
|
||||||
|
"New": "New",
|
||||||
|
"Open": "Open",
|
||||||
|
"Save": "Save",
|
||||||
|
"All fields should be filled": "All fields should be filled",
|
||||||
|
"Select image file": "Select image file",
|
||||||
|
"Unknown save path": "Unknown save path",
|
||||||
|
"Fragment": "Fragment",
|
||||||
|
"Vertex": "Vertex",
|
||||||
|
"Textures": "Textures",
|
||||||
|
"Unsaved shader": "Unsaved shader",
|
||||||
|
"Ignore unsaved file?": "Ignore unsaved file?",
|
||||||
|
"Open file": "Open file",
|
||||||
|
"Save as": "Save as"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -39,7 +39,6 @@ namespace OS {
|
|||||||
export namespace application {
|
export namespace application {
|
||||||
declare var ace: any;
|
declare var ace: any;
|
||||||
declare var THREE: any;
|
declare var THREE: any;
|
||||||
declare var GLSLX:any;
|
|
||||||
|
|
||||||
class AddTextureDialog extends GUI.BasicDialog
|
class AddTextureDialog extends GUI.BasicDialog
|
||||||
{
|
{
|
||||||
@ -106,20 +105,32 @@ namespace OS {
|
|||||||
|
|
||||||
class ShaderEditor
|
class ShaderEditor
|
||||||
{
|
{
|
||||||
|
static frg_template: string;
|
||||||
private ums: any[];
|
private ums: any[];
|
||||||
private glsl_values: string[];
|
private glsl_values: string[];
|
||||||
private cursors: any[];
|
private cursors: any[];
|
||||||
private editor: any;
|
private editor: any;
|
||||||
private current_idx: number;
|
private current_idx: number;
|
||||||
|
private editormux:boolean;
|
||||||
|
private gl_compiling_ctx: WebGLRenderingContext;
|
||||||
renderer: ShaderRenderer;
|
renderer: ShaderRenderer;
|
||||||
|
private tmp_canvas: HTMLCanvasElement;
|
||||||
|
private _filehandle: API.VFS.BaseFileHandle;
|
||||||
|
private _onfilechange: (t: string) => void;
|
||||||
|
private _ontextureadded: (data: GenericObject<any>) => void;
|
||||||
constructor(domel: HTMLElement, renderer: ShaderRenderer)
|
constructor(domel: HTMLElement, renderer: ShaderRenderer)
|
||||||
{
|
{
|
||||||
const empty_main = "void main(){}";
|
this.glsl_values = [ShaderEditor.frg_template, ""];
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
this.ums = [new ace.UndoManager(), new ace.UndoManager()];
|
this.ums = [new ace.UndoManager(), new ace.UndoManager()];
|
||||||
this.current_idx = -1;
|
this.current_idx = -1;
|
||||||
this.glsl_values = [empty_main, ""];
|
this.tmp_canvas = $("<canvas />")[0] as HTMLCanvasElement;
|
||||||
|
this.gl_compiling_ctx = this.tmp_canvas.getContext("webgl");
|
||||||
|
this._filehandle = undefined;
|
||||||
|
this.editormux = false;
|
||||||
ace.require("ace/ext/language_tools");
|
ace.require("ace/ext/language_tools");
|
||||||
|
this._onfilechange = (v) =>{};
|
||||||
|
this._ontextureadded = (t) => {};
|
||||||
this.editor = ace.edit(domel);
|
this.editor = ace.edit(domel);
|
||||||
this.editor.setOptions({
|
this.editor.setOptions({
|
||||||
enableBasicAutocompletion: true,
|
enableBasicAutocompletion: true,
|
||||||
@ -136,19 +147,23 @@ namespace OS {
|
|||||||
this.editor.getCursorPosition(),
|
this.editor.getCursorPosition(),
|
||||||
this.editor.getCursorPosition()
|
this.editor.getCursorPosition()
|
||||||
];
|
];
|
||||||
|
|
||||||
this.editor.on("input", (e) => {
|
this.editor.on("input", (e) => {
|
||||||
const value = this.editor.getValue();
|
const value = this.editor.getValue();
|
||||||
|
const stype = this.current_idx == 0 ? this.gl_compiling_ctx.FRAGMENT_SHADER: this.gl_compiling_ctx.VERTEX_SHADER;
|
||||||
const result = GLSLX.compile(value, {
|
const errors = this.compile(value, stype);
|
||||||
format: "json"
|
if(this.filehandle.dirty === false && !this.editormux)
|
||||||
});
|
{
|
||||||
if (result.output) {
|
this.filehandle.dirty = true;
|
||||||
this.editor.getSession().setAnnotations([]);
|
this._onfilechange(`${this.filehandle.path}*`);
|
||||||
this.glsl_values[this.current_idx] = value;
|
}
|
||||||
this.renderer.apply_mat(this.glsl_values[0],this.glsl_values[1]);
|
if(this.editormux)
|
||||||
} else {
|
{
|
||||||
const reg_str = "<stdin>:([0-9]+):([0-9]+):\\s*error:\\s*(.*)\\n";
|
this.editormux = false;
|
||||||
const matches = (result.log as string).match(new RegExp(reg_str, "g"));
|
}
|
||||||
|
if(errors) {
|
||||||
|
const reg_str = "ERROR:\\s*([0-9]+):([0-9]+):\\s*(.*)\\n";
|
||||||
|
const matches = errors.match(new RegExp(reg_str, "g"));
|
||||||
if(matches)
|
if(matches)
|
||||||
{
|
{
|
||||||
this.editor.getSession().setAnnotations(
|
this.editor.getSession().setAnnotations(
|
||||||
@ -158,8 +173,8 @@ namespace OS {
|
|||||||
if(err_data)
|
if(err_data)
|
||||||
{
|
{
|
||||||
ret = {
|
ret = {
|
||||||
row: parseInt(err_data[1]) - 1,
|
row: parseInt(err_data[2]) - 1,
|
||||||
column: parseInt(err_data[2]),
|
column: 0,
|
||||||
text: err_data[3],
|
text: err_data[3],
|
||||||
type: "error"
|
type: "error"
|
||||||
};
|
};
|
||||||
@ -169,9 +184,131 @@ namespace OS {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.editor.getSession().setAnnotations([]);
|
||||||
|
this.glsl_values[this.current_idx] = value;
|
||||||
|
this.renderer.apply_mat(this.glsl_values[0], this.glsl_values[1]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public set onfilechange(fn:(v: string) => void)
|
||||||
|
{
|
||||||
|
this._onfilechange = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set ontextureadded(fn:(v:GenericObject<any>)=> void)
|
||||||
|
{
|
||||||
|
this._ontextureadded = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set filehandle(v: API.VFS.BaseFileHandle)
|
||||||
|
{
|
||||||
|
this._filehandle = v;
|
||||||
|
this.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get filehandle(): API.VFS.BaseFileHandle
|
||||||
|
{
|
||||||
|
return this._filehandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
read() {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
if (this._filehandle === undefined) {
|
||||||
|
this.renderer.textures.length = 0;
|
||||||
|
this._filehandle = "Untitled".asFileHandle();
|
||||||
|
this._onfilechange(this._filehandle.path);
|
||||||
|
this.glsl_values = [ShaderEditor.frg_template, ""];
|
||||||
|
if(this.current_idx != 2 && this.current_idx != -1)
|
||||||
|
{
|
||||||
|
this.editormux = true;
|
||||||
|
this.editor.setValue(this.glsl_values[this.current_idx]);
|
||||||
|
}
|
||||||
|
this._ontextureadded(undefined);
|
||||||
|
return resolve(undefined);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const data = await this._filehandle.read("json");
|
||||||
|
this.glsl_values[0] = data.source[0];
|
||||||
|
this.glsl_values[1] = data.source[1];
|
||||||
|
if(this.current_idx != 2 && this.current_idx != -1)
|
||||||
|
{
|
||||||
|
this.editormux = true;
|
||||||
|
this.editor.setValue(this.glsl_values[this.current_idx]);
|
||||||
|
}
|
||||||
|
this._ontextureadded(undefined);
|
||||||
|
for(const v of data.textures)
|
||||||
|
{
|
||||||
|
this._ontextureadded(v);
|
||||||
|
}
|
||||||
|
this._onfilechange(this._filehandle.path);
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
write(p: string) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
let path = p;
|
||||||
|
const error = __("Unknown save path");
|
||||||
|
if(!path)
|
||||||
|
{
|
||||||
|
if(this._filehandle === undefined)
|
||||||
|
return reject(error);
|
||||||
|
path = this._filehandle.path;
|
||||||
|
}
|
||||||
|
if(path === "Untitled")
|
||||||
|
{
|
||||||
|
return reject(error);
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
this._filehandle.setPath(path);
|
||||||
|
const data = {} as GenericObject<any>;
|
||||||
|
if(this.current_idx != 2)
|
||||||
|
{
|
||||||
|
this.glsl_values[this.current_idx] = this.editor.getValue();
|
||||||
|
}
|
||||||
|
data.source = this.glsl_values;
|
||||||
|
data.textures = this.renderer.textures.map((v) => {
|
||||||
|
return {
|
||||||
|
name: v.name,
|
||||||
|
path: v.path
|
||||||
|
};
|
||||||
|
});
|
||||||
|
this.filehandle.cache = data;
|
||||||
|
const ret = await this.filehandle.write("object");
|
||||||
|
this._filehandle.dirty = false;
|
||||||
|
this._onfilechange(`${this.filehandle.path}`);
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private compile(code: string, type: number)
|
||||||
|
{
|
||||||
|
// Compiles either a shader of type gl.VERTEX_SHADER or gl.FRAGMENT_SHADER
|
||||||
|
let shader = this.gl_compiling_ctx.createShader( type );
|
||||||
|
this.gl_compiling_ctx.shaderSource( shader, code );
|
||||||
|
this.gl_compiling_ctx.compileShader( shader );
|
||||||
|
let errors: string = undefined;
|
||||||
|
if ( !this.gl_compiling_ctx.getShaderParameter(shader, this.gl_compiling_ctx.COMPILE_STATUS) ) {
|
||||||
|
errors = this.gl_compiling_ctx.getShaderInfoLog( shader );
|
||||||
|
}
|
||||||
|
this.gl_compiling_ctx.deleteShader(shader);
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
edit(index:number): void
|
edit(index:number): void
|
||||||
{
|
{
|
||||||
if(index < 0)
|
if(index < 0)
|
||||||
@ -185,7 +322,7 @@ namespace OS {
|
|||||||
this.glsl_values[1] = this.editor.getValue();
|
this.glsl_values[1] = this.editor.getValue();
|
||||||
this.cursors[1] = this.editor.getCursorPosition();
|
this.cursors[1] = this.editor.getCursorPosition();
|
||||||
}
|
}
|
||||||
else
|
else if(index === 1)
|
||||||
{
|
{
|
||||||
this.glsl_values[0] = this.editor.getValue();
|
this.glsl_values[0] = this.editor.getValue();
|
||||||
this.cursors[0] = this.editor.getCursorPosition();
|
this.cursors[0] = this.editor.getCursorPosition();
|
||||||
@ -199,6 +336,7 @@ namespace OS {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.current_idx = index;
|
this.current_idx = index;
|
||||||
|
this.editormux = true;
|
||||||
this.editor.getSession().setUndoManager(new ace.UndoManager());
|
this.editor.getSession().setUndoManager(new ace.UndoManager());
|
||||||
this.editor.setValue(this.glsl_values[index]);
|
this.editor.setValue(this.glsl_values[index]);
|
||||||
this.editor.getSession().setUndoManager(this.ums[index]);
|
this.editor.getSession().setUndoManager(this.ums[index]);
|
||||||
@ -220,6 +358,7 @@ namespace OS {
|
|||||||
cleanup(): void
|
cleanup(): void
|
||||||
{
|
{
|
||||||
this.renderer.cleanup();
|
this.renderer.cleanup();
|
||||||
|
$(this.tmp_canvas).remove();
|
||||||
}
|
}
|
||||||
resize(): void
|
resize(): void
|
||||||
{
|
{
|
||||||
@ -344,6 +483,19 @@ namespace OS {
|
|||||||
this.mesh.material = mat;
|
this.mesh.material = mat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShaderEditor.frg_template = `\
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
// uniform vec2 u_resolution;
|
||||||
|
// uniform vec2 u_mouse;
|
||||||
|
uniform float u_time;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = vec4(abs(sin(u_time)),0.0,0.0,1.0);
|
||||||
|
}\
|
||||||
|
`;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @class ShaderPlayground
|
* @class ShaderPlayground
|
||||||
@ -355,13 +507,21 @@ namespace OS {
|
|||||||
*/
|
*/
|
||||||
private tabbar: GUI.tag.TabBarTag;
|
private tabbar: GUI.tag.TabBarTag;
|
||||||
private editor: ShaderEditor;
|
private editor: ShaderEditor;
|
||||||
|
|
||||||
constructor(args: AppArgumentsType[]) {
|
constructor(args: AppArgumentsType[]) {
|
||||||
super("ShaderPlayground", args);
|
super("ShaderPlayground", args);
|
||||||
}
|
}
|
||||||
main(): void {
|
main(): void {
|
||||||
this.init_editor();
|
this.init_editor();
|
||||||
this.init_textures_list();
|
this.init_textures_list();
|
||||||
|
this.bindKey("ALT-N", () => {
|
||||||
|
return this.newFile();
|
||||||
|
});
|
||||||
|
this.bindKey("ALT-O", () => {
|
||||||
|
return this.openFile();
|
||||||
|
});
|
||||||
|
this.bindKey("CTRL-S", () => {
|
||||||
|
return this.saveFile();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -394,9 +554,38 @@ namespace OS {
|
|||||||
this.on("resize", (e) =>{
|
this.on("resize", (e) =>{
|
||||||
this.editor.resize();
|
this.editor.resize();
|
||||||
});
|
});
|
||||||
|
this.editor.onfilechange = (v: string) => {
|
||||||
|
(this.scheme as GUI.tag.WindowTag).apptitle = v;
|
||||||
|
};
|
||||||
|
this.editor.ontextureadded = (v: GenericObject<any>) =>
|
||||||
|
{
|
||||||
|
this.add_texture(v);
|
||||||
|
}
|
||||||
|
this.editor.filehandle = undefined;
|
||||||
this.tabbar.selected = 0;
|
this.tabbar.selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private add_texture(data: GenericObject<any>): void
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const listview = this.find("texture-list") as GUI.tag.ListViewTag;
|
||||||
|
if(!data)
|
||||||
|
{
|
||||||
|
this.editor.renderer.textures = [];
|
||||||
|
listview.data = this.editor.renderer.textures;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const loader = new THREE.TextureLoader();
|
||||||
|
const texture = loader.load(data.path.asFileHandle().getlink());
|
||||||
|
texture.minFilter = THREE.NearestFilter;
|
||||||
|
texture.magFilter = THREE.NearestFilter;
|
||||||
|
texture.wrapS = THREE.RepeatWrapping;
|
||||||
|
texture.wrapT = THREE.RepeatWrapping;
|
||||||
|
data.texture = texture;
|
||||||
|
listview.push(data);
|
||||||
|
this.editor.renderer.needupdateTexture = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
private init_textures_list(): void
|
private init_textures_list(): void
|
||||||
{
|
{
|
||||||
const listview = this.find("texture-list") as GUI.tag.ListViewTag;
|
const listview = this.find("texture-list") as GUI.tag.ListViewTag;
|
||||||
@ -404,24 +593,10 @@ namespace OS {
|
|||||||
{
|
{
|
||||||
text: "__(Add texture)",
|
text: "__(Add texture)",
|
||||||
iconclass: "bi bi-plus",
|
iconclass: "bi bi-plus",
|
||||||
onbtclick: (e) => {
|
onbtclick: (_e: any) => {
|
||||||
this
|
this
|
||||||
.openDialog(new AddTextureDialog())
|
.openDialog(new AddTextureDialog())
|
||||||
.then((data) => {
|
.then((data) => this.add_texture(data));
|
||||||
if(!data)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const loader = new THREE.TextureLoader();
|
|
||||||
const texture = loader.load(data.path.asFileHandle().getlink());
|
|
||||||
texture.minFilter = THREE.NearestFilter;
|
|
||||||
texture.magFilter = THREE.NearestFilter;
|
|
||||||
texture.wrapS = THREE.RepeatWrapping;
|
|
||||||
texture.wrapT = THREE.RepeatWrapping;
|
|
||||||
data.texture = texture;
|
|
||||||
listview.push(data);
|
|
||||||
this.editor.renderer.needupdateTexture = true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -430,7 +605,7 @@ namespace OS {
|
|||||||
this.editor.renderer.needupdateTexture = true;
|
this.editor.renderer.needupdateTexture = true;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
listview.data = this.editor.renderer.textures;
|
this.add_texture(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
private selectTab(): void
|
private selectTab(): void
|
||||||
@ -449,12 +624,124 @@ namespace OS {
|
|||||||
this.editor.edit(index);
|
this.editor.edit(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected cleanup(_e: any): void
|
menu() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
text: "__(File)",
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
text: "__(New)",
|
||||||
|
dataid: "new",
|
||||||
|
shortcut: 'A-N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "__(Open)",
|
||||||
|
dataid: "open",
|
||||||
|
shortcut: 'A-O'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "__(Save)",
|
||||||
|
dataid: "save",
|
||||||
|
shortcut: 'C-S'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
onchildselect: (e) => {
|
||||||
|
switch (e.data.item.data.dataid) {
|
||||||
|
case "new":
|
||||||
|
return this.newFile();
|
||||||
|
case "open":
|
||||||
|
return this.openFile();
|
||||||
|
case "save":
|
||||||
|
return this.saveFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private ignore_unsaved(): Promise<boolean>
|
||||||
{
|
{
|
||||||
|
return new Promise( async (resolve, reject) =>{
|
||||||
|
if(this.editor.filehandle.dirty === true)
|
||||||
|
{
|
||||||
|
const r = await this.ask({
|
||||||
|
title: __("Unsaved shader"),
|
||||||
|
text: __("Ignore unsaved file?")
|
||||||
|
});
|
||||||
|
if(!r)
|
||||||
|
{
|
||||||
|
return resolve(false);
|
||||||
|
}
|
||||||
|
return resolve(true);
|
||||||
|
}
|
||||||
|
return resolve(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private async newFile()
|
||||||
|
{
|
||||||
|
const ignore = await this.ignore_unsaved();
|
||||||
|
if(!ignore)
|
||||||
|
return;
|
||||||
|
this.editor.filehandle = undefined;
|
||||||
|
}
|
||||||
|
private async openFile() {
|
||||||
|
try{
|
||||||
|
const ignore = await this.ignore_unsaved();
|
||||||
|
if(!ignore)
|
||||||
|
return;
|
||||||
|
const d = await this.openDialog("FileDialog",{
|
||||||
|
title: __("Open file"),
|
||||||
|
mimes: this.meta().mimes
|
||||||
|
});
|
||||||
|
|
||||||
|
this.editor.filehandle.setPath(d.file.path);
|
||||||
|
await this.editor.read();
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
this.error(__(e.toString()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async saveFile() {
|
||||||
|
if (this.editor.filehandle.path !== "Untitled") {
|
||||||
|
return this.editor.write(undefined);
|
||||||
|
}
|
||||||
|
const f = await this.openDialog("FileDialog",{
|
||||||
|
title: __("Save as"),
|
||||||
|
file: this.editor.filehandle
|
||||||
|
});
|
||||||
|
let handle = f.file.path.asFileHandle();
|
||||||
|
if(f.file.type === "file") {
|
||||||
|
handle = handle.parent();
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
await this.editor.write(`${handle.path}/${f.name}`);
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
this.error(__(e.toString()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected cleanup(e: any): void
|
||||||
|
{
|
||||||
|
if(this.editor.filehandle.dirty)
|
||||||
|
{
|
||||||
|
this.ignore_unsaved()
|
||||||
|
.then((d) =>{
|
||||||
|
if(d)
|
||||||
|
{
|
||||||
|
this.editor.filehandle.dirty = false;
|
||||||
|
this.quit(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.editor.cleanup();
|
this.editor.cleanup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Application dependenicies preload
|
* Application dependenicies preload
|
||||||
*/
|
*/
|
||||||
|
@ -1,16 +1,42 @@
|
|||||||
{
|
{
|
||||||
"pkgname": "ShaderPlayground",
|
"pkgname": "ShaderPlayground",
|
||||||
"app":"ShaderPlayground",
|
"app": "ShaderPlayground",
|
||||||
"name":"OpenGL Shader Playground",
|
"name": "OpenGL Shader Playground",
|
||||||
"description":"OpenGL Shader Playground",
|
"description": "OpenGL Shader Playground",
|
||||||
"info":{
|
"info": {
|
||||||
"author": "Xuan Sang LE",
|
"author": "Xuan Sang LE",
|
||||||
"email": "mrsang@iohub.dev"
|
"email": "mrsang@iohub.dev"
|
||||||
},
|
},
|
||||||
"version":"0.0.1-a",
|
"version": "0.0.2-a",
|
||||||
"category":"Development",
|
"category": "Development",
|
||||||
"iconclass":"bi bi-lightbulb-fill",
|
"iconclass": "bi bi-lightbulb-fill",
|
||||||
"mimes":["none"],
|
"mimes": [
|
||||||
"dependencies":["libthreejs@0.0.129-r"],
|
"application/json"
|
||||||
"locale": {}
|
],
|
||||||
|
"dependencies": [
|
||||||
|
"libthreejs@0.0.129-r"
|
||||||
|
],
|
||||||
|
"locale": {},
|
||||||
|
"locales": {
|
||||||
|
"en_GB": {
|
||||||
|
"Name": "Name",
|
||||||
|
"Path/URL": "Path/URL",
|
||||||
|
"Ok": "Ok",
|
||||||
|
"Add texture": "Add texture",
|
||||||
|
"File": "File",
|
||||||
|
"New": "New",
|
||||||
|
"Open": "Open",
|
||||||
|
"Save": "Save",
|
||||||
|
"All fields should be filled": "All fields should be filled",
|
||||||
|
"Select image file": "Select image file",
|
||||||
|
"Unknown save path": "Unknown save path",
|
||||||
|
"Fragment": "Fragment",
|
||||||
|
"Vertex": "Vertex",
|
||||||
|
"Textures": "Textures",
|
||||||
|
"Unsaved shader": "Unsaved shader",
|
||||||
|
"Ignore unsaved file?": "Ignore unsaved file?",
|
||||||
|
"Open file": "Open file",
|
||||||
|
"Save as": "Save as"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -335,7 +335,7 @@
|
|||||||
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ShaderPlayground/README.md",
|
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ShaderPlayground/README.md",
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"author": "Xuan Sang LE",
|
"author": "Xuan Sang LE",
|
||||||
"version": "0.0.1-a",
|
"version": "0.0.2-a",
|
||||||
"dependencies": ["libthreejs@0.0.129-r"],
|
"dependencies": ["libthreejs@0.0.129-r"],
|
||||||
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ShaderPlayground/build/release/ShaderPlayground.zip"
|
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ShaderPlayground/build/release/ShaderPlayground.zip"
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user