mirror of https://github.com/buggins/dlangui.git
refactoring: ScrollBar and SliderWidget moved to scrollbar.d
This commit is contained in:
parent
ab05bf5340
commit
f3a03a7378
|
@ -351,6 +351,8 @@
|
||||||
<Compile Include="src\dlangui\widgets\docks.d" />
|
<Compile Include="src\dlangui\widgets\docks.d" />
|
||||||
<Compile Include="src\dlangui\widgets\editors.d" />
|
<Compile Include="src\dlangui\widgets\editors.d" />
|
||||||
<Compile Include="src\dlangui\widgets\grid.d" />
|
<Compile Include="src\dlangui\widgets\grid.d" />
|
||||||
|
<Compile Include="src\dlangui\widgets\groupbox.d" />
|
||||||
|
<Compile Include="src\dlangui\widgets\scrollbar.d" />
|
||||||
<Compile Include="src\dlangui\widgets\layouts.d" />
|
<Compile Include="src\dlangui\widgets\layouts.d" />
|
||||||
<Compile Include="src\dlangui\widgets\lists.d" />
|
<Compile Include="src\dlangui\widgets\lists.d" />
|
||||||
<Compile Include="src\dlangui\widgets\menu.d" />
|
<Compile Include="src\dlangui\widgets\menu.d" />
|
||||||
|
|
|
@ -162,6 +162,8 @@
|
||||||
<Compile Include="src\dlangui\widgets\docks.d" />
|
<Compile Include="src\dlangui\widgets\docks.d" />
|
||||||
<Compile Include="src\dlangui\widgets\editors.d" />
|
<Compile Include="src\dlangui\widgets\editors.d" />
|
||||||
<Compile Include="src\dlangui\widgets\grid.d" />
|
<Compile Include="src\dlangui\widgets\grid.d" />
|
||||||
|
<Compile Include="src\dlangui\widgets\groupbox.d" />
|
||||||
|
<Compile Include="src\dlangui\widgets\scrollbar.d" />
|
||||||
<Compile Include="src\dlangui\widgets\layouts.d" />
|
<Compile Include="src\dlangui\widgets\layouts.d" />
|
||||||
<Compile Include="src\dlangui\widgets\lists.d" />
|
<Compile Include="src\dlangui\widgets\lists.d" />
|
||||||
<Compile Include="src\dlangui\widgets\menu.d" />
|
<Compile Include="src\dlangui\widgets\menu.d" />
|
||||||
|
|
|
@ -153,6 +153,8 @@
|
||||||
<Compile Include="src\dlangui\widgets\docks.d" />
|
<Compile Include="src\dlangui\widgets\docks.d" />
|
||||||
<Compile Include="src\dlangui\widgets\editors.d" />
|
<Compile Include="src\dlangui\widgets\editors.d" />
|
||||||
<Compile Include="src\dlangui\widgets\grid.d" />
|
<Compile Include="src\dlangui\widgets\grid.d" />
|
||||||
|
<Compile Include="src\dlangui\widgets\groupbox.d" />
|
||||||
|
<Compile Include="src\dlangui\widgets\scrollbar.d" />
|
||||||
<Compile Include="src\dlangui\widgets\layouts.d" />
|
<Compile Include="src\dlangui\widgets\layouts.d" />
|
||||||
<Compile Include="src\dlangui\widgets\lists.d" />
|
<Compile Include="src\dlangui\widgets\lists.d" />
|
||||||
<Compile Include="src\dlangui\widgets\menu.d" />
|
<Compile Include="src\dlangui\widgets\menu.d" />
|
||||||
|
|
|
@ -983,6 +983,7 @@
|
||||||
<File path="src\dlangui\widgets\metadata.d" />
|
<File path="src\dlangui\widgets\metadata.d" />
|
||||||
<File path="src\dlangui\widgets\popup.d" />
|
<File path="src\dlangui\widgets\popup.d" />
|
||||||
<File path="src\dlangui\widgets\scroll.d" />
|
<File path="src\dlangui\widgets\scroll.d" />
|
||||||
|
<File path="src\dlangui\widgets\scrollbar.d" />
|
||||||
<File path="src\dlangui\widgets\srcedit.d" />
|
<File path="src\dlangui\widgets\srcedit.d" />
|
||||||
<File path="src\dlangui\widgets\statusline.d" />
|
<File path="src\dlangui\widgets\statusline.d" />
|
||||||
<File path="src\dlangui\widgets\styles.d" />
|
<File path="src\dlangui\widgets\styles.d" />
|
||||||
|
|
|
@ -59,6 +59,7 @@ public {
|
||||||
import dlangui.graphics.drawbuf;
|
import dlangui.graphics.drawbuf;
|
||||||
import dlangui.widgets.widget;
|
import dlangui.widgets.widget;
|
||||||
import dlangui.widgets.controls;
|
import dlangui.widgets.controls;
|
||||||
|
import dlangui.widgets.scrollbar;
|
||||||
import dlangui.widgets.layouts;
|
import dlangui.widgets.layouts;
|
||||||
import dlangui.widgets.groupbox;
|
import dlangui.widgets.groupbox;
|
||||||
import dlangui.widgets.lists;
|
import dlangui.widgets.lists;
|
||||||
|
|
|
@ -321,6 +321,7 @@ void registerStandardWidgets() {
|
||||||
import dlangui.widgets.widget;
|
import dlangui.widgets.widget;
|
||||||
import dlangui.widgets.layouts;
|
import dlangui.widgets.layouts;
|
||||||
import dlangui.widgets.controls;
|
import dlangui.widgets.controls;
|
||||||
|
import dlangui.widgets.scrollbar;
|
||||||
import dlangui.widgets.lists;
|
import dlangui.widgets.lists;
|
||||||
import dlangui.widgets.combobox;
|
import dlangui.widgets.combobox;
|
||||||
import dlangui.widgets.editors;
|
import dlangui.widgets.editors;
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
// Written in the D programming language.
|
// Written in the D programming language.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
|
|
||||||
This module contains simple controls widgets implementation.
|
This module contains simple controls widgets implementation.
|
||||||
|
|
||||||
|
|
||||||
TextWidget - static text
|
TextWidget - static text
|
||||||
|
|
||||||
ImageWidget - image
|
ImageWidget - image
|
||||||
|
@ -19,15 +22,12 @@ RadioButton - radio button
|
||||||
|
|
||||||
CheckBox - button with check mark
|
CheckBox - button with check mark
|
||||||
|
|
||||||
ScrollBar - scrollbar control
|
|
||||||
|
|
||||||
SliderWidget - slider control
|
|
||||||
|
|
||||||
UrlImageTextButton - URL link button
|
UrlImageTextButton - URL link button
|
||||||
|
|
||||||
CanvasWidget - for drawing arbitrary graphics
|
CanvasWidget - for drawing arbitrary graphics
|
||||||
|
|
||||||
|
|
||||||
|
Note: ScrollBar and SliderWidget are moved to dlangui.widgets.scrollbar
|
||||||
|
|
||||||
Synopsis:
|
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 - slot for onClick
|
||||||
interface OnDrawHandler {
|
interface OnDrawHandler {
|
||||||
|
|
|
@ -20,6 +20,7 @@ module dlangui.widgets.lists;
|
||||||
|
|
||||||
import dlangui.widgets.widget;
|
import dlangui.widgets.widget;
|
||||||
import dlangui.widgets.controls;
|
import dlangui.widgets.controls;
|
||||||
|
import dlangui.widgets.scrollbar;
|
||||||
import dlangui.widgets.layouts;
|
import dlangui.widgets.layouts;
|
||||||
import dlangui.core.signals;
|
import dlangui.core.signals;
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ module dlangui.widgets.scroll;
|
||||||
|
|
||||||
import dlangui.widgets.widget;
|
import dlangui.widgets.widget;
|
||||||
import dlangui.widgets.controls;
|
import dlangui.widgets.controls;
|
||||||
|
import dlangui.widgets.scrollbar;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
|
||||||
/** Scroll bar visibility mode. */
|
/** Scroll bar visibility mode. */
|
||||||
|
|
Loading…
Reference in New Issue