correct more app

This commit is contained in:
Xuan Sang LE 2020-05-21 21:56:16 +02:00
parent 04225e74fb
commit d62bafae48
32 changed files with 710 additions and 383 deletions

View File

@ -1,4 +1,5 @@
(function() { (function() {
void 0;
var DataViewer, LuaPlayground, PointCloudViewer; var DataViewer, LuaPlayground, PointCloudViewer;
DataViewer = class DataViewer { DataViewer = class DataViewer {
@ -175,7 +176,7 @@
} }
// point clound render // point clound render
render() { render() {
var end, j, len, path, ref, start, v; var end, j, len, path, ref, start, v;
this.drawGrid(20, "#DBDBDB"); // 20 px this.drawGrid(20, "#DBDBDB"); // 20 px
@ -204,42 +205,44 @@
} }
main() { main() {
var me;
me = this;
this.datarea = this.find("editorea"); this.datarea = this.find("editorea");
this.output = this.find("output"); this.output = this.find("output");
this.editor = ace.edit(this.datarea); this.editor = ace.edit(this.datarea);
this.editor.setOptions({ this.editor.setOptions({
enableBasicAutocompletion: true, enableBasicAutocompletion: true,
enableLiveAutocompletion: true, enableLiveAutocompletion: true,
fontSize: "10pt" highlightActiveLine: true,
highlightSelectedWord: true,
behavioursEnabled: true,
wrap: true,
fontSize: "11pt",
showInvisibles: true
}); });
this.editor.getSession().setUseWrapMode(true); this.editor.getSession().setUseWrapMode(true);
this.editor.session.setMode("ace/mode/lua"); this.editor.session.setMode("ace/mode/lua");
this.editor.setTheme("ace/theme/monokai"); this.editor.setTheme("ace/theme/monokai");
this.on("vboxchange", function() { this.on("vboxchange", () => {
return me.editor.resize(); return this.editor.resize();
}); });
(this.find("log-clear")).set("onbtclick", function(e) { (this.find("log-clear")).set("onbtclick", (e) => {
return me.log("clean"); return this.log("clean");
}); });
(this.find("code-run")).set("onbtclick", function(e) { (this.find("code-run")).set("onbtclick", (e) => {
return me.run(); return this.run();
}); });
(this.find("code-stop")).set("onbtclick", function(e) { (this.find("code-stop")).set("onbtclick", (e) => {
if (me.socket) { if (this.socket) {
return me.socket.close(); return this.socket.close();
} }
}); });
this.socket = null; this.socket = null;
return this.bindKey("CTRL-R", function() { return this.bindKey("CTRL-R", () => {
return me.run(); return this.run();
}); });
} }
menu() { menu() {
var me, menu; var menu;
me = this;
menu = [ menu = [
{ {
text: "__(Code)", text: "__(Code)",
@ -250,8 +253,8 @@
shortcut: "C-R" shortcut: "C-R"
} }
], ],
onmenuselect: function(e) { onchildselect: (e) => {
return me.run(); return this.run();
} }
} }
]; ];
@ -270,39 +273,42 @@
} }
run() { run() {
var me, value; var value;
me = this;
value = this.editor.getValue().trim(); value = this.editor.getValue().trim();
if (!(value && value !== "")) { if (!(value && value !== "")) {
return; return;
} }
this.socket = this.stream(); return this.stream().then((s) => {
this.socket.onopen = function() { this.socket = s;
//send data to server this.socket.onopen = () => {
return me.socket.send(JSON.stringify({ //send data to server
code: value return this.socket.send(JSON.stringify({
})); code: value
}; }));
this.socket.onmessage = function(e) { };
var err, obj; this.socket.onmessage = (e) => {
if (!e.data) { var err, obj;
return; if (!e.data) {
} return;
try {
obj = JSON.parse(e.data);
if (!me.view(obj)) {
return me.log("INFO", e.data);
} }
} catch (error) { try {
err = error; obj = JSON.parse(e.data);
me.log("INFO", e.data); if (!this.view(obj)) {
return console.log(err); return this.log("INFO", e.data);
} }
}; } catch (error) {
return this.socket.onclose = function() { err = error;
me.socket = null; this.log("INFO", e.data);
return console.log("socket closed"); return console.log(err);
}; }
};
return this.socket.onclose = () => {
this.socket = null;
return console.log("socket closed");
};
}).catch((e) => {
return this.error(__("Unable to get websocket stream"));
});
} }
view(obj) { view(obj) {
@ -330,7 +336,7 @@
}; };
LuaPlayground.dependencies = ["ace/ace"]; LuaPlayground.dependencies = ["os://scripts/ace/ace.js"];
this.OS.register("LuaPlayground", LuaPlayground); this.OS.register("LuaPlayground", LuaPlayground);

Binary file not shown.

View File

@ -147,38 +147,41 @@ class LuaPlayground extends this.OS.GUI.BaseApplication
super "LuaPlayground", args super "LuaPlayground", args
main: () -> main: () ->
me = @
@datarea = @find "editorea" @datarea = @find "editorea"
@output = @find "output" @output = @find "output"
@.editor = ace.edit @datarea @.editor = ace.edit @datarea
@.editor.setOptions { @.editor.setOptions {
enableBasicAutocompletion: true, enableBasicAutocompletion: true,
enableLiveAutocompletion: true, enableLiveAutocompletion: true,
fontSize: "10pt" highlightActiveLine: true,
highlightSelectedWord: true,
behavioursEnabled: true,
wrap: true,
fontSize: "11pt",
showInvisibles: true
} }
@editor.getSession().setUseWrapMode true @editor.getSession().setUseWrapMode true
@editor.session.setMode "ace/mode/lua" @editor.session.setMode "ace/mode/lua"
@editor.setTheme "ace/theme/monokai" @editor.setTheme "ace/theme/monokai"
@on "vboxchange", () -> @on "vboxchange", () =>
me.editor.resize() @editor.resize()
(@find "log-clear").set "onbtclick", (e) -> (@find "log-clear").set "onbtclick", (e) =>
me.log "clean" @log "clean"
(@find "code-run").set "onbtclick", (e) -> (@find "code-run").set "onbtclick", (e) =>
me.run() @run()
(@find "code-stop").set "onbtclick", (e) -> (@find "code-stop").set "onbtclick", (e) =>
me.socket.close() if me.socket @socket.close() if @socket
@socket = null @socket = null
@bindKey "CTRL-R", () -> me.run() @bindKey "CTRL-R", () => @run()
menu: () -> menu: () ->
me = @
menu = [{ menu = [{
text: "__(Code)", text: "__(Code)",
child: [ child: [
{ text: "__(Run)", dataid: "#{@name}-Run", shortcut: "C-R" } { text: "__(Run)", dataid: "#{@name}-Run", shortcut: "C-R" }
], ],
onmenuselect: (e) -> me.run() onchildselect: (e) => @run()
}] }]
menu menu
@ -190,26 +193,27 @@ class LuaPlayground extends this.OS.GUI.BaseApplication
($ @output).scrollTop @output.scrollHeight ($ @output).scrollTop @output.scrollHeight
run: () -> run: () ->
me = @
value = @editor.getValue().trim() value = @editor.getValue().trim()
return unless value and value isnt "" return unless value and value isnt ""
@socket = @stream() @stream().then (s) =>
@socket.onopen = () -> @socket = s
#send data to server @socket.onopen = () =>
me.socket.send( JSON.stringify { code: value } ) #send data to server
@socket.send( JSON.stringify { code: value } )
@socket.onmessage = (e) ->
return unless e.data @socket.onmessage = (e) =>
try return unless e.data
obj = JSON.parse e.data try
me.log "INFO", e.data unless me.view obj obj = JSON.parse e.data
catch err @log "INFO", e.data unless @view obj
me.log "INFO", e.data catch err
console.log err @log "INFO", e.data
console.log err
@socket.onclose = () ->
me.socket = null @socket.onclose = () =>
console.log "socket closed" @socket = null
console.log "socket closed"
.catch (e) => @error __("Unable to get websocket stream")
view: (obj) -> view: (obj) ->
return false unless obj and obj.type and @[obj.type] return false unless obj and obj.type and @[obj.type]
@ -226,5 +230,5 @@ class LuaPlayground extends this.OS.GUI.BaseApplication
cleanup: (e)-> cleanup: (e)->
@socket.close() if @socket @socket.close() if @socket
LuaPlayground.dependencies = ["ace/ace"] LuaPlayground.dependencies = ["os://scripts/ace/ace.js"]
this.OS.register "LuaPlayground", LuaPlayground this.OS.register "LuaPlayground", LuaPlayground

View File

@ -1 +0,0 @@
{"name":"LuaPlayground","root":"home://myws/antosdk-apps/LuaPlayground","css":["css/main.css"],"javascripts":["javascripts/paper-core.min.js"],"coffees":["coffees/main.coffee"],"copies":["assets/scheme.html","package.json","README.md"]}

View File

@ -0,0 +1,8 @@
{
"name": "LuaPlayground",
"root": "home://workspace/antosdk-apps/LuaPlayground",
"css": ["css/main.css"],
"javascripts": ["javascripts/paper-core.min.js"],
"coffees": ["coffees/main.coffee"],
"copies": ["assets/scheme.html", "package.json", "README.md"]
}

View File

@ -1,24 +1,14 @@
# OpenPage ![](https://os.lxsang.me/repo/OpenPage/OpenPage.png)
This is an example project, generated by AntOS Development Kit # OpenPage: ODT (Open Document Text) editor alpha
**OpenPage** is an AntOS application developed in-browser using AntOSDK. It is a Pure Javascript based rich text editor compatible with Open Document Format.
## Howto **Feature:**
* Open, view and edit *.odt* documents
1. Open the project.apj file with AntOSDK (simply double Click on it) * Offer various formatting style to text
2. Modify the UI in *assets/scheme.html* * Define and apply paragraph styles
3. Modify application code in *coffees/main.coffee* * Insert link, image
4. Modify CSS style in *css/main.css* * Embeded fonts
5. Other files need to be copied: put in to assets * Save documents as ODF format so that it can be compatible with desktop applications like Open Office
## Set up build target **Credit:**
OpenPage is heavily based on the WebODF javascript library: https://webodf.org
Click **Menu> Build > Build Option** or simply hit **ALT-Y**
In the build options dialog, add or remove files that need to be
included into the build
Click **Save**
## Build application
* To build: **Menu > Build > Build** or **ALT-C**
* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
* To release: **Menu > Build > Build release** or **ALT-P**

View File

@ -1,14 +0,0 @@
![](https://os.lxsang.me/repo/OpenPage/OpenPage.png)
# OpenPage: ODT (Open Document Text) editor alpha
**OpenPage** is an AntOS application developed in-browser using AntOSDK. It is a Pure Javascript based rich text editor compatible with Open Document Format.
**Feature:**
* Open, view and edit *.odt* documents
* Offer various formatting style to text
* Define and apply paragraph styles
* Insert link, image
* Embeded fonts
* Save documents as ODF format so that it can be compatible with desktop applications like Open Office
**Credit:**
OpenPage is heavily based on the WebODF javascript library: https://webodf.org

File diff suppressed because one or more lines are too long

View File

@ -66,6 +66,7 @@ class OpenPage extends this.OS.GUI.BaseApplication
newdoc: () -> newdoc: () ->
blank = "#{@meta().path}/blank.odt" blank = "#{@meta().path}/blank.odt"
@open blank, true @open blank, true
open: (p,b) -> open: (p,b) ->
me = @ me = @
@pathAsDataURL(p) @pathAsDataURL(p)

View File

@ -1 +0,0 @@
{"name":"OpenPage","root":"home://workspace/OpenPage","css":["css/main.css","css/dialog.css"],"javascripts":["javascripts/webodf.js","javascripts/EditorSession.js"],"coffees":["coffees/main.coffee","coffees/dialogs.coffee"],"copies":["assets/scheme.html","package.json","assets/OpenPage.md","assets/icon.png","assets/blank.odt"]}

8
OpenPage/project.json Normal file
View File

@ -0,0 +1,8 @@
{
"name": "OpenPage",
"root": "home://workspace/antosdk-apps/OpenPage",
"css": ["css/main.css", "css/dialog.css"],
"javascripts": ["javascripts/webodf.js", "javascripts/EditorSession.js"],
"coffees": ["coffees/main.coffee", "coffees/dialogs.coffee"],
"copies": ["assets/scheme.html", "package.json", "assets/icon.png", "assets/blank.odt"]
}

View File

@ -8,20 +8,26 @@ afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div[data-i
background-repeat: repeat; background-repeat: repeat;
} }
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div[data-id = "status"] afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] afx-hbox[data-id = "statcontainer"]
{ {
background-color: transparent; background-color: transparent;
border-top: 1px solid #cbcbcb; border-bottom: 1px solid #cbcbcb;
padding-left: 10px; }
padding-top: 3px; afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] afx-hbox[data-id = "statcontainer"] button,
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] afx-hbox[data-id = "statcontainer"] input
{
height: 24px;
} }
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] canvas{ afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] canvas{
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
display: block; display: block;
} }
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div.pdf-page {
margin-bottom: 5px;
}
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div[data-id = "view"].image afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div[data-id = "view"].image
{ {
display: flex; display: flex;

View File

@ -25,18 +25,62 @@
} }
main() { main() {
this.currfile = void 0;
if (this.args && this.args.length > 0) { if (this.args && this.args.length > 0) {
this.currfile = this.args[0].path.asFileHandle(); this.currfile = this.args[0].path.asFileHandle();
} }
this.view = this.find("view"); this.view = this.find("view");
this.status = this.find("status"); this.status = this.find("status");
this.zoom = this.find("zoom");
this.btnext = this.find("btnext");
this.btprev = this.find("btprev");
this.btreset = this.find("btreset");
this.txtpage = this.find("txtpage");
this.zoom.set("onchange", (e) => {
return this.setViewScale(e.data);
});
this.btreset.set("onbtclick", (e) => {
this.zoom.set("value", 100);
return this.setViewScale(100);
});
this.btnext.set("onbtclick", (e) => {
var val;
val = parseInt($(this.txtpage).val());
if (isNaN(val)) {
return;
}
$(this.txtpage).val(val + 1);
return this.gotoPage();
});
this.btprev.set("onbtclick", (e) => {
var val;
val = parseInt($(this.txtpage).val());
if (isNaN(val)) {
return;
}
$(this.txtpage).val(val - 1);
return this.gotoPage();
});
$(this.txtpage).keyup((e) => {
if (e.which !== 13) {
return;
}
if (!this.pdf) {
return;
}
return this.gotoPage();
});
PDFJS.workerSrc = `${this.path()}/pdf.worker.js`.asFileHandle().getlink(); PDFJS.workerSrc = `${this.path()}/pdf.worker.js`.asFileHandle().getlink();
this.pdf = void 0;
this.img = void 0;
this.bindKey("ALT-O", () => { this.bindKey("ALT-O", () => {
return this.actionFile(`${this.name}-Open`); return this.actionFile(`${this.name}-Open`);
}); });
this.bindKey("CTRL-X", () => { this.bindKey("CTRL-X", () => {
return this.actionFile(`${this.name}-Close`); return this.actionFile(`${this.name}-Close`);
}); });
this.zoom.set("max", 200);
this.zoom.set("value", 100);
return this.open(this.currfile); return this.open(this.currfile);
} }
@ -49,25 +93,46 @@
} }
return file.onready().then(() => { return file.onready().then(() => {
file.info.size = (file.info.size / 1024).toFixed(2); file.info.size = (file.info.size / 1024).toFixed(2);
return this.renderFile(file); return this.renderFile();
}).catch((err) => { }).catch((err) => {
return this.error(__("File not found {0}", file.path), err); return this.error(__("File not found {0}", file.path), err);
}); });
} }
renderFile(file) { gotoPage() {
var mime; var val;
mime = file.info.mime; if (!this.pdf) {
if (!mime) { return;
}
val = parseInt($(this.txtpage).val());
if (isNaN(val)) {
return;
}
if (val <= 0 || val > this.pdf.numPages) {
return; return;
} }
($(this.view)).empty(); ($(this.view)).empty();
return this.renderPDFPages(val, this.zoom.get("value") / 100, false).catch((e) => {
return this.error(__("Unable to render page {0}", val), e);
});
}
renderFile() {
var mime;
mime = this.currfile.info.mime;
if (!mime) {
return;
}
this.pdf = void 0;
this.img = void 0;
($(this.view)).empty();
this.zoom.set("value", 100);
if (mime.match(/^[^\/]+\/.*pdf.*/g)) { if (mime.match(/^[^\/]+\/.*pdf.*/g)) {
return this.renderPDF(file); return this.renderPDF();
} else if (mime.match(/image\/.*svg.*/g)) { } else if (mime.match(/image\/.*svg.*/g)) {
return this.renderSVG(file); return this.renderSVG();
} else if (mime.match(/image\/.*/g)) { } else if (mime.match(/image\/.*/g)) {
return this.renderImage(file); return this.renderImage();
} else { } else {
return this.notify(__("Mime type {0} is not supported", file.info.mime)); return this.notify(__("Mime type {0} is not supported", file.info.mime));
} }
@ -77,44 +142,92 @@
return ($(this.status)).html(t); return ($(this.status)).html(t);
} }
renderPDF(file) { setViewScale(value) {
return this.load(new Promise((resolve, reject) => { var canvas, context, h, mime, scale, w;
if (!this.currfile) {
return;
}
mime = this.currfile.info.mime;
scale = value / 100;
if (mime.match(/^[^\/]+\/.*pdf.*/g)) {
if (!this.pdf) {
return;
}
($(this.view)).empty();
return this.load(this.renderPDFPages(1, scale)).catch((e) => {
return this.error(__("Unable to set view scale"), e);
});
} else if (mime.match(/image\/.*svg.*/g)) {
return $($(this.view).children()[0]).css("width", `${Math.round(value)}%`).css("height", `${Math.round(value)}%`);
} else if (mime.match(/image\/.*/g)) {
if (!this.img) {
return;
}
canvas = $(this.view).children()[0];
context = canvas.getContext('2d');
w = this.img.width * scale;
h = this.img.height * scale;
canvas.height = h;
canvas.width = w;
context.clearRect(0, 0, canvas.width, canvas.height);
context.scale(scale, scale);
return context.drawImage(this.img, 0, 0);
}
}
renderPDFPages(n, scale, recursive) {
return new Promise((resolve, reject) => {
var status; var status;
status = `${file.info.name} (${file.info.size} Kb)`; status = `${this.currfile.info.name} (${this.currfile.info.size} Kb)`;
return file.read("binary").then((d) => { if (n > this.pdf.numPages) {
return resolve();
}
return this.pdf.getPage(n).then((page) => {
var canvas, context, div, renderContext, viewport;
viewport = page.getViewport(scale);
div = ($("<div/>")).attr("id", "page-" + (page.pageIndex + 1)).attr("scale", scale).addClass("pdf-page");
($(this.view)).append(div);
canvas = ($("<canvas>"))[0];
div.append(canvas);
context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
page._canvas = canvas;
this.setStatus(`${status} - page ${n}/${this.pdf.numPages} loaded`);
if (recursive) {
return this.renderPDFPages(n + 1, scale, recursive).then(function() {
return resolve();
}).catch(function(e) {
return reject(e);
});
} else {
return resolve();
}
}).catch(function(e) {
return reject(e);
});
});
}
renderPDF() {
return this.load(new Promise((resolve, reject) => {
return this.currfile.read("binary").then((d) => {
($(this.view)).removeClass(); ($(this.view)).removeClass();
return PDFJS.getDocument({ return PDFJS.getDocument({
data: d data: d
}).then((pdf) => { }).then((pdf) => {
var fn; this.pdf = pdf;
fn = (p) => { return this.renderPDFPages(1, 1, false).then(() => {
if (p > pdf.numPages) { $(this.txtpage).val("1");
this.setStatus(`${status} - loaded`); return resolve();
return resolve(); }).catch(function(e) {
} return reject(e);
return pdf.getPage(p).then((page) => { });
var canvas, context, div, renderContext, scale, viewport;
scale = 1.5;
viewport = page.getViewport(scale);
div = ($("<div/>")).attr("id", "page-" + (page.pageIndex + 1));
($(this.view)).append(div);
canvas = ($("<canvas>"))[0];
div.append(canvas);
context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
this.setStatus(`${status} - ${p}/${pdf.numPages} loaded`);
return fn(p + 1);
}).catch(function(e) {
return reject(e);
});
};
return fn(1);
}).catch(function(e) { }).catch(function(e) {
return reject(e); return reject(e);
}); });
@ -122,23 +235,23 @@
return reject(e); return reject(e);
}); });
})).catch((e) => { })).catch((e) => {
return this.error(__("Unable to view file: {}", file.path), e); return this.error(__("Unable to view file: {0}", this.currfile.path), e);
}); });
} }
renderSVG(file) { renderSVG() {
($(this.view)).attr("class", "image"); ($(this.view)).attr("class", "image");
return file.read().then((d) => { return this.currfile.read().then((d) => {
this.view.innerHTML = d; this.view.innerHTML = d;
return $($(this.view).children()[0]).css("width", "100%").css("height", "100%"); return $($(this.view).children()[0]).css("width", "100%").css("height", "100%");
}).catch((e) => { }).catch((e) => {
return this.error(__("Unable to read file: {}", file.path), e); return this.error(__("Unable to read file: {0}", this.currfile.path), e);
}); });
} }
renderImage(file) { renderImage() {
($(this.view)).attr("class", "image"); ($(this.view)).attr("class", "image");
return file.read("binary").then((d) => { return this.currfile.read("binary").then((d) => {
var blob, canvas, img; var blob, canvas, img;
img = new Image(); img = new Image();
canvas = ($("<canvas/>"))[0]; canvas = ($("<canvas/>"))[0];
@ -149,16 +262,17 @@
context = canvas.getContext('2d'); context = canvas.getContext('2d');
canvas.height = img.height; canvas.height = img.height;
canvas.width = img.width; canvas.width = img.width;
this.img = img;
//console.log canvas.width, canvas.height //console.log canvas.width, canvas.height
context.drawImage(img, 0, 0); context.drawImage(img, 0, 0);
return this.setStatus(`${file.info.name} (${file.info.size} Kb) - ${img.width}x${img.height}`); return this.setStatus(`${this.currfile.info.name} (${this.currfile.info.size} Kb) - ${img.width}x${img.height}`);
}; };
blob = new Blob([d], { blob = new Blob([d], {
type: file.info.mime type: this.currfile.info.mime
}); });
return img.src = URL.createObjectURL(blob); return img.src = URL.createObjectURL(blob);
}).catch((e) => { }).catch((e) => {
return this.error(__("Unable to read file: {}", file.path), e); return this.error(__("Unable to read file: {0}", this.currfile.path), e);
}); });
} }

View File

@ -6,7 +6,7 @@
"author": "Xuan Sang LE", "author": "Xuan Sang LE",
"email": "xsang.le@gmail.com" "email": "xsang.le@gmail.com"
}, },
"version":"0.0.2-a", "version":"0.0.3-a",
"category":"Utils", "category":"Utils",
"iconclass":"fa fa-eye", "iconclass":"fa fa-eye",
"mimes":["[^\/]*/.*pdf", "image/.*"] "mimes":["[^\/]*/.*pdf", "image/.*"]

View File

@ -1,6 +1,17 @@
<afx-app-window data-id = "preview-win" apptitle="Preview" width="600" height="400"> <afx-app-window data-id = "preview-win" apptitle="Preview" width="600" height="400">
<afx-vbox data-id = "container"> <afx-vbox data-id = "container">
<afx-hbox data-height = "25" data-id = "statcontainer" >
<div data-width = "5" ></div>
<afx-button data-width="20" iconclass="fa fa-chevron-left" data-id="btprev"></afx-button>
<input type="text" data-width="30" data-id="txtpage" />
<afx-button data-width="20" iconclass="fa fa-chevron-right" data-id="btnext"></afx-button>
<div data-width = "5" ></div>
<afx-button data-width="20" iconclass="fa fa-arrows-alt" data-id="btreset"></afx-button>
<div data-width = "5" ></div>
<afx-slider data-width="150" data-id="zoom" ></afx-slider>
<div data-id = "status" style="text-align: right;"></div>
<div data-width = "10" ></div>
</afx-hbox>
<div data-id="view" ></div> <div data-id="view" ></div>
<div data-id = "status" data-height = "20"></div>
</afx-vbox> </afx-vbox>
</afx-app-window> </afx-app-window>

Binary file not shown.

View File

@ -21,14 +21,46 @@ class Preview extends this.OS.GUI.BaseApplication
super "Preview", args super "Preview", args
main: () -> main: () ->
@currfile = undefined
@currfile = @args[0].path.asFileHandle() if @args and @args.length > 0 @currfile = @args[0].path.asFileHandle() if @args and @args.length > 0
@view = @find "view" @view = @find "view"
@status = @find "status" @status = @find "status"
@zoom = @find "zoom"
@btnext = @find "btnext"
@btprev = @find "btprev"
@btreset = @find "btreset"
@txtpage = @find "txtpage"
@zoom.set "onchange", (e) => @setViewScale e.data
@btreset.set "onbtclick", (e) =>
@zoom.set "value", 100
@setViewScale 100
@btnext.set "onbtclick", (e) =>
val = parseInt $(@txtpage).val()
return if isNaN val
$(@txtpage).val val + 1
@gotoPage()
@btprev.set "onbtclick", (e) =>
val = parseInt $(@txtpage).val()
return if isNaN val
$(@txtpage).val val - 1
@gotoPage()
$(@txtpage).keyup (e) =>
return unless e.which is 13
return unless @pdf
@gotoPage()
PDFJS.workerSrc = "#{@path()}/pdf.worker.js".asFileHandle().getlink() PDFJS.workerSrc = "#{@path()}/pdf.worker.js".asFileHandle().getlink()
@pdf = undefined
@img = undefined
@bindKey "ALT-O", () => @actionFile "#{@name}-Open" @bindKey "ALT-O", () => @actionFile "#{@name}-Open"
@bindKey "CTRL-X", () => @actionFile "#{@name}-Close" @bindKey "CTRL-X", () => @actionFile "#{@name}-Close"
@zoom.set "max", 200
@zoom.set "value", 100
@open @currfile @open @currfile
@ -37,72 +69,125 @@ class Preview extends this.OS.GUI.BaseApplication
@currfile = file unless @currfile is file @currfile = file unless @currfile is file
file.onready().then () => file.onready().then () =>
file.info.size = (file.info.size / 1024).toFixed(2) file.info.size = (file.info.size / 1024).toFixed(2)
@renderFile file @renderFile()
.catch (err) => .catch (err) =>
@error __("File not found {0}", file.path), err @error __("File not found {0}", file.path), err
renderFile: (file) ->
mime = file.info.mime gotoPage: () ->
return unless mime return unless @pdf
val = parseInt $(@txtpage).val()
return if isNaN(val)
return if val <= 0 or val > @pdf.numPages
($ @view).empty() ($ @view).empty()
@renderPDFPages val, (@zoom.get("value") / 100), false
.catch (e) => @error __("Unable to render page {0}", val), e
renderFile: () ->
mime = @currfile.info.mime
return unless mime
@pdf = undefined
@img = undefined
($ @view).empty()
@zoom.set "value", 100
if mime.match /^[^\/]+\/.*pdf.*/g if mime.match /^[^\/]+\/.*pdf.*/g
@renderPDF file @renderPDF()
else if mime.match /image\/.*svg.*/g else if mime.match /image\/.*svg.*/g
@renderSVG file @renderSVG()
else if mime.match /image\/.*/g else if mime.match /image\/.*/g
@renderImage file @renderImage()
else else
@notify __("Mime type {0} is not supported", file.info.mime) @notify __("Mime type {0} is not supported", file.info.mime)
setStatus: (t) -> setStatus: (t) ->
($ @status).html t ($ @status).html t
renderPDF: (file) -> setViewScale: (value) ->
return unless @currfile
mime = @currfile.info.mime
scale = (value / 100)
if mime.match /^[^\/]+\/.*pdf.*/g
return unless @pdf
($ @view).empty()
@load @renderPDFPages 1, scale
.catch (e) => @error __("Unable to set view scale"), e
else if mime.match /image\/.*svg.*/g
$($(@view).children()[0])
.css "width", "#{Math.round(value)}%"
.css "height", "#{Math.round(value)}%"
else if mime.match /image\/.*/g
return unless @img
canvas = $(@view).children()[0]
context = canvas.getContext '2d'
w = @img.width * scale
h = @img.height * scale
canvas.height = h
canvas.width = w
context.clearRect(0, 0, canvas.width, canvas.height)
context.scale scale, scale
context.drawImage @img, 0, 0
renderPDFPages: (n, scale, recursive) ->
new Promise (resolve, reject) =>
status = "#{@currfile.info.name} (#{@currfile.info.size} Kb)"
return resolve() if n > @pdf.numPages
@pdf.getPage(n).then (page) =>
viewport = page.getViewport scale
div = ($ "<div/>")
.attr("id", "page-" + (page.pageIndex + 1))
.attr("scale", scale)
.addClass "pdf-page"
($ @view).append div
canvas = ($ "<canvas>")[0]
div.append canvas
context = canvas.getContext '2d'
canvas.height = viewport.height
canvas.width = viewport.width
renderContext =
canvasContext: context
viewport: viewport
page.render renderContext
page._canvas = canvas
@setStatus "#{status} - page #{n}/#{@pdf.numPages} loaded"
if recursive
@renderPDFPages n + 1, scale, recursive
.then () -> resolve()
.catch (e) -> reject e
else
resolve()
.catch (e) -> reject e
renderPDF: () ->
@load new Promise (resolve, reject) => @load new Promise (resolve, reject) =>
status = "#{file.info.name} (#{file.info.size} Kb)" @currfile.read("binary").then (d) =>
file.read("binary").then (d) =>
($ @view).removeClass() ($ @view).removeClass()
PDFJS.getDocument { data: d } PDFJS.getDocument { data: d }
.then (pdf) => .then (pdf) =>
fn = (p) => @pdf = pdf
if p > pdf.numPages @renderPDFPages 1, 1, false
@setStatus "#{status} - loaded" .then () =>
return resolve() $(@txtpage).val("1")
pdf.getPage(p).then (page) => resolve()
scale = 1.5
viewport = page.getViewport scale
div = ($ "<div/>").attr("id", "page-" + (page.pageIndex + 1))
($ @view).append div
canvas = ($ "<canvas>")[0]
div.append canvas
context = canvas.getContext '2d'
canvas.height = viewport.height
canvas.width = viewport.width
renderContext =
canvasContext: context
viewport: viewport
page.render renderContext
@setStatus "#{status} - #{p}/#{pdf.numPages} loaded"
fn(p+1)
.catch (e) -> reject e .catch (e) -> reject e
fn(1)
.catch (e) -> reject e .catch (e) -> reject e
.catch (e) -> reject e .catch (e) -> reject e
.catch (e) => @error __("Unable to view file: {}", file.path), e .catch (e) => @error __("Unable to view file: {0}", @currfile.path), e
renderSVG: (file) -> renderSVG: () ->
($ @view).attr("class", "image") ($ @view).attr("class", "image")
file.read().then (d) => @currfile.read().then (d) =>
@view.innerHTML = d @view.innerHTML = d
$($(@view).children()[0]) $($(@view).children()[0])
.css "width", "100%" .css "width", "100%"
.css "height", "100%" .css "height", "100%"
.catch (e) => @error __("Unable to read file: {}", file.path), e .catch (e) => @error __("Unable to read file: {0}", @currfile.path), e
renderImage: (file) -> renderImage: () ->
($ @view).attr("class", "image") ($ @view).attr("class", "image")
file.read("binary").then (d) => @currfile.read("binary").then (d) =>
img = new Image() img = new Image()
canvas = ($ "<canvas/>")[0] canvas = ($ "<canvas/>")[0]
($ @view).append canvas ($ @view).append canvas
@ -112,13 +197,14 @@ class Preview extends this.OS.GUI.BaseApplication
context = canvas.getContext '2d' context = canvas.getContext '2d'
canvas.height = img.height canvas.height = img.height
canvas.width = img.width canvas.width = img.width
@img = img
#console.log canvas.width, canvas.height #console.log canvas.width, canvas.height
context.drawImage img, 0, 0 context.drawImage img, 0, 0
@setStatus "#{file.info.name} (#{file.info.size} Kb) - #{img.width}x#{img.height}" @setStatus "#{@currfile.info.name} (#{@currfile.info.size} Kb) - #{img.width}x#{img.height}"
blob = new Blob [d], { type: file.info.mime } blob = new Blob [d], { type: @currfile.info.mime }
img.src = URL.createObjectURL blob img.src = URL.createObjectURL blob
.catch (e) => @error __("Unable to read file: {}", file.path), e .catch (e) => @error __("Unable to read file: {0}", @currfile.path), e
menu: () -> menu: () ->
menu = [{ menu = [{

View File

@ -7,20 +7,26 @@ afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div[data-i
background-repeat: repeat; background-repeat: repeat;
} }
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div[data-id = "status"] afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] afx-hbox[data-id = "statcontainer"]
{ {
background-color: transparent; background-color: transparent;
border-top: 1px solid #cbcbcb; border-bottom: 1px solid #cbcbcb;
padding-left: 10px; }
padding-top: 3px; afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] afx-hbox[data-id = "statcontainer"] button,
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] afx-hbox[data-id = "statcontainer"] input
{
height: 24px;
} }
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] canvas{ afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] canvas{
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
display: block; display: block;
} }
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div.pdf-page {
margin-bottom: 5px;
}
afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div[data-id = "view"].image afx-app-window[data-id = "preview-win"] afx-vbox[data-id="container"] div[data-id = "view"].image
{ {
display: flex; display: flex;

View File

@ -6,7 +6,7 @@
"author": "Xuan Sang LE", "author": "Xuan Sang LE",
"email": "xsang.le@gmail.com" "email": "xsang.le@gmail.com"
}, },
"version":"0.0.2-a", "version":"0.0.3-a",
"category":"Utils", "category":"Utils",
"iconclass":"fa fa-eye", "iconclass":"fa fa-eye",
"mimes":["[^\/]*/.*pdf", "image/.*"] "mimes":["[^\/]*/.*pdf", "image/.*"]

View File

@ -1,6 +1,17 @@
<afx-app-window data-id = "preview-win" apptitle="Preview" width="600" height="400"> <afx-app-window data-id = "preview-win" apptitle="Preview" width="600" height="400">
<afx-vbox data-id = "container"> <afx-vbox data-id = "container">
<afx-hbox data-height = "25" data-id = "statcontainer" >
<div data-width = "5" ></div>
<afx-button data-width="20" iconclass="fa fa-chevron-left" data-id="btprev"></afx-button>
<input type="text" data-width="30" data-id="txtpage" />
<afx-button data-width="20" iconclass="fa fa-chevron-right" data-id="btnext"></afx-button>
<div data-width = "5" ></div>
<afx-button data-width="20" iconclass="fa fa-arrows-alt" data-id="btreset"></afx-button>
<div data-width = "5" ></div>
<afx-slider data-width="150" data-id="zoom" ></afx-slider>
<div data-id = "status" style="text-align: right;"></div>
<div data-width = "10" ></div>
</afx-hbox>
<div data-id="view" ></div> <div data-id="view" ></div>
<div data-id = "status" data-height = "20"></div>
</afx-vbox> </afx-vbox>
</afx-app-window> </afx-app-window>

View File

@ -1,24 +1,3 @@
# TinyEditor # TinyEditor
This is the example project for the tutorial: [https://blog.lxsang.me/post/id/20](https://blog.lxsang.me/post/id/20) This is the example project for the tutorial: [https://blog.lxsang.me/post/id/20](https://blog.lxsang.me/post/id/20)
## Howto
1. Open the project.apj file with AntOSDK (simply double Click on it)
2. Modify the UI in *assets/scheme.html*
3. Modify application code in *coffees/main.coffee*
4. Modify CSS style in *css/main.css*
5. Other files need to be copied: put in to assets
## Set up build target
Click **Menu> Build > Build Option** or simply hit **ALT-Y**
In the build options dialog, add or remove files that need to be
included into the build
Click **Save**
## Build application
* To build: **Menu > Build > Build** or **ALT-C**
* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
* To release: **Menu > Build > Build release** or **ALT-P**

View File

@ -1,24 +1,3 @@
# TinyEditor # TinyEditor
This is the example project for the tutorial: [https://blog.lxsang.me/post/id/20](https://blog.lxsang.me/post/id/20) This is the example project for the tutorial: [https://blog.lxsang.me/post/id/20](https://blog.lxsang.me/post/id/20)
## Howto
1. Open the project.apj file with AntOSDK (simply double Click on it)
2. Modify the UI in *assets/scheme.html*
3. Modify application code in *coffees/main.coffee*
4. Modify CSS style in *css/main.css*
5. Other files need to be copied: put in to assets
## Set up build target
Click **Menu> Build > Build Option** or simply hit **ALT-Y**
In the build options dialog, add or remove files that need to be
included into the build
Click **Save**
## Build application
* To build: **Menu > Build > Build** or **ALT-C**
* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
* To release: **Menu > Build > Build release** or **ALT-P**

View File

@ -1,8 +1,6 @@
afx-app-window[data-id="TinyEditor"] textarea[data-id="editor"] afx-app-window[data-id="TinyEditor"] textarea[data-id="editor"]
{ {
background-color: #272822;
color:white;
margin: 0; margin: 0;
padding:10px; padding:10px;
border: 0; border: 0;

View File

@ -1,4 +1,5 @@
(function() { (function() {
void 0;
var TinyEditor; var TinyEditor;
TinyEditor = class TinyEditor extends this.OS.GUI.BaseApplication { TinyEditor = class TinyEditor extends this.OS.GUI.BaseApplication {
@ -7,32 +8,29 @@
} }
main() { main() {
var me;
me = this;
this.editor = this.find("editor"); this.editor = this.find("editor");
this.bindKey("ALT-N", function() { this.bindKey("ALT-N", () => {
return me.newFile(); return this.newFile();
}); });
this.bindKey("ALT-O", function() { this.bindKey("ALT-O", () => {
return me.openFile(); return this.openFile();
}); });
this.bindKey("CTRL-S", function() { this.bindKey("CTRL-S", () => {
return me.saveFile(); return this.saveFile();
}); });
this.filehandler = this.args && this.args.length > 0 ? this.args[0].asFileHandler() : null; this.filehandle = this.args && this.args.length > 0 ? this.args[0].asFileHandle() : null;
$(this.editor).on('input', function(e) { $(this.editor).on('input', (e) => {
if (me.filehandler.dirty === true) { if (this.filehandle.dirty === true) {
return; return;
} }
me.filehandler.dirty = true; this.filehandle.dirty = true;
return me.scheme.set("apptitle", `${me.filehandler.path}*`); return this.scheme.set("apptitle", `${this.filehandle.path}*`);
}); });
return this.read(); return this.read();
} }
menu() { menu() {
var m, me; var m;
me = this;
m = [ m = [
{ {
text: "__(File)", text: "__(File)",
@ -53,14 +51,14 @@
shortcut: 'C-S' shortcut: 'C-S'
} }
], ],
onmenuselect: function(e) { onchildselect: (e) => {
switch (e.item.data.dataid) { switch (e.data.item.get("data").dataid) {
case "new": case "new":
return me.newFile(); return this.newFile();
case "open": case "open":
return me.openFile(); return this.openFile();
case "save": case "save":
return me.saveFile(); return this.saveFile();
} }
} }
} }
@ -69,71 +67,73 @@
} }
newFile() { newFile() {
this.filehandler = null; this.filehandle = null;
return this.read(); return this.read();
} }
openFile() { openFile() {
var me; return this.openDialog("FileDialog", {
me = this; title: __("Open file")
return this.openDialog("FileDiaLog", function(dir, fname, d) { }).then((d) => {
me.filehandler = `${dir}/${fname}`.asFileHandler(); this.filehandle = d.file.path.asFileHandle();
return me.read(); return this.read();
}, __("Open file")); });
} }
saveFile() { saveFile() {
var me; this.filehandle.cache = this.editor.value;
me = this; if (this.filehandle.path !== "Untitled") {
this.filehandler.cache = this.editor.value;
if (this.filehandler.path !== "Untitled") {
return this.write(); return this.write();
} }
return this.openDialog("FileDiaLog", function(dir, fname, d) { return this.openDialog("FileDialog", {
me.filehandler.setPath(`${dir}/${fname}`); title: __("Save as"),
return me.write(); file: this.filehandle
}, __("Save as"), { }).then((f) => {
file: me.filehandler var d;
d = f.file.path.asFileHandle();
if (f.file.type === "file") {
d = d.parent();
}
this.filehandle.setPath(`${d.path}/${f.name}`);
return this.write();
}); });
} }
read() { read() {
var me;
me = this;
this.editor.value = ""; this.editor.value = "";
if (this.filehandler === null) { if (this.filehandle === null) {
this.filehandler = "Untitled".asFileHandler(); this.filehandle = "Untitled".asFileHandle();
this.scheme.set("apptitle", "Untitled"); this.scheme.set("apptitle", "Untitled");
return; return;
} }
return this.filehandler.read(function(d) { return this.filehandle.read().then((d) => {
me.scheme.set("apptitle", me.filehandler.path); this.scheme.set("apptitle", this.filehandle.path);
return me.editor.value = d; return this.editor.value = d;
}).catch((e) => {
return this.error(__("Unable to read file content"));
}); });
} }
write() { write() {
var me; return this.filehandle.write("text/plain").then((d) => {
me = this; this.filehandle.dirty = false;
return this.filehandler.write("text/plain", function(d) { return this.scheme.set("apptitle", `${this.filehandle.path}`);
if (d.error) { }).catch((e) => {
return me.error(__("Error saving file {0}", me.filehandler.path)); return this.error(__("Error saving file {0}", this.filehandle.path), e);
}
me.filehandler.dirty = false;
return me.scheme.set("apptitle", `${me.filehandler.path}`);
}); });
} }
cleanup(e) { cleanup(e) {
var me; if (!this.filehandle.dirty) {
if (!this.filehandler.dirty) {
return; return;
} }
me = this;
e.preventDefault(); e.preventDefault();
return this.ask("__(Quit)", "__(Quit without saving?)", function() { return this.ask({
me.filehandler.dirty = false; title: "__(Quit)",
return me.quit(); text: "__(Quit without saving?)"
}).then(() => {
this.filehandle.dirty = false;
return this.quit();
}); });
} }

View File

@ -1,10 +1,10 @@
{ {
"app":"TinyEditor", "app":"TinyEditor",
"name":"TinyEditor", "name":"Tiny editor",
"description":"", "description":"Basic plain text file editor",
"info":{ "info":{
"author": "", "author": "Xuan Sang LE",
"email": "" "email": "xsang.le@gmail.com"
}, },
"version":"0.0.1-a", "version":"0.0.1-a",
"category":"Other", "category":"Other",

Binary file not shown.

View File

@ -3,20 +3,18 @@ class TinyEditor extends this.OS.GUI.BaseApplication
super "TinyEditor", args super "TinyEditor", args
main: () -> main: () ->
me = @
@editor = @find "editor" @editor = @find "editor"
@bindKey "ALT-N", () -> me.newFile() @bindKey "ALT-N", () => @newFile()
@bindKey "ALT-O", () -> me.openFile() @bindKey "ALT-O", () => @openFile()
@bindKey "CTRL-S", () -> me.saveFile() @bindKey "CTRL-S", () => @saveFile()
@filehandler = if @args and @args.length > 0 then @args[0].asFileHandler() else null @filehandle = if @args and @args.length > 0 then @args[0].asFileHandle() else null
$(@editor).on 'input', (e) -> $(@editor).on 'input', (e) =>
return if me.filehandler.dirty is true return if @filehandle.dirty is true
me.filehandler.dirty = true @filehandle.dirty = true
me.scheme.set "apptitle", "#{me.filehandler.path}*" @scheme.set "apptitle", "#{@filehandle.path}*"
@read() @read()
menu: () -> menu: () ->
me = @
m = [ m = [
{ {
text: "__(File)", text: "__(File)",
@ -25,60 +23,62 @@ class TinyEditor extends this.OS.GUI.BaseApplication
{ text: "__(Open)", dataid :"open", shortcut: 'A-O' }, { text: "__(Open)", dataid :"open", shortcut: 'A-O' },
{ text: "__(Save)", dataid :"save", shortcut: 'C-S' } { text: "__(Save)", dataid :"save", shortcut: 'C-S' }
], ],
onmenuselect: (e) -> onchildselect: (e) =>
switch e.item.data.dataid switch e.data.item.get("data").dataid
when "new" then me.newFile() when "new" then @newFile()
when "open" then me.openFile() when "open" then @openFile()
when "save" then me.saveFile() when "save" then @saveFile()
} }
] ]
m m
newFile: () -> newFile: () ->
@filehandler = null @filehandle = null
@read() @read()
openFile: () -> openFile: () ->
me = @ @openDialog "FileDialog", { title: __("Open file") }
@openDialog "FileDiaLog", ( dir, fname, d ) -> .then (d) =>
me.filehandler = "#{dir}/#{fname}".asFileHandler() @filehandle = d.file.path.asFileHandle()
me.read() @read()
, __("Open file") ,
saveFile: () -> saveFile: () ->
me = @ @filehandle.cache = @editor.value
@filehandler.cache = @editor.value return @write() unless @filehandle.path is "Untitled"
return @write() unless @filehandler.path is "Untitled" @openDialog("FileDialog", {
@openDialog "FileDiaLog", (dir, fname, d) -> title: __("Save as"),
me.filehandler.setPath "#{dir}/#{fname}" file: @filehandle
me.write() }).then (f) =>
, __("Save as"), { file: me.filehandler } d = f.file.path.asFileHandle()
d = d.parent() if f.file.type is "file"
@filehandle.setPath "#{d.path}/#{f.name}"
@write()
read: () -> read: () ->
me = @
@editor.value = "" @editor.value = ""
if @filehandler is null if @filehandle is null
@filehandler = "Untitled".asFileHandler() @filehandle = "Untitled".asFileHandle()
@scheme.set "apptitle", "Untitled" @scheme.set "apptitle", "Untitled"
return return
@filehandler.read (d) -> @filehandle.read().then (d) =>
me.scheme.set "apptitle", me.filehandler.path @scheme.set "apptitle", @filehandle.path
me.editor.value = d @editor.value = d
.catch (e) => @error __("Unable to read file content")
write: () -> write: () ->
me = @ @filehandle.write("text/plain").then (d) =>
@filehandler.write "text/plain", (d) -> @filehandle.dirty = false
return me.error __("Error saving file {0}", me.filehandler.path) if d.error @scheme.set "apptitle", "#{@filehandle.path}"
me.filehandler.dirty = false .catch (e) => @error __("Error saving file {0}", @filehandle.path), e
me.scheme.set "apptitle", "#{me.filehandler.path}"
cleanup: (e) -> cleanup: (e) ->
return unless @filehandler.dirty return unless @filehandle.dirty
me = @
e.preventDefault() e.preventDefault()
@ask "__(Quit)", "__(Quit without saving?)", () -> @ask { title: "__(Quit)", text: "__(Quit without saving?)" }
me.filehandler.dirty = false .then () =>
me.quit() @filehandle.dirty = false
@quit()
this.OS.register "TinyEditor", TinyEditor this.OS.register "TinyEditor", TinyEditor

View File

@ -1,7 +1,5 @@
afx-app-window[data-id="TinyEditor"] textarea[data-id="editor"] afx-app-window[data-id="TinyEditor"] textarea[data-id="editor"]
{ {
background-color: #272822;
color:white;
margin: 0; margin: 0;
padding:10px; padding:10px;
border: 0; border: 0;

View File

@ -1,10 +1,10 @@
{ {
"app":"TinyEditor", "app":"TinyEditor",
"name":"TinyEditor", "name":"Tiny editor",
"description":"", "description":"Basic plain text file editor",
"info":{ "info":{
"author": "", "author": "Xuan Sang LE",
"email": "" "email": "xsang.le@gmail.com"
}, },
"version":"0.0.1-a", "version":"0.0.1-a",
"category":"Other", "category":"Other",

View File

@ -1 +0,0 @@
{"name":"TinyEditor","root":"home://workspace/TinyEditor","css":["css/main.css"],"javascripts":[],"coffees":["coffees/main.coffee"],"copies":["assets/scheme.html","package.json","README.md"]}

8
TinyEditor/project.json Normal file
View File

@ -0,0 +1,8 @@
{
"name": "TinyEditor",
"root": "home://workspace/antosdk-apps/TinyEditor",
"css": ["css/main.css"],
"javascripts": [],
"coffees": ["coffees/main.coffee"],
"copies": ["assets/scheme.html", "package.json", "README.md"]
}

View File

@ -17,6 +17,15 @@
"version": "0.0.1-a", "version": "0.0.1-a",
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ActivityMonitor/build/release/ActivityMonitor.zip" "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ActivityMonitor/build/release/ActivityMonitor.zip"
}, },
{
"pkgname": "LuaPlayground",
"name": "LuaPlayground",
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/LuaPlayground/README.md",
"category": "System",
"author": "Xuan Sang LEs",
"version": "0.0.1-a",
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/LuaPlayground/build/release/LuaPlayground.zip"
},
{ {
"pkgname": "MarkOn", "pkgname": "MarkOn",
"name": "Markdown editor", "name": "Markdown editor",
@ -32,7 +41,7 @@
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Preview/README.md", "description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Preview/README.md",
"category": "Utils", "category": "Utils",
"author": "Xuan Sang LE", "author": "Xuan Sang LE",
"version": "0.0.2-a", "version": "0.0.3-a",
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Preview/build/release/Preview.zip" "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/Preview/build/release/Preview.zip"
}, },
{ {
@ -44,6 +53,15 @@
"version": "0.0.2-a", "version": "0.0.2-a",
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ShowCase/build/release/ShowCase.zip" "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ShowCase/build/release/ShowCase.zip"
}, },
{
"pkgname": "TinyEditor",
"name": "Tiny editor",
"description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/TinyEditor/README.md",
"category": "Other",
"author": "Xuan Sang LE",
"version": "0.0.1-a",
"download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/TinyEditor/build/release/TinyEditor.zip"
},
{ {
"pkgname": "wTerm", "pkgname": "wTerm",
"name": "Terminal", "name": "Terminal",