core for app development

This commit is contained in:
Xuan Sang LE 2017-08-14 00:20:19 +02:00
parent f4c54c712d
commit 2985689217
43 changed files with 1414 additions and 172 deletions

View File

@ -1,14 +1,16 @@
BUILDDIR = build/htdocs BUILDDIR = build/htdocs
BLUE=\033[0;34m BLUE=\033[1;34m
NC=\033[0m NC=\033[0m
coffees= src/define.coffee\ coffees= src/define.coffee\
src/core/apis/api.coffee\ src/core/api.coffee\
src/core/apis/handlers/InBrowserHandler.coffee\ src/core/processes.coffee\
src/core/handlers/InBrowserHandler.coffee\
src/core/gui/gui.coffee\ src/core/gui/gui.coffee\
src/core/gui/BaseApplication.coffee\ src/core/gui/BaseApplication.coffee\
src/core/gui/BaseEvent.coffee\
src/antos.coffee src/antos.coffee
tags= src/core/gui/tags/afx-button.js\ tags= src/core/gui/tags/afx-button.js\
@ -18,7 +20,9 @@ tags= src/core/gui/tags/afx-button.js\
src/core/gui/tags/afx-app-window.js\ src/core/gui/tags/afx-app-window.js\
src/core/gui/tags/afx-vbox.js\ src/core/gui/tags/afx-vbox.js\
src/core/gui/tags/afx-hbox.js\ src/core/gui/tags/afx-hbox.js\
src/core/gui/tags/afx-list-view.js src/core/gui/tags/afx-list-view.js\
src/core/gui/tags/afx-tree-view.js \
src/core/gui/tags/afx-grid-view.js
antos_themes = src/core/gui/themes/antos/font-awesome.css\ antos_themes = src/core/gui/themes/antos/font-awesome.css\
src/core/gui/themes/antos/ubuntu-regular.css\ src/core/gui/themes/antos/ubuntu-regular.css\
@ -28,19 +32,23 @@ antos_themes = src/core/gui/themes/antos/font-awesome.css\
src/core/gui/themes/antos/afx-menu.css\ src/core/gui/themes/antos/afx-menu.css\
src/core/gui/themes/antos/afx-sys-panel.css\ src/core/gui/themes/antos/afx-sys-panel.css\
src/core/gui/themes/antos/afx-dock.css\ src/core/gui/themes/antos/afx-dock.css\
src/core/gui/themes/antos/afx-app-window.css src/core/gui/themes/antos/afx-list-view.css\
src/core/gui/themes/antos/afx-tree-view.css\
src/core/gui/themes/antos/afx-grid-view.css\
src/core/gui/themes/antos/afx-app-window.css
packages = NotePad
main: build_coffee build_tag build_theme schemes libs packages_builds packages = NotePad Terminal ActivityMonitor
main: clean build_coffee build_tag build_theme schemes libs build_packages
- cp src/index.html $(BUILDDIR)/ - cp src/index.html $(BUILDDIR)/
#%.js: %.coffee #%.js: %.coffee
# coffee --compile $< # coffee --compile $<
build_coffee: build_coffee:
- echo "$(BLUE)=======Building coffee files=======$(NC)" @echo "$(BLUE)=======Building coffee files=======$(NC)"
- mkdir $(BUILDDIR)/scripts - mkdir $(BUILDDIR)/scripts
- rm $(BUILDDIR)/scripts/antos.js - rm $(BUILDDIR)/scripts/antos.js
for f in $(coffees); do (cat "$${f}"; echo) >> $(BUILDDIR)/scripts/antos.coffee; done for f in $(coffees); do (cat "$${f}"; echo) >> $(BUILDDIR)/scripts/antos.coffee; done
@ -49,36 +57,37 @@ build_coffee:
libs: libs:
- echo "$(BLUE)=======Copy lib files=======$(NC) @echo "$(BLUE)=======Copy lib files=======$(NC)"
- cp -rf src/libs/* $(BUILDDIR)/scripts cp -rf src/libs/* $(BUILDDIR)/scripts/
schemes: schemes:
- echo "$(BLUE)=======Copy schemes files======= $(NC)" @echo "$(BLUE)=======Copy schemes files======= $(NC)"
- mkdir -p $(BUILDDIR)/resources/schemes - mkdir -p $(BUILDDIR)/resources/schemes
- cp src/core/gui/schemes/* $(BUILDDIR)/resources/schemes cp src/core/gui/schemes/* $(BUILDDIR)/resources/schemes/
build_tag: build_tag:
- echo "=======$(BLUE)Building tag files=======$(NC)" @echo "=======$(BLUE)Building tag files=======$(NC)"
-mkdir $(BUILDDIR)/resources -mkdir $(BUILDDIR)/resources
-rm $(BUILDDIR)/resources/antos_tags.js -rm $(BUILDDIR)/resources/antos_tags.js
- for f in $(tags); do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/antos_tags.js; done for f in $(tags); do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/antos_tags.js; done
build_theme: antos_themes_build build_theme: antos_themes_build
antos_themes_build: antos_themes_build:
- echo "=======$(BLUE)Building themes name: antos=======$(NC)" @echo "=======$(BLUE)Building themes name: antos=======$(NC)"
-rm -rf $(BUILDDIR)/resources/themes/antos/*
-mkdir -p $(BUILDDIR)/resources/themes/antos -mkdir -p $(BUILDDIR)/resources/themes/antos
- for f in $(antos_themes); do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/themes/antos/antos.css; done for f in $(antos_themes); 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/core/gui/themes/antos/fonts/* $(BUILDDIR)/resources/themes/antos/fonts cp -rf src/core/gui/themes/antos/fonts/* $(BUILDDIR)/resources/themes/antos/fonts
- cp src/core/gui/themes/antos/wallpaper.jpg $(BUILDDIR)/resources/themes/antos/ cp src/core/gui/themes/antos/wallpaper.jpg $(BUILDDIR)/resources/themes/antos/
packages_builds: build_packages:
- mkdir $(BUILDDIR)/packages - mkdir $(BUILDDIR)/packages
- for d in $(packages); do (cd src/packages/$$d; make);done for d in $(packages); do (cd src/packages/$$d; make);done
- for d in $(packages); do ( test -d $(BUILDDIR)/packages/$$d || mkdir -p $(BUILDDIR)/packages/$$d && cp -rf src/packages/$$d/build/* $(BUILDDIR)/packages/$$d/);done for d in $(packages); do ( test -d $(BUILDDIR)/packages/$$d || mkdir -p $(BUILDDIR)/packages/$$d && cp -rf src/packages/$$d/build/* $(BUILDDIR)/packages/$$d/);done
- for d in $(packages); do ( test -d src/packages/$$d/build && rm -r src/packages/$$d/build ); done for d in $(packages); do ( test -d src/packages/$$d/build && rm -r src/packages/$$d/build ); done
clean: clean:
rm -rf $(BUILDDIR)/* rm -rf $(BUILDDIR)/*

View File

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

View File

@ -13,13 +13,12 @@ self.OS.API =
_API.request 'config', (result) -> _API.request 'config', (result) ->
console.log result console.log result
get:(p,c)=> get:(p,c,f)->
$.get p $.get p
.done (data) -> .done (data) ->
c(data) c(data)
.fail -> .fail ->
alert "cannot get data" f()
c(null)
resource: (resource,callback) -> resource: (resource,callback) ->
path = "resources/#{resource}" path = "resources/#{resource}"
_API.get path,callback _API.get path,callback

View File

@ -1,21 +1,88 @@
self = this
_PM = self.OS.PM
_APP = self.OS.APP
class BaseApplication class BaseApplication
constructor: (@name) -> constructor: (@name) ->
@observable = riot.observable() @observable = riot.observable()
@pid = 0
@_api = self.OS.API
init: -> init: ->
#first load the scheme me = @
# first register some base event to the app
@on "exit", ()-> me.quit()
@on "focus", () ->
me.sysdock.set "selectedApp", me
me.appmenu.pid = me.pid
me.appmenu.set "items", (me.baseMenu() || [])
me.appmenu.set "onmenuselect", (d)->
me.trigger("menuselect",d)
@on "hide", ()->
me.sysdock.set "selectedApp", null
me.appmenu.set "items",[]
@on "menuselect", (item) ->
switch item.data.dataid
when "#{me.name}-about" then alert "About " + me.pid + me.name
when "#{me.name}-exit" then me.trigger "exit"
#now load the scheme
path = "packages/#{@name}/scheme.html" path = "packages/#{@name}/scheme.html"
@scheme = _GUI.loadScheme path,@observable _GUI.loadScheme path ,this
#if(!scheme) bug repporter go here
@event()
event: ->
#implement by subclasses
on: (e,f) -> @observable.on e,f on: (e,f) -> @observable.on e,f
trigger:(e,d) -> @observable.trigger e,d trigger:(e,d) -> @observable.trigger e,d
show: () ->
@observable.trigger "focus"
blur: () ->
@.appmenu.set "items",[] if @.appmenu and @.pid == @.appmenu.pid
@observable.trigger "blur"
hide: () ->
@observable.trigger "hide"
toggle:() ->
@observable.trigger "toggle"
quit: () ->
evt = new _GUI.BaseEvent("exit")
@exit(evt)
if not evt.prevent
@.appmenu.set "items",[] if @.pid == @.appmenu.pid
_PM.kill(@)
($ @scheme).remove()
find: (id) -> ($ "[data-id='#{id}']",@scheme)[0]
baseMenu:->
menu =
[{
text:_APP[@name].meta.name,
child:[
{text:"About", dataid:"#{@name}-about"},
{text:"Exit", dataid:"#{@name}-exit"}
]
}]
menu = menu.concat @menu() || []
menu
main: ->
#main program
# implement by subclasses
menu: ->
# implement by subclasses
# to add menu to application
[]
open:-> open:->
#implement by subclasses #implement by subclasses
data:-> data:->
#implement by subclasses #implement by subclasses
# to return app data
update:-> update:->
#implement by subclasses #implement by subclasses
exit: (e) ->
this.OS.GUI.BaseApplication = BaseApplication #implement by subclasses
# to handle the exit event
# use e.preventDefault() to
# discard the quit command
this.OS.GUI.BaseApplication = BaseApplication

View File

@ -0,0 +1,7 @@
class BaseEvent
constructor: (@name) ->
@prevent = false
preventDefault:()->
@prevent = true
this.OS.GUI.BaseEvent = BaseEvent

View File

@ -1,82 +1,109 @@
self.OS.GUI = self.OS.GUI =
tagPath: "resources/tags/"
init: () -> init: () ->
query = query =
path: 'VFS/get' path: 'VFS/get'
data: "#{_GUI.tagPath}/tags.json" data: "#{_GUI.tagPath}/tags.json"
self.OS.API.request query, ()-> self.OS.API.request query, ()->
loadScheme: (path, obs) -> loadScheme: (path,app) ->
_API.get path, (x) -> _API.get path,
(x) ->
return null unless x return null unless x
scheme = $.parseHTML x scheme = $.parseHTML x
($ "#desktop").append scheme ($ "#desktop").append scheme
riot.mount ($ scheme), {observable:obs} riot.mount ($ scheme), {observable:app.observable}
scheme app.scheme = scheme[0]
app.show()
app.main()
, (f) ->
alert "cannot load scheme"
loadTheme: (name) -> loadTheme: (name) ->
path = "resources/themes/#{name}/#{name}.css" path = "resources/themes/#{name}/#{name}.css"
$ "head link#ostheme" $ "head link#ostheme"
.attr "href", path .attr "href", path
launch: (app) -> launch: (app) ->
if not _APP[app] if not _APP[app]
# first load it # first load it
path = "packages/#{app}/main.js" path = "packages/#{app}/"
$.getScript path $.getScript path + "main.js"
.done (e,s) -> .done (e,s) ->
#load css file
$.get "#{path}main.css", () ->
$ '<link>', {rel:'stylesheet', type:'text/css', 'href':"#{path}main.css"}
.appendTo 'head'
#launch #launch
_app = new _APP[app] if _APP[app]
_app.init() # load app meta data
console.log "Fist time loading "+app _API.get "#{path}package.json",
(data) ->
_APP[app].meta = data
_PM.createProcess app, _APP[app]
console.log "Fist time loading "+app
,(e,s)->
alert "cannot read application, meta-data"
.fail (e,s) -> .fail (e,s) ->
#BUG report here #BUG report here
console.log "bug report" console.log "bug report"
else else
# now launch it # now launch it
_app = new _APP[app] if _APP[app]
_app.init() _PM.createProcess app, _APP[app]
dock: (app,meta) ->
# dock an application to a dock
# create a data object
data =
icon:null
iconclass:meta.iconclass||""
app:app
onbtclick:() ->
app.toggle()
data.icon = "packages/#{meta.app}/#{meta.icon}" if meta.icon
data.iconclass = "fa fa-cogs" if (not meta.icon) and (not meta.iconclass)
dock = $ "#sysdock"
dock.get(0).newapp data
app.sysdock = dock.get(0)
app.appmenu = ($ "[data-id = 'appmenu']","#syspanel")[0]
app.init()
#app.show() -- notwork, sice the scheme is not loaded yet
undock: (app) ->
($ "#sysdock").get(0).removeapp app
initDM: -> initDM: ->
_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
($ "#wrapper").append scheme ($ "#wrapper").append scheme
#riot.mount $ "#button", $ "#wrapper" ($ "#desktop").on "click", (e)->
return if e.target isnt ($ "#desktop").get(0)
($ "#sysdock").get(0).set "selectedApp",null
osmenu = {child:[ osmenu = {child:[
{text:"",icon:"fa fa-circle", child:[ {text:"",iconclass:"fa fa-eercast", child:[
{text:"About"}, {text:"About"},
{text:"System Preferences", icon:"fa fa-commenting"}, {text:"System Preferences", iconclass:"fa fa-commenting"},
{text:"Applications",child:[{text:"Terminal"},{text:"Text edit"}]}, {text:"Applications",child:[
{text:"Terminal",type:"app"},
{text:"NotePad",type:"app", icon:"packages/NotePad/icon.png"},
{text:"ActivityMonitor",type:"app"}
]},
{text:"Logout"} {text:"Logout"}
]} ]}
], ],onmenuselect: (item)->
onmenuselect: (item)-> switch item.data.type
console.log item when "app" then _GUI.launch item.data.text
_GUI.launch "NotePad"
} }
appmenu = {child:[ appmenu = {child:[]}
{text:"Text edit", child:[
{text:"About"},
{text:"Preferences"},
{text:"Exit"}
]},
{text:"File",child:[
{text:"Open"},{text:"Save"}]}
],
onmenuselect: (item)-> console.log item}
systray = {child:[ systray = {child:[
{text:"Sun 22:57 6 August 2017"}, {text:"Sun 22:57 6 August 2017"},
{text:"",icon:"fa fa-search"}, {text:"",iconclass:"fa fa-search"},
{text:"",icon:"fa fa-commenting"} {text:"",iconclass:"fa fa-commenting"}
], ],onmenuselect: (item)->
onmenuselect: (item)-> console.log item
console.log item
} }
riot.mount ($ "#syspanel", $ "#wrapper"),{osmenu:osmenu,appmenu:appmenu,systray:systray} riot.mount ($ "#syspanel", $ "#wrapper"),{osmenu:osmenu,appmenu:appmenu,systray:systray}
riot.mount ($ "#sysdock", $ "#wrapper"), {items:[]}
docks = {items:[
{icon:"fa fa-cogs"},
{icon:"fa fa-life-ring"},
{icon:"fa fa-cubes"}
]}
riot.mount ($ "#sysdock", $ "#wrapper"), docks

View File

@ -1,8 +1,8 @@
<afx-app-window ref = "window"> <afx-app-window ref = "window" >
<div class = "afx-window-wrapper" > <div class = "afx-window-wrapper">
<ul class= "afx-window-top"> <ul class= "afx-window-top" >
<li class = "afx-window-close"></li> <li class = "afx-window-close" onclick = {close}></li>
<li class = "afx-window-minimize"></li> <li class = "afx-window-minimize" onclick = {minimize}></li>
<li class = "afx-window-maximize" onclick={maximize}></li> <li class = "afx-window-maximize" onclick={maximize}></li>
<li ref = "dragger" class = "afx-window-title">{ apptitle }</li> <li ref = "dragger" class = "afx-window-title">{ apptitle }</li>
</ul> </ul>
@ -25,6 +25,32 @@
var height = opts.height || 300 var height = opts.height || 300
this.root.observable = opts.observable || riot.observable() this.root.observable = opts.observable || riot.observable()
if(!window._zidex) window._zidex = 10 if(!window._zidex) window._zidex = 10
this.shown = false
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
return self[k]
}
self.root.update = function()
{
self.update()
}
minimize()
{
this.root.observable.trigger("hide")
}
close()
{
this.root.observable.trigger("exit")
}
this.on('mount', function() { this.on('mount', function() {
var left,top var left,top
left = 20 + Math.floor(Math.random() * width) left = 20 + Math.floor(Math.random() * width)
@ -37,8 +63,13 @@
.css("height", height + "px") .css("height", height + "px")
.css("z-index",window._zidex++) .css("z-index",window._zidex++)
$(self.refs.window).on("mousedown", function(e){ $(self.refs.window).on("mousedown", function(e){
window._zidex++ if(self.shown == false)
$(self.refs.window).css("z-index",window._zidex) self.root.observable.trigger("focus")
})
$(self.refs.window).click(function(e) {
//e.stopPropagation()
//e.windowactive = true
//self.root.observable.trigger("windowselect")
}) })
enable_dragging() enable_dragging()
if(isResize) if(isResize)
@ -49,6 +80,34 @@
$(self.refs.content).children().each(function(e){ $(self.refs.content).children().each(function(e){
this.observable = self.root.observable this.observable = self.root.observable
}) })
self.root.observable.on("focus",function(){
window._zidex++
$(self.refs.window)
.show()
.css("z-index",window._zidex)
.removeClass("unactive")
self.shown = true
})
self.root.observable.on("blur", function(){
self.shown = false
$(self.refs.window)
.addClass("unactive")
// add css to blur app :)
})
self.root.observable.on("hide", function()
{
$(self.refs.window).hide()
self.shown = false
})
self.root.observable.on("toggle", function(){
if(self.shown)
self.root.observable.trigger("hide")
else
self.root.observable.trigger("focus")
})
}) })
var enable_dragging = function() var enable_dragging = function()
{ {
@ -112,7 +171,8 @@
.css("width", w +"px") .css("width", w +"px")
.css("height",h + "px") .css("height",h + "px")
isMaxi = false isMaxi = false
self.root.observable.trigger('resize',w,h) self.root.observable.trigger('resize',
{id:$(self.root).attr("data-id"),w:w,h:h})
}) })
$(window).on("mouseup", function(e){ $(window).on("mouseup", function(e){
$(window).unbind("mousemove", null) $(window).unbind("mousemove", null)
@ -137,7 +197,8 @@
.css("width", w + "px") .css("width", w + "px")
.css("height", h + "px") .css("height", h + "px")
.css("top","0").css("left","0") .css("top","0").css("left","0")
self.root.observable.trigger('resize',w,h) self.root.observable.trigger('resize',
{id:$(self.root).attr("data-id"),w:w,h:h})
isMaxi = true isMaxi = true
} }
else else
@ -147,7 +208,8 @@
.css("width",history.width) .css("width",history.width)
.css("height",history.height) .css("height",history.height)
.css("top",history.top).css("left",history.left) .css("top",history.top).css("left",history.left)
self.root.observable.trigger('resize',history.width, history.height) self.root.observable.trigger('resize',
{id:$(self.root).attr("data-id"),w:history.width,h:history.height} )
} }
} }

View File

@ -1,7 +1,60 @@
<afx-apps-dock> <afx-apps-dock>
<afx-button each={ items } icon = {icon} text = {text}> <afx-button class = {selected: parent.selectedApp && app.pid == parent.selectedApp.pid} each={ items } icon = {icon} text = {text} onbtclick = {onbtclick}>
</afx-button> </afx-button>
<script> <script>
this.items = opts.items this.items = opts.items || []
var self = this
self.selectedApp = null
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
{
self[k] = v
if(k == "selectedApp")
{
for(var i in self.items)
self.items[i].app.blur()
//v.show()
}
}
self.update()
}
self.root.newapp = function(i)
{
self.items.push(i)
self.selectedApp = i.app
self.update()
for(var i in self.items)
self.items[i].app.blur()
}
self.root.removeapp = function(a)
{
var i = -1;
for(var k in self.items)
if(self.items[k].app.pid == a.pid)
{
i = k; break;
}
if(i != -1)
{
delete self.items[i].app
self.items.splice(i,1)
self.update()
}
}
self.root.get = function(k)
{
return self[k]
}
self.root.update = function()
{
self.update()
}
</script> </script>
</afx-apps-dock> </afx-apps-dock>

View File

@ -1,20 +1,41 @@
<afx-button> <afx-button>
<button disabled={ enable == "false" } onclick="{ _onbtclick }" > <button disabled={ enable == "false" } onclick="{ _onbtclick }" >
<i class = { icon } ></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>
{ opts.text } { opts.text }
</button> </button>
<script> <script>
this.enable = opts.enable this.enable = opts.enable
this.icon = opts.icon this.icon = opts.icon
this.iconclass = opts.iconclass
var self = this var self = this
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
return self[k]
}
self.root.update = function()
{
self.update()
}
this._onbtclick = function(e) this._onbtclick = function(e)
{ {
if(opts.onbtclick) if(typeof opts.onbtclick == 'string')
eval(opts.onbtclick) eval(opts.onbtclick())
else if(opts.onbtclick)
opts.onbtclick()
if(self.root.observable) if(self.root.observable)
{ {
console.log("btclick") self.root.observable.trigger("btclick",{id:$(self.root).attr("data-id"),data:self.root})
self.root.observable.trigger("btclick",this)
} }
} }
</script> </script>

View File

@ -0,0 +1,162 @@
<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>
<div ref = "scroller" style="width:100%; overflow:auto;">
<div ref = "container">
<afx-grid-row each={ child, i in rows } class = {selected: child.selected} rootid = {parent.rid} observable = {parent.root.observable} cols = {child} onclick = {parent._select}></afx-grid-row>
</div>
</div>
<script>
this.rows= []
if(opts.data)
{
this.header = opts.data.header
this.rows = opts.data.data
}
var self = this
this.rid = $(self.root).attr("data-id")
self.selidx = -1
self.nrow = 0
self.root.set = function(k,v)
{
if(k == "selected")
self._select({item:self.rows[v], preventDefault:function(){}})
else if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
var calibrate_size = function()
{
if(self.header)
{
$(self.refs.scroller).css("height",
$(self.root).height() - $(self.refs.gridhead.root).height()
+ "px")
}
else
$(self.refs.scroller).css("height","100%")
}
self.root.get = function(k)
{
if(k == "selected")
return (self.selidx == -1?null:self.rows[self.selidx])
return self[k]
}
if(opts.observable)
this.root.observable = opts.observable
else
{
this.root.observable = riot.observable()
}
this.on("mount", function(){
$(self.refs.container)
.css("display","flex")
.css("flex-direction","column")
.css("width","100%")
calibrate_size()
this.root.observable.on("resize",function(){
calibrate_size()
if(self.refs.gridhead)
self.refs.gridhead.calibrate_size()
})
})
this.on("updated",function(){
if(self.selidx >= self.rows.length)
self.selidx = -1
if(self.nrow == self.rows.length) return
self.nrow = self.rows.length
calibrate_size()
if(self.refs.gridhead)
self.refs.gridhead.calibrate_size()
})
_select(event)
{
var data = {
id:self.rid,
data:event.item}
if(opts.onlistselect)
opts.onlistselect(data)
console.log(data)
if(self.selidx != -1)
self.rows[self.selidx].selected =false
self.selidx = event.item.i
self.rows[self.selidx].selected = true
this.root.observable.trigger('gridselect',data)
event.preventUpdate = true
self.update()
event.preventDefault()
}
</script>
</afx-grid-view>
<afx-grid-row>
<div style = "flex-grow:1;" each = { child,i in cols } class = {string:typeof child.value == "string", number: typeof child.value == "number"} >
<i if={child.iconclass} class = {child.iconclass} ></i>
<i if={child.icon} class="icon-style" style = { "background: url("+child.icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i>
{child.value}
</div>
<script>
this.cols = opts.cols || []
var self = this
this.rid = opts.rootid
this.observable = opts.observable
this.header = opts.header||false
this.calibrate_size = function()
{
if(!self.cols || self.cols.length == 0 || !self.observable) return
var totalw = $(self.root).parent().width()
var ocw = 0
var nauto = 0
var dist = []
$.each(self.cols, function(i,e){
if(e.width)
{
dist.push(e.width)
ocw += e.width
}
else
{
dist.push(-1)
nauto++
}
})
if(nauto > 0)
{
var cellw = (totalw - ocw)/ nauto
$.each(dist,function(i,e){
if(e == -1) dist[i] = cellw
})
}
self.observable.trigger("cellresize",{id:self.rid,data:dist})
}
self.observable.on("cellresize",function(d){
if(d.id && d.id == self.rid)
{
var i = 0
$(self.root)
.children()
.each(function(){
$(this).css("width", d.data[i]+"px")
i++
})
}
})
this.on("mount", function(){
$(self.root)
.css("display","flex")
.css("flex-direction","row")
.css("width","100%")
if(self.header)
self.calibrate_size()
})
</script>
</afx-grid-row>

View File

@ -4,14 +4,30 @@
</div> </div>
<script> <script>
var self = this var self = this
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
return self[k]
}
self.root.update = function()
{
self.update()
}
this.on('mount', function(){ this.on('mount', function(){
$(self.refs.container) $(self.refs.container)
.css("display","flex") .css("display","flex")
.css("flex-direction","column") .css("flex-direction","column")
.css("width","100%") .css("width","100%")
.css("background-color","red") //.css("background-color","red")
.css("table-layout","fixed") //.css("overflow", "hidden")
.css("overflow", "hidden")
calibrate_size() calibrate_size()
@ -36,7 +52,7 @@
this.observable = self.root.observable this.observable = self.root.observable
$(this) $(this)
.css("flex-grow","1") .css("flex-grow","1")
.css("border","1px solid black") //.css("border","1px solid black")
var dw = $(this).attr("data-height") var dw = $(this).attr("data-height")
if(dw) if(dw)
{ {

View File

@ -1,29 +1,101 @@
<afx-list-view> <afx-list-view class = {dropdown: opts.dropdown == "true"}>
<ul> <div class = "list-container" ref = "container">
<li each={ items } class = {child != null ? "afx-sublist":""} onclick = {parent.onselect}> <div if = {opts.dropdown == "true"} ref = "current" style = {opts.width?"min-width:" + opts.width + "px;":"min-width:150px;"} onclick = {show_list}>
<afx-list-view if={child != null} child={child} observable = {parent.observable} ></afx-list-view> {selectedText}
</div>
<ul ref = "mlist">
<li each={ items } class={selected: selected} onclick = {parent._select}>
<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>
{ text }
</li> </li>
</ul> </ul>
</div>
<script> <script>
this.items = opts.child this.items = opts.child
var self = this
self.selidx = -1
self.selectedText = ""
self.onlistselect = opts.onlistselect
self.root.set = function(k,v)
{
if(k == "selected")
self._select({item:self.items[v], preventDefault:function(){}})
else if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.update = function()
{
self.update()
}
self.root.get = function(k)
{
if(k == "selected")
return self.items[self.selidx]
return self[k]
}
if(opts.observable) if(opts.observable)
this.observable = opts.observable this.root.observable = opts.observable
else if(this.root.observable)
this.observable = this.root.observable
else else
{ {
this.observable = riot.observable() this.root.observable = riot.observable()
this.observable.on('listselect',function(data){
if(opts.listselect)
opts.listselect(data)
})
} }
this.on("mount", function(){
onselect(event) if(opts.dropdown == "true")
{
$(document).click(function(event) {
if(!$(event.target).closest(self.refs.container).length) {
$(self.refs.mlist).hide()
}
})
//$(self.root).css("position","relative")
$(self.refs.container)
.css("position","absolute")
.css("display","inline-block")
$(self.refs.mlist)
.css("position","absolute")
.css("display","none")
.css("top","100%")
.css("left","0")
}
})
show_list()
{ {
var desktoph = $("#desktop").height()
this.observable.trigger('listselect',event.item) var off = $(self.root).offset().top + $(self.refs.mlist).height()
event.preventDefault() console.log(desktoph,off)
if( off > desktoph )
$(self.refs.mlist)
.css("top","-" + $(self.refs.mlist).outerHeight() + "px")
else
$(self.refs.mlist).css("top","100%")
$(self.refs.mlist).show()
}
_select(event)
{
var data = {
id:$(self.root).attr("data-id"),
data:event.item,
idx:self.items.indexOf(event.item)}
if(self.selidx != -1)
self.items[self.selidx].selected =false
self.selidx = data.idx
self.items[self.selidx].selected = true
if(opts.dropdown == "true")
{
$(self.refs.mlist).hide()
self.selectedText = self.items[self.selidx].text
}
if(self.onlistselect)
self.onlistselect(data)
this.root.observable.trigger('listselect',data)
event.preventDefault()
} }
</script> </script>
</afx-list-view> </afx-list-view>

View File

@ -1,17 +1,42 @@
<afx-menu> <afx-menu>
<ul> <ul>
<li class="afx-corner-fix"></li> <li class="afx-corner-fix"></li>
<li each={ items } class = {child != null ? "afx-submenu":""}> <li each={ items } class = {afx_submenu:child != null, fix_padding:icon}>
<a href="#" onclick = {parent.onselect}> <a href="#" onclick = {parent.onselect}>
<i class = {icon} ></i>{ text } <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>
{ text }
</a> </a>
<afx-menu if={child != null} child={child} observable = {parent.root.observable} ></afx-menu> <afx-menu if={child != null} child={child} onmenuselect={onmenuselect} observable = {parent.root.observable} rootid = {parent.rid}></afx-menu>
</li> </li>
<li class="afx-corner-fix"></li> <li class="afx-corner-fix"></li>
</ul> </ul>
<script> <script>
this.items = opts.child this.items = opts.child
if(opts.rootid)
this.rid = opts.rootid
else
this.rid = $(this.root).attr("data-id")
var self = this
this.onmenuselect = opts.onmenuselect
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
return self[k]
}
self.root.update = function()
{
self.update()
}
if(opts.observable) if(opts.observable)
{ {
this.root.observable = opts.observable this.root.observable = opts.observable
@ -20,17 +45,24 @@
{ {
this.root.observable = riot.observable() this.root.observable = riot.observable()
this.root.observable.on('menuselect',function(data){ this.root.observable.on('menuselect',function(data){
if(opts.onmenuselect) //console.log("From root",self.root)
if(self.onmenuselect)
{ {
opts.onmenuselect(data) self.onmenuselect(data)
} }
}) })
} }
onselect(event) onselect(event)
{ {
this.root.observable.trigger('menuselect',event.item) var data = {id:self.rid, data:event.item}
/*if(self.onmenuselect)
{
self.onmenuselect(data)
} else*/
this.root.observable.trigger('menuselect',data)
event.preventDefault() event.preventDefault()
} }

View File

@ -1,8 +1,8 @@
<afx-sys-panel> <afx-sys-panel>
<div> <div>
<afx-menu ref = "aOsmenu" child={osmenu.child} onmenuselect = {osmenu.onmenuselect} class="afx-panel-os-menu"></afx-menu> <afx-menu data-id = "os_menu" ref = "aOsmenu" child={osmenu.child} onmenuselect = {osmenu.onmenuselect} class="afx-panel-os-menu"></afx-menu>
<afx-menu ref = "aAppmenu" child={appmenu.child} onmenuselect = {appmenu.onmenuselect} class = "afx-panel-os-app"></afx-menu> <afx-menu data-id = "appmenu" ref = "aAppmenu" child={appmenu.child} onmenuselect = {appmenu.onmenuselect} class = "afx-panel-os-app"></afx-menu>
<afx-menu ref = "aTray" child={systray.child} onmenuselect = {systray.onmenuselect} class = "afx-panel-os-stray"></afx-menu> <afx-menu data-id = "sys_tray" ref = "aTray" child={systray.child} onmenuselect = {systray.onmenuselect} class = "afx-panel-os-stray"></afx-menu>
</div> </div>
<script> <script>
@ -10,6 +10,24 @@
this.appmenu = opts.appmenu this.appmenu = opts.appmenu
this.systray = opts.systray this.systray = opts.systray
var self = this var self = this
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
return self[k]
}
self.root.update = function()
{
self.update()
}
this.on('mount', function() { this.on('mount', function() {
//console.log(self.refs.aOsmenu.root) //console.log(self.refs.aOsmenu.root)
$(self.refs.aOsmenu.root).css("z-index",1000000) $(self.refs.aOsmenu.root).css("z-index",1000000)

View File

@ -0,0 +1,103 @@
<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}>
<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>
{ name }
</div>
<ul if={ isFolder() } show={ isFolder() && open }>
<li each={ child, i in nodes }>
<afx-tree-view data={child} indent={indent+1} observable = {parent.root.observable} path = {parent.path + ">" + i} treeroot= {parent.treeroot}></afx-tree-view>
</li>
</ul>
<script>
var self = this
if(opts.data)
{
self.name = opts.data.name
self.nodes = opts.data.nodes
self.icon = opts.data.icon
}
self.indent = opts.indent || 1
self.open = true
var istoggle = false
if(opts.treeroot)
{
this.treeroot = opts.treeroot
this.treeroot.counter++
}
else
{
this.treeroot = self
this.treeroot.counter = 0
}
self.path = opts.path || 0
self.selected = false
self.selectedItem = null
self.index = this.treeroot.counter
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.update = function()
{
self.update()
}
self.root.get = function(k)
{
return self[k]
}
if(opts.observable)
this.root.observable = opts.observable
else
{
this.root.observable = riot.observable()
}
this.on("mount", function(){
$(self.refs.namediv).css("padding-left", self.indent*15 + "px" )
})
isFolder() {
return self.nodes && self.nodes.length
}
toggle(e) {
self.open = !self.open
e.preventDefault()
istoggle = true
}
select(event)
{
if(istoggle)
{
istoggle = false
return
}
var data = {
id:$(self.treeroot.root).attr("data-id"),
data:event.item,
path:self.path
}
if(opts.ontreeselect)
opts.ontreeselect(data)
self.treeroot.selectedItem = data
this.root.observable.trigger('treeselect',data)
event.preventUpdate = true
self.treeroot.update()
event.preventDefault()
}
</script>
</afx-tree-view>

View File

@ -4,6 +4,23 @@
</div> </div>
<script> <script>
var self = this var self = this
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
return self[k]
}
self.root.update = function()
{
self.update()
}
this.on('mount', function(){ this.on('mount', function(){
$(self.refs.container) $(self.refs.container)
.css("display","flex") .css("display","flex")

View File

@ -3,16 +3,15 @@ afx-app-window div.afx-window-wrapper{
/*box-shadow: 1px 1px 1px #cbcbcb;*/ /*box-shadow: 1px 1px 1px #cbcbcb;*/
box-shadow: 1px 1px 1px #9f9F9F; box-shadow: 1px 1px 1px #9f9F9F;
border-radius: 5px; border-radius: 5px;
background-color:#e7e7e7; background-color:#dfdfdf;
padding:0; padding:0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
afx-app-window{ afx-app-window.unactive > div.afx-window-wrapper{
/*width: 600px; background-color: #f6f6f6;
height: 400px;*/
} }
afx-app-window ul.afx-window-top{ afx-app-window ul.afx-window-top{

View File

@ -12,7 +12,12 @@ afx-button button{
afx-button button[disabled]{ afx-button button[disabled]{
color: #a6a6a6; color: #a6a6a6;
} }
afx-button i.icon-style {
width: 16px;
height: 16px;
display: inline-block;
float:left;
}
afx-button button:active { afx-button button:active {
background-color: #2786F3; background-color: #2786F3;
color: white; color: white;

View File

@ -17,8 +17,20 @@ afx-apps-dock afx-button button{
width: 32px; width: 32px;
height: 32px; height: 32px;
font-size: 19px; font-size: 19px;
margin-bottom: 3px;
padding:0px;
background-color: transparent;
border:0;
}
afx-apps-dock afx-button .icon-style{
width: 24px;
height: 24px;
margin-bottom: 0px; margin-bottom: 0px;
border:0; border:0;
background-color: transparent; }
afx-apps-dock afx-button.selected > button {
background-color: #2786F3;
color: white;
border: 1px solid #dedede;
} }

View File

@ -0,0 +1,33 @@
afx-grid-view{
overflow: hidden;
padding:5px;
}
afx-grid-view afx-grid-row div{
padding:3px;
padding-left: 5px;
padding-right: 5px;
}
afx-grid-view afx-grid-row:nth-child(even){
background-color: #f5F5F5;
}
afx-grid-view afx-grid-row.grid_row_header div{
border-right: 2px solid #e5e5e5;
}
afx-grid-view afx-grid-row i.icon-style {
width: 16px;
height: 16px;
display: inline-block;
float:left;
}
afx-grid-view afx-grid-row.selected {
background-color: #116cd6;
color:white;
}
afx-grid-view afx-grid-row.grid_row_header {
font-weight: bold;
border: 1px solid #e5e5e5;
border-right:0;
}

View File

@ -0,0 +1,104 @@
afx-list-view{
overflow:auto;
padding: 5px;
}
/*
afx-list-view div.list-container{
width: 100%;
height: 100%;
display: inline-block;
position: relative;
background-color: red;
}*/
afx-list-view ul{
margin:0;
padding: 0;
}
afx-list-view li{
margin:0;
padding:0;
list-style: none;
padding: 5px;
padding-top:3px;
padding-bottom: 3px;
color: #414339;
background-color: white;
}
afx-list-view li:nth-child(odd){
background-color: #f5F5F5;
}
afx-list-view i.icon-style {
width: 16px;
height: 16px;
display: inline-block;
float:left;
}
afx-list-view li > i {
margin-right: 3px;
}
afx-list-view li.selected {
background-color: #116cd6;
color:white;
}
/*
afx-list-view.dropdown div.list-container{
position: relative;
display: inline-block;
}
afx-list-view.dropdown div.list-container ul{
position:absolute;
top:100%;
left:0;
display: none;
border:1px solid red;
}*/
afx-list-view.dropdown {
padding:0;
margin: 0;
}
afx-list-view.dropdown div.list-container ul{
max-height: 150px;
overflow-y: auto;
overflow-x: hidden;
background-color: white;
}
afx-list-view.dropdown div.list-container ul{
border:1px solid #a6a6a6;
box-shadow: 1px 1px 1px #9f9F9F;
border-radius: 3px;
padding:2px;
border-top-left-radius: 0px;
}
afx-list-view.dropdown div.list-container ul li{
display: inline-block;
width:100%;
}
afx-list-view.dropdown div.list-container div{
padding:3px;
border:1px solid #a6a6a6;
border-radius: 3px;
padding-right:15px;
background-color: white;
height: 17px;
}
afx-list-view.dropdown div.list-container div:before {
content: "\f107";
font-family: "FontAwesome";
font-size: 11px;
font-style: normal;
color: #414339;
position: absolute;
top:25%;
right: 5px;
}
afx-list-view.dropdown div.list-container ul li:hover{
background-color: #dcdcdc;
color: #414339;
}

View File

@ -6,8 +6,6 @@ afx-menu {
} }
afx-menu a{ afx-menu a{
text-decoration: none; text-decoration: none;
width: 100%;
height: 100%;
color: #414339; color: #414339;
display: inline-block; display: inline-block;
width: 100%; width: 100%;
@ -17,6 +15,14 @@ afx-menu ul{
padding:0; padding:0;
margin: 0; margin: 0;
} }
afx-menu i.icon-style {
width: 16px;
height: 16px;
display: inline-block;
float:left;
}
afx-menu afx-menu ul { afx-menu afx-menu ul {
padding: 0; padding: 0;
border:1px solid #a6a6a6; border:1px solid #a6a6a6;
@ -35,6 +41,18 @@ afx-menu ul > li{
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
} }
afx-menu ul > li.fix_padding{
padding-top:1px;
padding-bottom: 0;
padding-left: 5px;
padding-right: 5px;
}
afx-menu afx-menu ul > li.fix_padding{
padding:3px;
padding-left: 5px;
padding-right: 5px;
}
afx-menu afx-menu { afx-menu afx-menu {
top:100%; top:100%;
left:0; left:0;
@ -46,7 +64,7 @@ afx-menu afx-menu i{
} }
afx-menu afx-menu li{ afx-menu afx-menu li{
float:none; float:none;
width: 150px; min-width: 150px;
} }
afx-menu afx-menu afx-menu{ afx-menu afx-menu afx-menu{
top:-4px; top:-4px;
@ -74,11 +92,11 @@ afx-menu li.afx-corner-fix:hover{
background-color: transparent; background-color: transparent;
} }
afx-menu afx-menu .afx-submenu:before { afx-menu afx-menu .afx_submenu:before {
content: "\f054"; content: "\f054";
font-family: "FontAwesome"; font-family: "FontAwesome";
font-size: 10px; font-size: 10px;
left:93%; right:5px;
color: #414339; color: #414339;
position:absolute; position:absolute;
top:25%; top:25%;

View File

@ -1,4 +1,8 @@
afx-sys-panel{
padding:0;
margin: 0;
}
afx-sys-panel div{ afx-sys-panel div{
width: 100%; width: 100%;
height: 23px; height: 23px;
@ -7,13 +11,18 @@ afx-sys-panel div{
background-color: #e7e7e7; background-color: #e7e7e7;
border-bottom: 1px solid #9c9C9C; border-bottom: 1px solid #9c9C9C;
box-shadow: 1px 1px 1px #9F9F9F; box-shadow: 1px 1px 1px #9F9F9F;
position:absolute;
} }
afx-sys-panel .afx-panel-os-menu{
padding:0;
margin: 0;
float:left;
}
afx-sys-panel .afx-panel-os-stray{ afx-sys-panel .afx-panel-os-stray{
float:right; float:right;
} }
afx-sys-panel .afx-panel-os-stray afx-menu afx-menu{ afx-sys-panel .afx-panel-os-stray afx-menu afx-menu{
top:-4px; top:-4px;
left: -100%; right:0;
} }

View File

@ -0,0 +1,59 @@
afx-tree-view{
color: #414339;
padding:3px;
overflow: auto;
}
afx-tree-view afx-tree-view{
padding:0;
overflow: hidden;
}
afx-tree-view ul{
margin:0;
padding:0;
}
afx-tree-view li{
list-style: none;
margin:0;
padding: 0;
}
afx-tree-view div{
padding:3px;
background-color: white;
}
afx-tree-view i.icon-style {
width: 16px;
height: 16px;
display: inline-block;
float:left;
margin-right: 3px;
}
afx-tree-view div.afx_tree_item_selected{
background-color: #116cd6;
color:white;
}
afx-tree-view div.afx_tree_item_selected:hover{
background-color: #116cd6;
color:white;
}
/*
afx-tree-view div:hover{
background-color: #f5F5F5;
color: #414339;
}*/
afx-tree-view .afx_folder_item{
font-weight: bold;
}
afx-tree-view .afx-tree-view-folder-open:before{
content: "\f147";
font-family: "FontAwesome";
font-size: 13px;
}
afx-tree-view .afx-tree-view-folder-close:before{
content: "\f196";
font-family: "FontAwesome";
font-size: 13px;
}
afx-tree-view .afx_tree_item_odd{
background-color: #f5F5F5;
}

35
src/core/processes.coffee Normal file
View File

@ -0,0 +1,35 @@
self.OS.PM =
pidalloc:0
processes: new Object
createProcess: (app,cls) ->
#if it is single ton
# and a process is existing
# just return it
if cls.singleton and _PM.processes[app] and _PM.processes[app].length == 1
_PM.processes[app][0].show()
return _PM.processes[app][0]
else
_PM.processes[app] = [] if not _PM.processes[app]
obj = new cls
obj.birth = (new Date).getTime()
_PM.pidalloc++
obj.pid = _PM.pidalloc
_PM.processes[app].push obj
_GUI.dock obj,cls.meta
appByPid:(pid)->
app = undefined
find = (l) ->
return a for a in l when a.pid is pid
for k,v of _PM.processes
app = find v
break if app
app
kill: (app) ->
return if not _PM.processes[app.name]
i = _PM.processes[app.name].indexOf app
if i >= 0
_GUI.undock _PM.processes[app.name][i]
delete _PM.processes[app.name][i]
_PM.processes[app.name].splice i,1

View File

@ -4,11 +4,15 @@ self.OS or=
API: new Object() API: new Object()
GUI: new Object() GUI: new Object()
APP: new Object() APP: new Object()
register: (name,x)-> self.OS.APP[name] = x PM: new Object()
register: (name,x)->
# load the metadata first
_APP[name] = x
boot: -> boot: ->
#first load the configuration #first load the configuration
#then load the theme #then load the theme
_GUI = self.OS.GUI _GUI = self.OS.GUI
_GUI.loadTheme "antos" _GUI.loadTheme "antos"
_GUI.initDM() _GUI.initDM()
_GUI.loadScheme "resources/schemes/test.html",null #_GUI.loadScheme "resources/schemes/test.html",null

View File

@ -10,6 +10,8 @@
<script src="resources/antos_tags.js" type="riot/tag"></script> <script src="resources/antos_tags.js" type="riot/tag"></script>
<script src="scripts/riot.compiler.min.js"> </script> <script src="scripts/riot.compiler.min.js"> </script>
<script src="scripts/ace/ace.js"></script> <script src="scripts/ace/ace.js"></script>
<script src="scripts/ace/ext-language_tools.js"></script>
<script src="scripts/ace/ext-modelist.js"></script>
<script src="scripts/antos.js"></script> <script src="scripts/antos.js"></script>
</head> </head>
<body> <body>

View File

@ -0,0 +1,33 @@
coffee_files = main.coffee
jsfiles =
cssfiles = main.css
copyfiles = scheme.html package.json
BLUE=\033[1;34m
NC=\033[0m
main: title clean js css copy
title:
@echo "$(BLUE)======= Package ActivityMonitor =======$(NC)"
coffee:
- mkdir build
for f in $(coffee_files); do (coffee -cs < $$f >build/"$$f.js");done
for f in build/*.coffee.js; do (cat "$${f}"; echo) >> build/main.js; done
- rm build/*.coffee.js
js: coffee
for f in $(jsfiles); do (cat "$${f}"; echo) >> build/main.js; done
css:
for f in $(cssfiles); do (cat "$${f}"; echo) >> build/main.css; done
copy:
cp -rf $(copyfiles) build/
clean:
- rm -rf build/*

View File

@ -0,0 +1,56 @@
_PM = this.OS.PM
_APP = this.OS.APP
class ActivityMonitor extends this.OS.GUI.BaseApplication
constructor: () ->
super "ActivityMonitor"
main: () ->
me = @
@scheme.set "apptitle", "Activity Monitor"
@grid = @find "mygrid"
@on "btclick", (e)->
return unless e.id == "btkill"
item = me.grid.get "selected"
return unless item
app = _PM.appByPid item[0].value
app.quit() if app
header = [{width:50,value:"Pid"},{value:"Name"},{width:100,value:"Alive (ms)"}]
@gdata =
processes:{}
alive:[]
@grid.set "header",header
@monitor()
monitor: () ->
me = @
#get all current running process
me.gdata.alive = []
now = (new Date).getTime()
$.each _PM.processes, (i,d)->
$.each d , (j,a)->
if me.gdata.processes[a.pid] #update it
me.gdata.processes[a.pid][2].value = now - a.birth
else #add it
me.gdata.processes[a.pid] = [
{value:a.pid},
{icon:_APP[a.name].meta.icon,iconclass:_APP[a.name].meta.iconclass,value:a.name},
{value: now - a.birth}
]
me.gdata.alive.push a.pid
@refreshGrid()
@timer = setTimeout (()-> me.monitor()),500#one second
refreshGrid: ()->
activeList = []
me = @
$.each @gdata.processes, (i,e) ->
if ($.inArray (Number i),me.gdata.alive) >= 0
activeList.push e
else
me.gdata.processes[i] = undefined
@grid.set "rows",activeList
exit: (e) ->
clearTimeout @timer if @timer
ActivityMonitor.singleton = true
this.OS.register "ActivityMonitor",ActivityMonitor

View File

@ -0,0 +1,8 @@
afx-app-window[data-id="am-window"] afx-button{
margin: 3px;
}
afx-app-window[data-id="am-window"] afx-grid-view{
padding-left:10px;
padding-right: 10px;
}

View File

@ -0,0 +1,12 @@
{
"app":"ActivityMonitor",
"name":"Activity monitor",
"description":"Processes monitor and manager",
"author":{
"name": "Xuan Sang LE",
"email": "xsang.le@gmail.com"
},
"category":"System",
"iconclass":"fa fa-heartbeat",
"mimes":["*"]
}

View File

@ -0,0 +1,7 @@
<afx-app-window data-id = "am-window" apptitle="" width="400" height="300">
<afx-vbox>
<afx-hbox>
<afx-grid-view data-id = "mygrid"></afx-grid-view>
<afx-button data-height="30" data-id = "btkill" text = "Kill process" iconclass="fa fa-times"></afx-button>
</afx-hbox>
</afx-app-window>

View File

@ -7,27 +7,27 @@ cssfiles = main.css
copyfiles = scheme.html package.json copyfiles = scheme.html package.json
BLUE=\033[0;34m BLUE=\033[1;34m
NC=\033[0m NC=\033[0m
main: title clean js css copy main: title clean js css copy
title: title:
- echo "$(BLUE)======= Package NotePad =======$(NC)" @echo "$(BLUE)======= Package NotePad =======$(NC)"
coffee: coffee:
- mkdir build - mkdir build
- for f in $(coffee_files); do (coffee -cs < $$f >build/"$$f.js");done for f in $(coffee_files); do (coffee -cs < $$f >build/"$$f.js");done
- for f in build/*.coffee.js; do (cat "$${f}"; echo) >> build/main.js; done for f in build/*.coffee.js; do (cat "$${f}"; echo) >> build/main.js; done
- rm build/*.coffee.js - rm build/*.coffee.js
js: coffee js: coffee
- for f in $(jsfiles); do (cat "$${f}"; echo) >> build/main.js; done for f in $(jsfiles); do (cat "$${f}"; echo) >> build/main.js; done
css: css:
- for f in $(cssfiles); do (cat "$${f}"; echo) >> build/main.css; done for f in $(cssfiles); do (cat "$${f}"; echo) >> build/main.css; done
copy: copy:
- cp -rf $(copyfiles) build/ cp -rf $(copyfiles) build/
clean: clean:
- rm -rf build/* - rm -rf build/*

View File

@ -1,10 +1,53 @@
class NotePad extends this.OS.GUI.BaseApplication class NotePad extends this.OS.GUI.BaseApplication
constructor: () -> constructor: () ->
super "NotePad" super "NotePad"
event: () -> main: () ->
console.log @scheme me = @
@on "btclick", (e)-> @scheme.set "apptitle", "NotePad"
alert "Happy pola"
@on "resize", (w,h)-> div = @find "datarea"
console.log "resize" ace.require "ace/ext/language_tools"
@.editor = ace.edit div
@.editor.setTheme "ace/theme/monokai"
@.editor.getSession().setMode 'ace/mode/text'
@.editor.setOptions {
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
fontSize: "10pt"
}
@.editor.completers.push {getCompletions:(editor, session, pos, prefix, callback)->}
@.editor.getSession().setUseWrapMode true
list = @find "modelist"
@modes = ace.require "ace/ext/modelist"
ldata = []
ldata.push {text:m.name, mode:m.mode} for m in @modes.modes
list.set "items",ldata
list.set "onlistselect", (e)->
me.editor.session.setMode e.data.mode
stat = @find "editorstat"
#status
stup = (e)->
c = me.editor.session.selection.getCursor()
l = me.editor.session.getLength()
$(stat).html "Row #{c.row}, col #{c.column}, lines: #{l}"
stup(0)
@.editor.getSession().selection.on "changeCursor", (e)->
stup(e)
@on "resize", ()-> me.editor.resize()
@on "focus", ()->me.editor.focus()
menu: ()->
menu = [{
text:"File",
child:[
{text:"Open", dataid:"#{@name}-Open"},
{text:"Close", dataid:"#{@name}-Close"}
]
}]
menu
NotePad.singleton = false
this.OS.register "NotePad",NotePad this.OS.register "NotePad",NotePad

View File

@ -1,3 +1,9 @@
fut{
background-color: black afx-app-window[data-id="notepad"] afx-list-view[data-id="modelist"]{
margin:2px;
}
afx-app-window[data-id="notepad"] span[data-id="editorstat"]{
padding:5px;
display: inline-block;
} }

View File

@ -7,6 +7,6 @@
"email": "xsang.le@gmail.com" "email": "xsang.le@gmail.com"
}, },
"category":"System", "category":"System",
"icon":"", "iconclass":"fa fa-pencil-square-o",
"mimes":["*"] "mimes":["*"]
} }

View File

@ -1,16 +1,24 @@
<afx-app-window apptitle="Preview" width="600" height="400"> <afx-app-window apptitle="" width="600" height="400" data-id="notepad">
<afx-vbox> <afx-hbox>
<afx-list-view data-width = "250"> </afx-list-view> <!--afx-list-view data-id = "flist" data-width = "150" > </afx-list-view>
<afx-hbox> <afx-hbox>
<afx-button data-height="50" onbtclick="alert('im clicked')" text="Read more" icon="fa fa-camera-retro fa-lg" id="button"> <afx-button data-height="50" text="Read more" iconclass="fa fa-camera-retro fa-lg" id="button">
</afx-button> </afx-button>
<div 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 <div>
big text here
</div>
<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 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. 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> Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div data-width="100">Test</div>
</afx-hbox> </afx-hbox-->
</afx-vbox> <div data-id="datarea"></div>
<afx-vbox data-height="30">
<div ><span data-id = "editorstat"></span></div>
<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

@ -0,0 +1,33 @@
coffee_files = main.coffee
jsfiles =
cssfiles = main.css
copyfiles = scheme.html package.json
BLUE=\033[1;34m
NC=\033[0m
main: title clean js css copy
title:
@echo "$(BLUE)======= Package Terminal =======$(NC)"
coffee:
- mkdir build
for f in $(coffee_files); do (coffee -cs < $$f >build/"$$f.js");done
for f in build/*.coffee.js; do (cat "$${f}"; echo) >> build/main.js; done
- rm build/*.coffee.js
js: coffee
for f in $(jsfiles); do (cat "$${f}"; echo) >> build/main.js; done
css:
for f in $(cssfiles); do (cat "$${f}"; echo) >> build/main.css; done
copy:
cp -rf $(copyfiles) build/
clean:
- rm -rf build/*

View File

@ -0,0 +1,80 @@
class Terminal extends this.OS.GUI.BaseApplication
constructor: () ->
super "Terminal"
main: () ->
self = @
@on "btclick", (e)->
alert "#{self.name}: Happy pola"
@on "resize", (w,h)->
console.log "#{self.name}: resize"
#@on "listselect", (i)->
# console.log self.name, i
@on "treeselect", (i) ->
console.log self.name,i
@on "focus", ()->
console.log self.name, "is focused"
tree = @find "mytree"
@scheme.set "apptitle", "Terminal"
tdata = {
name: 'My Tree',
nodes: [
{ name: 'hello', icon:'packages/NotePad/icon.png'},
{ name: 'wat' },
{
name: 'child folder',
nodes: [
{
name: 'child folder',
nodes: [
{ name: 'hello' },
{ name: 'wat' }
]
},
{ name: 'hello' },
{ name: 'wat' },
{
name: 'child folder',
nodes: [
{ name: 'hello' },
{ name: 'wat' }
]
}
]
}
]
}
tree.set "*",tdata
list = @find "mylist"
ldata = [
{text:"some thing with avery long text"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"},
{text:"some thing"}
]
list.set "items",ldata
list.set "onlistselect", (e)->
console.log e
Terminal.singleton = false
this.OS.register "Terminal",Terminal

View File

View File

@ -0,0 +1,12 @@
{
"app":"Terminal",
"name":"Unix terminal like",
"description":"Access Unix terminal from web",
"author":{
"name": "Xuan Sang LE",
"email": "xsang.le@gmail.com"
},
"category":"System",
"iconclass":"fa fa-terminal",
"mimes":["*"]
}

View File

@ -1,16 +1,14 @@
<afx-app-window apptitle="Preview" width="600" height="400"> <afx-app-window apptitle="Preview" width="600" height="400">
<afx-vbox> <afx-vbox>
<afx-tree-view data-id="mytree"> </afx-tree-view>
<afx-list-view data-width = "250"> </afx-list-view>
<afx-hbox> <afx-hbox>
<afx-button data-height="50" onbtclick="alert('im clicked')" text="Read more" icon="fa fa-camera-retro fa-lg" id="button"> <afx-button data-height="50" text="Read more" iconclass="fa fa-camera-retro fa-lg" id="button">
</afx-button> </afx-button>
<div 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 <afx-list-view data-id = "mylist" dropdown = "true" width="200"></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 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. 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> Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div data-width="100">Test</div>
</afx-hbox> </afx-hbox>
</afx-vbox> </afx-vbox>
</afx-app-window> </afx-app-window>