add tree-view

This commit is contained in:
lxsang 2020-04-05 22:51:31 +02:00
parent 8b44c3b3c0
commit 9924c642c5
5 changed files with 308 additions and 79 deletions

View File

@ -37,6 +37,7 @@ coffees= src/core/core.coffee \
src/core/tags/MenuTag.coffee \ src/core/tags/MenuTag.coffee \
src/core/tags/GridView.coffee \ src/core/tags/GridView.coffee \
src/core/tags/TabBarTag.coffee \ src/core/tags/TabBarTag.coffee \
src/core/tags/TreeViewTag.coffee \
src/antos.coffee src/antos.coffee

View File

@ -11,10 +11,15 @@ class ListViewItemTag extends Ant.OS.GUI.BaseTag
@setopt "index", 0 @setopt "index", 0
@setopt "closable", false @setopt "closable", false
@setopt "selected", false @setopt "selected", false
__closable__: (v) ->
if v then $(@refs.btcl).show() else $(@refs.btcl).hide()
__selected__: (v) ->
$(@refs.item).removeClass()
return unless v
$(@refs.item).addClass "selected"
@get("onselect")({ item: @root })
class SimpleListItemTag extends ListViewItemTag
constructor: (r, o) ->
super r, o
mount: () -> mount: () ->
me = @ me = @
$(@refs.item).contextmenu (e) -> $(@refs.item).contextmenu (e) ->
@ -31,15 +36,19 @@ class SimpleListItemTag extends ListViewItemTag
$(@refs.btcl).click (e) -> $(@refs.btcl).click (e) ->
e.item = me.root e.item = me.root
me.get("onclose")(e) me.get("onclose")(e)
layout: () ->
[{
el: "li", ref: "item", children: [
@itemlayout(),
{ el: "i", class: "closable", ref: "btcl" }
]
}]
__closable__: (v) -> itemlayout: () ->
if v then $(@refs.btcl).show() else $(@refs.btcl).hide()
__selected__: (v) -> class SimpleListItemTag extends ListViewItemTag
$(@refs.item).removeClass() constructor: (r, o) ->
return unless v super r, o
$(@refs.item).addClass "selected"
@get("onselect")({ item: @root })
__data__: (v) -> __data__: (v) ->
return unless v return unless v
@ -51,14 +60,8 @@ class SimpleListItemTag extends ListViewItemTag
@set "selected", v.selected if v.selected @set "selected", v.selected if v.selected
@set "closable", v.closable if v.closable @set "closable", v.closable if v.closable
layout: () -> itemlayout: () ->
[{ { el: "afx-label", ref: "label" }
el: "li", ref: "item", children: [
{ el: "afx-label", ref: "label" },
{ el: "i", class: "closable", ref: "btcl" }
]
}]
class ListViewTag extends Ant.OS.GUI.BaseTag class ListViewTag extends Ant.OS.GUI.BaseTag
constructor: (r, o) -> constructor: (r, o) ->
@ -104,11 +107,11 @@ class ListViewTag extends Ant.OS.GUI.BaseTag
el[0] el[0]
.set "data", item .set "data", item
.set "oncontextmenu", (e) -> .set "oncontextmenu", (e) ->
me.iclick e me.iclick e, true
.set "ondbclick", (e) -> .set "ondbclick", (e) ->
me.idbclick e me.idbclick e, false
.set "onclick", (e) -> .set "onclick", (e) ->
me.iclick e me.iclick e, false
.set "onselect", (e) -> .set "onselect", (e) ->
me.iselect e me.iselect e
.set "onclose", (e) -> .set "onclose", (e) ->
@ -132,10 +135,10 @@ class ListViewTag extends Ant.OS.GUI.BaseTag
for item in data for item in data
@push item, false @push item, false
iclick: (e) -> iclick: (e, flag) ->
return if not e.item return if not e.item
list = @get("selectedItems") list = @get("selectedItems")
if @multiselect() and list.includes(e.item) if @multiselect() and list.includes(e.item) and not flag
list.splice(list.indexOf(e.item), 1) list.splice(list.indexOf(e.item), 1)
return e.item.set "selected", false return e.item.set "selected", false
e.item.set "selected", true e.item.set "selected", true

View File

@ -23,6 +23,57 @@ class MenuEntryTag extends Ant.OS.GUI.BaseTag
is_root: () -> is_root: () ->
return if @get "parent" then false else true return if @get "parent" then false else true
layout: () ->
[{
el: "li", ref: "container", children: [
{
el: "a", ref: "entry", children: @itemlayout()
},
{ el: "afx-menu", ref: "submenu" }
]
}]
__children__: (v) ->
me = @
$(@refs.container).removeClass("afx_submenu")
return $(@refs.submenu).hide() unless v and v.length > 0
$(@refs.container).addClass("afx_submenu")
$(@refs.submenu)
.show()
.attr("style", "")
@refs.submenu.set "parent", @
@refs.submenu.set "root", me.get("root")
@refs.submenu.set "items", v
if @is_root()
$(@refs.container).mouseleave (e) ->
$(me.refs.submenu).attr("style", "")
mount: () ->
me = @
@refs.switch.set "enable", false
$(@refs.entry).click (e) -> me.select e
submenuoff: () ->
p = @get "parent"
return $(@refs.submenu).attr("style", "") unless p
p.submenuoff()
select: (e) ->
me = @
e.item = @root
evt = { id: @aid(), data: e }
e.preventDefault()
if @is_root() and @has_children() and not @get "context"
$(@refs.submenu).show()
else
@submenuoff()
@get("onmenuselect") evt
if @get("parent")
@get("parent").get("onchildselect") evt
if @get("root")
@get("root").get("onmenuitemselect") evt
itemlayout: () ->
class SimpleMenuEntryTag extends MenuEntryTag class SimpleMenuEntryTag extends MenuEntryTag
constructor: (r, o) -> constructor: (r, o) ->
super r, o super r, o
@ -75,31 +126,6 @@ class SimpleMenuEntryTag extends MenuEntryTag
$(@refs.shortcut).show() $(@refs.shortcut).show()
$(@refs.shortcut).val v $(@refs.shortcut).val v
__children__: (v) ->
me = @
$(@refs.container).removeClass("afx_submenu")
return $(@refs.submenu).hide() unless v and v.length > 0
$(@refs.container).addClass("afx_submenu")
$(@refs.submenu)
.show()
.attr("style", "")
@refs.submenu.set "parent", @
@refs.submenu.set "root", me.get("root")
@refs.submenu.set "items", v
if @is_root()
$(@refs.container).mouseleave (e) ->
$(me.refs.submenu).attr("style", "")
mount: () ->
me = @
@refs.switch.set "enable", false
$(@refs.entry).click (e) -> me.select e
submenuoff: () ->
p = @get "parent"
return $(@refs.submenu).attr("style", "") unless p
p.submenuoff()
reset_radio: () -> reset_radio: () ->
return unless @has_children() return unless @has_children()
for v in @get "children" for v in @get "children"
@ -108,39 +134,20 @@ class SimpleMenuEntryTag extends MenuEntryTag
select: (e) -> select: (e) ->
me = @ super.select(e)
e.item = @root
evt = { id: @aid(), data: e }
e.preventDefault()
if @is_root() and @has_children() and not @get "context"
$(@refs.submenu).show()
else
@submenuoff()
if @get "switch" if @get "switch"
@set "checked", !@get "checked" @set "checked", !@get "checked"
else if @get "radio" else if @get "radio"
p = @get "parent" p = @get "parent"
p.reset_radio() if p p.reset_radio() if p
@set "checked", !@get "checked" @set "checked", !@get "checked"
@get("onmenuselect") evt
if @get("parent")
@get("parent").get("onchildselect") evt
if @get("root")
@get("root").get("onmenuitemselect") evt
layout: () -> itemlayout: () ->
[{ [
el: "li", ref: "container", children: [
{
el: "a", ref: "entry", children: [
{ el: "afx-switch", ref: "switch" }, { el: "afx-switch", ref: "switch" },
{ el: "afx-label", ref: "label" }, { el: "afx-label", ref: "label" },
{ el: "span", class: "shortcut", ref: "shortcut" } { el: "span", class: "shortcut", ref: "shortcut" }
] ]
},
{ el: "afx-menu", ref: "submenu" }
]
}]
class MenuTag extends Ant.OS.GUI.BaseTag class MenuTag extends Ant.OS.GUI.BaseTag
constructor: (r, o) -> constructor: (r, o) ->

View File

@ -0,0 +1,181 @@
class TreeViewItemPrototype extends Ant.OS.GUI.BaseTag
constructor: (r, o) ->
super r, o
@setopt "data", undefined
@setopt "nodes", []
@setopt "treeroot", undefined
@setopt "indent", 0
@setopt "toggle", false
@setopt "fetch", undefined
@setopt "open", true
@setopt "itemindex", 0
@setopt "selected", false
@setopt "treepath", @aid()
__data__: (v) ->
return unless v
@set "nodes", v.nodes if v.nodes
__selected__: (v) ->
return $(@refs.wrapper).addClass("afx_tree_item_selected") if v
$(@refs.wrapper).removeClass("afx_tree_item_selected")
__open__: (v) ->
$(@refs.toggle)
.removeClass()
return unless @is_folder()
if(v)
$(@refs.childnodes).show()
else
$(@refs.childnodes).hide()
return $(@refs.toggle).addClass "afx-tree-view-folder-open" if v
$(@refs.toggle).addClass "afx-tree-view-folder-close"
__itemindex__: (v) ->
return unless v
$(@refs.wrapper).addClass "afx_tree_item_odd" if v % 2 isnt 0
__indent__: (v) ->
return unless v
$(@refs.padding)
.css("display", "inline-block")
.css("height", "1px")
.css("padding", 0)
.css("margin", 0)
.css("background-color", "transparent")
.css("width", v * 15 + "px" )
is_folder: () ->
return @get("nodes") and @get("nodes").length > 0
__nodes__: (nodes) ->
return unless @get("nodes") and @get("nodes").length > 0
$(@refs.childnodes).empty()
$(@refs.wrapper).addClass("afx_folder_item")
root = @get("treeroot")
for v in nodes
el = $("<afx-tree-view>").appendTo @refs.childnodes
el[0].uify undefined
el[0].set "treeroot", @get("treeroot")
el[0].set "indent", (@get("indent") + 1)
root.indexcounter++
el[0].set "itemindex", root.indexcounter
el[0].set "treepath", "#{@get("treepath")}/#{el[0].aid()}"
el[0].set "data", v
mount: () ->
me = @
super.mount()
$(@refs.container)
.css "padding", 0
.css "margin", 0
.css "white-space", "nowrap"
$(@refs.itemholder)
.css "display", "inline-block"
$(@refs.wrapper)
.click (e) ->
e.item = me.root
me.get("treeroot").itemclick e, false
$(@refs.wrapper)
.dblclick (e) ->
e.item = me.root
me.get("treeroot").itemclick e, true
$(@refs.toggle)
.css "display", "inline-block"
.css "width", "15px"
.click (e) ->
me.set "open", not me.get("open")
e.preventDefault()
e.stopPropagation()
layout: () ->
[ {
el: "div", ref: "wrapper", children: [
{
el: "ul", ref: "container", children: [
{ el: "li", ref: "padding" },
{ el: "li", ref: "toggle" }
{ el: "li", ref: "itemholder", class: "itemname", children: @itemlayout() }
]
}
] },
{
el: "ul", ref: "childnodes"
}
]
itemlayout: () ->
class SimpleTreeViewItem extends TreeViewItemPrototype
constructor: (r, o) ->
super r, o
__data__: (v) ->
return unless v
super.__data__(v)
@refs.label.set "color", v.color if v.color
@refs.label.set "text", v.name if v.name
@refs.label.set "icon", v.icon if v.icon
@refs.label.set "iconclass", v.iconclass if v.iconclass
itemlayout: () ->
[{ el: "afx-label", ref: "label" }]
class TreeViewTag extends Ant.OS.GUI.BaseTag
constructor: (r, o) ->
super r, o
@setopt "itemtag", "afx-tree-view-item"
@setopt "data", undefined
@setopt "treeroot", undefined
@setopt "parent", undefined
@setopt "indent", 0
@setopt "open", true
@setopt "itemindex", 0
@setopt "ontreeselect", () ->
@setopt "ontreedbclick", () ->
@setopt "selectedItem", undefined
@setopt "treepath", @aid()
@indexcounter = 0
__selectedItem__: (v) ->
return unless v
v.set "selected", true
itemclick: (e, flag) ->
return unless e and e.item
return if e.item is @get("selectedItem") and not flag
@get("selectedItem").set "selected", false if @get("selectedItem")
@set "selectedItem", e.item
evt = { id: @aid(), data: e }
if flag
console.log "dblclick"
@get("ontreedbclick") evt
@observable.trigger "treedbclick", evt
else
@get("ontreeselect") evt
@observable.trigger "treeselect", evt
is_root: () ->
return @get("treeroot") is undefined
__data__: (v) ->
return unless v
$(@root).empty()
el = $("<#{@get "itemtag"}>").appendTo @root
el[0].uify undefined
el[0].set "treeroot", if @is_root() then @ else @get "treeroot"
el[0].set "indent", @get("indent")
el[0].set "itemindex", @get "itemindex"
el[0].set "treepath", @get("treepath")
el[0].set "data", v
el[0].set "open", @get("open")
Ant.OS.GUI.define "afx-tree-view", TreeViewTag
Ant.OS.GUI.define "afx-tree-view-item-proto", TreeViewItemPrototype
Ant.OS.GUI.define "afx-tree-view-item", SimpleTreeViewItem

View File

@ -41,8 +41,7 @@ class ShowCase extends this.OS.GUI.BaseApplication
<afx-tab-bar data-height="30" data-id="tab" /> <afx-tab-bar data-height="30" data-id="tab" />
<afx-hbox> <afx-hbox>
<afx-vbox data-width="150"> <afx-vbox data-width="150">
<div>box 2</div> <afx-tree-view data-id="tree" />
<div>box 2</div>
</afx-vbox> </afx-vbox>
<afx-resizer data-width="5" /> <afx-resizer data-width="5" />
<afx-vbox data-width="grow"> <afx-vbox data-width="grow">
@ -155,6 +154,44 @@ class ShowCase extends this.OS.GUI.BaseApplication
[{ text: "text 7" }, { text: "text 8" }, { text: "text 9" }] [{ text: "text 7" }, { text: "text 8" }, { text: "text 9" }]
] ]
tdata = {
name: 'My Tree',
nodes: [
{ name: 'hello', iconclass:'fa fa-car'},
{ name: 'wat' },
{
name: 'child folder',
nodes: [
{
name: 'child folder',
nodes: [
{ name: 'hello' },
{ name: 'wat' }
]
},
{ name: 'hello' },
{ name: 'wat' },
{
name: 'child folder',
nodes: [
{ name: 'hello' },
{ name: 'wat' }
]
}
]
}
]
}
tree = $ "[data-id='tree']", scheme[0]
tree[0].set "data", tdata
tree[0].set "ontreeselect", (e) ->
console.log e.data.item.get "treepath"
tree[0].set "ontreedbclick", (e) ->
console.log "treedbclick", e
me.subwin.observable.on "treedbclick", (e) ->
console.log "observable treedbclick", e
mnFile: () -> mnFile: () ->
#console.log file #console.log file
me = @ me = @