From 7eaf08aec364dd348f43b6262be84eca75f57ca9 Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Tue, 25 Mar 2014 11:49:26 +0400 Subject: [PATCH] scrollbars support --- dlanguilib.visualdproj | 12 ++-- examples/example1/example1.visualdproj | 2 +- .../res/btn_default_small_normal.9.png | Bin 1508 -> 582 bytes .../btn_default_small_normal_disable.9.png | Bin 1487 -> 557 bytes .../res/btn_default_small_normal_hover.9.png | Bin 0 -> 670 bytes .../res/btn_default_small_pressed.9.png | Bin 1413 -> 497 bytes .../res/btn_default_small_selected.9.png | Bin 1391 -> 481 bytes .../res/expander_close_holo_light.9.png | Bin 0 -> 371 bytes src/dlangui/core/events.d | 39 +++++++++++ src/dlangui/platforms/windows/winapp.d | 6 +- src/dlangui/widgets/controls.d | 66 ++++++++++++++++-- src/dlangui/widgets/styles.d | 14 +++- src/dlangui/widgets/widget.d | 10 ++- 13 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 examples/example1/res/btn_default_small_normal_hover.9.png create mode 100644 examples/example1/res/expander_close_holo_light.9.png 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 5dddd4640d9c603443dc3fc2ac3dc01e82a92c91..bc7caa51ee465d7a9a32a08f61ab5cf6ab54a81e 100644 GIT binary patch literal 582 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 Eg2S>Rk^lez literal 0 HcmV?d00001 diff --git a/examples/example1/res/btn_default_small_pressed.9.png b/examples/example1/res/btn_default_small_pressed.9.png index 43e82f977878dff5b8501a8916d69fc8fa89d639..6c651e50189fc19fc830bd5f72b040a12d38f3fb 100644 GIT binary patch literal 497 zcmVPx#32;bRa{vGf6951U69E94oEQKA00(qQO+^RZ0~rS;Gu%BAP5=M_gGod|R7l6Q zmO)CxKoo|*nWSQ+Sl(7}kxJZn1?fe+g1Gkt?!_y35$O>W1hEK$Zi+!0t5`D6h11e# z)l7^JW)o(9-v7Nnlfdt#74~36!~m;657-1Es#O8p0z=?61}w0>w|{iJ)l2&X)b;S{ z?DXXD0633<7)X;O?cdx#;0jks#734RN&7$wT+W2rs>*a)RPLs51*!_r2IAN=X{l4x zX^6Ag{#KS{dF-D>s)}O5gg!co@Sp*VBfR_>QxeibgN6JVg9i;@RTYEQv1S*AjH+Tx zEk-44_79B89Ra}|u>`ga&Co)QY=1qKblx5lD;?zP`X=)4tGU;qq^h{XO!U>#WV n-|~x}6hvePm;w{v33z!20F1Tz_e_sn00000NkvXXu0mjfgMHNj literal 1413 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3M!3HD`oXegDq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Keo`G(%fti7VnW3Jc zv5C34xsHO7fuVuEfswwUk*=Y+m9dePfq?=PC;@FNN=dT{a&d#&1?1T(Wt5Z@Sn2DR zmzV368|&p4rRy77T3Uk4Ff!5ws?aU2%qvN((9J7WhMC}!TAW;zSx}OhpQivaF)=B> zw8T~k=u(ImatnNY;RfdwLjwvJWcn3}1^R}12Ku?VAb){X7ncO3BAkI$b#X{#L8^XG zYH@yPQ8F+-(v)GEfnkT=B9KC$Ypnc>GJ%njnB$V4T$-DjSK{ens|1wMOUX>JGIVls zHa9e}FflYTFtac;bTYHFbT)K#a&vYxbv83JgqeX&ucd{#rK6*%tCNeNxuKzpn}w5w znT5Hble3eVo1vkh2~4kNUU5lcUUDkT-b|pqP`xgA^;$U>r6!i-7lq{K=fF}xKt_H^ zesM;Afr4|ese*4}a%LWg4~ia$Z(UN0GRsm^+=}vZ6~N(Zm5IfEXG0@%b2D>eBNHQI z?EZ%6O(7@D^ns4i2PF=q!~zonra%xAp7ennc;-pX1Ll|_VAjYMi95%@z_``Z#WAGf z)|D_{Z)QV*xt`^&t}OgbB6~PQTWme|de%>3ukT>5pH#8>xRY(Apcnrlg`=x-jr}%7 zzOCCb*JXOr14ps6xO@A2)EFo5f9hb}BI(j#Q?cu$MUsq>lvAJNzC+1rTaT7 zx+NJi-}p?juxFh-`B_w7ztYB!Cfgjnn(uG;`0>uZfRK(1hC+c!^7@$?dE2x?Ie)JD zt9EXt_|((>r~jUf-Z&*<>FVT;q^&W979XudlV!UU9Sl80vd_jI>6h4gB6*d@`_Qm} zrAf1*d2{(cezkaOt$K7ua8CW{;Ei!_3wvj~Gj^#yb=#(uwb|*fvUZN|qx)A1Jq!!P0E#>)9tPoS)Z7b@p($(DmWz{<|2c9kaR&59q_;-tI&5otbYa>?N_;dd914;L@ zdmr}kzkT4^>yuZ;(!F}d_Uk*HCvQ}I^4H`}Pjq|X#2dC;iPJZ}?UH1bo1s*fyvOR2 z=9F1AU2h7P+gM#Vqq{(RzU$Mo-)dx@`4`$cKS~VvH=Ti*A-8+6=F5ChW>CTC>FVdQ I&MBb@0Bgbd7XSbN diff --git a/examples/example1/res/btn_default_small_selected.9.png b/examples/example1/res/btn_default_small_selected.9.png index 7a376a97f0d695fb8dedaf5f7dc8708276f8a174..6ef7653aa21d1bcce539e6f24e5f03d00bfaf86c 100644 GIT binary patch literal 481 zcmV<70UrK|P)Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RZ0~rS-B{A}rUH||Ab4f%&R7l6Q zmd{GVKoG`%vrW}{uy|^*2qNgk7m;52HXa189=!ShK0_~}k5N$YBn43n6k0`$)n?a& zo1`g$W;b;XIc2_le`Yod%gdB_2LYtl>umu0z%EduT*bf>@YwJ7zXCu3hkM5-=bd(| zi$guXhS$TJi&Nk(00Q8k({6RcXi99P6i7`Bop!4`ge%}70crruj4I7$mVK}R1j>3+ zH^$&vwx%kS(J7$vgHt(170k{_Q(Aj?qzf2T^(bTH zpPHICTmBxVI-?5GQjgwNm0EKZ9%a%z;-@HnBOcPEU?3}a^k33EhTA0LH^2QxjPpQR zj}~^#Us|4#7WeZ=3#(_8rKWthY%#UiV~%1|aQOQ(5}=u$M>+ zs`|DI&?Nd910z5O_Iff1Z_h46*a6l`;(P-yzyOG4?h>&DY}$YM{SuHP;0O2w-ht>B Xcu0iMqn5Om00000NkvXXu0mjfJ#@v| literal 1391 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3M!3HD`oXegDq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$^BXQ!4Z zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Keo`G(%fti7VnW3Jc zv5C34xsHO7fuVuEfswwUk*=Y+m9dePfq?=PC;@FNN=dT{a&d#&1?1T(Wt5Z@Sn2DR zmzV368|&p4rRy77T3Uk4Ff!5ws?aU2%qvN((9J7WhMC}!TAW;zSx}OhpQivaF)=B> zw8T~k=u(ImatnNY;RfdwLjwvJWcn3}1^R}12Ku?VAb){X7ncO3BAkI$b#X{#L8^XG zYH@yPQ8F+-(v)GEfnkT=B9KC$Ypnc>GJ%njnB$V4T$-DjSK{ens|1wMOUX>JGIVls zHa9e}FflYTFtac;bTYHFbT)K#a&vYxbv83JgqeX&ucd{Bft#VRsgsMLxuKzpn}w5w znT5Hble3eVo1vkh2~4kNUU5lcUUDkT-b|pqP`xI2^;$U>r6!i-7lq{K=fF}xKt_H^ zesM;Afr4|ese*4}a%LWg4~ia$Z(UN0GRsm^+=}vZ6~N(Zm5IfEXG0@%b2D>eBNHQI z?EZ%6O(7@D^ns4i2PF=q!~zonra%xAp7ennc;-pX1Ll|_VAkmW$CAy!z&PL2#WAGf z)}1hGKW0M#*=lnRjUOc(6WJKK+&f&HXFm=oVmKAk7=7WALLsAygNI4yihw2!j>a|Z z>FXVTpKQwA0Xl^y3LzPfedO6%i8eHwR8`ybSN43se}_Vw*o`Y33wMaB z9*yigv}YQ}rbSndC&|^ur0+hP7BFLZMqEmFIz`}@mA^MJ$8*w+8P@Quyp%FZb(Yrcupez)3igGEfH z@_qyR11IL<> ne0!aRy;o_**zlbCFOb0CD713zv9QicP!Z_q>gTe~DWM4fzpL@p 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 0000000000000000000000000000000000000000..54149e9a6239dafbd21dafc02d785464b6d98fa9 GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4uAB#T}@sR2@q#X;^)4C~IxyaaMM3p^r=85p=b zL736}mj2AvWZ7mNE&l`j0nG0vN z^t_S2UR2b%hMS!IHDb&WS6i<)(f6bFlF&P{LkPQbJ-z z?;Gju#YNq_{{8)({j+l}YoN!u)TD%jAL$S65+#j|qo4HWuP>i#8}R<*kpl-lOrIQm z=elF{r5}E+!E~E+o literal 0 HcmV?d00001 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).