antos-frontend/src/core/gui.coffee

280 lines
10 KiB
CoffeeScript
Raw Normal View History

2017-08-07 00:49:24 +02:00
self.OS.GUI =
2018-01-26 18:57:28 +01:00
dialogs: new Object()
dialog: undefined
2017-08-24 01:53:13 +02:00
htmlToScheme: (html, app, parent) ->
scheme = $.parseHTML html
($ parent).append scheme
riot.mount ($ scheme), { observable: app.observable }
app.scheme = scheme[0]
app.main()
app.show()
loadScheme: (path, app, parent) ->
2017-08-15 02:56:04 +02:00
_API.get path,
2017-08-14 00:20:19 +02:00
(x) ->
2017-08-11 01:58:46 +02:00
return null unless x
2017-08-24 01:53:13 +02:00
_GUI.htmlToScheme x, app, parent
2017-08-26 16:50:13 +02:00
, (e, s) ->
2017-08-27 23:40:02 +02:00
_courrier.osfail "Cannot load scheme file: #{path} for #{app.name} (#{app.pid})",e,s
clearTheme: () ->
$ "head link#ostheme"
.attr "href", ""
2017-08-14 00:20:19 +02:00
2018-01-26 18:57:28 +01:00
loadTheme: (name, force) ->
_GUI.clearTheme() if force
2017-08-07 00:49:24 +02:00
path = "resources/themes/#{name}/#{name}.css"
2017-08-11 01:58:46 +02:00
$ "head link#ostheme"
.attr "href", path
2017-08-14 00:20:19 +02:00
pushServices: (srvs) ->
f = (v) ->
_courrier.observable.one "srvroutineready", () -> _GUI.pushService v
_GUI.pushService srvs[0]
srvs.splice 0, 1
f i for i in srvs
2018-01-26 18:57:28 +01:00
openDialog: (d, f, title, data) ->
if _GUI.dialog
_GUI.dialog.show()
return
if not _GUI.dialogs[d]
ex = _API.throwe "Dialog"
return _courrier.oserror "Dialog #{d} not found", ex, null
_GUI.dialog = new _GUI.dialogs[d]()
_GUI.dialog.parent = _GUI
_GUI.dialog.handler = f
_GUI.dialog.pid = -1
_GUI.dialog.data = data
_GUI.dialog.title = title
_GUI.dialog.init()
2018-01-22 19:59:08 +01:00
pushService: (ph) ->
arr = ph.split "/"
srv = arr[1]
app = arr[0]
2017-08-27 23:40:02 +02:00
return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv]
2018-01-22 19:59:08 +01:00
_GUI.loadApp app,
2018-01-24 01:03:14 +01:00
(a) ->
2018-01-22 19:59:08 +01:00
return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv]
(e, s) ->
_courrier.trigger "srvroutineready", srv
2017-08-27 23:40:02 +02:00
_courrier.osfail "Cannot read service script: #{srv} ", e, s
2018-01-22 19:59:08 +01:00
2018-01-26 18:57:28 +01:00
appsByMime: (mime) ->
metas = ( a.meta for k, a of _OS.APP when a.type is 1)
mimes = ( m.mimes for m in metas )
apps = []
# search app by mimes
f = ( arr, idx ) ->
arr.filter (m, i) ->
if mime.match (new RegExp m, "g")
apps.push metas[idx]
return false
return false
2018-01-26 19:10:00 +01:00
( f m, i if m ) for m, i in mimes
2018-01-26 18:57:28 +01:00
return apps
openWith: (it) ->
return unless it
console.log "open #{it.path}"
apps = _GUI.appsByMime ( if it.type is "dir" then "dir" else it.mime )
return OS.info "No application available to open #{it.filename}" if apps.length is 0
return _GUI.launch apps[0].app, [it.path] if apps.length is 1
list = ( { text: e.app, icon: e.icon, iconclass: e.iconclass } for e in apps )
_GUI.openDialog "SelectionDialog", ( d ) ->
_GUI.launch d.text, [it.path]
, "Open width", list
2017-08-27 23:40:02 +02:00
forceLaunch: (app, args) ->
console.log "This method is used for developing only, please use the launch method instead"
_PM.killAll app
_OS.APP[app] = undefined
_GUI.launch app, args
2018-01-24 01:03:14 +01:00
loadApp: (app, ok, err) ->
2018-01-22 19:59:08 +01:00
path = "packages/#{app}/"
_API.script path + "main.js",
(d) ->
#load css file
_API.get "#{path}main.css",
() ->
$ '<link>', { rel: 'stylesheet', type: 'text/css', 'href': "#{path}main.css" }
.appendTo 'head'
, () ->
#launch
if _OS.APP[app]
# load app meta data
_API.get "#{path}package.json",
(data) ->
_OS.APP[app].meta = data
ok app
, (e, s) ->
_courrier.osfail "Cannot read application metadata: #{app}", e, s
err e, s
else
ok app
, (e, s) ->
#BUG report here
_courrier.osfail "Cannot load application script: #{app}", e, s
console.log "bug report", e, s, path
err e,s
2017-08-27 23:40:02 +02:00
launch: (app, args) ->
if not _OS.APP[app]
2017-08-11 01:58:46 +02:00
# first load it
2018-01-22 19:59:08 +01:00
_GUI.loadApp app,
(a)->
_PM.createProcess a, _OS.APP[a], args
2017-08-26 16:50:13 +02:00
, (e, s) ->
2017-08-11 01:58:46 +02:00
else
2017-08-14 00:20:19 +02:00
# now launch it
2017-08-27 23:40:02 +02:00
if _OS.APP[app]
_PM.createProcess app, _OS.APP[app], args
2017-08-26 16:50:13 +02:00
dock: (app, meta) ->
2017-08-14 00:20:19 +02:00
# dock an application to a dock
# create a data object
2017-08-15 02:56:04 +02:00
data =
icon: null
iconclass: meta.iconclass || ""
2017-08-26 16:50:13 +02:00
app: app
onbtclick: () -> app.toggle()
2017-08-14 00:20:19 +02:00
data.icon = "packages/#{meta.app}/#{meta.icon}" if meta.icon
2017-08-26 16:50:13 +02:00
# TODO: add default app icon class in system setting
# so that it can be themed
2017-08-14 00:20:19 +02:00
data.iconclass = "fa fa-cogs" if (not meta.icon) and (not meta.iconclass)
dock = $ "#sysdock"
2017-08-26 16:50:13 +02:00
app.one "rendered", () ->
dock.get(0).newapp data
app.sysdock = dock.get(0)
app.appmenu = ($ "[data-id = 'appmenu']", "#syspanel")[0]
2017-08-14 00:20:19 +02:00
app.init()
undock: (app) ->
($ "#sysdock").get(0).removeapp app
2017-08-15 02:56:04 +02:00
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
p = $(e).parent().get(0)
handler p if p isnt ($ "#workspace").get(0)
handler event.target
event.preventDefault()
2017-08-11 01:58:46 +02:00
initDM: ->
2017-08-27 23:40:02 +02:00
# check login first
2017-08-11 01:58:46 +02:00
_API.resource "schemes/dm.html", (x) ->
return null unless x
2017-08-15 02:56:04 +02:00
scheme = $.parseHTML x
2017-08-11 01:58:46 +02:00
($ "#wrapper").append scheme
2018-01-26 18:57:28 +01:00
# system menu and dock
riot.mount ($ "#syspanel", $ "#wrapper")
riot.mount ($ "#sysdock", $ "#wrapper"), { items: [] }
2017-08-15 02:56:04 +02:00
# context menu
riot.mount ($ "#contextmenu")
($ "#workspace").contextmenu (e) -> _GUI.bindContextMenu e
2018-01-26 18:57:28 +01:00
# desktop default file manager
desktop = $ "#desktop"
desktop[0].fetch = () ->
fp = _OS.setting.desktop.path.asFileHandler()
fn = () ->
fp.read (d) ->
return _courrier.osfail d.error, (_API.throwe "OS.VFS"), d.error if d.error
items = []
$.each d.result, (i, v) ->
return if v.filename[0] is '.' and not _OS.setting.desktop.showhidden
v.text = v.filename
#v.text = v.text.substring(0,9) + "..." ifv.text.length > 10
v.iconclass = v.type
items.push(v)
desktop[0].set "items", items
desktop[0].refresh()
fp.onready () ->
fn()
, ( e ) -> # try to create the path
console.log "#{fp.path} not found"
name = fp.basename
fp.parent().asFileHandler().mk name, (r) ->
ex = _API.throwe "OS.VFS"
if r.error then _courrier.osfail d.error, ex, d.error else fn()
desktop[0].ready = (e) ->
e.observable = _courrier
window.onresize = () ->
_courrier.trigger "desktopresize"
e.refresh()
desktop[0].set "onlistselect", (d) ->
($ "#sysdock").get(0).set "selectedApp", null
desktop[0].set "onlistdbclick", ( d ) ->
($ "#sysdock").get(0).set "selectedApp", null
it = desktop[0].get "selected"
_GUI.openWith it
($ "#workingenv").on "click", (e) ->
desktop[0].set "selected", -1
desktop.on "click", (e) ->
($ "#sysdock").get(0).set "selectedApp", null
desktop[0].set "selected", -1 if e.target is desktop[0]
console.log "desktop clicked"
desktop[0].contextmenuHandler = (e, m) ->
desktop[0].set "selected", -1 if e.target is desktop[0]
console.log "context menu handler for desktop"
desktop[0].fetch()
_courrier.trigger "desktoploaded"
# mount it
riot.mount desktop
2017-08-27 23:40:02 +02:00
, (e, s) ->
alert "System fall: Cannot init desktop manager"
login: () ->
2018-01-04 11:51:12 +01:00
_OS.cleanup()
2017-08-27 23:40:02 +02:00
_API.resource "schemes/login.html", (x) ->
return null unless x
scheme = $.parseHTML x
($ "#wrapper").append scheme
($ "#btlogin").click () ->
data =
username: ($ "#txtuser").val(),
password: ($ "#txtpass").val()
_API.handler.login data, (d) ->
if d.error then ($ "#login_error").html d.error else _GUI.startAntOS d.result
, (e, s) ->
alert "System fall: Cannot init login screen"
startAntOS: (conf) ->
2018-01-26 18:57:28 +01:00
# clean up things
2018-01-04 11:51:12 +01:00
_OS.cleanup()
2018-01-26 18:57:28 +01:00
# get setting from conf
_OS.setting.desktop = conf.desktop if conf.desktop
2017-08-27 23:40:02 +02:00
_OS.setting.applications = conf.applications if conf.applications
_OS.setting.appearance = conf.appearance if conf.appearance
_OS.setting.user = conf.user
2018-01-26 18:57:28 +01:00
_OS.setting.desktop.path = "home:///.desktop" unless _OS.setting.desktop.path
2017-08-27 23:40:02 +02:00
# load theme
_GUI.loadTheme "antos"
2018-01-26 18:57:28 +01:00
# initDM
2017-08-27 23:40:02 +02:00
_GUI.initDM()
_courrier.observable.one "syspanelloaded", () ->
2018-01-26 18:57:28 +01:00
# TODO load packages list then build system menu
# push startup services
# TODO: get services list from user setting
_GUI.pushServices ["CoreServices/PushNotification", "CoreServices/Spotlight", "CoreServices/Calendar"]
# startup application here
_courrier.observable.one "desktoploaded", () ->
_GUI.launch "Files"
_GUI.launch "NotePad"