mirror of https://github.com/buggins/dlangui.git
Scroll Widget is working
This commit is contained in:
parent
04c30ae566
commit
7f0c4250d0
|
@ -572,6 +572,54 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
tabs.addTab(grid, "Grid"d);
|
tabs.addTab(grid, "Grid"d);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
// Scroll view example
|
||||||
|
ScrollWidget scroll = new ScrollWidget("SCROLL1");
|
||||||
|
scroll.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||||
|
WidgetGroup scrollContent = new VerticalLayout("CONTENT");
|
||||||
|
scrollContent.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||||
|
|
||||||
|
TableLayout table2 = new TableLayout("TABLE2");
|
||||||
|
table2.colCount = 2;
|
||||||
|
// headers
|
||||||
|
table2.addChild((new TextWidget(null, "Parameter Name"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new TextWidget(null, "Edit Box to edit parameter"d)).alignment(Align.Left | Align.VCenter));
|
||||||
|
// row 1
|
||||||
|
table2.addChild((new TextWidget(null, "Parameter 1 name"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new EditLine("edit1", "Text 1"d)).layoutWidth(FILL_PARENT));
|
||||||
|
// row 2
|
||||||
|
table2.addChild((new TextWidget(null, "Parameter 2 name bla bla"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new EditLine("edit2", "Some text for parameter 2 blah blah blah"d)).layoutWidth(FILL_PARENT));
|
||||||
|
// row 3
|
||||||
|
table2.addChild((new TextWidget(null, "Param 3"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new EditLine("edit3", "Parameter 3 value"d)).layoutWidth(FILL_PARENT));
|
||||||
|
// row 4
|
||||||
|
table2.addChild((new TextWidget(null, "Param 4"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new EditLine("edit3", "Parameter 4 value shdjksdfh hsjdfas hdjkf hdjsfk ah"d)).layoutWidth(FILL_PARENT));
|
||||||
|
// row 5
|
||||||
|
table2.addChild((new TextWidget(null, "Param 5 - edit text here - blah blah blah"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT));
|
||||||
|
// row 6
|
||||||
|
table2.addChild((new TextWidget(null, "Param 6 - just to fill content widget"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT));
|
||||||
|
// row 7
|
||||||
|
table2.addChild((new TextWidget(null, "Param 7 - just to fill content widget"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT));
|
||||||
|
// row 8
|
||||||
|
table2.addChild((new TextWidget(null, "Param 8 - just to fill content widget"d)).alignment(Align.Right | Align.VCenter));
|
||||||
|
table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT));
|
||||||
|
table2.margins(Rect(10,10,10,10)).layoutWidth(FILL_PARENT);
|
||||||
|
scrollContent.addChild(table2);
|
||||||
|
|
||||||
|
scrollContent.addChild(new TextWidget(null, "Now - some buttons"d));
|
||||||
|
scrollContent.addChild(new ImageTextButton("btn1", "fileclose", "Close"d));
|
||||||
|
scrollContent.addChild(new ImageTextButton("btn2", "fileopen", "Open"d));
|
||||||
|
scrollContent.addChild(new TextWidget(null, "And checkboxes"d));
|
||||||
|
scrollContent.addChild(new CheckBox("btn1", "CheckBox 1"d));
|
||||||
|
scrollContent.addChild(new CheckBox("btn2", "CheckBox 2"d));
|
||||||
|
|
||||||
|
scroll.contentWidget = scrollContent;
|
||||||
|
tabs.addTab(scroll, "Scroll"d);
|
||||||
|
//==========================================================================
|
||||||
// tree view example
|
// tree view example
|
||||||
TreeWidget tree = new TreeWidget("TREE1");
|
TreeWidget tree = new TreeWidget("TREE1");
|
||||||
tree.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
tree.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||||
|
|
|
@ -56,6 +56,7 @@ public import dlangui.widgets.layouts;
|
||||||
public import dlangui.widgets.lists;
|
public import dlangui.widgets.lists;
|
||||||
public import dlangui.widgets.tabs;
|
public import dlangui.widgets.tabs;
|
||||||
public import dlangui.widgets.menu;
|
public import dlangui.widgets.menu;
|
||||||
|
public import dlangui.widgets.scroll;
|
||||||
public import dlangui.widgets.editors;
|
public import dlangui.widgets.editors;
|
||||||
public import dlangui.widgets.grid;
|
public import dlangui.widgets.grid;
|
||||||
public import dlangui.widgets.tree;
|
public import dlangui.widgets.tree;
|
||||||
|
|
|
@ -808,7 +808,7 @@ class EditableContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// base for all editor widgets
|
/// base for all editor widgets
|
||||||
class EditWidgetBase : ScrollWidget, EditableContentListener, MenuItemActionHandler {
|
class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemActionHandler {
|
||||||
protected EditableContent _content;
|
protected EditableContent _content;
|
||||||
|
|
||||||
protected int _lineHeight;
|
protected int _lineHeight;
|
||||||
|
@ -2344,7 +2344,6 @@ class EditBox : EditWidgetBase {
|
||||||
|
|
||||||
override protected void drawClient(DrawBuf buf) {
|
override protected void drawClient(DrawBuf buf) {
|
||||||
Rect rc = _clientRect;
|
Rect rc = _clientRect;
|
||||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
|
||||||
|
|
||||||
FontRef font = font();
|
FontRef font = font();
|
||||||
//dstring txt = text;
|
//dstring txt = text;
|
||||||
|
|
|
@ -150,7 +150,7 @@ enum GridActions : int {
|
||||||
SelectDocumentEnd,
|
SelectDocumentEnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridWidgetBase : ScrollWidget {
|
class GridWidgetBase : ScrollWidgetBase {
|
||||||
/// column count (including header columns and fixed columns)
|
/// column count (including header columns and fixed columns)
|
||||||
protected int _cols;
|
protected int _cols;
|
||||||
/// row count (including header rows and fixed rows)
|
/// row count (including header rows and fixed rows)
|
||||||
|
@ -373,20 +373,6 @@ class GridWidgetBase : ScrollWidget {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// update horizontal scrollbar widget position
|
|
||||||
override protected void updateHScrollBar() {
|
|
||||||
_hscrollbar.setRange(0, _fullScrollableArea.width);
|
|
||||||
_hscrollbar.pageSize(_visibleScrollableArea.width);
|
|
||||||
_hscrollbar.position(_visibleScrollableArea.left - _fullScrollableArea.left);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// update verticat scrollbar widget position
|
|
||||||
override protected void updateVScrollBar() {
|
|
||||||
_vscrollbar.setRange(0, _fullScrollableArea.height);
|
|
||||||
_vscrollbar.pageSize(_visibleScrollableArea.height);
|
|
||||||
_vscrollbar.position(_visibleScrollableArea.top - _fullScrollableArea.top);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// update scrollbar positions
|
/// update scrollbar positions
|
||||||
override protected void updateScrollBars() {
|
override protected void updateScrollBars() {
|
||||||
calcScrollableAreaPos();
|
calcScrollableAreaPos();
|
||||||
|
|
|
@ -14,7 +14,7 @@ enum ScrollBarMode {
|
||||||
Auto
|
Auto
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScrollWidget : WidgetGroup, OnScrollHandler {
|
class ScrollWidgetBase : WidgetGroup, OnScrollHandler {
|
||||||
protected ScrollBarMode _vscrollbarMode;
|
protected ScrollBarMode _vscrollbarMode;
|
||||||
protected ScrollBarMode _hscrollbarMode;
|
protected ScrollBarMode _hscrollbarMode;
|
||||||
/// vertical scrollbar control
|
/// vertical scrollbar control
|
||||||
|
@ -24,6 +24,9 @@ class ScrollWidget : WidgetGroup, OnScrollHandler {
|
||||||
/// inner area, excluding additional controls like scrollbars
|
/// inner area, excluding additional controls like scrollbars
|
||||||
protected Rect _clientRect;
|
protected Rect _clientRect;
|
||||||
|
|
||||||
|
protected Rect _fullScrollableArea;
|
||||||
|
protected Rect _visibleScrollableArea;
|
||||||
|
|
||||||
this(string ID = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
this(string ID = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
||||||
super(ID);
|
super(ID);
|
||||||
_hscrollbarMode = hscrollbarMode;
|
_hscrollbarMode = hscrollbarMode;
|
||||||
|
@ -60,16 +63,6 @@ class ScrollWidget : WidgetGroup, OnScrollHandler {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// update horizontal scrollbar widget position
|
|
||||||
protected void updateHScrollBar() {
|
|
||||||
// override it
|
|
||||||
}
|
|
||||||
|
|
||||||
/// update verticat scrollbar widget position
|
|
||||||
protected void updateVScrollBar() {
|
|
||||||
// override it
|
|
||||||
}
|
|
||||||
|
|
||||||
/// update scrollbar positions
|
/// update scrollbar positions
|
||||||
protected void updateScrollBars() {
|
protected void updateScrollBars() {
|
||||||
if (_hscrollbar) {
|
if (_hscrollbar) {
|
||||||
|
@ -80,6 +73,22 @@ class ScrollWidget : WidgetGroup, OnScrollHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// update horizontal scrollbar widget position
|
||||||
|
protected void updateHScrollBar() {
|
||||||
|
// default implementation: use _fullScrollableArea, _visibleScrollableArea: override it if necessary
|
||||||
|
_hscrollbar.setRange(0, _fullScrollableArea.width);
|
||||||
|
_hscrollbar.pageSize(_visibleScrollableArea.width);
|
||||||
|
_hscrollbar.position(_visibleScrollableArea.left - _fullScrollableArea.left);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// update verticat scrollbar widget position
|
||||||
|
protected void updateVScrollBar() {
|
||||||
|
// default implementation: use _fullScrollableArea, _visibleScrollableArea: override it if necessary
|
||||||
|
_vscrollbar.setRange(0, _fullScrollableArea.height);
|
||||||
|
_vscrollbar.pageSize(_visibleScrollableArea.height);
|
||||||
|
_vscrollbar.position(_visibleScrollableArea.top - _fullScrollableArea.top);
|
||||||
|
}
|
||||||
|
|
||||||
protected void drawClient(DrawBuf buf) {
|
protected void drawClient(DrawBuf buf) {
|
||||||
// override it
|
// override it
|
||||||
}
|
}
|
||||||
|
@ -100,6 +109,7 @@ class ScrollWidget : WidgetGroup, OnScrollHandler {
|
||||||
_hscrollbar.onDraw(buf);
|
_hscrollbar.onDraw(buf);
|
||||||
if (_vscrollbar)
|
if (_vscrollbar)
|
||||||
_vscrollbar.onDraw(buf);
|
_vscrollbar.onDraw(buf);
|
||||||
|
auto saver2 = ClipRectSaver(buf, _clientRect, alpha);
|
||||||
drawClient(buf);
|
drawClient(buf);
|
||||||
_needDraw = false;
|
_needDraw = false;
|
||||||
}
|
}
|
||||||
|
@ -178,3 +188,111 @@ class ScrollWidget : WidgetGroup, OnScrollHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Widget which can show content of widget group with optional scrolling.
|
||||||
|
*/
|
||||||
|
class ScrollWidget : ScrollWidgetBase {
|
||||||
|
protected WidgetGroup _contentWidget;
|
||||||
|
@property WidgetGroup contentWidget() { return _contentWidget; }
|
||||||
|
@property ScrollWidget contentWidget(WidgetGroup newContent) {
|
||||||
|
if (_contentWidget) {
|
||||||
|
removeChild(childIndex(_contentWidget));
|
||||||
|
destroy(_contentWidget);
|
||||||
|
}
|
||||||
|
_contentWidget = newContent;
|
||||||
|
addChild(_contentWidget);
|
||||||
|
requestLayout();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this(string ID = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
||||||
|
super(ID, hscrollbarMode, vscrollbarMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// calculate full content size in pixels
|
||||||
|
override Point fullContentSize() {
|
||||||
|
// override it
|
||||||
|
Point sz;
|
||||||
|
if (_contentWidget) {
|
||||||
|
_contentWidget.measure(SIZE_UNSPECIFIED, SIZE_UNSPECIFIED);
|
||||||
|
sz.x = _contentWidget.measuredWidth;
|
||||||
|
sz.y = _contentWidget.measuredHeight;
|
||||||
|
}
|
||||||
|
_fullScrollableArea.right = sz.x;
|
||||||
|
_fullScrollableArea.bottom = sz.y;
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// update scrollbar positions
|
||||||
|
override protected void updateScrollBars() {
|
||||||
|
Point sz = fullContentSize();
|
||||||
|
_visibleScrollableArea.right = _visibleScrollableArea.left + _clientRect.width;
|
||||||
|
_visibleScrollableArea.bottom = _visibleScrollableArea.top + _clientRect.height;
|
||||||
|
// move back if scroll is too big after window resize
|
||||||
|
int extrax = _visibleScrollableArea.right - _fullScrollableArea.right;
|
||||||
|
int extray = _visibleScrollableArea.bottom - _fullScrollableArea.bottom;
|
||||||
|
if (extrax > _visibleScrollableArea.left)
|
||||||
|
extrax = _visibleScrollableArea.left;
|
||||||
|
if (extray > _visibleScrollableArea.top)
|
||||||
|
extray = _visibleScrollableArea.top;
|
||||||
|
if (extrax < 0)
|
||||||
|
extrax = 0;
|
||||||
|
if (extray < 0)
|
||||||
|
extray = 0;
|
||||||
|
_visibleScrollableArea.offset(-extrax, -extray);
|
||||||
|
super.updateScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
override protected void drawClient(DrawBuf buf) {
|
||||||
|
if (_contentWidget) {
|
||||||
|
Point sz = fullContentSize();
|
||||||
|
Point p = scrollPos;
|
||||||
|
_contentWidget.layout(Rect(_pos.left - p.x, _pos.top - p.y, _pos.left + sz.x - p.x, _pos.top + sz.y - p.y));
|
||||||
|
_contentWidget.onDraw(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property Point scrollPos() {
|
||||||
|
return Point(_visibleScrollableArea.left - _fullScrollableArea.left, _visibleScrollableArea.top - _fullScrollableArea.top);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void scrollTo(int x, int y) {
|
||||||
|
_visibleScrollableArea.left = x;
|
||||||
|
_visibleScrollableArea.top = y;
|
||||||
|
updateScrollBars();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// process horizontal scrollbar event
|
||||||
|
override bool onHScroll(ScrollEvent event) {
|
||||||
|
if (event.action == ScrollAction.SliderMoved || event.action == ScrollAction.SliderReleased) {
|
||||||
|
scrollTo(event.position, scrollPos.y);
|
||||||
|
} else if (event.action == ScrollAction.PageUp) {
|
||||||
|
//handleAction(new Action(GridActions.ScrollPageLeft));
|
||||||
|
} else if (event.action == ScrollAction.PageDown) {
|
||||||
|
//handleAction(new Action(GridActions.ScrollPageRight));
|
||||||
|
} else if (event.action == ScrollAction.LineUp) {
|
||||||
|
//handleAction(new Action(GridActions.ScrollLeft));
|
||||||
|
} else if (event.action == ScrollAction.LineDown) {
|
||||||
|
//handleAction(new Action(GridActions.ScrollRight));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// process vertical scrollbar event
|
||||||
|
override bool onVScroll(ScrollEvent event) {
|
||||||
|
if (event.action == ScrollAction.SliderMoved || event.action == ScrollAction.SliderReleased) {
|
||||||
|
scrollTo(scrollPos.x, event.position);
|
||||||
|
} else if (event.action == ScrollAction.PageUp) {
|
||||||
|
//handleAction(new Action(GridActions.ScrollPageUp));
|
||||||
|
} else if (event.action == ScrollAction.PageDown) {
|
||||||
|
//handleAction(new Action(GridActions.ScrollPageDown));
|
||||||
|
} else if (event.action == ScrollAction.LineUp) {
|
||||||
|
//handleAction(new Action(GridActions.ScrollUp));
|
||||||
|
} else if (event.action == ScrollAction.LineDown) {
|
||||||
|
//handleAction(new Action(GridActions.ScrollDown));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import dlangui.widgets.controls;
|
||||||
import dlangui.widgets.scroll;
|
import dlangui.widgets.scroll;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
|
||||||
class TreeWidgetBase : ScrollWidget {
|
class TreeWidgetBase : ScrollWidgetBase {
|
||||||
|
|
||||||
this(string ID = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
this(string ID = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
||||||
super(ID, hscrollbarMode, vscrollbarMode);
|
super(ID, hscrollbarMode, vscrollbarMode);
|
||||||
|
@ -34,7 +34,7 @@ class TreeWidgetBase : ScrollWidget {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TreeWidget : ScrollWidget {
|
class TreeWidget : TreeWidgetBase {
|
||||||
this(string ID = null) {
|
this(string ID = null) {
|
||||||
super(ID);
|
super(ID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1041,7 +1041,10 @@ class Widget {
|
||||||
_measuredHeight = dy;
|
_measuredHeight = dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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).
|
||||||
|
|
||||||
|
*/
|
||||||
void measure(int parentWidth, int parentHeight) {
|
void measure(int parentWidth, int parentHeight) {
|
||||||
measuredContent(parentWidth, parentHeight, 0, 0);
|
measuredContent(parentWidth, parentHeight, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue