1 module ws.gui.slider;
2 
3 import
4 	ws.io,
5 	ws.string,
6 	ws.event,
7 	ws.math.math,
8 	ws.gl.draw,
9 	ws.gui.base;
10 
11 class Slider: Base {
12 
13 	float[4] background = [0.2, 0.2, 0.2, 1];
14 	float[4] slider = [1, 0.2, 0.2, 1];
15 
16 	Event!float onSlide;
17 
18 	this(){
19 		onSlide = new Event!float;
20 	}
21 
22 	this(float value, float min, float max){
23 		this();
24 		set(value, min, max);
25 	}
26 
27 	override void onMouseButton(Mouse.button b, bool p, int x, int y){
28 		if(p)
29 			slide(x, y);
30 		sliding = p;
31 	}
32 
33 	override void onMouseFocus(bool f){
34 		if(!f)
35 			sliding = false;
36 	}
37 
38 	override void onMouseMove(int x, int y){
39 		if(sliding)
40 			slide(x, y);
41 	}
42 
43 	override void onDraw(){
44 		draw.setColor(background);
45 		draw.rect(pos, size);
46 		draw.setColor([0,0,0,1]);
47 		draw.rect(pos.a + [0, size.y/2-1], [size.x, 2]);
48 		int x = cast(int)((current - min)/(max-min) * (size.x-width) + pos.x+width/2);
49 		draw.setColor(slider);
50 		draw.rect(pos.a + [0, size.y/2-1], [x-pos.x, 2]);
51 		draw.rect(pos.a + [x-pos.x-width/2, 3], [width,width]);
52 		//draw.setColor(slider);
53 		draw.setColor([0.1,0.1,0.1,1]);
54 		//draw.rect(pos + Point(x-pos.x, 2), Point(2, size.y-4));
55 		draw.rect(pos.a + [x-pos.x-width/2+2, 5], [width-4,width-4]);
56 	}
57 
58 	void setValue(float v){
59 		if(v != current){
60 			if(v < min || v > max)
61 				throw new RangeError(v, min, max);
62 			current = v;
63 			onSlide(v);
64 		}
65 	}
66 
67 	void set(float value, float min, float max){
68 		if(max <= min)
69 			throw new Exception(tostring("Min is larger than max (% > %)", min, max));
70 		if(value < min || value > max)
71 			throw new RangeError(value, min, max);
72 		current = value;
73 		this.min = min;
74 		this.max = max;
75 	}
76 
77 	override void resize(int[2] size){
78 		width = size.h-6;
79 		super.resize(size);
80 	}
81 
82 	protected:
83 		float min = 0;
84 		float max = 1;
85 		float current = 0.5;
86 		int width;
87 		bool sliding;
88 
89 		void slide(int x, int y){
90 			float normalized = clamp(cast(float)(x-pos.x-width/2)/cast(float)(size.x-width), 0, 1);
91 			setValue((max - min)*normalized + min);
92 		}
93 
94 }
95 
96 class RangeError: Exception {
97 	
98 	this(float v, float min, float max){
99 		super(tostring("Range error (Value: %, min: %, max: %)", v, min, max));
100 	}
101 	
102 }