1 module armos.utils.gui.widgets.slider;
2 
3 import armos.utils.gui.widgets.widget;
4 
5 import armos.events;
6 
7 /++
8 値を操作するSliderを表す,Widgetを継承したclassです.
9 +/
10 class Slider(T) : Widget{
11     import std.format:format;
12     import std.conv;
13     public{
14         /++
15             初期化を行います.Slider固有の名前と操作する値,その上限下限を設定します.
16         +/
17         this(string name, ref T var, T min, T max){
18             _var = &var;
19             _varMin = min;
20             _varMax = max;
21             _name = name;
22             _height = 32;
23 
24             static import armos.app;
25             armos.events.addListener(armos.app.currentEvents.mouseMoved, this, &this.mouseMoved);
26             armos.events.addListener(armos.app.currentEvents.mouseReleased, this, &this.mouseReleased);
27             armos.events.addListener(armos.app.currentEvents.mousePressed, this, &this.mousePressed);
28         };
29 
30         /++
31         +/
32         override void draw(){
33             import armos.graphics.renderer:color,
34                                            drawRectangle;
35 
36             color(_style.colors["background"]);
37             drawRectangle(0, 0, _style.width, _style.font.height*4);
38 
39             string varString = "";
40             static if(__traits(isIntegral, *_var)){
41                 varString = format("%d", *_var).to!string;
42             }else if(__traits(isFloating, *_var)){
43                 varString = format("%f", *_var).to!string;
44             }
45             _style.font.material.uniform("diffuse", _style.colors["font1"]);
46             
47             _style.font.draw(_name ~ " : " ~ varString, _style.font.width, 0);
48 
49             import armos.math:map;
50             immutable int currentValueAsSliderPosition = map( ( *_var ).to!float, _varMin.to!float, _varMax.to!float, 0.0, _style.width.to!float - _style.font.width.to!float*2.0).to!int;
51             color(_style.colors["base1"]);
52             drawRectangle(_style.font.width, _style.font.height, _style.width - _style.font.width*2, _style.font.height*2);
53             color(_style.colors["base2"]);
54             drawRectangle(_style.font.width, _style.font.height, currentValueAsSliderPosition.to!int, _style.font.height*2);
55         };
56 
57         /++
58         +/
59         override void mousePressed(ref armos.events.MousePressedEventArg message){
60             _isPressing = isOnMouse(message.x, message.y);
61         }
62 
63         /++
64         +/
65         override void mouseMoved(ref armos.events.MouseMovedEventArg message){
66             if(_isPressing){
67                 import armos.math:map;
68                 *_var = map( 
69                         ( message.x-_position[0]).to!float,
70                         _style.font.width.to!float, _style.width.to!float - _style.font.width.to!float, 
71                         _varMin.to!float, _varMax.to!float
72                         , true).to!T;
73             }
74         }
75 
76         /++
77         +/
78         override void mouseReleased(ref armos.events.MouseReleasedEventArg message){
79             if(_isPressing){
80                 import armos.math:map;
81                 *_var = map( 
82                         ( message.x-_position[0]).to!float,
83                         _style.font.width.to!float, _style.width.to!float - _style.font.width.to!float, 
84                         _varMin.to!float, _varMax.to!float
85                         , true).to!T;
86                 _isPressing = false;
87             }
88         }
89     }//public
90 
91     private{
92         string _name;
93         T* _var;
94         T _varMin;
95         T _varMax;
96         bool _isPressing = false;
97 
98         bool isOnMouse(int x, int y){
99             immutable int localX = x-_position[0];
100             immutable int localY = y-_position[1];
101             if(_style.font.width<localX && localX<_style.width - _style.font.width){
102                 if(_style.font.height<localY && localY<_height - _style.font.height){
103                     return true;
104                 }
105             }
106             return false;
107         }
108     }//private
109 }//class Slider