Scroll Widget is working

This commit is contained in:
Vadim Lopatin 2014-11-28 14:51:26 +03:00
parent 04c30ae566
commit 7f0c4250d0
7 changed files with 186 additions and 31 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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);
} }

View File

@ -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);
} }