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 }