mirror of https://github.com/buggins/dlangui.git
list adapters: support adding/removing items, fix issue #80
This commit is contained in:
parent
433263133c
commit
b28a1e95b7
|
@ -467,12 +467,12 @@ extern (C) int UIAppMain(string[] args) {
|
|||
|
||||
StringListAdapter stringList = new StringListAdapter();
|
||||
WidgetListAdapter listAdapter = new WidgetListAdapter();
|
||||
listAdapter.widgets.add((new TextWidget()).text("This is a list of widgets"d).styleId("LIST_ITEM"));
|
||||
stringList.items.add("This is a list of strings from StringListAdapter"d);
|
||||
listAdapter.add((new TextWidget()).text("This is a list of widgets"d).styleId("LIST_ITEM"));
|
||||
stringList.add("This is a list of strings from StringListAdapter"d);
|
||||
for (int i = 1; i < 1000; i++) {
|
||||
dstring label = "List item "d ~ to!dstring(i);
|
||||
listAdapter.widgets.add((new TextWidget()).text("Widget list - "d ~ label).styleId("LIST_ITEM"));
|
||||
stringList.items.add("Simple string - "d ~ label);
|
||||
listAdapter.add((new TextWidget()).text("Widget list - "d ~ label).styleId("LIST_ITEM"));
|
||||
stringList.add("Simple string - "d ~ label);
|
||||
}
|
||||
list.ownAdapter = listAdapter;
|
||||
listAdapter.resetItemState(0, State.Enabled);
|
||||
|
@ -492,6 +492,19 @@ extern (C) int UIAppMain(string[] args) {
|
|||
list2.selectItem(0);
|
||||
longLists.addChild(list2);
|
||||
|
||||
VerticalLayout itemedit = new VerticalLayout();
|
||||
itemedit.addChild(new TextWidget(null, "New item text:"d));
|
||||
EditLine itemtext = new EditLine(null, "Text for new item"d);
|
||||
itemedit.addChild(itemtext);
|
||||
Button btn = new Button(null, "Add item"d);
|
||||
itemedit.addChild(btn);
|
||||
longLists.addChild(itemedit);
|
||||
btn.onClickListener = delegate(Widget src)
|
||||
{
|
||||
stringList.add(itemtext.text);
|
||||
listAdapter.add((new TextWidget()).text(itemtext.text).styleId("LIST_ITEM"));
|
||||
return true;
|
||||
};
|
||||
tabs.addTab(longLists, "TAB_LONG_LIST"c);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
// Written in the D programming language.
|
||||
|
||||
/**
|
||||
|
||||
This module implements object collection.
|
||||
|
||||
Wrapper around array of objects, providing a set of useful operations, and handling of object ownership.
|
||||
|
||||
Optionally can be owner of its items if instanciated with ownItems=true - will destroy removed items.
|
||||
|
||||
|
||||
Synopsis:
|
||||
|
||||
----
|
||||
import dlangui.core.collections;
|
||||
|
||||
// add
|
||||
Collection!Widget widgets;
|
||||
widgets ~= new Widget("id1");
|
||||
widgets ~= new Widget("id2");
|
||||
Widget w3 = new Widget("id3");
|
||||
widgets ~= w3;
|
||||
|
||||
// remove by index
|
||||
widgets.remove(1);
|
||||
|
||||
// foreach
|
||||
foreach(w; widgets)
|
||||
writeln("widget: ", w.id);
|
||||
|
||||
// remove by value
|
||||
widgets -= w3;
|
||||
writeln(widgets[0].id);
|
||||
----
|
||||
|
||||
|
||||
Copyright: Vadim Lopatin, 2014
|
||||
License: Boost License 1.0
|
||||
Authors: Vadim Lopatin, coolreader.org@gmail.com
|
||||
*/
|
||||
// Written in the D programming language.
|
||||
|
||||
/**
|
||||
|
||||
This module implements object collection.
|
||||
|
||||
Wrapper around array of objects, providing a set of useful operations, and handling of object ownership.
|
||||
|
||||
Optionally can be owner of its items if instanciated with ownItems=true - will destroy removed items.
|
||||
|
||||
|
||||
Synopsis:
|
||||
|
||||
----
|
||||
import dlangui.core.collections;
|
||||
|
||||
// add
|
||||
Collection!Widget widgets;
|
||||
widgets ~= new Widget("id1");
|
||||
widgets ~= new Widget("id2");
|
||||
Widget w3 = new Widget("id3");
|
||||
widgets ~= w3;
|
||||
|
||||
// remove by index
|
||||
widgets.remove(1);
|
||||
|
||||
// foreach
|
||||
foreach(w; widgets)
|
||||
writeln("widget: ", w.id);
|
||||
|
||||
// remove by value
|
||||
widgets -= w3;
|
||||
writeln(widgets[0].id);
|
||||
----
|
||||
|
||||
|
||||
Copyright: Vadim Lopatin, 2014
|
||||
License: Boost License 1.0
|
||||
Authors: Vadim Lopatin, coolreader.org@gmail.com
|
||||
*/
|
||||
module dlangui.core.collections;
|
||||
|
||||
import std.algorithm;
|
||||
|
@ -70,10 +70,10 @@ struct Collection(T, bool ownItems = false) {
|
|||
// shrink
|
||||
static if (is(T == class) || is(T == struct)) {
|
||||
// clear items
|
||||
for (size_t i = newSize; i < _len; i++) {
|
||||
static if (ownItems)
|
||||
for (size_t i = newSize; i < _len; i++) {
|
||||
static if (ownItems)
|
||||
destroy(_items[i]);
|
||||
_items[i] = T.init;
|
||||
_items[i] = T.init;
|
||||
}
|
||||
}
|
||||
} else if (newSize > _len) {
|
||||
|
@ -104,11 +104,11 @@ struct Collection(T, bool ownItems = false) {
|
|||
}
|
||||
_items[index] = item;
|
||||
_len++;
|
||||
}
|
||||
/// add all items from other collection
|
||||
void addAll(ref Collection!(T, ownItems) v) {
|
||||
for (int i = 0; i < v.length; i++)
|
||||
add(v[i]);
|
||||
}
|
||||
/// add all items from other collection
|
||||
void addAll(ref Collection!(T, ownItems) v) {
|
||||
for (int i = 0; i < v.length; i++)
|
||||
add(v[i]);
|
||||
}
|
||||
/// support for appending (~=, +=) and removing by value (-=)
|
||||
ref Collection opOpAssign(string op)(T item) {
|
||||
|
@ -146,8 +146,8 @@ struct Collection(T, bool ownItems = false) {
|
|||
size_t index = indexOf(value);
|
||||
if (index == size_t.max)
|
||||
return false;
|
||||
T res = remove(index);
|
||||
static if (ownItems)
|
||||
T res = remove(index);
|
||||
static if (ownItems)
|
||||
destroy(res);
|
||||
return true;
|
||||
}
|
||||
|
@ -165,10 +165,10 @@ struct Collection(T, bool ownItems = false) {
|
|||
void clear() {
|
||||
static if (is(T == class) || is(T == struct)) {
|
||||
/// clear references
|
||||
for(size_t i = 0; i < _len; i++) {
|
||||
static if (ownItems)
|
||||
for(size_t i = 0; i < _len; i++) {
|
||||
static if (ownItems)
|
||||
destroy(_items[i]);
|
||||
_items[i] = T.init;
|
||||
_items[i] = T.init;
|
||||
}
|
||||
}
|
||||
_len = 0;
|
||||
|
@ -236,98 +236,103 @@ struct Collection(T, bool ownItems = false) {
|
|||
}
|
||||
|
||||
|
||||
/** 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 */
|
||||
T get(int index) {
|
||||
assert(index >= 0 && index < _count, "child index out of range");
|
||||
return _list[index];
|
||||
}
|
||||
/// get item by index
|
||||
T opIndex(int index) {
|
||||
return get(index);
|
||||
}
|
||||
/** add item to list */
|
||||
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 */
|
||||
T insert(T item, int index = -1) {
|
||||
if (index > _count || index < 0)
|
||||
index = _count;
|
||||
if (_list.length <= _count) // resize
|
||||
_list.length = _list.length < 4 ? 4 : _list.length * 2;
|
||||
for (int i = _count; i > index; i--)
|
||||
_list[i] = _list[i - 1];
|
||||
_list[index] = item;
|
||||
_count++;
|
||||
return item;
|
||||
}
|
||||
/** find child index for item, return -1 if not found */
|
||||
int indexOf(T item) {
|
||||
if (item is null)
|
||||
return -1;
|
||||
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 */
|
||||
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 */
|
||||
T remove(int index) {
|
||||
assert(index >= 0 && index < _count, "child index out of range");
|
||||
T item = _list[index];
|
||||
for (int i = index; i < _count - 1; i++)
|
||||
_list[i] = _list[i + 1];
|
||||
_count--;
|
||||
return item;
|
||||
}
|
||||
/** Replace item with another value, destroy old value. */
|
||||
void replace(T item, int index) {
|
||||
T old = _list[index];
|
||||
_list[index] = item;
|
||||
destroy(old);
|
||||
}
|
||||
/** Replace item with another value, destroy old value. */
|
||||
void replace(T newItem, T oldItem) {
|
||||
int idx = indexOf(oldItem);
|
||||
if (newItem is null) {
|
||||
if (idx >= 0) {
|
||||
T item = remove(idx);
|
||||
destroy(item);
|
||||
}
|
||||
} else {
|
||||
if (idx >= 0)
|
||||
replace(newItem, idx);
|
||||
else
|
||||
add(newItem);
|
||||
}
|
||||
}
|
||||
/** remove and destroy all items */
|
||||
void clear() {
|
||||
for (int i = 0; i < _count; i++) {
|
||||
destroy(_list[i]);
|
||||
_list[i] = null;
|
||||
}
|
||||
_count = 0;
|
||||
}
|
||||
~this() {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
/** 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 */
|
||||
T get(int index) {
|
||||
assert(index >= 0 && index < _count, "child index out of range");
|
||||
return _list[index];
|
||||
}
|
||||
/** get const item by index */
|
||||
const(T) get(int index) const {
|
||||
assert(index >= 0 && index < _count, "child index out of range");
|
||||
return _list[index];
|
||||
}
|
||||
/// get item by index
|
||||
T opIndex(int index) {
|
||||
return get(index);
|
||||
}
|
||||
/** add item to list */
|
||||
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 */
|
||||
T insert(T item, int index = -1) {
|
||||
if (index > _count || index < 0)
|
||||
index = _count;
|
||||
if (_list.length <= _count) // resize
|
||||
_list.length = _list.length < 4 ? 4 : _list.length * 2;
|
||||
for (int i = _count; i > index; i--)
|
||||
_list[i] = _list[i - 1];
|
||||
_list[index] = item;
|
||||
_count++;
|
||||
return item;
|
||||
}
|
||||
/** find child index for item, return -1 if not found */
|
||||
int indexOf(T item) {
|
||||
if (item is null)
|
||||
return -1;
|
||||
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 */
|
||||
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 */
|
||||
T remove(int index) {
|
||||
assert(index >= 0 && index < _count, "child index out of range");
|
||||
T item = _list[index];
|
||||
for (int i = index; i < _count - 1; i++)
|
||||
_list[i] = _list[i + 1];
|
||||
_count--;
|
||||
return item;
|
||||
}
|
||||
/** Replace item with another value, destroy old value. */
|
||||
void replace(T item, int index) {
|
||||
T old = _list[index];
|
||||
_list[index] = item;
|
||||
destroy(old);
|
||||
}
|
||||
/** Replace item with another value, destroy old value. */
|
||||
void replace(T newItem, T oldItem) {
|
||||
int idx = indexOf(oldItem);
|
||||
if (newItem is null) {
|
||||
if (idx >= 0) {
|
||||
T item = remove(idx);
|
||||
destroy(item);
|
||||
}
|
||||
} else {
|
||||
if (idx >= 0)
|
||||
replace(newItem, idx);
|
||||
else
|
||||
add(newItem);
|
||||
}
|
||||
}
|
||||
/** remove and destroy all items */
|
||||
void clear() {
|
||||
for (int i = 0; i < _count; i++) {
|
||||
destroy(_list[i]);
|
||||
_list[i] = null;
|
||||
}
|
||||
_count = 0;
|
||||
}
|
||||
~this() {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ struct UIStringCollection {
|
|||
private int _length;
|
||||
|
||||
/** Returns number of items */
|
||||
@property int length() { return _length; }
|
||||
@property int length() const { return _length; }
|
||||
/** Slice */
|
||||
UIString[] opIndex() {
|
||||
return _items[0 .. _length];
|
||||
|
@ -160,7 +160,7 @@ struct UIStringCollection {
|
|||
return _items[start .. end];
|
||||
}
|
||||
/** Read item by index */
|
||||
UIString opIndex(size_t index) {
|
||||
UIString opIndex(size_t index) const {
|
||||
return _items[index];
|
||||
}
|
||||
/** Modify item by index */
|
||||
|
@ -169,7 +169,7 @@ struct UIStringCollection {
|
|||
return _items[index];
|
||||
}
|
||||
/** Return unicode string for item by index */
|
||||
dstring get(size_t index) {
|
||||
dstring get(size_t index) const {
|
||||
return _items[index].value;
|
||||
}
|
||||
/** Assign UIStringCollection */
|
||||
|
@ -247,7 +247,7 @@ struct UIStringCollection {
|
|||
_length--;
|
||||
}
|
||||
/** Return index of first item with specified text or -1 if not found. */
|
||||
int indexOf(dstring str) {
|
||||
int indexOf(dstring str) const {
|
||||
for (int i = 0; i < _length; i++) {
|
||||
if (_items[i].value.equal(str))
|
||||
return i;
|
||||
|
@ -255,7 +255,7 @@ struct UIStringCollection {
|
|||
return -1;
|
||||
}
|
||||
/** Return index of first item with specified string resource id or -1 if not found. */
|
||||
int indexOf(string strId) {
|
||||
int indexOf(string strId) const {
|
||||
for (int i = 0; i < _length; i++) {
|
||||
if (_items[i].id.equal(strId))
|
||||
return i;
|
||||
|
@ -263,7 +263,7 @@ struct UIStringCollection {
|
|||
return -1;
|
||||
}
|
||||
/** Return index of first item with specified string or -1 if not found. */
|
||||
int indexOf(UIString str) {
|
||||
int indexOf(UIString str) const {
|
||||
if (str.id !is null)
|
||||
return indexOf(str.id);
|
||||
return indexOf(str.value);
|
||||
|
|
|
@ -249,7 +249,7 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
|||
btn.orientation = Orientation.Vertical;
|
||||
btn.styleId = STYLE_TRANSPARENT_BUTTON_BACKGROUND;
|
||||
btn.focusable = false;
|
||||
adapter.widgets.add(btn);
|
||||
adapter.add(btn);
|
||||
}
|
||||
res.ownAdapter = adapter;
|
||||
res.layoutWidth(WRAP_CONTENT).layoutHeight(FILL_PARENT).layoutWeight(0);
|
||||
|
|
|
@ -22,32 +22,106 @@ import dlangui.widgets.widget;
|
|||
import dlangui.widgets.controls;
|
||||
import dlangui.core.signals;
|
||||
|
||||
/** interface - slot for onAdapterChangeListener */
|
||||
interface OnAdapterChangeHandler {
|
||||
void onAdapterChange(ListAdapter source);
|
||||
}
|
||||
|
||||
|
||||
/// list widget adapter provides items for list widgets
|
||||
interface ListAdapter {
|
||||
/// returns number of widgets in list
|
||||
@property int itemCount();
|
||||
@property int itemCount() const;
|
||||
/// return list item widget by item index
|
||||
Widget itemWidget(int index);
|
||||
/// return list item's state flags
|
||||
uint itemState(int index);
|
||||
uint itemState(int index) const;
|
||||
/// set one or more list item's state flags, returns updated state
|
||||
uint setItemState(int index, uint flags);
|
||||
/// reset one or more list item's state flags, returns updated state
|
||||
uint resetItemState(int index, uint flags);
|
||||
/// returns integer item id by index (if supported)
|
||||
int itemId(int index);
|
||||
int itemId(int index) const;
|
||||
/// returns string item id by index (if supported)
|
||||
string itemStringId(int index);
|
||||
string itemStringId(int index) const;
|
||||
|
||||
/// remove all items
|
||||
void clear();
|
||||
|
||||
/// connect adapter change handler
|
||||
ListAdapter connect(OnAdapterChangeHandler handler);
|
||||
/// disconnect adapter change handler
|
||||
ListAdapter disconnect(OnAdapterChangeHandler handler);
|
||||
}
|
||||
|
||||
/// List adapter for simple list of widget instances
|
||||
class WidgetListAdapter : ListAdapter {
|
||||
class ListAdapterBase : ListAdapter {
|
||||
/** Handle items change */
|
||||
protected Signal!OnAdapterChangeHandler onAdapterChangeListener;
|
||||
|
||||
/// connect adapter change handler
|
||||
override ListAdapter connect(OnAdapterChangeHandler handler) {
|
||||
onAdapterChangeListener.connect(handler);
|
||||
return this;
|
||||
}
|
||||
/// disconnect adapter change handler
|
||||
override ListAdapter disconnect(OnAdapterChangeHandler handler) {
|
||||
onAdapterChangeListener.disconnect(handler);
|
||||
return this;
|
||||
}
|
||||
/// returns integer item id by index (if supported)
|
||||
override int itemId(int index) const {
|
||||
return 0;
|
||||
}
|
||||
/// returns string item id by index (if supported)
|
||||
override string itemStringId(int index) const {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// returns number of widgets in list
|
||||
override @property int itemCount() const {
|
||||
// override it
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// return list item widget by item index
|
||||
override Widget itemWidget(int index) {
|
||||
// override it
|
||||
return null;
|
||||
}
|
||||
|
||||
/// return list item's state flags
|
||||
override uint itemState(int index) const {
|
||||
// override it
|
||||
return State.Enabled;
|
||||
}
|
||||
/// set one or more list item's state flags, returns updated state
|
||||
override uint setItemState(int index, uint flags) {
|
||||
return 0;
|
||||
}
|
||||
/// reset one or more list item's state flags, returns updated state
|
||||
override uint resetItemState(int index, uint flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// remove all items
|
||||
override void clear() {
|
||||
}
|
||||
|
||||
/// notify listeners about list items changes
|
||||
void updateViews() {
|
||||
if (onAdapterChangeListener.assigned)
|
||||
onAdapterChangeListener.emit(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// List adapter for simple list of widget instances
|
||||
class WidgetListAdapter : ListAdapterBase {
|
||||
private WidgetList _widgets;
|
||||
/// list of widgets to display
|
||||
@property ref WidgetList widgets() { return _widgets; }
|
||||
@property ref const(WidgetList) widgets() { return _widgets; }
|
||||
/// returns number of widgets in list
|
||||
@property override int itemCount() {
|
||||
@property override int itemCount() const {
|
||||
return _widgets.count;
|
||||
}
|
||||
/// return list item widget by item index
|
||||
|
@ -55,7 +129,7 @@ class WidgetListAdapter : ListAdapter {
|
|||
return _widgets.get(index);
|
||||
}
|
||||
/// return list item's state flags
|
||||
override uint itemState(int index) {
|
||||
override uint itemState(int index) const {
|
||||
return _widgets.get(index).state;
|
||||
}
|
||||
/// set one or more list item's state flags, returns updated state
|
||||
|
@ -66,13 +140,23 @@ class WidgetListAdapter : ListAdapter {
|
|||
override uint resetItemState(int index, uint flags) {
|
||||
return _widgets.get(index).resetState(flags).state;
|
||||
}
|
||||
/// returns integer item id by index (if supported)
|
||||
override int itemId(int index) {
|
||||
return 0;
|
||||
/// add item
|
||||
WidgetListAdapter add(Widget item, int index = -1) {
|
||||
_widgets.insert(item, index);
|
||||
updateViews();
|
||||
return this;
|
||||
}
|
||||
/// returns string item id by index (if supported)
|
||||
override string itemStringId(int index) {
|
||||
return null;
|
||||
/// remove item
|
||||
WidgetListAdapter remove(int index) {
|
||||
auto item = _widgets.remove(index);
|
||||
destroy(item);
|
||||
updateViews();
|
||||
return this;
|
||||
}
|
||||
/// remove all items
|
||||
override void clear() {
|
||||
_widgets.clear();
|
||||
updateViews();
|
||||
}
|
||||
~this() {
|
||||
//Log.d("Destroying WidgetListAdapter");
|
||||
|
@ -104,7 +188,7 @@ struct StringListValue {
|
|||
|
||||
|
||||
/** List adapter providing strings only. */
|
||||
class StringListAdapter : ListAdapter {
|
||||
class StringListAdapter : ListAdapterBase {
|
||||
protected UIStringCollection _items;
|
||||
protected uint[] _states;
|
||||
protected int[] _intIds;
|
||||
|
@ -148,21 +232,88 @@ class StringListAdapter : ListAdapter {
|
|||
updateStatesLength();
|
||||
}
|
||||
|
||||
/// remove all items
|
||||
override void clear() {
|
||||
_items.clear();
|
||||
updateStatesLength();
|
||||
updateViews();
|
||||
}
|
||||
|
||||
/// remove item by index
|
||||
StringListAdapter remove(int index) {
|
||||
if (index < 0 || index >= _items.length)
|
||||
return this;
|
||||
for (int i = 0; i < _items.length - 1; i++) {
|
||||
_intIds[i] = _intIds[i + 1];
|
||||
_stringIds[i] = _stringIds[i + 1];
|
||||
_states[i] = _states[i + 1];
|
||||
}
|
||||
_items.remove(index);
|
||||
_intIds.length = items.length;
|
||||
_states.length = _items.length;
|
||||
_stringIds.length = items.length;
|
||||
updateViews();
|
||||
return this;
|
||||
}
|
||||
|
||||
/// add new item
|
||||
StringListAdapter add(UIString item, int index = -1) {
|
||||
if (index < 0 || index > _items.length)
|
||||
index = _items.length;
|
||||
_items.add(item, index);
|
||||
_intIds.length = items.length;
|
||||
_states.length = _items.length;
|
||||
_stringIds.length = items.length;
|
||||
for (int i = _items.length - 1; i > index; i--) {
|
||||
_intIds[i] = _intIds[i - 1];
|
||||
_stringIds[i] = _stringIds[i - 1];
|
||||
_states[i] = _states[i - 1];
|
||||
}
|
||||
_intIds[index] = 0;
|
||||
_stringIds[index] = null;
|
||||
_states[index] = State.Enabled;
|
||||
updateViews();
|
||||
return this;
|
||||
}
|
||||
/// add new string resource item
|
||||
StringListAdapter add(string item, int index = -1) {
|
||||
return add(UIString(item), index);
|
||||
}
|
||||
/// add new raw dstring item
|
||||
StringListAdapter add(dstring item, int index = -1) {
|
||||
return add(UIString(item), index);
|
||||
}
|
||||
|
||||
/** Access to items collection. */
|
||||
@property ref UIStringCollection items() { return _items; }
|
||||
@property ref const(UIStringCollection) items() { return _items; }
|
||||
|
||||
/** Replace items collection. */
|
||||
@property StringListAdapter items(dstring[] values) {
|
||||
_items = values;
|
||||
_intIds.length = items.length;
|
||||
_states.length = _items.length;
|
||||
_stringIds.length = items.length;
|
||||
for (int i = 0; i < _items.length; i++) {
|
||||
_intIds[i] = 0;
|
||||
_stringIds[i] = null;
|
||||
_states[i] = State.Enabled;
|
||||
}
|
||||
updateViews();
|
||||
return this;
|
||||
}
|
||||
|
||||
/// returns number of widgets in list
|
||||
@property override int itemCount() {
|
||||
@property override int itemCount() const {
|
||||
return _items.length;
|
||||
}
|
||||
|
||||
/// returns integer item id by index (if supported)
|
||||
override int itemId(int index) {
|
||||
override int itemId(int index) const {
|
||||
return index >= 0 && index < _intIds.length ? _intIds[index] : 0;
|
||||
}
|
||||
|
||||
/// returns string item id by index (if supported)
|
||||
override string itemStringId(int index) {
|
||||
override string itemStringId(int index) const {
|
||||
return index >= 0 && index < _stringIds.length ? _stringIds[index] : null;
|
||||
}
|
||||
|
||||
|
@ -197,8 +348,9 @@ class StringListAdapter : ListAdapter {
|
|||
}
|
||||
|
||||
/// return list item's state flags
|
||||
override uint itemState(int index) {
|
||||
updateStatesLength();
|
||||
override uint itemState(int index) const {
|
||||
if (index < 0 || index >= _items.length)
|
||||
return 0;
|
||||
return _states[index];
|
||||
}
|
||||
|
||||
|
@ -238,7 +390,7 @@ interface OnItemClickHandler {
|
|||
|
||||
|
||||
/** List widget - shows content as hori*/
|
||||
class ListWidget : WidgetGroup, OnScrollHandler {
|
||||
class ListWidget : WidgetGroup, OnScrollHandler, OnAdapterChangeHandler {
|
||||
|
||||
/** Handle selection change. */
|
||||
Signal!OnItemSelectedHandler onItemSelectedListener;
|
||||
|
@ -326,20 +478,32 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
@property ListAdapter adapter() { return _adapter; }
|
||||
/// set adapter
|
||||
@property ListWidget adapter(ListAdapter adapter) {
|
||||
if (_adapter is adapter)
|
||||
return this; // no changes
|
||||
if (_adapter)
|
||||
_adapter.disconnect(this);
|
||||
if (_adapter !is null && _ownAdapter)
|
||||
destroy(_adapter);
|
||||
_adapter = adapter;
|
||||
if (_adapter)
|
||||
_adapter.connect(this);
|
||||
_ownAdapter = false;
|
||||
onAdapterChanged();
|
||||
onAdapterChange(_adapter);
|
||||
return this;
|
||||
}
|
||||
/// set adapter, which will be owned by list (destroy will be called for adapter on widget destroy)
|
||||
@property ListWidget ownAdapter(ListAdapter adapter) {
|
||||
if (_adapter is adapter)
|
||||
return this; // no changes
|
||||
if (_adapter)
|
||||
_adapter.disconnect(this);
|
||||
if (_adapter !is null && _ownAdapter)
|
||||
destroy(_adapter);
|
||||
_adapter = adapter;
|
||||
if (_adapter)
|
||||
_adapter.connect(this);
|
||||
_ownAdapter = true;
|
||||
onAdapterChanged();
|
||||
onAdapterChange(_adapter);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -364,10 +528,6 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
return false;
|
||||
}
|
||||
|
||||
void onAdapterChanged() {
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
/// empty parameter list constructor - for usage by factory
|
||||
this() {
|
||||
this(null);
|
||||
|
@ -399,6 +559,11 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/// item list is changed
|
||||
override void onAdapterChange(ListAdapter source) {
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
/// override to handle change of selection
|
||||
protected void selectionChanged(int index, int previouslySelectedItem = -1) {
|
||||
if (onItemSelectedListener.assigned)
|
||||
|
@ -555,6 +720,8 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
}
|
||||
|
||||
~this() {
|
||||
if (_adapter)
|
||||
_adapter.disconnect(this);
|
||||
//Log.d("Destroying List ", _id);
|
||||
if (_adapter !is null && _ownAdapter)
|
||||
destroy(_adapter);
|
||||
|
|
|
@ -438,7 +438,7 @@ class MenuWidgetBase : ListWidget {
|
|||
if (orientation == Orientation.Horizontal)
|
||||
widget.styleId = STYLE_MAIN_MENU_ITEM;
|
||||
widget.parent = this;
|
||||
adapter.widgets.add(widget);
|
||||
adapter.add(widget);
|
||||
}
|
||||
ownAdapter = adapter;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue