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).