mirror of
https://github.com/lxsang/antos-frontend.git
synced 2024-12-26 17:38:20 +01:00
add services
This commit is contained in:
parent
2985689217
commit
16074ac3f8
13
Makefile
13
Makefile
@ -10,6 +10,7 @@ coffees= src/define.coffee\
|
||||
src/core/handlers/InBrowserHandler.coffee\
|
||||
src/core/gui/gui.coffee\
|
||||
src/core/gui/BaseApplication.coffee\
|
||||
src/core/gui/BaseService.coffee\
|
||||
src/core/gui/BaseEvent.coffee\
|
||||
src/antos.coffee
|
||||
|
||||
@ -39,11 +40,13 @@ antos_themes = src/core/gui/themes/antos/font-awesome.css\
|
||||
|
||||
|
||||
|
||||
packages = NotePad Terminal ActivityMonitor
|
||||
packages = NotePad wTerm ActivityMonitor DummyApp
|
||||
services = PushNotification Spotlight Calendar
|
||||
|
||||
main: clean build_coffee build_tag build_theme schemes libs build_packages
|
||||
main: clean build_coffee build_tag build_theme schemes libs build_services build_packages
|
||||
- cp src/index.html $(BUILDDIR)/
|
||||
|
||||
lite: build_coffee build_tag build_theme schemes build_services build_packages
|
||||
#%.js: %.coffee
|
||||
# coffee --compile $<
|
||||
|
||||
@ -84,8 +87,14 @@ antos_themes_build:
|
||||
cp src/core/gui/themes/antos/wallpaper.jpg $(BUILDDIR)/resources/themes/antos/
|
||||
|
||||
|
||||
build_services:
|
||||
@echo "=======$(BLUE)Building services=======$(NC)"
|
||||
-mkdir -p $(BUILDDIR)/services
|
||||
-rm -rf $(BUILDDIR)/services/*
|
||||
for f in $(services); do (coffee -cs < "src/services/$$f.coffee" >$(BUILDDIR)/services/"$$f.js");done
|
||||
build_packages:
|
||||
- mkdir $(BUILDDIR)/packages
|
||||
- for d in $(packages); do ( test -d $(BUILDDIR)/packages/$$d && rm -rf $(BUILDDIR)/packages/$$d/* ); 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 src/packages/$$d/build && rm -r src/packages/$$d/build ); done
|
||||
|
@ -2,6 +2,7 @@ _GUI = self.OS.GUI
|
||||
_API = self.OS.API
|
||||
_APP = self.OS.APP
|
||||
_PM = self.OS.PM
|
||||
_courrier = self.OS.courrier
|
||||
this.onload = () ->
|
||||
console.log "Booting the os"
|
||||
self.OS.boot()
|
@ -6,61 +6,62 @@ class BaseApplication
|
||||
@observable = riot.observable()
|
||||
@pid = 0
|
||||
@_api = self.OS.API
|
||||
|
||||
init: ->
|
||||
me = @
|
||||
# first register some base event to the app
|
||||
@on "exit", ()-> me.quit()
|
||||
@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.appmenu.set "onmenuselect", (d) ->
|
||||
me.trigger("menuselect", d)
|
||||
@on "hide", () ->
|
||||
me.sysdock.set "selectedApp", null
|
||||
me.appmenu.set "items",[]
|
||||
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"
|
||||
_GUI.loadScheme path ,this
|
||||
_GUI.loadScheme path , @
|
||||
|
||||
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
|
||||
@.appmenu.set "items", [] if @.appmenu and @.pid == @.appmenu.pid
|
||||
@observable.trigger "blur"
|
||||
|
||||
hide: () ->
|
||||
@observable.trigger "hide"
|
||||
|
||||
toggle:() ->
|
||||
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(@)
|
||||
@.appmenu.set "items", [] if @.pid == @.appmenu.pid
|
||||
_PM.kill @
|
||||
($ @scheme).remove()
|
||||
|
||||
find: (id) -> ($ "[data-id='#{id}']",@scheme)[0]
|
||||
find: (id) -> ($ "[data-id='#{id}']", @scheme)[0]
|
||||
|
||||
baseMenu:->
|
||||
baseMenu: ->
|
||||
menu =
|
||||
[{
|
||||
text:_APP[@name].meta.name,
|
||||
child:[
|
||||
{text:"About", dataid:"#{@name}-about"},
|
||||
{text:"Exit", dataid:"#{@name}-exit"}
|
||||
text: _APP[@name].meta.name,
|
||||
child: [
|
||||
{ text: "About", dataid: "#{@name}-about" },
|
||||
{ text: "Exit", dataid: "#{@name}-exit" }
|
||||
]
|
||||
}]
|
||||
menu = menu.concat @menu() || []
|
||||
@ -85,4 +86,5 @@ class BaseApplication
|
||||
# to handle the exit event
|
||||
# use e.preventDefault() to
|
||||
# discard the quit command
|
||||
BaseApplication.type = 1
|
||||
this.OS.GUI.BaseApplication = BaseApplication
|
40
src/core/gui/BaseService.coffee
Normal file
40
src/core/gui/BaseService.coffee
Normal file
@ -0,0 +1,40 @@
|
||||
MAIL = this.OS.courrier
|
||||
_API = this.OS.API
|
||||
_PM = this.OS.PM
|
||||
class BaseService
|
||||
constructor: (@name) ->
|
||||
@icon = undefined
|
||||
@iconclass = "fa-paper-plane-o"
|
||||
@text = ""
|
||||
@_api = _API
|
||||
@timer = undefined
|
||||
@holder = undefined
|
||||
|
||||
init: ()->
|
||||
#implement by user
|
||||
# event registe, etc
|
||||
# scheme loader
|
||||
|
||||
attach: (h) -> @holder = h
|
||||
update: () -> @holder.update() if @holder
|
||||
on: (e, f) -> MAIL.on e, f
|
||||
trigger: (e, d) -> MAIL.trigger e, d
|
||||
watch: ( t, f) ->
|
||||
me = @
|
||||
func = () ->
|
||||
f()
|
||||
me.timer = setTimeout (() -> func()), t
|
||||
func()
|
||||
quit: ()->
|
||||
console.log "clean timer" if @timer
|
||||
clearTimeout @timer if @timer
|
||||
@cleanup()
|
||||
_PM.kill @
|
||||
main: () ->
|
||||
show: () ->
|
||||
awake: () ->
|
||||
#implement by user to tart the service
|
||||
cleanup:() ->
|
||||
#implemeted by user
|
||||
BaseService.type = 2
|
||||
this.OS.GUI.BaseService = BaseService
|
@ -5,16 +5,16 @@ self.OS.GUI =
|
||||
data: "#{_GUI.tagPath}/tags.json"
|
||||
self.OS.API.request query, ()->
|
||||
|
||||
loadScheme: (path,app) ->
|
||||
loadScheme: (path, app) ->
|
||||
_API.get path,
|
||||
(x) ->
|
||||
return null unless x
|
||||
scheme = $.parseHTML x
|
||||
($ "#desktop").append scheme
|
||||
riot.mount ($ scheme), {observable:app.observable}
|
||||
riot.mount ($ scheme), { observable: app.observable }
|
||||
app.scheme = scheme[0]
|
||||
app.show()
|
||||
app.main()
|
||||
app.show()
|
||||
, (f) ->
|
||||
alert "cannot load scheme"
|
||||
|
||||
@ -23,15 +23,26 @@ self.OS.GUI =
|
||||
$ "head link#ostheme"
|
||||
.attr "href", path
|
||||
|
||||
pushService: (srv) ->
|
||||
return _PM.createProcess srv, _APP[srv] if _APP[srv]
|
||||
path = "services/#{srv}.js"
|
||||
$.getScript path
|
||||
.done (e, s) ->
|
||||
_PM.createProcess srv, _APP[srv]
|
||||
.fail (e, s) ->
|
||||
_courrier.trigger "fail",
|
||||
{ m: "Cannot read service script: #{srv} ",
|
||||
e: e, s: s }
|
||||
|
||||
launch: (app) ->
|
||||
if not _APP[app]
|
||||
# first load it
|
||||
path = "packages/#{app}/"
|
||||
$.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"}
|
||||
$ '<link>', { rel: 'stylesheet', type: 'text/css', 'href': "#{path}main.css" }
|
||||
.appendTo 'head'
|
||||
#launch
|
||||
if _APP[app]
|
||||
@ -40,12 +51,18 @@ self.OS.GUI =
|
||||
(data) ->
|
||||
_APP[app].meta = data
|
||||
_PM.createProcess app, _APP[app]
|
||||
console.log "Fist time loading "+app
|
||||
,(e,s)->
|
||||
console.log "Fist time loading " + app
|
||||
, (e, s) ->
|
||||
_courrier.trigger "fail",
|
||||
{ m: "Cannot read application metadata: #{app} ",
|
||||
e: e, s: s }
|
||||
alert "cannot read application, meta-data"
|
||||
.fail (e,s) ->
|
||||
#BUG report here
|
||||
console.log "bug report"
|
||||
_courrier.trigger "fail",
|
||||
{ m: "Cannot load application script: #{app}",
|
||||
e: e, s:s }
|
||||
console.log "bug report", e, s, path
|
||||
else
|
||||
# now launch it
|
||||
if _APP[app]
|
||||
@ -54,56 +71,53 @@ self.OS.GUI =
|
||||
# dock an application to a dock
|
||||
# create a data object
|
||||
data =
|
||||
icon:null
|
||||
iconclass:meta.iconclass||""
|
||||
icon: null
|
||||
iconclass: meta.iconclass || ""
|
||||
app:app
|
||||
onbtclick:() ->
|
||||
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.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
|
||||
|
||||
attachservice: (srv) ->
|
||||
($ "#syspanel")[0].attachservice srv
|
||||
srv.init()
|
||||
detachservice: (srv) ->
|
||||
($ "#syspanel")[0].detachservice srv
|
||||
bindContextMenu: (event) ->
|
||||
handler = (e) ->
|
||||
if e.contextmenuHandler
|
||||
e.contextmenuHandler event, ($ "#contextmenu")[0]
|
||||
else
|
||||
#console.log ($ "#workspace").get(0), ($ e).parent().get(0)
|
||||
p = $(e).parent().get(0)
|
||||
handler p if p isnt ($ "#workspace").get(0)
|
||||
handler event.target
|
||||
event.preventDefault()
|
||||
initDM: ->
|
||||
_API.resource "schemes/dm.html", (x) ->
|
||||
return null unless x
|
||||
scheme = $.parseHTML x
|
||||
($ "#wrapper").append scheme
|
||||
($ "#desktop").on "click", (e)->
|
||||
return if e.target isnt ($ "#desktop").get(0)
|
||||
($ "#sysdock").get(0).set "selectedApp",null
|
||||
|
||||
osmenu = {child:[
|
||||
{text:"",iconclass:"fa fa-eercast", child:[
|
||||
{text:"About"},
|
||||
{text:"System Preferences", iconclass:"fa fa-commenting"},
|
||||
{text:"Applications",child:[
|
||||
{text:"Terminal",type:"app"},
|
||||
{text:"NotePad",type:"app", icon:"packages/NotePad/icon.png"},
|
||||
{text:"ActivityMonitor",type:"app"}
|
||||
]},
|
||||
{text:"Logout"}
|
||||
]}
|
||||
],onmenuselect: (item)->
|
||||
switch item.data.type
|
||||
when "app" then _GUI.launch item.data.text
|
||||
}
|
||||
appmenu = {child:[]}
|
||||
systray = {child:[
|
||||
{text:"Sun 22:57 6 August 2017"},
|
||||
{text:"",iconclass:"fa fa-search"},
|
||||
{text:"",iconclass:"fa fa-commenting"}
|
||||
|
||||
],onmenuselect: (item)->
|
||||
console.log item
|
||||
}
|
||||
|
||||
riot.mount ($ "#syspanel", $ "#wrapper"),{osmenu:osmenu,appmenu:appmenu,systray:systray}
|
||||
riot.mount ($ "#sysdock", $ "#wrapper"), {items:[]}
|
||||
# context menu
|
||||
riot.mount ($ "#contextmenu")
|
||||
($ "#workspace").contextmenu (e) -> _GUI.bindContextMenu e
|
||||
#desktop
|
||||
desktop = ($ "#desktop")
|
||||
desktop.on "click", (e) ->
|
||||
return if e.target isnt desktop.get(0)
|
||||
($ "#sysdock").get(0).set "selectedApp", null
|
||||
desktop.get(0).contextmenuHandler = (e, m) ->
|
||||
console.log "context menu handler for desktop"
|
||||
# system menu
|
||||
riot.mount ($ "#syspanel", $ "#wrapper")
|
||||
riot.mount ($ "#sysdock", $ "#wrapper"), { items: [] }
|
@ -6,3 +6,4 @@
|
||||
<div id = "desktop">
|
||||
</div>
|
||||
</div>
|
||||
<afx-menu id="contextmenu" context="true" style="display:none;"></afx-menu>
|
||||
|
@ -39,10 +39,6 @@
|
||||
{
|
||||
return self[k]
|
||||
}
|
||||
self.root.update = function()
|
||||
{
|
||||
self.update()
|
||||
}
|
||||
minimize()
|
||||
{
|
||||
this.root.observable.trigger("hide")
|
||||
@ -108,6 +104,7 @@
|
||||
else
|
||||
self.root.observable.trigger("focus")
|
||||
})
|
||||
self.root.observable.trigger("loaded", self.root)
|
||||
})
|
||||
var enable_dragging = function()
|
||||
{
|
||||
|
@ -51,10 +51,9 @@
|
||||
{
|
||||
return self[k]
|
||||
}
|
||||
self.root.update = function()
|
||||
{
|
||||
self.update()
|
||||
}
|
||||
this.on("mount", function(){
|
||||
window.OS.courrier.trigger("sysdockloaded")
|
||||
})
|
||||
|
||||
</script>
|
||||
</afx-apps-dock>
|
@ -23,10 +23,6 @@
|
||||
{
|
||||
return self[k]
|
||||
}
|
||||
self.root.update = function()
|
||||
{
|
||||
self.update()
|
||||
}
|
||||
this._onbtclick = function(e)
|
||||
{
|
||||
if(typeof opts.onbtclick == 'string')
|
||||
|
@ -82,7 +82,6 @@
|
||||
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
|
||||
|
@ -4,23 +4,6 @@
|
||||
</div>
|
||||
<script>
|
||||
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(){
|
||||
$(self.refs.container)
|
||||
.css("display","flex")
|
||||
@ -44,6 +27,7 @@
|
||||
var auto_height = []
|
||||
var csize, ocheight = 0, avaiheight;
|
||||
avaiheight = $(self.root).parent().height()
|
||||
avaiwidth = $(self.root).parent().width()
|
||||
$(self.refs.container).css("height",avaiheight + "px")
|
||||
$(self.refs.container)
|
||||
.children()
|
||||
@ -69,6 +53,8 @@
|
||||
{
|
||||
$(v).css("height", csize + "px")
|
||||
})
|
||||
self.root.observable.trigger("hboxchange",
|
||||
{id:$(self.root).attr("data-id"), w:avaiwidth, h:csize})
|
||||
}
|
||||
</script>
|
||||
</afx-hbox>
|
@ -28,10 +28,6 @@
|
||||
self[k] = v
|
||||
self.update()
|
||||
}
|
||||
self.root.update = function()
|
||||
{
|
||||
self.update()
|
||||
}
|
||||
self.root.get = function(k)
|
||||
{
|
||||
if(k == "selected")
|
||||
@ -69,7 +65,6 @@
|
||||
{
|
||||
var desktoph = $("#desktop").height()
|
||||
var off = $(self.root).offset().top + $(self.refs.mlist).height()
|
||||
console.log(desktoph,off)
|
||||
if( off > desktoph )
|
||||
$(self.refs.mlist)
|
||||
.css("top","-" + $(self.refs.mlist).outerHeight() + "px")
|
||||
|
@ -1,23 +1,30 @@
|
||||
<afx-menu>
|
||||
<ul>
|
||||
<afx-menu >
|
||||
<ul class={context: opts.context == "true"}>
|
||||
<li class="afx-corner-fix"></li>
|
||||
<li each={ items } class = {afx_submenu:child != null, fix_padding:icon}>
|
||||
<li ref = "container" each={ item,i in items } class = {afx_submenu:item.child != null, fix_padding:item.icon} no-reorder>
|
||||
<a href="#" onclick = {parent.onselect}>
|
||||
<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 }
|
||||
<i if={item.iconclass} class = {item.iconclass} ></i>
|
||||
<i if={item.icon} class="icon-style" style = { "background: url("+item.icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i>
|
||||
{ item.text }
|
||||
</a>
|
||||
|
||||
<afx-menu if={child != null} child={child} onmenuselect={onmenuselect} observable = {parent.root.observable} rootid = {parent.rid}></afx-menu>
|
||||
<afx-menu if={item.child != null} child={item.child} observable = {parent.root.observable} rootid = {parent.rid}></afx-menu>
|
||||
</li>
|
||||
<li class="afx-corner-fix"></li>
|
||||
</ul>
|
||||
<script>
|
||||
this.items = opts.child
|
||||
this.items = opts.child || []
|
||||
var isRoot
|
||||
if(opts.rootid)
|
||||
{
|
||||
this.rid = opts.rootid
|
||||
isRoot = false
|
||||
}
|
||||
else
|
||||
{
|
||||
this.rid = $(this.root).attr("data-id")
|
||||
isRoot = true
|
||||
}
|
||||
var self = this
|
||||
this.onmenuselect = opts.onmenuselect
|
||||
self.root.set = function(k,v)
|
||||
@ -29,14 +36,45 @@
|
||||
self[k] = v
|
||||
self.update()
|
||||
}
|
||||
self.root.get = function(k)
|
||||
self.root.push = function(e,u)
|
||||
{
|
||||
return self[k]
|
||||
self.items.push(e)
|
||||
if(u)
|
||||
self.update()
|
||||
}
|
||||
self.root.unshift = function(e,u)
|
||||
{
|
||||
self.items.unshift(e)
|
||||
if(u)
|
||||
self.update()
|
||||
}
|
||||
self.root.remove = function(e,u)
|
||||
{
|
||||
var i = self.items.indexOf(e)
|
||||
if(i >= 0)
|
||||
self.items.splice(i, 1)
|
||||
if(u)
|
||||
self.update()
|
||||
}
|
||||
self.root.update = function()
|
||||
{
|
||||
self.update()
|
||||
}
|
||||
self.root.get = function(k)
|
||||
{
|
||||
return self[k]
|
||||
}
|
||||
self.root.show = function(e)
|
||||
{
|
||||
//only for menucontext
|
||||
if(opts.context != "true") return;
|
||||
$(self.root)
|
||||
.css("top", e.clientY - 15 + "px")
|
||||
.css("left",e.clientX -5 + "px")
|
||||
.show()
|
||||
$(document).on("click",mnhide)
|
||||
}
|
||||
|
||||
if(opts.observable)
|
||||
{
|
||||
this.root.observable = opts.observable
|
||||
@ -47,23 +85,61 @@
|
||||
this.root.observable.on('menuselect',function(data){
|
||||
//console.log("From root",self.root)
|
||||
if(self.onmenuselect)
|
||||
{
|
||||
self.onmenuselect(data)
|
||||
|
||||
if(opts.context == "true")
|
||||
$(self.root).hide()
|
||||
else if(!data.root && self.refs.container)
|
||||
{
|
||||
var arr = self.refs.container.length?self.refs.container:[self.refs.container]
|
||||
for( var i in arr)
|
||||
$("afx-menu",arr[i]).first().hide()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
var mnhide = function(event)
|
||||
{
|
||||
if(opts.context == "true")
|
||||
{
|
||||
if(!$(event.target).closest(self.root).length) {
|
||||
$(self.root).hide()
|
||||
$(document).unbind("click",mnhide)
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!$(event.target).closest(self.refs.container).length && self.refs.container) {
|
||||
var arr = self.refs.container.length?self.refs.container:[self.refs.container]
|
||||
for( var i in arr)
|
||||
$("afx-menu",arr[i]).first().hide()
|
||||
$(document).unbind("click",mnhide)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(self.refs.container && self.refs.container.length)
|
||||
for(var i in self.refs.container)
|
||||
if(!$(event.target).closest(self.refs.container[i]).length) {
|
||||
$("afx-menu",self.refs.container[i]).first().hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onselect(event)
|
||||
{
|
||||
var data = {id:self.rid, data:event.item}
|
||||
/*if(self.onmenuselect)
|
||||
{
|
||||
self.onmenuselect(data)
|
||||
} else*/
|
||||
var data = {id:self.rid, data:event.item.item, root:isRoot}
|
||||
this.root.observable.trigger('menuselect',data)
|
||||
event.preventDefault()
|
||||
$(document).unbind("click",mnhide)
|
||||
if(opts.context == "true") return
|
||||
if(isRoot && self.refs.container)
|
||||
{
|
||||
if(self.refs.container.length)
|
||||
$("afx-menu",self.refs.container[event.item.i]).first().show()
|
||||
else
|
||||
$("afx-menu",self.refs.container).first().show()
|
||||
$(document).on("click",mnhide)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
3
src/core/gui/tags/afx-service.js
Normal file
3
src/core/gui/tags/afx-service.js
Normal file
@ -0,0 +1,3 @@
|
||||
<afx-service>
|
||||
<yield/>
|
||||
</afx-service>
|
@ -1,16 +1,42 @@
|
||||
<afx-sys-panel>
|
||||
<div>
|
||||
<afx-menu data-id = "os_menu" ref = "aOsmenu" child={osmenu.child} onmenuselect = {osmenu.onmenuselect} class="afx-panel-os-menu"></afx-menu>
|
||||
<afx-menu data-id = "appmenu" 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} class = "afx-panel-os-app"></afx-menu>
|
||||
<afx-menu data-id = "sys_tray" ref = "aTray" child={systray.child} onmenuselect = {systray.onmenuselect} class = "afx-panel-os-stray"></afx-menu>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
this.osmenu = opts.osmenu
|
||||
this.appmenu = opts.appmenu
|
||||
this.systray = opts.systray
|
||||
var self = this
|
||||
this.osmenu = {child:[
|
||||
{text:"",iconclass:"fa fa-eercast", child:[
|
||||
{text:"About"},
|
||||
{text:"System Preferences", iconclass:"fa fa-commenting"},
|
||||
{text:"Applications",child:[
|
||||
{text:"wTerm",type:"app"},
|
||||
{text:"NotePad",type:"app", iconclass:"fa fa-commenting"},
|
||||
{text:"ActivityMonitor",type:"app"},
|
||||
{text:"DummyApp",type:"app"}
|
||||
]},
|
||||
{text:"Logout"}
|
||||
]}
|
||||
],onmenuselect: function(item)
|
||||
{
|
||||
if(item.data.type == "app")
|
||||
window.OS.GUI.launch(item.data.text)
|
||||
}
|
||||
}
|
||||
this.appmenu = { child: [] }
|
||||
this.systray = { child: [], onmenuselect: function(item){item.data.awake()}}
|
||||
|
||||
var self = this
|
||||
self.root.attachservice = function(s)
|
||||
{
|
||||
s.attach(self.refs.aTray)
|
||||
self.refs.aTray.root.unshift(s,true)
|
||||
}
|
||||
self.root.detachservice = function(s)
|
||||
{
|
||||
self.refs.aTray.root.remove(s, true)
|
||||
}
|
||||
self.root.set = function(k,v)
|
||||
{
|
||||
if(k == "*")
|
||||
@ -24,15 +50,12 @@
|
||||
{
|
||||
return self[k]
|
||||
}
|
||||
self.root.update = function()
|
||||
{
|
||||
self.update()
|
||||
}
|
||||
this.on('mount', function() {
|
||||
//console.log(self.refs.aOsmenu.root)
|
||||
$(self.refs.aOsmenu.root).css("z-index",1000000)
|
||||
$(self.refs.aAppmenu.root).css("z-index",1000000)
|
||||
$(self.refs.aTray.root).css("z-index",1000000)
|
||||
window.OS.courrier.trigger("syspanelloaded")
|
||||
})
|
||||
</script>
|
||||
</afx-sys-panel>
|
@ -49,10 +49,6 @@
|
||||
self[k] = v
|
||||
self.update()
|
||||
}
|
||||
self.root.update = function()
|
||||
{
|
||||
self.update()
|
||||
}
|
||||
self.root.get = function(k)
|
||||
{
|
||||
return self[k]
|
||||
|
@ -4,23 +4,6 @@
|
||||
</div>
|
||||
<script>
|
||||
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(){
|
||||
$(self.refs.container)
|
||||
.css("display","flex")
|
||||
@ -36,7 +19,6 @@
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
var calibrate_size = function()
|
||||
{
|
||||
var auto_width = []
|
||||
@ -51,6 +33,7 @@
|
||||
this.observable = self.root.observable
|
||||
$(this)
|
||||
.css("flex-grow","1")
|
||||
//.css("height",avaiheight + "px")
|
||||
var dw = $(this).attr("data-width")
|
||||
if(dw)
|
||||
{
|
||||
@ -67,6 +50,8 @@
|
||||
{
|
||||
$(v).css("width", csize + "px")
|
||||
})
|
||||
self.root.observable.trigger("vboxchange",
|
||||
{id:$(self.root).attr("data-id"), w:csize, h:avaiheight})
|
||||
}
|
||||
</script>
|
||||
</afx-vbox>
|
@ -66,7 +66,7 @@ afx-menu afx-menu li{
|
||||
float:none;
|
||||
min-width: 150px;
|
||||
}
|
||||
afx-menu afx-menu afx-menu{
|
||||
afx-menu afx-menu afx-menu, afx-menu ul.context afx-menu{
|
||||
top:-4px;
|
||||
left: 100%;
|
||||
}
|
||||
@ -78,7 +78,7 @@ afx-menu li:hover > a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
afx-menu li:hover > afx-menu
|
||||
afx-menu afx-menu li:hover > afx-menu, ul.context li:hover > afx-menu
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
@ -92,7 +92,7 @@ afx-menu li.afx-corner-fix:hover{
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
afx-menu afx-menu .afx_submenu:before {
|
||||
afx-menu afx-menu .afx_submenu:before, afx-menu ul.context .afx_submenu:before{
|
||||
content: "\f054";
|
||||
font-family: "FontAwesome";
|
||||
font-size: 10px;
|
||||
@ -101,3 +101,19 @@ afx-menu afx-menu .afx_submenu:before {
|
||||
position:absolute;
|
||||
top:25%;
|
||||
}
|
||||
|
||||
afx-menu ul.context{
|
||||
position: absolute;
|
||||
z-index: 1000000;
|
||||
padding: 0;
|
||||
border:1px solid #a6a6a6;
|
||||
border-radius: 5px;
|
||||
border-top-left-radius: 0px;
|
||||
/*box-shadow: 2px 2px 2px #cbcbcb;*/
|
||||
box-shadow: 1px 1px 1px #9f9F9F;
|
||||
background-color: #e7e7e7;
|
||||
}
|
||||
afx-menu ul.context li{
|
||||
clear:float;
|
||||
min-width: 150px;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
self.OS.PM =
|
||||
pidalloc:0
|
||||
pidalloc: 0
|
||||
processes: new Object
|
||||
createProcess: (app,cls) ->
|
||||
createProcess: (app, cls) ->
|
||||
#if it is single ton
|
||||
# and a process is existing
|
||||
# just return it
|
||||
@ -15,12 +15,12 @@ self.OS.PM =
|
||||
_PM.pidalloc++
|
||||
obj.pid = _PM.pidalloc
|
||||
_PM.processes[app].push obj
|
||||
_GUI.dock obj,cls.meta
|
||||
if cls.type is 1 then _GUI.dock obj, cls.meta else _GUI.attachservice obj
|
||||
appByPid:(pid)->
|
||||
app = undefined
|
||||
find = (l) ->
|
||||
return a for a in l when a.pid is pid
|
||||
for k,v of _PM.processes
|
||||
for k, v of _PM.processes
|
||||
app = find v
|
||||
break if app
|
||||
app
|
||||
@ -30,6 +30,7 @@ self.OS.PM =
|
||||
|
||||
i = _PM.processes[app.name].indexOf app
|
||||
if i >= 0
|
||||
_GUI.undock _PM.processes[app.name][i]
|
||||
p = _PM.processes[app.name][i]
|
||||
if _APP[app.name].type == 1 then _GUI.undock p else _GUI.detachservice p
|
||||
delete _PM.processes[app.name][i]
|
||||
_PM.processes[app.name].splice i,1
|
||||
_PM.processes[app.name].splice i, 1
|
||||
|
@ -5,6 +5,7 @@ self.OS or=
|
||||
GUI: new Object()
|
||||
APP: new Object()
|
||||
PM: new Object()
|
||||
courrier: riot.observable()
|
||||
register: (name,x)->
|
||||
# load the metadata first
|
||||
_APP[name] = x
|
||||
@ -15,4 +16,8 @@ self.OS or=
|
||||
_GUI = self.OS.GUI
|
||||
_GUI.loadTheme "antos"
|
||||
_GUI.initDM()
|
||||
#_GUI.loadScheme "resources/schemes/test.html",null
|
||||
_courrier.on "syspanelloaded", () ->
|
||||
_GUI.pushService "PushNotification"
|
||||
_GUI.pushService "Spotlight"
|
||||
_GUI.pushService "Calendar"
|
||||
|
@ -14,7 +14,7 @@ class ActivityMonitor extends this.OS.GUI.BaseApplication
|
||||
app = _PM.appByPid item[0].value
|
||||
app.quit() if app
|
||||
|
||||
header = [{width:50,value:"Pid"},{value:"Name"},{width:100,value:"Alive (ms)"}]
|
||||
header = [{width:50,value:"Pid"},{value:"Name"}, {value:"Type", width:75},{width:70,value:"Alive (ms)"}]
|
||||
@gdata =
|
||||
processes:{}
|
||||
alive:[]
|
||||
@ -29,11 +29,14 @@ class ActivityMonitor extends this.OS.GUI.BaseApplication
|
||||
$.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
|
||||
me.gdata.processes[a.pid][3].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},
|
||||
{icon:if _APP[a.name].type == 1 then _APP[a.name].meta.icon else a.icon,
|
||||
iconclass:if _APP[a.name].type == 1 then _APP[a.name].meta.iconclass else a.iconclass,
|
||||
value:a.name},
|
||||
{value: if _APP[a.name].type == 1 then "Application" else "Service"}
|
||||
{value: now - a.birth}
|
||||
]
|
||||
me.gdata.alive.push a.pid
|
||||
|
@ -13,7 +13,7 @@ NC=\033[0m
|
||||
main: title clean js css copy
|
||||
|
||||
title:
|
||||
@echo "$(BLUE)======= Package Terminal =======$(NC)"
|
||||
@echo "$(BLUE)======= Package DummyApp =======$(NC)"
|
||||
|
||||
coffee:
|
||||
- mkdir build
|
@ -1,6 +1,6 @@
|
||||
class Terminal extends this.OS.GUI.BaseApplication
|
||||
class DummyApp extends this.OS.GUI.BaseApplication
|
||||
constructor: () ->
|
||||
super "Terminal"
|
||||
super "DummyApp"
|
||||
main: () ->
|
||||
self = @
|
||||
@on "btclick", (e)->
|
||||
@ -19,7 +19,7 @@ class Terminal extends this.OS.GUI.BaseApplication
|
||||
tdata = {
|
||||
name: 'My Tree',
|
||||
nodes: [
|
||||
{ name: 'hello', icon:'packages/NotePad/icon.png'},
|
||||
{ name: 'hello', icon:'fa fa-car'},
|
||||
{ name: 'wat' },
|
||||
{
|
||||
name: 'child folder',
|
||||
@ -76,5 +76,12 @@ class Terminal extends this.OS.GUI.BaseApplication
|
||||
list.set "onlistselect", (e)->
|
||||
console.log e
|
||||
|
||||
Terminal.singleton = false
|
||||
this.OS.register "Terminal",Terminal
|
||||
@scheme.set "apptitle", "AntOS feature showcase"
|
||||
|
||||
@scheme.contextmenuHandler = (e, m) ->
|
||||
mdata = [ { text: " Child 1" }, { text: "child2", child: [{text: "sub child", child:[{text:"sub sub child"}] }]}]
|
||||
m.set "items", mdata
|
||||
m.show(e)
|
||||
|
||||
DummyApp.singleton = false
|
||||
this.OS.register "DummyApp",DummyApp
|
12
src/packages/DummyApp/package.json
Normal file
12
src/packages/DummyApp/package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"app":"DummyApp",
|
||||
"name":"DummyApp",
|
||||
"description":"App for test",
|
||||
"author":{
|
||||
"name": "Xuan Sang LE",
|
||||
"email": "xsang.le@gmail.com"
|
||||
},
|
||||
"category":"System",
|
||||
"iconclass":"fa fa-user-circle-o",
|
||||
"mimes":["*"]
|
||||
}
|
@ -14,7 +14,7 @@ class NotePad extends this.OS.GUI.BaseApplication
|
||||
enableBasicAutocompletion: true,
|
||||
enableSnippets: true,
|
||||
enableLiveAutocompletion: true,
|
||||
fontSize: "10pt"
|
||||
fontSize: "9pt"
|
||||
}
|
||||
@.editor.completers.push {getCompletions:(editor, session, pos, prefix, callback)->}
|
||||
@.editor.getSession().setUseWrapMode true
|
||||
@ -34,8 +34,7 @@ class NotePad extends this.OS.GUI.BaseApplication
|
||||
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)
|
||||
@.editor.getSession().selection.on "changeCursor", (e)->stup(e)
|
||||
|
||||
@on "resize", ()-> me.editor.resize()
|
||||
@on "focus", ()->me.editor.focus()
|
||||
|
@ -1,9 +1,16 @@
|
||||
afx-app-window[data-id="notepad"] afx-list-view[data-id="modelist"] {
|
||||
margin: 2px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
afx-app-window[data-id="notepad"] afx-list-view[data-id="modelist"]{
|
||||
margin:2px;
|
||||
afx-app-window[data-id="notepad"] afx-list-view[data-id="modelist"] div.list-container{
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
afx-app-window[data-id="notepad"] span[data-id="editorstat"]{
|
||||
padding:5px;
|
||||
display: inline-block;
|
||||
}
|
||||
afx-app-window[data-id="notepad"] afx-vbox[data-id="bottom-vbox"]{
|
||||
background-color: #dfdfdf;
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
|
||||
</afx-hbox-->
|
||||
<div data-id="datarea"></div>
|
||||
<afx-vbox data-height="30">
|
||||
<afx-vbox data-height="30" data-id="bottom-vbox">
|
||||
<div ><span data-id = "editorstat"></span></div>
|
||||
<afx-list-view data-width="170" data-id = "modelist" dropdown = "true" width="150"></afx-list-view>
|
||||
|
||||
|
34
src/packages/wTerm/Makefile
Normal file
34
src/packages/wTerm/Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
coffee_files = main.coffee
|
||||
|
||||
jsfiles = xterm.js
|
||||
|
||||
cssfiles = xterm.css main.css
|
||||
|
||||
copyfiles = scheme.html package.json
|
||||
|
||||
|
||||
BLUE=\033[1;34m
|
||||
NC=\033[0m
|
||||
|
||||
main: title clean js css copy
|
||||
|
||||
title:
|
||||
@echo "$(BLUE)======= Package wTerm =======$(NC)"
|
||||
- rm -rf build/*
|
||||
|
||||
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/*
|
71
src/packages/wTerm/main.coffee
Normal file
71
src/packages/wTerm/main.coffee
Normal file
@ -0,0 +1,71 @@
|
||||
class wTerm extends this.OS.GUI.BaseApplication
|
||||
constructor: () ->
|
||||
super "wTerm"
|
||||
|
||||
main: () ->
|
||||
me = @
|
||||
@scheme.set "apptitle", "Terminal"
|
||||
@mterm = @find "myterm"
|
||||
@term = new Terminal { cursorBlink: true }
|
||||
@term.on "key", (d, e) ->
|
||||
me.socket.send "i#{d}" if me.socket
|
||||
@term.on 'title', () -> console.log "title change"
|
||||
@term.open @mterm
|
||||
@socket = null
|
||||
#@on "resize", () -> me.resizeContent()
|
||||
@on "focus", () -> me.term.focus()
|
||||
# handle the paste event
|
||||
area = ($ ".xterm-helper-textarea", @mterm)[0]
|
||||
area.onpaste = (e) ->
|
||||
#ifreturn false unless @socket
|
||||
pastedText = undefined
|
||||
if window.clipboardData and window.clipboardData.getData #IE
|
||||
pastedText = window.clipboardData.getData 'Text'
|
||||
else if e.clipboardData and e.clipboardData.getData
|
||||
pastedText = e.clipboardData.getData 'text/plain'
|
||||
return false unless pastedText
|
||||
# send by chunk, to ease the handle on server side
|
||||
len = pastedText.length
|
||||
chunklen = len / 1000 + if (len % 1000 == 0) then 0 else 1
|
||||
for i in [0..(len - 1)]
|
||||
end = if (i + 1) * 1000 > len then len else (i + 1) * 1000
|
||||
me.term.write pastedText.substring i * 1000, end
|
||||
#self.socket.send("i"+ substr.replace(/\n/g,"\r\n"))
|
||||
@openSession()
|
||||
@on "vboxchange", (e) -> me.resizeContent e.w, e.h
|
||||
|
||||
resizeContent: (w, h) ->
|
||||
ex = @term.rowContainer.firstElementChild
|
||||
oldhtml = ($ ex).html()
|
||||
($ ex).css "display", "inline"
|
||||
($ ex).html "W"
|
||||
ncol = parseInt (w / ($ ex).width())
|
||||
nrow = parseInt (h / ($ ex).height())
|
||||
($ ex).css "display", ""
|
||||
($ ex).html oldhtml
|
||||
@term.resize ncol, nrow
|
||||
return if not @socket or (@socket.readyState isnt @socket.OPEN)
|
||||
#initialGeometry = @.term.proposeGeometry()
|
||||
#cols = initialGeometry.cols
|
||||
#rows = initialGeometry.rows
|
||||
#console.log "send", "s#{ncol}:#{nrow}"
|
||||
@socket.send "s#{ncol}:#{nrow}"
|
||||
|
||||
openSession: () ->
|
||||
me = @
|
||||
@term.clear()
|
||||
@term.focus()
|
||||
@socket = new WebSocket "ws://" + window.location.host + "/wterm"
|
||||
@socket.onopen = () ->
|
||||
#el.style.display = "none"
|
||||
me.resizeContent (($ me.mterm).width()) , (($ me.mterm).height())
|
||||
me.term.focus()
|
||||
|
||||
@socket.onmessage = (e) -> me.term.write e.data if me.term and e.data
|
||||
@socket.onclose = () ->
|
||||
me.socket = null
|
||||
console.log "socket closed"
|
||||
#el.style.display = "block"
|
||||
exit: (e)->
|
||||
@socket.close() if @socket
|
||||
this.OS.register "wTerm",wTerm
|
0
src/packages/wTerm/main.css
Normal file
0
src/packages/wTerm/main.css
Normal file
@ -1,5 +1,5 @@
|
||||
{
|
||||
"app":"Terminal",
|
||||
"app":"wTerm",
|
||||
"name":"Unix terminal like",
|
||||
"description":"Access Unix terminal from web",
|
||||
"author":{
|
5
src/packages/wTerm/scheme.html
Normal file
5
src/packages/wTerm/scheme.html
Normal file
@ -0,0 +1,5 @@
|
||||
<afx-app-window apptitle="Preview" width="600" height="400">
|
||||
<afx-vbox data-id = "mybox">
|
||||
<div data-id="myterm" ></div>
|
||||
</afx-vbox>
|
||||
</afx-app-window>
|
2261
src/packages/wTerm/xterm.css
Executable file
2261
src/packages/wTerm/xterm.css
Executable file
File diff suppressed because it is too large
Load Diff
5132
src/packages/wTerm/xterm.js
Executable file
5132
src/packages/wTerm/xterm.js
Executable file
File diff suppressed because it is too large
Load Diff
23
src/services/Calendar.coffee
Normal file
23
src/services/Calendar.coffee
Normal file
@ -0,0 +1,23 @@
|
||||
class Calendar extends this.OS.GUI.BaseService
|
||||
constructor: () ->
|
||||
super "Calendar"
|
||||
#@iconclass = "fa fa-commenting"
|
||||
@text = ""
|
||||
@iconclass = "fa fa-calendar"
|
||||
init: ->
|
||||
#update time each second
|
||||
me = @
|
||||
@watch 1000, () ->
|
||||
now = new Date
|
||||
me.text = "#{now.getDate()}/#{(now.getMonth()+1)}/#{now.getFullYear()} " +
|
||||
"#{now.getHours()}:#{now.getMinutes()}:#{now.getSeconds()}"
|
||||
me.update()
|
||||
|
||||
awake: ->
|
||||
console.log @name,@pid
|
||||
# do nothing
|
||||
cleanup: ->
|
||||
console.log "cleanup for quit"
|
||||
# do nothing
|
||||
|
||||
this.OS.register "Calendar",Calendar
|
13
src/services/PushNotification.coffee
Normal file
13
src/services/PushNotification.coffee
Normal file
@ -0,0 +1,13 @@
|
||||
class PushNotification extends this.OS.GUI.BaseService
|
||||
constructor: () ->
|
||||
super "PushNotification"
|
||||
@iconclass = "fa fa-commenting"
|
||||
|
||||
init: ->
|
||||
# do nothing
|
||||
awake: ->
|
||||
console.log @name,@pid
|
||||
cleanup: ->
|
||||
# do nothing
|
||||
|
||||
this.OS.register "PushNotification",PushNotification
|
13
src/services/Spotlight.coffee
Normal file
13
src/services/Spotlight.coffee
Normal file
@ -0,0 +1,13 @@
|
||||
class Spotlight extends this.OS.GUI.BaseService
|
||||
constructor: () ->
|
||||
super "Spotlight"
|
||||
@iconclass = "fa fa-search"
|
||||
|
||||
init: ->
|
||||
# do nothing
|
||||
awake: ->
|
||||
console.log @name,@pid
|
||||
cleanup: ->
|
||||
# do nothing
|
||||
|
||||
this.OS.register "Spotlight",Spotlight
|
Loading…
Reference in New Issue
Block a user