mirror of https://github.com/buggins/dlangui.git
tree widget: selection movement
This commit is contained in:
parent
9fd29770a9
commit
c1614f9f72
|
@ -159,6 +159,10 @@ struct Rect {
|
|||
bool isInsideOf(Rect rc) {
|
||||
return left >= rc.left && right <= rc.right && top >= rc.top && bottom <= rc.bottom;
|
||||
}
|
||||
|
||||
bool opEquals(Rect rc) {
|
||||
return left == rc.left && right == rc.right && top == rc.top && bottom == rc.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
/// character glyph
|
||||
|
|
|
@ -193,6 +193,21 @@ class ScrollWidgetBase : WidgetGroup, OnScrollHandler {
|
|||
updateScrollBars();
|
||||
}
|
||||
|
||||
void makeRectVisible(Rect rc, bool alignHorizontally = true, bool alignVertically = true) {
|
||||
if (rc.isInsideOf(_visibleScrollableArea))
|
||||
return;
|
||||
Rect oldRect = _visibleScrollableArea;
|
||||
if (alignHorizontally && rc.right > _visibleScrollableArea.right)
|
||||
_visibleScrollableArea.offset(rc.right - _visibleScrollableArea.right, 0);
|
||||
if (alignVertically && rc.bottom > _visibleScrollableArea.bottom)
|
||||
_visibleScrollableArea.offset(0, rc.bottom - _visibleScrollableArea.bottom);
|
||||
if (alignHorizontally && rc.left < _visibleScrollableArea.left)
|
||||
_visibleScrollableArea.offset(rc.left - _visibleScrollableArea.left, 0);
|
||||
if (alignVertically && rc.top < _visibleScrollableArea.top)
|
||||
_visibleScrollableArea.offset(0, rc.top - _visibleScrollableArea.top);
|
||||
if (_visibleScrollableArea != oldRect)
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -258,6 +273,7 @@ class ScrollWidget : ScrollWidgetBase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@property Point scrollPos() {
|
||||
return Point(_visibleScrollableArea.left - _fullScrollableArea.left, _visibleScrollableArea.top - _fullScrollableArea.top);
|
||||
}
|
||||
|
@ -309,4 +325,14 @@ class ScrollWidget : ScrollWidgetBase {
|
|||
return true;
|
||||
}
|
||||
|
||||
void makeWidgetVisible(Widget widget, bool alignHorizontally = true, bool alignVertically = true) {
|
||||
if (!widget || !widget.visibility == Visibility.Gone)
|
||||
return;
|
||||
if (!_contentWidget || !_contentWidget.isChild(widget))
|
||||
return;
|
||||
Rect wpos = widget.pos;
|
||||
Rect cpos = _contentWidget.pos;
|
||||
wpos.offset(-cpos.left, -cpos.top);
|
||||
makeRectVisible(wpos, alignHorizontally, alignVertically);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,32 @@ class TreeItem {
|
|||
protected void activateItem(TreeItem item) {
|
||||
root.activateItem(item);
|
||||
}
|
||||
|
||||
protected TreeItem nextVisible(TreeItem item, ref bool found) {
|
||||
if (this is item)
|
||||
found = true;
|
||||
else if (found && isVisible)
|
||||
return this;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
TreeItem res = child(i).nextVisible(item, found);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected TreeItem prevVisible(TreeItem item, ref TreeItem prevFoundVisible) {
|
||||
if (this is item)
|
||||
return prevFoundVisible;
|
||||
else if (isVisible)
|
||||
prevFoundVisible = this;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
TreeItem res = child(i).prevVisible(item, prevFoundVisible);
|
||||
if (res)
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface OnTreeContentChangeListener {
|
||||
|
@ -237,6 +263,25 @@ class TreeItems : TreeItem {
|
|||
return _selectedItem;
|
||||
}
|
||||
|
||||
void selectNext() {
|
||||
if (!hasChildren)
|
||||
return;
|
||||
if (!_selectedItem)
|
||||
selectItem(child(0));
|
||||
bool found = false;
|
||||
TreeItem next = nextVisible(_selectedItem, found);
|
||||
if (next)
|
||||
selectItem(next);
|
||||
}
|
||||
|
||||
void selectPrevious() {
|
||||
if (!hasChildren)
|
||||
return;
|
||||
TreeItem found = null;
|
||||
TreeItem prev = prevVisible(_selectedItem, found);
|
||||
if (prev)
|
||||
selectItem(prev);
|
||||
}
|
||||
}
|
||||
|
||||
/// grid control action codes
|
||||
|
@ -319,6 +364,10 @@ class TreeItemWidget : HorizontalLayout {
|
|||
ImageWidget _icon;
|
||||
TextWidget _label;
|
||||
long lastClickTime;
|
||||
|
||||
@property TreeItem item() { return _item; }
|
||||
|
||||
|
||||
this(TreeItem item) {
|
||||
super(item.id);
|
||||
styleId = "TREE_ITEM";
|
||||
|
@ -434,19 +483,20 @@ class TreeWidgetBase : ScrollWidget, OnTreeContentChangeListener, OnTreeStateCh
|
|||
_tree = new TreeItems();
|
||||
_tree.contentListener = this;
|
||||
_tree.stateListener = this;
|
||||
_tree.selectionListener = this;
|
||||
_needUpdateWidgets = true;
|
||||
_needUpdateWidgetStates = true;
|
||||
acceleratorMap.add( [
|
||||
new Action(TreeActions.Up, KeyCode.UP, 0),
|
||||
new Action(TreeActions.Down, KeyCode.DOWN, 0),
|
||||
new Action(TreeActions.Left, KeyCode.LEFT, 0),
|
||||
new Action(TreeActions.Right, KeyCode.RIGHT, 0),
|
||||
new Action(TreeActions.LineBegin, KeyCode.HOME, 0),
|
||||
new Action(TreeActions.LineEnd, KeyCode.END, 0),
|
||||
new Action(TreeActions.ScrollLeft, KeyCode.LEFT, 0),
|
||||
new Action(TreeActions.ScrollRight, KeyCode.RIGHT, 0),
|
||||
//new Action(TreeActions.LineBegin, KeyCode.HOME, 0),
|
||||
//new Action(TreeActions.LineEnd, KeyCode.END, 0),
|
||||
new Action(TreeActions.PageUp, KeyCode.PAGEUP, 0),
|
||||
new Action(TreeActions.PageDown, KeyCode.PAGEDOWN, 0),
|
||||
new Action(TreeActions.PageBegin, KeyCode.PAGEUP, KeyFlag.Control),
|
||||
new Action(TreeActions.PageEnd, KeyCode.PAGEDOWN, KeyFlag.Control),
|
||||
//new Action(TreeActions.PageBegin, KeyCode.PAGEUP, KeyFlag.Control),
|
||||
//new Action(TreeActions.PageEnd, KeyCode.PAGEDOWN, KeyFlag.Control),
|
||||
new Action(TreeActions.ScrollTop, KeyCode.HOME, KeyFlag.Control),
|
||||
new Action(TreeActions.ScrollBottom, KeyCode.END, KeyFlag.Control),
|
||||
new Action(TreeActions.ScrollPageUp, KeyCode.PAGEUP, KeyFlag.Control),
|
||||
|
@ -539,11 +589,32 @@ class TreeWidgetBase : ScrollWidget, OnTreeContentChangeListener, OnTreeStateCh
|
|||
requestLayout();
|
||||
}
|
||||
|
||||
TreeItemWidget findItemWidget(TreeItem item) {
|
||||
for (int i = 0; i < _contentWidget.childCount; i++) {
|
||||
TreeItemWidget child = cast(TreeItemWidget) _contentWidget.child(i);
|
||||
if (child && child.item is item)
|
||||
return child;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
override void onTreeItemSelected(TreeItems source, TreeItem selectedItem, bool activated) {
|
||||
TreeItemWidget selected = findItemWidget(selectedItem);
|
||||
if (selected && selected.visibility == Visibility.Visible) {
|
||||
selected.setFocus();
|
||||
makeWidgetVisible(selected, false, true);
|
||||
}
|
||||
if (selectionListener.assigned)
|
||||
selectionListener(source, selectedItem, activated);
|
||||
}
|
||||
|
||||
void makeItemVisible(TreeItem item) {
|
||||
TreeItemWidget widget = findItemWidget(item);
|
||||
if (widget && widget.visibility == Visibility.Visible) {
|
||||
makeWidgetVisible(widget, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
override protected bool handleAction(const Action a) {
|
||||
Log.d("tree.handleAction ", a.id);
|
||||
switch (a.id) {
|
||||
|
@ -571,6 +642,16 @@ class TreeWidgetBase : ScrollWidget, OnTreeContentChangeListener, OnTreeStateCh
|
|||
if (_vscrollbar)
|
||||
_vscrollbar.sendScrollEvent(ScrollAction.PageDown);
|
||||
break;
|
||||
case TreeActions.Up:
|
||||
_tree.selectPrevious();
|
||||
break;
|
||||
case TreeActions.Down:
|
||||
_tree.selectNext();
|
||||
break;
|
||||
case TreeActions.PageUp:
|
||||
break;
|
||||
case TreeActions.PageDown:
|
||||
break;
|
||||
default:
|
||||
return super.handleAction(a);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue