NotePad apps

This commit is contained in:
Xuan Sang LE 2018-01-28 02:01:21 +01:00
parent ea074d9690
commit c048824ce4
13 changed files with 210 additions and 60 deletions

3
TODO Normal file
View File

@ -0,0 +1,3 @@
VFS mountpoints object (selected) is changed between apps, which is not a good ideal
API handler readfile function return JSON object in reading JSON file, need to be text
Some error in event handle using observable

View File

@ -3,7 +3,6 @@ class BaseApplication extends this.OS.GUI.BaseModel
super name, args
_OS.setting.applications[@name] = {} if not _OS.setting.applications[@name]
@setting = _OS.setting.applications[@name]
init: ->
me = @
# first register some base event to the app

View File

@ -179,7 +179,7 @@ class YesNoDialog extends BasicDialog
},
{
label: "No", onclick: (d) ->
d handler false if dhandler
d.handler false if d.handler
d.quit()
}
],
@ -234,4 +234,42 @@ class AboutDialog extends BaseDialog
rows.push [ { value: k }, { value: v } ] for k, v of mt.info
(@find "mygrid").set "rows", rows
this.OS.register "AboutDialog", AboutDialog
this.OS.register "AboutDialog", AboutDialog
class FileDiaLog extends BaseDialog
constructor: () ->
super "FileDiaLog"
init: () ->
@render "resources/schemes/filedialog.html"
main: () ->
fileview = @find "fileview"
location = @find "location"
me = @
@scheme.set "apptitle", "#{@title}"
fileview.set "fetch", (e, f) ->
return unless e.child
e.child.path.asFileHandler().read (d) ->
return me.error "Resource not found #{e.child.path}" if d.error
f d.result
location.set "onlistselect", (e) ->
return unless e and e.data.path
e.data.path.asFileHandler().read (d) ->
if(d.error)
return me.error "Resource not found #{e.data.path}"
fileview.set "path", e.data.path
fileview.set "data", d.result
location.set "items", ( i for i in @systemsetting.VFS.mountpoints when i.type isnt "app" )
location.set "selected", 0 unless location.get "selected"
(@find "bt-ok").set "onbtclick", (e) ->
f = fileview.get "selectedFile"
return unless f
return unless f.type is "file" or ( me.data and me.data.seldir )
me.handler f if me.handler
me.quit()
(@find "bt-cancel").set "onbtclick", (e) ->
me.quit()
this.OS.register "FileDiaLog", FileDiaLog

View File

@ -3,6 +3,7 @@ class BaseModel
@observable = riot.observable()
@_api = self.OS.API
@_gui = self.OS.GUI
@systemsetting = self.OS.setting
me = @
@on "exit", () -> me.quit()
@host = "#desktop"

View File

@ -13,7 +13,7 @@ self.OS.API =
url: p,
contentType: 'application/json',
data: JSON.stringify d,
dataType: 'json',
dataType: 'json', # data type need to be configurable
success: null
}
#$.getJSON p, d
@ -89,7 +89,7 @@ self.OS.API =
get: (p, c, f) ->
q = _courrier.getMID()
_API.loading q, p
$.get p
$.get p # TODO add return type setting support
.done (data) ->
_API.loaded q, p, "OK"
c(data)

View File

@ -10,6 +10,7 @@ self.OS or=
applications: {}
desktop: {}
appearance: {}
VFS: {}
courrier:
observable: riot.observable()
quota: 0

View File

@ -61,16 +61,19 @@ self.OS.GUI =
_courrier.osfail "Cannot read service script: #{srv} ", e, s
appsByMime: (mime) ->
metas = ( a.meta for k, a of _OS.APP when a.type is 1)
mimes = ( m.mimes for m in metas )
metas = ( a.meta for k, a of _OS.APP when a and a.type is 1)
mimes = ( m.mimes for m in metas when m)
apps = []
# search app by mimes
f = ( arr, idx ) ->
arr.filter (m, i) ->
if mime.match (new RegExp m, "g")
apps.push metas[idx]
try
arr.filter (m, i) ->
if mime.match (new RegExp m, "g")
apps.push metas[idx]
return false
return false
return false
catch e
_courrier.osfail "Find app by mimes #{mime}", e, mime
( f m, i if m ) for m, i in mimes
return apps
@ -265,6 +268,14 @@ self.OS.GUI =
_OS.setting.applications = conf.applications if conf.applications
_OS.setting.appearance = conf.appearance if conf.appearance
_OS.setting.user = conf.user
_OS.setting.VFS = conf.VFS if conf.VFS
_OS.setting.VFS.mountpoints = [ #TODO: multi app try to write to this object, it neet to be cloned
{ text: "Applications", path: 'app:///', iconclass: "fa fa-adn", type: "app" },
{ text: "Home", path: 'home:///', iconclass: "fa fa-home", type: "fs" },
{ text: "OS", path: 'os:///', iconclass: "fa fa-inbox", type: "fs" },
{ text: "Desktop", path: 'home:///.desktop', iconclass: "fa fa-desktop", type: "fs"},
] if not _OS.setting.VFS.mountpoints
_OS.setting.desktop.path = "home:///.desktop" unless _OS.setting.desktop.path
_OS.setting.appearance.theme = "antos" unless _OS.setting.appearance.theme
# load theme
@ -279,5 +290,5 @@ self.OS.GUI =
# startup application here
_courrier.observable.one "desktoploaded", () ->
_GUI.launch "DummyApp"
#_GUI.launch "NotePad"
#_GUI.launch "DummyApp"
_GUI.launch "NotePad"

View File

@ -0,0 +1,12 @@
<afx-app-window data-id = 'file-dialog-window' width='400' height='250'>
<afx-vbox>
<afx-list-view data-id = "location" dropdown = "false" data-width = "120"></afx-list-view>
<afx-hbox>
<afx-file-view data-id = "fileview" view='tree' status = false></afx-file-view>
<div data-height = '30' style=' text-align:right;padding-top:3px;'>
<afx-button data-id = "bt-ok" text = "Ok"></afx-button>
<afx-button data-id = "bt-cancel" text = "Cancel"></afx-button>
</div>
</afx-hbox>
</afx-vbox>
</afx-app-window>

View File

@ -12,6 +12,7 @@
self.data = opts.data || []
self.path = opts.path || "home:///"
self.onfileselect
self.onfileopen
this.status = opts.status == undefined?true:opts.status
this.selectedFile = undefined
this.showhidden = opts.showhidden
@ -182,8 +183,11 @@
$(self.refs.stbar).html("Selected: " + e.data.filename + " (" + e.data.size + " bytes)")
})
self.root.observable.on("filedbclick", function(e){
if(e.id != self.rid || e.data.type == 'file' || !self.chdir) return
self.chdir(e.data.path)
if(e.id != self.rid ) return
if(e.data.type == "file" && self.onfileopen)
self.onfileopen(e.data)
else if(self.chdir)
self.chdir(e.data.path)
})
calibre_size()
self.root.observable.on("resize", function(e){

View File

@ -22,6 +22,7 @@
{
if(k == "selected")
{
console.log("selected", v)
if(self.selidx != -1)
self.items[self.selidx].selected =false
if(self.items[v]) self.items[v].selected = true
@ -121,6 +122,7 @@
_autoselect(it,i)
{
if(!it.selected || it.selected == false) return false
//if(self.selidx == i) return false
var data = {
id:self.rid,
data:it,
@ -133,9 +135,11 @@
$(self.refs.mlist).hide()
$(self.refs.current).html(it.text)
}
if(self.onlistselect)
self.onlistselect(data)
this.root.observable.trigger('listselect',data)
//console.log("list select")
return true
}
_select(event)

View File

@ -4,6 +4,7 @@
var self = this
this.closable = opts.closable || false
self.root.observable = opts.observable || riot.observable()
self.ontabselect = opts.ontabselect
get_observable(){
return self.root.observable
}
@ -12,6 +13,9 @@
return self.refs.list.root.get(k)
}
self.root.update = function(){
self.update()
}
self.on("mount", function(){
self.refs.list.root.observable = self.root.observable
@ -19,7 +23,10 @@
console.log("list select")
})*/
self.refs.list.root.set ("onlistselect",function (e) {
//console.log("tab is seleced")
self.root.observable.trigger("tabselect", e)
if(self.ontabselect)
self.ontabselect(e)
})
})
@ -31,6 +38,8 @@
{
self.closable = v
}
else if(k == "ontabselect")
self.ontabselect = v
else
{
if(k == "items")
@ -56,5 +65,6 @@
{
self.refs.list.root.remove(e,u)
}
</script>
</afx-tab-container>

View File

@ -16,10 +16,12 @@ class Files extends this.OS.GUI.BaseApplication
m.set "items", [ me.mnFile(), me.mnEdit() ]
m.show(e)
#@on "fileselect", (d) -> console.log d
@on "filedbclick", (e) ->
return unless e.data
return if e.data.type is "dir"
me._gui.openWith e.data
@view.set "onfileopen", (e) ->
return unless e
return if e.type is "dir"
#console.log e
me._gui.openWith e
@favo.set "onlistselect", (e) -> me.chdir e.data.path
($ @find "btback").click () ->
@ -34,23 +36,18 @@ class Files extends this.OS.GUI.BaseApplication
@view.set "chdir", (p) -> me.chdir p
@view.set "fetch", (e, f) ->
return unless e.child
me._api.handler.scandir e.child.path,
(d) -> f d.result
, (e, s) -> me.error "Cannot fetch child dir #{e.child.path}"
e.child.path.asFileHandler().read (d) ->
return me.error "Resource not found #{e.child.path}" if d.error
f d.result
@setting.favorite = [
{ text: "Applications", path: 'app:///', iconclass: "fa fa-adn" },
{ text: "Home", path: 'home:///', iconclass: "fa fa-home" },
{ text: "OS", path: 'os:///', iconclass: "fa fa-inbox" },
{ text: "Desktop", path: 'home:///.desktop', iconclass: "fa fa-desktop" },
] if not @setting.favorite
@setting.sidebar = true if @setting.sidebar is undefined
@setting.nav = true if @setting.nav is undefined
@setting.showhidden = false if @setting.showhidden is undefined
el.selected = false for el, i in @setting.favorite
mntpoints = @systemsetting.VFS.mountpoints
el.selected = false for el, i in mntpoints
@favo.set "items", @setting.favorite
@favo.set "items", mntpoints
#@favo.set "selected", -1
@applySetting()
@chdir null

View File

@ -9,7 +9,7 @@ class NotePad extends this.OS.GUI.BaseApplication
@fileview = @find "fileview"
div = @find "datarea"
ace.require "ace/ext/language_tools"
@currfile = if @args and @args.length > 0 then @args[0].asFileHandler() else undefined
@currfile = if @args and @args.length > 0 then @args[0].asFileHandler() else "Untitled".asFileHandler()
@.editor = ace.edit div
@.editor.setOptions {
enableBasicAutocompletion: true,
@ -20,16 +20,19 @@ class NotePad extends this.OS.GUI.BaseApplication
@.editor.completers.push { getCompletions: ( editor, session, pos, prefix, callback ) -> }
@.editor.getSession().setUseWrapMode true
list = @find "modelist"
@mlist = @find "modelist"
@modes = ace.require "ace/ext/modelist"
ldata = []
ldata.push {
text: m.name,
mode: m.mode,
selected: if m.mode is 'ace/mode/text' then true else false
} for m in @modes.modes
list.set "items", ldata
list.set "onlistselect", (e) ->
f = (m, i) ->
ldata.push {
text: m.name,
mode: m.mode,
selected: if m.mode is 'ace/mode/text' then true else false
}
m.idx = i
f(m, i) for m, i in @modes.modes
@mlist.set "items", ldata
@mlist.set "onlistselect", (e) ->
me.editor.session.setMode e.data.mode
themelist = @find "themelist"
@ -52,6 +55,15 @@ class NotePad extends this.OS.GUI.BaseApplication
$(stat).html "Row #{c.row}, col #{c.column}, lines: #{l}"
stup(0)
@.editor.getSession().selection.on "changeCursor", (e) -> stup(e)
@editormux = false
@editor.on "input", () ->
if me.editormux
me.editormux = false
return false
if not me.currfile.dirty
me.currfile.dirty = true
me.currfile.text += "*"
me.tabarea.update()
@on "resize", () -> me.editor.resize()
@on "focus", () -> me.editor.focus()
@ -59,39 +71,89 @@ class NotePad extends this.OS.GUI.BaseApplication
@fileview.set "chdir", (d) -> me.chdir d
@fileview.set "fetch", (e, f) ->
return unless e.child
me._api.handler.scandir e.child.path,
(d) -> f d.result
, (e, s) -> me.error "Cannot fetch child dir #{e.child.path}"
e.child.path.asFileHandler().read (d) ->
return me.error "Resource not found #{e.child.path}" if d.error
f d.result
@fileview.set "onfileopen", (e) ->
me.open e.path.asFileHandler()
@location.set "onlistselect", (e) -> me.chdir e.data.path
@location.set "items", [
{ text: "Home", path: 'home:///', iconclass: "fa fa-home", selected: true },
{ text: "OS", path: 'os:///', iconclass: "fa fa-inbox" },
{ text: "Desktop", path: 'home:///.desktop', iconclass: "fa fa-desktop" },
]
@location.set "items", ( i for i in @systemsetting.VFS.mountpoints when i.type isnt "app" )
@location.set "selected", 0 unless @location.get "selected"
@tabarea = @find "tabarea"
@tabarea.set "ontabselect", (e) ->
me.selecteTab e.idx
@tabarea.set "onitemclose", (e) ->
it = e.item.item
return false unless it
return me.closeTab it unless it.dirty
me.openDialog "YesNoDialog", (d) ->
return me.closeTab it if d
me.editor.focus()
, "Close tab", { text: "Close without saving ?" }
return false
#@tabarea.set "closable", true
@open @currfile
open: (file) ->
#find table
@newtab "undefined".asFileHandler() unless file
return @newtab "undefined".asFileHandler() unless file
i = @findTabByFile file
return @tabarea.set "selected", i if i isnt -1
return @newtab file if file.path.toString() is "Untitled"
me = @
file.read (d) ->
return unless d
file.read (_d) ->
d = if typeof _d is "string" then _d else JSON.stringify _d
me.scheme.set "apptitle", file.basename
file.cache = d
file.cache = d or ""
me.newtab file
newtab: (file) ->
file.text = if file.basename then file.basename else "undefined"
file.cache = "" unless file.cache
findTabByFile: (file) ->
lst = @tabarea.get "items"
its = ( i for d, i in lst when d.hash() is file.hash() )
return -1 if its.length is 0
return its[0]
closeTab: (it) ->
@tabarea.remove it, false
cnt = @tabarea.get "count"
if cnt is 0
@open "Untitled".asFileHandler()
return false
@tabarea.set "selected", cnt - 1
return false
newtab: (file) ->
file.text = if file.basename then file.basename else file.path
file.cache = "" unless file.cache
file.um = new ace.UndoManager()
@currfile.selected = false
file.selected = true
#console.log cnt
@tabarea.push file, true
@tabarea.set "selected", cnt
#@currfile = @file
#TODO: fix problem : @tabarea.set "selected", cnt
selecteTab: (i) ->
#return if i is @tabarea.get "selidx"
file = (@tabarea.get "items")[i]
return unless file
#return if file is @currfile
if @currfile isnt file
@currfile.cache = @editor.getValue()
@currfile.cursor = @editor.selection.getCursor()
@currfile = file
m = "ace/mode/text"
m = (@modes.getModeForPath file.path) if file.path.toString() isnt "Untitled"
@mlist.set "selected", m.idx
@editormux = true
@editor.setValue file.cache, -1
@editor.session.setMode m.mode
@editor.session.setUndoManager file.um
if file.cursor
@editor.renderer.scrollCursorIntoView { row: file.cursor.row, column: file.cursor.column }, 0.5
@editor.selection.moveTo file.cursor.row, file.cursor.column
@editor.focus()
chdir: (p) ->
me = @
@ -104,14 +166,22 @@ class NotePad extends this.OS.GUI.BaseApplication
, (e, s) ->
me.error "Cannot chdir #{p}"
menu: ()->
menu: () ->
me = @
menu = [{
text: "File",
child: [
{ text: "Open", dataid: "#{@name}-Open" },
{ text: "Close", dataid: "#{@name}-Close" }
]
],
onmenuselect: (e) -> me.actionFile e
}]
menu
actionFile: (e) ->
switch e.item.data.dataid
when "#{@name}-Open"
@openDialog "FileDiaLog", null, "Select file", { seldir: true }
NotePad.singleton = false
this.OS.register "NotePad", NotePad