diff --git a/dlangui-monod-linux.dproj b/dlangui-monod-linux.dproj
index 57f959d9..77092165 100644
--- a/dlangui-monod-linux.dproj
+++ b/dlangui-monod-linux.dproj
@@ -351,6 +351,8 @@
+
+
diff --git a/dlangui-monod-osx.dproj b/dlangui-monod-osx.dproj
index 9bcd7891..fa8280d3 100644
--- a/dlangui-monod-osx.dproj
+++ b/dlangui-monod-osx.dproj
@@ -162,6 +162,8 @@
+
+
diff --git a/dlangui-monod-windows.dproj b/dlangui-monod-windows.dproj
index 8bfa6627..7d401108 100644
--- a/dlangui-monod-windows.dproj
+++ b/dlangui-monod-windows.dproj
@@ -153,6 +153,8 @@
+
+
diff --git a/dlangui-msvc.visualdproj b/dlangui-msvc.visualdproj
index 91d25095..1e132160 100644
--- a/dlangui-msvc.visualdproj
+++ b/dlangui-msvc.visualdproj
@@ -983,6 +983,7 @@
+
diff --git a/src/dlangui/package.d b/src/dlangui/package.d
index c675cd49..7727d6e2 100644
--- a/src/dlangui/package.d
+++ b/src/dlangui/package.d
@@ -59,6 +59,7 @@ public {
import dlangui.graphics.drawbuf;
import dlangui.widgets.widget;
import dlangui.widgets.controls;
+ import dlangui.widgets.scrollbar;
import dlangui.widgets.layouts;
import dlangui.widgets.groupbox;
import dlangui.widgets.lists;
diff --git a/src/dlangui/platforms/common/startup.d b/src/dlangui/platforms/common/startup.d
index e8881f1d..f3603261 100644
--- a/src/dlangui/platforms/common/startup.d
+++ b/src/dlangui/platforms/common/startup.d
@@ -321,6 +321,7 @@ void registerStandardWidgets() {
import dlangui.widgets.widget;
import dlangui.widgets.layouts;
import dlangui.widgets.controls;
+ import dlangui.widgets.scrollbar;
import dlangui.widgets.lists;
import dlangui.widgets.combobox;
import dlangui.widgets.editors;
diff --git a/src/dlangui/widgets/controls.d b/src/dlangui/widgets/controls.d
index 05bbcce4..f1ff04b8 100644
--- a/src/dlangui/widgets/controls.d
+++ b/src/dlangui/widgets/controls.d
@@ -1,8 +1,11 @@
// Written in the D programming language.
/**
+
+
This module contains simple controls widgets implementation.
+
TextWidget - static text
ImageWidget - image
@@ -19,15 +22,12 @@ RadioButton - radio button
CheckBox - button with check mark
-ScrollBar - scrollbar control
-
-SliderWidget - slider control
-
UrlImageTextButton - URL link button
CanvasWidget - for drawing arbitrary graphics
+Note: ScrollBar and SliderWidget are moved to dlangui.widgets.scrollbar
Synopsis:
@@ -576,966 +576,6 @@ class Button : Widget {
}
-/// scroll event handler interface
-interface OnScrollHandler {
- /// handle scroll event
- bool onScrollEvent(AbstractSlider source, ScrollEvent event);
-}
-
-/// base class for widgets like scrollbars and sliders
-class AbstractSlider : WidgetGroup {
- protected int _minValue = 0;
- protected int _maxValue = 100;
- protected int _pageSize = 30;
- protected int _position = 20;
-
- /// create with ID parameter
- this(string ID) {
- super(ID);
- }
-
- /// scroll event listeners
- Signal!OnScrollHandler scrollEvent;
-
- /// returns slider position
- @property int position() const { return _position; }
- /// sets new slider position
- @property AbstractSlider position(int newPosition) {
- if (_position != newPosition) {
- _position = newPosition;
- onPositionChanged();
- }
- return this;
- }
- protected void onPositionChanged() {
- requestLayout();
- }
- /// returns slider range min value
- @property int minValue() const { return _minValue; }
- /// sets slider range min value
- @property AbstractSlider minValue(int v) { _minValue = v; return this; }
- /// returns slider range max value
- @property int maxValue() const { return _maxValue; }
- /// sets slider range max value
- @property AbstractSlider maxValue(int v) { _maxValue = v; return this; }
-
-
-
- /// page size (visible area size)
- @property int pageSize() const { return _pageSize; }
- /// set page size (visible area size)
- @property AbstractSlider pageSize(int size) {
- if (_pageSize != size) {
- _pageSize = size;
- //requestLayout();
- }
- return this;
- }
-
- /// set int property value, for ML loaders
- //mixin(generatePropertySettersMethodOverride("setIntProperty", "int",
- // "minValue", "maxValue", "pageSize", "position"));
- /// set int property value, for ML loaders
- override bool setIntProperty(string name, int value) {
- if (name.equal("orientation")) { // use same value for all sides
- orientation = cast(Orientation)value;
- return true;
- }
- mixin(generatePropertySetters("minValue", "maxValue", "pageSize", "position"));
- return super.setIntProperty(name, value);
- }
-
- /// set new range (min and max values for slider)
- AbstractSlider setRange(int min, int max) {
- if (_minValue != min || _maxValue != max) {
- _minValue = min;
- _maxValue = max;
- //requestLayout();
- }
- return this;
- }
-
- bool sendScrollEvent(ScrollAction action) {
- return sendScrollEvent(action, _position);
- }
-
- bool sendScrollEvent(ScrollAction action, int position) {
- if (!scrollEvent.assigned)
- return false;
- ScrollEvent event = new ScrollEvent(action, _minValue, _maxValue, _pageSize, position);
- bool res = scrollEvent(this, event);
- if (event.positionChanged) {
- _position = event.position;
- if (_position > _maxValue)
- _position = _maxValue;
- if (_position < _minValue)
- _position = _minValue;
- onPositionChanged();
- }
- return true;
- }
-
- protected Orientation _orientation = Orientation.Vertical;
- /// returns scrollbar orientation (Vertical, Horizontal)
- @property Orientation orientation() { return _orientation; }
- /// sets scrollbar orientation
- @property AbstractSlider orientation(Orientation value) {
- if (_orientation != value) {
- _orientation = value;
- requestLayout();
- }
- return this;
- }
-
-}
-
-/// scroll bar - either vertical or horizontal
-class ScrollBar : AbstractSlider, OnClickHandler {
- protected ImageButton _btnBack;
- protected ImageButton _btnForward;
- protected SliderButton _indicator;
- protected PageScrollButton _pageUp;
- protected PageScrollButton _pageDown;
- protected Rect _scrollArea;
- protected int _btnSize;
- protected int _minIndicatorSize;
-
-
-
- class PageScrollButton : Widget {
- this(string ID) {
- super(ID);
- styleId = STYLE_PAGE_SCROLL;
- trackHover = true;
- clickable = true;
- }
- }
-
- class SliderButton : ImageButton {
- Point _dragStart;
- int _dragStartPosition;
- bool _dragging;
- Rect _dragStartRect;
-
- this(string resourceId) {
- super("SLIDER", resourceId);
- styleId = STYLE_SCROLLBAR_BUTTON;
- trackHover = true;
- }
-
- /// process mouse event; return true if event is processed by widget.
- override bool onMouseEvent(MouseEvent event) {
- // support onClick
- if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
- setState(State.Pressed);
- _dragging = true;
- _dragStart.x = event.x;
- _dragStart.y = event.y;
- _dragStartPosition = _position;
- _dragStartRect = _pos;
- sendScrollEvent(ScrollAction.SliderPressed, _position);
- return true;
- }
- if (event.action == MouseAction.FocusOut && _dragging) {
- debug(scrollbar) Log.d("ScrollBar slider dragging - FocusOut");
- return true;
- }
- if (event.action == MouseAction.FocusIn && _dragging) {
- debug(scrollbar) Log.d("ScrollBar slider dragging - FocusIn");
- return true;
- }
- if (event.action == MouseAction.Move && _dragging) {
- int delta = _orientation == Orientation.Vertical ? event.y - _dragStart.y : event.x - _dragStart.x;
- debug(scrollbar) Log.d("ScrollBar slider dragging - Move delta=", delta);
- Rect rc = _dragStartRect;
- int offset;
- int space;
- if (_orientation == Orientation.Vertical) {
- rc.top += delta;
- rc.bottom += delta;
- if (rc.top < _scrollArea.top) {
- rc.top = _scrollArea.top;
- rc.bottom = _scrollArea.top + _dragStartRect.height;
- } else if (rc.bottom > _scrollArea.bottom) {
- rc.top = _scrollArea.bottom - _dragStartRect.height;
- rc.bottom = _scrollArea.bottom;
- }
- offset = rc.top - _scrollArea.top;
- space = _scrollArea.height - rc.height;
- } else {
- rc.left += delta;
- rc.right += delta;
- if (rc.left < _scrollArea.left) {
- rc.left = _scrollArea.left;
- rc.right = _scrollArea.left + _dragStartRect.width;
- } else if (rc.right > _scrollArea.right) {
- rc.left = _scrollArea.right - _dragStartRect.width;
- rc.right = _scrollArea.right;
- }
- offset = rc.left - _scrollArea.left;
- space = _scrollArea.width - rc.width;
- }
- layoutButtons(rc);
- //_pos = rc;
- int position = cast(int)(space > 0 ? _minValue + cast(long)offset * (_maxValue - _minValue - _pageSize) / space : 0);
- invalidate();
- onIndicatorDragging(_dragStartPosition, position);
- return true;
- }
- if (event.action == MouseAction.ButtonUp && event.button == MouseButton.Left) {
- resetState(State.Pressed);
- if (_dragging) {
- sendScrollEvent(ScrollAction.SliderReleased, _position);
- _dragging = false;
- }
- return true;
- }
- if (event.action == MouseAction.Move && trackHover) {
- if (!(state & State.Hovered)) {
- debug(scrollbar) Log.d("Hover ", id);
- setState(State.Hovered);
- }
- return true;
- }
- if (event.action == MouseAction.Leave && trackHover) {
- debug(scrollbar) Log.d("Leave ", id);
- resetState(State.Hovered);
- return true;
- }
- if (event.action == MouseAction.Cancel && trackHover) {
- debug(scrollbar) Log.d("Cancel ? trackHover", id);
- resetState(State.Hovered);
- resetState(State.Pressed);
- _dragging = false;
- return true;
- }
- if (event.action == MouseAction.Cancel) {
- debug(scrollbar) Log.d("SliderButton.onMouseEvent event.action == MouseAction.Cancel");
- resetState(State.Pressed);
- _dragging = false;
- return true;
- }
- return false;
- }
-
- }
-
- protected bool onIndicatorDragging(int initialPosition, int currentPosition) {
- _position = currentPosition;
- return sendScrollEvent(ScrollAction.SliderMoved, currentPosition);
- }
-
- private bool calcButtonSizes(int availableSize, ref int spaceBackSize, ref int spaceForwardSize, ref int indicatorSize) {
- int dv = _maxValue - _minValue;
- if (_pageSize >= dv) {
- // full size
- spaceBackSize = spaceForwardSize = 0;
- indicatorSize = availableSize;
- return false;
- }
- if (dv < 0)
- dv = 0;
- indicatorSize = dv ? _pageSize * availableSize / dv : _minIndicatorSize;
- if (indicatorSize < _minIndicatorSize)
- indicatorSize = _minIndicatorSize;
- if (indicatorSize >= availableSize) {
- // full size
- spaceBackSize = spaceForwardSize = 0;
- indicatorSize = availableSize;
- return false;
- }
- int spaceLeft = availableSize - indicatorSize;
- int topv = _position - _minValue;
- int bottomv = _position + _pageSize - _minValue;
- if (topv < 0)
- topv = 0;
- if (bottomv > dv)
- bottomv = dv;
- bottomv = dv - bottomv;
- spaceBackSize = cast(int)(cast(long)spaceLeft * topv / (topv + bottomv));
- spaceForwardSize = spaceLeft - spaceBackSize;
- return true;
- }
-
- /// returns scrollbar orientation (Vertical, Horizontal)
- override @property Orientation orientation() { return _orientation; }
- /// sets scrollbar orientation
- override @property AbstractSlider orientation(Orientation value) {
- if (_orientation != value) {
- _orientation = value;
- _btnBack.drawableId = style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_BUTTON_UP : ATTR_SCROLLBAR_BUTTON_LEFT);
- _btnForward.drawableId = style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_BUTTON_DOWN : ATTR_SCROLLBAR_BUTTON_RIGHT);
- _indicator.drawableId = style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_INDICATOR_VERTICAL : ATTR_SCROLLBAR_INDICATOR_HORIZONTAL);
- requestLayout();
- }
- return this;
- }
-
- /// set string property value, for ML loaders
- override bool setStringProperty(string name, string value) {
- if (name.equal("orientation")) {
- if (value.equal("Vertical") || value.equal("vertical"))
- orientation = Orientation.Vertical;
- else
- orientation = Orientation.Horizontal;
- return true;
- }
- return super.setStringProperty(name, value);
- }
-
-
- /// empty parameter list constructor - for usage by factory
- this() {
- this(null, Orientation.Vertical);
- }
- /// create with ID parameter
- this(string ID, Orientation orient = Orientation.Vertical) {
- super(ID);
- styleId = STYLE_SCROLLBAR;
- _orientation = orient;
- _btnBack = new ImageButton("BACK", style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_BUTTON_UP : ATTR_SCROLLBAR_BUTTON_LEFT));
- _btnForward = new ImageButton("FORWARD", style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_BUTTON_DOWN : ATTR_SCROLLBAR_BUTTON_RIGHT));
- _pageUp = new PageScrollButton("PAGE_UP");
- _pageDown = new PageScrollButton("PAGE_DOWN");
- _btnBack.styleId = STYLE_SCROLLBAR_BUTTON_TRANSPARENT;
- _btnForward.styleId = STYLE_SCROLLBAR_BUTTON_TRANSPARENT;
- _indicator = new SliderButton(style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_INDICATOR_VERTICAL : ATTR_SCROLLBAR_INDICATOR_HORIZONTAL));
- addChild(_btnBack);
- addChild(_btnForward);
- addChild(_indicator);
- addChild(_pageUp);
- addChild(_pageDown);
- _btnBack.focusable = false;
- _btnForward.focusable = false;
- _indicator.focusable = false;
- _pageUp.focusable = false;
- _pageDown.focusable = false;
- _btnBack.click = &onClick;
- _btnForward.click = &onClick;
- _pageUp.click = &onClick;
- _pageDown.click = &onClick;
- }
-
- override void measure(int parentWidth, int parentHeight) {
- Point sz;
- _btnBack.measure(parentWidth, parentHeight);
- _btnForward.measure(parentWidth, parentHeight);
- _indicator.measure(parentWidth, parentHeight);
- _pageUp.measure(parentWidth, parentHeight);
- _pageDown.measure(parentWidth, parentHeight);
- _btnSize = _btnBack.measuredWidth;
- _minIndicatorSize = _orientation == Orientation.Vertical ? _indicator.measuredHeight : _indicator.measuredWidth;
- if (_btnSize < _minIndicatorSize)
- _btnSize = _minIndicatorSize;
- if (_btnSize < _btnForward.measuredWidth)
- _btnSize = _btnForward.measuredWidth;
- if (_btnSize < _btnForward.measuredHeight)
- _btnSize = _btnForward.measuredHeight;
- if (_btnSize < _btnBack.measuredHeight)
- _btnSize = _btnBack.measuredHeight;
- static if (BACKEND_GUI) {
- if (_btnSize < 16)
- _btnSize = 16;
- }
- if (_orientation == Orientation.Vertical) {
- // vertical
- sz.x = _btnSize;
- sz.y = _btnSize * 5; // min height
- } else {
- // horizontal
- sz.y = _btnSize;
- sz.x = _btnSize * 5; // min height
- }
- measuredContent(parentWidth, parentHeight, sz.x, sz.y);
- }
-
- override protected void onPositionChanged() {
- if (!needLayout)
- layoutButtons();
- }
-
- /// hide controls when scroll is not possible
- protected void updateState() {
- bool canScroll = _maxValue - _minValue > _pageSize;
- if (canScroll) {
- _btnBack.setState(State.Enabled);
- _btnForward.setState(State.Enabled);
- _indicator.visibility = Visibility.Visible;
- _pageUp.visibility = Visibility.Visible;
- _pageDown.visibility = Visibility.Visible;
- } else {
- _btnBack.resetState(State.Enabled);
- _btnForward.resetState(State.Enabled);
- _indicator.visibility = Visibility.Gone;
- _pageUp.visibility = Visibility.Gone;
- _pageDown.visibility = Visibility.Gone;
- }
- cancelLayout();
- }
-
- override void cancelLayout() {
- _btnBack.cancelLayout();
- _btnForward.cancelLayout();
- _indicator.cancelLayout();
- _pageUp.cancelLayout();
- _pageDown.cancelLayout();
- super.cancelLayout();
- }
-
- protected void layoutButtons() {
- Rect irc = _scrollArea;
- if (_orientation == Orientation.Vertical) {
- // vertical
- int spaceBackSize, spaceForwardSize, indicatorSize;
- bool indicatorVisible = calcButtonSizes(_scrollArea.height, spaceBackSize, spaceForwardSize, indicatorSize);
- irc.top += spaceBackSize;
- irc.bottom -= spaceForwardSize;
- layoutButtons(irc);
- } else {
- // horizontal
- int spaceBackSize, spaceForwardSize, indicatorSize;
- bool indicatorVisible = calcButtonSizes(_scrollArea.width, spaceBackSize, spaceForwardSize, indicatorSize);
- irc.left += spaceBackSize;
- irc.right -= spaceForwardSize;
- layoutButtons(irc);
- }
- updateState();
- cancelLayout();
- }
-
- protected void layoutButtons(Rect irc) {
- Rect r;
- _indicator.visibility = Visibility.Visible;
- if (_orientation == Orientation.Vertical) {
- _indicator.layout(irc);
- if (_scrollArea.top < irc.top) {
- r = _scrollArea;
- r.bottom = irc.top;
- _pageUp.layout(r);
- _pageUp.visibility = Visibility.Visible;
- } else {
- _pageUp.visibility = Visibility.Invisible;
- }
- if (_scrollArea.bottom > irc.bottom) {
- r = _scrollArea;
- r.top = irc.bottom;
- _pageDown.layout(r);
- _pageDown.visibility = Visibility.Visible;
- } else {
- _pageDown.visibility = Visibility.Invisible;
- }
- } else {
- _indicator.layout(irc);
- if (_scrollArea.left < irc.left) {
- r = _scrollArea;
- r.right = irc.left;
- _pageUp.layout(r);
- _pageUp.visibility = Visibility.Visible;
- } else {
- _pageUp.visibility = Visibility.Invisible;
- }
- if (_scrollArea.right > irc.right) {
- r = _scrollArea;
- r.left = irc.right;
- _pageDown.layout(r);
- _pageDown.visibility = Visibility.Visible;
- } else {
- _pageDown.visibility = Visibility.Invisible;
- }
- }
- }
-
- override void layout(Rect rc) {
- _needLayout = false;
- applyMargins(rc);
- applyPadding(rc);
- Rect r;
- if (_orientation == Orientation.Vertical) {
- // vertical
- // buttons
- int backbtnpos = rc.top + _btnSize;
- int fwdbtnpos = rc.bottom - _btnSize;
- r = rc;
- r.bottom = backbtnpos;
- _btnBack.layout(r);
- r = rc;
- r.top = fwdbtnpos;
- _btnForward.layout(r);
- // indicator
- r = rc;
- r.top = backbtnpos;
- r.bottom = fwdbtnpos;
- _scrollArea = r;
- } else {
- // horizontal
- int backbtnpos = rc.left + _btnSize;
- int fwdbtnpos = rc.right - _btnSize;
- r = rc;
- r.right = backbtnpos;
- _btnBack.layout(r);
- r = rc;
- r.left = fwdbtnpos;
- _btnForward.layout(r);
- // indicator
- r = rc;
- r.left = backbtnpos;
- r.right = fwdbtnpos;
- _scrollArea = r;
- }
- layoutButtons();
- _pos = rc;
- }
-
- override bool onClick(Widget source) {
- Log.d("Scrollbar.onClick ", source.id);
- if (source.compareId("BACK"))
- return sendScrollEvent(ScrollAction.LineUp, position);
- if (source.compareId("FORWARD"))
- return sendScrollEvent(ScrollAction.LineDown, position);
- if (source.compareId("PAGE_UP"))
- return sendScrollEvent(ScrollAction.PageUp, position);
- if (source.compareId("PAGE_DOWN"))
- return sendScrollEvent(ScrollAction.PageDown, position);
- return true;
- }
-
- /// handle mouse wheel events
- override bool onMouseEvent(MouseEvent event) {
- if (visibility != Visibility.Visible)
- return false;
- if (event.action == MouseAction.Wheel) {
- int delta = event.wheelDelta;
- if (delta > 0)
- sendScrollEvent(ScrollAction.LineUp, position);
- else if (delta < 0)
- sendScrollEvent(ScrollAction.LineDown, position);
- return true;
- }
- return super.onMouseEvent(event);
- }
-
- /// Draw widget at its position to buffer
- override void onDraw(DrawBuf buf) {
- if (visibility != Visibility.Visible && !buf.isClippedOut(_pos))
- return;
- super.onDraw(buf);
- Rect rc = _pos;
- applyMargins(rc);
- applyPadding(rc);
- auto saver = ClipRectSaver(buf, rc, alpha);
- _btnForward.onDraw(buf);
- _btnBack.onDraw(buf);
- _pageUp.onDraw(buf);
- _pageDown.onDraw(buf);
- _indicator.onDraw(buf);
- }
-}
-
-/// scroll bar - either vertical or horizontal
-class SliderWidget : AbstractSlider, OnClickHandler {
- protected SliderButton _indicator;
- protected PageScrollButton _pageUp;
- protected PageScrollButton _pageDown;
- protected Rect _scrollArea;
- protected int _btnSize;
- protected int _minIndicatorSize;
-
- class PageScrollButton : Widget {
- this(string ID) {
- super(ID);
- styleId = STYLE_PAGE_SCROLL;
- trackHover = true;
- clickable = true;
- }
- }
-
- class SliderButton : ImageButton {
- Point _dragStart;
- int _dragStartPosition;
- bool _dragging;
- Rect _dragStartRect;
-
- this(string resourceId) {
- super("SLIDER", resourceId);
- styleId = STYLE_SCROLLBAR_BUTTON;
- trackHover = true;
- }
-
- /// process mouse event; return true if event is processed by widget.
- override bool onMouseEvent(MouseEvent event) {
- // support onClick
- if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
- setState(State.Pressed);
- _dragging = true;
- _dragStart.x = event.x;
- _dragStart.y = event.y;
- _dragStartPosition = _position;
- _dragStartRect = _pos;
- sendScrollEvent(ScrollAction.SliderPressed, _position);
- return true;
- }
- if (event.action == MouseAction.FocusOut && _dragging) {
- debug(scrollbar) Log.d("ScrollBar slider dragging - FocusOut");
- return true;
- }
- if (event.action == MouseAction.FocusIn && _dragging) {
- debug(scrollbar) Log.d("ScrollBar slider dragging - FocusIn");
- return true;
- }
- if (event.action == MouseAction.Move && _dragging) {
- int delta = _orientation == Orientation.Vertical ? event.y - _dragStart.y : event.x - _dragStart.x;
- debug(scrollbar) Log.d("ScrollBar slider dragging - Move delta=", delta);
- Rect rc = _dragStartRect;
- int offset;
- int space;
- if (_orientation == Orientation.Vertical) {
- rc.top += delta;
- rc.bottom += delta;
- if (rc.top < _scrollArea.top) {
- rc.top = _scrollArea.top;
- rc.bottom = _scrollArea.top + _dragStartRect.height;
- } else if (rc.bottom > _scrollArea.bottom) {
- rc.top = _scrollArea.bottom - _dragStartRect.height;
- rc.bottom = _scrollArea.bottom;
- }
- offset = rc.top - _scrollArea.top;
- space = _scrollArea.height - rc.height;
- } else {
- rc.left += delta;
- rc.right += delta;
- if (rc.left < _scrollArea.left) {
- rc.left = _scrollArea.left;
- rc.right = _scrollArea.left + _dragStartRect.width;
- } else if (rc.right > _scrollArea.right) {
- rc.left = _scrollArea.right - _dragStartRect.width;
- rc.right = _scrollArea.right;
- }
- offset = rc.left - _scrollArea.left;
- space = _scrollArea.width - rc.width;
- }
- layoutButtons(rc);
- //_pos = rc;
- int position = cast(int)(space > 0 ? _minValue + cast(long)offset * (_maxValue - _minValue - _pageSize) / space : 0);
- invalidate();
- onIndicatorDragging(_dragStartPosition, position);
- return true;
- }
- if (event.action == MouseAction.ButtonUp && event.button == MouseButton.Left) {
- resetState(State.Pressed);
- if (_dragging) {
- sendScrollEvent(ScrollAction.SliderReleased, _position);
- _dragging = false;
- }
- return true;
- }
- if (event.action == MouseAction.Move && trackHover) {
- if (!(state & State.Hovered)) {
- debug(scrollbar) Log.d("Hover ", id);
- setState(State.Hovered);
- }
- return true;
- }
- if (event.action == MouseAction.Leave && trackHover) {
- debug(scrollbar) Log.d("Leave ", id);
- resetState(State.Hovered);
- return true;
- }
- if (event.action == MouseAction.Cancel && trackHover) {
- debug(scrollbar) Log.d("Cancel ? trackHover", id);
- resetState(State.Hovered);
- resetState(State.Pressed);
- _dragging = false;
- return true;
- }
- if (event.action == MouseAction.Cancel) {
- debug(scrollbar) Log.d("SliderButton.onMouseEvent event.action == MouseAction.Cancel");
- resetState(State.Pressed);
- _dragging = false;
- return true;
- }
- return false;
- }
-
- }
-
- protected bool onIndicatorDragging(int initialPosition, int currentPosition) {
- _position = currentPosition;
- return sendScrollEvent(ScrollAction.SliderMoved, currentPosition);
- }
-
- private bool calcButtonSizes(int availableSize, ref int spaceBackSize, ref int spaceForwardSize, ref int indicatorSize) {
- int dv = _maxValue - _minValue;
- if (_pageSize >= dv) {
- // full size
- spaceBackSize = spaceForwardSize = 0;
- indicatorSize = availableSize;
- return false;
- }
- if (dv < 0)
- dv = 0;
- indicatorSize = dv ? _pageSize * availableSize / dv : _minIndicatorSize;
- if (indicatorSize < _minIndicatorSize)
- indicatorSize = _minIndicatorSize;
- if (indicatorSize >= availableSize) {
- // full size
- spaceBackSize = spaceForwardSize = 0;
- indicatorSize = availableSize;
- return false;
- }
- int spaceLeft = availableSize - indicatorSize;
- int topv = _position - _minValue;
- int bottomv = _position + _pageSize - _minValue;
- if (topv < 0)
- topv = 0;
- if (bottomv > dv)
- bottomv = dv;
- bottomv = dv - bottomv;
- spaceBackSize = cast(int)(cast(long)spaceLeft * topv / (topv + bottomv));
- spaceForwardSize = spaceLeft - spaceBackSize;
- return true;
- }
-
- /// returns scrollbar orientation (Vertical, Horizontal)
- override @property Orientation orientation() { return _orientation; }
- /// sets scrollbar orientation
- override @property AbstractSlider orientation(Orientation value) {
- if (_orientation != value) {
- _orientation = value;
- _indicator.drawableId = style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_INDICATOR_VERTICAL : ATTR_SCROLLBAR_INDICATOR_HORIZONTAL);
- requestLayout();
- }
- return this;
- }
-
- /// set string property value, for ML loaders
- override bool setStringProperty(string name, string value) {
- if (name.equal("orientation")) {
- if (value.equal("Vertical") || value.equal("vertical"))
- orientation = Orientation.Vertical;
- else
- orientation = Orientation.Horizontal;
- return true;
- }
- return super.setStringProperty(name, value);
- }
-
-
- /// empty parameter list constructor - for usage by factory
- this() {
- this(null, Orientation.Horizontal);
- }
- /// create with ID parameter
- this(string ID, Orientation orient = Orientation.Horizontal) {
- super(ID);
- styleId = STYLE_SLIDER;
- _orientation = orient;
- _pageSize = 1;
- _pageUp = new PageScrollButton("PAGE_UP");
- _pageDown = new PageScrollButton("PAGE_DOWN");
- _indicator = new SliderButton(style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_INDICATOR_VERTICAL : ATTR_SCROLLBAR_INDICATOR_HORIZONTAL));
- addChild(_indicator);
- addChild(_pageUp);
- addChild(_pageDown);
- _indicator.focusable = false;
- _pageUp.focusable = false;
- _pageDown.focusable = false;
- _pageUp.click = &onClick;
- _pageDown.click = &onClick;
- }
-
- override void measure(int parentWidth, int parentHeight) {
- Point sz;
- _indicator.measure(parentWidth, parentHeight);
- _pageUp.measure(parentWidth, parentHeight);
- _pageDown.measure(parentWidth, parentHeight);
- _minIndicatorSize = _orientation == Orientation.Vertical ? _indicator.measuredHeight : _indicator.measuredWidth;
- _btnSize = _minIndicatorSize;
- if (_btnSize < _minIndicatorSize)
- _btnSize = _minIndicatorSize;
- static if (BACKEND_GUI) {
- if (_btnSize < 16)
- _btnSize = 16;
- }
- if (_orientation == Orientation.Vertical) {
- // vertical
- sz.x = _btnSize;
- sz.y = _btnSize * 5; // min height
- } else {
- // horizontal
- sz.y = _btnSize;
- sz.x = _btnSize * 5; // min height
- }
- measuredContent(parentWidth, parentHeight, sz.x, sz.y);
- }
-
- override protected void onPositionChanged() {
- if (!needLayout)
- layoutButtons();
- }
-
- /// hide controls when scroll is not possible
- protected void updateState() {
- bool canScroll = _maxValue - _minValue > _pageSize;
- if (canScroll) {
- _indicator.visibility = Visibility.Visible;
- _pageUp.visibility = Visibility.Visible;
- _pageDown.visibility = Visibility.Visible;
- } else {
- _indicator.visibility = Visibility.Gone;
- _pageUp.visibility = Visibility.Gone;
- _pageDown.visibility = Visibility.Gone;
- }
- cancelLayout();
- }
-
- override void cancelLayout() {
- _indicator.cancelLayout();
- _pageUp.cancelLayout();
- _pageDown.cancelLayout();
- super.cancelLayout();
- }
-
- protected void layoutButtons() {
- Rect irc = _scrollArea;
- if (_orientation == Orientation.Vertical) {
- // vertical
- int spaceBackSize, spaceForwardSize, indicatorSize;
- bool indicatorVisible = calcButtonSizes(_scrollArea.height, spaceBackSize, spaceForwardSize, indicatorSize);
- irc.top += spaceBackSize;
- irc.bottom -= spaceForwardSize;
- layoutButtons(irc);
- } else {
- // horizontal
- int spaceBackSize, spaceForwardSize, indicatorSize;
- bool indicatorVisible = calcButtonSizes(_scrollArea.width, spaceBackSize, spaceForwardSize, indicatorSize);
- irc.left += spaceBackSize;
- irc.right -= spaceForwardSize;
- layoutButtons(irc);
- }
- updateState();
- cancelLayout();
- }
-
- protected void layoutButtons(Rect irc) {
- Rect r;
- _indicator.visibility = Visibility.Visible;
- if (_orientation == Orientation.Vertical) {
- _indicator.layout(irc);
- if (_scrollArea.top < irc.top) {
- r = _scrollArea;
- r.bottom = irc.top;
- _pageUp.layout(r);
- _pageUp.visibility = Visibility.Visible;
- } else {
- _pageUp.visibility = Visibility.Invisible;
- }
- if (_scrollArea.bottom > irc.bottom) {
- r = _scrollArea;
- r.top = irc.bottom;
- _pageDown.layout(r);
- _pageDown.visibility = Visibility.Visible;
- } else {
- _pageDown.visibility = Visibility.Invisible;
- }
- } else {
- _indicator.layout(irc);
- if (_scrollArea.left < irc.left) {
- r = _scrollArea;
- r.right = irc.left;
- _pageUp.layout(r);
- _pageUp.visibility = Visibility.Visible;
- } else {
- _pageUp.visibility = Visibility.Invisible;
- }
- if (_scrollArea.right > irc.right) {
- r = _scrollArea;
- r.left = irc.right;
- _pageDown.layout(r);
- _pageDown.visibility = Visibility.Visible;
- } else {
- _pageDown.visibility = Visibility.Invisible;
- }
- }
- }
-
- override void layout(Rect rc) {
- _needLayout = false;
- applyMargins(rc);
- applyPadding(rc);
- Rect r;
- if (_orientation == Orientation.Vertical) {
- // vertical
- // buttons
- // indicator
- r = rc;
- _scrollArea = r;
- } else {
- // horizontal
- // indicator
- r = rc;
- _scrollArea = r;
- }
- layoutButtons();
- _pos = rc;
- }
-
- override bool onClick(Widget source) {
- Log.d("Scrollbar.onClick ", source.id);
- if (source.compareId("PAGE_UP"))
- return sendScrollEvent(ScrollAction.PageUp, position);
- if (source.compareId("PAGE_DOWN"))
- return sendScrollEvent(ScrollAction.PageDown, position);
- return true;
- }
-
- /// handle mouse wheel events
- override bool onMouseEvent(MouseEvent event) {
- if (visibility != Visibility.Visible)
- return false;
- if (event.action == MouseAction.Wheel) {
- int delta = event.wheelDelta;
- if (delta > 0)
- sendScrollEvent(ScrollAction.LineUp, position);
- else if (delta < 0)
- sendScrollEvent(ScrollAction.LineDown, position);
- return true;
- }
- return super.onMouseEvent(event);
- }
-
- /// Draw widget at its position to buffer
- override void onDraw(DrawBuf buf) {
- if (visibility != Visibility.Visible && !buf.isClippedOut(_pos))
- return;
- Rect rc = _pos;
- applyMargins(rc);
- auto saver = ClipRectSaver(buf, rc, alpha);
- DrawableRef bg = backgroundDrawable;
- if (!bg.isNull) {
- Rect r = rc;
- if (_orientation == Orientation.Vertical) {
- int dw = bg.width;
- r.left += (rc.width - dw)/2;
- r.right = r.left + dw;
- } else {
- int dw = bg.height;
- r.top += (rc.height - dw)/2;
- r.bottom = r.top + dw;
- }
- bg.drawTo(buf, r, state);
- }
- applyPadding(rc);
- if (state & State.Focused) {
- rc.expand(FOCUS_RECT_PADDING, FOCUS_RECT_PADDING);
- drawFocusRect(buf, rc);
- }
- _needDraw = false;
- _pageUp.onDraw(buf);
- _pageDown.onDraw(buf);
- _indicator.onDraw(buf);
- }
-}
-
/// interface - slot for onClick
interface OnDrawHandler {
diff --git a/src/dlangui/widgets/lists.d b/src/dlangui/widgets/lists.d
index d8ca353a..46e7e0e3 100644
--- a/src/dlangui/widgets/lists.d
+++ b/src/dlangui/widgets/lists.d
@@ -20,6 +20,7 @@ module dlangui.widgets.lists;
import dlangui.widgets.widget;
import dlangui.widgets.controls;
+import dlangui.widgets.scrollbar;
import dlangui.widgets.layouts;
import dlangui.core.signals;
diff --git a/src/dlangui/widgets/scroll.d b/src/dlangui/widgets/scroll.d
index a055689f..966b23d5 100644
--- a/src/dlangui/widgets/scroll.d
+++ b/src/dlangui/widgets/scroll.d
@@ -72,6 +72,7 @@ module dlangui.widgets.scroll;
import dlangui.widgets.widget;
import dlangui.widgets.controls;
+import dlangui.widgets.scrollbar;
import std.conv;
/** Scroll bar visibility mode. */