diff --git a/dlanguilib.visualdproj b/dlanguilib.visualdproj index dca3cfc7..6afca629 100644 --- a/dlanguilib.visualdproj +++ b/dlanguilib.visualdproj @@ -66,7 +66,7 @@ 0 0 - Unicode + Unicode USE_OPENGL 0 0 1 @@ -190,6 +190,11 @@ + + + + + @@ -220,11 +225,6 @@ - - - - - diff --git a/examples/example1/example1.visualdproj b/examples/example1/example1.visualdproj index 72167204..7927e2b4 100644 --- a/examples/example1/example1.visualdproj +++ b/examples/example1/example1.visualdproj @@ -66,7 +66,7 @@ 0 0 - Unicode + Unicode USE_OPENGL 0 0 0 diff --git a/examples/example1/res/btn_default_small_normal.9.png b/examples/example1/res/btn_default_small_normal.9.png index 5dddd464..bc7caa51 100644 Binary files a/examples/example1/res/btn_default_small_normal.9.png and b/examples/example1/res/btn_default_small_normal.9.png differ diff --git a/examples/example1/res/btn_default_small_normal_disable.9.png b/examples/example1/res/btn_default_small_normal_disable.9.png index 6ab5c4a2..782d16eb 100644 Binary files a/examples/example1/res/btn_default_small_normal_disable.9.png and b/examples/example1/res/btn_default_small_normal_disable.9.png differ diff --git a/examples/example1/res/btn_default_small_normal_hover.9.png b/examples/example1/res/btn_default_small_normal_hover.9.png new file mode 100644 index 00000000..27a7caf2 Binary files /dev/null and b/examples/example1/res/btn_default_small_normal_hover.9.png differ diff --git a/examples/example1/res/btn_default_small_pressed.9.png b/examples/example1/res/btn_default_small_pressed.9.png index 43e82f97..6c651e50 100644 Binary files a/examples/example1/res/btn_default_small_pressed.9.png and b/examples/example1/res/btn_default_small_pressed.9.png differ diff --git a/examples/example1/res/btn_default_small_selected.9.png b/examples/example1/res/btn_default_small_selected.9.png index 7a376a97..6ef7653a 100644 Binary files a/examples/example1/res/btn_default_small_selected.9.png and b/examples/example1/res/btn_default_small_selected.9.png differ diff --git a/examples/example1/res/expander_close_holo_light.9.png b/examples/example1/res/expander_close_holo_light.9.png new file mode 100644 index 00000000..54149e9a Binary files /dev/null and b/examples/example1/res/expander_close_holo_light.9.png differ diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d index 8a70c0a3..b302773d 100644 --- a/src/dlangui/core/events.d +++ b/src/dlangui/core/events.d @@ -115,3 +115,42 @@ class MouseEvent { _wheelDelta = wheelDelta; } } + + +enum ScrollAction : ubyte { + /// space above indicator pressed + PageUp, + /// space below indicator pressed + PageDown, + /// up/left button pressed + LineUp, + /// down/right button pressed + LineDown, + /// slider pressed + SliderPressed, + /// dragging in progress + SliderMoved, + /// dragging finished + SliderReleased +} + +/// slider/scrollbar event +class ScrollEvent { + private ScrollAction _action; + private int _minValue; + private int _maxValue; + private int _pageSize; + private int _position; + @property ScrollAction action() { return _action; } + @property int minValue() { return _minValue; } + @property int maxValue() { return _maxValue; } + @property int pageSize() { return _pageSize; } + @property int position() { return _position; } + this(ScrollAction action, int minValue, int maxValue, int pageSize, int position) { + _action = action; + _minValue = minValue; + _maxValue = minValue; + _pageSize = pageSize; + _position = position; + } +} diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index 4e277a5d..b5bc48d8 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -324,7 +324,7 @@ class Win32Window : Window { private bool _mouseTracking; private bool onMouse(uint message, uint flags, short x, short y) { - Log.d("Win32 Mouse Message ", message, " flags=", flags, " x=", x, " y=", y); + //Log.d("Win32 Mouse Message ", message, " flags=", flags, " x=", x, " y=", y); MouseButton button = MouseButton.None; MouseAction action = MouseAction.ButtonDown; ButtonDetails * pbuttonDetails = null; @@ -559,7 +559,7 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int Platform.setInstance(platform); - if (true) { + if (false) { /// testing freetype font manager import dlangui.graphics.ftfonts; import win32.shlobj; @@ -607,7 +607,7 @@ int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int // just to check OpenGL context Log.i("Trying to setup OpenGL context"); - Win32Window tmpWindow = new Win32Window("", null); + Win32Window tmpWindow = new Win32Window(platform, "", null); destroy(tmpWindow); if (openglEnabled) Log.i("OpenGL support is enabled"); diff --git a/src/dlangui/widgets/controls.d b/src/dlangui/widgets/controls.d index 9388ef21..90f62444 100644 --- a/src/dlangui/widgets/controls.d +++ b/src/dlangui/widgets/controls.d @@ -154,7 +154,9 @@ class Button : Widget { class ScrollBar : WidgetGroup, OnClickHandler { protected ImageButton _btnBack; protected ImageButton _btnForward; - protected ImageButton _indicator; + protected SliderButton _indicator; + protected PageScrollButton _pageUp; + protected PageScrollButton _pageDown; protected Rect _scrollArea; protected int _btnSize; protected int _minIndicatorSize; @@ -163,13 +165,20 @@ class ScrollBar : WidgetGroup, OnClickHandler { protected int _pageSize = 30; protected int _position = 20; - class IndicatorButton : ImageButton { + class PageScrollButton : Widget { + this(string ID) { + super(ID); + styleId = "PAGE_SCROLL"; + } + } + + class SliderButton : ImageButton { Point _dragStart; int _dragStartPosition; bool _dragging; Rect _dragStartRect; this(string resourceId) { - super("INDICATOR", resourceId); + super("SLIDER", resourceId); } /// process mouse event; return true if event is processed by widget. @@ -229,7 +238,7 @@ class ScrollBar : WidgetGroup, OnClickHandler { return true; } if (event.action == MouseAction.Cancel) { - Log.d("IndicatorButton.onMouseEvent event.action == MouseAction.Cancel"); + Log.d("SliderButton.onMouseEvent event.action == MouseAction.Cancel"); resetState(State.Pressed); _dragging = false; return true; @@ -293,16 +302,24 @@ class ScrollBar : WidgetGroup, OnClickHandler { this(string ID = null, Orientation orient = Orientation.Vertical) { super(ID); - styleId = "BUTTON"; + styleId = "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)); - _indicator = new IndicatorButton(style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_INDICATOR_VERTICAL : ATTR_SCROLLBAR_INDICATOR_HORIZONTAL)); + _pageUp = new PageScrollButton("PAGE_UP"); + _pageDown = new PageScrollButton("PAGE_DOWN"); + _btnBack.styleId("SCROLLBAR_BUTTON"); + _btnForward.styleId("SCROLLBAR_BUTTON"); + _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.onClickListener = &onClick; _btnForward.onClickListener = &onClick; + _pageUp.onClickListener = &onClick; + _pageDown.onClickListener = &onClick; } override void measure(int parentWidth, int parentHeight) { @@ -310,6 +327,8 @@ class ScrollBar : WidgetGroup, OnClickHandler { _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 < _btnBack.measuredHeight) @@ -354,6 +373,22 @@ class ScrollBar : WidgetGroup, OnClickHandler { irc.top += spaceBackSize; irc.bottom -= spaceForwardSize; _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 { // horizontal int backbtnpos = rc.left + _btnSize; @@ -375,12 +410,29 @@ class ScrollBar : WidgetGroup, OnClickHandler { irc.left += spaceBackSize; irc.right -= spaceForwardSize; _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; + } } _pos = rc; _needLayout = false; } override bool onClick(Widget source) { + Log.d("Scrollbar.onClick ", source.id); return true; } @@ -395,6 +447,8 @@ class ScrollBar : WidgetGroup, OnClickHandler { ClipRectSaver(buf, rc); _btnForward.onDraw(buf); _btnBack.onDraw(buf); + _pageUp.onDraw(buf); + _pageDown.onDraw(buf); _indicator.onDraw(buf); } } diff --git a/src/dlangui/widgets/styles.d b/src/dlangui/widgets/styles.d index 5a3dadb9..9c6ac143 100644 --- a/src/dlangui/widgets/styles.d +++ b/src/dlangui/widgets/styles.d @@ -488,7 +488,7 @@ class Style { if (state == 0) return this; //Log.d("forState ", state, " styleId=", _id, " substates=", _substates.length); - if (id is null && parentStyle !is null && _substates.length == 0) + if (parentStyle !is null && _substates.length == 0) //id is null && return parentStyle.forState(state); foreach(item; _substates) { if ((item._stateMask & state) == item._stateValue) @@ -616,7 +616,7 @@ Theme createDefaultTheme() { Log.d("Creating default theme"); Theme res = new Theme("default"); Style button = res.createSubstyle("BUTTON").backgroundImageId("btn_default_small_normal").alignment(Align.Center); - Style text = res.createSubstyle("TEXT").margins(Rect(3,3,3,3)).padding(Rect(3,3,3,3)); + Style text = res.createSubstyle("TEXT").margins(Rect(2,2,2,2)).padding(Rect(1,1,1,1)); button.createState(State.Disabled | State.Focused, State.Disabled | State.Focused).backgroundImageId("btn_default_small_normal_disable_focused"); button.createState(State.Disabled, State.Disabled).backgroundImageId("btn_default_small_normal_disable"); button.createState(State.Pressed, State.Pressed).backgroundImageId("btn_default_small_pressed"); @@ -627,7 +627,15 @@ Theme createDefaultTheme() { res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_RIGHT, "scrollbar_btn_right"); res.setCustomDrawable(ATTR_SCROLLBAR_INDICATOR_VERTICAL, "scrollbar_indicator_vertical"); res.setCustomDrawable(ATTR_SCROLLBAR_INDICATOR_HORIZONTAL, "scrollbar_indicator_horizontal"); - res.dumpStats(); + + Style scrollbar = res.createSubstyle("SCROLLBAR"); + Style scrollbarButton = button.createSubstyle("SCROLLBAR_BUTTON"); + scrollbar.backgroundColor(0xC0C0C0C0); + Style scrollbarSlider = res.createSubstyle("SLIDER"); + Style scrollbarPage = res.createSubstyle("PAGE_SCROLL").backgroundColor(0xFFFFFFFF); // transparent + scrollbarPage.createState(State.Pressed, State.Pressed).backgroundColor(0xC0404040); + + //res.dumpStats(); return res; } diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index 05a29dda..7da5f48b 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -35,6 +35,10 @@ interface OnClickHandler { bool onClick(Widget source); } +interface OnScrollHandler { + bool onScrollEvent(Widget source, ScrollEvent event); +} + class Widget { /// widget id protected string _id; @@ -63,17 +67,17 @@ class Widget { /// window (to be used for top level widgets only!) protected Window _window; - private static int _instanceCount = 0; + //private static int _instanceCount = 0; /// create widget, with optional id this(string ID = null) { _id = ID; - Log.d("Created widget, count = ", ++_instanceCount); + //Log.d("Created widget, count = ", ++_instanceCount); } ~this() { if (_ownStyle !is null) destroy(_ownStyle); _ownStyle = null; - Log.d("Destroyed widget, count = ", --_instanceCount); + //Log.d("Destroyed widget, count = ", --_instanceCount); } /// accessor to style - by lookup in theme by styleId (if style id is not set, theme base style will be used).