mirror of https://github.com/buggins/dlangui.git
ComboEdit enhancements - issue #224
This commit is contained in:
parent
c1a48eea18
commit
53e13ff706
|
|
@ -46,7 +46,7 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
layoutWidth: fill
|
layoutWidth: fill
|
||||||
CheckBox { id: cb1; text: "checkbox 1" }
|
CheckBox { id: cb1; text: "checkbox 1" }
|
||||||
CheckBox { id: cb2; text: "checkbox 2" }
|
CheckBox { id: cb2; text: "checkbox 2" }
|
||||||
ComboEdit { id: ce1; text: "some text"; }
|
ComboEdit { id: ce1; text: "some text"; minWidth: 100; items: ["Item 1", "Item 2", "Additional item"] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HorizontalLayout {
|
HorizontalLayout {
|
||||||
|
|
|
||||||
|
|
@ -192,20 +192,42 @@ struct UIStringCollection {
|
||||||
clear();
|
clear();
|
||||||
addAll(items);
|
addAll(items);
|
||||||
}
|
}
|
||||||
/** Append array of string resource IDs */
|
|
||||||
void addAll(string[] items) {
|
|
||||||
foreach (string item; items) {
|
|
||||||
add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** Assign array of unicode strings */
|
/** Assign array of unicode strings */
|
||||||
void opAssign(dstring[] items) {
|
void opAssign(dstring[] items) {
|
||||||
clear();
|
clear();
|
||||||
addAll(items);
|
addAll(items);
|
||||||
}
|
}
|
||||||
|
/** Assign array of UIString */
|
||||||
|
void opAssign(UIString[] items) {
|
||||||
|
clear();
|
||||||
|
addAll(items);
|
||||||
|
}
|
||||||
|
/** Assign array of StringListValue */
|
||||||
|
void opAssign(StringListValue[] items) {
|
||||||
|
clear();
|
||||||
|
addAll(items);
|
||||||
|
}
|
||||||
/** Append array of unicode strings */
|
/** Append array of unicode strings */
|
||||||
void addAll(dstring[] items) {
|
void addAll(dstring[] items) {
|
||||||
foreach (dstring item; items) {
|
foreach (item; items) {
|
||||||
|
add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Append array of unicode strings */
|
||||||
|
void addAll(string[] items) {
|
||||||
|
foreach (item; items) {
|
||||||
|
add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Append array of unicode strings */
|
||||||
|
void addAll(UIString[] items) {
|
||||||
|
foreach (item; items) {
|
||||||
|
add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Append array of unicode strings */
|
||||||
|
void addAll(StringListValue[] items) {
|
||||||
|
foreach (item; items) {
|
||||||
add(item);
|
add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -226,6 +248,10 @@ struct UIStringCollection {
|
||||||
s = item;
|
s = item;
|
||||||
add(s, index);
|
add(s, index);
|
||||||
}
|
}
|
||||||
|
/** Insert StringListValue.label item into specified position */
|
||||||
|
void add(StringListValue item, int index = -1) {
|
||||||
|
add(item.label, index);
|
||||||
|
}
|
||||||
/** Insert UIString item into specified position */
|
/** Insert UIString item into specified position */
|
||||||
void add(UIString item, int index = -1) {
|
void add(UIString item, int index = -1) {
|
||||||
if (index < 0 || index > _length)
|
if (index < 0 || index > _length)
|
||||||
|
|
@ -274,6 +300,43 @@ struct UIStringCollection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// string values string list adapter - each item can have optional string or integer id, and optional icon resource id
|
||||||
|
struct StringListValue {
|
||||||
|
/// integer id for item
|
||||||
|
int intId;
|
||||||
|
/// string id for item
|
||||||
|
string stringId;
|
||||||
|
/// icon resource id
|
||||||
|
string iconId;
|
||||||
|
/// label to show for item
|
||||||
|
UIString label;
|
||||||
|
|
||||||
|
this(string id, dstring name, string iconId = null) {
|
||||||
|
this.stringId = id;
|
||||||
|
this.label = name;
|
||||||
|
this.iconId = iconId;
|
||||||
|
}
|
||||||
|
this(string id, string nameResourceId, string iconId = null) {
|
||||||
|
this.stringId = id;
|
||||||
|
this.label = nameResourceId;
|
||||||
|
this.iconId = iconId;
|
||||||
|
}
|
||||||
|
this(int id, dstring name, string iconId = null) {
|
||||||
|
this.intId = id;
|
||||||
|
this.label = name;
|
||||||
|
this.iconId = iconId;
|
||||||
|
}
|
||||||
|
this(int id, string nameResourceId, string iconId = null) {
|
||||||
|
this.intId = id;
|
||||||
|
this.label = nameResourceId;
|
||||||
|
this.iconId = iconId;
|
||||||
|
}
|
||||||
|
this(dstring name, string iconId = null) {
|
||||||
|
this.label = name;
|
||||||
|
this.iconId = iconId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** UI Strings internationalization translator */
|
/** UI Strings internationalization translator */
|
||||||
class UIStringTranslator {
|
class UIStringTranslator {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,18 @@ class MLParser {
|
||||||
error("unknown double property " ~ propName);
|
error("unknown double property " ~ propName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setStringListValueProperty(string propName, StringListValue[] values) {
|
||||||
|
if (!_currentWidget.setStringListValueListProperty(propName, values)) {
|
||||||
|
UIString[] strings;
|
||||||
|
foreach(value; values)
|
||||||
|
strings ~= value.label;
|
||||||
|
if (!_currentWidget.setUIStringListProperty(propName, strings)) {
|
||||||
|
error("unknown string list property " ~ propName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void setRectProperty(string propName, Rect value) {
|
protected void setRectProperty(string propName, Rect value) {
|
||||||
if (!_currentWidget.setRectProperty(propName, value))
|
if (!_currentWidget.setRectProperty(propName, value))
|
||||||
error("unknown Rect property " ~ propName);
|
error("unknown Rect property " ~ propName);
|
||||||
|
|
@ -300,6 +312,66 @@ class MLParser {
|
||||||
setRectProperty(propName, Rect(values[0], values[1], values[2], values[3]));
|
setRectProperty(propName, Rect(values[0], values[1], values[2], values[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// something in []
|
||||||
|
protected void parseArrayProperty(string propName) {
|
||||||
|
// current token is Rect
|
||||||
|
nextToken();
|
||||||
|
skipWhitespaceAndEolsNoEof();
|
||||||
|
StringListValue[] values;
|
||||||
|
for (;;) {
|
||||||
|
if (_token.type == TokenType.squareClose)
|
||||||
|
break;
|
||||||
|
if (_token.type == TokenType.integer) {
|
||||||
|
if (_token.text.length)
|
||||||
|
error("Integer literal suffixes not allowed for [] items");
|
||||||
|
StringListValue value;
|
||||||
|
value.intId = _token.intvalue;
|
||||||
|
value.label = UIString(to!dstring(_token.intvalue));
|
||||||
|
values ~= value;
|
||||||
|
nextToken();
|
||||||
|
skipWhitespaceAndEolsNoEof();
|
||||||
|
if (_token.type == TokenType.comma || _token.type == TokenType.semicolon) {
|
||||||
|
nextToken();
|
||||||
|
skipWhitespaceAndEolsNoEof();
|
||||||
|
}
|
||||||
|
} else if (_token.type == TokenType.ident) {
|
||||||
|
string name = _token.text;
|
||||||
|
|
||||||
|
StringListValue value;
|
||||||
|
value.stringId = name;
|
||||||
|
value.label = UIString(name);
|
||||||
|
values ~= value;
|
||||||
|
|
||||||
|
nextToken();
|
||||||
|
skipWhitespaceAndEolsNoEof();
|
||||||
|
|
||||||
|
if (_token.type == TokenType.comma || _token.type == TokenType.semicolon) {
|
||||||
|
nextToken();
|
||||||
|
skipWhitespaceAndEolsNoEof();
|
||||||
|
}
|
||||||
|
} else if (_token.type == TokenType.str) {
|
||||||
|
string name = _token.text;
|
||||||
|
|
||||||
|
StringListValue value;
|
||||||
|
value.stringId = name;
|
||||||
|
value.label = UIString(name.toUTF32);
|
||||||
|
values ~= value;
|
||||||
|
|
||||||
|
nextToken();
|
||||||
|
skipWhitespaceAndEolsNoEof();
|
||||||
|
|
||||||
|
if (_token.type == TokenType.comma || _token.type == TokenType.semicolon) {
|
||||||
|
nextToken();
|
||||||
|
skipWhitespaceAndEolsNoEof();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error("invalid [] item");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
setStringListValueProperty(propName, values);
|
||||||
|
}
|
||||||
|
|
||||||
protected void parseProperty() {
|
protected void parseProperty() {
|
||||||
if (_token.type != TokenType.ident)
|
if (_token.type != TokenType.ident)
|
||||||
error("identifier expected");
|
error("identifier expected");
|
||||||
|
|
@ -323,6 +395,8 @@ class MLParser {
|
||||||
error("number expected after + and -");
|
error("number expected after + and -");
|
||||||
} else if (_token.type == TokenType.floating)
|
} else if (_token.type == TokenType.floating)
|
||||||
setFloatProperty(propName, _token.floatvalue);
|
setFloatProperty(propName, _token.floatvalue);
|
||||||
|
else if (_token.type == TokenType.squareOpen)
|
||||||
|
parseArrayProperty(propName);
|
||||||
else if (_token.type == TokenType.str)
|
else if (_token.type == TokenType.str)
|
||||||
setStringProperty(propName, _token.text);
|
setStringProperty(propName, _token.text);
|
||||||
else if (_token.type == TokenType.ident) {
|
else if (_token.type == TokenType.ident) {
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,9 @@ enum TokenType : ushort {
|
||||||
minus,
|
minus,
|
||||||
/// + operator
|
/// + operator
|
||||||
plus,
|
plus,
|
||||||
/// [
|
/// {
|
||||||
curlyOpen,
|
curlyOpen,
|
||||||
/// ]
|
/// }
|
||||||
curlyClose,
|
curlyClose,
|
||||||
/// (
|
/// (
|
||||||
open,
|
open,
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,8 @@ class ComboBoxBase : HorizontalLayout, OnClickHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showPopup() {
|
protected void showPopup() {
|
||||||
|
if (!_adapter || !_adapter.itemCount)
|
||||||
|
return; // don't show empty popup
|
||||||
_popupList = createPopup();
|
_popupList = createPopup();
|
||||||
_popup = window.showPopup(_popupList, this, PopupAlign.Below | PopupAlign.FitAnchorSize);
|
_popup = window.showPopup(_popupList, this, PopupAlign.Below | PopupAlign.FitAnchorSize);
|
||||||
_popup.flags = PopupFlags.CloseOnClickOutside;
|
_popup.flags = PopupFlags.CloseOnClickOutside;
|
||||||
|
|
@ -233,6 +235,9 @@ class ComboBox : ComboBoxBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@property void items(StringListValue[] items) {
|
@property void items(StringListValue[] items) {
|
||||||
|
if (auto a = cast(StringListAdapter)_adapter)
|
||||||
|
a.items = items;
|
||||||
|
else
|
||||||
setAdapter(new StringListAdapter(items));
|
setAdapter(new StringListAdapter(items));
|
||||||
if(items.length > 0) {
|
if(items.length > 0) {
|
||||||
selectedItemIndex = 0;
|
selectedItemIndex = 0;
|
||||||
|
|
@ -240,6 +245,15 @@ class ComboBox : ComboBoxBase {
|
||||||
requestLayout();
|
requestLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// StringListValue list values
|
||||||
|
override bool setStringListValueListProperty(string propName, StringListValue[] values) {
|
||||||
|
if (propName == "items") {
|
||||||
|
items = values;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// get selected item as text
|
/// get selected item as text
|
||||||
@property dstring selectedItem() {
|
@property dstring selectedItem() {
|
||||||
if (_selectedItemIndex < 0 || _selectedItemIndex >= _adapter.itemCount)
|
if (_selectedItemIndex < 0 || _selectedItemIndex >= _adapter.itemCount)
|
||||||
|
|
@ -348,6 +362,9 @@ class IconTextComboBox : ComboBoxBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@property void items(StringListValue[] items) {
|
@property void items(StringListValue[] items) {
|
||||||
|
if (auto a = cast(IconStringListAdapter)_adapter)
|
||||||
|
a.items = items;
|
||||||
|
else
|
||||||
setAdapter(new IconStringListAdapter(items));
|
setAdapter(new IconStringListAdapter(items));
|
||||||
if(items.length > 0) {
|
if(items.length > 0) {
|
||||||
selectedItemIndex = 0;
|
selectedItemIndex = 0;
|
||||||
|
|
@ -451,18 +468,42 @@ class ComboEdit : ComboBox {
|
||||||
/// empty parameter list constructor - for usage by factory
|
/// empty parameter list constructor - for usage by factory
|
||||||
this() {
|
this() {
|
||||||
this(null);
|
this(null);
|
||||||
|
postInit();
|
||||||
}
|
}
|
||||||
/// create with ID parameter
|
/// create with ID parameter
|
||||||
this(string ID) {
|
this(string ID) {
|
||||||
super(ID);
|
super(ID);
|
||||||
|
postInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
this(string ID, string[] items) {
|
this(string ID, string[] items) {
|
||||||
super(ID, items);
|
super(ID, items);
|
||||||
|
postInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
this(string ID, dstring[] items) {
|
this(string ID, dstring[] items) {
|
||||||
super(ID, items);
|
super(ID, items);
|
||||||
|
postInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void postInit() {
|
||||||
|
focusable = false;
|
||||||
|
clickable = false;
|
||||||
|
_edit.focusable = true;
|
||||||
|
keyEvent = delegate(Widget source, KeyEvent event) {
|
||||||
|
if (event.keyCode == KeyCode.DOWN) {
|
||||||
|
if (event.action == KeyAction.KeyDown) {
|
||||||
|
showPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _edit.onKeyEvent(event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// called to process click and notify listeners
|
||||||
|
override protected bool handleClick() {
|
||||||
|
_edit.setFocus();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property bool readOnly() {
|
@property bool readOnly() {
|
||||||
|
|
@ -484,6 +525,8 @@ class ComboEdit : ComboBox {
|
||||||
res.layoutHeight = WRAP_CONTENT;
|
res.layoutHeight = WRAP_CONTENT;
|
||||||
res.readOnly = false;
|
res.readOnly = false;
|
||||||
_edit = res;
|
_edit = res;
|
||||||
|
postInit();
|
||||||
|
//_edit.focusable = true;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,43 +177,6 @@ class WidgetListAdapter : ListAdapterBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// string values string list adapter - each item can have optional string or integer id, and optional icon resource id
|
|
||||||
struct StringListValue {
|
|
||||||
/// integer id for item
|
|
||||||
int intId;
|
|
||||||
/// string id for item
|
|
||||||
string stringId;
|
|
||||||
/// icon resource id
|
|
||||||
string iconId;
|
|
||||||
/// label to show for item
|
|
||||||
UIString label;
|
|
||||||
|
|
||||||
this(string id, dstring name, string iconId = null) {
|
|
||||||
this.stringId = id;
|
|
||||||
this.label = name;
|
|
||||||
this.iconId = iconId;
|
|
||||||
}
|
|
||||||
this(string id, string nameResourceId, string iconId = null) {
|
|
||||||
this.stringId = id;
|
|
||||||
this.label = nameResourceId;
|
|
||||||
this.iconId = iconId;
|
|
||||||
}
|
|
||||||
this(int id, dstring name, string iconId = null) {
|
|
||||||
this.intId = id;
|
|
||||||
this.label = name;
|
|
||||||
this.iconId = iconId;
|
|
||||||
}
|
|
||||||
this(int id, string nameResourceId, string iconId = null) {
|
|
||||||
this.intId = id;
|
|
||||||
this.label = nameResourceId;
|
|
||||||
this.iconId = iconId;
|
|
||||||
}
|
|
||||||
this(dstring name, string iconId = null) {
|
|
||||||
this.label = name;
|
|
||||||
this.iconId = iconId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** List adapter providing strings only. */
|
/** List adapter providing strings only. */
|
||||||
class StringListAdapterBase : ListAdapterBase {
|
class StringListAdapterBase : ListAdapterBase {
|
||||||
protected UIStringCollection _items;
|
protected UIStringCollection _items;
|
||||||
|
|
@ -340,6 +303,40 @@ class StringListAdapterBase : ListAdapterBase {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Replace items collection. */
|
||||||
|
@property StringListAdapterBase items(UIString[] values) {
|
||||||
|
_items = values;
|
||||||
|
_intIds.length = items.length;
|
||||||
|
_states.length = _items.length;
|
||||||
|
_stringIds.length = items.length;
|
||||||
|
_iconIds.length = items.length;
|
||||||
|
for (int i = 0; i < _items.length; i++) {
|
||||||
|
_intIds[i] = 0;
|
||||||
|
_stringIds[i] = null;
|
||||||
|
_iconIds[i] = null;
|
||||||
|
_states[i] = State.Enabled;
|
||||||
|
}
|
||||||
|
updateViews();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Replace items collection. */
|
||||||
|
@property StringListAdapterBase items(StringListValue[] values) {
|
||||||
|
_items = values;
|
||||||
|
_intIds.length = items.length;
|
||||||
|
_states.length = _items.length;
|
||||||
|
_stringIds.length = items.length;
|
||||||
|
_iconIds.length = items.length;
|
||||||
|
for (int i = 0; i < _items.length; i++) {
|
||||||
|
_intIds[i] = values[i].intId;
|
||||||
|
_stringIds[i] = values[i].stringId;
|
||||||
|
_iconIds[i] = values[i].iconId;
|
||||||
|
_states[i] = State.Enabled;
|
||||||
|
}
|
||||||
|
updateViews();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/// returns number of widgets in list
|
/// returns number of widgets in list
|
||||||
@property override int itemCount() const {
|
@property override int itemCount() const {
|
||||||
return _items.length;
|
return _items.length;
|
||||||
|
|
@ -1355,6 +1352,15 @@ class StringListWidget : ListWidget {
|
||||||
requestLayout();
|
requestLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// StringListValue list values
|
||||||
|
override bool setStringListValueListProperty(string propName, StringListValue[] values) {
|
||||||
|
if (propName == "items") {
|
||||||
|
items = values;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// get selected item as text
|
/// get selected item as text
|
||||||
@property dstring selectedItem() {
|
@property dstring selectedItem() {
|
||||||
if (_selectedItemIndex < 0 || _selectedItemIndex >= _adapter.itemCount)
|
if (_selectedItemIndex < 0 || _selectedItemIndex >= _adapter.itemCount)
|
||||||
|
|
|
||||||
|
|
@ -1570,6 +1570,16 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// StringListValue list values
|
||||||
|
bool setStringListValueListProperty(string propName, StringListValue[] values) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// UIString list values
|
||||||
|
bool setUIStringListProperty(string propName, UIString[] values) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// set string property value, for ML loaders
|
/// set string property value, for ML loaders
|
||||||
bool setBoolProperty(string name, bool value) {
|
bool setBoolProperty(string name, bool value) {
|
||||||
mixin(generatePropertySetters("enabled", "clickable", "checkable", "focusable", "checked", "fontItalic"));
|
mixin(generatePropertySetters("enabled", "clickable", "checkable", "focusable", "checked", "fontItalic"));
|
||||||
|
|
@ -1809,3 +1819,4 @@ string generatePropertySettersMethodOverride(string methodName, string typeName,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue