add darkmode themes, clean up

This commit is contained in:
Xuan Sang LE 2020-05-18 18:53:59 +02:00
parent c94cb0963d
commit 40b06f8f1a
118 changed files with 1138 additions and 4508 deletions

View File

@ -91,20 +91,25 @@ languages:
genlang:
read -r -p "Enter locale: " LOCAL;\
./src/core/languages/gen.sh ./src ./src/core/languages/$$LOCAL.json
build_themes: antos_themes_build
build_themes: antos_light antos_dark
-rm -rf $(BUILDDIR)/resources/themes/system/*
-mkdir -p $(BUILDDIR)/resources/themes/system
cp -r src/themes/system/fonts $(BUILDDIR)/resources/themes/system
cp -r src/themes/system/wp $(BUILDDIR)/resources/themes/system
for f in src/themes/system/*.css; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/themes/system/system.css;done
antos_themes_build:
@echo "$(BLUE)Building themes name: antos$(NC)"
-rm -rf $(BUILDDIR)/resources/themes/antos/*
-mkdir -p $(BUILDDIR)/resources/themes/antos
for f in src/themes/antos/*.css; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/themes/antos/antos.css;done
-mkdir -p $(BUILDDIR)/resources/themes/antos/fonts
cp -rf src/themes/antos/fonts/* $(BUILDDIR)/resources/themes/antos/fonts
antos_light:
@echo "$(BLUE)Building themes name: antos-light$(NC)"
-rm -rf $(BUILDDIR)/resources/themes/antos_light/*
-mkdir -p $(BUILDDIR)/resources/themes/antos_light
for f in src/themes/antos_light/*.css; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/themes/antos_light/antos_light.css;done
antos_dark:
@echo "$(BLUE)Building themes name: antos-dark$(NC)"
-rm -rf $(BUILDDIR)/resources/themes/antos_dark/*
-mkdir -p $(BUILDDIR)/resources/themes/antos_dark
for f in src/themes/antos_dark/*.css; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/themes/antos_dark/antos_dark.css;done
build_packages:
@ -139,7 +144,8 @@ uglify:
# uglify tags
# npm install uglifycss -g
# uglify the css
uglifycss --output $(BUILDDIR)/resources/themes/antos/antos.css $(BUILDDIR)/resources/themes/antos/antos.css
uglifycss --output $(BUILDDIR)/resources/themes/antos_light/antos_light.css $(BUILDDIR)/resources/themes/antos_light/antos_light.css
uglifycss --output $(BUILDDIR)/resources/themes/antos_dark/antos_dark.css $(BUILDDIR)/resources/themes/antos_dark/antos_dark.css
uglifycss --output $(BUILDDIR)/resources/themes/system/system.css $(BUILDDIR)/resources/themes/system/system.css
#uglify each packages

View File

@ -112,8 +112,8 @@ class BaseModel
warn: (m) ->
@publish "warning", m
error: (m) ->
@publish "error", m, (@_api.throwe @name)
error: (m, e) ->
@publish "error", m, if e then e else (@_api.throwe @name)
fail: (m) ->
@publish "fail", m

View File

@ -169,8 +169,8 @@ Ant.OS.API =
# handles are defined in /src/handles
handle: {}
shared: {} # shared libraries
searchHandle:{}
lang:{}
searchHandle: {}
lang: {}
#request a user data
mid: () ->
return Ant.OS.announcer.getMID()
@ -182,16 +182,23 @@ Ant.OS.API =
type: 'POST',
url: p,
contentType: 'application/json',
data: JSON.stringify d,
data: JSON.stringify(d,
(k, v) ->
return undefined if k is "domel"
return v
, 4),
dataType: 'json',
success: null
}
.done (data) ->
Ant.OS.API.loaded q, p, "OK"
resolve(data)
.fail (e, s) ->
.fail (j, s, e) ->
Ant.OS.API.loaded q, p, "FAIL"
reject(e, s)
if e
reject e
else
reject(Ant.OS.API.throwe s)
blob: (p) ->
new Promise (resolve, reject) ->
@ -232,9 +239,12 @@ Ant.OS.API =
Ant.OS.API.loaded q, p, "OK"
resolve(data)
o.remove()
.fail (e, s) ->
.fail (j, s, e) ->
Ant.OS.API.loaded q, p, "FAIL"
reject(e, s)
if e
reject e
else
reject(Ant.OS.API.throwe s)
o.remove()
o.click()
@ -268,21 +278,15 @@ Ant.OS.API =
.done (data) ->
Ant.OS.API.loaded q, p, "OK"
resolve(data)
.fail (e, s) ->
.fail (j, s, e) ->
Ant.OS.API.loaded q, p, "FAIL"
reject(e, s)
if e
reject e
else
reject(Ant.OS.API.throwe s)
script: (p) ->
new Promise (resolve, reject) ->
q = Ant.OS.announcer.getMID()
Ant.OS.API.loading q, p
$.getScript p
.done (data) ->
Ant.OS.API.loaded q, p, "OK"
resolve(data)
.fail (e, s) ->
Ant.OS.API.loaded q, p, "FAIL"
reject(e, s)
Ant.OS.API.get p, "script"
resource: (r) ->
path = "resources/#{r}"
@ -400,7 +404,7 @@ Ant.OS.API =
Object.defineProperty o, v, {
enumerable: true,
set: (value) ->
for k,l of @__p
for k, l of @__p
@__p[k] = false
o.__p[v] = value
, get: () ->
@ -412,7 +416,7 @@ Ant.OS.API =
configurable: true,
enumerable: false,
get: () ->
for k,v of o.__p
for k, v of o.__p
return k if v
}
return o

View File

@ -20,7 +20,7 @@
ord() {
LC_CTYPE=C printf '%d' "'$1"
}
grep --include=\*.{coffee,tag} -roh "$1" -e '__("[^"]*"' | while read -r line ; do
grep --include=\*.{coffee} -roh "$1" -e '__("[^"]*"' | while read -r line ; do
SUBSTRING=$(echo $line| cut -d'"' -f 2)
if test -f "$2" && [ ! -z "$(grep -F "\"$SUBSTRING\":" "$2")" ]
then
@ -29,7 +29,7 @@ grep --include=\*.{coffee,tag} -roh "$1" -e '__("[^"]*"' | while read -r line ;
echo -e "\t\"$SUBSTRING\":\"$SUBSTRING\"," >> "tmp.json"
fi
done
grep --include=\*.{coffee,html,tag} -roh "$1" -e '\"__([^\"]*)\"' | while read -r line; do
grep --include=\*.{coffee,html} -roh "$1" -e '\"__([^\"]*)\"' | while read -r line; do
len=$(( ${#line} - 6 ))
#echo $len
#echo $line

View File

@ -48,7 +48,8 @@
],
apps: []
} if not Ant.OS.setting.system.startup
if not Ant.OS.setting.system.error_report
Ant.OS.setting.system.error_report = "https://os.iohub.dev/report"
Ant.OS.setting.system.pkgpaths = {
user: "home://.packages",
system: "os://packages"
@ -56,8 +57,18 @@
Ant.OS.setting.system.locale = "en_GB" unless Ant.OS.setting.system.locale
Ant.OS.setting.system.menu = {} unless Ant.OS.setting.system.menu
Ant.OS.setting.system.repositories = [] unless Ant.OS.setting.system.repositories
Ant.OS.setting.appearance.theme = "antos" unless Ant.OS.setting.appearance.theme
Ant.OS.setting.appearance.theme = "antos_dark" unless Ant.OS.setting.appearance.theme
if not Ant.OS.setting.appearance.themes
Ant.OS.setting.appearance.themes = [
{
text: "AntOS light",
name: "antos_light"
},
{
text: "AntOS dark",
name: "antos_dark"
}
]
Ant.OS.setting.VFS.gdrive = {
CLIENT_ID: ""
API_KEY: ""

View File

@ -5,9 +5,7 @@ class LabelTag extends Ant.OS.GUI.BaseTag
@setopt "icon", undefined
@setopt "iconclass", undefined
@setopt "class", undefined
@refs.text = document.createTextNode ""
$(@refs.container).append @refs.text
@setopt "text", ""
@setopt "text", undefined
mount: () ->
@ -37,7 +35,6 @@ class LabelTag extends Ant.OS.GUI.BaseTag
$(@refs.iclass).removeClass()
if v
$(@refs.iclass).addClass v
$(@refs.iclass).css "margin-right", "5px"
$(@refs.iclass).show()
else
$(@refs.iclass).hide()
@ -45,13 +42,18 @@ class LabelTag extends Ant.OS.GUI.BaseTag
__text__: (v) ->
@refs.text.nodeValue = v.__() if v
if v and v isnt ""
$(@refs.text).show()
$(@refs.text).html v.__()
else
$(@refs.text).hide()
layout: () ->
[{
el: "span", ref: "container", children: [
{ el: "i", ref: "iclass" },
{ el: "i", ref: "i", class: "icon-style" }
{ el: "i", ref: "i", class: "icon-style" },
{ el: "i", ref: "text", class: "label-text" }
]
}]

View File

@ -168,8 +168,8 @@ class WindowTag extends Ant.OS.GUI.BaseTag
width: $(@root).css("width"),
height: $(@root).css("height")
}
w = $(@desktop).width() - 5
h = $(@desktop).height() - 10
w = $(@desktop).width()
h = $(@desktop).height()
$(@root)
.css("top", "0")
.css("left", "0")

View File

@ -1,246 +0,0 @@
<afx-app-window ref = "window" >
<div class = "afx-window-wrapper">
<ul class= "afx-window-top" >
<li class = "afx-window-close" onclick = {close}></li>
<li if = {minimizable == true} class = "afx-window-minimize" onclick = {minimize}></li>
<li if = {resizable == true} class = "afx-window-maximize" onclick={maximize}></li>
<li ref = "dragger" class = "afx-window-title">{ apptitle?apptitle.__():apptitle }</li>
</ul>
<div class = "afx-clear"></div>
<div ref = "content" class = "afx-window-content">
<yield/>
</div>
<div if = {resizable == true} ref = "grip" class = "afx-window-grip">
</div>
<script>
this.apptitle = opts.apptitle || ""
if(opts.minimizable == undefined)
this.minimizable = true
else
this.minimizable = eval(opts.minimizable)
if(opts.resizable == undefined)
this.resizable = true
else
this.resizable = eval(opts.resizable)
var self = this
var offset = {top:0,left:0}
var desktop_pos = $("#desktop").offset()
var isMaxi = false
var history = {}
var width = opts.width || 400
var height = opts.height || 300
this.root.observable = opts.observable || riot.observable()
if(!window._zindex) window._zindex = 10
this.shown = false
self.root.contextmenuHandler = function (e) {}
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
if(k == "apptitle")
self.root.observable.trigger("apptitlechange")
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() {
var left,top
//left = 20 + Math.floor(Math.random() * ($("#desktop").width() - width))
//top = 20 + Math.floor(Math.random() * ($("#desktop").height() - height))
left = ($("#desktop").width() - width)/2
top = ($("#desktop").height() - height)/2
$(self.refs.window)
.css("position",'absolute')
.css("left",left + "px")
.css("top",top + "px")
.css("width",width + "px")
.css("height", height + "px")
.css("z-index",window._zindex++)
$(self.refs.window).on("mousedown", function(e){
if(self.shown == false)
self.root.observable.trigger("focus")
})
$(self.refs.window).click(function(e) {
//e.stopPropagation()
//e.windowactive = true
//self.root.observable.trigger("windowselect")
})
enable_dragging()
if(self.resizable)
enable_resize()
$(self.refs.dragger).dblclick(function(e){
toggle_window()
})
$(self.refs.content).children().each(function(e){
this.observable = self.root.observable
})
var fn = function()
{
var ch = $(self.refs.content).height()/ $(self.refs.content).children().length
$(self.refs.content).children().each(function(e){
$(this).css("height",ch+"px")
})
}
fn()
self.root.observable.on("resize", function(){ fn()})
self.root.observable.on("focus",function(){
window._zindex++
$(self.refs.window)
.show()
.css("z-index",window._zindex)
.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")
})
self.root.observable.trigger("rendered", self.root)
})
var enable_dragging = function()
{
$(self.refs.dragger)
.css("user-select","none")
.css("cursor","default")
$(self.refs.dragger).on("mousedown", function(e){
e.preventDefault()
offset = $(self.refs.window).offset()
offset.top = e.clientY - offset.top
offset.left = e.clientX - offset.left
$(window).on("mousemove", function(e){
var top,left
if(isMaxi)
{
toggle_window()
top = 0
letf = e.clientX - $(self.refs.window).width()/2
offset.top = 10 //center
offset.left = $(self.refs.window).width()/2
} else
{
top = e.clientY - offset.top - desktop_pos.top
left = e.clientX - desktop_pos.top - offset.left
left = left < 0?0:left;
top = top < 0?0:top;
}
$(self.refs.window).css("top", top +"px")
.css("left",left + "px")
})
$(window).on("mouseup", function(e){
//console.log("unbind mouse up")
$(window).unbind("mousemove", null)
})
})
}
var enable_resize = function()
{
if(!self.resizable) return
$(self.refs.grip)
.css("user-select","none")
.css("cursor","default")
.css("position","absolute")
.css("bottom","0")
.css("right","0")
.css("cursor","nwse-resize")
$(self.refs.grip).on("mousedown", function(e){
e.preventDefault()
offset.top = e.clientY
offset.left = e.clientX
$(window).on("mousemove", function(e){
var w,h
w = $(self.refs.window).width() + e.clientX - offset.left
h = $(self.refs.window).height() + e.clientY - offset.top
w = w < 100 ? 100:w
h = h < 100 ?100:h
offset.top = e.clientY
offset.left = e.clientX
$(self.refs.window)
.css("width", w +"px")
.css("height",h + "px")
isMaxi = false
self.root.observable.trigger('resize',
{id:$(self.root).attr("data-id"),w:w,h:h})
})
$(window).on("mouseup", function(e){
$(window).unbind("mousemove", null)
})
})
}
var toggle_window = function()
{
if(!self.resizable) return
if(isMaxi == false)
{
history = {
top: $(self.refs.window).css("top"),
left:$(self.refs.window).css("left"),
width:$(self.refs.window).css("width"),
height:$(self.refs.window).css("height")
}
var w,h
w = ($("#desktop").width() - 5)
h = ($("#desktop").height() - 10)
$(self.refs.window)
.css("width", w + "px")
.css("height", h + "px")
.css("top","0").css("left","0")
self.root.observable.trigger('resize',
{id:$(self.root).attr("data-id"),w:w,h:h})
isMaxi = true
}
else
{
isMaxi = false
$(self.refs.window)
.css("width",history.width)
.css("height",history.height)
.css("top",history.top).css("left",history.left)
self.root.observable.trigger('resize',
{id:$(self.root).attr("data-id"),w:history.width,h:history.height} )
}
}
maximize()
{
toggle_window()
}
</script>
</afx-app-window>

View File

@ -1,82 +0,0 @@
<afx-apps-dock>
<afx-button class = {selected: parent.selectedApp && it.app.pid == parent.selectedApp.pid} each={ it,i in items} iconclass = {it.iconclass} icon = {it.icon} appindex = {i} text = {it.text} onbtclick = {it.onbtclick} tooltip= {"cr:" + it.app.title()} >
</afx-button>
<script>
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()
if(v)
$("#desktop")[0].set("selected", -1)
}
}
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.update = function()
{
self.update()
}
self.root.get = function(k)
{
return self[k]
}
this.on("mount", function(){
window.OS.announcer.trigger("sysdockloaded")
})
self.root.contextmenuHandle = function(e, m)
{
if(e.target == self.root) return;
var appidx = $(e.target).closest( "afx-button" ).attr("appindex")
var app = self.items[appidx].app
m.set("items", [
{ text: "__(Show)", dataid:"show" },
{ text: "__(Hide)", dataid:"hide" },
{ text: "__(Close)", dataid:"quit" }
])
m.set("onmenuselect", function(evt)
{
if(app[evt.item.data.dataid])
app[evt.item.data.dataid]()
})
m.show(e)
}
</script>
</afx-apps-dock>

View File

@ -1,47 +0,0 @@
<afx-button >
<button class= { btactive: selected } disabled={ enable == false } onclick="{ _onbtclick }" ref = "mybtn" >
<afx-label color = {color} icon={icon} iconclass = {iconclass} text = {text} ></afx-label>
</button>
<script>
opts.enable = opts.enable || "true"
this.enable = eval(opts.enable) || false
this.icon = opts.icon
this.iconclass = opts.iconclass
this.color = opts.color
this.text = opts.text || ""
this.selected = eval(opts.selected) || false
this.toggle = eval(opts.toggle) || false
var self = this
this.onbtclick = opts.onbtclick
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.trigger = function()
{
$(self.refs.mybtn).trigger("click")
}
self.root.get = function(k)
{
return self[k]
}
this._onbtclick = function(e)
{
if(typeof self.onbtclick == 'string')
eval(self.onbtclick)
else if(self.onbtclick)
self.onbtclick(e)
if(self.root.observable)
{
self.root.observable.trigger("btclick",{id:$(self.root).attr("data-id"),data:self.root})
}
if(self.toggle)
self.root.set("selected",!self.selected)
}
</script>
</afx-button>

View File

@ -1,107 +0,0 @@
<afx-calendar-view>
<div><i class ="prevmonth" onclick={prevmonth}></i>
<afx-label text = {mtext}></afx-label>
<afx-label text = {year}></afx-label>
<i onclick={nextmonth} class="nextmonth"></i></div>
<afx-grid-view data-id ={"grid_" + rid} style = "height:100%;" ref = "grid" header = {header}> </afx-grid-view>
<script >
this.header = [{value:"__(Sun)"},{value:"__(Mon)"},{value:"__(Tue)"},{value:"__(Wed)"},{value:"__(Thu)"},{value:"__(Fri)"},{value:"__(Sat)"}]
this.root.observable = opts.observable
var self = this
this.day = 0
this.month = 0
this.year = 0
this.ondayselect = opts.ondayselect
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.selectedDate = undefined
self.root.get = function(k)
{
return self[k]
}
this.on("mount", function (e) {
self.refs.grid.root.observable = self.root.observable
calendar(null)
self.root.observable.on("gridcellselect", function(d){
if(d.id != "grid_" + self.rid) return
if(d.data.value == "") return
var data = {id:self.rid, data:new Date(self.year, self.month,d.data.value)};
if(self.ondayselect)
self.ondayselect(data)
self.selectedDate = data.data
self.root.observable.trigger("dayselect",data)
})
})
prevmonth()
{
self.selectedDate = undefined
this.month--
if(this.month < 0)
{
this.month = 11
this.year--
}
calendar(new Date(this.year, this.month,1))
}
nextmonth()
{
self.selectedDate = undefined
this.month++
if(this.month > 11)
{
this.month = 0
this.year++
}
calendar(new Date(this.year, this.month,1))
}
var calendar = function (date) {
if (date === null)
date = new Date()
self.day = date.getDate()
self.month = date.getMonth()
self.year = date.getFullYear()
var now ={ d:(new Date()).getDate(), m:(new Date()).getMonth(), y:(new Date()).getFullYear()}
months = ["__(January)", "__(February)", "__(March)", "__(April)", "__(May)", "__(June)", "__(July)", "__(August)", "__(September)", "__(October)", "__(November)", "__(December)"]
this_month = new Date(self.year, self.month, 1)
next_month = new Date(self.year, self.month + 1, 1)
// Find out when this month starts and ends.
first_week_day = this_month.getDay()
days_in_this_month = Math.round((next_month.getTime() - this_month.getTime()) / (1000 * 60 * 60 * 24))
self.mtext = months[self.month]
var rows = []
var row = []
// Fill the first week of the month with the appropriate number of blanks.
for (week_day = 0; week_day < first_week_day; week_day++)
row.push({value:""})
week_day = first_week_day;
for (day_counter = 1; day_counter <= days_in_this_month; day_counter++) {
week_day %= 7
if (week_day == 0)
{
rows.push(row)
row =[]
}
// Do something different for the current day.
if (now.d == day_counter && self.month == now.m && self.year == now.y)
row.push({value:day_counter, selected:true})
else
row.push({value:day_counter})
week_day++;
}
for(var i = 0; i <= 7 - row.length;i++)
row.push({value:""})
rows.push(row)
self.refs.grid.root.set("rows",rows)
}
</script>
</afx-calendar-view>

View File

@ -1,110 +0,0 @@
<afx-color-picker>
<div style = "width:310px; height:190px;display:block; padding:3px;">
<canvas class = "color-palette" width="284" height="155" style ="float:left;" ref = "palette" ></canvas>
<div class = "color-sample" style= "width:15px; height:155px; text-align:center; margin-left:3px; display:block;float:left;" ref = "colorval"></div>
<div class = "afx-clear"></div>
<div style ="margin-top:3px;">
<span>Hex:</span><input type = "text" ref = "hextext" style = "width:70px; margin-left:3px;margin-right:5px;"></input>
<span ref = 'rgbtext'></span>
</div>
</div>
<script>
var self = this
var colorctx = undefined
self.root.observable = opts.observable
self.oncolorsetect = opts.oncolorsetect
self.selectedColor = undefined
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]
}
var build_palette = function()
{
colorctx = $(self.refs.palette).get(0).getContext('2d')
var gradient = colorctx.createLinearGradient(0,0,$(self.refs.palette).width(),0)
// fill color
gradient.addColorStop(0, "rgb(255, 0, 0)")
gradient.addColorStop(0.15, "rgb(255, 0, 255)")
gradient.addColorStop(0.33, "rgb(0, 0, 255)")
gradient.addColorStop(0.49, "rgb(0, 255, 255)")
gradient.addColorStop(0.67, "rgb(0, 255, 0)")
gradient.addColorStop(0.84, "rgb(255, 255, 0)")
gradient.addColorStop(1, "rgb(255, 0, 0)")
gradient.addColorStop(0, "rgb(0, 0, 0)")
// Apply gradient to canvas
colorctx.fillStyle = gradient;
colorctx.fillRect(0, 0, colorctx.canvas.width, colorctx.canvas.height)
// Create semi transparent gradient (white -> trans. -> black)
gradient = colorctx.createLinearGradient(0, 0, 0, $(self.refs.palette).width())
gradient.addColorStop(0, "rgba(255, 255, 255, 1)")
gradient.addColorStop(0.5, "rgba(255, 255, 255, 0)")
gradient.addColorStop(0.5, "rgba(0, 0, 0, 0)")
gradient.addColorStop(1, "rgba(0, 0, 0, 1)")
// Apply gradient to canvas
colorctx.fillStyle = gradient
colorctx.fillRect(0, 0, colorctx.canvas.width, colorctx.canvas.height)
//$(self.refs.palette).css("position", "absolute")
// now add mouse move event
var getHex = function(c)
{
s = c.toString(16)
if(s.length == 1) s = "0" + s
return s
}
var pick_color = function(e)
{
$(self.refs.palette).css("cursor","crosshair")
var offset = $(self.refs.palette).offset()
var x = e.pageX - offset.left
var y = e.pageY - offset.top
var color = colorctx.getImageData(x,y, 1, 1)
var data = {
r:color.data[0],
g:color.data[1],
b:color.data[2],
text:'rgb(' + color.data[0] + ', ' + color.data[1] + ', ' + color.data[2] + ')',
hex:'#' + getHex(color.data[0]) + getHex(color.data[1]) + getHex(color.data[2])
}
return data
}
var mouse_move_h = function(e)
{
var data = pick_color(e)
$(self.refs.colorval).css("background-color", data.text)
}
$(self.refs.palette).mouseenter(function(e){
$(self.refs.palette).on("mousemove",mouse_move_h)
})
$(self.refs.palette).mouseout(function(e){
$(self.refs.palette).unbind("mousemove",mouse_move_h)
if(self.selectedColor)
$(self.refs.colorval).css("background-color", self.selectedColor.text)
})
$(self.refs.palette).on("click", function(e){
data = pick_color(e)
$(self.refs.rgbtext).html(data.text)
$(self.refs.hextext).val(data.hex)
self.selectedColor = data
if(self.oncolorsetect)
self.oncolorsetect(data)
if(! self.root.observable) return
self.root.observable.trigger("colorselect",data)
})
}
this.on("mount", function(){
build_palette()
})
</script>
</afx-color-picker>

View File

@ -1,10 +0,0 @@
<afx-dummy>
<yield/>
<script>
var self = this
self.root.update = function()
{
self.update()
}
</script>
</afx-dummy>

View File

@ -1,226 +0,0 @@
<afx-file-view>
<afx-list-view ref="listview" observable = {root.observable}></afx-list-view>
<afx-grid-view ref = "gridview" header = {header} observable = {root.observable}></afx-grid-view>
<div class = "treecontainer" ref="treecontainer">
<afx-tree-view ref = "treeview" observable = {root.observable}></afx-tree-view>
</div>
<afx-label if = {status == true} class = "status" ref = "stbar"></afx-label>
<script>
var self = this
self.root.observable = opts.observable || riot.observable()
self.view = opts.view || 'list'
self.data = opts.data || []
self.path = opts.path || "home:///"
self.onfileselect
self.onfileopen
this.status = opts.status == undefined?true:opts.status
this.selectedFile = undefined
this.showhidden = opts.showhidden
this.preventUpdate = false
this.fetch = opts.fetch
this.chdir = opts.chdir
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.header = [{value:"__(File name)"},{value: "__(Type)", width:150}, {value: "__(Size)", width:70}]
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
if(k == 'view')
switchView()
if(k == "data")
self.selectedFile = undefined
if(k != "preventUpdate")
self.update()
}
self.root.get = function(k)
{
return self[k]
}
var sortByType = function(a,b)
{
return a.type < b.type ? -1 : ( a.type > b.type ? 1: 0 )
}
var calibre_size = function()
{
var h = $(self.root).outerHeight()
var w = $(self.root).width()
if(self.refs.stbar)
h -= ($(self.refs.stbar.root).height() + 10)
$(self.refs.listview.root).css("height", h + "px")
$(self.refs.gridview.root).css("height", h + "px")
$(self.refs.treecontainer).css("height", h + "px")
$(self.refs.listview.root).css("width", w + "px")
$(self.refs.gridview.root).css("width", w + "px")
$(self.refs.treecontainer).css("width", w + "px")
}
var refreshList = function(){
var items = []
$.each(self.data, function(i, v){
if(v.filename[0] == '.' && !self.showhidden) return
v.text = v.filename
if(v.text.length > 10)
v.text = v.text.substring(0,9) + "..."
v.iconclass = v.iconclass?v.iconclass:v.type
v.icon = v.icon
items.push(v)
})
self.refs.listview.root.set("items", items)
}
var refreshGrid = function(){
var rows = []
$.each(self.data, function(i,v){
if(v.filename[0] == '.' && !self.showhidden) return
var row = [{value:v.filename, iconclass: v.iconclass?v.iconclass:v.type, icon:v.icon},{value:v.mime},{value:v.size},{idx:i}]
rows.push(row)
})
self.refs.gridview.root.set("rows",rows)
}
var refreshTree = function(){
self.refs.treeview.root.set("selectedItem", null)
var tdata = {}
tdata.name = self.path
tdata.nodes = getTreeData(self.data)
self.refs.treeview.root.set("data", tdata)
}
var getTreeData = function(data)
{
nodes = []
$.each(data, function(i,v){
if(v.filename[0] == '.' && !self.showhidden) return
v.name = v.filename
if(v.type == 'dir')
{
v.nodes = []
v.open = false
}
v.iconclass = v.iconclass?v.iconclass:v.type
v.icon = v.icon
nodes.push(v)
})
return nodes
}
var refreshData = function(){
self.data.sort(sortByType)
if(self.view == "icon")
refreshList()
else if(self.view == "list")
refreshGrid()
else
refreshTree()
}
var switchView = function()
{
$(self.refs.listview.root).hide()
$(self.refs.gridview.root).hide()
$(self.refs.treecontainer).hide()
self.selectedFile = undefined
self.refs.listview.root.set("selected", -1)
self.refs.treeview.selectedItem = undefined
self.refs.treeview.root.set("fetch",function(e,f){
if(!self.fetch) return
self.fetch(e, function(d){
f(getTreeData(d))
})
})
if(self.refs.stbar)
self.refs.stbar.root.set("text", "")
switch (self.view) {
case 'icon':
$(self.refs.listview.root).show()
break;
case 'list':
$(self.refs.gridview.root).show()
break;
case 'tree':
$(self.refs.treecontainer).show()
break;
default:
break;
}
calibre_size()
}
self.on("updated", function(){
if(self.preventUpdate)
{
self.preventUpdate = false
}
else
refreshData()
//console.log("update")
//calibre_size()
})
self.on("mount", function(){
switchView()
self.refs.listview.onlistselect = function(data)
{
data.id = self.rid
self.root.observable.trigger("fileselect",data)
}
self.refs.listview.onlistdbclick = function(data)
{
data.id = self.rid
self.root.observable.trigger("filedbclick",data)
}
self.refs.gridview.root.observable = self.root.observable
self.refs.gridview.ongridselect = function(d)
{
var data = {id:self.rid, data:self.data[d.data.child[3].idx], idx:d.data.child[3].idx}
self.root.observable.trigger("fileselect",data)
}
self.refs.gridview.ongriddbclick = function(d)
{
var data = {id:self.rid, data:self.data[d.data.child[3].idx], idx:d.data.child[3].idx}
self.root.observable.trigger("filedbclick",data)
}
self.refs.treeview.ontreeselect = function(d)
{
if(!d) return;
var data;
var el = d;
if(d.treepath == 0)// select the root
{
el = self.path.asFileHandler()
el.size = 0
el.filename = el.path
}
var data = {id:self.rid, data:el}
self.root.observable.trigger("fileselect",data)
}
self.refs.treeview.ontreedbclick = function(d)
{
if(!d || d.treepath == 0) return;
var data = {id:self.rid, data:d}
self.root.observable.trigger("filedbclick",data)
}
self.root.observable.on("fileselect", function(e){
if(e.id != self.rid) return
self.selectedFile = e.data
if(self.onfileselect)
self.onfileselect(e.data)
if(self.refs.stbar)
self.refs.stbar.root.set("text", __("Selected: {0} ({1} bytes)", e.data.filename, e.data.size?e.data.size:"0"))//.html()
})
self.root.observable.on("filedbclick", function(e){
if(e.id != self.rid ) return
if(e.data.type != "dir" && self.onfileopen)
self.onfileopen(e.data)
else if(self.chdir && e.data.type == "dir")
self.chdir(e.data.path)
})
calibre_size()
self.root.observable.on("resize", function(e){
calibre_size()
})
self.root.observable.on("calibrate", function(e){
calibre_size()
})
/*self.root.observable.on("*", function(e){
console.log(e)
})*/
})
</script>
</afx-file-view>

View File

@ -1,183 +0,0 @@
<afx-float-list ref = "container">
<div ref = "list">
<div each={item,i in items } class={float_list_item:true, float_list_item_selected: parent._autoselect(item,i)} ondblclick = {parent._dbclick} onmousedown = {parent._select} oncontextmenu = {parent._select}>
<afx-label color = {item.color} iconclass = {item.iconclass} icon = {item.icon} text = {item.text}></afx-label>
</div>
</div>
<script>
this.items = opts.items || []
var self = this
self.selidx = -1
self.onlistselect = opts.onlistselect
self.onlistdbclick = opts.onlistdbclick
self.fetch = undefined
this.root.observable = opts.observable || riot.observable()
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
self.dir = opts.dir || "horizontal"
self.root.set = function(k,v)
{
if(k == "selected")
{
if(self.selidx != -1)
self.items[self.selidx].selected =false
if(v == -1)
self.selidx = -1
else
if(self.items[v]) self.items[v].selected = true
}
else if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
if(k == "selected")
if(self.selidx == -1)
return undefined
else
return self.items[self.selidx]
return self[k]
}
self.root.push = function(e,u)
{
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)
{
if(self.selidx != -1)
{
self.items[self.selidx].selected =false
self.selidx = -1
}
self.items.splice(i, 1)
if(u)
self.update()
}
}
self.root.refresh = function()
{
_refresh()
}
this.on("mount", function(){
if(self.root.ready)
self.root.ready(self.root)
// now refresh the list
_refresh()
})
var _refresh = function()
{
var ctop = 20
var cleft = 20
var gw = $(self.refs.container).width()
var gh = $(self.refs.container).height()
$(self.refs.list)
.children()
.each(function(e)
{
$(this).unbind("mousedown")
_enable_drag($(this))
var w = $(this).width()
var h = $(this).height()
$(this).css("top", ctop + "px").css("left", cleft + "px")
if(self.dir == "horizontal")
{
ctop += h + 20
if(ctop > gh)
{
ctop = 20
cleft += w + 20
}
}
else
{
cleft += w + 20
if(cleft > gw )
{
cleft = 20
ctop += h + 20
}
}
})
}
var _enable_drag = function(el)
{
var globalof = $(self.refs.container).offset()
el
.css("user-select","none")
.css("cursor","default")
.css("position",'absolute')
.on("mousedown", function(e){
e.preventDefault()
offset = el.offset()
offset.top = e.clientY - offset.top
offset.left = e.clientX - offset.left
$(window).on("mousemove", function(e){
var top,left
top = e.clientY - offset.top - globalof.top
left = e.clientX - globalof.top - offset.left
left = left < 0?0:left
top = top < 0?0:top
el.css("top", top +"px").css("left",left + "px")
})
$(window).on("mouseup", function(e){
//console.log("unbind mouse up")
$(window).unbind("mousemove", null)
})
})
}
_autoselect(it,i)
{
if(self.selidx == i) return true
if(!it.selected || it.selected == false) return false
var data = {
id:self.rid,
data:it,
idx:i}
//if(self.selidx != -1)
// self.items[self.selidx].selected =false
self.selidx = i
if(self.onlistselect)
self.onlistselect(data)
this.root.observable.trigger('listselect',data)
return true
}
_select(event)
{
if(self.selidx != -1 && self.selidx < self.items.length)
self.items[self.selidx].selected =false
event.item.item.selected = true
//console.log(self.items)
self.update()
//event.preventUpdate = true
}
_dbclick(event)
{
data = {
id:self.rid,
data:event.item.item,
idx: event.item.i}
if(self.onlistdbclick)
self.onlistdbclick(data)
self.root.observable.trigger('listdbclick', data)
}
</script>
</afx-float-list>

View File

@ -1,218 +0,0 @@
<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" style ="padding-bottom:10px">
<afx-grid-row each={ child, i in rows } class = {selected: child.selected} rootid = {parent.rid} observable = {parent.root.observable} index = {i} cols = {child} ondblclick = {parent._dbclick} onclick = {parent._select} oncontextmenu = {parent._select} head = {parent.refs.gridhead} ></afx-grid-row>
</div>
</div>
<script>
this.header = opts.header
this.rows = opts.rows || []
var self = this
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
self.selidx = -1
self.nrow = 0
self.ongridselect = opts.ongridselect
self.ongriddbclick = opts.ongriddbclick
self.root.observable = opts.observable
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()
}
this.calibrate_size = function()
{
if(self.header && self.refs.gridhead)
{
$(self.refs.scroller).css("height",
$(self.root).height() - $(self.refs.gridhead.root).children().first().height()
+ "px")
}
else
$(self.refs.scroller).css("height",
$(self.root).height() + "px")
}
self.root.get = function(k)
{
if(k == "selected")
return (self.selidx == -1?null:self.rows[self.selidx])
return self[k]
}
this.on("mount", function(){
if(self.refs.gridhead)
self.refs.gridhead.observable = self.root.observable
$(self.refs.container)
.css("display","table")
//.css("flex-direction","column")
.css("width","100%")
self.calibrate_size()
self.root.observable.on("resize",function(){
if(self.root)
self.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
self.calibrate_size()
})
_select(event)
{
var data = {
id:self.rid,
data:event.item}
if(self.ongridselect)
self.ongridselect(data)
if(self.selidx != -1)
self.rows[self.selidx].selected =false
self.selidx = event.item.i
self.rows[self.selidx].selected = true
self.root.observable.trigger('gridselect',data)
event.preventUpdate = true
self.update()
//event.preventDefault()
}
_dbclick(event)
{
data = {
id:self.rid,
data:event.item}
if(self.ongriddbclick)
self.ongriddbclick(data)
self.root.observable.trigger('griddbclick', data)
}
</script>
</afx-grid-view>
<afx-grid-row>
<div style = {!header? "display: table-cell;" :""} onclick = {parent._cell_select} each = { child,i in cols } class = {string:typeof child.value == "string", number: typeof child.value == "number", cellselected: parent._auto_cell_select(child,i)} >
<afx-label color={child.color} icon = {child.icon} iconclass = {child.iconclass} text = {child.value} ></afx-label>
</div>
<script>
this.cols = opts.cols || []
var self = this
this.rid = opts.rootid
this.index = opts.index
this.header = eval(opts.header)||false
this.head = opts.head
this.selidx = -1
self.observable = opts.observable
this.colssize = []
var update_header_size = function()
{
if(!self.cols || self.cols.length == 0) return
var totalw = $(self.root).parent().width()
if(totalw == 0) return
var ocw = 0
var nauto = 0
self.colssize = []
$.each(self.cols, function(i,e){
if(e.width)
{
self.colssize.push(e.width)
ocw += e.width
}
else
{
self.colssize.push(-1)
nauto++
}
})
if(nauto > 0)
{
var cellw = parseInt((totalw - ocw)/ nauto)
$.each(self.colssize,function(i,e){if(e == -1) self.colssize[i] = cellw})
}
calibrate_size()
}
var calibrate_size = function()
{
var i = 0
$(self.root)
.children()
.each(function(){
$(this).css("width", self.colssize[i]+"px")
i++
})
}
this.on("updated", function(){
if(self.header)
update_header_size()
else if(self.head && self.index == 0)
{
self.colssize = self.head.colssize
calibrate_size()
}
})
this.on("mount", function(){
if (self.header)
{
$(self.root)
.css("display", "flex")
.css("flex-direction", "row")
update_header_size()
}
else
{
$(self.root)
.css("display","table-row")
//.css("flex-direction","row")
.css("width","100%")
if(self.head && self.index == 0)
{
self.colssize = self.head.colssize
calibrate_size()
}
}
self.observable.on("gridcellselect", function(data){
if(data.id != self.rid || self.selidx == -1) return;
if(data.row != self.index)
{
self.cols[self.selidx].selected = false
self.selidx = -1
}
})
self.observable.on("resize",function(){
self.update()
})
})
_cell_select(event)
{
if(self.header) return;
if(self.selidx != -1)
{
self.cols[self.selidx].selected = false
self.selidx = -1
}
self.cols[event.item.i].selected = true
}
_auto_cell_select(child,i)
{
if(!child.selected || self.header) return false;
if(self.selidx == i) return true;
var data = {
id:self.rid,
data:child,
col:i,
row:self.index}
self.selidx = i
self.observable.trigger("gridcellselect",data)
return true;
}
</script>
</afx-grid-row>

View File

@ -1,79 +0,0 @@
<afx-hbox style = "display:block;">
<div ref = "container" class="afx-hbox-container">
<yield/>
</div>
<script>
var self = this
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.on('mount', function(){
self.root.observable = (self.parent && self.parent.root && self.parent.root.observable) || opts.observable || riot.observable()
$(self.refs.container)
.css("display","flex")
.css("flex-direction","row")
.css("width","100%")
calibrate_size()
if(self.root.observable)
{
self.root.observable.on("resize", function(w,h){
calibrate_size()
})
self.root.observable.on("calibrate", function(){
calibrate_size()
})
}
})
self.root.update = function()
{
self.update()
}
var calibrate_size = function()
{
var auto_width = []
var csize, ocwidth = 0, avaiheight;
avaiheight = $(self.root).height()
avaiWidth = $(self.root).width()
/*if(avaiheight == 0)
{
avaiheight = $(self.parent.root).height()
$(self.root).css("height", avaiheight+"px")
}
if(avaiWidth == 0)
{
avaiWidth = $(self.parent.root).width()
$(self.root).css("height", avaiWidth+"px")
}*/
$(self.refs.container).css("height",avaiheight + "px")
$(self.refs.container)
.children()
.each(function(e)
{
this.observable = self.root.observable
//.css("height",avaiheight + "px")
var dw = $(this).attr("data-width")
if(dw)
{
if(dw == "grow") return
if(dw[dw.length-1] === "%")
dw = Number(dw.slice(0,-1))*avaiWidth/100;
$(this).css("width",dw + "px")
ocwidth += Number(dw)
}
else
{
$(this).css("flex-grow","1")
auto_width.push(this)
}
})
csize = (avaiWidth - ocwidth)/ (auto_width.length)
if(csize > 0)
$.each(auto_width, function(i,v)
{
$(v).css("width", csize + "px")
})
self.root.observable.trigger("hboxchange",
{id:self.rid, w:csize, h:avaiheight})
}
</script>
</afx-hbox>

View File

@ -1,20 +0,0 @@
<afx-html ref = "container">
<script>
this.content = opts.content
this.root.innerHTML = this.content
this.updateContent = undefined
var self = this
this.root.set = function(k, v)
{
self[k] = v
if(k == "content")
self.root.innerHTML = v
else if(k == "updateContent")
self.update()
}
this.on("update", function(){
if(self.updateContent)
self.root.innerHTML = self.updateContent()
})
</script>
</afx-html>

View File

@ -1,33 +0,0 @@
<afx-label>
<span style = {color?"color:" + color:""} >
<i if={iconclass} class = {iconclass} ></i>
<i if={icon} class="icon-style" style = { "background: url("+window.OS.API.handle.get+"/"+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i>
{ text?text.__():"" }
</span>
<script>
this.iconclass = opts.iconclass
this.icon = opts.icon
this.text = opts.text
this.color = opts.color
var self = this
this.on("update",function(){
self.iconclass = opts.iconclass
self.icon = opts.icon
self.text = opts.text
self.color = opts.color
})
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
opts[i] = v[i]
else
opts[k] = v
self.update()
}
self.root.get = function(k)
{
return self[k]
}
</script>
</afx-label>

View File

@ -1,227 +0,0 @@
<afx-list-view class = {dropdown: opts.dropdown == "true"} style = "display:flex; flex-direction:column">
<div class = "list-container" ref = "container" style="flex:1;">
<div if = {opts.dropdown == "true"} ref = "current" onclick = {show_list}>
<afx-label ref = "drlabel"></afx-label>
</div>
<ul ref = "mlist" >
<li each={item,i in items } class={selected: parent._autoselect(item,i)} ondblclick = {parent._dbclick} onclick = {parent._select} oncontextmenu = {parent._select}>
<afx-label class = {item.class} color = {item.color} iconclass = {item.iconclass} icon = {item.icon} text = {item.text}></afx-label>
<i if = {item.closable} class = "closable" click = {parent._remove}></i>
<ul if = {item.complex} class = "complex-content">
<li each = {ctn,j in item.detail} class = {ctn.class}>{ctn.text.toString()}</li>
</ul>
</li>
</ul>
</div>
<div if = {opts.dropdown != "true" && buttons} class = "button_container">
<afx-button each = {btn,i in buttons} text = {btn.text} icon = {btn.icon} iconclass = {btn.iconclass} onbtclick = {btn.onbtclick}></afx-button>
</div>
<script>
this.items = opts.items || []
var self = this
self.selidx = -1
self.onlistselect = opts.onlistselect
self.onlistdbclick = opts.onlistdbclick
self.onitemclose = opts.onitemclose
self.buttons = opts.buttons
var onclose = false
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
self.root.set = function(k,v)
{
if(k == "selected")
{
if(self.selidx != -1)
self.items[self.selidx].selected =false
if(v == -1)
self.selidx = -1
else
if(self.items[v]) self.items[v].selected = true
}
else if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
if(k == "selected")
if(self.selidx != -1)
return self.items[self.selidx]
else
return undefined
else if(k == "count")
return self.items.length
return self[k]
}
self.root.selectNext = function()
{
var idx = self.selidx + 1
if(idx >= self.items.length) return;
if(self.selidx != -1)
self.items[self.selidx].selected =false
self.items[idx].selected =true
self.update()
}
self.root.selectPrev = function()
{
var idx = self.selidx - 1
if(idx < 0) return;
if(self.selidx != -1)
self.items[self.selidx].selected =false
self.items[idx].selected =true
self.update()
}
self.root.push = function(e,u)
{
self.items.push(e)
if(u) self.update()
}
self.root.unshift = function(e,u)
{
self.items.unshift(e)
if(u) self.update()
}
self.root.replaceItem = function(o, n, u)
{
var ix = self.items.indexOf(o)
if(ix >= 0)
{
self.items[ix] = n
if(u) self.update()
}
}
self.root.remove = function(e,u)
{
var i = self.items.indexOf(e)
if(i >= 0)
{
if(self.selidx != -1)
{
self.items[self.selidx].selected =false
self.selidx = -1
}
self.items.splice(i, 1)
if(u)
self.update()
onclose = true
}
}
if(opts.observable)
this.root.observable = opts.observable
else
{
this.root.observable = riot.observable()
}
this.on("mount", function(){
self.root.observable = opts.observable || (self.parent && self.parent.root && self.parent.root.observable) || riot.observable()
if(opts.dropdown == "true")
{
var cl = function()
{
$(self.refs.container).css("width", $(self.root).width() + "px" )
$(self.refs.current).css("width", $(self.root).width() + "px" )
$(self.refs.mlist).css("width", $(self.root).width() + "px" )
}
cl()
self.root.observable.on("calibrate", function(){
cl()
})
self.root.observable.on("resize", function(){
cl()
})
$(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")
self.root.observable.on("vboxchange", function(e){
if(e.id == self.parent.rid)
$(self.refs.container).css("width", $(self.root).parent().innerWidth() + "px" )
})
}
})
show_list(event)
{
var desktoph = $("#desktop").height()
var off = $(self.root).offset().top + $(self.refs.mlist).height()
if( off > desktoph )
$(self.refs.mlist)
.css("top","-" + $(self.refs.mlist).outerHeight() + "px")
else
$(self.refs.mlist).css("top","100%")
$(self.refs.mlist).show()
//event.preventDefault()
event.preventUpdate = true
}
_remove(event)
{
r = true
if(self.onitemclose)
r = self.onitemclose(event)
if(r)
self.root.remove(event.item.item, true)
}
_autoselect(it,i)
{
if(!it.selected || it.selected == false) return false
if(self.selidx == i) return true
var data = {
id:self.rid,
data:it,
idx:i}
//if(self.selidx != -1)
// self.items[self.selidx].selected =false
self.selidx = i
if(opts.dropdown == "true")
{
$(self.refs.mlist).hide()
self.refs.drlabel.root.set("*",it)
}
if(self.onlistselect)
self.onlistselect(data)
this.root.observable.trigger('listselect',data)
//console.log("list select")
return true
}
_select(event)
{
if(onclose)
{
onclose = false
event.preventUpdate = true
return
}
if(self.selidx != -1 && self.selidx < self.items.length)
self.items[self.selidx].selected =false
event.item.item.selected = true
}
_dbclick(event)
{
data = {
id:self.rid,
data:event.item.item,
idx: event.item.i}
if(self.onlistdbclick)
self.onlistdbclick(data)
self.root.observable.trigger('listdbclick', data)
}
</script>
</afx-list-view>

View File

@ -1,179 +0,0 @@
<afx-menu >
<ul class={context: opts.context == "true"}>
<li class="afx-corner-fix"></li>
<li ref = "container" each={ data,i in items } class = {afx_submenu:data.child != null && data.child.length > 0, fix_padding:data.icon} no-reorder>
<a href="#" onclick = {parent.onselect}>
<afx-switch if = {data.switch || data.radio} class = {checked:parent.checkItem(data)} enable = false swon = {data.checked} ></afx-switch>
<afx-label color = {data.color} iconclass = {data.iconclass} icon = {data.icon} text = {data.text} ></afx-label>
<span if={data.shortcut} class = "shortcut">{data.shortcut}</span>
</a>
<afx-menu ref = "submenus" index = {i} if={data.child != null && data.child.length > 0} child={data.child} onmenuselect = {data.onmenuselect} observable = {parent.root.observable} rootid = {parent.rid}></afx-menu>
</li>
<li class="afx-corner-fix"></li>
</ul>
<script>
this.items = opts.child || []
if(opts.index != undefined)
this.index = opts.index
else
this.index = -1
var isRoot
var lastChecked = undefined
if(opts.rootid)
{
this.rid = opts.rootid
isRoot = false
}
else
{
this.rid = $(this.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
isRoot = true
}
var self = this
this.onmenuselect = opts.onmenuselect
checkItem(d)
{
if(d.checked == true && d.radio)
{
if(lastChecked)
lastChecked.checked = false
lastChecked = d
lastChecked.checked = true
}
return 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.push = function(e,u)
{
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
}
else
{
this.root.observable = riot.observable()
this.root.observable.on('menuselect',function(data){
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.button == 2 || event.originalEvent.button == 2)
{
return
}
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, root:isRoot, e:event, item:event.item}
if(event.item.data.switch)
{
event.item.data.checked = !event.item.data.checked
} else if(event.item.data.radio)
{
if(lastChecked)
{
lastChecked.checked = false
}
event.item.data.checked = true
lastChecked = event.item.data
}
this.root.observable.trigger('menuselect',data)
if( this.onmenuselect && !isRoot) this.onmenuselect(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>
</afx-menu>

View File

@ -1,100 +0,0 @@
<afx-nspinner>
<input ref = "holder" type="text" value = {value}></input>
<ul ref = "spinner">
<li class = "incr" ref= "incr" onclick="{ _incr }"> <i></i> </li>
<li class = "decr" ref = "decr" onclick="{ _decr }"> <i></i> </li>
</ul>
<script>
this.value = eval(opts.value) || 0
this.step = Number(opts.step) || 1
this.onchange = opts.onchange
var self = this
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
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._incr = function(e)
{
self.value = self.value + self.step;
self.update();
if(self.onchange) self.onchange(self.value);
}
self.on("mount", function(){
self.root.observable = opts.observable || (self.parent && self.parent.root && self.parent.root.observable) || riot.observable()
$(self.refs.spinner).css("width", "20px" );
var cl = function()
{
$(self.refs.holder).css("width", $(self.root).width() - 20 + "px" )
$(self.refs.holder).css("height", $(self.root).height() + "px" )
$(self.refs.spinner)
.css("width","20px")
.css("height", $(self.root).height() + "px" )
$(self.refs.incr)
.css("height", $(self.root).height()/2 - 2 + "px")
.css("position", "relative")
$(self.refs.decr).css("height", $(self.root).height()/2 -2 + "px")
.css("position", "relative")
$(self.refs.spinner).find("li")
.css("display","block")
.css("text-align", "center")
.css("vertical-align", "middle")
$(self.refs.spinner).find("i")
.css("font-size", "16px")
.css("position", "absolute")
var fn = function(ie, pos)
{
var el = $(ie).find("i")
el
.css(pos,($(ie).height()-el.height()) /2 + "px" )
.css("left", ($(ie).width()-el.width())/2 + "px" )
}
fn(self.refs.decr, "bottom")
fn(self.refs.incr, "top")
}
cl()
self.root.observable.on("calibrate", function(){
cl()
})
self.root.observable.on("resize", function(){
cl()
});
$(self.refs.holder).on('keyup', function (e) {
if (e.keyCode == 13) {
var val = self.refs.holder.value;
if(!isNaN(val))
{
val = eval(val)
if(val < 0)
val = self.value;
self.value = val;
}
self.refs.holder.value = self.value;
if(self.onchange) self.onchange(self.value);
}
});
})
self._decr = function(e)
{
if(self.value == 0) return;
self.value = self.value - self.step;
self.update();
if(self.onchange) self.onchange(self.value);
}
</script>
</afx-nspinner>

View File

@ -1,45 +0,0 @@
<afx-overlay>
<yield/>
<script>
this.width = opts.width || 200
this.height = opts.height || 400
var self = this;
self.commander = null
this.root.observable = opts.observable || riot.observable()
var id = $(self.root).attr("data-id")
var calibre_size = function()
{
$(self.root)
.css("width", self.width + "px")
.css("height", self.height + "px")
self.root.observable.trigger("resize", {id:id,w:self.width,h:self.height})
}
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
if( k == "width" || k == "height")
calibre_size()
self.update()
}
self.root.get = function(k)
{
return self[k]
}
self.on("mount", function(){
$(self.root)
.css("position", "absolute")
//.css("z-index",1000000)
$(self.root).children().each(function(e){
this.observalbe = self.root.observalbe
})
calibre_size()
self.root.observable.trigger("rendered", self.root)
})
</script>
</afx-overlay>

View File

@ -1,85 +0,0 @@
<afx-resizer>
<script>
var self = this
self.dir = "hz"
self.resizable = undefined
self.parent = undefined
self.minsize = 0
self.on("mount", function(){
//self.parent = $(self.root).parent().parent()
var tagname = $(self.parent.root).prop("tagName")
self.resizable = $(self.root).prev().length == 1 ? $(self.root).prev()[0]: undefined
//self.nextel = $(self.root).next().length == 1 ? $(self.root).next()[0]: undefined
if(tagname == "AFX-HBOX")
{
self.dir = "hz"
$(self.root).css("cursor", "col-resize")
if(self.resizable)
{
self.minsize = parseInt($(self.resizable).attr("min-width"))
}
}
else if(tagname == "AFX-VBOX")
{
self.dir = "ve"
$(self.root).css("cursor", "row-resize")
if(self.resizable)
{
self.minsize = parseInt($(self.resizable).attr("min-height"))
}
}
else
{
//$(self.root).css("cursor", "normal")
self.dir = "none"
}
if(!self.minsize)
self.minsize = 10
enable_dragging()
})
var enable_dragging = function()
{
$(self.root)
.css("user-select","none")
$(self.root).on("mousedown", function(e){
e.preventDefault()
$(window).on("mousemove", function(evt){
if(!self.resizable) return
if(self.dir == "hz")
horizontalResize(evt)
else if (self.dir == "ve")
verticalResize(evt)
})
$(window).on("mouseup", function(evt){
//console.log("unbind mouse up")
$(window).unbind("mousemove", null)
})
})
}
var horizontalResize = function(e)
{
if(!self.resizable) return
var offset = $(self.resizable).offset()
w = Math.round(e.clientX - offset.left)
if(w < self.minsize) w = self.minsize
$(self.resizable).attr("data-width", w.toString())
self.parent.root.observable.trigger("calibrate", self.resizable)
}
var verticalResize = function(e)
{
//console.log("vboz")
if(!self.resizable) return
var offset = $(self.resizable).offset()
//console.log($(self.resizable).innerHeight())
//console.log(e.clientY, offset.top)
h = Math.round(e.clientY - offset.top)
if(h < self.minsize) h = minsize
$(self.resizable).attr("data-height", h.toString())
self.parent.root.observable.trigger("calibrate", self.resizable)
}
</script>
</afx-resizer>

View File

@ -1,107 +0,0 @@
<afx-slider>
<div class= "container" ref="container">
<div class = "progress" ref ="prg"></div>
<div if = {dragable} class = "dragpoint" ref = "point"></div>
</div>
<script>
this.value = Number(opts.value) || 0
this.max = Number(opts.max) || 100
if(opts.dragable != undefined)
this.dragable = eval(opts.dragable)
else
this.dragable = true
this.onchanging = opts.onchanging
this.onchange = opts.onchange
//this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
var self = this
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else
self[k] = v
/*if(k == "value")
{
if(self.onchange) self.onchange(self.value)
if(self.onchanging) self.onchanging(self.value)
}*/
self.update()
}
self.root.get = function(k)
{
return self[k]
}
var calibrate = function() {
if(self.value > self.max) self.value = self.max
$(self.refs.container).css("width", $(self.root).width() + "px")
var w = $(self.refs.container).width()*self.value/ self.max
$(self.refs.prg).css("width", w + "px").css("height", $(self.refs.container).height()+"px")
if(self.dragable)
{
var ow = w - $(self.refs.point).width()/2
var top = Math.floor(($(self.refs.prg).height() - $(self.refs.point).height())/2)
$(self.refs.point).css("left", ow + "px").css("top", top + "px")
}
}
self.on("update", function(){
calibrate()
})
var enable_dragging = function()
{
$(self.refs.point)
.css("user-select","none")
.css("cursor","default")
$(self.refs.point).on("mousedown", function(e){
e.preventDefault()
offset = $(self.refs.container).offset()
$(window).on("mousemove", function(e){
var left
left = e.clientX - offset.left
left = left < 0?0:left
var maxw = $(self.refs.container).width();
left = left > maxw?maxw : left
self.value = left*self.max/maxw
calibrate()
if(self.onchanging) self.onchanging(self.value)
})
$(window).on("mouseup", function(e){
if(self.onchange) self.onchange(self.value)
$(window).unbind("mousemove", null)
$(window).unbind("mouseup", null)
})
})
}
self.on("mount", function(){
self.root.observable = opts.observable || (self.parent && self.parent.root && self.parent.root.observable) || riot.observable()
if(self.dragable)
{
$(self.refs.point).css("position", "absolute")
$(self.refs.point).hide()
$(self.root).mouseover(function(){
$(self.refs.point).show()
}).mouseout(function(){
$(self.refs.point).hide()
})
enable_dragging()
}
$(self.refs.container).click( function(e){
var offset = $(self.refs.container).offset()
var left = e.clientX - offset.left
var maxw = $(self.refs.container).width()
self.value = left*self.max/maxw
calibrate()
if(self.onchange) self.onchange(self.value)
if(self.onchanging) self.onchanging(self.value)
})
self.root.observable.on("calibrate",function(){
calibrate()
})
self.root.observable.on("resize", function(){
calibrate()
})
calibrate()
})
</script>
</afx-slider>

View File

@ -1,56 +0,0 @@
<afx-switch>
<span class = {swon: swon} onclick = {toggle}></span>
<script>
if(opts.swon != undefined)
this.swon = opts.swon
else
this.swon = false
var self = this
//this.root.observable = opts.observable
if(opts.enable != undefined)
this.enable = opts.enable
else
this.enable = true
this.onchange = opts.onchange
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
opts[i] = v[i]
else
opts[k] = v
self.update()
}
self.root.get = function(k)
{
return self[k]
}
this.root.toggle = function()
{
opts.swon = !self.swon
self.update()
}
/*this.on("mount", function(){
})*/
this.on("update", function(e){
self.swon = typeof opts.swon == "function"?opts.swon():opts.swon
})
toggle(e)
{
if(!self.enable) return
opts.swon = !self.swon
self.swon = opts.swon
var data = {
id: self.rid,
data: opts.swon
}
if(opts.onchange)
opts.onchange(data)
if(self.root.observable)
self.root.observable.trigger("switch", data)
}
</script>
</afx-switch>

View File

@ -1,54 +0,0 @@
<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} 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 = { child: [] }
this.appmenu = { child: [] }
this.systray = {
child: [],
onmenuselect: function(d){
if(d.root)
d.e.item.data.awake(d.e)
}
}
var self = this
self.root.attachservice = function(s)
{
self.refs.aTray.root.unshift(s,true)
s.attach(self.refs.aTray)
}
self.root.detachservice = function(s)
{
self.refs.aTray.root.remove(s, true)
}
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() {
//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.announcer.trigger("syspanelloaded")
})
</script>
</afx-sys-panel>

View File

@ -1,71 +0,0 @@
<afx-tab-bar>
<afx-list-view ref = "list" />
<script>
var self = this
this.closable = opts.closable || false
self.ontabselect = opts.ontabselect
self.root.get = function (k) {
return self.refs.list.root.get(k)
}
self.root.update = function(){
self.update(true)
}
self.on("mount", function(){
self.root.observable = opts.observable || (self.parent && self.parent.root && self.parent.root.observable) || riot.observable()
self.refs.list.root.observable = self.root.observable
/*self.root.observable.on("listselect", function(){
console.log("list select")
})*/
self.refs.list.root.set ("onlistselect",function (e) {
//console.log("tab is seleced")
self.root.observable.trigger("tabselect", e)
if(self.ontabselect)
self.ontabselect(e)
})
})
self.root.set = function (k,v){
if( k == "*")
for(var i in v)
self.refs.list.root.set(i,v[i])
else if(k == "closable")
{
self.closable = v
}
else if(k == "ontabselect")
self.ontabselect = v
else
{
if(k == "items")
{
for(var i in v)
v[i].closable = self.closable
}
self.refs.list.root.set(k,v)
}
//self.update()
}
self.root.push = function(e,u)
{
e.closable = self.closable
self.refs.list.root.push(e,u)
}
self.root.replaceItem = function(o,n,u)
{
n.closable = self.closable
self.refs.list.root.replaceItem(o,n,u)
}
self.root.unshift = function(e,u)
{
self.refs.list.root.unshift(e,u)
}
self.root.remove = function(e,u)
{
self.refs.list.root.remove(e,u)
}
</script>
</afx-tab-bar>

View File

@ -1,91 +0,0 @@
<afx-tab-container>
<afx-hbox ref = "mybox" if = {bar == "left"}>
<afx-tab-bar data-ref="tabbar" ></afx-tab-bar>
<div data-ref="container"></div>
</afx-hbox>
<afx-vbox ref = "mybox" if = { bar == "top"}>
<afx-tab-bar data-ref="tabbar" ></afx-tab-bar>
<div data-ref="container"></div>
</afx-vbox>
<script>
this.bar = opts.bar || "top"
this.barwidth = opts.barwidth
this.barheight = opts.barheight
var schemes = []
var self = this
var calibrate = function()
{
$(self.refs.mybox.root).css("width", $(self.root).width()+"px")
$(self.refs.mybox.root).css("height", $(self.root).height()+"px")
self.root.observable.trigger("calibrate")
}
self.on("mount", function () {
self.tabbar = $("[data-ref='tabbar']", self.root)[0]
self.container = $("[data-ref='container']", self.root)[0]
if(self.barwidth)
$(self.tabbar).attr("data-width", self.barwidth)
if(self.barheight)
$(self.tabbar).attr("data-height", self.barheight)
self.root.observable = (self.parent && self.parent.root && self.parent.root.observable) || opts.observable || riot.observable()
self.tabbar.set("ontabselect", function(e){
$(self.container).children().each(function(el){
$(this).hide()
})
$(e.data.scheme).show()
e.data.handler.render()
calibrate()
})
self.root.observable.on("resize", function(){
calibrate()
})
})
self.on("update", function(){
$(self.container).children().each(function(e){
if(this.update) this.update()
})
})
var render = function(el)
{
var sch = $.parseHTML(el.scheme)
$(self.container).append(sch)
el.scheme = sch
riot.mount(sch, {observable: self.root.observable})
$(sch).hide()
el.handler = el.handler(sch[0])
//console.log(el.handler)
//el.handler.render()
self.root.observable.trigger("tabrendered")
//self.root.observable.trigger("calibrate")
}
var addTab = function(el)
{
if(!el.f)
el.f = (function(){})
self.tabbar.push(el)
if(el.url)
{
el.url.asFileHandle().read(function(d){
el.scheme = d
render(el)
})
}
else
{
render(el)
}
}
self.root.setTabs = function(arr)
{
if(arr.length <= 0)
{
self.tabbar.set("selected", 0)
return
}
self.root.observable.one("tabrendered", function(){
arr.splice(0,1)
self.root.setTabs(arr)
})
addTab(arr[0])
}
</script>
</afx-tab-container>

View File

@ -1,169 +0,0 @@
<afx-tree-view>
<div class={afx_tree_item_selected:treeroot.selectedItem && treeroot.selectedItem.treepath == data.treepath, afx_folder_item: isFolder(), afx_tree_item_odd: index%2 != 0 } onclick={select} ondblclick = {_dbclick} oncontextmenu = {select}>
<ul style = "padding:0;margin:0;white-space: nowrap;">
<li ref = "padding" ></li>
<li class = "itemname" style="display:inline-block;" >
<i if={ !isFolder() && data.iconclass} class = {data.iconclass} ></i>
<i if={!isFolder() && data.icon} class="icon-style" style = { "background: url("+data.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>
{ data.name }
</li>
</ul>
</div>
<ul if={ isFolder() } show={ isFolder() && open }>
<li each={ child, i in data.nodes }>
<afx-tree-view ontreeselect = {parent.ontreeselect} index = {i} fetch = {parent.fetch} ontreedbclick = {parent.ontreedbclick} data={child} indent={indent+1} observable = {parent.root.observable} path = {parent.data.treepath + ">" + i} treeroot= {parent.treeroot}></afx-tree-view>
</li>
</ul>
<script>
var self = this
self.open = true
self.data = { name:"", nodes:null, treepath: opts.path, i:-1}
if(opts.data)
{
self.data = opts.data
//self.name = opts.data.name
//self.nodes = opts.data.nodes
//self.icon = opts.data.icon
self.open = opts.data.open == undefined?true:opts.data.open
//self.iconclass = opts.data.iconclass
}
self.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
self.data.rid = self.rid
self.data.i = opts.index
self.ontreeselect = opts.ontreeselect
self.ontreedbclick = opts.ontreedbclick
self.fetch = opts.fetch
self.indent = opts.indent || 0
var istoggle = false
if(opts.treeroot)
{
this.treeroot = opts.treeroot
this.treeroot.counter++
}
else
{
this.treeroot = self
this.treeroot.counter = 0
}
self.data.treepath = opts.path || 0
//self.selected = false
self.selectedItem = null
self.index = this.treeroot.counter
var _dfind = function(l,d, k, v)
{
if( d[k] == v ) return l.push(d)
if(d.nodes && d.nodes.length > 0)
for(var i in d.nodes)
_dfind(l, d.nodes[i],k,v)
}
self.root.find = function(k, v)
{
var l = []
_dfind(l,self.data,k,v)
return l
}
self.root.set = function(k,v)
{
if(k == "*")
for(var i in v)
self[i] = v[i]
else if (k == "data")
for(var i in v)
self.data[i] = v[i]
else if (k == "selectedItem")
{
if(self.ontreeselect)
self.ontreeselect(self.data)
self.treeroot.selectedItem = v
self.root.observable.trigger('treeselect',self.data)
}
else
self[k] = v
self.update()
}
self.root.get = function(k)
{
//if(k == "data")
// return {name:self.name, nodes: self.nodes, icon:self.icon, iconclass: self.iconclass, selectedItem:self.selectedItem}
return self[k]
}
if(opts.observable)
this.root.observable = opts.observable
else
{
this.root.observable = riot.observable()
}
this.on("mount", function(){
$(self.refs.padding)
.css("display", "inline-block")
.css("height","1px")
.css("padding",0)
.css("margin", 0)
.css("background-color","transparent")
.css("width", self.indent*15 + "px" )
})
isFolder() {
return self.data.nodes //&& self.nodes.length
}
toggle(e) {
self.open = !self.open
e.preventDefault()
istoggle = true
if(self.open && self.data.nodes.length == 0 && self.fetch)
{
self.fetch(e.item, function(d){
self.data.nodes = d
self.update()
})
}
}
select(event)
{
if(istoggle)
{
istoggle = false
return
}
/*var data = {
id:self.rid,
data:event.item,
path:self.data.path
} */
if(self.ontreeselect)
self.ontreeselect(self.data)
self.treeroot.selectedItem = self.data
this.root.observable.trigger('treeselect',self.data)
event.preventUpdate = true
self.treeroot.update()
event.preventDefault()
}
_dbclick(event)
{
if(istoggle)
{
istoggle = false
return
}
/*data = {
id:self.rid,
data:event.item,
path: self.data.path}*/
if(self.ontreedbclick)
{
self.ontreedbclick(self.data)
}
self.root.observable.trigger('treedbclick', self.data)
}
</script>
</afx-tree-view>

View File

@ -1,81 +0,0 @@
<afx-vbox style = "display:block;">
<div ref = "container" class="afx-vbox-container">
<yield/>
</div>
<script>
var self = this
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.on('mount', function(){
self.root.observable = (self.parent && self.parent.root && self.parent.root.observable) || opts.observable || riot.observable()
$(self.refs.container)
.css("display","flex")
.css("flex-direction","column")
.css("width","100%")
//.css("background-color","red")
//.css("overflow", "hidden")
calibrate_size()
if(self.root.observable)
{
self.root.observable.on("resize", function(w,h){
calibrate_size()
})
self.root.observable.on("calibrate", function(){
calibrate_size()
})
}
})
self.root.update = function()
{
self.update()
}
var calibrate_size = function()
{
var auto_height = []
var csize, ocheight = 0, avaiheight;
avaiheight = $(self.root).height()
avaiwidth = $(self.root).width()
/*if(avaiheight == 0)
{
avaiheight = $(self.parent.root).height()
$(self.root).css("height", avaiheight+"px")
}
if(avaiwidth == 0)
{
avaiwidth = $(self.parent.root).width()
$(self.root).css("height", avaiwidth+"px")
}*/
$(self.refs.container).css("height",avaiheight + "px")
$(self.refs.container)
.children()
.each(function(e)
{
this.observable = self.root.observable
//.css("border","1px solid black")
var dw = $(this).attr("data-height")
if(dw)
{
if(dw == "grow") return
if(dw[dw.length-1] === "%")
dw = Number(dw.slice(0,-1))*avaiheight/100;
$(this).css("height",dw + "px")
ocheight += Number(dw)
}
else
{
$(this).css("flex-grow","1")
auto_height.push(this)
}
})
csize = (avaiheight - ocheight)/ (auto_height.length)
if(csize > 0)
$.each(auto_height, function(i,v)
{
$(v).css("height", csize + "px")
})
self.root.observable.trigger("vboxchange",
{id:self.rid, w:avaiwidth, h:csize})
}
</script>
</afx-vbox>

View File

@ -5,7 +5,7 @@
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
@ -80,7 +80,7 @@ class BaseFileHandle
return resolve "" unless @cache
if t is "object" or typeof @cache is "string"
if t is "object"
b64 = (JSON.stringify @cache).asBase64()
b64 = JSON.stringify(@cache, undefined, 4).asBase64()
else
b64 = @cache.asBase64()
b64 = "data:#{m};base64,#{b64}"

View File

@ -8,7 +8,6 @@ afx-app-window[data-id="am-window"] afx-grid-view afx-grid-row afx-grid-cell{
afx-app-window[data-id="am-window"] afx-grid-view .grid_row_header afx-grid-cell{
background-color: #dfdfdf;
border: 1px solid #a6a6a6;
padding: 5px;
}

View File

@ -1,11 +0,0 @@
coffee_files = main.coffee dialog.coffee
jsfiles = coffeescript.js
cssfiles = main.css
copyfiles = scheme.html welcome.html package.json
PKG_NAME=AntOSDK
include ../pkg.mk

File diff suppressed because one or more lines are too long

View File

@ -1,109 +0,0 @@
class BuildDialog extends this.OS.GUI.BasicDialog
constructor: () ->
super "BuildDialog", {
tags: [
{ tag: "afx-label", att: 'text="__(Coffees)" data-height="23" class="header"' },
{ tag: "afx-list-view" }
{ tag: "afx-label", att: 'text="__(Javascripts)" data-height="23" class="header"' },
{ tag: "afx-list-view" }
{ tag: "afx-label", att: 'text="__(Css)" data-height="23" class="header"' },
{ tag: "afx-list-view" }
{ tag: "afx-label", att: 'text="__(Copied files)" data-height="23" class="header"' },
{ tag: "afx-list-view" }
{ tag: "div", att: ' data-height="5"' }
],
width: 350,
height: 450,
resizable: true,
buttons: [
{
label: "__(Save)", onclick: (d) ->
data =
coffees: (v.text for v in (d.find "content1").get "items")
javascripts: (v.text for v in (d.find "content3").get "items")
css: (v.text for v in (d.find "content5").get "items")
copies: (v.text for v in (d.find "content7").get "items")
d.handler data if d.handler
d.quit()
},
{ label: "__(Cancel)", onclick: (d) -> d.quit() }
],
filldata: (d) ->
lv = d.find "content1"
lv.set "items", ({ text: v } for v in d.parent.prjfile.cache.coffees)
lv.set "buttons", [
{
text: "+",
onbtclick: (e) ->
d.selectFile ["text/.*coffeescript"], (f) ->
lv.push { text: f }, true if f
},
{
text: "-",
onbtclick: (e) ->
sel = lv.get "selected"
return unless sel
lv.remove sel, true
}
]
lv1 = d.find "content3"
lv1.set "items", ({ text: v } for v in d.parent.prjfile.cache.javascripts)
lv1.set "buttons", [
{
text: "+",
onbtclick: (e) ->
d.selectFile ["application/javascript"], (f) ->
lv1.push { text: f }, true if f
},
{
text: "-",
onbtclick: (e) ->
sel = lv1.get "selected"
return unless sel
lv1.remove sel, true
}
]
lv2 = d.find "content5"
lv2.set "items", ({ text: v } for v in d.parent.prjfile.cache.css)
lv2.set "buttons", [
{
text: "+",
onbtclick: (e) ->
d.selectFile ["text/css"], (f) ->
lv2.push { text: f }, true if f
},
{
text: "-",
onbtclick: (e) ->
sel = lv2.get "selected"
return unless sel
lv2.remove sel, true
}
]
lv3 = d.find "content7"
lv3.set "items", ({ text: v } for v in d.parent.prjfile.cache.copies)
lv3.set "buttons", [
{
text: "+",
onbtclick: (e) ->
d.selectFile [".*"], (f) ->
lv3.push { text: f }, true if f
},
{
text: "-",
onbtclick: (e) ->
sel = lv3.get "selected"
return unless sel
lv3.remove sel, true
}
]
}
selectFile: (mimes, f) ->
me = @
@openDialog "FileDiaLog", (d, n, p) ->
f p.replace me.parent.prjfile.cache.root + "/", ""
, "__(Select a file)", { mimes: mimes, type: "file", root: @parent.prjfile.cache.root }

View File

@ -1,758 +0,0 @@
# Copyright 2017-2018 Xuan Sang LE <xsang.le AT gmail DOT com>
# AnTOS Web desktop is is licensed under the GNU General Public
# License v3.0, see the LICENCE file for more information
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/.
class AntOSDK extends this.OS.GUI.BaseApplication
constructor: ( args ) ->
super "AntOSDK", args
@prjfile = if @args and @args.length > 0 then @args[0].asFileHandler() else null
loadScheme: () ->
path = "#{@meta().path}/" + if @prjfile then "scheme.html" else "welcome.html"
@render path
main: () ->
me = @
@scheme.set "apptitle", "AntOSDK"
@output = @find "output"
if not @prjfile
(@find "btnnewprj").set "onbtclick", () ->
me.newProject (path) ->
me.prjfile = "#{path}/project.apj".asFileHandler()
me.init()
(@find "btnopenprj").set "onbtclick", () ->
me.actionProject "#{me.name}-Open"
return
@initWorkspace()
initWorkspace: () ->
me = @
@dirty = true
@fileview = @find "fileview"
div = @find "datarea"
@currfile = "Untitled".asFileHandler()
ace.require "ace/ext/language_tools"
@prjfile.dirty = false
@.editor = ace.edit div
@.editor.setOptions {
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
fontSize: "13px"
}
@.editor.completers.push { getCompletions: ( editor, session, pos, prefix, callback ) -> }
@.editor.getSession().setUseWrapMode true
@fileview.contextmenuHandler = (e, m) ->
m.set "items", me.contextMenu()
m.set "onmenuselect", (evt) ->
me.contextAction evt
m.show e
@mlist = @find "modelist"
@modes = ace.require "ace/ext/modelist"
ldata = []
f = (m, i) ->
ldata.push {
text: m.name,
mode: m.mode,
selected: if m.mode is 'ace/mode/text' then true else false
}
m.idx = i
f(m, i) for m, i in @modes.modes
@mlist.set "items", ldata
@mlist.set "onlistselect", (e) ->
me.editor.session.setMode e.data.mode
themelist = @find "themelist"
themes = ace.require "ace/ext/themelist"
ldata = []
ldata.push {
text: m.caption,
mode: m.theme,
selected: if m.theme is "ace/theme/monokai" then true else false
} for k, m of themes.themesByName
themelist.set "onlistselect", (e) ->
me.editor.setTheme e.data.mode
themelist.set "items", ldata
statbar = @find "editorstat"
#status
stup = (e) ->
c = me.editor.session.selection.getCursor()
l = me.editor.session.getLength()
statbar.set "text", __("Row {0}, col {1}, lines: {2}", c.row, c.column, l)
stup(0)
@.editor.getSession().selection.on "changeCursor", (e) -> stup(e)
@editormux = false
@editor.on "input", () ->
if me.editormux
me.editormux = false
return false
if not me.currfile.dirty
me.currfile.dirty = true
me.currfile.text += "*"
me.tabarea.update()
@on "resize", () -> me.editor.resize()
@on "vboxchange", () -> me.editor.resize()
@on "focus", () -> me.editor.focus()
@fileview.set "fetch", (e, f) ->
return unless e.child
return if e.child.filename is "[..]"
e.child.path.asFileHandler().read (d) ->
return me.error __("Resource not found {0}", e.child.path) if d.error
f d.result
@fileview.set "onfileopen", (e) ->
return if e.type is "dir"
me.open e.path.asFileHandler()
@subscribe "VFS", (d) ->
p = (me.fileview.get "path").asFileHandler()
me.chdir p.path if d.data.file.hash() is p.hash() or d.data.file.parent().hash() is p.hash()
@tabarea = @find "tabarea"
@tabarea.set "ontabselect", (e) ->
me.selecteTab e.idx
@tabarea.set "onitemclose", (e) ->
it = e.item.item
return false unless it
return me.closeTab it unless it.dirty
me.openDialog "YesNoDialog", (d) ->
return me.closeTab it if d
me.editor.focus()
, __("Close tab"), { text: __("Close without saving ?") }
return false
(@find "log-clear").set "onbtclick", (e) ->
($ me.output).empty()
#@tabarea.set "closable", true
@bindKey "ALT-N", () -> me.actionFile "#{me.name}-New"
@bindKey "ALT-O", () -> me.actionFile "#{me.name}-Open"
@bindKey "CTRL-S", () -> me.actionFile "#{me.name}-Save"
@bindKey "ALT-W", () -> me.actionFile "#{me.name}-Saveas"
@bindKey "CTRL-R", () -> me.bnR()
@bindKey "ALT-C", () -> me.actionBuild "#{me.name}-Build"
@bindKey "ALT-P", () -> me.buildAndRelease()
@bindKey "ALT-Y", () ->
me.actionBuild "#{me.name}-Options"
@openProject @prjfile if @prjfile
@trigger "calibrate"
newProject: (f) ->
me = @
@openDialog "FileDiaLog", (d, n, p) ->
rpath = "#{d}/#{n}"
# create folder
# create javascripts dir
# create css dir
# create coffees dir
# create asset dir
dirs = [
rpath,
"#{rpath}/build",
"#{rpath}/build/release",
"#{rpath}/build/debug",
"#{rpath}/javascripts",
"#{rpath}/css",
"#{rpath}/coffees",
"#{rpath}/assets"
]
fn = (list, f1) ->
return f1() if list.length is 0
dir = (list.splice 0, 1)[0].asFileHandler()
name = dir.basename
dir = dir.parent().asFileHandler()
dir.mk name, (r) ->
return me.error __("Error when create directory: {0}", r.error) if r.error
me.log "INFO", __("Created directory: {0}", dir.path + "/" + name)
#console.log "created", dir.path + "/" + name
fn list, f1
fn dirs, () ->
# create package.json
# create README.md
# create project.apj
# create coffees/main.coffee
# create shemes/scheme.html
files = [
{
path: "#{rpath}/package.json",
content: """
{
"app":"#{n}",
"name":"#{n}",
"description":"",
"info":{
"author": "",
"email": ""
},
"version":"0.0.1-a",
"category":"Other",
"iconclass":"fa fa-adn",
"mimes":["none"]
}"""
},
{
path: "#{rpath}/README.md",
content: """
# #{n}
This is an example project, generated by AntOS Development Kit
## Howto
1. Open the project.apj file with AntOSDK (simply double Click on it)
2. Modify the UI in *assets/scheme.html*
3. Modify application code in *coffees/main.coffee*
4. Modify CSS style in *css/main.css*
5. Other files need to be copied: put in to assets
## Set up build target
Click **Menu> Build > Build Option** or simply hit **ALT-Y**
In the build options dialog, add or remove files that need to be
included into the build
Click **Save**
## Build application
* To build: **Menu > Build > Build** or **ALT-C**
* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
* To release: **Menu > Build > Build release** or **ALT-P**
"""
},
{
path: "#{rpath}/project.apj",
content: """
{
"name": "#{n}",
"root": "#{d}/#{n}",
"css": [],
"javascripts": [],
"coffees": ["coffees/main.coffee"],
"copies": ["assets/scheme.html", "package.json", "README.md"]
}
"""
},
{
path: "#{rpath}/coffees/main.coffee",
content: """
class #{n} extends this.OS.GUI.BaseApplication
constructor: ( args ) ->
super "#{n}", args
main: () ->
this.OS.register "#{n}", #{n}
"""
},
{
path: "#{rpath}/assets/scheme.html",
content: """
<afx-app-window apptitle="#{n}" width="600" height="500" data-id="#{n}">
<afx-hbox ></afx-hbox>
</afx-app-window>
"""
}
]
fn1 = (list, f2) ->
return f2(rpath) if list.length is 0
entry = (list.splice 0, 1)[0]
file = entry.path.asFileHandler()
file.cache = entry.content
file.write "text/plain", (res) ->
return me.error __("Cannot create file: {0}", res.error) if res.error
me.log "INFO", __("Created file: {0}", file.path)
fn1 list, f2
fn1 files, f
, "__(New Project at)", { file: { basename: __("ProjectName") } }
openProject: (file) ->
me = @
me.prjfile = file
if(me.tabarea)
file.read (data) ->
me.log "INFO", __("Opening {0}", me.prjfile.path)
fn = (d, dt) ->
me.tabarea.set "selected", -1
me.tabarea.set "items", []
me.currfile = "#{d.root}/README.md".asFileHandler()
me.currfile.dirty = dt
me.chdir d.root if d.root
me.prjfile.cache = d
me.log "INFO", __("Opening {0}", me.currfile.path)
me.open me.currfile
# verify if the path is ok
data.root.asFileHandler().onready () ->
fn(data, false)
, (e) ->
# try the current folder of the project file
pr = file.parent()
me.log "INFO", __("Project root folder not found, try {0}", pr)
pr.asFileHandler().onready () ->
data.root = pr
fn(data, true)
, (e) ->
me.error __("Cannot find the project root, please modify the project file")
,"json"
else
me.init()
open: (file) ->
#find table
i = @findTabByFile file
return @tabarea.set "selected", i if i isnt -1
return @newtab file if file.path.toString() is "Untitled"
me = @
file.read (d) ->
file.cache = d or ""
me.newtab file
contextMenu: () ->
[
{ text: __("New file"), dataid: "#{@name}-mkf" },
{ text: __("New folder"), dataid: "#{@name}-mkd" },
{ text: __("Delete"), dataid: "#{@name}-rm" }
{ text: __("Refresh"), dataid: "#{@name}-refresh" }
]
contextAction: (e) ->
me = @
file = @fileview.get "selectedFile"
dir = if file then file.path.asFileHandler() else (@fileview.get "path").asFileHandler()
dir = dir.parent().asFileHandler() if file and file.type isnt "dir"
switch e.item.data.dataid
when "#{@name}-mkd"
@openDialog "PromptDialog",
(d) ->
dir.mk d, (r) ->
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, "__(New folder)"
when "#{@name}-mkf"
@openDialog "PromptDialog",
(d) ->
fp = "#{dir.path}/#{d}".asFileHandler()
fp.write "", (r) ->
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, "__(New file)"
when "#{@name}-rm"
return unless file
@openDialog "YesNoDialog",
(d) ->
return unless d
file.path.asFileHandler()
.remove (r) ->
me.error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error
, "__(Delete)" ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", file.filename) }
when "#{@name}-refresh"
@.chdir ( @fileview.get "path" )
save: (file) ->
me = @
file.write "text/plain", (d) ->
return me.error __("Error saving file {0}", file.basename) if d.error
me.dirty = true
file.dirty = false
file.text = file.basename
me.tabarea.update()
findTabByFile: (file) ->
lst = @tabarea.get "items"
its = ( i for d, i in lst when d.hash() is file.hash() )
return -1 if its.length is 0
return its[0]
closeTab: (it) ->
@tabarea.remove it, false
cnt = @tabarea.get "count"
if cnt is 0
@open "Untitled".asFileHandler()
return false
@tabarea.set "selected", cnt - 1
return false
newtab: (file) ->
file.text = if file.basename then file.basename else file.path
file.cache = "" unless file.cache
file.um = new ace.UndoManager()
@currfile.selected = false
file.selected = true
#console.log cnt
@tabarea.push file, true
#@currfile = @file
#TODO: fix problem : @tabarea.set "selected", cnt
selecteTab: (i) ->
#return if i is @tabarea.get "selidx"
file = (@tabarea.get "items")[i]
return unless file
@fileview.set "preventUpdate", true
@scheme.set "apptitle", file.text.toString()
#return if file is @currfile
if @currfile isnt file
@currfile.cache = @editor.getValue()
@currfile.cursor = @editor.selection.getCursor()
@currfile = file
m = "ace/mode/text"
m = (@modes.getModeForPath file.path) if file.path.toString() isnt "Untitled"
@mlist.set "selected", m.idx
@editormux = true
@editor.setValue file.cache, -1
@editor.session.setMode m.mode
@editor.session.setUndoManager file.um
if file.cursor
@editor.renderer.scrollCursorIntoView { row: file.cursor.row, column: file.cursor.column }, 0.5
@editor.selection.moveTo file.cursor.row, file.cursor.column
@editor.focus()
chdir: (pth) ->
#console.log "called", @_api.throwe("FCK")
return unless pth
me = @
dir = pth.asFileHandler()
dir.read (d) ->
if(d.error)
return me.error __("Resource not found {0}", p)
if not dir.isRoot()
p = dir.parent().asFileHandler()
p.filename = "[..]"
p.type = "dir"
#p.size = 0
d.result.unshift p
($ me.navinput).val dir.path
me.fileview.set "path", pth
me.fileview.set "data", d.result
menu: () ->
me = @
menu = [
{
text: "__(Project)",
child: [
{ text: "__(New)", dataid: "#{@name}-New", },
{ text: "__(Open)", dataid: "#{@name}-Open" },
{ text: "__(Save)", dataid: "#{@name}-Save" }
],
onmenuselect: (e) -> me.actionProject e.item.data.dataid
},
{
text: "__(File)",
child: [
{ text: "__(New)", dataid: "#{@name}-New", shortcut: "A-N" },
{ text: "__(Open)", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "__(Save)", dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "__(Save as)", dataid: "#{@name}-Saveas", shortcut: "A-W" }
],
onmenuselect: (e) -> me.actionFile e.item.data.dataid
},
{
text: "__(Build)",
child: [
{ text: "__(Build and Run)", dataid: "#{@name}-Run", shortcut: "C-R" },
{ text: "__(Build release)", dataid: "#{@name}-Release", shortcut: "A-P" },
{ text: "__(Build)", dataid: "#{@name}-Build", shortcut: "A-C" },
{ text: "__(Build Options)", dataid: "#{@name}-Options", shortcut: "A-Y" }
],
onmenuselect: (e) -> me.actionBuild e.item.data.dataid
}
]
menu
actionFile: (e) ->
me = @
return unless @prjfile
saveas = () ->
me.openDialog "FileDiaLog", (d, n) ->
file = "#{d}/#{n}".asFileHandler()
file.cache = me.currfile.cache
file.dirty = me.currfile.dirty
file.um = me.currfile.um
file.cursor = me.currfile.cursor
file.selected = me.currfile.selected
file.text = me.currfile.text
me.tabarea.replaceItem me.currfile, file, false
me.currfile = file
me.save me.currfile
, "__(Save as)", { file: me.currfile }
switch e
when "#{@name}-Open"
@openDialog "FileDiaLog", ( d, f ) ->
me.open "#{d}/#{f}".asFileHandler()
, "__(Open file)"
when "#{@name}-Save"
@currfile.cache = @editor.getValue()
return @save @currfile if @currfile.basename
saveas()
when "#{@name}-Saveas"
@currfile.cache = @editor.getValue()
saveas()
when "#{@name}-New"
@open "Untitled".asFileHandler()
actionProject: (e) ->
me = @
switch e
when "#{@name}-Open"
fn = () ->
me.openDialog "FileDiaLog", (d, f, p) ->
me.prjfile = "#{d}/#{f}".asFileHandler()
me.log "clean"
me.openProject me.prjfile
, "__(Open Project)", { mimes: me.meta().mimes }
return fn() unless @isDirty()
@ask "__(Unsaved project)", "__(Ignore unsaved project ?)", () ->
fn()
when "#{@name}-New"
fn = () ->
me.log "clean"
me.newProject (p) ->
me.openProject "#{p}/project.apj".asFileHandler()
return fn() unless @isDirty()
@ask "__(Unsaved project)", "__(Ignore unsaved project ?)", () ->
fn()
when "#{@name}-Save"
return unless @prjfile
@prjfile.write "object", (r) ->
return me.error __("Cannot save project: {0}", r.error) if r.error
me.notify __("project saved")
me.prjfile.dirty = false
actionBuild: (e) ->
me = @
return unless @prjfile
switch e
when "#{@name}-Run" then me.bnR()
when "#{@name}-Build"
me.build().then(() ->).catch (ex) ->
me.log "ERROR", ex.toString()
when "#{@name}-Release"
me.buildAndRelease()
when "#{@name}-Options"
me.openDialog new BuildDialog(), (d) ->
me.prjfile.cache[k] = v for k, v of d
me.prjfile.dirty = true
me.dirty = true
, "__(Add files to build target)"
isDirty: () ->
return false unless @tabarea
dirties = ( v for v in @tabarea.get "items" when v.dirty )
return true if dirties.length > 0 or @prjfile.dirty
return false
cleanup: (evt) ->
return unless @currfile
return unless @isDirty()
me = @
evt.preventDefault()
dirties = ( v for v in @tabarea.get "items" when v.dirty )
m = __("Ignore: {0} unsaved files {1}?", dirties.length, if @prjfile.dirty then "__(and unsaved project)" else "")
@ask "__(Quit)", m, () ->
v.dirty = false for v in dirties
me.prjfile.dirty = false
me.quit()
log: (t, m) ->
return $(@output).empty() if t is "clean"
p = ($ "<p>").attr("class", t.toLowerCase())[0]
$(p).html "#{t}: #{m.__()}"
($ @output).append p
($ @output).scrollTop @output.scrollHeight
verify: () ->
me = @
return new Promise (r, e) ->
return e me._api.throwe "Project not found" unless me.prjfile.cache
# perform the verification on each coffee file
list = ("#{me.prjfile.cache.root}/#{v}" for v in me.prjfile.cache.coffees)
return r() if list.length is 0
fn = (l) ->
return r() if l.length is 0
f = (l.splice 0, 1)[0].asFileHandler()
me.log "INFO", __("Verifying {0}", f.path)
f.read (d) ->
try
CoffeeScript.nodes d
fn l
catch ex
e ex
return fn list
cat: (files, t) ->
me = @
return new Promise (r, e) ->
fn = (l) ->
return r(t) if l.length is 0
f = (l.splice 0, 1)[0].asFileHandler()
f.read (d) ->
t = t + "\n" + d
fn l
return fn files
copy: (files, to) ->
me = @
return new Promise (r, e) ->
fn = (l) ->
return r() if l.length is 0
f = (l.splice 0, 1)[0].asFileHandler()
tof = "#{to}/#{f.basename}".asFileHandler()
f.read (d) ->
tof.cache = new Blob [d], { type: f.info.mime }
tof.write f.info.mime, (res) ->
me.log "INFO", __("Copied {0} -> {1}", f.path, to)
return e res.error if res.error
fn(l)
, "binary"
return fn files
compile: () ->
me = @
list = ("#{me.prjfile.cache.root}/#{v}" for v in me.prjfile.cache.coffees)
t = ""
@verify().then () ->
me.cat(list, t)
.then (code) ->
return new Promise (r, e) ->
try
jsrc = CoffeeScript.compile code
me.log "SUCCESS", __("Compiled successful")
r jsrc
catch ex
e ex
build: () ->
me = @
@log "clean"
@compile().then (r) ->
# cat to the javascript
list = ("#{me.prjfile.cache.root}/#{v}" for v in me.prjfile.cache.javascripts)
me.cat(list, r).then (jsrc) ->
return new Promise (r, e) ->
r jsrc
.then (jsrc) ->
# write javascript src to file
return new Promise (r, e) ->
fp = "#{me.prjfile.cache.root}/build/debug/main.js".asFileHandler()
fp.cache = jsrc
fp.write "text/plain", (res) ->
return e res.error if res.error
me.log "SUCCESS", __("Generated {0}", fp.path)
r()
.then () ->
# cat the css file
csslist = ("#{me.prjfile.cache.root}/#{v}" for v in me.prjfile.cache.css)
csstxt = ""
me.cat(csslist, csstxt).then (txt) ->
return new Promise (r, e) ->
return r() if txt is ""
fp = "#{me.prjfile.cache.root}/build/debug/main.css".asFileHandler()
fp.cache = txt
fp.write "text/plain", (d) ->
return e d.error if d.error
me.log "SUCCESS", __("Generated {0}", fp.path)
r()
.then () ->
# copy the remain files
copylist = ("#{me.prjfile.cache.root}/#{v}" for v in me.prjfile.cache.copies)
me.copy copylist, "#{me.prjfile.cache.root}/build/debug"
.then () ->
me.log "SUCCESS", __("Build done")
me.dirty = false
return new Promise (r, e) -> r()
run: () ->
me = @
fp = "#{me.prjfile.cache.root}/build/debug/package.json".asFileHandler()
fp.read (v) ->
me.log "INFO", __("Metadata found...")
v.text = v.name
v.path = "#{me.prjfile.cache.root}/build/debug"
v.filename = me.prjfile.cache.name
v.type = "app"
v.mime = "antos/app"
v.icon = "#{v.path}/#{v.icon}" if v.icon
v.iconclass = "fa fa-adn" unless v.iconclass or v.icon
me.log "INFO", __("Installing...")
me.systemsetting.system.packages[me.prjfile.cache.name] = v
# todo: auto matic refresh menu
me._gui.refreshSystemMenu()
#me._gui.buildSystemMenu()
me.log "INFO", __("Running {0}...", me.prjfile.cache.name)
me._gui.forceLaunch me.prjfile.cache.name
, "json"
bnR: () ->
@log "clean"
return @run() unless @dirty
me = @
@build().then () ->
me.run()
.catch (ex) ->
me.log "ERROR", ex.toString()
release: () ->
me = @
@log "INFO", __("Preparing for release")
new Promise (r, e) ->
me._api.require "jszip.min", () ->
fp = "#{me.prjfile.cache.root}/build/debug".asFileHandler()
fp.read (d) ->
return e d.error if d.error
r d.result
.then (files) ->
return new Promise (r, e) ->
zip = new JSZip()
fn = (list) ->
return r zip if list.length is 0
f = (list.splice 0, 1)[0].path.asFileHandler()
return fn list if f.type is "dir"
f.read (d) ->
zip.file f.basename, d, { binary: true }
me.log "INFO", __("add {0} to zip", f.basename)
fn list
, "binary"
fn files
.then (zip) ->
zip.generateAsync({type:"base64"}).then (data) ->
f = "#{me.prjfile.cache.root}/build/release/#{me.prjfile.cache.name}.zip".asFileHandler()
f.cache = 'data:application/zip;base64,' + data
f.write "base64", (r) ->
return me.log "ERROR", __("Cannot save the zip file {0} : {1}", f.path, r.error) if r.error
me.log "SUCCESS", __("zip file generated in release folder")
buildAndRelease: () ->
@log "clean"
return @release() unless @dirty
me = @
@build().then () ->
me.release()
.catch (ex) ->
me.log "ERROR", ex.toString()
AntOSDK.singleton = false
AntOSDK.dependencies = [
"ace/ace",
"ace/ext-language_tools",
"ace/ext-modelist",
"ace/ext-themelist"
]
this.OS.register "AntOSDK", AntOSDK

View File

@ -1,121 +0,0 @@
afx-app-window[data-id="antOSDK"] afx-list-view {
margin: 2px;
margin-right: 5px;
}
afx-app-window[data-id="antOSDK"] afx-list-view div.list-container{
z-index: 10;
}
afx-app-window[data-id="antOSDK"] afx-resizer{
z-index: 11;
background-color: transparent;
border-right: 1px solid #a6a6a6;
}
afx-app-window[data-id="antOSDK"] afx-resizer[data-id="botrz"]
{
z-index: 9;
border-top: 1px solid #a6a6a6;
background-color: #2f3129;
border-right: 0;
}
afx-app-window[data-id="antOSDK"] div.welcome-cnt {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
afx-app-window[data-id="antOSDK"] div.welcome-cnt afx-label.wmsg {
font-weight: bold;
color: #a6A6A6;
font-size: 20px;
}
afx-app-window[data-id="antOSDK"] div.welcome-cnt p{
text-align: center;
display: block;
width: 100%;
}
afx-app-window[data-id="antOSDK"] afx-label[data-id="editorstat"]{
padding-right:5px;
text-align: right;
display: inline-block;
}
afx-app-window[data-id="antOSDK"] .afx-window-content {
background-color: #f6F6F6;
}
afx-app-window[data-id="antOSDK"] div[data-id= "output"] {
background-color: #2f3129;
padding: 10px;
padding-left: 40px;
color:white;
overflow: auto;
}
afx-app-window[data-id="antOSDK"] div[data-id= "output"] p{
margin:0;
padding:0;
font-family: "HermitLight";
text-align: left;
}
afx-app-window[data-id="antOSDK"] div[data-id= "output"] p.error{
color: red;
}
afx-app-window[data-id="antOSDK"] div[data-id= "output"] p.warning{
color: orange;
}
afx-app-window[data-id="antOSDK"] div[data-id= "output"] p.success {
color: green;
}
afx-app-window[data-id="antOSDK"] afx-label.outputheader {
background-color: #2f3129;
font-weight: bold;
padding-left: 10px;
color:white;
}
afx-app-window[data-id="antOSDK"] afx-hbox[data-id="bottom-vbox"] {
background-color:#2f3129;
}
afx-app-window[data-id="antOSDK"] afx-hbox[data-id="bottom-vbox"] afx-button button{
background-color:#2f3129;
color:white;
border:0;
border-radius: 0;
}
afx-app-window[data-id="antOSDK"] afx-hbox[data-id="bottom-vbox"] afx-list-view > div.list-container > div {
background-color: #3c3c3c;
color:white;
border:0;
border-radius: 0;
}
afx-app-window[data-id="antOSDK"] afx-hbox[data-id="bottom-vbox"] afx-list-view > div.list-container > div::before{
color: white;
}
afx-tab-bar[data-id="tabarea"] afx-list-view > div.list-container > ul > li {
background-color: #dfdfdf;
color:#272822;
border: 0;
border-top: 1px solid #a6a6a6;
border-right: 1px solid #a6a6a6;
border-radius: 0;
}
afx-tab-bar[data-id="tabarea"] afx-list-view{
padding:0;
margin: 0;
border-left: 0;
border-bottom: 1px solid #a6a6a6;
}
/*afx-tab-bar[data-id="tabarea"] afx-list-view i.closable:before{
color: white;
}*/
afx-tab-bar[data-id="tabarea"] afx-list-view > div.list-container > ul > li.selected {
background-color: #f6F6F6;
border-radius: 0;
}
afx-app-window[data-id="BuildDialog"] afx-label.header {
font-weight: bold;
margin: 0;
}
afx-app-window[data-id="BuildDialog"] afx-list-view {
border: 1px solid #a6A6A6;
}

View File

@ -1,15 +0,0 @@
{
"app":"AntOSDK",
"name":"AntOS development kit",
"description":"Development tool for building AntOS application",
"info":{
"author": "Xuan Sang LE",
"email": "xsang.le@gmail.com"
},
"version":"0.0.5-a",
"category":"System",
"iconclass":"fa fa-cubes",
"mimes":[
"text/antos-project"
]
}

View File

@ -1,19 +0,0 @@
<afx-app-window apptitle="" width="600" height="500" data-id="antOSDK">
<afx-hbox >
<afx-file-view data-width = "155" min-width="155" data-id = "fileview" view='tree' status = false></afx-file-view>
<afx-resizer data-width = "3" ></afx-resizer>
<afx-vbox>
<afx-tab-bar data-id="tabarea" data-height="23" closable = true></afx-tab-bar>
<div data-id="datarea" data-height="80%"></div>
<afx-resizer data-height="3" data-id="botrz"></afx-resizer>
<afx-hbox data-height="30" data-id="bottom-vbox">
<afx-label class="outputheader" iconclass= "fa fa-wpforms" text = "__(Output)"></afx-label>
<afx-list-view data-width="160" data-id = "themelist" dropdown = "true" width="135"></afx-list-view>
<afx-list-view data-width="125" data-id = "modelist" dropdown = "true" width="100"></afx-list-view>
<afx-button data-id = "log-clear" data-width="25" iconclass="fa fa-trash"></afx-button>
</afx-hbox>
<div data-id= "output" ></div>
<afx-label data-id="editorstat" data-height="20"></afx-label>
</afx-vbox>
</afx-hbox>
</afx-app-window>

View File

@ -1,15 +0,0 @@
<afx-app-window apptitle="" width="600" height="500" data-id="antOSDK">
<afx-vbox>
<afx-hbox >
<div class = "welcome-cnt">
<afx-label text="__(Welcome to AntOSDK)" class="wmsg"></afx-label>
<p>
<afx-button data-id="btnnewprj" iconclass= "fa fa-plus-circle" text = "__(New project)"></afx-button>
<afx-button data-id="btnopenprj" iconclass = "fa fa-folder-open" text = "__(Open project)"></afx-button>
</p>
</div>
</afx-hbox>
<div data-id= "output" ></div>
</afx-vbox>
</afx-app-window>

View File

@ -8,7 +8,7 @@
</afx-vbox>
<afx-resizer data-width = "3" ></afx-resizer>
<afx-vbox>
<afx-tab-bar closable="true" data-height="27" data-id = "tabbar"></afx-tab-bar>
<afx-tab-bar closable="true" data-height="26" data-id = "tabbar"></afx-tab-bar>
<div data-id="datarea"></div>
</afx-vbox>
</afx-hbox>

View File

@ -50,36 +50,37 @@ class CodePad.BaseExtension
mkar: (src, dest) ->
@notify __("Preparing for release")
new Promise (r, e) =>
@import("os://scripts/jszip.min.js").then () ->
src.asFileHandle()
.read().then (d) ->
return e d.error if d.error
r d.result
.catch (ex) -> e ex
.catch (ex) -> e ex
.then (files) =>
new Promise (resolve, reject) =>
new Promise (r, e) =>
zip = new JSZip()
fn = (list) =>
return r zip if list.length is 0
f = (list.splice 0, 1)[0].path.asFileHandle()
return fn list if f.type is "dir"
f.read("binary").then (d) =>
zip.file f.basename, d, { binary: true }
@notify __("add {0} to zip", f.basename)
fn list
@import("os://scripts/jszip.min.js").then () ->
src.asFileHandle()
.read().then (d) ->
return e d.error if d.error
r d.result
.catch (ex) -> e ex
fn files
.then (zip) =>
zip.generateAsync({ type: "base64" }).then (data) =>
dest.asFileHandle()
.setCache('data:application/zip;base64,' + data)
.write("base64").then (r) =>
return @error __("Cannot save the zip file: {0}", r.error) if r.error
@notify __("Package is generated in release folder")
.catch (e) => @error e.toString()
.catch (e) => @error e.toString()
.catch (ex) -> e ex
.then (files) =>
new Promise (r, e) =>
zip = new JSZip()
fn = (list) =>
return r zip if list.length is 0
f = (list.splice 0, 1)[0].path.asFileHandle()
return fn list if f.type is "dir"
f.read("binary").then (d) =>
zip.file f.basename, d, { binary: true }
@notify __("add {0} to zip", f.basename)
fn list
.catch (ex) -> e ex
fn files
.then (zip) =>
zip.generateAsync({ type: "base64" }).then (data) =>
dest.asFileHandle()
.setCache('data:application/zip;base64,' + data)
.write("base64").then (r) =>
return reject r.error if r.error
@notify __("Package is generated in release folder")
.catch (e) -> reject e
.catch (e) -> reject e
mkdirAll: (list) ->
new Promise (resolve, reject) =>

View File

@ -27,20 +27,20 @@ class App.extensions.AntOSDK extends App.BaseExtension
buildnrun: () ->
@metadata("project.json").then (meta) =>
@build(meta).then () =>
@run(meta).catch (e) => @error.toString()
@run(meta).catch (e) => @error __("Unable to run project"), e
.catch (e) =>
@error e.toString()
.catch (e) => @error e.toString()
@error __("Unable to build project"), e
.catch (e) => @error __("Unable to read meta-data"), e
release: () ->
@metadata("project.json").then (meta) =>
@build(meta).then () =>
@mkar("#{meta.root}/build/debug", "#{meta.root}/build/release/#{meta.name}.zip")
.then () ->
.catch (e) => @error.toString()
.catch (e) => @error __("Unable to create package archive"), e
.catch (e) =>
@error e.toString()
.catch (e) => @error e.toString()
@error __("Unable to build project"), e
.catch (e) => @error __("Unable to read meta-data"), e
# private functions
@ -70,8 +70,8 @@ class App.extensions.AntOSDK extends App.BaseExtension
@app.currdir = rpath.asFileHandle()
@app.initSideBar()
@app.openFile "#{rpath}/README.md".asFileHandle()
.catch (e) => @error e.stack
.catch (e) => @error e.stack
.catch (e) => @error __("Unable to create template files"), e
.catch (e) => @error __("Unable to create project directory"), e
verify: (list) ->
new Promise (resolve, reject) =>
@ -112,7 +112,7 @@ class App.extensions.AntOSDK extends App.BaseExtension
.setCache jsrc
.write("text/plain")
.then (d) ->
return e d if d.error
return e d.error if d.error
r()
.catch (ex) -> e ex
.then () =>
@ -125,7 +125,7 @@ class App.extensions.AntOSDK extends App.BaseExtension
.setCache txt
.write("text/plain")
.then (d) ->
return e d if d.error
return e d.error if d.error
r()
.catch (ex) -> e ex
.then () =>

View File

@ -18,10 +18,10 @@ class App.extensions.ExtensionMaker extends App.BaseExtension
buildnrun: () ->
@metadata("extension.json").then (meta) =>
@build(meta).then () =>
@run(meta).catch (e) => @error.toString()
@run(meta).catch (e) => @error __("Unable to run extension"), e
.catch (e) =>
@error e.toString()
.catch (e) => @error e.toString()
@error __("Unable to build extension"), e
.catch (e) => @error __("Unable to read meta-data"), e
release: () ->
@metadata("extension.json").then (meta) =>
@ -29,10 +29,10 @@ class App.extensions.ExtensionMaker extends App.BaseExtension
@mkar("#{meta.root}/build/debug",
"#{meta.root}/build/release/#{meta.meta.name}.zip")
.then () ->
.catch (e) => @error.toString()
.catch (e) => @error __("Unable to create archive"), e
.catch (e) =>
@error e.toString()
.catch (e) => @error e.toString()
@error __("Unable to build extension"), e
.catch (e) => @error __("Unable to read meta-data"), e
install: () ->
@app.openDialog("FileDialog", {
@ -43,7 +43,7 @@ class App.extensions.ExtensionMaker extends App.BaseExtension
.then () =>
@notify __("Extension installed")
@app.loadExtensionMetaData()
.catch (e) => @error e.stack
.catch (e) => @error __("Unable to install extension"), e
# private functions
mktpl: (path, name) ->
rpath = "#{path}/#{name}"
@ -64,8 +64,8 @@ class App.extensions.ExtensionMaker extends App.BaseExtension
@app.currdir = rpath.asFileHandle()
@app.initSideBar()
@app.openFile "#{rpath}/#{name}.coffee".asFileHandle()
.catch (e) => @error e.stack
.catch (e) => @error e.stack
.catch (e) => @error __("Unable to create extension template"), e
.catch (e) => @error __("Unable to create extension directories"), e
verify: (list) ->
@ -107,7 +107,7 @@ class App.extensions.ExtensionMaker extends App.BaseExtension
.setCache jsrc
.write("text/plain")
.then (d) ->
return e d if d.error
return e d.error if d.error
r()
.catch (ex) -> e ex
.then () ->
@ -127,22 +127,24 @@ class App.extensions.ExtensionMaker extends App.BaseExtension
.catch (e) -> reject e
run: (meta) ->
path = "#{meta.root}/build/debug/#{meta.meta.name}.js"
delete @app._api.shared[path] if @app._api.shared[path]
@app._api.requires path
.then () =>
if @app.extensions[meta.meta.name]
@app.extensions[meta.meta.name].child = []
@app.extensions[meta.meta.name].addAction v for v in meta.meta.actions
else
@app.extensions[meta.meta.name] = new App.CMDMenu meta.meta.text
@app.extensions[meta.meta.name].name = meta.meta.name
@app.extensions[meta.meta.name].addAction v for v in meta.meta.actions
@app.spotlight.addAction @app.extensions[meta.meta.name]
@app.extensions[meta.meta.name].onchildselect (e) =>
@app.loadAndRunExtensionAction e.data.item.get "data"
@app.spotlight.run @app
.catch (e) => @error e.toString()
new Promise (resolve, reject) =>
path = "#{meta.root}/build/debug/#{meta.meta.name}.js"
delete @app._api.shared[path] if @app._api.shared[path]
@app._api.requires path
.then () =>
if @app.extensions[meta.meta.name]
@app.extensions[meta.meta.name].child = []
@app.extensions[meta.meta.name].addAction v for v in meta.meta.actions
else
@app.extensions[meta.meta.name] = new App.CMDMenu meta.meta.text
@app.extensions[meta.meta.name].name = meta.meta.name
@app.extensions[meta.meta.name].addAction v for v in meta.meta.actions
@app.spotlight.addAction @app.extensions[meta.meta.name]
@app.extensions[meta.meta.name].onchildselect (e) =>
@app.loadAndRunExtensionAction e.data.item.get "data"
@app.spotlight.run @app
resolve()
.catch (e) -> reject e
installExtension: (files, zip) ->

View File

@ -2,23 +2,14 @@
This is an example project, generated by AntOS Development Kit
## Howto
Use the CodePad command palette to access to the SDK functionalities:
1. Open the project.apj file with AntOSDK (simply double Click on it)
2. Modify the UI in *assets/scheme.html*
3. Modify application code in *coffees/main.coffee*
4. Modify CSS style in *css/main.css*
5. Other files need to be copied: put in to assets
1. Create new project
2. Init the project from the current folder located in side bar
3. Build and run the project
4. Release the project in zip package
## Set up build target
Click **Menu> Build > Build Option** or simply hit **ALT-Y**
In the build options dialog, add or remove files that need to be
included into the build
Click **Save**
## Build application
* To build: **Menu > Build > Build** or **ALT-C**
* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
* To release: **Menu > Build > Build release** or **ALT-P**
Open the `project.json` file from the current project tree and add/remove
build target entries. Save the file

View File

@ -1,3 +1,3 @@
<afx-app-window apptitle="{0}" width="600" height="500" data-id="{0}">
<afx-app-window apptitle="{0}" width="500" height="400" data-id="{0}">
<afx-hbox ></afx-hbox>
</afx-app-window>

View File

@ -126,7 +126,7 @@ class CodePad extends this.OS.GUI.BaseApplication
file.cache = d or ""
@newTab file
.catch (e) =>
@error __("Unable to open: {0}", file.path)
@error __("Unable to open: {0}", file.path), e
findTabByFile: (file) ->
lst = @tabbar.get "items"
@ -242,7 +242,7 @@ class CodePad extends this.OS.GUI.BaseApplication
@extensions[ext.name].onchildselect (e) =>
@loadAndRunExtensionAction e.data.item.get "data"
.catch (e) =>
@error __("Cannot load extension meta data")
@error __("Cannot load extension meta data"), e
runExtensionAction: (name, action) ->
return @error __("Unable to find extension: {0}", name) unless CodePad.extensions[name]
@ -252,7 +252,7 @@ class CodePad extends this.OS.GUI.BaseApplication
.then () ->
ext[action]()
.catch (e) =>
@error e.stack
@error __("Unable to preload extension"), e
loadAndRunExtensionAction: (data) ->
name = data.parent.name
@ -264,7 +264,7 @@ class CodePad extends this.OS.GUI.BaseApplication
@_api.requires path
.then () => @runExtensionAction name, action
.catch (e) =>
@error __("unable to load extension: {}", name)
@error __("unable to load extension: {0}", name), e
else
@runExtensionAction name, action
@ -306,7 +306,7 @@ class CodePad extends this.OS.GUI.BaseApplication
return @error __("Fail to create {0}: {1}", d, r.error) if r.error
@fileview.update dir.path
.catch (e) =>
@error __("Fail to create: {0}", e.stack)
@error __("Fail to create: {0}", e.stack), e
when "newdir"
return unless dir
@ -320,7 +320,7 @@ class CodePad extends this.OS.GUI.BaseApplication
return @error __("Fail to create {0}: {1}", d, r.error) if r.error
@fileview.update dir.path
.catch (e) =>
@error __("Fail to create: {0}", e.stack)
@error __("Fail to create: {0}", dir.path), e
when "rename"
return unless file
@ -338,8 +338,7 @@ class CodePad extends this.OS.GUI.BaseApplication
return @error __("Fail to rename to {0}: {1}", d, r.error) if r.error
@fileview.update dir.path
.catch (e) =>
console.log e
@error __("Fail to rename: {0}", e.stack)
@error __("Fail to rename: {0}", file.path), e
when "delete"
return unless file
@ -357,7 +356,7 @@ class CodePad extends this.OS.GUI.BaseApplication
return @error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error
@fileview.update dir.path
.catch (e) =>
@error __("Fail to delete: {0}", e.stack)
@error __("Fail to delete: {0}", file.path), e
else
@ -370,7 +369,7 @@ class CodePad extends this.OS.GUI.BaseApplication
file.text = file.basename
@tabbar.update()
@scheme.set "apptitle", "#{@currfile.basename}"
.catch (e) => @error e.stack
.catch (e) => @error __("Unable to save file: {0}", file.path), e
saveAs: () ->
@ -383,8 +382,6 @@ class CodePad extends this.OS.GUI.BaseApplication
d = d.parent() if f.file.type is "file"
@currfile.setPath "#{d.path}/#{f.name}"
@save @currfile
.catch (e) =>
@error e.stack
menuAction: (dataid, r) ->
me = @

View File

@ -1,6 +1,6 @@
afx-app-window[data-id = "codepad"] afx-tab-bar> afx-list-view > div.list-container
{
border-top: 1px solid #272822;
/*border-top: 1px solid #272822;*/
overflow: hidden;
font-size: 12px;
}

View File

@ -15,6 +15,74 @@
# You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/.
Ant = this
class LogDialog extends this.OS.GUI.BasicDialog
constructor: () ->
super "LogDialog", LogDialog.scheme
init: () ->
@loglist = @find "loglist"
@logdetail = @find "logdetail"
@loglist.set "data", @data.logs if @data and @data.logs
$(@find("txturi")).val Ant.OS.setting.system.error_report
@loglist.set "onlistselect", (e) =>
data = e.data.item.get("data") if e and e.data
return unless data
stacktrace = "None"
stacktrace = data.error.stack if data.error
$(@logdetail).text LogDialog.template.format(
data.text,
data.type,
data.time,
data.name,
data.id,
stacktrace
)
@find("btnreport").set "onbtclick", (e) =>
uri = $(@find("txturi")).val()
return if uri is ""
el = @loglist.get "selectedItem"
return unless el
data = el.get("data")
return unless data
Ant.OS.API.post uri, data
.then (d) =>
@notify __("Error reported")
.catch (e) =>
@notify __("Unable to report error: {0}", e.toString())
LogDialog.template = """
{0}
Log type: {1}
Log time: {2}
Process: {3} ({4})
detail:
{5}
"""
LogDialog.scheme = """
<afx-app-window data-id="LogDialog" width='500' height='350' apptitle = "__(System error log)" >
<afx-hbox>
<afx-list-view data-id = "loglist" data-width="200"> </afx-list-view>
<afx-resizer data-width = "2" />
<afx-vbox>
<div data-height="10" />
<div data-id = "container">
<pre><code data-id="logdetail"></code></pre>
</div>
<div data-height="10" />
<afx-hbox style="text-align:right;" data-height = "27">
<div data-width="5" />
<input type = "text" data-id = "txturi" />
<afx-button data-width ="80" text = "__(Report)"
iconclass = "fa fa-bug" data-id = "btnreport" />
<div data-width="10" />
</afx-hbox>
<div data-height="10" />
</afx-vbox>
</afx-hbox>
</afx-app-window>
"""
class PushNotification extends this.OS.GUI.BaseService
constructor: (args) ->
@ -22,6 +90,7 @@ class PushNotification extends this.OS.GUI.BaseService
@iconclass = "fa fa-bars"
@cb = undefined
@pending = []
@logs = []
init: ->
@view = false
@_gui.htmlToScheme PushNotification.scheme, @, @host
@ -29,11 +98,9 @@ class PushNotification extends this.OS.GUI.BaseService
spin: (b) ->
if b and @iconclass is "fa fa-bars"
@iconclass = "fa fa-spinner fa-spin"
@color = "#f90e00"
@update()
else if not b and @iconclass is "fa fa-spinner fa-spin"
@iconclass = "fa fa-bars"
@color = "#414339"
@update()
main: ->
@ -42,12 +109,12 @@ class PushNotification extends this.OS.GUI.BaseService
@nzone = @find "notifyzone"
@fzone = @find "feedzone"
(@find "btclear").set "onbtclick", (e) => @mlist.set "data", []
#@subscribe "fail", (e) -> console.log e
(@find "bterrlog").set "onbtclick", (e) => @showLogReport()
@subscribe "notification", (o) => @pushout 'INFO', o
@subscribe "fail", (o) => @pushout 'FAIL', o
@subscribe "error", (o) => @pushout 'ERROR', o
@subscribe "info", (o) => @pushout 'INFO', o
#@subscribe "VFS", (o) => @pushout 'INFO', o
@subscribe "loading", (o) =>
@pending.push o.id
@ -62,7 +129,7 @@ class PushNotification extends this.OS.GUI.BaseService
@fzone.set "height", "100%"
($ @nzone).css "right", 0
.css "top", "-3px"
.css "top", "0"
.css "bottom", "0"
.hide()
($ @fzone)
@ -71,13 +138,32 @@ class PushNotification extends this.OS.GUI.BaseService
.css "bottom", "0"
.hide()
showLogReport: () ->
@openDialog(new LogDialog(), {
logs: @logs
})
addLog: (s, o) ->
logtime = new Date()
@logs.push {
type: s,
name: o.name,
text: "#{logtime}: #{o.data.m}",
id: o.id,
icon: o.data.icon,
iconclass: o.data.iconclass,
error: o.data.e,
time: logtime
}
pushout: (s, o) ->
d = {
text: "[#{s}] #{o.name} (#{o.id}): #{o.data.m}",
icon: o.data.icon,
iconclass: o.data.iconclass,
closable: true }
console.log o.data.e
closable: true
}
@addLog s, o unless s is "INFO"
@mlist.unshift d
@notifeed d
@ -109,7 +195,10 @@ class PushNotification extends this.OS.GUI.BaseService
PushNotification.scheme = """
<div>
<afx-overlay data-id = "notifyzone" width = "250px">
<afx-button text = "__(Clear all)" data-id = "btclear" data-height="30"></afx-button>
<afx-hbox data-height="30">
<afx-button text = "__(Clear all)" data-id = "btclear" ></afx-button>
<afx-button iconclass = "fa fa-bug" data-id = "bterrlog" data-width = "25"></afx-button>
</afx-hbox>
<afx-list-view data-id="notifylist"></afx-list-view>
</afx-overlay>
<afx-overlay data-id = "feedzone" width = "250">

View File

@ -1,5 +1,5 @@
afx-overlay[data-id = "notifyzone"]{
background-color: rgba(215,215,215,0.7);
/*opacity: 0.85;*/
overflow-y: auto;
overflow-x: hidden;
@ -7,23 +7,22 @@ afx-overlay[data-id = "notifyzone"]{
margin: 0;
}
afx-overlay[data-id = "notifyzone"] afx-button button{
width: 250px;
background-color: rgba(215,215,215,0.9);
}
afx-overlay[data-id = "notifyzone"] afx-button button:active{
color:#414339;
width: 100%;
border-radius: 0;
}
afx-list-view[data-id = "notifylist"]
{
padding:0;
}
afx-list-view[data-id = "notifylist"] li{
border:1px solid #a6a6a6;
border-radius: 6px;
margin-bottom: 2px;
afx-list-view[data-id = "notifylist"] > div.list-container > ul li{
border:1px solid #464646;
border-radius: 3px;
margin-bottom: 5px;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
padding-top: 5px;
padding-bottom: 5px;
}
afx-overlay[data-id = "feedzone"]{
@ -40,12 +39,23 @@ afx-list-view[data-id = "notifeed"]
margin:0;
}
afx-list-view[data-id = "notifeed"] li{
box-shadow: 1px 1px 1px #9f9F9F;
border:1px solid #a6a6a6;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border:1px solid #262626;
border-radius: 6px;
margin-bottom: 2px;
z-index: 99999;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
}
afx-app-window[data-id ='LogDialog'] div[data-id ='container']{
overflow: auto;
}
afx-app-window[data-id ='LogDialog'] pre {
padding: 10px;
}
afx-app-window[data-id ='LogDialog'] input{
height: 100%;
}

View File

@ -41,7 +41,7 @@ class Files extends this.OS.GUI.BaseApplication
file.mime = "dir" if file.type is "dir"
for v in @_gui.appsByMime file.mime
v.args = [ file.path ]
v.args = [ file ]
apps.push v
m.set "items", [
{ text: "__(Open with)", dataid: "#{@name}-open", child: apps },
@ -216,9 +216,8 @@ class Files extends this.OS.GUI.BaseApplication
file.path.asFileHandle().move "#{@currdir.path}/#{d}"
.then (r) =>
@error __("Fail to rename to {0}: {1}", d, r.error) if r.error
.catch (e) =>
console.log e
@error __("Fail to rename: {0}", e.stack)
.catch (e) =>
@error __("Fail to rename: {0}", file.path), e
when "#{@name}-rm"
return unless file
@ -232,8 +231,8 @@ class Files extends this.OS.GUI.BaseApplication
file.path.asFileHandle().remove()
.then (r) =>
@error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error
.catch (e) =>
@error __("Fail to delete: {0}", e.stack)
.catch (e) =>
@error __("Fail to delete: {0}", file.path), e
when "#{@name}-cut"
return unless file
@ -257,7 +256,7 @@ class Files extends this.OS.GUI.BaseApplication
@clipboard = undefined
@error __("Fail to paste: {0}", r.error) if r.error
.catch (e) =>
@error __("Fail to paste: {0}", e.stack)
@error __("Fail to paste: {0}", @clipboard.file.path), e
else
@clipboard.file.read("binary")
.then (d) =>
@ -268,8 +267,10 @@ class Files extends this.OS.GUI.BaseApplication
.then (r) =>
@clipboard = undefined
@error __("Fail to paste: {0}", r.error) if r.error
.catch (e) =>
@error __("Fail to paste: {0}", @clipboard.file.path), e
.catch (e) =>
@error __("Fail to paste: {0}", e.stack)
@error __("Fail to read: {0}", @clipboard.file.path), e
else
@_api.handle.setting()
@ -285,8 +286,8 @@ class Files extends this.OS.GUI.BaseApplication
@currdir.mk(d)
.then (r) =>
@error __("Fail to create {0}: {1}", d, r.error) if r.error
.catch (e) =>
@error __("Fail to create: {0}", e.stack)
.catch (e) =>
@error __("Fail to create: {0}", d), e
when "#{@name}-mkf"
@openDialog("PromptDialog", {
@ -298,8 +299,8 @@ class Files extends this.OS.GUI.BaseApplication
fp.write("text/plain")
.then (r) =>
@error __("Fail to create {0}: {1}", d, r.error) if r.error
.catch (e) =>
@error __("Fail to create: {0}", e.stack)
.catch (e) =>
@error __("Fail to create: {0}", fp.path)
when "#{@name}-info"
return unless file
@ -310,7 +311,7 @@ class Files extends this.OS.GUI.BaseApplication
.then (r) =>
@error __("Fail to upload to {0}: {1}", @currdir.path, r.error) if r.error
.catch (e) =>
@error __("Fail to upload: {0}", e.stack)
@error __("Fail to upload: {0}", e.toString()), e
when "#{@name}-share"
return unless file and file.type is "file"
@ -319,13 +320,13 @@ class Files extends this.OS.GUI.BaseApplication
return @error __("Cannot share file: {0}", r.error) if r.error
return @notify __("Shared url: {0}", r.result)
.catch (e) =>
@error __("Fail to publish: {0}", e.stack)
@error __("Fail to publish: {0}", file.path), e
when "#{@name}-download"
return unless file.type is "file"
file.path.asFileHandle().download()
.catch (e) =>
@error __("Fail to download: {0}", e.stack)
@error __("Fail to download: {0}", file.path), e
else
console.log e

View File

@ -2,7 +2,6 @@ afx-app-window[data-id ='files-app-window'] afx-list-view{
border-top:1px solid #A6A6A6;
}
afx-app-window[data-id ='files-app-window'] afx-list-view[data-id='favouri']{
background-color: #f6F6F6;
border-right: 0;
border-top:1px solid #A6A6A6;
padding:0;

View File

@ -21,7 +21,6 @@ class MarkOn extends this.OS.GUI.BaseApplication
super "MarkOn", args
main: () ->
me = @
markarea = @find "markarea"
@container = @find "mycontainer"
@previewOn = false
@ -42,8 +41,8 @@ class MarkOn extends this.OS.GUI.BaseApplication
{
name: "preview",
className: "fa fa-eye no-disable",
action: (e) ->
me.previewOn = !me.previewOn
action: (e) =>
@previewOn = !@previewOn
SimpleMDE.togglePreview e
#if(self.previewOn) toggle the highlight
#{
@ -59,16 +58,16 @@ class MarkOn extends this.OS.GUI.BaseApplication
}
]
@editor.codemirror.on "change", () ->
return if me.editormux
if me.currfile.dirty is false
me.currfile.dirty = true
me.scheme.set "apptitle", "#{me.currfile.basename}*"
@on "hboxchange", (e) -> me.resizeContent()
@bindKey "ALT-N", () -> me.actionFile "#{me.name}-New"
@bindKey "ALT-O", () -> me.actionFile "#{me.name}-Open"
@bindKey "CTRL-S", () -> me.actionFile "#{me.name}-Save"
@bindKey "ALT-W", () -> me.actionFile "#{me.name}-Saveas"
@editor.codemirror.on "change", () =>
return if @editormux
if @currfile.dirty is false
@currfile.dirty = true
@scheme.set "apptitle", "#{@currfile.basename}*"
@on "hboxchange", (e) => @resizeContent()
@bindKey "ALT-N", () => @actionFile "#{@name}-New"
@bindKey "ALT-O", () => @actionFile "#{@name}-Open"
@bindKey "CTRL-S", () => @actionFile "#{@name}-Save"
@bindKey "ALT-W", () => @actionFile "#{@name}-Saveas"
@resizeContent()
@open @currfile
@ -83,30 +82,27 @@ class MarkOn extends this.OS.GUI.BaseApplication
open: (file) ->
#find table
return if file.path is "Untitled"
me = @
file.dirty = false
file.read()
.then (d) ->
me.currfile = file
me.editormux = true
me.editor.value d
me.scheme.set "apptitle", "#{me.currfile.basename}"
me.editormux = false
.catch (e) -> me.error e.stack
.then (d) =>
@currfile = file
@editormux = true
@editor.value d
@scheme.set "apptitle", "#{@currfile.basename}"
@editormux = false
.catch (e) => @error __("Unable to open: {0}", file.path), e
save: (file) ->
me = @
file.write("text/plain")
.then (d) ->
return me.error __("Error saving file {0}: {1}", file.basename, d.error) if d.error
.then (d) =>
return @error __("Error saving file {0}: {1}", file.basename, d.error) if d.error
file.dirty = false
file.text = file.basename
me.scheme.set "apptitle", "#{me.currfile.basename}"
.catch (e) -> me.error e.stack
@scheme.set "apptitle", "#{@currfile.basename}"
.catch (e) => @error __("Unable to save file: {0}", file.path), e
menu: () ->
me = @
menu = [{
text: "__(File)",
child: [
@ -115,33 +111,29 @@ class MarkOn extends this.OS.GUI.BaseApplication
{ text: "__(Save)", dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "__(Save as)", dataid: "#{@name}-Saveas", shortcut: "A-W" }
],
onchildselect: (e) -> me.actionFile e.data.item.get("data").dataid
onchildselect: (e) => @actionFile e.data.item.get("data").dataid
}]
menu
actionFile: (e) ->
me = @
saveas = () ->
me.openDialog("FileDialog", {
saveas = () =>
@openDialog("FileDialog", {
title: __("Save as"),
file: me.currfile
file: @currfile
})
.then (f) ->
.then (f) =>
d = f.file.path.asFileHandle()
d = d.parent() if f.file.type is "file"
me.currfile.setPath "#{d.path}/#{f.name}"
console.log me.currfile
me.save me.currfile
.catch (e) ->
me.error e.stack
@currfile.setPath "#{d.path}/#{f.name}"
@save @currfile
switch e
when "#{@name}-Open"
@openDialog("FileDialog", {
title: __("Open file")
})
.then (f) ->
me.open f.file.path.asFileHandle()
.then (f) =>
@open f.file.path.asFileHandle()
when "#{@name}-Save"
@currfile.cache = @editor.value()
@ -157,12 +149,11 @@ class MarkOn extends this.OS.GUI.BaseApplication
cleanup: (evt) ->
return unless @currfile.dirty
me = @
evt.preventDefault()
@.openDialog "YesNoDialog", (d) ->
@.openDialog "YesNoDialog", (d) =>
if d
me.currfile.dirty = false
me.quit()
@currfile.dirty = false
@quit()
, __("Quit"), { text: __("Quit without saving ?") }
MarkOn.dependencies = [

View File

@ -1,4 +1,3 @@
/*afx-app-window[data-id ='markon-win'] div.CodeMirror-scroll{
height: calc(100%) - 50px;
background-color: red;
}*/
afx-app-window[data-id ='markon-win'] div.editor-toolbar{
background-color: white;
}

View File

@ -1,11 +0,0 @@
coffee_files = extensions/extensions.coffee extensions/RemoteRunExtension.coffee main.coffee
jsfiles =
cssfiles = main.css
copyfiles = scheme.html package.json
PKG_NAME=NotePad
include ../pkg.mk

View File

@ -1,68 +0,0 @@
class RemoteRunExtension extends BaseExtension
constructor: () ->
super "RemoteRunExtension"
init: () ->
@_gui.htmlToScheme RemoteRunExtension.scheme, @, @host
main: () ->
me = @
@output = @find "output"
(@find "log-clear").set "onbtclick", (e) ->
me.log "clean"
(@find "restart").set "onbtclick", (e) ->
me.run()
@socket = null
# Now run the file
@run()
log: (t, m) ->
return $(@output).empty() if t is "clean"
p = ($ "<p>").attr("class", t.toLowerCase())[0]
$(p).html "#{t}: #{m.__()}"
($ @output).append p
($ @output).scrollTop @output.scrollHeight
run: () ->
me = @
return @log "ERROR", __("No target file found") unless @data
@gateway = @gw()
return @log "ERROR", __("No backend found for file: {0}", @data.path) unless @gateway
$((@find "stat")).html(@data.path)
@socket.close() if @socket
proto = if window.location.protocol is "https:" then "wss://" else "ws://"
@socket = new WebSocket proto + @_api.HOST + @gateway
@socket.onopen = () ->
#send data to server
me.socket.send( JSON.stringify {path:me.data.path} )
@socket.onmessage = (e) -> me.log "INFO", e.data if e.data
@socket.onclose = () ->
me.socket = null
console.log "socket closed"
gw: () ->
return unless @data
for k,v of RemoteRunExtension.backends
if @data.info.mime.match (new RegExp k, "g") then return v
return null
cleanup: (e)->
@socket.close() if @socket
RemoteRunExtension.backends = {
"text/lua": "/system/apigateway?ws=1"
}
RemoteRunExtension.scheme = """
<afx-app-window apptitle="RemoteRun Ouput" width="300" height="450" data-id="win-remote-run">
<afx-vbox >
<afx-hbox data-height="20" data-id="bottom-vbox">
<afx-button data-id = "restart" data-width="25" iconclass="fa fa-repeat"></afx-button>
<afx-button data-id = "log-clear" data-width="25" iconclass="fa fa-trash"></afx-button>
<div data-id="stat"></div>
</afx-hbox>
<div data-id="output"></div>
</afx-vbox>
</afx-app-window>
"""

View File

@ -1,4 +0,0 @@
class BaseExtension extends this.OS.GUI.BaseDialog
constructor: (name) ->
super name

View File

@ -1,331 +0,0 @@
# Copyright 2017-2018 Xuan Sang LE <xsang.le AT gmail DOT com>
# AnTOS Web desktop is is licensed under the GNU General Public
# License v3.0, see the LICENCE file for more information
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# You should have received a copy of the GNU General Public License
#along with this program. If not, see https://www.gnu.org/licenses/.
class NotePad extends this.OS.GUI.BaseApplication
constructor: ( args ) ->
super "NotePad", args
main: () ->
me = @
@scheme.set "apptitle", "NotePad"
@sidebar = @find "sidebar"
@location = @find "location"
@fileview = @find "fileview"
div = @find "datarea"
ace.require "ace/ext/language_tools"
@currfile = if @args and @args.length > 0 then @args[0].asFileHandler() else "Untitled".asFileHandler()
@.editor = ace.edit div
@.editor.setOptions {
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
fontSize: "9pt"
}
@.editor.completers.push { getCompletions: ( editor, session, pos, prefix, callback ) -> }
@.editor.getSession().setUseWrapMode true
@fileview.contextmenuHandler = (e, m) ->
m.set "items", me.contextMenu()
m.set "onmenuselect", (evt) ->
me.contextAction evt
m.show e
@mlist = @find "modelist"
@modes = ace.require "ace/ext/modelist"
ldata = []
f = (m, i) ->
ldata.push {
text: m.name,
mode: m.mode,
selected: if m.mode is 'ace/mode/text' then true else false
}
m.idx = i
f(m, i) for m, i in @modes.modes
@mlist.set "items", ldata
@mlist.set "onlistselect", (e) ->
me.editor.session.setMode e.data.mode
themelist = @find "themelist"
themes = ace.require "ace/ext/themelist"
ldata = []
ldata.push {
text: m.caption,
mode: m.theme,
selected: if m.theme is "ace/theme/monokai" then true else false
} for k, m of themes.themesByName
themelist.set "onlistselect", (e) ->
me.editor.setTheme e.data.mode
themelist.set "items", ldata
stat = @find "editorstat"
#status
stup = (e) ->
c = me.editor.session.selection.getCursor()
l = me.editor.session.getLength()
stat.set "text", __("Row {0}, col {1}, lines: {2}", c.row, c.column, l)
stup(0)
@.editor.getSession().selection.on "changeCursor", (e) -> stup(e)
@editormux = false
@editor.on "input", () ->
if me.editormux
me.editormux = false
return false
if not me.currfile.dirty
me.currfile.dirty = true
me.currfile.text += "*"
me.tabarea.update()
@on "resize", () -> me.editor.resize()
@on "focus", () -> me.editor.focus()
@fileview.set "chdir", (d) -> me.chdir d
@fileview.set "fetch", (e, f) ->
return unless e.child
return if e.child.filename is "[..]"
e.child.path.asFileHandler().read (d) ->
return me.error __("Resource not found {0}", e.child.path) if d.error
f d.result
@fileview.set "onfileopen", (e) ->
return if e.type is "dir"
me.open e.path.asFileHandler()
@subscribe "VFS", (d) ->
p = (me.fileview.get "path").asFileHandler()
me.chdir p.path if d.data.file.hash() is p.hash() or d.data.file.parent().hash() is p.hash()
@location.set "onlistselect", (e) ->
me.chdir e.data.path
@location.set "items", ( i for i in @systemsetting.VFS.mountpoints when i.type isnt "app" )
@location.set "selected", 0 unless @location.get "selected"
@tabarea = @find "tabarea"
@tabarea.set "ontabselect", (e) ->
me.selecteTab e.idx
@tabarea.set "onitemclose", (e) ->
it = e.item.item
return false unless it
return me.closeTab it unless it.dirty
me.openDialog "YesNoDialog", (d) ->
return me.closeTab it if d
me.editor.focus()
, __("Close tab"), { text: __("Close without saving ?") }
return false
#@tabarea.set "closable", true
@bindKey "ALT-N", () -> me.actionFile "#{me.name}-New"
@bindKey "ALT-O", () -> me.actionFile "#{me.name}-Open"
@bindKey "CTRL-S", () -> me.actionFile "#{me.name}-Save"
@bindKey "ALT-W", () -> me.actionFile "#{me.name}-Saveas"
@bindKey "ALT-R", () -> me.actionFile "#{me.name}-Run"
@open @currfile
open: (file) ->
#find tab
i = @findTabByFile file
return @tabarea.set "selected", i if i isnt -1
return @newtab file if file.path.toString() is "Untitled"
me = @
file.read (d) ->
file.cache = d or ""
me.newtab file
contextMenu: () ->
[
{ text: __("New file"), dataid: "#{@name}-mkf" },
{ text: __("New folder"), dataid: "#{@name}-mkd" },
{ text: __("Delete"), dataid: "#{@name}-rm" }
{ text: __("Refresh"), dataid: "#{@name}-refresh" }
]
contextAction: (e) ->
me = @
file = @fileview.get "selectedFile"
dir = if file then file.path.asFileHandler() else (@fileview.get "path").asFileHandler()
console.log dir
dir = dir.parent().asFileHandler() if file and file.type isnt "dir"
switch e.item.data.dataid
when "#{@name}-mkd"
@openDialog "PromptDialog",
(d) ->
dir.mk d, (r) ->
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, "__(New folder)"
when "#{@name}-mkf"
@openDialog "PromptDialog",
(d) ->
fp = "#{dir.path}/#{d}".asFileHandler()
fp.write "", (r) ->
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, "__(New file)"
when "#{@name}-rm"
return unless file
@openDialog "YesNoDialog",
(d) ->
return unless d
file.path.asFileHandler()
.remove (r) ->
me.error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error
, "__(Delete)" ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", file.filename) }
when "#{@name}-refresh"
@.chdir ( @fileview.get "path" )
save: (file) ->
me = @
file.write "text/plain", (d) ->
return me.error __("Error saving file {0}", file.basename) if d.error
file.dirty = false
file.text = file.basename
me.tabarea.update()
findTabByFile: (file) ->
lst = @tabarea.get "items"
its = ( i for d, i in lst when d.hash() is file.hash() )
return -1 if its.length is 0
return its[0]
closeTab: (it) ->
@tabarea.remove it, false
cnt = @tabarea.get "count"
if cnt is 0
@open "Untitled".asFileHandler()
return false
@tabarea.set "selected", cnt - 1
return false
newtab: (file) ->
file.text = if file.basename then file.basename else file.path
file.cache = "" unless file.cache
file.um = new ace.UndoManager()
@currfile.selected = false
file.selected = true
#console.log cnt
@tabarea.push file, true
#@currfile = @file
#TODO: fix problem : @tabarea.set "selected", cnt
selecteTab: (i) ->
#return if i is @tabarea.get "selidx"
file = (@tabarea.get "items")[i]
return unless file
@fileview.set "preventUpdate", true
@scheme.set "apptitle", file.text.toString()
#return if file is @currfile
if @currfile isnt file
@currfile.cache = @editor.getValue()
@currfile.cursor = @editor.selection.getCursor()
@currfile = file
m = "ace/mode/text"
m = (@modes.getModeForPath file.path) if file.path.toString() isnt "Untitled"
@mlist.set "selected", m.idx
@editormux = true
@editor.setValue file.cache, -1
@editor.session.setMode m.mode
@editor.session.setUndoManager file.um
if file.cursor
@editor.renderer.scrollCursorIntoView { row: file.cursor.row, column: file.cursor.column }, 0.5
@editor.selection.moveTo file.cursor.row, file.cursor.column
@editor.focus()
chdir: (pth) ->
#console.log "called", @_api.throwe("FCK")
return unless pth
me = @
dir = pth.asFileHandler()
dir.read (d) ->
if(d.error)
return me.error __("Resource not found {0}", p)
if not dir.isRoot()
p = dir.parent().asFileHandler()
p.filename = "[..]"
p.type = "dir"
#p.size = 0
d.result.unshift p
($ me.navinput).val dir.path
me.fileview.set "path", pth
me.fileview.set "data", d.result
menu: () ->
me = @
menu = [{
text: "__(File)",
child: [
{ text: "__(New)", dataid: "#{@name}-New", shortcut: "A-N" },
{ text: "__(Open)", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "__(Save)", dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "__(Save as)", dataid: "#{@name}-Saveas", shortcut: "A-W" },
{ text: "__(Run)", dataid: "#{@name}-Run", shortcut: "A-R" }
],
onmenuselect: (e) -> me.actionFile e.item.data.dataid
}]
menu
actionFile: (e) ->
me = @
saveas = () ->
me.openDialog "FileDiaLog", (d, n) ->
file = "#{d}/#{n}".asFileHandler()
file.cache = me.currfile.cache
file.dirty = me.currfile.dirty
file.um = me.currfile.um
file.cursor = me.currfile.cursor
file.selected = me.currfile.selected
file.text = me.currfile.text
me.tabarea.replaceItem me.currfile, file, false
me.currfile = file
me.save me.currfile
, "__(Save as)", { file: me.currfile }
switch e
when "#{@name}-Open"
@openDialog "FileDiaLog", ( d, f ) ->
me.open "#{d}/#{f}".asFileHandler()
, "__(Open file)"
when "#{@name}-Save"
@currfile.cache = @editor.getValue()
return @save @currfile if @currfile.basename
saveas()
when "#{@name}-Saveas"
@currfile.cache = @editor.getValue()
saveas()
when "#{@name}-New"
@open "Untitled".asFileHandler()
when "#{@name}-Run"
if @currfile.dirty
return @notify __("Please save the file before running it")
else
if @dialog then @dialog.quit()
@openDialog new RemoteRunExtension(), null, null, @currfile
cleanup: (evt) ->
dirties = ( v for v in @tabarea.get "items" when v.dirty )
return if dirties.length is 0
me = @
evt.preventDefault()
@.openDialog "YesNoDialog", (d) ->
if d
v.dirty = false for v in dirties
me.quit()
, "__(Quit)", { text: __("Ignore all {0} unsaved files ?", dirties.length) }
NotePad.singleton = false
NotePad.dependencies = [
"ace/ace",
"ace/ext-language_tools",
"ace/ext-modelist",
"ace/ext-themelist"
]
NotePad.extensions = {}
this.OS.register "NotePad", NotePad

View File

@ -1,79 +0,0 @@
afx-app-window[data-id="notepad"] afx-list-view {
margin: 2px;
margin-right: 5px;
}
afx-app-window[data-id="notepad"] afx-list-view div.list-container{
z-index: 10;
}
afx-app-window[data-id="notepad"] afx-resizer{
z-index: 11;
background-color: transparent;
border-right: 1px solid #a6a6a6;
}
afx-app-window[data-id="notepad"] afx-label[data-id="editorstat"]{
padding:5px;
display: inline-block;
}
afx-app-window[data-id="notepad"] afx-vbox[data-id="bottom-vbox"]{
background-color: #dfdfdf;
}
afx-app-window[data-id="notepad"] .afx-window-content {
background-color: #f6F6F6;
}
afx-tab-bar[data-id="tabarea"] afx-list-view > div.list-container > ul > li {
background-color: #dfdfdf;
color:#272822;
border: 0;
border-top: 1px solid #a6a6a6;
border-right: 1px solid #a6a6a6;
border-radius: 0;
}
afx-tab-bar[data-id="tabarea"] afx-list-view{
padding:0;
margin: 0;
border-left: 0;
border-bottom: 1px solid #a6a6a6;
}
/*afx-tab-bar[data-id="tabarea"] afx-list-view i.closable:before{
color: white;
}*/
afx-tab-bar[data-id="tabarea"] afx-list-view > div.list-container > ul > li.selected {
background-color: #f6F6F6;
border-radius: 0;
}
afx-app-window[data-id="win-remote-run"] div[data-id="output"] p{
margin:0;
padding:0;
font-family: "HermitLight";
text-align: left;
}
afx-app-window[data-id="win-remote-run"] div[data-id="output"]{
background-color: #2f3129;
padding: 10px;
color:white;
overflow: auto;
}
afx-app-window[data-id="win-remote-run"] div[data-id="stat"]{
background-color: #2f3129;
padding: 5px;
color:white;
font-weight: bold;
font-size: 10px;
}
afx-app-window[data-id="win-remote-run"] afx-resizer{
border-top: 1px solid #a6a6a6;
background-color: #2f3129;
border-right: 0;
}
afx-app-window[data-id="win-remote-run"] afx-hbox[data-id="bottom-vbox"] {
background-color:#2f3129;
}
afx-app-window[data-id="win-remote-run"] afx-hbox[data-id="bottom-vbox"] afx-button button{
background-color:#2f3129;
color:white;
border:0;
border-radius: 0;
}

View File

@ -1,18 +0,0 @@
{
"app":"NotePad",
"name":"NotePad editor",
"description":"Basic application for text editing",
"info":{
"author": "Xuan Sang LE",
"email": "xsang.le@gmail.com"
},
"version":"0.0.2-a",
"category":"System",
"iconclass":"fa fa-pencil-square-o",
"mimes":[
"text/.*",
"[^/]*/json.*",
"[^/]*/.*ml",
"[^/]*/javascript"
]
}

View File

@ -1,19 +0,0 @@
<afx-app-window apptitle="" width="600" height="400" data-id="notepad">
<afx-hbox>
<afx-vbox data-width = "155" data-id = "sidebar" min-width="155">
<afx-list-view data-id = "location" dropdown = "true" data-height= "30" width = "150"></afx-list-view>
<afx-file-view data-id = "fileview" view='tree' status = false></afx-file-view>
</afx-vbox>
<afx-resizer data-width = "3" ></afx-resizer>
<afx-vbox>
<afx-tab-bar data-id="tabarea" data-height="23" closable = true></afx-tab-bar>
<div data-id="datarea"></div>
<afx-hbox data-height="30" data-id="bottom-vbox">
<afx-label data-id="editorstat"></afx-label>
<afx-list-view data-width="160" data-id = "themelist" dropdown = "true" width="135"></afx-list-view>
<afx-list-view data-width="125" data-id = "modelist" dropdown = "true" width="100"></afx-list-view>
</afx-hbox>
</afx-vbox>
</afx-hbox>
</afx-app-window>

View File

@ -66,9 +66,15 @@ class AppearanceHandle extends SettingHandle
@parent.systemsetting.appearance.wp.repeat = e.data.item.get("data").text
@parent._gui.wallpaper()
@wprepeat.set "data", repeats
@themelist.set "data" , [{ text: "antos", selected: true }]
currtheme = @parent.systemsetting.appearance.theme
v.selected = v.name is currtheme for v in @parent.systemsetting.appearance.themes
@themelist.set "data" , @parent.systemsetting.appearance.themes
@themelist.set "onlistselect", (e) =>
data = e.data.item.get("data") if e and e.data
return unless data
return if data.name is @parent.systemsetting.appearance.theme
@parent.systemsetting.appearance.theme = data.name
@parent._gui.loadTheme data.name, true
if not @syswp
path = "os://resources/themes/system/wp"
path.asFileHandle().read()
@ -79,7 +85,7 @@ class AppearanceHandle extends SettingHandle
v.iconclass = "fa fa-file-image-o"
@syswp = d.result
@wplist.set "data", @getwplist()
.catch (e) => @parent.error e.stack
.catch (e) => @parent.error __("Unable to read: {0}", path), e
else
@wplist.set "data", @getwplist()

View File

@ -33,6 +33,6 @@ class LocaleHandle extends SettingHandle
v.selected = v.text is @parent.systemsetting.system.locale
@localelist = d.result
@lglist.set "data", @localelist
.catch (e) => @parent.error e.stack
.catch (e) => @parent.error __("Unable to read: {0}", path), e
else
@lglist.set "data", @localelist

View File

@ -41,6 +41,6 @@ class Setting extends this.OS.GUI.BaseApplication
return @error __("Cannot save system setting: {0}", d.error) if d.error
@notify __("System setting saved")
.catch (e) =>
@error __("Cannot save system setting: {0}", e.stack)
@error __("Cannot save system setting: {0}", e.toString()), e
Setting.singleton = true
this.OS.register "Setting", Setting

View File

@ -120,8 +120,8 @@ class ShowCase extends this.OS.GUI.BaseApplication
@notify e
fileview = @find 'fileview'
fileview.set "fetch", (path) =>
new Promise (resolve, reject) =>
fileview.set "fetch", (path) ->
new Promise (resolve, reject) ->
dir = path.asFileHandle()
dir.read().then (d) ->
p = dir.parent().asFileHandle()

View File

@ -1,12 +0,0 @@
/*! Generated by Font Squirrel (https://www.fontsquirrel.com) on August 6, 2017 */
@font-face {
font-family: 'HermitLight';
src: url('fonts/hermit-light-webfont.woff2') format('woff2'),
url('fonts/hermit-light-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}

View File

@ -0,0 +1,53 @@
afx-app-window div.afx-window-wrapper{
border:1px solid #262626;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border-radius: 0px;
background-color:#363636;
}
afx-app-window.unactive > div.afx-window-wrapper{
background-color: #464646;
}
afx-app-window ul.afx-window-top{
height: 20px;
border-bottom: 1px solid #262626;
}
afx-app-window ul.afx-window-top li{
margin-left: 3px;
margin-top:4px;
}
afx-app-window ul.afx-window-top .afx-window-close,.afx-window-minimize,.afx-window-maximize{
width: 10px;
height: 10px;
border-radius: 0;
}
afx-app-window ul li.afx-window-close{
background-color: #Fc605b;
float:left;
}
afx-app-window ul li.afx-window-minimize{
background-color: #fec041;
float:left;
}
afx-app-window ul li.afx-window-maximize{
background-color: #35cc4b;
float:left;
}
afx-app-window ul li.afx-window-title{
margin-top:1px;
text-align: center;
}
afx-app-window div.afx-window-content
{
background-color:#363636;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
afx-app-window.unactive div.afx-window-content
{
background-color:#464646;
}

View File

@ -0,0 +1,22 @@
afx-button button{
padding: 4px;
border: 1px solid #262626;
background-color: #464646;
color: white;
border-radius: 3px;
font-family: "Ubuntu";
}
afx-button button[disabled]{
color: #868686;
}
afx-button i.icon-style {
width: 16px;
height: 16px;
display: inline-block;
}
afx-button button:active, afx-button button.btactive {
background-color: #2786F3;
color: white;
border: 1px solid #363636;
}

View File

@ -0,0 +1,53 @@
afx-calendar-view div{
text-align: center;
}
afx-calendar-view > div {
font-weight: bold;
}
afx-calendar-view i.prevmonth, afx-calendar-view i.nextmonth{
display: inline-block;
width: 16px;
height: 16px;
cursor: pointer;
}
afx-calendar-view i.prevmonth{
margin-right: 20px;
}
afx-calendar-view i.nextmonth{
margin-left: 20px;
}
afx-calendar-view i.prevmonth:before{
content: "\f104";
font-family: "FontAwesome";
font-size: 16px;
font-style: normal;
/*position:absolute;
top:25%;
right:5px;*/
}
afx-calendar-view i.nextmonth:before{
content: "\f105";
font-family: "FontAwesome";
font-size: 16px;
font-style: normal;
margin-left: 20px;
/*position:absolute;
top:25%;
right:5px;*/
}
afx-calendar-view afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell
{
background-color: transparent;
}
afx-calendar-view afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell.afx-grid-cell-selected
{
background-color: #116cd6;
color:white;
border-radius: 6px;
}

View File

@ -0,0 +1,4 @@
afx-color-picker canvas.color-palette, afx-color-picker div.color-sample{
border: 1px solid #262626;
/*border-radius: 3px;*/
}

View File

@ -0,0 +1,35 @@
afx-apps-dock{
bottom: 0px;
top: 0px;
width: 32px;
background-color:#363636;
padding:0;
padding-top: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border:1px solid #262626;
box-shadow: none;
}
afx-apps-dock afx-button button{
width: 32px;
height: 32px;
font-size: 19px;
margin-bottom: 0;
padding:0px;
background-color: transparent;
border:0;
border-radius: 0;
}
afx-apps-dock afx-button afx-label i.icon-style{
width: 24px;
height: 24px;
margin-left: 2px;
margin-bottom: 0px;
border:0;
}
afx-apps-dock afx-button.selected > button {
background-color: #464646;
color: white;
border: 1px solid #464646;
}

View File

@ -0,0 +1,131 @@
afx-file-view afx-label.status{
padding:3px;
right: 0px;
height: 15px;
background-color: #464646;
border-top: 1px solid #262626;
}
afx-file-view afx-list-view > div.list-container > ul li{
width:70px;
height: 60px;
background-color: transparent;
text-align: center;
padding:3px;
margin-right: 5px;
margin-bottom: 5px;
}
afx-file-view afx-list-view > div.list-container > ul afx-list-item:nth-child(even) li {
background-color: transparent;
}
afx-file-view afx-list-view i.dir:before{
content: "\f07b";
font-family: "FontAwesome";
font-size: 32px;
color: #76D2F9;
font-weight: normal;
font-style: normal;
}
afx-file-view afx-list-view i{
width: 32px;
height: 32px;
margin-left: 19px;
}
afx-file-view afx-list-view i.file:before{
content: "\f016";
font-family: "FontAwesome";
font-size: 28px;
color: white;
font-style: normal;
font-weight: normal;
}
afx-file-view afx-list-view > div.list-container > ul > afx-list-item > li.selected, afx-file-view afx-list-view div.list-container > ul li.selected i:before {
background-color: #116cd6;
color:white;
border-radius: 6px;
}
afx-file-view afx-grid-view{
padding:0;
}
afx-file-view afx-grid-view i.file:before{
content: "\f016";
font-family: "FontAwesome";
font-size: 16px;
color: white;
font-style: normal;
font-weight: normal;
}
afx-file-view afx-grid-view i.dir:before{
content: "\f07b";
font-family: "FontAwesome";
font-size: 16px;
color: #76D2F9;
font-style: normal;
font-weight: normal;
}
afx-file-view afx-grid-view i{
margin-right: 5px;
}
afx-file-view afx-grid-view afx-grid-row.afx-grid-row-selected i:before{
color:white;
}
afx-file-view afx-grid-view afx-grid-row afx-grid-cell
{
padding: 3px;
}
afx-file-view afx-grid-view .grid_row_header afx-grid-cell{
background-color: #464646;
border-top: 1px solid #262626;
border-right: 1px solid #262626;
border-bottom: 1px solid #262626;
padding: 3px;
}
afx-file-view afx-tree-view .afx-tree-view-folder-close:before{
content: "\f07b";
font-family: "FontAwesome";
font-size: 16px;
color:#76D2F9;
}
afx-file-view afx-tree-view .afx-tree-view-folder-open:before{
content: "\f07c";
font-family: "FontAwesome";
color:#76D2F9;
font-size: 16px;
}
afx-file-view afx-tree-view .afx-tree-view-item:before{
content: "\f016";
font-family: "FontAwesome";
font-size: 16px;
color: #414339;
font-style: normal;
font-weight: normal;
}
afx-file-view afx-tree-view div.afx_tree_item_selected, afx-file-view afx-tree-view div.afx_tree_item_selected:hover{
background-color: transparent;
color:#414339;
}
afx-file-view afx-tree-view li.itemname{
padding:3px;
padding-right: 5px;
}
afx-file-view afx-tree-view div.afx_tree_item_selected .itemname{
background-color: #116cd6;
color:white;
border-radius: 3px;
}
afx-file-view afx-tree-view div.afx_tree_item_selected i.file:before{
color:white;
}
afx-file-view afx-tree-view .afx_folder_item{
font-weight: normal;
}

View File

@ -0,0 +1,19 @@
afx-grid-view afx-grid-row:nth-child(even) afx-grid-cell
{
background-color: #464646;
}
afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell
{
background-color: #116cd6;
color:white;
}
afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell.afx-grid-cell-selected
{
font-weight: bold;
}
afx-grid-view .grid_row_header afx-grid-cell{
border:0;
}

View File

@ -1,9 +1,4 @@
afx-label i.icon-style {
width: 16px;
height: 16px;
}
afx-label i
{
margin-right: 3px;
}

View File

@ -0,0 +1,92 @@
afx-list-view > div.list-container > ul li{
padding: 5px;
padding-top:3px;
padding-bottom: 3px;
padding-right: 10px;
background-color: #363636;
}
afx-list-view > div.list-container > ul afx-list-item:nth-child(even) li{
background-color:#464646;
}
afx-list-view i.closable{
width: 16px;
height: 16px;
}
afx-list-view i.closable:before{
font-size: 10px;
margin-left: 10px;
color: #868686;
}
afx-list-view > div.list-container > ul li > i {
margin-right: 3px;
}
afx-list-view > div.list-container > ul > afx-list-item > li.selected{
background-color: #116cd6;
color:white;
}
afx-list-view.dropdown > div.list-container > ul{
border:1px solid #a6a6a6;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border-radius: 3px;
max-height: 150px;
background-color: #363636;
border-top-left-radius: 0px;
z-index: 10;
}
afx-list-view.dropdown div.list-container div{
color: white;
padding-top:3px;
padding-bottom: 3px;
border:1px solid #a6a6a6;
border-radius: 3px;
background-color: transparent;
height: 17px;
}
afx-list-view.dropdown div.list-container div > afx-label{
padding-left:3px;
}
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;
}
afx-list-view ul.complex-content{
padding: 0;
margin: 0;
background-color: transparent;
}
afx-list-view ul.complex-content li{
padding:0;
background-color: transparent;
color:#5e5f59;
list-style: none;
}
afx-list-view > div.list-container > ul li.selected ul.complex-content li{
color:white;
}
afx-list-view div.button_container afx-button{
margin-right: 2px;
}
afx-list-view div.button_container afx-button button{
border-radius: 0;
padding-left:5px;
padding-top:1px;
padding-bottom: 1px;
padding-right: 5px;
}

View File

@ -0,0 +1,58 @@
afx-menu afx-switch span{
width: 20px;
height: 16px;
font-size: 16px;
/*margin-top:5px;*/
}
afx-menu span.shortcut{
text-align: right;
}
afx-menu li:hover > a afx-switch span:before{
color:white;
}
afx-menu afx-menu ul {
padding: 0;
border:1px solid #262626;
border-radius: 5px;
border-top-left-radius: 0px;
/*box-shadow: 2px 2px 2px #cbcbcb;*/
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
background-color: #363636;
}
afx-menu ul li /*, afx-menu ul >afx-menu-entry > li*/{
padding:3px;
padding-left: 5px;
padding-right: 5px;
}
afx-menu afx-menu li{
min-width: 150px;
}
afx-menu li:hover {
background-color: #2786F3;
}
afx-menu li:hover > a {
color: white;
}
afx-menu afx-menu .afx_submenu:before, afx-menu ul.context .afx_submenu:before{
content: "\f054";
font-family: "FontAwesome";
font-size: 10px;
right:5px;
color: #414339;
position:absolute;
top:25%;
}
afx-menu ul.context{
border:1px solid #262626;
border-radius: 5px;
border-top-left-radius: 0px;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
background-color: #363636;
}
afx-menu ul.context li{
min-width: 150px;
}

View File

@ -0,0 +1,25 @@
afx-nspinner ul li{
border: 1px solid #262626;
width: 100%;
}
afx-nspinner ul li.incr{
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
afx-nspinner ul li.decr{
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
afx-nspinner ul li:hover{
color:#116cD6;
}
afx-nspinner ul li.incr i:before{
font-size: 16px;
}
afx-nspinner ul li.decr i:before{
font-size: 16px;
}

View File

@ -0,0 +1,3 @@
afx-overlay {
background-color: rgba(54, 54, 54, 0.7);
}

View File

@ -0,0 +1,3 @@
afx-resizer {
background-color: #868686;
}

View File

@ -0,0 +1,19 @@
afx-slider div.container{
border-radius: 3px;
height: 5px;
background-color: #868686;
}
afx-slider div.progress {
background-color: #116cd6;
border-radius: 3px;
}
afx-slider div.dragpoint {
width: 20px;
height: 20px;
border:1px solid #262626;
border-radius: 20px;
background-color:#868686;
}

View File

@ -0,0 +1,17 @@
afx-switch span{
width: 30px;
height:24px;
font-size: 24px;
font-family: "FontAwesome";
}
afx-switch span:before{
content: "\f204";
font-style: normal;
font-weight: normal;
}
afx-switch span.swon:before{
content: "\f205";
color: #116cd6;
font-style: normal;
font-weight: normal;
}

View File

@ -0,0 +1,103 @@
afx-sys-panel > div{
background-color: #363636;
border-bottom: 1px solid #262626;
box-shadow: none;
height: 22px;
}
afx-sys-panel .afx-panel-os-menu li
{
font-weight: bold;
background-color: #e7414d;
border-top-right-radius: 9px;
border-bottom-right-radius: 9px;
}
afx-sys-panel .afx-panel-os-menu a {
color: white;
}
afx-sys-panel afx-menu.afx-panel-os-stray afx-menu {
left: calc(100% - 170px);
}
afx-sys-panel afx-menu.afx-panel-os-stray afx-menu li.afx_submenu a{
margin-left: 10px;
}
afx-sys-panel afx-menu.afx-panel-os-stray afx-menu li.afx_submenu:before {
content: "\f054";
font-family: "FontAwesome";
font-size: 10px;
position:absolute;
text-align: left;
left:5px;
top:25%;
}
afx-sys-panel afx-menu.afx-panel-os-stray afx-menu ul{
border:1px solid #262626;
border-radius: 5px;
border-top-right-radius: 0px;
}
afx-sys-panel afx-menu.afx-panel-os-stray afx-menu li{
min-width: 150px;
}
afx-sys-panel afx-overlay
{
background-color: #363636;
border: 1px solid #262626;
width: 250px;
}
afx-sys-panel afx-list-view[data-id="applist"]
{
border-top: 1px solid #262626;
border-bottom: 1px solid #262626;
}
afx-sys-panel afx-list-view[data-id="applist"] > div.list-container > ul li
{
padding-top: 5px;
padding-bottom: 5px;
background-color: transparent;
}
afx-sys-panel afx-hbox[data-id="btlist"] afx-button button
{
border: 0;
border-left: 1px solid #262626;
}
afx-sys-panel afx-list-view[data-id="applist"] > div.list-container > ul li:hover{
background-color: #cecece;
color: #262626;
}
afx-sys-panel afx-list-view[data-id="applist"] > div.list-container > ul li.selected
{
background-color: #116cd6;
color:white;
}
afx-sys-panel afx-list-view[data-id="applist"] afx-label.search-header {
font-weight: bold;
}
afx-sys-panel afx-list-view[data-id="applist"] afx-label i,
afx-sys-panel afx-list-view[data-id="applist"] afx-label i::before {
margin-right: 10px;
}
afx-sys-panel div[data-id="searchicon"]:before{
content: "\f002";
display: block;
background-color:transparent;
color:#afafaf;
font-family: "FontAwesome";
padding-left:3px;
font-size: 25px;
}
afx-sys-panel input{
border:0;
height: 25px;
color:#afafaf;
background-color: transparent;
}

View File

@ -0,0 +1,15 @@
afx-tab-bar afx-list-view > div.list-container > ul > afx-list-item > li.selected
{
background-color: #464646;
color:white;
}
afx-tab-bar afx-list-view > div.list-container > ul li{
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding-bottom: 2px;
padding-right:15px;
padding-top:2px;
border:1px solid #262626;
}

View File

@ -0,0 +1,27 @@
afx-tree-view{
padding:3px;
}
afx-tree-view div{
padding:3px;
}
afx-tree-view i.icon-style {
width: 16px;
height: 16px;
}
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 .afx_folder_item{
font-weight: bold;
}
afx-tree-view .afx_tree_item_odd{
background-color: #464646;
}

View File

@ -0,0 +1,69 @@
html,body{
font-family: "Ubuntu";
font-size: 13px;
color: white;
}
#workspace {
top: 23px;
}
#desktop{
top:0;
left: 35px;
}
#desktop > div > ul afx-list-item {
width: 70px;
color: white;
padding:3px;
}
#desktop > div > ul afx-list-item li.selected {
background-color: #116cd6;
color:white;
border-radius: 6px;
width: 70px;
color: white;
padding:3px;
}
#desktop > div > ul afx-list-item i.file:before{
content: "\f15b\a";
font-family: "FontAwesome";
font-size: 32px;
display: block;
color: white;
font-style: normal;
font-weight: normal;
}
#desktop > div > ul afx-list-item i.dir:before{
display: block;
content: "\f07b\a";
font-family: "FontAwesome";
font-size: 32px;
color: #76D2F9;
font-weight: normal;
font-style: normal;
}
#systooltip {
border:1px solid #363636;
border-radius: 3px;
padding-left:3px;
padding-right:3px;
box-shadow: none;
background-color: #464646;
}
input {
outline: none;
padding: 2px;
height:23px;
border: 1px solid #262626;
background-color:#464646;
color: white;
border-radius: 3px;
box-sizing: border-box;
font-family: "Ubuntu";
font-size: 13px;
}

View File

@ -1,6 +1,6 @@
afx-app-window div.afx-window-wrapper{
border:1px solid #a6a6a6;
box-shadow: 1px 1px 1px #9f9F9F;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border-radius: 5px;
background-color:#dfdfdf;
}
@ -37,8 +37,6 @@ afx-app-window ul li.afx-window-maximize{
afx-app-window ul li.afx-window-title{
margin-top:1px;
padding-left: 5px;
padding-right: 5px;
text-align: center;
}
@ -47,4 +45,8 @@ afx-app-window div.afx-window-content
background-color: white;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
afx-app-window.unactive div.afx-window-content
{
background-color:white;
}

View File

@ -5,7 +5,7 @@ afx-button button{
color: #414339;
border-radius: 6px;
font-family: "Ubuntu";
font-size: 13px;
}
afx-button button[disabled]{

View File

@ -1,6 +1,5 @@
afx-calendar-view div{
text-align: center;
background-color: white;
}
afx-calendar-view > div {
font-weight: bold;
@ -24,7 +23,6 @@ afx-calendar-view i.prevmonth:before{
font-family: "FontAwesome";
font-size: 16px;
font-style: normal;
color: #414339;
/*position:absolute;
top:25%;
right:5px;*/
@ -34,7 +32,6 @@ afx-calendar-view i.nextmonth:before{
font-family: "FontAwesome";
font-size: 16px;
font-style: normal;
color: #414339;
margin-left: 20px;
/*position:absolute;
top:25%;

View File

@ -1,23 +1,24 @@
afx-apps-dock{
bottom: 3px;
top: 3px;
bottom: 0;
top: 0;
width: 32px;
background-color:#e7e7e7;
padding:2px;
padding-top: 5px;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
padding:0;
padding-top: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border:1px solid #a6a6a6;
box-shadow: 1px 1px 1px #9f9F9F;
box-shadow: none;
}
afx-apps-dock afx-button button{
width: 32px;
height: 32px;
font-size: 19px;
margin-bottom: 3px;
margin-bottom: 0;
padding:0px;
background-color: transparent;
border:0;
border-radius: 0;
}
afx-apps-dock afx-button afx-label i.icon-style{
width: 24px;

View File

@ -4,7 +4,6 @@ afx-file-view afx-label.status{
height: 15px;
background-color: #f6F6F6;
border-top: 1px solid #cbcbcb;
color:#414339;
}
afx-file-view afx-list-view > div.list-container > ul li{
width:70px;
@ -81,6 +80,8 @@ afx-file-view afx-grid-view .grid_row_header afx-grid-cell{
background-color: #dfdfdf;
border-top: 1px solid #a6a6a6;
border-right: 1px solid #a6a6a6;
border-bottom: 1px solid #a6a6a6;
padding: 3px;
}
afx-file-view afx-tree-view .afx-tree-view-folder-close:before{

View File

@ -15,5 +15,5 @@ afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell.afx-grid-cell-sel
afx-grid-view .grid_row_header afx-grid-cell{
border-right: 2px solid #e5e5e5;
border: 0;
}

View File

@ -0,0 +1,4 @@
afx-label i.icon-style {
width: 16px;
height: 16px;
}

View File

@ -3,7 +3,6 @@ afx-list-view > div.list-container > ul li{
padding-top:3px;
padding-bottom: 3px;
padding-right: 10px;
color: #414339;
background-color: white;
}
afx-list-view > div.list-container > ul afx-list-item:nth-child(even) li{
@ -31,10 +30,10 @@ afx-list-view > div.list-container > ul > afx-list-item > li.selected{
afx-list-view.dropdown > div.list-container > ul{
border:1px solid #a6a6a6;
box-shadow: 1px 1px 1px #9f9F9F;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
border-radius: 3px;
max-height: 150px;
background-color: transparent;
background-color: white;
border-top-left-radius: 0px;
z-index: 10;
}

View File

@ -1,7 +1,3 @@
afx-menu a{
color: #414339;
}
afx-menu afx-switch span{
width: 20px;
height: 16px;
@ -21,7 +17,7 @@ afx-menu afx-menu ul {
border-radius: 5px;
border-top-left-radius: 0px;
/*box-shadow: 2px 2px 2px #cbcbcb;*/
box-shadow: 1px 1px 1px #9f9F9F;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
background-color: #e7e7e7;
}
afx-menu ul li /*, afx-menu ul >afx-menu-entry > li*/{
@ -29,9 +25,6 @@ afx-menu ul li /*, afx-menu ul >afx-menu-entry > li*/{
padding-left: 5px;
padding-right: 5px;
}
afx-menu afx-menu i{
margin-right: 5px;
}
afx-menu afx-menu li{
min-width: 150px;
}
@ -57,7 +50,7 @@ afx-menu afx-menu .afx_submenu:before, afx-menu ul.context .afx_submenu:before
border:1px solid #a6a6a6;
border-radius: 5px;
border-top-left-radius: 0px;
box-shadow: 1px 1px 1px #9f9F9F;
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.65);
background-color: #e7e7e7;
}
afx-menu ul.context li{

View File

@ -1,7 +1,6 @@
afx-nspinner ul li{
border: 1px solid #a6a6a6;
width: 100%;
color: #414339;
}
afx-nspinner ul li.incr{

View File

@ -0,0 +1,3 @@
afx-overlay {
background-color: rgba(231, 231, 231, 0.7);
}

Some files were not shown because too many files have changed in this diff Show More