mirror of https://github.com/buggins/dlangui.git
fix lists
This commit is contained in:
parent
716027aab4
commit
dd687b4433
|
@ -139,6 +139,11 @@ extern (C) int UIAppMain(string[] args) {
|
|||
for (int i = 0; i < 1000; i++)
|
||||
listAdapter.widgets.add((new TextWidget()).text("List item "d ~ to!dstring(i)).styleId("LIST_ITEM"));
|
||||
list.ownAdapter = listAdapter;
|
||||
listAdapter.resetItemState(5, State.Enabled);
|
||||
listAdapter.resetItemState(7, State.Enabled);
|
||||
listAdapter.resetItemState(12, State.Enabled);
|
||||
assert(list.itemEnabled(5) == false);
|
||||
assert(list.itemEnabled(6) == true);
|
||||
list.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||
tabs.addTab(list, "Long List"d);
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ wstring fromWStringz(const(wchar[]) s) {
|
|||
/// widget state flags - bits
|
||||
enum State : uint {
|
||||
/// state not specified / normal
|
||||
Normal = 0,
|
||||
Normal = 4, // Normal is Enabled
|
||||
Pressed = 1,
|
||||
Focused = 2,
|
||||
Enabled = 4,
|
||||
|
|
|
@ -92,6 +92,8 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
|
||||
/// returns rectangle for item (not scrolled, first item starts at 0,0)
|
||||
Rect itemRectNoScroll(int index) {
|
||||
if (index < 0 || index >= _itemRects.length)
|
||||
return Rect.init;
|
||||
Rect res;
|
||||
res = _itemRects[index];
|
||||
return res;
|
||||
|
@ -99,6 +101,8 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
|
||||
/// returns rectangle for item (scrolled)
|
||||
Rect itemRect(int index) {
|
||||
if (index < 0 || index >= _itemRects.length)
|
||||
return Rect.init;
|
||||
Rect res = itemRectNoScroll(index);
|
||||
if (_orientation == Orientation.Horizontal) {
|
||||
res.left -= _scrollPosition;
|
||||
|
@ -154,6 +158,13 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
return null;
|
||||
}
|
||||
|
||||
/// returns true if item with corresponding index is enabled
|
||||
bool itemEnabled(int index) {
|
||||
if (_adapter !is null && index >= 0 && index < itemCount)
|
||||
return (_adapter.itemState(index) & State.Enabled) != 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void onAdapterChanged() {
|
||||
requestLayout();
|
||||
}
|
||||
|
@ -243,32 +254,44 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
}
|
||||
|
||||
/// move selection
|
||||
void moveSelection(int direction, bool wrapAround = true) {
|
||||
bool moveSelection(int direction, bool wrapAround = true) {
|
||||
if (itemCount <= 0)
|
||||
return;
|
||||
if (_selectedItemIndex < 0) {
|
||||
// no previous selection
|
||||
if (direction > 0)
|
||||
selectItem(wrapAround ? 0 : itemCount - 1);
|
||||
else
|
||||
selectItem(wrapAround ? itemCount - 1 : 0);
|
||||
return;
|
||||
return false;
|
||||
int maxAttempts = itemCount - 1;
|
||||
int index = _selectedItemIndex;
|
||||
for (int i = 0; i < maxAttempts; i++) {
|
||||
int newIndex = 0;
|
||||
if (index < 0) {
|
||||
// no previous selection
|
||||
if (direction > 0)
|
||||
newIndex = wrapAround ? 0 : itemCount - 1;
|
||||
else
|
||||
newIndex = wrapAround ? itemCount - 1 : 0;
|
||||
} else {
|
||||
// step
|
||||
newIndex = index + direction;
|
||||
}
|
||||
if (newIndex < 0)
|
||||
newIndex = wrapAround ? itemCount - 1 : 0;
|
||||
else if (newIndex >= itemCount)
|
||||
newIndex = wrapAround ? 0 : itemCount - 1;
|
||||
if (newIndex != index) {
|
||||
if (selectItem(newIndex))
|
||||
return true;
|
||||
index = newIndex;
|
||||
}
|
||||
}
|
||||
int newIndex = _selectedItemIndex + direction;
|
||||
if (newIndex < 0)
|
||||
newIndex = wrapAround ? itemCount - 1 : 0;
|
||||
else if (newIndex >= itemCount)
|
||||
newIndex = wrapAround ? 0 : itemCount - 1;
|
||||
if (newIndex != _selectedItemIndex)
|
||||
selectItem(newIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void selectItem(int index) {
|
||||
protected bool selectItem(int index) {
|
||||
if (_selectedItemIndex == index) {
|
||||
updateSelectedItemFocus();
|
||||
makeSelectionVisible();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (index != -1 && !itemEnabled(index))
|
||||
return false;
|
||||
if (_selectedItemIndex != -1) {
|
||||
_adapter.resetItemState(_selectedItemIndex, State.Selected | State.Focused);
|
||||
invalidate();
|
||||
|
@ -279,6 +302,7 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
_adapter.setItemState(_selectedItemIndex, State.Selected | (state & State.Focused));
|
||||
invalidate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
~this() {
|
||||
|
@ -567,6 +591,17 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
moveSelection(navigationDelta);
|
||||
return true;
|
||||
}
|
||||
if (event.action == KeyAction.KeyDown) {
|
||||
if (event.keyCode == KeyCode.HOME) {
|
||||
// select first item on HOME key
|
||||
selectItem(0);
|
||||
return true;
|
||||
} else if (event.keyCode == KeyCode.END) {
|
||||
// select last item on END key
|
||||
selectItem(itemCount - 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
//if (_selectedItemIndex != -1 && event.action == KeyAction.KeyUp && (event.keyCode == KeyCode.SPACE || event.keyCode == KeyCode.RETURN)) {
|
||||
// itemClicked(_selectedItemIndex);
|
||||
|
@ -624,19 +659,23 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
itemrc.bottom += rc.top - scrollOffset.y;
|
||||
if (itemrc.isPointInside(Point(event.x, event.y))) {
|
||||
if ((event.flags & (MouseFlag.LButton || MouseFlag.RButton)) || _selectOnHover) {
|
||||
if (_selectedItemIndex != i) {
|
||||
if (_selectedItemIndex != i && itemEnabled(i)) {
|
||||
int prevSelection = _selectedItemIndex;
|
||||
selectItem(i);
|
||||
setHoverItem(-1);
|
||||
selectionChanged(_selectedItemIndex, prevSelection);
|
||||
}
|
||||
} else
|
||||
setHoverItem(i);
|
||||
} else {
|
||||
if (itemEnabled(i))
|
||||
setHoverItem(i);
|
||||
}
|
||||
if ((event.button == MouseFlag.LButton || event.button == MouseFlag.RButton)) {
|
||||
if ((_clickOnButtonDown && event.action == MouseAction.ButtonDown) || (!_clickOnButtonDown && event.action == MouseAction.ButtonUp)) {
|
||||
itemClicked(i);
|
||||
if (_clickOnButtonDown)
|
||||
event.doNotTrackButtonDown = true;
|
||||
if (itemEnabled(i)) {
|
||||
itemClicked(i);
|
||||
if (_clickOnButtonDown)
|
||||
event.doNotTrackButtonDown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -479,7 +479,7 @@ class Style {
|
|||
|
||||
/// find substyle based on widget state (e.g. focused, pressed, ...)
|
||||
const(Style) forState(uint state) const {
|
||||
if (state == 0)
|
||||
if (state == State.Normal)
|
||||
return this;
|
||||
//Log.d("forState ", state, " styleId=", _id, " substates=", _substates.length);
|
||||
if (parentStyle !is null && _substates.length == 0 && parentStyle._substates.length > 0) //id is null &&
|
||||
|
@ -676,6 +676,7 @@ Theme createDefaultTheme() {
|
|||
|
||||
Style listItem = res.createSubstyle("LIST_ITEM");
|
||||
listItem.createState(State.Selected, State.Selected).backgroundColor(0xC04040FF).textColor(0x000000);
|
||||
listItem.createState(State.Enabled, 0).textColor(0x80000000); // half transparent text for disabled item
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ class Widget {
|
|||
/// accessor to style - by lookup in theme by styleId (if style id is not set, theme base style will be used).
|
||||
protected @property const (Style) style(uint stateFlags) const {
|
||||
const (Style) normalStyle = style();
|
||||
if (!stateFlags) // state is normal
|
||||
if (stateFlags == State.Normal) // state is normal
|
||||
return normalStyle;
|
||||
const (Style) stateStyle = normalStyle.forState(stateFlags);
|
||||
if (stateStyle !is normalStyle)
|
||||
|
|
Loading…
Reference in New Issue