mirror of https://github.com/buggins/dlangui.git
refactor: use ScrollWidget as base for editors
This commit is contained in:
parent
257496b6f8
commit
04c30ae566
|
@ -24,6 +24,7 @@ module dlangui.widgets.editors;
|
|||
|
||||
import dlangui.widgets.widget;
|
||||
import dlangui.widgets.controls;
|
||||
import dlangui.widgets.scroll;
|
||||
import dlangui.core.signals;
|
||||
import dlangui.core.collections;
|
||||
import dlangui.platforms.common.platform;
|
||||
|
@ -807,9 +808,8 @@ class EditableContent {
|
|||
}
|
||||
|
||||
/// base for all editor widgets
|
||||
class EditWidgetBase : WidgetGroup, EditableContentListener, MenuItemActionHandler {
|
||||
class EditWidgetBase : ScrollWidget, EditableContentListener, MenuItemActionHandler {
|
||||
protected EditableContent _content;
|
||||
protected Rect _clientRc;
|
||||
|
||||
protected int _lineHeight;
|
||||
protected Point _scrollPos;
|
||||
|
@ -830,8 +830,8 @@ class EditWidgetBase : WidgetGroup, EditableContentListener, MenuItemActionHandl
|
|||
protected uint _selectionColorNormal = 0xD060A0FF;
|
||||
|
||||
|
||||
this(string ID) {
|
||||
super(ID);
|
||||
this(string ID, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
||||
super(ID, hscrollbarMode, vscrollbarMode);
|
||||
focusable = true;
|
||||
acceleratorMap.add( [
|
||||
new Action(EditorActions.Up, KeyCode.UP, 0),
|
||||
|
@ -922,6 +922,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener, MenuItemActionHandl
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// override to change popup menu items state
|
||||
override bool isActionEnabled(const Action action) {
|
||||
switch (action.id) {
|
||||
|
@ -1130,7 +1131,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener, MenuItemActionHandl
|
|||
caretRc.right += _spaceWidth;
|
||||
}
|
||||
}
|
||||
caretRc.offset(_clientRc.left, _clientRc.top);
|
||||
caretRc.offset(_clientRect.left, _clientRect.top);
|
||||
return caretRc;
|
||||
}
|
||||
|
||||
|
@ -1139,7 +1140,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener, MenuItemActionHandl
|
|||
if (focused) {
|
||||
// draw caret
|
||||
Rect caretRc = caretRect();
|
||||
if (caretRc.intersects(_clientRc)) {
|
||||
if (caretRc.intersects(_clientRect)) {
|
||||
Rect rc1 = caretRc;
|
||||
rc1.right = rc1.left + 1;
|
||||
caretRc.left++;
|
||||
|
@ -1669,12 +1670,12 @@ class EditWidgetBase : WidgetGroup, EditableContentListener, MenuItemActionHandl
|
|||
// support onClick
|
||||
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
|
||||
setFocus();
|
||||
updateCaretPositionByMouse(event.x - _clientRc.left, event.y - _clientRc.top, false);
|
||||
updateCaretPositionByMouse(event.x - _clientRect.left, event.y - _clientRect.top, false);
|
||||
invalidate();
|
||||
return true;
|
||||
}
|
||||
if (event.action == MouseAction.Move && (event.flags & MouseButton.Left) != 0) {
|
||||
updateCaretPositionByMouse(event.x - _clientRc.left, event.y - _clientRc.top, true);
|
||||
updateCaretPositionByMouse(event.x - _clientRect.left, event.y - _clientRect.top, true);
|
||||
return true;
|
||||
}
|
||||
if (event.action == MouseAction.ButtonUp && event.button == MouseButton.Left) {
|
||||
|
@ -1713,7 +1714,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener, MenuItemActionHandl
|
|||
class EditLine : EditWidgetBase {
|
||||
|
||||
this(string ID, dstring initialContent = null) {
|
||||
super(ID);
|
||||
super(ID, ScrollBarMode.Invisible, ScrollBarMode.Invisible);
|
||||
_content = new EditableContent(false);
|
||||
_content.contentChangeListeners = this;
|
||||
wantTabs = false;
|
||||
|
@ -1727,7 +1728,7 @@ class EditLine : EditWidgetBase {
|
|||
|
||||
override protected Rect textPosToClient(TextPosition p) {
|
||||
Rect res;
|
||||
res.bottom = _clientRc.height;
|
||||
res.bottom = _clientRect.height;
|
||||
if (p.pos == 0)
|
||||
res.left = 0;
|
||||
else if (p.pos >= _measuredText.length)
|
||||
|
@ -1760,13 +1761,13 @@ class EditLine : EditWidgetBase {
|
|||
Rect rc = textPosToClient(_caretPos);
|
||||
if (rc.left < 0) {
|
||||
// scroll left
|
||||
_scrollPos.x -= -rc.left + _clientRc.width / 10;
|
||||
_scrollPos.x -= -rc.left + _clientRect.width / 10;
|
||||
if (_scrollPos.x < 0)
|
||||
_scrollPos.x = 0;
|
||||
invalidate();
|
||||
} else if (rc.left >= _clientRc.width - 10) {
|
||||
} else if (rc.left >= _clientRect.width - 10) {
|
||||
// scroll right
|
||||
_scrollPos.x += (rc.left - _clientRc.width) + _spaceWidth * 4;
|
||||
_scrollPos.x += (rc.left - _clientRect.width) + _spaceWidth * 4;
|
||||
invalidate();
|
||||
}
|
||||
updateScrollbars();
|
||||
|
@ -1819,16 +1820,16 @@ class EditLine : EditWidgetBase {
|
|||
|
||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||
override void layout(Rect rc) {
|
||||
_needLayout = false;
|
||||
if (visibility == Visibility.Gone) {
|
||||
return;
|
||||
}
|
||||
_needLayout = false;
|
||||
Point sz = Point(rc.width, measuredHeight);
|
||||
applyAlign(rc, sz);
|
||||
_pos = rc;
|
||||
_clientRc = rc;
|
||||
applyMargins(_clientRc);
|
||||
applyPadding(_clientRc);
|
||||
_clientRect = rc;
|
||||
applyMargins(_clientRect);
|
||||
applyPadding(_clientRect);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1838,8 +1839,8 @@ class EditLine : EditWidgetBase {
|
|||
// line inside selection
|
||||
Rect startrc = textPosToClient(_selectionRange.start);
|
||||
Rect endrc = textPosToClient(_selectionRange.end);
|
||||
int startx = startrc.left + _clientRc.left;
|
||||
int endx = endrc.left + _clientRc.left;
|
||||
int startx = startrc.left + _clientRect.left;
|
||||
int endx = endrc.left + _clientRect.left;
|
||||
Rect rc = lineRect;
|
||||
rc.left = startx;
|
||||
rc.right = endx;
|
||||
|
@ -1863,12 +1864,12 @@ class EditLine : EditWidgetBase {
|
|||
dstring txt = text;
|
||||
Point sz = font.textSize(txt);
|
||||
//applyAlign(rc, sz);
|
||||
Rect lineRect = _clientRc;
|
||||
lineRect.left = _clientRc.left - _scrollPos.x;
|
||||
Rect lineRect = _clientRect;
|
||||
lineRect.left = _clientRect.left - _scrollPos.x;
|
||||
lineRect.right = lineRect.left + calcLineWidth(txt);
|
||||
Rect visibleRect = lineRect;
|
||||
visibleRect.left = _clientRc.left;
|
||||
visibleRect.right = _clientRc.right;
|
||||
visibleRect.left = _clientRect.left;
|
||||
visibleRect.right = _clientRect.right;
|
||||
drawLineBackground(buf, lineRect, visibleRect);
|
||||
font.drawText(buf, rc.left - _scrollPos.x, rc.top, txt, textColor, tabSize);
|
||||
|
||||
|
@ -1879,22 +1880,13 @@ class EditLine : EditWidgetBase {
|
|||
|
||||
|
||||
/// single line editor
|
||||
class EditBox : EditWidgetBase, OnScrollHandler {
|
||||
protected ScrollBar _hscrollbar;
|
||||
protected ScrollBar _vscrollbar;
|
||||
|
||||
this(string ID, dstring initialContent = null) {
|
||||
super(ID);
|
||||
class EditBox : EditWidgetBase {
|
||||
this(string ID, dstring initialContent = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
||||
super(ID, hscrollbarMode, vscrollbarMode);
|
||||
_content = new EditableContent(true); // multiline
|
||||
_content.contentChangeListeners = this;
|
||||
styleId = "EDIT_BOX";
|
||||
text = initialContent;
|
||||
_hscrollbar = new ScrollBar("hscrollbar", Orientation.Horizontal);
|
||||
_vscrollbar = new ScrollBar("vscrollbar", Orientation.Vertical);
|
||||
_hscrollbar.onScrollEventListener = this;
|
||||
_vscrollbar.onScrollEventListener = this;
|
||||
addChild(_hscrollbar);
|
||||
addChild(_vscrollbar);
|
||||
}
|
||||
|
||||
protected int _firstVisibleLine;
|
||||
|
@ -1939,7 +1931,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
Point sz;
|
||||
FontRef font = font();
|
||||
_lineHeight = font.height;
|
||||
_numVisibleLines = (_clientRc.height + _lineHeight - 1) / _lineHeight;
|
||||
_numVisibleLines = (_clientRect.height + _lineHeight - 1) / _lineHeight;
|
||||
if (_firstVisibleLine + _numVisibleLines > _content.length)
|
||||
_numVisibleLines = _content.length - _firstVisibleLine;
|
||||
_visibleLines.length = _numVisibleLines;
|
||||
|
@ -1958,56 +1950,60 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
return sz;
|
||||
}
|
||||
|
||||
override protected void updateScrollbars() {
|
||||
int visibleLines = _clientRc.height / _lineHeight; // fully visible lines
|
||||
/// update horizontal scrollbar widget position
|
||||
override protected void updateHScrollBar() {
|
||||
_hscrollbar.setRange(0, _maxLineWidth + _clientRect.width / 4);
|
||||
_hscrollbar.pageSize = _clientRect.width;
|
||||
_hscrollbar.position = _scrollPos.x;
|
||||
}
|
||||
|
||||
/// update verticat scrollbar widget position
|
||||
override protected void updateVScrollBar() {
|
||||
int visibleLines = _clientRect.height / _lineHeight; // fully visible lines
|
||||
if (visibleLines < 1)
|
||||
visibleLines = 1;
|
||||
_vscrollbar.setRange(0, _content.length - 1);
|
||||
_vscrollbar.pageSize = visibleLines;
|
||||
_vscrollbar.position = _firstVisibleLine;
|
||||
_hscrollbar.setRange(0, _maxLineWidth + _clientRc.width / 4);
|
||||
_hscrollbar.pageSize = _clientRc.width;
|
||||
_hscrollbar.position = _scrollPos.x;
|
||||
}
|
||||
|
||||
/// handle scroll event
|
||||
override bool onScrollEvent(AbstractSlider source, ScrollEvent event) {
|
||||
if (source.compareId("hscrollbar")) {
|
||||
if (event.action == ScrollAction.SliderMoved || event.action == ScrollAction.SliderReleased) {
|
||||
if (_scrollPos.x != event.position) {
|
||||
_scrollPos.x = event.position;
|
||||
invalidate();
|
||||
}
|
||||
} else if (event.action == ScrollAction.PageUp) {
|
||||
handleAction(new Action(EditorActions.ScrollLeft));
|
||||
} else if (event.action == ScrollAction.PageDown) {
|
||||
handleAction(new Action(EditorActions.ScrollRight));
|
||||
} else if (event.action == ScrollAction.LineUp) {
|
||||
handleAction(new Action(EditorActions.ScrollLeft));
|
||||
} else if (event.action == ScrollAction.LineDown) {
|
||||
handleAction(new Action(EditorActions.ScrollRight));
|
||||
/// process horizontal scrollbar event
|
||||
override bool onHScroll(ScrollEvent event) {
|
||||
if (event.action == ScrollAction.SliderMoved || event.action == ScrollAction.SliderReleased) {
|
||||
if (_scrollPos.x != event.position) {
|
||||
_scrollPos.x = event.position;
|
||||
invalidate();
|
||||
}
|
||||
return true;
|
||||
} else if (source.compareId("vscrollbar")) {
|
||||
if (event.action == ScrollAction.SliderMoved || event.action == ScrollAction.SliderReleased) {
|
||||
if (_firstVisibleLine != event.position) {
|
||||
_firstVisibleLine = event.position;
|
||||
measureVisibleText();
|
||||
invalidate();
|
||||
}
|
||||
} else if (event.action == ScrollAction.PageUp) {
|
||||
handleAction(new Action(EditorActions.ScrollPageUp));
|
||||
} else if (event.action == ScrollAction.PageDown) {
|
||||
handleAction(new Action(EditorActions.ScrollPageDown));
|
||||
} else if (event.action == ScrollAction.LineUp) {
|
||||
handleAction(new Action(EditorActions.ScrollLineUp));
|
||||
} else if (event.action == ScrollAction.LineDown) {
|
||||
handleAction(new Action(EditorActions.ScrollLineDown));
|
||||
}
|
||||
return true;
|
||||
} else if (event.action == ScrollAction.PageUp) {
|
||||
handleAction(new Action(EditorActions.ScrollLeft));
|
||||
} else if (event.action == ScrollAction.PageDown) {
|
||||
handleAction(new Action(EditorActions.ScrollRight));
|
||||
} else if (event.action == ScrollAction.LineUp) {
|
||||
handleAction(new Action(EditorActions.ScrollLeft));
|
||||
} else if (event.action == ScrollAction.LineDown) {
|
||||
handleAction(new Action(EditorActions.ScrollRight));
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// process vertical scrollbar event
|
||||
override bool onVScroll(ScrollEvent event) {
|
||||
if (event.action == ScrollAction.SliderMoved || event.action == ScrollAction.SliderReleased) {
|
||||
if (_firstVisibleLine != event.position) {
|
||||
_firstVisibleLine = event.position;
|
||||
measureVisibleText();
|
||||
invalidate();
|
||||
}
|
||||
} else if (event.action == ScrollAction.PageUp) {
|
||||
handleAction(new Action(EditorActions.ScrollPageUp));
|
||||
} else if (event.action == ScrollAction.PageDown) {
|
||||
handleAction(new Action(EditorActions.ScrollPageDown));
|
||||
} else if (event.action == ScrollAction.LineUp) {
|
||||
handleAction(new Action(EditorActions.ScrollLineUp));
|
||||
} else if (event.action == ScrollAction.LineDown) {
|
||||
handleAction(new Action(EditorActions.ScrollLineDown));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
override protected void ensureCaretVisible() {
|
||||
|
@ -2015,7 +2011,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
_caretPos.line = _content.length - 1;
|
||||
if (_caretPos.line < 0)
|
||||
_caretPos.line = 0;
|
||||
int visibleLines = _clientRc.height / _lineHeight; // fully visible lines
|
||||
int visibleLines = _clientRect.height / _lineHeight; // fully visible lines
|
||||
if (visibleLines < 1)
|
||||
visibleLines = 1;
|
||||
if (_caretPos.line < _firstVisibleLine) {
|
||||
|
@ -2033,13 +2029,13 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
Rect rc = textPosToClient(_caretPos);
|
||||
if (rc.left < 0) {
|
||||
// scroll left
|
||||
_scrollPos.x -= -rc.left + _clientRc.width / 4;
|
||||
_scrollPos.x -= -rc.left + _clientRect.width / 4;
|
||||
if (_scrollPos.x < 0)
|
||||
_scrollPos.x = 0;
|
||||
invalidate();
|
||||
} else if (rc.left >= _clientRc.width - 10) {
|
||||
} else if (rc.left >= _clientRect.width - 10) {
|
||||
// scroll right
|
||||
_scrollPos.x += (rc.left - _clientRc.width) + _clientRc.width / 4;
|
||||
_scrollPos.x += (rc.left - _clientRect.width) + _clientRect.width / 4;
|
||||
invalidate();
|
||||
}
|
||||
updateScrollbars();
|
||||
|
@ -2081,9 +2077,12 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
}
|
||||
}
|
||||
res.pos = cast(int)_visibleLines[lineIndex].length;
|
||||
} else {
|
||||
} else if (_visibleLines.length > 0) {
|
||||
res.line = _firstVisibleLine + cast(int)_visibleLines.length - 1;
|
||||
res.pos = cast(int)_visibleLines[$ - 1].length;
|
||||
} else {
|
||||
res.line = 0;
|
||||
res.pos = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -2135,7 +2134,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
case EditorActions.SelectPageEnd:
|
||||
{
|
||||
ensureCaretVisible();
|
||||
int fullLines = _clientRc.height / _lineHeight;
|
||||
int fullLines = _clientRect.height / _lineHeight;
|
||||
int newpos = _firstVisibleLine + fullLines - 1;
|
||||
if (newpos >= _content.length)
|
||||
newpos = _content.length - 1;
|
||||
|
@ -2147,7 +2146,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
case EditorActions.SelectPageUp:
|
||||
{
|
||||
ensureCaretVisible();
|
||||
int fullLines = _clientRc.height / _lineHeight;
|
||||
int fullLines = _clientRect.height / _lineHeight;
|
||||
int newpos = _firstVisibleLine - fullLines;
|
||||
if (newpos < 0) {
|
||||
_firstVisibleLine = 0;
|
||||
|
@ -2166,7 +2165,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
case EditorActions.SelectPageDown:
|
||||
{
|
||||
ensureCaretVisible();
|
||||
int fullLines = _clientRc.height / _lineHeight;
|
||||
int fullLines = _clientRect.height / _lineHeight;
|
||||
int newpos = _firstVisibleLine + fullLines;
|
||||
if (newpos >= _content.length) {
|
||||
_caretPos.line = _content.length - 1;
|
||||
|
@ -2194,10 +2193,10 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
return true;
|
||||
case EditorActions.ScrollRight:
|
||||
{
|
||||
if (_scrollPos.x < _maxLineWidth - _clientRc.width) {
|
||||
if (_scrollPos.x < _maxLineWidth - _clientRect.width) {
|
||||
int newpos = _scrollPos.x + _spaceWidth * 4;
|
||||
if (newpos > _maxLineWidth - _clientRc.width)
|
||||
newpos = _maxLineWidth - _clientRc.width;
|
||||
if (newpos > _maxLineWidth - _clientRect.width)
|
||||
newpos = _maxLineWidth - _clientRect.width;
|
||||
_scrollPos.x = newpos;
|
||||
updateScrollbars();
|
||||
invalidate();
|
||||
|
@ -2218,7 +2217,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
return true;
|
||||
case EditorActions.ScrollPageUp:
|
||||
{
|
||||
int fullLines = _clientRc.height / _lineHeight;
|
||||
int fullLines = _clientRect.height / _lineHeight;
|
||||
if (_firstVisibleLine > 0) {
|
||||
_firstVisibleLine -= fullLines * 3 / 4;
|
||||
if (_firstVisibleLine < 0)
|
||||
|
@ -2231,7 +2230,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
return true;
|
||||
case EditorActions.ScrollLineDown:
|
||||
{
|
||||
int fullLines = _clientRc.height / _lineHeight;
|
||||
int fullLines = _clientRect.height / _lineHeight;
|
||||
if (_firstVisibleLine + fullLines < _content.length) {
|
||||
_firstVisibleLine += 3;
|
||||
if (_firstVisibleLine > _content.length - fullLines)
|
||||
|
@ -2246,7 +2245,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
return true;
|
||||
case EditorActions.ScrollPageDown:
|
||||
{
|
||||
int fullLines = _clientRc.height / _lineHeight;
|
||||
int fullLines = _clientRect.height / _lineHeight;
|
||||
if (_firstVisibleLine + fullLines < _content.length) {
|
||||
_firstVisibleLine += fullLines * 3 / 4;
|
||||
if (_firstVisibleLine > _content.length - fullLines)
|
||||
|
@ -2295,55 +2294,25 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
return super.handleAction(a);
|
||||
}
|
||||
|
||||
/// calculate full content size in pixels
|
||||
override Point fullContentSize() {
|
||||
Point textSz = measureVisibleText();
|
||||
int maxy = _lineHeight * 5; // limit measured height
|
||||
if (textSz.y > maxy)
|
||||
textSz.y = maxy;
|
||||
return textSz;
|
||||
}
|
||||
|
||||
/// measure
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
if (visibility == Visibility.Gone) {
|
||||
return;
|
||||
}
|
||||
_hscrollbar.measure(parentWidth, parentHeight);
|
||||
_vscrollbar.measure(parentWidth, parentHeight);
|
||||
int hsbheight = _hscrollbar.measuredHeight;
|
||||
int vsbwidth = _vscrollbar.measuredWidth;
|
||||
|
||||
updateFontProps();
|
||||
|
||||
updateMaxLineWidth();
|
||||
|
||||
Point textSz = measureVisibleText();
|
||||
int maxy = _lineHeight * 5; // limit measured height
|
||||
if (textSz.y > maxy)
|
||||
textSz.y = maxy;
|
||||
measuredContent(parentWidth, parentHeight, textSz.x + vsbwidth, textSz.y + hsbheight);
|
||||
}
|
||||
|
||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||
override void layout(Rect rc) {
|
||||
_needLayout = false;
|
||||
if (visibility == Visibility.Gone) {
|
||||
return;
|
||||
}
|
||||
_pos = rc;
|
||||
|
||||
|
||||
applyMargins(rc);
|
||||
applyPadding(rc);
|
||||
int hsbheight = _hscrollbar.measuredHeight;
|
||||
int vsbwidth = _vscrollbar.measuredWidth;
|
||||
Rect sbrc = rc;
|
||||
sbrc.left = sbrc.right - vsbwidth;
|
||||
sbrc.bottom -= hsbheight;
|
||||
_vscrollbar.layout(sbrc);
|
||||
sbrc = rc;
|
||||
sbrc.right -= vsbwidth;
|
||||
sbrc.top = sbrc.bottom - hsbheight;
|
||||
_hscrollbar.layout(sbrc);
|
||||
// calc client rectangle
|
||||
_clientRc = rc;
|
||||
_clientRc.right -= vsbwidth;
|
||||
_clientRc.bottom -= hsbheight;
|
||||
Point textSz = measureVisibleText();
|
||||
updateScrollbars();
|
||||
super.measure(parentWidth, parentHeight);
|
||||
// do we need to add vsbwidth, hsbheight ???
|
||||
//measuredContent(parentWidth, parentHeight, textSz.x + vsbwidth, textSz.y + hsbheight);
|
||||
}
|
||||
|
||||
/// override to custom highlight of line background
|
||||
|
@ -2356,8 +2325,8 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
// line inside selection
|
||||
Rect startrc = textPosToClient(_selectionRange.start);
|
||||
Rect endrc = textPosToClient(_selectionRange.end);
|
||||
int startx = lineIndex == _selectionRange.start.line ? startrc.left + _clientRc.left : lineRect.left;
|
||||
int endx = lineIndex == _selectionRange.end.line ? endrc.left + _clientRc.left : lineRect.right + _spaceWidth;
|
||||
int startx = lineIndex == _selectionRange.start.line ? startrc.left + _clientRect.left : lineRect.left;
|
||||
int endx = lineIndex == _selectionRange.end.line ? endrc.left + _clientRect.left : lineRect.right + _spaceWidth;
|
||||
Rect rc = lineRect;
|
||||
rc.left = startx;
|
||||
rc.right = endx;
|
||||
|
@ -2373,15 +2342,8 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// draw content
|
||||
override void onDraw(DrawBuf buf) {
|
||||
if (visibility != Visibility.Visible)
|
||||
return;
|
||||
super.onDraw(buf);
|
||||
_hscrollbar.onDraw(buf);
|
||||
_vscrollbar.onDraw(buf);
|
||||
Rect rc = _clientRc;
|
||||
override protected void drawClient(DrawBuf buf) {
|
||||
Rect rc = _clientRect;
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
|
||||
FontRef font = font();
|
||||
|
@ -2391,13 +2353,13 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
for (int i = 0; i < _visibleLines.length; i++) {
|
||||
dstring txt = _visibleLines[i];
|
||||
Rect lineRect = rc;
|
||||
lineRect.left = _clientRc.left - _scrollPos.x;
|
||||
lineRect.left = _clientRect.left - _scrollPos.x;
|
||||
lineRect.right = lineRect.left + calcLineWidth(_content[_firstVisibleLine + i]);
|
||||
lineRect.top = _clientRc.top + i * _lineHeight;
|
||||
lineRect.top = _clientRect.top + i * _lineHeight;
|
||||
lineRect.bottom = lineRect.top + _lineHeight;
|
||||
Rect visibleRect = lineRect;
|
||||
visibleRect.left = _clientRc.left;
|
||||
visibleRect.right = _clientRc.right;
|
||||
visibleRect.left = _clientRect.left;
|
||||
visibleRect.right = _clientRect.right;
|
||||
drawLineBackground(buf, _firstVisibleLine + i, lineRect, visibleRect);
|
||||
if (txt.length > 0) {
|
||||
font.drawText(buf, rc.left - _scrollPos.x, rc.top + i * _lineHeight, txt, textColor, tabSize);
|
||||
|
|
|
@ -179,8 +179,6 @@ class GridWidgetBase : ScrollWidget {
|
|||
protected int _col;
|
||||
/// selected cell row
|
||||
protected int _row;
|
||||
/// inner area, excluding additional controls like scrollbars
|
||||
protected Rect _clientRect;
|
||||
/// when true, allows to select only whole row
|
||||
protected bool _rowSelect;
|
||||
/// default column width - for newly added columns
|
||||
|
@ -852,7 +850,8 @@ class GridWidgetBase : ScrollWidget {
|
|||
}
|
||||
}
|
||||
|
||||
Point fullContentSize() {
|
||||
/// calculate full content size in pixels
|
||||
override Point fullContentSize() {
|
||||
Point sz;
|
||||
for (int i = 0; i < _cols; i++)
|
||||
sz.x += _colWidths[i];
|
||||
|
@ -861,62 +860,7 @@ class GridWidgetBase : ScrollWidget {
|
|||
return sz;
|
||||
}
|
||||
|
||||
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
Rect m = margins;
|
||||
Rect p = padding;
|
||||
// calc size constraints for children
|
||||
int pwidth = parentWidth;
|
||||
int pheight = parentHeight;
|
||||
if (parentWidth != SIZE_UNSPECIFIED)
|
||||
pwidth -= m.left + m.right + p.left + p.right;
|
||||
if (parentHeight != SIZE_UNSPECIFIED)
|
||||
pheight -= m.top + m.bottom + p.top + p.bottom;
|
||||
_hscrollbar.measure(pwidth, pheight);
|
||||
_vscrollbar.measure(pwidth, pheight);
|
||||
Point sz = fullContentSize();
|
||||
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
||||
}
|
||||
|
||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||
override void layout(Rect rc) {
|
||||
if (visibility == Visibility.Gone) {
|
||||
return;
|
||||
}
|
||||
_pos = rc;
|
||||
_needLayout = false;
|
||||
applyMargins(rc);
|
||||
applyPadding(rc);
|
||||
Point sz = fullContentSize();
|
||||
bool needHscroll = sz.x > rc.width;
|
||||
bool needVscroll = sz.y > rc.height;
|
||||
if (needVscroll)
|
||||
needHscroll = sz.x > rc.width - _vscrollbar.measuredWidth;
|
||||
if (needHscroll)
|
||||
needVscroll = sz.y > rc.height - _hscrollbar.measuredHeight;
|
||||
if (needVscroll)
|
||||
needHscroll = sz.x > rc.width - _vscrollbar.measuredWidth;
|
||||
// scrollbars
|
||||
Rect vsbrc = rc;
|
||||
vsbrc.left = vsbrc.right - _vscrollbar.measuredWidth;
|
||||
vsbrc.bottom = vsbrc.bottom - _hscrollbar.measuredHeight;
|
||||
Rect hsbrc = rc;
|
||||
hsbrc.right = hsbrc.right - _vscrollbar.measuredWidth;
|
||||
hsbrc.top = hsbrc.bottom - _hscrollbar.measuredHeight;
|
||||
_vscrollbar.layout(vsbrc);
|
||||
_hscrollbar.layout(hsbrc);
|
||||
_vscrollbar.visibility = needVscroll ? Visibility.Visible : Visibility.Gone;
|
||||
_hscrollbar.visibility = needHscroll ? Visibility.Visible : Visibility.Gone;
|
||||
// client area
|
||||
_clientRect = rc;
|
||||
if (needVscroll)
|
||||
_clientRect.right = vsbrc.left;
|
||||
if (needHscroll)
|
||||
_clientRect.bottom = hsbrc.top;
|
||||
updateScrollBars();
|
||||
}
|
||||
|
||||
protected void drawClient(DrawBuf buf) {
|
||||
override protected void drawClient(DrawBuf buf) {
|
||||
auto saver = ClipRectSaver(buf, _clientRect, 0);
|
||||
//buf.fillRect(_clientRect, 0x80A08080);
|
||||
Rect rc;
|
||||
|
@ -961,23 +905,6 @@ class GridWidgetBase : ScrollWidget {
|
|||
}
|
||||
}
|
||||
}
|
||||
/// Draw widget at its position to buffer
|
||||
override void onDraw(DrawBuf buf) {
|
||||
if (visibility != Visibility.Visible)
|
||||
return;
|
||||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
DrawableRef bg = backgroundDrawable;
|
||||
if (!bg.isNull) {
|
||||
bg.drawTo(buf, rc, state);
|
||||
}
|
||||
applyPadding(rc);
|
||||
_hscrollbar.onDraw(buf);
|
||||
_vscrollbar.onDraw(buf);
|
||||
drawClient(buf);
|
||||
_needDraw = false;
|
||||
}
|
||||
|
||||
/// draw data cell content
|
||||
protected void drawCell(DrawBuf buf, Rect rc, int col, int row) {
|
||||
|
@ -1051,8 +978,8 @@ class GridWidgetBase : ScrollWidget {
|
|||
autoFitRowHeights();
|
||||
}
|
||||
|
||||
this(string ID = null) {
|
||||
super(ID);
|
||||
this(string ID = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
||||
super(ID, hscrollbarMode, vscrollbarMode);
|
||||
_headerCols = 1;
|
||||
_headerRows = 1;
|
||||
_defRowHeight = 20;
|
||||
|
|
|
@ -4,20 +4,40 @@ import dlangui.widgets.widget;
|
|||
import dlangui.widgets.controls;
|
||||
import std.conv;
|
||||
|
||||
/** Scroll bar visibility mode. */
|
||||
enum ScrollBarMode {
|
||||
/** always invisible */
|
||||
Invisible,
|
||||
/** always visible */
|
||||
Visible,
|
||||
/** automatically show/hide scrollbar depending on content size */
|
||||
Auto
|
||||
}
|
||||
|
||||
class ScrollWidget : WidgetGroup, OnScrollHandler {
|
||||
protected ScrollBarMode _vscrollbarMode;
|
||||
protected ScrollBarMode _hscrollbarMode;
|
||||
/// vertical scrollbar control
|
||||
protected ScrollBar _vscrollbar;
|
||||
/// horizontal scrollbar control
|
||||
protected ScrollBar _hscrollbar;
|
||||
/// inner area, excluding additional controls like scrollbars
|
||||
protected Rect _clientRect;
|
||||
|
||||
this(string ID = null) {
|
||||
this(string ID = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
||||
super(ID);
|
||||
_vscrollbar = new ScrollBar("vscrollbar", Orientation.Vertical);
|
||||
_hscrollbar = new ScrollBar("hscrollbar", Orientation.Horizontal);
|
||||
_hscrollbar.onScrollEventListener = this;
|
||||
_vscrollbar.onScrollEventListener = this;
|
||||
addChild(_vscrollbar);
|
||||
addChild(_hscrollbar);
|
||||
_hscrollbarMode = hscrollbarMode;
|
||||
_vscrollbarMode = vscrollbarMode;
|
||||
if (_vscrollbarMode != ScrollBarMode.Invisible) {
|
||||
_vscrollbar = new ScrollBar("vscrollbar", Orientation.Vertical);
|
||||
_vscrollbar.onScrollEventListener = this;
|
||||
addChild(_vscrollbar);
|
||||
}
|
||||
if (_hscrollbarMode != ScrollBarMode.Invisible) {
|
||||
_hscrollbar = new ScrollBar("hscrollbar", Orientation.Horizontal);
|
||||
_hscrollbar.onScrollEventListener = this;
|
||||
addChild(_hscrollbar);
|
||||
}
|
||||
}
|
||||
|
||||
/// process horizontal scrollbar event
|
||||
|
@ -60,5 +80,101 @@ class ScrollWidget : WidgetGroup, OnScrollHandler {
|
|||
}
|
||||
}
|
||||
|
||||
protected void drawClient(DrawBuf buf) {
|
||||
// override it
|
||||
}
|
||||
|
||||
}
|
||||
/// Draw widget at its position to buffer
|
||||
override void onDraw(DrawBuf buf) {
|
||||
if (visibility != Visibility.Visible)
|
||||
return;
|
||||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
DrawableRef bg = backgroundDrawable;
|
||||
if (!bg.isNull) {
|
||||
bg.drawTo(buf, rc, state);
|
||||
}
|
||||
applyPadding(rc);
|
||||
if (_hscrollbar)
|
||||
_hscrollbar.onDraw(buf);
|
||||
if (_vscrollbar)
|
||||
_vscrollbar.onDraw(buf);
|
||||
drawClient(buf);
|
||||
_needDraw = false;
|
||||
}
|
||||
|
||||
/// calculate full content size in pixels
|
||||
Point fullContentSize() {
|
||||
// override it
|
||||
Point sz;
|
||||
return sz;
|
||||
}
|
||||
|
||||
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||
override void measure(int parentWidth, int parentHeight) {
|
||||
if (visibility == Visibility.Gone) {
|
||||
return;
|
||||
}
|
||||
Rect m = margins;
|
||||
Rect p = padding;
|
||||
// calc size constraints for children
|
||||
int pwidth = parentWidth;
|
||||
int pheight = parentHeight;
|
||||
if (parentWidth != SIZE_UNSPECIFIED)
|
||||
pwidth -= m.left + m.right + p.left + p.right;
|
||||
if (parentHeight != SIZE_UNSPECIFIED)
|
||||
pheight -= m.top + m.bottom + p.top + p.bottom;
|
||||
if (_hscrollbar)
|
||||
_hscrollbar.measure(pwidth, pheight);
|
||||
if (_vscrollbar)
|
||||
_vscrollbar.measure(pwidth, pheight);
|
||||
Point sz = fullContentSize();
|
||||
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
||||
}
|
||||
|
||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||
override void layout(Rect rc) {
|
||||
if (visibility == Visibility.Gone) {
|
||||
return;
|
||||
}
|
||||
_pos = rc;
|
||||
_needLayout = false;
|
||||
applyMargins(rc);
|
||||
applyPadding(rc);
|
||||
Point sz = fullContentSize();
|
||||
bool needHscroll = _hscrollbarMode != ScrollBarMode.Invisible && sz.x > rc.width;
|
||||
bool needVscroll = _vscrollbarMode != ScrollBarMode.Invisible && sz.y > rc.height;
|
||||
if (needVscroll && _vscrollbarMode != ScrollBarMode.Invisible)
|
||||
needHscroll = sz.x > rc.width - _vscrollbar.measuredWidth;
|
||||
if (needHscroll && _hscrollbarMode != ScrollBarMode.Invisible)
|
||||
needVscroll = sz.y > rc.height - _hscrollbar.measuredHeight;
|
||||
if (needVscroll && _vscrollbarMode != ScrollBarMode.Invisible)
|
||||
needHscroll = sz.x > rc.width - _vscrollbar.measuredWidth;
|
||||
needVscroll = needVscroll || (_vscrollbarMode == ScrollBarMode.Visible);
|
||||
needHscroll = needHscroll || (_hscrollbarMode == ScrollBarMode.Visible);
|
||||
// scrollbars
|
||||
Rect vsbrc = rc;
|
||||
vsbrc.left = vsbrc.right - (needVscroll ? _vscrollbar.measuredWidth : 0);
|
||||
vsbrc.bottom = vsbrc.bottom - (needHscroll ? _hscrollbar.measuredHeight : 0);
|
||||
Rect hsbrc = rc;
|
||||
hsbrc.right = hsbrc.right - (needVscroll ? _vscrollbar.measuredWidth : 0);
|
||||
hsbrc.top = hsbrc.bottom - (needHscroll ? _hscrollbar.measuredHeight : 0);
|
||||
if (_vscrollbar) {
|
||||
_vscrollbar.layout(vsbrc);
|
||||
_vscrollbar.visibility = needVscroll ? Visibility.Visible : Visibility.Gone;
|
||||
}
|
||||
if (_hscrollbar) {
|
||||
_hscrollbar.layout(hsbrc);
|
||||
_hscrollbar.visibility = needHscroll ? Visibility.Visible : Visibility.Gone;
|
||||
}
|
||||
// client area
|
||||
_clientRect = rc;
|
||||
if (needVscroll)
|
||||
_clientRect.right = vsbrc.left;
|
||||
if (needHscroll)
|
||||
_clientRect.bottom = hsbrc.top;
|
||||
updateScrollBars();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,19 +6,9 @@ import dlangui.widgets.scroll;
|
|||
import std.conv;
|
||||
|
||||
class TreeWidgetBase : ScrollWidget {
|
||||
/// vertical scrollbar control
|
||||
protected ScrollBar _vscrollbar;
|
||||
/// horizontal scrollbar control
|
||||
protected ScrollBar _hscrollbar;
|
||||
|
||||
this(string ID = null) {
|
||||
super(ID);
|
||||
_vscrollbar = new ScrollBar("vscrollbar", Orientation.Vertical);
|
||||
_hscrollbar = new ScrollBar("hscrollbar", Orientation.Horizontal);
|
||||
_hscrollbar.onScrollEventListener = this;
|
||||
_vscrollbar.onScrollEventListener = this;
|
||||
addChild(_vscrollbar);
|
||||
addChild(_hscrollbar);
|
||||
this(string ID = null, ScrollBarMode hscrollbarMode = ScrollBarMode.Visible, ScrollBarMode vscrollbarMode = ScrollBarMode.Visible) {
|
||||
super(ID, hscrollbarMode, vscrollbarMode);
|
||||
}
|
||||
|
||||
/// process horizontal scrollbar event
|
||||
|
|
Loading…
Reference in New Issue