remote handler

This commit is contained in:
Xuan Sang LE 2017-08-27 23:40:02 +02:00
parent fc406be924
commit 6f298fc52b
42 changed files with 714 additions and 205 deletions

View File

@ -6,7 +6,7 @@ NC=\033[0m
coffees= src/core/core.coffee\ coffees= src/core/core.coffee\
src/core/api.coffee\ src/core/api.coffee\
src/core/handlers/TestHandler.coffee\ src/core/handlers/RemoteHandler.coffee\
src/core/gui.coffee\ src/core/gui.coffee\
src/core/BaseModel.coffee\ src/core/BaseModel.coffee\
src/core/BaseApplication.coffee\ src/core/BaseApplication.coffee\
@ -22,7 +22,7 @@ coffees= src/core/core.coffee\
packages = NotePad wTerm ActivityMonitor DummyApp Files packages = NotePad wTerm ActivityMonitor DummyApp Files
services = PushNotification Spotlight Calendar services = PushNotification Spotlight Calendar
main: clean build_coffees build_tags build_themes schemes libs build_services build_packages main: build_coffees build_tags build_themes schemes libs build_services build_packages
- cp src/index.html $(BUILDDIR)/ - cp src/index.html $(BUILDDIR)/
lite: build_coffee build_tag build_theme schemes build_services build_packages lite: build_coffee build_tag build_theme schemes build_services build_packages
@ -67,7 +67,7 @@ antos_themes_build:
for f in src/themes/antos/*.css; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/themes/antos/antos.css;done for f in src/themes/antos/*.css; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/themes/antos/antos.css;done
-mkdir -p $(BUILDDIR)/resources/themes/antos/fonts -mkdir -p $(BUILDDIR)/resources/themes/antos/fonts
cp -rf src/themes/antos/fonts/* $(BUILDDIR)/resources/themes/antos/fonts cp -rf src/themes/antos/fonts/* $(BUILDDIR)/resources/themes/antos/fonts
cp src/themes/antos/wallpaper.jpg $(BUILDDIR)/resources/themes/antos/ cp src/themes/antos/wp.png $(BUILDDIR)/resources/themes/antos/
build_services: build_services:

View File

@ -1,7 +1,7 @@
_GUI = self.OS.GUI _GUI = self.OS.GUI
_API = self.OS.API _API = self.OS.API
_APP = self.OS.APP
_PM = self.OS.PM _PM = self.OS.PM
_OS = self.OS
_courrier = self.OS.courrier _courrier = self.OS.courrier
this.onload = () -> this.onload = () ->
console.log "Booting the os" console.log "Booting the os"

View File

@ -1,7 +1,7 @@
self = this self = this
class BaseApplication extends this.OS.GUI.BaseModel class BaseApplication extends this.OS.GUI.BaseModel
constructor: (name) -> constructor: (name, args) ->
super name super name, args
init: -> init: ->
me = @ me = @
@ -44,11 +44,11 @@ class BaseApplication extends this.OS.GUI.BaseModel
if not evt.prevent if not evt.prevent
@.appmenu.set "items", [] if @.pid == @.appmenu.pid @.appmenu.set "items", [] if @.pid == @.appmenu.pid
($ @scheme).remove() ($ @scheme).remove()
meta: () -> _APP[@name].meta meta: () -> _OS.APP[@name].meta
baseMenu: -> baseMenu: ->
mn = mn =
[{ [{
text: _APP[@name].meta.name, text: _OS.APP[@name].meta.name,
child: [ child: [
{ text: "About", dataid: "#{@name}-about" }, { text: "About", dataid: "#{@name}-about" },
{ text: "Exit", dataid: "#{@name}-exit" } { text: "Exit", dataid: "#{@name}-exit" }

View File

@ -1,6 +1,6 @@
class BaseDialog extends this.OS.GUI.BaseModel class BaseDialog extends this.OS.GUI.BaseModel
constructor: (name) -> constructor: (name) ->
super name super name, null
@parent = undefined @parent = undefined
@modal = false @modal = false
@handler = undefined @handler = undefined
@ -47,8 +47,8 @@ class BasicDialog extends BaseDialog
html = "<afx-app-window data-id = 'dia-window' apptitle='#{@name}' width='#{@conf.width}' height='#{@conf.height}'> html = "<afx-app-window data-id = 'dia-window' apptitle='#{@name}' width='#{@conf.width}' height='#{@conf.height}'>
<afx-hbox>" <afx-hbox>"
html += "<#{@conf.tag} data-id = 'content'></#{@conf.tag}>" html += "<#{@conf.tag} data-id = 'content'></#{@conf.tag}>"
html += "<div data-height = '40' style='padding:5px; text-align:right;'>" html += "<div data-height = '40' style=' text-align:right;padding-top:3px;'>"
html += "<afx-button data-id = 'bt#{k}' text = '#{v.label}' style='margin-left:3px;'></afx-button>" for k,v of @conf.buttons html += "<afx-button data-id = 'bt#{k}' text = '#{v.label}' style='margin-right:5px;'></afx-button>" for k,v of @conf.buttons
html += "</div></afx-hbox></afx-app-window>" html += "</div></afx-hbox></afx-app-window>"
#render the html #render the html
_GUI.htmlToScheme html, @, @host _GUI.htmlToScheme html, @, @host
@ -60,6 +60,7 @@ class BasicDialog extends BaseDialog
f = (_v) -> () -> _v.onclick me f = (_v) -> () -> _v.onclick me
# bind action to button # bind action to button
( (me.find "bt#{k}").set "onbtclick", f(v) ) for k, v of @conf.buttons ( (me.find "bt#{k}").set "onbtclick", f(v) ) for k, v of @conf.buttons
@conf.filldata @ if @conf.filldata
this.OS.GUI.BasicDialog = BasicDialog this.OS.GUI.BasicDialog = BasicDialog
@ -115,6 +116,22 @@ class ColorPickerDialog extends BasicDialog
} }
this.OS.register "ColorPickerDialog", ColorPickerDialog this.OS.register "ColorPickerDialog", ColorPickerDialog
class InfoDialog extends BasicDialog
constructor: () ->
super "InfoDialog", {
tag: 'afx-grid-view',
width: 250,
height: 300,
resizable: true,
buttons: [ { label: 'Cancel', onclick: (d) -> d.quit() } ],
filldata: (d) ->
return unless d.data
rows = []
rows.push [ { value: k }, { value: v } ] for k, v of d.data
(d.find "content").set "rows", rows
}
this.OS.register "InfoDialog", InfoDialog
class AboutDialog extends BaseDialog class AboutDialog extends BaseDialog
constructor: () -> constructor: () ->
super "AboutDialog" super "AboutDialog"

View File

@ -1,10 +1,12 @@
class BaseModel class BaseModel
constructor: (@name) -> constructor: (@name, @args) ->
@observable = riot.observable() @observable = riot.observable()
@_api = self.OS.API @_api = self.OS.API
me = @ me = @
@on "exit", () -> me.quit() @on "exit", () -> me.quit()
@host = "#desktop" @host = "#desktop"
_OS.setting.applications[@name] = {} if not _OS.setting.applications[@name]
@setting = _OS.setting.applications[@name]
@dialog = undefined @dialog = undefined
render: (p) -> render: (p) ->
@ -29,7 +31,7 @@ class BaseModel
subscribe: (e, f) -> _courrier.on e, f, @ subscribe: (e, f) -> _courrier.on e, f, @
openDialog: (d, f) -> openDialog: (d, f, data) ->
if @dialog if @dialog
@dialog.show() @dialog.show()
return return
@ -40,6 +42,7 @@ class BaseModel
@dialog.parent = @ @dialog.parent = @
@dialog.handler = f @dialog.handler = f
@dialog.pid = @pid @dialog.pid = @pid
@dialog.data = data
@dialog.init() @dialog.init()
publish: (t, m) -> publish: (t, m) ->

View File

@ -1,6 +1,6 @@
class BaseService extends this.OS.GUI.BaseModel class BaseService extends this.OS.GUI.BaseModel
constructor: (name) -> constructor: (name, args) ->
super name super name, args
@icon = undefined @icon = undefined
@iconclass = "fa-paper-plane-o" @iconclass = "fa-paper-plane-o"
@text = "" @text = ""

View File

@ -3,20 +3,20 @@ self.OS.API =
# fetch user data, used by the API to make requests # fetch user data, used by the API to make requests
# handlers are defined in /src/handlers # handlers are defined in /src/handlers
handler: {} handler: {}
VFS:
scandir: (p, c, f) ->
_API.handler.request "scandir", { path: p }, c, f
#request a user data #request a user data
post: (p, d, c, f) -> post: (p, d, c, f) ->
q = _courrier.getMID() q = _courrier.getMID()
_API.loading q, p _API.loading q, p
$.ajax { $.ajax {
type: "POST", type: 'POST',
url: p, url: p,
data: d, contentType: 'application/json',
success: null, data: JSON.stringify d,
dataType: 'json' dataType: 'json',
success: null
} }
#$.getJSON p, d
.done (data) -> .done (data) ->
_API.loaded q, p, "OK" _API.loaded q, p, "OK"
c(data) c(data)
@ -51,7 +51,7 @@ self.OS.API =
.fail (e, s) -> .fail (e, s) ->
_API.loaded q, p, "FAIL" _API.loaded q, p, "FAIL"
f(e, s) f(e, s)
resource: (resource, callback) -> resource: (r, c, f) ->
path = "resources/#{resource}" path = "resources/#{r}"
_API.get path, callback _API.get path, c, f

View File

@ -2,10 +2,13 @@
self = this self = this
self.OS or= self.OS or=
API: new Object() API: {}
GUI: new Object() GUI: {}
APP: new Object() APP: {}
setting:
user: {}
applications: {}
appearance: {}
courrier: courrier:
observable: riot.observable() observable: riot.observable()
quota: 0 quota: 0
@ -15,6 +18,12 @@ self.OS or=
_courrier.listeners[a.pid].push { e: e, f: f } _courrier.listeners[a.pid].push { e: e, f: f }
_courrier.observable.on e, f _courrier.observable.on e, f
trigger: (e, d) -> _courrier.observable.trigger e, d trigger: (e, d) -> _courrier.observable.trigger e, d
osfail: (m, e, s) ->
_courrier.ostrigger "fail", { m: m, e: e, s: s }
oserror: (m, e, s) ->
_courrier.ostrigger "error", { m: m, e: e, s: s }
ostrigger: (e, d) ->
_courrier.trigger e, { id: 0, data: d, name: "OS" }
unregister: (app) -> unregister: (app) ->
return unless _courrier.listeners[app.pid] and _courrier.listeners[app.pid].length > 0 return unless _courrier.listeners[app.pid] and _courrier.listeners[app.pid].length > 0
_courrier.observable.off i.e, i.f for i in _courrier.listeners[app.pid] _courrier.observable.off i.e, i.f for i in _courrier.listeners[app.pid]
@ -24,12 +33,12 @@ self.OS or=
_courrier.quota += 1 _courrier.quota += 1
_courrier.quota _courrier.quota
register: (name, x) -> register: (name, x) ->
if x.type is 3 then self.OS.GUI.dialog[name] = x else _APP[name] = x if x.type is 3 then self.OS.GUI.dialog[name] = x else _OS.APP[name] = x
PM: PM:
pidalloc: 0 pidalloc: 0
processes: new Object processes: {}
createProcess: (app, cls) -> createProcess: (app, cls, args) ->
#if it is single ton #if it is single ton
# and a process is existing # and a process is existing
# just return it # just return it
@ -37,7 +46,7 @@ self.OS or=
_PM.processes[app][0].show() _PM.processes[app][0].show()
else else
_PM.processes[app] = [] if not _PM.processes[app] _PM.processes[app] = [] if not _PM.processes[app]
obj = new cls obj = new cls(args)
obj.birth = (new Date).getTime() obj.birth = (new Date).getTime()
_PM.pidalloc++ _PM.pidalloc++
obj.pid = _PM.pidalloc obj.pid = _PM.pidalloc
@ -55,20 +64,28 @@ self.OS or=
app app
kill: (app) -> kill: (app) ->
return if not _PM.processes[app.name] return if not app.name or not _PM.processes[app.name]
i = _PM.processes[app.name].indexOf app i = _PM.processes[app.name].indexOf app
if i >= 0 if i >= 0
if _APP[app.name].type == 1 then _GUI.undock app else _GUI.detachservice app if _OS.APP[app.name].type == 1 then _GUI.undock app else _GUI.detachservice app
_courrier.unregister app _courrier.unregister app
delete _PM.processes[app.name][i] delete _PM.processes[app.name][i]
_PM.processes[app.name].splice i, 1 _PM.processes[app.name].splice i, 1
killAll: (app) ->
return unless _PM.processes[app]
tmp = []
tmp.push a for a in _PM.processes[app]
a.quit() for a in tmp
boot: -> boot: ->
#first load the configuration #first login
#then load the theme _API.handler.auth (d) ->
_GUI = self.OS.GUI # in case someone call it more than once :)
_GUI.loadTheme "antos" if d.error
_GUI.initDM() # show login screen
_courrier.observable.one "syspanelloaded", () -> _GUI.login()
_GUI.pushServices ["PushNotification", "Spotlight", "Calendar"] else
# startX :)
_GUI.startAntOS d.result

View File

@ -18,11 +18,11 @@ self.OS.GUI =
return null unless x return null unless x
_GUI.htmlToScheme x, app, parent _GUI.htmlToScheme x, app, parent
, (e, s) -> , (e, s) ->
_courrier.trigger "fail", _courrier.osfail "Cannot load scheme file: #{path} for #{app.name} (#{app.pid})",e,s
{id: 0, data: {
m: "Cannot load scheme file: #{path} for #{app.name} (#{app.pid})",e: e, s: s }, clearTheme: () ->
name:"OS" $ "head link#ostheme"
} .attr "href", ""
loadTheme: (name) -> loadTheme: (name) ->
path = "resources/themes/#{name}/#{name}.css" path = "resources/themes/#{name}/#{name}.css"
@ -37,19 +37,23 @@ self.OS.GUI =
f i for i in srvs f i for i in srvs
pushService: (srv) -> pushService: (srv) ->
return _PM.createProcess srv, _APP[srv] if _APP[srv] return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv]
path = "services/#{srv}.js" path = "services/#{srv}.js"
_API.script path, _API.script path,
(d) -> (d) ->
_PM.createProcess srv, _APP[srv] _PM.createProcess srv, _OS.APP[srv]
, (e, s) -> , (e, s) ->
_courrier.trigger "srvroutineready", srv _courrier.trigger "srvroutineready", srv
_courrier.trigger "fail", _courrier.osfail "Cannot read service script: #{srv} ", e, s
{ id:0,data:{m: "Cannot read service script: #{srv} ", e: e, s: s },
name:"0S"}
launch: (app) -> forceLaunch: (app, args) ->
if not _APP[app] console.log "This method is used for developing only, please use the launch method instead"
_PM.killAll app
_OS.APP[app] = undefined
_GUI.launch app, args
launch: (app, args) ->
if not _OS.APP[app]
# first load it # first load it
path = "packages/#{app}/" path = "packages/#{app}/"
_API.script path + "main.js", _API.script path + "main.js",
@ -61,26 +65,23 @@ self.OS.GUI =
.appendTo 'head' .appendTo 'head'
, () -> , () ->
#launch #launch
if _APP[app] if _OS.APP[app]
# load app meta data # load app meta data
_API.get "#{path}package.json", _API.get "#{path}package.json",
(data) -> (data) ->
_APP[app].meta = data _OS.APP[app].meta = data
_PM.createProcess app, _APP[app] _PM.createProcess app, _OS.APP[app], args
, (e, s) -> , (e, s) ->
_courrier.trigger "fail", _courrier.osfail "Cannot read application metadata: #{app}", e, s
{id:0, data:{ m: "Cannot read application metadata: #{app} ",e: e, s: s }, name:"OS"}
alert "cannot read application, meta-data" alert "cannot read application, meta-data"
, (e, s) -> , (e, s) ->
#BUG report here #BUG report here
_courrier.trigger "fail", _courrier.osfail "Cannot load application script: #{app}", e, s
{id :0, data:{m: "Cannot load application script: #{app}",
e: e, s:s }, name:"OS"}
console.log "bug report", e, s, path console.log "bug report", e, s, path
else else
# now launch it # now launch it
if _APP[app] if _OS.APP[app]
_PM.createProcess app, _APP[app] _PM.createProcess app, _OS.APP[app], args
dock: (app, meta) -> dock: (app, meta) ->
# dock an application to a dock # dock an application to a dock
# create a data object # create a data object
@ -118,6 +119,7 @@ self.OS.GUI =
handler event.target handler event.target
event.preventDefault() event.preventDefault()
initDM: -> initDM: ->
# check login first
_API.resource "schemes/dm.html", (x) -> _API.resource "schemes/dm.html", (x) ->
return null unless x return null unless x
scheme = $.parseHTML x scheme = $.parseHTML x
@ -135,3 +137,41 @@ self.OS.GUI =
# system menu # system menu
riot.mount ($ "#syspanel", $ "#wrapper") riot.mount ($ "#syspanel", $ "#wrapper")
riot.mount ($ "#sysdock", $ "#wrapper"), { items: [] } riot.mount ($ "#sysdock", $ "#wrapper"), { items: [] }
, (e, s) ->
alert "System fall: Cannot init desktop manager"
login: () ->
($ "#wrapper").empty()
_GUI.clearTheme()
_API.resource "schemes/login.html", (x) ->
return null unless x
scheme = $.parseHTML x
($ "#wrapper").append scheme
($ "#btlogin").click () ->
data =
username: ($ "#txtuser").val(),
password: ($ "#txtpass").val()
_API.handler.login data, (d) ->
console.log d
if d.error then ($ "#login_error").html d.error else _GUI.startAntOS d.result
, (e, s) ->
alert "System fall: Cannot init login screen"
startAntOS: (conf) ->
($ "#wrapper").empty()
_GUI.clearTheme()
_courrier.observable = riot.observable()
_OS.APP = {}
_PM.processes = {}
_PM.pidalloc = 0
_OS.setting.applications = conf.applications if conf.applications
_OS.setting.appearance = conf.appearance if conf.appearance
_OS.setting.user = conf.user
# get setting from conf
# load packages list
# load theme
# initDM
_GUI.loadTheme "antos"
_GUI.initDM()
_courrier.observable.one "syspanelloaded", () ->
_GUI.pushServices ["PushNotification", "Spotlight", "Calendar"]

View File

@ -0,0 +1,26 @@
self.OS.API.handler =
scandir: (p, c ) ->
path = "lua-api/fs/scandir"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to make request: #{path}", e, s
auth: (c) ->
p = "lua-api/system/auth"
_API.post p, {}, c, () ->
alert "Resource not found: #{p}"
login: (d, c) ->
p = "lua-api/system/login"
_API.post p, d, c, () ->
alert "Resource not found: #{p}"
logout: () ->
p = "lua-api/system/logout"
_API.post p, {}, (d) ->
_OS.boot()
, () ->
alert "Resource not found #{p}"
setting: () ->
p = "lua-api/system/settings"
_API.post p, _OS.setting, (d) ->
_courrier.oserror "Cannot save system setting", d.error if d.error
, (e, s) ->
_courrier.osfail "Fail to make request: #{p}", e, s

View File

@ -1,8 +1,6 @@
self.OS.API.handler = self.OS.API.handler =
request: ( p, d, c, f) -> scandir: (p, c ) ->
path = switch p path = 'resources/jsons/scandir.json'
when 'scandir' then 'resources/jsons/scandir.json' _API.get path , c, (e, s) ->
else undefined _courrier.osfail "System fall: Cannot read #{path}", e, s
return unless path
_API.get path, c, f

View File

@ -0,0 +1,78 @@
<!--
Since nothing is loaded, the login form is a standalone element,
it deserves it own unique style
For now, it can not be themed !!!
-->
<style>
body, html{
background-color: rgba(215,215,215,0.7);
}
#login_form{
width:300px;
height: 200px;
display: block;
border:1px solid #a6a6a6;
border-radius: 6px;
box-shadow: 1px 1px 1px #9f9F9F;
position: absolute;
margin: auto;
top:0;
right: 0;
bottom: 0;
left: 0;
font-family:Verdana, Geneva, Tahoma, sans-serif;
font-size: 13px;
text-align: center;
background-color: white;
color: #414339;
}
#login_form p{
display: inline-block;
background-color:#dfdfdf;
border-bottom: 1px solid #a6a6a6;
padding:10px;
width: calc(100% - 20px);
border-top-left-radius: 6px;
border-top-right-radius: 6px;
font-weight: bold;
margin:0;
}
#login_form input {
width: 250px;
outline: none;
margin-top:10px;
border-radius: 6px;
box-sizing: border-box;
font-size: 13px;
padding: 5px;
border: 1px solid #a6a6a6;
background-color: white;
color: #414339;
}
#login_form button{
margin-top:10px;
width: 250px;
height: 30px;
background-color: #2786F3;
color: white;
border: 1px solid #dedede;
border-radius: 6px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 13px;
padding:5px;
}
#login_error{
padding:3px;
color:red;
font-weight: normal;
}
</style>
<div id = "login_form">
<p>Welcome to AntOS, plese identify</p>
<input id = "txtuser" type = "text" value = "User name" />
<input id = "txtpass" type = "password" value = "password" />
<button id = "btlogin">Login</button>
<span id = "login_error"></span>
</div>

View File

@ -77,7 +77,15 @@
$(self.refs.content).children().each(function(e){ $(self.refs.content).children().each(function(e){
this.observable = self.root.observable this.observable = self.root.observable
}) })
var fn = function()
{
var ch = $(self.refs.content).height()/ $(self.refs.content).children().length
$(self.refs.content).children().each(function(e){
$(this).css("height",ch+"px")
})
}
fn()
self.root.observable.on("resize", function(){ fn()})
self.root.observable.on("focus",function(){ self.root.observable.on("focus",function(){
window._zindex++ window._zindex++
$(self.refs.window) $(self.refs.window)

View File

@ -1,11 +1,12 @@
<afx-button> <afx-button>
<button disabled={ enable == "false" } onclick="{ _onbtclick }" > <button disabled={ enable == "false" } onclick="{ _onbtclick }" >
<afx-label icon={icon} iconclass = {iconclass} text = {text} ></afx-label> <afx-label color = {color} icon={icon} iconclass = {iconclass} text = {text} ></afx-label>
</button> </button>
<script> <script>
this.enable = opts.enable this.enable = opts.enable
this.icon = opts.icon this.icon = opts.icon
this.iconclass = opts.iconclass this.iconclass = opts.iconclass
this.color = opts.color
this.text = opts.text || "" this.text = opts.text || ""
var self = this var self = this
this.onbtclick = opts.onbtclick this.onbtclick = opts.onbtclick

View File

@ -56,6 +56,12 @@
colorctx.fillRect(0, 0, colorctx.canvas.width, colorctx.canvas.height) colorctx.fillRect(0, 0, colorctx.canvas.width, colorctx.canvas.height)
//$(self.refs.palette).css("position", "absolute") //$(self.refs.palette).css("position", "absolute")
// now add mouse move event // now add mouse move event
var getHex = function(c)
{
s = c.toString(16)
if(s.length == 1) s = "0" + s
return s
}
var pick_color = function(e) var pick_color = function(e)
{ {
$(self.refs.palette).css("cursor","crosshair") $(self.refs.palette).css("cursor","crosshair")
@ -68,7 +74,7 @@
g:color.data[1], g:color.data[1],
b:color.data[2], b:color.data[2],
text:'rgb(' + color.data[0] + ', ' + color.data[1] + ', ' + color.data[2] + ')', text:'rgb(' + color.data[0] + ', ' + color.data[1] + ', ' + color.data[2] + ')',
hex:'#' + color.data[0].toString(16) + color.data[1].toString(16) + color.data[2].toString(16) hex:'#' + getHex(color.data[0]) + getHex(color.data[1]) + getHex(color.data[2])
} }
return data return data
} }

View File

@ -1,7 +1,9 @@
<afx-file-view> <afx-file-view>
<afx-list-view ref="listview" observable = {root.observable}></afx-list-view> <afx-list-view ref="listview" observable = {root.observable}></afx-list-view>
<afx-grid-view ref = "gridview" header = {header} observable = {root.observable}></afx-grid-view> <afx-grid-view ref = "gridview" header = {header} observable = {root.observable}></afx-grid-view>
<afx-tree-view ref = "treeview" observable = {root.observable}></afx-tree-view> <div class = "treecontainer" ref="treecontainer">
<afx-tree-view ref = "treeview" observable = {root.observable}></afx-tree-view>
</div>
<div if = {status == true} class = "status" ref = "stbar"></div> <div if = {status == true} class = "status" ref = "stbar"></div>
<script> <script>
var self = this var self = this
@ -12,8 +14,11 @@
self.onfileselect self.onfileselect
this.status = opts.status == undefined?true:opts.status this.status = opts.status == undefined?true:opts.status
this.selectedFile = undefined this.selectedFile = undefined
this.showhidden = opts.showhidden
this.fetch = opts.fetch
this.chdir = opts.chdir
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1 this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.header = [{value:"File name"},{value: "Type", width:100}, {value: "Size", width:70}] this.header = [{value:"File name"},{value: "Type", width:150}, {value: "Size", width:70}]
self.root.set = function(k,v) self.root.set = function(k,v)
{ {
@ -36,35 +41,50 @@
} }
var calibre_size = function() var calibre_size = function()
{ {
var h = $(self.root).height() var h = $(self.root).outerHeight()
var w = $(self.root).width()
if(self.refs.stbar) if(self.refs.stbar)
h -= $(self.refs.stbar).height() h -= ($(self.refs.stbar).height() + 10)
$(self.refs.listview.root).css("height", h + "px") $(self.refs.listview.root).css("height", h + "px")
$(self.refs.gridview.root).css("height", h + "px") $(self.refs.gridview.root).css("height", h + "px")
$(self.refs.treeview.root).css("height", h + "px") $(self.refs.treecontainer).css("height", h + "px")
$(self.refs.listview.root).css("width", w + "px")
$(self.refs.gridview.root).css("width", w + "px")
$(self.refs.treecontainer).css("width", w + "px")
} }
var refreshList = function(){ var refreshList = function(){
var items = []
$.each(self.data, function(i, v){ $.each(self.data, function(i, v){
if(v.filename[0] == '.' && !self.showhidden) return
v.text = v.filename v.text = v.filename
if(v.text.length > 10) if(v.text.length > 10)
v.text = v.text.substring(0,9) + "..." v.text = v.text.substring(0,9) + "..."
v.iconclass = v.type v.iconclass = v.type
items.push(v)
}) })
self.refs.listview.root.set("items", self.data) self.refs.listview.root.set("items", items)
} }
var refreshGrid = function(){ var refreshGrid = function(){
var rows = [] var rows = []
$.each(self.data, function(i,v){ $.each(self.data, function(i,v){
if(v.filename[0] == '.' && !self.showhidden) return
var row = [{value:v.filename, iconclass: v.type},{value:v.mime},{value:v.size}] var row = [{value:v.filename, iconclass: v.type},{value:v.mime},{value:v.size}]
rows.push(row) rows.push(row)
}) })
self.refs.gridview.root.set("rows",rows) self.refs.gridview.root.set("rows",rows)
} }
var refreshTree = function(){ var refreshTree = function(){
self.refs.treeview.root.set("selectedItem", null)
var tdata = {} var tdata = {}
tdata.name = self.path tdata.name = self.path
tdata.nodes = [] tdata.nodes = getTreeData(self.data)
$.each(self.data, function(i,v){ self.refs.treeview.root.set("*", tdata)
}
var getTreeData = function(data)
{
nodes = []
$.each(data, function(i,v){
if(v.filename[0] == '.' && !self.showhidden) return
v.name = v.filename v.name = v.filename
if(v.type == 'dir') if(v.type == 'dir')
{ {
@ -72,9 +92,9 @@
v.open = false v.open = false
} }
v.iconclass = v.type v.iconclass = v.type
tdata.nodes.push(v) nodes.push(v)
}) })
self.refs.treeview.root.set("*", tdata) return nodes
} }
var refreshData = function(){ var refreshData = function(){
self.data.sort(sortByType) self.data.sort(sortByType)
@ -89,10 +109,16 @@
{ {
$(self.refs.listview.root).hide() $(self.refs.listview.root).hide()
$(self.refs.gridview.root).hide() $(self.refs.gridview.root).hide()
$(self.refs.treeview.root).hide() $(self.refs.treecontainer).hide()
self.selectedFile = undefined self.selectedFile = undefined
self.refs.listview.root.set("selected", -1) self.refs.listview.root.set("selected", -1)
self.refs.treeview.selectedItem = undefined self.refs.treeview.selectedItem = undefined
self.refs.treeview.root.set("fetch",function(e,f){
if(!self.fetch) return
self.fetch(e, function(d){
f(getTreeData(d))
})
})
$(self.refs.stbar).html("") $(self.refs.stbar).html("")
switch (self.view) { switch (self.view) {
case 'icon': case 'icon':
@ -102,7 +128,7 @@
$(self.refs.gridview.root).show() $(self.refs.gridview.root).show()
break; break;
case 'tree': case 'tree':
$(self.refs.treeview.root).show() $(self.refs.treecontainer).show()
break; break;
default: default:
break; break;
@ -120,22 +146,43 @@
data.id = self.rid data.id = self.rid
self.root.observable.trigger("fileselect",data) self.root.observable.trigger("fileselect",data)
} }
self.refs.listview.onlistdbclick = function(data)
{
data.id = self.rid
self.root.observable.trigger("filedbclick",data)
}
self.refs.gridview.root.observable = self.root.observable self.refs.gridview.root.observable = self.root.observable
self.refs.gridview.ongridselect = function(d) self.refs.gridview.ongridselect = function(d)
{ {
var data = {id:self.rid, data:self.data[d.data.i], idx:d.data.i} var data = {id:self.rid, data:self.data[d.data.i], idx:d.data.i}
self.root.observable.trigger("fileselect",data) self.root.observable.trigger("fileselect",data)
} }
self.refs.gridview.ongriddbclick = function(d)
{
var data = {id:self.rid, data:self.data[d.data.i], idx:d.data.i}
self.root.observable.trigger("filedbclick",data)
}
self.refs.treeview.ontreeselect = function(d) self.refs.treeview.ontreeselect = function(d)
{ {
if(!d.data) return;
var data = {id:self.rid, data:d.data.child, idx:d.data.i} var data = {id:self.rid, data:d.data.child, idx:d.data.i}
self.root.observable.trigger("fileselect",data) self.root.observable.trigger("fileselect",data)
} }
self.refs.treeview.ontreedbclick = function(d)
{
if(!d.data) return;
var data = {id:self.rid, data:d.data.child, idx:d.data.i}
self.root.observable.trigger("filedbclick",data)
}
self.root.observable.on("fileselect", function(e){ self.root.observable.on("fileselect", function(e){
if(e.id != self.rid) return if(e.id != self.rid) return
self.selectedFile = e.data self.selectedFile = e.data
$(self.refs.stbar).html("Selected: " + e.data.filename + " (" + e.data.size + " bytes)") $(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)
})
calibre_size() calibre_size()
self.root.observable.on("resize", function(e){ self.root.observable.on("resize", function(e){
calibre_size() calibre_size()

View File

@ -1,8 +1,8 @@
<afx-grid-view> <afx-grid-view>
<afx-grid-row ref="gridhead" rootid = {rid} observable = {root.observable} header="true" class = {grid_row_header:header} if = {header} cols = {header}> </afx-grid-row> <afx-grid-row ref="gridhead" rootid = {rid} observable = {root.observable} header="true" class = {grid_row_header:header} if = {header} cols = {header}> </afx-grid-row>
<div ref = "scroller" style="width:100%; overflow:auto;"> <div ref = "scroller" style="width:100%; overflow:auto;">
<div ref = "container"> <div ref = "container" style ="padding-bottom:10px">
<afx-grid-row each={ child, i in rows } class = {selected: child.selected} rootid = {parent.rid} observable = {parent.root.observable} index = {i} cols = {child} onclick = {parent._select} head = {parent.refs.gridhead} ></afx-grid-row> <afx-grid-row each={ child, i in rows } class = {selected: child.selected} rootid = {parent.rid} observable = {parent.root.observable} index = {i} cols = {child} ondblclick = {parent._dbclick} onclick = {parent._select} oncontextmenu = {parent._select} head = {parent.refs.gridhead} ></afx-grid-row>
</div> </div>
</div> </div>
<script> <script>
@ -13,6 +13,7 @@
self.selidx = -1 self.selidx = -1
self.nrow = 0 self.nrow = 0
self.ongridselect = opts.ongridselect self.ongridselect = opts.ongridselect
self.ongriddbclick = opts.ongriddbclick
self.root.observable = opts.observable self.root.observable = opts.observable
self.root.set = function(k,v) self.root.set = function(k,v)
{ {
@ -82,13 +83,22 @@
self.update() self.update()
//event.preventDefault() //event.preventDefault()
} }
_dbclick(event)
{
data = {
id:self.rid,
data:event.item}
if(self.ongriddbclick)
self.ongriddbclick(data)
self.root.observable.trigger('griddbclick', data)
}
</script> </script>
</afx-grid-view> </afx-grid-view>
<afx-grid-row> <afx-grid-row>
<div style = {!header? "display: table-cell;" :""} onclick = {parent._cell_select} each = { child,i in cols } class = {string:typeof child.value == "string", number: typeof child.value == "number", cellselected: parent._auto_cell_select(child,i)} > <div style = {!header? "display: table-cell;" :""} onclick = {parent._cell_select} each = { child,i in cols } class = {string:typeof child.value == "string", number: typeof child.value == "number", cellselected: parent._auto_cell_select(child,i)} >
<afx-label icon = {child.icon} iconclass = {child.iconclass} text = {child.value} ></afx-label> <afx-label color={child.color} icon = {child.icon} iconclass = {child.iconclass} text = {child.value} ></afx-label>
</div> </div>
<script> <script>
this.cols = opts.cols || [] this.cols = opts.cols || []

View File

@ -1,4 +1,4 @@
<afx-hbox> <afx-hbox style = "display:block;">
<div ref = "container" class="afx-hbox-container"> <div ref = "container" class="afx-hbox-container">
<yield/> <yield/>
</div> </div>
@ -26,8 +26,8 @@
{ {
var auto_height = [] var auto_height = []
var csize, ocheight = 0, avaiheight; var csize, ocheight = 0, avaiheight;
avaiheight = $(self.root).parent().height() avaiheight = $(self.root).height()
avaiwidth = $(self.root).parent().width() avaiwidth = $(self.root).width()
$(self.refs.container).css("height",avaiheight + "px") $(self.refs.container).css("height",avaiheight + "px")
$(self.refs.container) $(self.refs.container)
.children() .children()

View File

@ -1,5 +1,5 @@
<afx-label> <afx-label>
<span> <span style = {color?"color:" + color:""} >
<i if={iconclass} class = {iconclass} ></i> <i if={iconclass} class = {iconclass} ></i>
<i if={icon} class="icon-style" style = { "background: url("+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i> <i if={icon} class="icon-style" style = { "background: url("+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i>
{ text } { text }
@ -8,11 +8,13 @@
this.iconclass = opts.iconclass this.iconclass = opts.iconclass
this.icon = opts.icon this.icon = opts.icon
this.text = opts.text this.text = opts.text
this.color = opts.color
var self = this var self = this
this.on("update",function(){ this.on("update",function(){
self.iconclass = opts.iconclass self.iconclass = opts.iconclass
self.icon = opts.icon self.icon = opts.icon
self.text = opts.text self.text = opts.text
self.color = opts.color
}) })
self.root.set = function(k,v) self.root.set = function(k,v)
{ {

View File

@ -3,8 +3,8 @@
<div if = {opts.dropdown == "true"} ref = "current" style = {opts.width?"min-width:" + opts.width + "px;":"min-width:150px;"} onclick = {show_list}> <div if = {opts.dropdown == "true"} ref = "current" style = {opts.width?"min-width:" + opts.width + "px;":"min-width:150px;"} onclick = {show_list}>
</div> </div>
<ul ref = "mlist"> <ul ref = "mlist">
<li each={item,i in items } class={selected: parent._autoselect(item,i)} onclick = {parent._select}> <li each={item,i in items } class={selected: parent._autoselect(item,i)} ondblclick = {parent._dbclick} onclick = {parent._select} oncontextmenu = {parent._select}>
<afx-label iconclass = {item.iconclass} icon = {item.icon} text = {item.text}></afx-label> <afx-label color = {item.color} iconclass = {item.iconclass} icon = {item.icon} text = {item.text}></afx-label>
<i if = {item.closable} class = "closable" click = {parent._remove}></i> <i if = {item.closable} class = "closable" click = {parent._remove}></i>
</li> </li>
</ul> </ul>
@ -14,6 +14,7 @@
var self = this var self = this
self.selidx = -1 self.selidx = -1
self.onlistselect = opts.onlistselect self.onlistselect = opts.onlistselect
self.onlistdbclick = opts.onlistdbclick
var onclose = false var onclose = false
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1 this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
self.root.set = function(k,v) self.root.set = function(k,v)
@ -138,5 +139,15 @@
self.items[self.selidx].selected =false self.items[self.selidx].selected =false
event.item.item.selected = true event.item.item.selected = true
} }
_dbclick(event)
{
data = {
id:self.rid,
data:event.item.item,
idx: event.item.i}
if(self.onlistdbclick)
self.onlistdbclick(data)
self.root.observable.trigger('listdbclick', data)
}
</script> </script>
</afx-list-view> </afx-list-view>

View File

@ -4,7 +4,7 @@
<li ref = "container" each={ data,i in items } class = {afx_submenu:data.child != null, fix_padding:data.icon} no-reorder> <li ref = "container" each={ data,i in items } class = {afx_submenu:data.child != null, fix_padding:data.icon} no-reorder>
<a href="#" onclick = {parent.onselect}> <a href="#" onclick = {parent.onselect}>
<afx-switch if = {data.switch || data.radio} class = {checked:parent.checkItem(data)} enable = false swon = {data.checked} ></afx-switch> <afx-switch if = {data.switch || data.radio} class = {checked:parent.checkItem(data)} enable = false swon = {data.checked} ></afx-switch>
<afx-label iconclass = {data.iconclass} icon = {data.icon} text = {data.text} ></afx-label> <afx-label color = {data.color} iconclass = {data.iconclass} icon = {data.icon} text = {data.text} ></afx-label>
</a> </a>
<afx-menu if={data.child != null} child={data.child} onmenuselect = {data.onmenuselect} observable = {parent.root.observable} rootid = {parent.rid}></afx-menu> <afx-menu if={data.child != null} child={data.child} onmenuselect = {data.onmenuselect} observable = {parent.root.observable} rootid = {parent.rid}></afx-menu>
@ -22,7 +22,7 @@
} }
else else
{ {
this.rid = $(this.root).attr("data-id") this.rid = $(this.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
isRoot = true isRoot = true
} }
var self = this var self = this
@ -94,7 +94,6 @@
{ {
this.root.observable = riot.observable() this.root.observable = riot.observable()
this.root.observable.on('menuselect',function(data){ this.root.observable.on('menuselect',function(data){
//console.log("From root",self.root)
if(self.onmenuselect) if(self.onmenuselect)
self.onmenuselect(data) self.onmenuselect(data)

View File

@ -21,12 +21,17 @@
onmenuselect: function(d) onmenuselect: function(d)
{ {
if(d.e.item.data.type == "app") if(d.e.item.data.type == "app")
window.OS.GUI.launch(d.e.item.data.text) window.OS.GUI.launch(d.e.item.data.text, null)
} }
}, },
{text:"Logout"} {text:"Logout", dataid: "sys-logout"}
]} ]}
] ],
onmenuselect: function(d)
{
if(d.e.item.data.dataid == "sys-logout")
window.OS.API.handler.logout()
}
} }
this.appmenu = { child: [] } this.appmenu = { child: [] }
this.systray = { this.systray = {

View File

@ -1,17 +1,22 @@
<afx-tree-view> <afx-tree-view>
<div ref = namediv class={afx_tree_item_selected:treeroot.selectedItem && treeroot.selectedItem.path == path, afx_folder_item: isFolder(), afx_tree_item_odd: index%2 != 0 } click={select}> <div class={afx_tree_item_selected:treeroot.selectedItem && treeroot.selectedItem.path == path, afx_folder_item: isFolder(), afx_tree_item_odd: index%2 != 0 } onclick={select} ondblclick = {_dbclick} oncontextmenu = {select}>
<i if={ !isFolder() && iconclass} class = {iconclass} ></i> <ul style = "padding:0;margin:0;white-space: nowrap;">
<i if={!isFolder() && icon} class="icon-style" style = { "background: url("+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i> <li ref = "padding" ></li>
<li class = "itemname" style="display:inline-block;" >
<i if={ !isFolder() && iconclass} class = {iconclass} ></i>
<i if={!isFolder() && icon} class="icon-style" style = { "background: url("+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i>
<span onclick={ toggle } if={ isFolder() } class={open ? 'afx-tree-view-folder-open' : 'afx-tree-view-folder-close'}></span> <span onclick={ toggle } if={ isFolder() } class={open ? 'afx-tree-view-folder-open' : 'afx-tree-view-folder-close'}></span>
{ name } { name }
</li>
</ul>
</div> </div>
<ul if={ isFolder() } show={ isFolder() && open }> <ul if={ isFolder() } show={ isFolder() && open }>
<li each={ child, i in nodes }> <li each={ child, i in nodes }>
<afx-tree-view ontreeselect = {parent.ontreeselect} data={child} indent={indent+1} observable = {parent.root.observable} path = {parent.path + ">" + i} treeroot= {parent.treeroot}></afx-tree-view> <afx-tree-view ontreeselect = {parent.ontreeselect} fetch = {parent.fetch} ontreedbclick = {parent.ontreedbclick} data={child} indent={indent+1} observable = {parent.root.observable} path = {parent.path + ">" + i} treeroot= {parent.treeroot}></afx-tree-view>
</li> </li>
</ul> </ul>
@ -28,6 +33,8 @@
} }
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1 this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
self.ontreeselect = opts.ontreeselect self.ontreeselect = opts.ontreeselect
self.ontreedbclick = opts.ontreedbclick
self.fetch = opts.fetch
self.indent = opts.indent || 1 self.indent = opts.indent || 1
var istoggle = false var istoggle = false
if(opts.treeroot) if(opts.treeroot)
@ -66,7 +73,13 @@
} }
this.on("mount", function(){ this.on("mount", function(){
$(self.refs.namediv).css("padding-left", self.indent*15 + "px" ) $(self.refs.padding)
.css("display", "inline-block")
.css("height","1px")
.css("padding",0)
.css("margin", 0)
.css("background-color","transparent")
.css("width", self.indent*15 + "px" )
}) })
isFolder() { isFolder() {
@ -77,6 +90,11 @@
self.open = !self.open self.open = !self.open
e.preventDefault() e.preventDefault()
istoggle = true istoggle = true
if(self.open && self.nodes.length == 0 && self.fetch)
self.fetch(e.item, function(d){
self.nodes = d
self.update()
})
} }
select(event) select(event)
@ -99,5 +117,22 @@
self.treeroot.update() self.treeroot.update()
event.preventDefault() event.preventDefault()
} }
_dbclick(event)
{
if(istoggle)
{
istoggle = false
return
}
data = {
id:self.rid,
data:event.item,
path: self.path}
if(self.ontreedbclick)
{
self.ontreedbclick(data)
}
self.root.observable.trigger('treedbclick', data)
}
</script> </script>
</afx-tree-view> </afx-tree-view>

View File

@ -1,4 +1,4 @@
<afx-vbox> <afx-vbox style = "display:block;">
<div ref = "container" class="afx-vbox-container"> <div ref = "container" class="afx-vbox-container">
<yield/> <yield/>
</div> </div>
@ -23,8 +23,8 @@
{ {
var auto_width = [] var auto_width = []
var csize, ocwidth = 0, avaiheight; var csize, ocwidth = 0, avaiheight;
avaiheight = $(self.root).parent().height() avaiheight = $(self.root).height()
avaiWidth = $(self.root).parent().width() avaiWidth = $(self.root).width()
$(self.refs.container).css("height",avaiheight + "px") $(self.refs.container).css("height",avaiheight + "px")
$(self.refs.container) $(self.refs.container)
.children() .children()

View File

@ -1,8 +1,8 @@
_PM = this.OS.PM _PM = this.OS.PM
_APP = this.OS.APP _APP = this.OS.APP
class ActivityMonitor extends this.OS.GUI.BaseApplication class ActivityMonitor extends this.OS.GUI.BaseApplication
constructor: () -> constructor: (args) ->
super "ActivityMonitor" super "ActivityMonitor", args
main: () -> main: () ->
me = @ me = @
@scheme.set "apptitle", "Activity Monitor" @scheme.set "apptitle", "Activity Monitor"

View File

@ -1,7 +1,7 @@
_GUI = this.OS.GUI _GUI = this.OS.GUI
class DummyApp extends this.OS.GUI.BaseApplication class DummyApp extends this.OS.GUI.BaseApplication
constructor: () -> constructor: (args) ->
super "DummyApp" super "DummyApp", args
main: () -> main: () ->
self = @ self = @
@on "btclick", (e)-> @on "btclick", (e)->
@ -83,7 +83,14 @@ class DummyApp extends this.OS.GUI.BaseApplication
@scheme.set "apptitle", "AntOS feature showcase" @scheme.set "apptitle", "AntOS feature showcase"
@scheme.contextmenuHandler = (e, m) -> @scheme.contextmenuHandler = (e, m) ->
mdata = [ { text: " Child 1" }, { text: "child2", child: [{text: "sub child", child:[{text:"sub sub child"}] }]}] mdata = [
{ text: " Child 1" },
{ text: "child2", child: [
{text: "sub child", child:[{text:"sub sub child"}] },
{text: "sub child 1" }
], onmenuselect: (e) -> console.log e
}
]
m.set "items", mdata m.set "items", mdata
m.show(e) m.show(e)

View File

@ -1,62 +1,146 @@
class Files extends this.OS.GUI.BaseApplication class Files extends this.OS.GUI.BaseApplication
constructor: () -> constructor: (args) ->
super "Files" super "Files", args
main: () -> main: () ->
me = @ me = @
@scheme.set "apptitle", "Files manager" @scheme.set "apptitle", "Files manager"
@view = @find "fileview" @view = @find "fileview"
@scheme.contextmenuHandler = (e, m) -> @navinput = @find "navinput"
mdata = [ { text: " Child 1" }, { text: "child2", child: [{text: "sub child", child:[{text:"sub sub child"}] }]}] @navbar = @find "nav-bar"
m.set "items", mdata @prepaths = []
@favo = @find "favouri"
@loadSetting()
@view.contextmenuHandler = (e, m) ->
m.set "items", [ me.mnFile(), me.mnEdit() ]
m.show(e) m.show(e)
@on "fileselect", (d) -> console.log d #@on "fileselect", (d) -> console.log d
#load home directory @on "filedbclick", (e) ->
p = 'home:///' #if e.data.type is 'dir' then me.chdir e.data.path, true
@_api.VFS.scandir p, @favo.set "onlistselect", (e) -> me.chdir e.data.path, true
($ @find "btback").click () ->
return if me.prepaths.length is 0
p = me.prepaths.pop()
me.favo.set "selected", -1
me.chdir p, false
($ @navinput).keyup (e) ->
me.chdir ($ me.navinput).val() if e.keyCode is 13 #enter
@view.set "chdir", (p) -> me.chdir p, true
@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}"
@favo.set "items", @setting.favorite
loadSetting: () ->
# view setting
@view.set "view", @setting.view if @setting.view
@view.set "showhidden", @setting.showhidden if @setting.showhidden
@setting.favorite = [
{ text: "Applications", path: 'apps:///', iconclass:"fa fa-adn"},
{ 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" },
] if not @setting.favorite
@setting.sidebar = true if @setting.sidebar is undefined
@toggleSidebar @setting.sidebar
@setting.nav = true if @setting.nav is undefined
@toggleNav @setting.nav
chdir: (p, push) ->
me = @
me._api.handler.scandir p,
(d) -> (d) ->
if(d.error)
return me.error "Resource not found #{p}"
v = ($ me.navinput).val()
me.prepaths.push v if push and v isnt ""
($ me.navinput).val p
me.view.set "path", p me.view.set "path", p
me.view.set "data", d.result me.view.set "data", d.result
, (e, s) -> , (e, s) ->
alert "cannot open dir" me.error "Cannot chdir #{p}"
mnFile:() ->
{
text: "File",
child: [
{ text: "New file", dataid: "#{@name}-mkf" },
{ text: "New folder", dataid: "#{@name}-mkdir" },
{ text: "Upload", dataid: "#{@name}-upload" }
]
}
mnEdit: () ->
me = @
{
text: "Edit",
child: [
{ text: "Rename", dataid: "#{@name}-mv" },
{ text: "Delete", dataid: "#{@name}-rm" },
{ text: "Information", dataid: "#{@name}-info" },
{ text: "Open with", dataid: "#{@name}-open" },
{ text: "Download", dataid: "#{@name}-download" },
], onmenuselect: (e) -> me.actionEdit e
}
menu: () -> menu: () ->
me = @ me = @
menu = [ menu = [
{ @mnFile(),
text: "File", @mnEdit(),
child: [
{ text: "New file", dataid: "#{@name}-mkf" },
{ text: "New folder", dataid: "#{@name}-mkdir" },
{ text: "Upload", dataid: "#{@name}-upload" }
]
},
{
text: "Edit",
child: [
{ text: "Rename", dataid: "#{@name}-mv" },
{ text: "Delete", dataid: "#{@name}-rm" },
{ text: "Information", dataid: "#{@name}-info" },
{ text: "Open with", dataid: "#{@name}-open" },
{ text: "Download", dataid: "#{@name}-download" },
]
},
{ {
text: "View", text: "View",
child: [ child: [
{ text: "Refresh", dataid: "#{@name}-refresh" }, { text: "Refresh", dataid: "#{@name}-refresh" },
{ text: "Sidebar", switch: true, dataid: "#{@name}-side" }, { text: "Sidebar", switch: true, checked: @setting.sidebar, dataid: "#{@name}-side" },
{ text: "Navigation bar", switch: true , dataid: "#{@name}-nav" }, { text: "Navigation bar", switch: true, checked: @setting.nav, dataid: "#{@name}-nav" },
{ text: "Hidden files", switch: true, dataid: "#{@name}-hidden" }, { text: "Hidden files", switch: true, checked: @setting.showhidden, dataid: "#{@name}-hidden" },
{ text: "Type", child: [ { text: "Type", child: [
{ text: "Icon view", radio: true, dataid: "#{@name}-icon", type: 'icon' }, { text: "Icon view", radio: true, checked: @setting.view is 'icon', dataid: "#{@name}-icon", type: 'icon' },
{ text: "List view", radio:true, checked: true, dataid: "#{@name}-list", type: 'list' }, { text: "List view", radio:true, checked: @setting.view is 'list' or not @setting.view, dataid: "#{@name}-list", type: 'list' },
{ text: "Tree view", radio:true, dataid: "#{@name}-tree", type: 'tree' } { text: "Tree view", radio:true, checked: @setting.view is 'tree', dataid: "#{@name}-tree", type: 'tree' }
], onmenuselect: (e) -> ], onmenuselect: (e) ->
me.view.set 'view', e.item.data.type me.view.set 'view', e.item.data.type
me.setting.view = e.item.data.type
}, },
] ], onmenuselect: (e) -> me.actionView e
}, },
] ]
menu menu
this.OS.register "Files",Files toggleSidebar: (b) ->
if b then ($ @favo).show() else ($ @favo).hide()
@trigger "resize"
toggleNav: (b) ->
if b then ($ @navbar).show() else ($ @navbar).hide()
@trigger "resize"
actionView: (e) ->
switch e.item.data.dataid
when "#{@name}-hidden"
@.view.set "showhidden", e.item.data.checked
@.setting.showhidden = e.item.data.checked
when "#{@name}-refresh"
@.chdir ($ @.navinput).val(), false
when "#{@name}-side"
@setting.sidebar = e.item.data.checked
@toggleSidebar e.item.data.checked
when "#{@name}-nav"
@setting.nav = e.item.data.checked
@toggleNav e.item.data.checked
actionEdit: (e) ->
switch e.item.data.dataid
when "#{@.name}-info"
file = @view.get "selectedFile"
return unless file
@openDialog "InfoDialog", null, file
else
@_api.handler.setting()
this.OS.register "Files", Files

View File

@ -0,0 +1,36 @@
afx-app-window[data-id ='files-app-window'] afx-list-view{
border-top:1px solid #A6A6A6;
}
afx-app-window[data-id ='files-app-window'] afx-list-view[data-id='favouri']{
background-color: #f6F6F6;
border-right: 1px solid #cbcbcb;
border-top:1px solid #A6A6A6;
padding:0;
}
afx-app-window[data-id ='files-app-window'] afx-list-view[data-id='favouri'] li{
background-color: transparent;
}
afx-app-window[data-id ='files-app-window'] afx-list-view[data-id='favouri'] li.selected {
background-color: #cecece;
color:#414339;
}
afx-app-window[data-id ='files-app-window'] .afx-window-top{
border-bottom: 0;
}
afx-app-window[data-id ='files-app-window'] afx-vbox[data-id = "nav-bar"]{
background-color: #dfdfdf;
}
afx-app-window[data-id ='files-app-window'] afx-grid-view afx-grid-row.grid_row_header div{
border-top:1px solid #A6A6A6;
}
afx-app-window[data-id ='files-app-window'] button{
height: 23px;
border-radius: 3px;
padding-top:2px;
margin-left: 5px;
}
afx-app-window[data-id ='files-app-window'] input{
border-radius: 3px;
}

View File

@ -1,5 +1,14 @@
<afx-app-window apptitle="Files" width="600" height="400"> <afx-app-window data-id = "files-app-window" apptitle="Files" width="600" height="400">
<afx-vbox> <afx-hbox>
<afx-file-view data-id = "fileview"></afx-file-view> <afx-vbox data-height = "30" data-id = "nav-bar">
</afx-vbox> <afx-button data-width = "30" data-id = "btback" iconclass = "fa fa-arrow-left"></afx-button>
</afx-app-window> <input type = "text" data-id = "navinput"></input>
<div data-width = "5"></div>
</afx-vbox>
<afx-vbox>
<afx-list-view data-id = "favouri" data-width = "150">
</afx-list-view>
<afx-file-view data-id = "fileview"></afx-file-view>
</afx-vbox>
</afx-hbox>
</afx-app-window>

View File

@ -1,10 +1,12 @@
class NotePad extends this.OS.GUI.BaseApplication class NotePad extends this.OS.GUI.BaseApplication
constructor: () -> constructor: (args) ->
super "NotePad" super "NotePad", args
main: () -> main: () ->
me = @ me = @
@scheme.set "apptitle", "NotePad" @scheme.set "apptitle", "NotePad"
@sidebar = @find "sidebar"
@location = @find "location"
@fileview = @find "fileview"
div = @find "datarea" div = @find "datarea"
ace.require "ace/ext/language_tools" ace.require "ace/ext/language_tools"
@.editor = ace.edit div @.editor = ace.edit div
@ -53,6 +55,31 @@ class NotePad extends this.OS.GUI.BaseApplication
@on "resize", () -> me.editor.resize() @on "resize", () -> me.editor.resize()
@on "focus", () -> me.editor.focus() @on "focus", () -> me.editor.focus()
@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}"
@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" },
]
chdir: (p) ->
me = @
me._api.handler.scandir p,
(d) ->
if(d.error)
return me.error "Resource not found #{p}"
me.fileview.set "path", p
me.fileview.set "data", d.result
, (e, s) ->
me.error "Cannot chdir #{p}"
menu: ()-> menu: ()->
menu = [{ menu = [{
text:"File", text:"File",

View File

@ -14,3 +14,6 @@ afx-app-window[data-id="notepad"] span[data-id="editorstat"]{
afx-app-window[data-id="notepad"] afx-vbox[data-id="bottom-vbox"]{ afx-app-window[data-id="notepad"] afx-vbox[data-id="bottom-vbox"]{
background-color: #dfdfdf; background-color: #dfdfdf;
} }
afx-app-window[data-id="notepad"] .afx-window-content {
background-color: #f6F6F6;
}

View File

@ -1,25 +1,17 @@
<afx-app-window apptitle="" width="600" height="400" data-id="notepad"> <afx-app-window apptitle="" width="600" height="400" data-id="notepad">
<afx-hbox> <afx-vbox>
<afx-hbox data-width = "175" data-id = "sidebar">
<!--afx-list-view data-id = "flist" data-width = "150" > </afx-list-view> <afx-list-view data-id = "location" dropdown = "true" data-height= "30" width = "150"></afx-list-view>
<afx-file-view data-id = "fileview" view='tree' status = false></afx-file-view>
</afx-hbox>
<afx-hbox> <afx-hbox>
<afx-button data-height="50" text="Read more" iconclass="fa fa-camera-retro fa-lg" id="button"> <div data-id="datarea"></div>
</afx-button> <afx-vbox data-height="30" data-id="bottom-vbox">
<div> <div ><span data-id = "editorstat"></span></div>
big text here <afx-list-view data-width="160" data-id = "themelist" dropdown = "true" width="135"></afx-list-view>
</div> <afx-list-view data-width="125" data-id = "modelist" dropdown = "true" width="100"></afx-list-view>
<div data-height="100" style=" vertical-align: top; width:100%;height:100%;">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</afx-hbox--> </afx-vbox>
<div data-id="datarea"></div> </afx-hbox>
<afx-vbox data-height="30" data-id="bottom-vbox"> </afx-vbox>
<div ><span data-id = "editorstat"></span></div>
<afx-list-view data-width="170" data-id = "themelist" dropdown = "true" width="150"></afx-list-view>
<afx-list-view data-width="170" data-id = "modelist" dropdown = "true" width="150"></afx-list-view>
</afx-vbox>
</afx-hbox>
</afx-app-window> </afx-app-window>

View File

@ -1,6 +1,6 @@
class wTerm extends this.OS.GUI.BaseApplication class wTerm extends this.OS.GUI.BaseApplication
constructor: () -> constructor: (args) ->
super "wTerm" super "wTerm", args
main: () -> main: () ->
me = @ me = @

View File

@ -1,6 +1,6 @@
class Calendar extends this.OS.GUI.BaseService class Calendar extends this.OS.GUI.BaseService
constructor: () -> constructor: (args) ->
super "Calendar" super "Calendar", args
#@iconclass = "fa fa-commenting" #@iconclass = "fa fa-commenting"
@text = "" @text = ""
@iconclass = "fa fa-calendar" @iconclass = "fa fa-calendar"

View File

@ -1,6 +1,6 @@
class PushNotification extends this.OS.GUI.BaseService class PushNotification extends this.OS.GUI.BaseService
constructor: () -> constructor: (args) ->
super "PushNotification" super "PushNotification", args
@iconclass = "fa fa-bars" @iconclass = "fa fa-bars"
@onmenuselect = (e) -> console.log e @onmenuselect = (e) -> console.log e
@cb = undefined @cb = undefined
@ -13,9 +13,11 @@ class PushNotification extends this.OS.GUI.BaseService
spin: (b) -> spin: (b) ->
if b and @iconclass is "fa fa-bars" if b and @iconclass is "fa fa-bars"
@iconclass = "fa fa-spinner fa-spin" @iconclass = "fa fa-spinner fa-spin"
@color = "#f90e00"
@update() @update()
else if not b and @iconclass is "fa fa-spinner fa-spin" else if not b and @iconclass is "fa fa-spinner fa-spin"
@iconclass = "fa fa-bars" @iconclass = "fa fa-bars"
@color = "#414339"
@update() @update()
main: -> main: ->

View File

@ -1,6 +1,6 @@
class Spotlight extends this.OS.GUI.BaseService class Spotlight extends this.OS.GUI.BaseService
constructor: () -> constructor: (args) ->
super "Spotlight" super "Spotlight", args
@iconclass = "fa fa-search" @iconclass = "fa fa-search"
init: -> init: ->
@child = [ @child = [

View File

@ -2,7 +2,7 @@ afx-button button{
outline: none; outline: none;
padding: 4px; padding: 4px;
border: 1px solid #a6a6a6; border: 1px solid #a6a6a6;
background-color: white; background-color: #f6F6F6;
color: #414339; color: #414339;
border-radius: 6px; border-radius: 6px;
font-family: "Ubuntu"; font-family: "Ubuntu";

View File

@ -3,13 +3,13 @@ afx-file-view {
} }
afx-file-view div.status{ afx-file-view div.status{
position: absolute; position: absolute;
bottom: 0px; bottom: 1px;
left:0px; left:0px;
padding:3px; padding:3px;
right: 0px; right: 0px;
height: 15px; height: 15px;
background-color: #dfdfdf; background-color: #f6F6F6;
border-top: 1px solid #a6A6a6; border-top: 1px solid #cbcbcb;
} }
afx-file-view afx-list-view li{ afx-file-view afx-list-view li{
float:left; float:left;
@ -29,7 +29,7 @@ afx-file-view afx-list-view i.dir:before{
content: "\f07b"; content: "\f07b";
font-family: "FontAwesome"; font-family: "FontAwesome";
font-size: 32px; font-size: 32px;
color: #414339; color: #76D2F9;
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
@ -55,7 +55,9 @@ afx-file-view afx-list-view li.selected, afx-file-view afx-list-view li.select
color:white; color:white;
border-radius: 6px; border-radius: 6px;
} }
afx-file-view afx-grid-view{
padding:0;
}
afx-file-view afx-grid-view i.file:before{ afx-file-view afx-grid-view i.file:before{
content: "\f016"; content: "\f016";
font-family: "FontAwesome"; font-family: "FontAwesome";
@ -68,7 +70,7 @@ afx-file-view afx-grid-view i.dir:before{
content: "\f07b"; content: "\f07b";
font-family: "FontAwesome"; font-family: "FontAwesome";
font-size: 16px; font-size: 16px;
color: #414339; color: #76D2F9;
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
} }
@ -83,21 +85,30 @@ afx-file-view afx-grid-view afx-grid-row.grid_row_header{
background-color: #dfdfdf; background-color: #dfdfdf;
} }
afx-file-view afx-grid-view afx-grid-row.grid_row_header div{ afx-file-view afx-grid-view afx-grid-row.grid_row_header div{
border: 1px solid #a6a6a6; border-top: 1px solid #a6a6a6;
border-right: 1px solid #a6a6a6;
} }
afx-file-view afx-tree-view .afx-tree-view-folder-close:before{ afx-file-view afx-tree-view .afx-tree-view-folder-close:before{
content: "\f07b"; content: "\f07b";
font-family: "FontAwesome"; font-family: "FontAwesome";
font-size: 16px; font-size: 16px;
color:#76D2F9;
} }
afx-file-view afx-tree-view .afx-tree-view-folder-open:before{ afx-file-view afx-tree-view .afx-tree-view-folder-open:before{
content: "\f07c"; content: "\f07c";
font-family: "FontAwesome"; font-family: "FontAwesome";
color:#76D2F9;
font-size: 16px; font-size: 16px;
} }
afx-file-view afx-tree-view { afx-file-view afx-tree-view{
margin:0; margin:0;
overflow: hidden;
display: inline-block;
background-color: transparent;
}
afx-file-view afx-tree-view .afx_tree_item_odd{
background-color: transparent;
} }
afx-file-view afx-tree-view i.file:before{ afx-file-view afx-tree-view i.file:before{
content: "\f016"; content: "\f016";
@ -107,8 +118,41 @@ afx-file-view afx-tree-view i.file:before{
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
} }
afx-file-view afx-tree-view div{
overflow: hidden;
white-space: nowrap;
background-color: transparent;
padding:0;
}
afx-file-view div.treecontainer{
display: block;
overflow: auto;
padding:0;
margin:0;
}
afx-file-view afx-tree-view div.afx_tree_item_selected, afx-file-view afx-tree-view div.afx_tree_item_selected:hover{
background-color: transparent;
color:#414339;
}
afx-file-view afx-tree-view div.afx_tree_item_selected i.file:before{ afx-file-view afx-tree-view li.itemname{
padding:3px;
padding-right: 5px;
}
afx-file-view afx-tree-view div.afx_tree_item_selected .itemname{
background-color: #116cd6; background-color: #116cd6;
color:white; color:white;
border-radius: 3px;
}
afx-file-view afx-tree-view div.afx_tree_item_selected i.file:before{
color:white;
}
afx-file-view afx-tree-view .afx_folder_item{
font-weight: normal;
}
afx-file-view afx-tree-view afx-tree-view{
display: inline-block;
} }

View File

@ -7,6 +7,7 @@ afx-tree-view{
afx-tree-view afx-tree-view{ afx-tree-view afx-tree-view{
padding:0; padding:0;
overflow: hidden; overflow: hidden;
display: block;
} }
afx-tree-view ul{ afx-tree-view ul{
margin:0; margin:0;

View File

@ -5,8 +5,9 @@ html,body{
font-size: 13px; font-size: 13px;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-image: url(wallpaper.jpg); background-image: url(wp.png);
background-size: cover; /*background-size: cover;*/
background-repeat: repeat;
overflow: hidden; overflow: hidden;
} }
#wrapper{ #wrapper{
@ -46,7 +47,7 @@ input {
padding: 2px; padding: 2px;
height:23px; height:23px;
border: 1px solid #a6a6a6; border: 1px solid #a6a6a6;
background-color: white; background-color: #f6F6F6;
color: #414339; color: #414339;
border-radius: 5px; border-radius: 5px;
box-sizing: border-box; box-sizing: border-box;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

BIN
src/themes/antos/wp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB