mirror of https://github.com/buggins/dlangui.git
ListWidget
This commit is contained in:
parent
6d705c51e2
commit
91764870d9
|
@ -324,6 +324,7 @@
|
||||||
<Folder name="widgets">
|
<Folder name="widgets">
|
||||||
<File path="src\dlangui\widgets\controls.d" />
|
<File path="src\dlangui\widgets\controls.d" />
|
||||||
<File path="src\dlangui\widgets\layouts.d" />
|
<File path="src\dlangui\widgets\layouts.d" />
|
||||||
|
<File path="src\dlangui\widgets\lists.d" />
|
||||||
<File path="src\dlangui\widgets\styles.d" />
|
<File path="src\dlangui\widgets\styles.d" />
|
||||||
<File path="src\dlangui\widgets\widget.d" />
|
<File path="src\dlangui\widgets\widget.d" />
|
||||||
</Folder>
|
</Folder>
|
||||||
|
|
|
@ -16,7 +16,7 @@ class ListWidget : WidgetGroup {
|
||||||
/// returns linear layout orientation (Vertical, Horizontal)
|
/// returns linear layout orientation (Vertical, Horizontal)
|
||||||
@property Orientation orientation() { return _orientation; }
|
@property Orientation orientation() { return _orientation; }
|
||||||
/// sets linear layout orientation
|
/// sets linear layout orientation
|
||||||
@property LinearLayout orientation(Orientation value) {
|
@property ListWidget orientation(Orientation value) {
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
_scrollbar.orientation = value;
|
_scrollbar.orientation = value;
|
||||||
requestLayout();
|
requestLayout();
|
||||||
|
@ -24,7 +24,12 @@ class ListWidget : WidgetGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Rect[] _itemRects;
|
protected Rect[] _itemRects;
|
||||||
|
protected Point[] _itemSizes;
|
||||||
|
protected bool _needScrollbar;
|
||||||
|
protected Point _sbsz; // scrollbar size
|
||||||
protected ScrollBar _scrollbar;
|
protected ScrollBar _scrollbar;
|
||||||
|
protected int _lastMeasureWidth;
|
||||||
|
protected int _lastMeasureHeight;
|
||||||
|
|
||||||
protected ListAdapter _adapter;
|
protected ListAdapter _adapter;
|
||||||
/// get adapter
|
/// get adapter
|
||||||
|
@ -59,6 +64,7 @@ class ListWidget : WidgetGroup {
|
||||||
_orientation = orientation;
|
_orientation = orientation;
|
||||||
_scrollbar = new ScrollBar("listscroll", orientation);
|
_scrollbar = new ScrollBar("listscroll", orientation);
|
||||||
_scrollbar.visibility = Visibility.Gone;
|
_scrollbar.visibility = Visibility.Gone;
|
||||||
|
addChild(_scrollbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||||
|
@ -67,6 +73,8 @@ class ListWidget : WidgetGroup {
|
||||||
_measuredWidth = _measuredHeight = 0;
|
_measuredWidth = _measuredHeight = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (_itemSizes.length < itemCount)
|
||||||
|
_itemSizes.length = itemCount;
|
||||||
Rect m = margins;
|
Rect m = margins;
|
||||||
Rect p = padding;
|
Rect p = padding;
|
||||||
// calc size constraints for children
|
// calc size constraints for children
|
||||||
|
@ -76,16 +84,25 @@ class ListWidget : WidgetGroup {
|
||||||
pwidth -= m.left + m.right + p.left + p.right;
|
pwidth -= m.left + m.right + p.left + p.right;
|
||||||
if (parentHeight != SIZE_UNSPECIFIED)
|
if (parentHeight != SIZE_UNSPECIFIED)
|
||||||
pheight -= m.top + m.bottom + p.top + p.bottom;
|
pheight -= m.top + m.bottom + p.top + p.bottom;
|
||||||
|
_scrollbar.visibility = Visibility.Visible;
|
||||||
_scrollbar.measure(pwidth, pheight);
|
_scrollbar.measure(pwidth, pheight);
|
||||||
|
|
||||||
|
_lastMeasureWidth = pwidth;
|
||||||
|
_lastMeasureHeight = pheight;
|
||||||
|
|
||||||
int sbsize = _orientation == Orientation.Vertical ? _scrollbar.measuredWidth : _scrollbar.measuredHeight;
|
int sbsize = _orientation == Orientation.Vertical ? _scrollbar.measuredWidth : _scrollbar.measuredHeight;
|
||||||
// measure children
|
// measure children
|
||||||
Point sz;
|
Point sz;
|
||||||
Point sbsz;
|
_sbsz.clear;
|
||||||
for (int i = 0; i < itemCount; i++) {
|
for (int i = 0; i < itemCount; i++) {
|
||||||
Widget w = itemWidget(i);
|
Widget w = itemWidget(i);
|
||||||
if (w is null || w.visibility == Visibility.Gone)
|
if (w is null || w.visibility == Visibility.Gone) {
|
||||||
|
_itemSizes[i].x = _itemSizes[i].y = 0;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
w.measure(pwidth, pheight);
|
w.measure(pwidth, pheight);
|
||||||
|
_itemSizes[i].x = w.measuredWidth;
|
||||||
|
_itemSizes[i].y = w.measuredHeight;
|
||||||
if (_orientation == Orientation.Vertical) {
|
if (_orientation == Orientation.Vertical) {
|
||||||
// Vertical
|
// Vertical
|
||||||
if (sz.x < w.measuredWidth)
|
if (sz.x < w.measuredWidth)
|
||||||
|
@ -99,14 +116,13 @@ class ListWidget : WidgetGroup {
|
||||||
sz.x += w.measuredWidth;
|
sz.x += w.measuredWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool needScrollbar;
|
|
||||||
if (_orientation == Orientation.Vertical) {
|
if (_orientation == Orientation.Vertical) {
|
||||||
if (pheight != SIZE_UNSPECIFIED && sz.y > pheight) {
|
if (pheight != SIZE_UNSPECIFIED && sz.y > pheight) {
|
||||||
// need scrollbar
|
// need scrollbar
|
||||||
if (pwidth != SIZE_UNSPECIFIED) {
|
if (pwidth != SIZE_UNSPECIFIED) {
|
||||||
pwidth -= sbsize;
|
pwidth -= sbsize;
|
||||||
sbsz.x = sbsize;
|
_sbsz.x = sbsize;
|
||||||
needScrollbar = true;
|
_needScrollbar = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -114,12 +130,12 @@ class ListWidget : WidgetGroup {
|
||||||
// need scrollbar
|
// need scrollbar
|
||||||
if (pheight != SIZE_UNSPECIFIED) {
|
if (pheight != SIZE_UNSPECIFIED) {
|
||||||
pheight -= sbsize;
|
pheight -= sbsize;
|
||||||
sbsz.y = sbsize;
|
_sbsz.y = sbsize;
|
||||||
needScrollbar = true;
|
_needScrollbar = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (needScrollbar) {
|
if (_needScrollbar) {
|
||||||
// recalculate with scrollbar
|
// recalculate with scrollbar
|
||||||
sz.x = sz.y = 0;
|
sz.x = sz.y = 0;
|
||||||
for (int i = 0; i < itemCount; i++) {
|
for (int i = 0; i < itemCount; i++) {
|
||||||
|
@ -127,6 +143,8 @@ class ListWidget : WidgetGroup {
|
||||||
if (w is null || w.visibility == Visibility.Gone)
|
if (w is null || w.visibility == Visibility.Gone)
|
||||||
continue;
|
continue;
|
||||||
w.measure(pwidth, pheight);
|
w.measure(pwidth, pheight);
|
||||||
|
_itemSizes[i].x = w.measuredWidth;
|
||||||
|
_itemSizes[i].y = w.measuredHeight;
|
||||||
if (_orientation == Orientation.Vertical) {
|
if (_orientation == Orientation.Vertical) {
|
||||||
// Vertical
|
// Vertical
|
||||||
if (sz.x < w.measuredWidth)
|
if (sz.x < w.measuredWidth)
|
||||||
|
@ -141,7 +159,7 @@ class ListWidget : WidgetGroup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
measuredContent(parentWidth, parentHeight, sz.x + sbsz.x, sz.y + sbsz.y);
|
measuredContent(parentWidth, parentHeight, sz.x + _sbsz.x, sz.y + _sbsz.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||||
|
@ -150,40 +168,64 @@ class ListWidget : WidgetGroup {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_pos = rc;
|
_pos = rc;
|
||||||
|
|
||||||
applyMargins(rc);
|
applyMargins(rc);
|
||||||
applyPadding(rc);
|
applyPadding(rc);
|
||||||
|
|
||||||
if (_itemRects.length < itemCount)
|
if (_itemRects.length < itemCount)
|
||||||
_itemRects.length = itemCount;
|
_itemRects.length = itemCount;
|
||||||
|
|
||||||
Rect r;
|
// measure again if client size has been changed
|
||||||
Point sz;
|
if (_lastMeasureWidth != rc.width || _lastMeasureHeight != rc.height)
|
||||||
Point sbsz;
|
measure(rc.width, rc.height);
|
||||||
int sbsize = _orientation == Orientation.Vertical ? _scrollbar.measuredWidth : _scrollbar.measuredHeight;
|
|
||||||
r = rc;
|
|
||||||
for (int i = 0; i < itemCount; i++) {
|
|
||||||
|
|
||||||
Widget w = itemWidget(i);
|
// layout scrollbar
|
||||||
if (w is null || w.visibility == Visibility.Gone)
|
if (_needScrollbar) {
|
||||||
|
_scrollbar.visibility = Visibility.Visible;
|
||||||
|
Rect sbrect = rc;
|
||||||
|
if (_orientation == Orientation.Vertical)
|
||||||
|
sbrect.left = sbrect.right - _sbsz.x;
|
||||||
|
else
|
||||||
|
sbrect.top = sbrect.bottom - _sbsz.y;
|
||||||
|
_scrollbar.layout(sbrect);
|
||||||
|
rc.right -= _sbsz.x;
|
||||||
|
rc.bottom -= _sbsz.y;
|
||||||
|
} else {
|
||||||
|
_scrollbar.visibility = Visibility.Gone;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calc item rectangles
|
||||||
|
Rect r;
|
||||||
|
int p = 0;
|
||||||
|
for (int i = 0; i < itemCount; i++) {
|
||||||
|
if (_itemSizes[i].x == 0 && _itemSizes[i].y == 0)
|
||||||
continue;
|
continue;
|
||||||
if (_orientation == Orientation.Vertical) {
|
if (_orientation == Orientation.Vertical) {
|
||||||
w.measure(rc.width, SIZE_UNSPECIFIED);
|
|
||||||
// Vertical
|
// Vertical
|
||||||
if (sz.x < w.measuredWidth)
|
int w = rc.width;
|
||||||
sz.x = w.measuredWidth;
|
int h = _itemSizes[i].y;
|
||||||
sz.y += w.measuredHeight;
|
r.top = p;
|
||||||
r.bottom =
|
r.bottom = p + h;
|
||||||
|
r.left = 0;
|
||||||
|
r.right = w;
|
||||||
|
_itemRects[i] = r;
|
||||||
|
p += h;
|
||||||
} else {
|
} else {
|
||||||
// Horizontal
|
// Horizontal
|
||||||
w.measure(pwidth, pheight);
|
int h = rc.height;
|
||||||
if (sz.y < w.measuredHeight)
|
int w = _itemSizes[i].x;
|
||||||
sz.y = w.measuredHeight;
|
r.top = 0;
|
||||||
sz.x += w.measuredWidth;
|
r.bottom = h;
|
||||||
|
r.left = p;
|
||||||
|
r.right = p + w;
|
||||||
|
_itemRects[i] = r;
|
||||||
|
p += w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_needLayout = false;
|
_needLayout = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw widget at its position to buffer
|
/// Draw widget at its position to buffer
|
||||||
override void onDraw(DrawBuf buf) {
|
override void onDraw(DrawBuf buf) {
|
||||||
if (visibility != Visibility.Visible)
|
if (visibility != Visibility.Visible)
|
||||||
|
@ -193,11 +235,25 @@ class ListWidget : WidgetGroup {
|
||||||
applyMargins(rc);
|
applyMargins(rc);
|
||||||
applyPadding(rc);
|
applyPadding(rc);
|
||||||
ClipRectSaver(buf, rc);
|
ClipRectSaver(buf, rc);
|
||||||
for (int i = 0; i < _children.count; i++) {
|
// draw scrollbar
|
||||||
Widget item = _children.get(i);
|
if (_needScrollbar)
|
||||||
if (item.visibility != Visibility.Visible)
|
_scrollbar.onDraw(buf);
|
||||||
|
|
||||||
|
Point scrollOffset;
|
||||||
|
// todo: scrollOffset
|
||||||
|
// draw items
|
||||||
|
for (int i = 0; i < itemCount; i++) {
|
||||||
|
Widget w = itemWidget(i);
|
||||||
|
if (w is null || w.visibility != Visibility.Visible)
|
||||||
continue;
|
continue;
|
||||||
item.onDraw(buf);
|
Rect itemrc = _itemRects[i];
|
||||||
|
itemrc.left += rc.left - scrollOffset.x;
|
||||||
|
itemrc.right += rc.left - scrollOffset.x;
|
||||||
|
itemrc.top += rc.top - scrollOffset.y;
|
||||||
|
itemrc.bottom += rc.top - scrollOffset.y;
|
||||||
|
w.measure(itemrc.width, itemrc.height);
|
||||||
|
w.layout(itemrc);
|
||||||
|
w.onDraw(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue