From d06ad1a2f1a5551a4c71de96800517de6bfaf34d Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Fri, 28 Nov 2014 17:16:18 +0300 Subject: [PATCH] tree widget, continue development --- src/dlangui/widgets/tree.d | 107 +++++++++++++++++++++++++++++++++++ src/dlangui/widgets/widget.d | 33 ++++++----- 2 files changed, 126 insertions(+), 14 deletions(-) diff --git a/src/dlangui/widgets/tree.d b/src/dlangui/widgets/tree.d index f9fdcb05..31107e34 100644 --- a/src/dlangui/widgets/tree.d +++ b/src/dlangui/widgets/tree.d @@ -4,6 +4,113 @@ import dlangui.widgets.widget; import dlangui.widgets.controls; import dlangui.widgets.scroll; import std.conv; +import std.algorithm; + +// tree widget item data container +class TreeItem { + protected TreeItem _parent; + protected string _id; + protected string _iconRes; + protected int _level; + protected UIString _text; + protected ObjectList!TreeItem _children; + protected bool _expanded; + + @property TreeItem parent() { return _parent; } + @property protected TreeItem parent(TreeItem p) { _parent = p; return this; } + @property string id() { return _id; } + @property TreeItem id(string id) { _id = id; return this; } + @property string iconRes() { return _iconRes; } + @property TreeItem iconRes(string res) { _iconRes = res; return this; } + @property int level() { return _level; } + @property protected TreeItem level(int level) { + _level = level; + for (int i = 0; i < childCount; i++) + child(i).level = _level + 1; + return this; + } + @property bool expanded() { return _expanded; } + @property protected TreeItem expanded(bool expanded) { _expanded = expanded; return this; } + bool isFullyExpanded() { + if (!_expanded) + return false; + if (_parent) + return _parent.isFullyExpanded(); + return false; + } + void expand() { + _expanded = true; + if (_parent) + _parent.expand(); + } + + /// get widget text + @property dstring text() { return _text; } + /// set text to show + @property TreeItem text(dstring s) { + _text = s; + return this; + } + /// set text to show + @property TreeItem text(UIString s) { + _text = s; + return this; + } + /// set text resource ID to show + @property TreeItem textResource(string s) { + _text = s; + return this; + } + + bool compareId(string id) { + return _id !is null && _id.equal(id); + } + + @property TreeItem topParent() { + if (!_parent) + return this; + return _parent.topParent; + } + + /// returns number of children of this widget + @property int childCount() { return _children.count; } + /// returns child by index + TreeItem child(int index) { return _children.get(index); } + /// adds child, returns added item + TreeItem addChild(TreeItem item) { + return _children.add(item).parent(this).level(_level + 1); + } + /// removes child, returns removed item + TreeItem removeChild(int index) { + TreeItem res = _children.remove(index); + if (res !is null) + res.parent = null; + return res; + } + /// removes child by ID, returns removed item + TreeItem removeChild(string ID) { + TreeItem res = null; + int index = _children.indexOf(ID); + if (index < 0) + return null; + res = _children.remove(index); + if (res !is null) + res.parent = null; + return res; + } + /// returns index of widget in child list, -1 if passed widget is not a child of this widget + int childIndex(TreeItem item) { return _children.indexOf(item); } + +} + +interface OnTreeContentChangeListener { + void onTreeContentChange(TreeItems source); +} + +class TreeItems : TreeItem { + // signal handler OnTreeContentChangeListener + Listener!OnTreeContentChangeListener listener; +} class TreeWidgetBase : ScrollWidgetBase { diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index 0d337b8f..49bb6857 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -1210,26 +1210,26 @@ class Widget { } -/// widget list holder -struct WidgetList { - protected Widget[] _list; +/// object list holder, owning its objects - on destroy of holder, all own objects will be destroyed +struct ObjectList(T) { + protected T[] _list; protected int _count; /// returns count of items @property int count() const { return _count; } /// get item by index - Widget get(int index) { + T get(int index) { assert(index >= 0 && index < _count, "child index out of range"); return _list[index]; } /// add item to list - Widget add(Widget item) { + T add(T item) { if (_list.length <= _count) // resize _list.length = _list.length < 4 ? 4 : _list.length * 2; _list[_count++] = item; return item; } /// add item to list - Widget insert(Widget item, int index = -1) { + T insert(T item, int index = -1) { if (index > _count || index < 0) index = _count; if (_list.length <= _count) // resize @@ -1241,23 +1241,25 @@ struct WidgetList { return item; } /// find child index for item, return -1 if not found - int indexOf(Widget item) { + int indexOf(T item) { for (int i = 0; i < _count; i++) if (_list[i] == item) return i; return -1; } /// find child index for item by id, return -1 if not found - int indexOf(string id) { - for (int i = 0; i < _count; i++) - if (_list[i].compareId(id)) - return i; - return -1; + static if (__traits(hasMember, T, "compareId")) { + int indexOf(string id) { + for (int i = 0; i < _count; i++) + if (_list[i].compareId(id)) + return i; + return -1; + } } /// remove item from list, return removed item - Widget remove(int index) { + T remove(int index) { assert(index >= 0 && index < _count, "child index out of range"); - Widget item = _list[index]; + T item = _list[index]; for (int i = index; i < _count - 1; i++) _list[i] = _list[i + 1]; _count--; @@ -1276,6 +1278,9 @@ struct WidgetList { } } +/// widget list holder +alias WidgetList = ObjectList!Widget; + /// base class for widgets which have children class WidgetGroup : Widget {