1 /**
2 Copyright: Copyright (c) 2014 Andrey Penechko.
3 License: a$(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module anchovy.gui.behaviors.scrollbarbehavior;
8 
9 import anchovy.gui;
10 import anchovy.gui.interfaces.iwidgetbehavior;
11 
12 // version = Button_debug;
13 
14 alias ScrollbarBehaviorVert = ScrollbarBehavior!true;
15 alias ScrollbarBehaviorHori = ScrollbarBehavior!false;
16 
17 class ScrollbarBehavior(bool vertical) : IWidgetBehavior
18 {
19 protected:
20 	Widget _slider;
21 	Widget _body;
22 	Widget _widget;
23 	double _sliderSize = 0.5;
24 	double _sliderPos = 0.0;
25 
26 public:
27 
28 	override void attachTo(Widget widget)
29 	{
30 		_body = widget["subwidgets"].get!(Widget[string]).get("body", null);
31 		_slider = widget["subwidgets"].get!(Widget[string]).get("slider", null);
32 		_widget = widget;
33 
34 		if (_slider && _body)
35 		{
36 			_body.size.valueChanged.connect((FlexibleObject obj, Variant value){updateSize();});
37 			_slider.position.valueChanging.connect(&handleSliderMoved);
38 
39 			_widget["sliderSize"] = new ValueProperty(_widget, cast(double)_sliderSize);
40 			_widget["sliderPos"] = new ValueProperty(_widget, cast(double)_sliderPos);
41 
42 			_widget.property("sliderPos").valueChanging.connect(&handleSliderPositionChanging);
43 
44 			updateSize();
45 		}
46 	}
47 
48 	void updateSize()
49 	{
50 		static if (vertical)
51 		{
52 			_slider.setProperty!"size"(ivec2(_body.size.value.get!ivec2.x, cast(int)(_body.size.value.get!ivec2.y * _sliderSize)));
53 			_slider.setProperty!"position"(ivec2(0, 
54 				cast(int)((_body.size.value.get!ivec2.y - _slider["size"].get!ivec2.y) * _widget["sliderPos"].get!double)));
55 		}
56 		else
57 		{
58 			_slider.setProperty!"size"(ivec2(cast(int)(_body.size.value.get!ivec2.x * _sliderSize), _body.size.value.get!ivec2.y));
59 			_slider.setProperty!"position"(
60 				ivec2(cast(int)((_body.size.value.get!ivec2.x - _slider["size"].get!ivec2.x) * _widget["sliderPos"].get!double), 0));
61 		}
62 	}
63 
64 	void handleSliderPositionChanging(FlexibleObject widget, Variant* position)
65 	{
66 		double* pos = (*position).peek!double;
67 		if (!pos) *pos = (*position).coerce!double;
68 
69 		if (pos)
70 		{
71 			if (*pos < 0) *pos = 0;
72 			else if (*pos > 1.0) *pos = 1.0;
73 		}
74 
75 		*position = *pos;
76 	}
77 
78 	void handleSliderMoved(FlexibleObject slider, Variant* position)
79 	{
80 		int newPosition;
81 		int bodySize;
82 		int sliderSize;
83 
84 		static if (vertical)
85 		{
86 			int pos = position.get!ivec2.y;
87 			bodySize = _body.size.value.get!ivec2.y;
88 			sliderSize = _slider.size.value.get!ivec2.y;
89 			newPosition = pos < 0 ? 0 : (pos + sliderSize > bodySize ? bodySize - sliderSize : pos);
90 			(*position) = ivec2(0, newPosition);
91 		}
92 		else
93 		{
94 			int pos = position.get!ivec2.x;
95 			bodySize = _body.size.value.get!ivec2.x;
96 			sliderSize = _slider.size.value.get!ivec2.x;
97 			newPosition = pos < 0 ? 0 : (pos + sliderSize > bodySize ? bodySize - sliderSize : pos);
98 			(*position) = ivec2(newPosition, 0);
99 		}
100 
101 		double sliderPos = cast(double)newPosition / cast(double)(bodySize - sliderSize);
102 		_widget["sliderPos"] = sliderPos is double.nan ? 0 : sliderPos;
103 
104 		writeln("slider moved ", sliderPos);
105 	}
106 
107 }