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(b == Mouse.buttonLeft && p)
29 			slide(x, y);
30 		sliding = b == Mouse.buttonLeft && p;
31 		if(b == Mouse.wheelDown){
32 			setValue((current - (max-min)/50).max(min).min(max));
33 		}
34 		if(b == Mouse.wheelUp){
35 			setValue((current + (max-min)/50).max(min).min(max));
36 		}
37 	}
38 
39 	override void onMouseFocus(bool f){
40 		if(!f)
41 			sliding = false;
42 	}
43 
44 	override void onMouseMove(int x, int y){
45 		if(sliding)
46 			slide(x, y);
47 	}
48 
49 	override void onDraw(){
50 		draw.setColor([0,0,0,1]);
51 		draw.rect(pos.a + [0, size.y/2-1], [size.x, 2]);
52 		int x = cast(int)((current - min)/(max-min) * (size.x-width) + pos.x+width/2);
53 		draw.setColor(slider);
54 		draw.rect(pos.a + [0, size.y/2-1], [x-pos.x, 2]);
55 		draw.rect(pos.a + [x-pos.x-width/2, 3], [width,width]);
56 		//draw.setColor(slider);
57 		draw.setColor([0.1,0.1,0.1,1]);
58 		//draw.rect(pos + Point(x-pos.x, 2), Point(2, size.y-4));
59 		draw.rect(pos.a + [x-pos.x-width/2+2, 5], [width-4,width-4]);
60 	}
61 
62 	void setValue(float v){
63 		if(v != current){
64 			if(v < min || v > max)
65 				throw new RangeError(v, min, max);
66 			current = v;
67 			onSlide(v);
68 		}
69 	}
70 
71 	void set(float value, float min, float max){
72 		if(max <= min)
73 			throw new Exception(tostring("Min is larger than max (% > %)", min, max));
74 		if(value < min || value > max)
75 			throw new RangeError(value, min, max);
76 		current = value;
77 		this.min = min;
78 		this.max = max;
79 	}
80 
81 	override void resize(int[2] size){
82 		width = size.h-6;
83 		super.resize(size);
84 	}
85 
86 	protected:
87 		float min = 0;
88 		float max = 1;
89 		float current = 0.5;
90 		int width;
91 		bool sliding;
92 
93 		void slide(int x, int y){
94 			float normalized = clamp(cast(float)(x-pos.x-width/2)/cast(float)(size.x-width), 0, 1);
95 			setValue((max - min)*normalized + min);
96 		}
97 
98 }
99 
100 class RangeError: Exception {
101 	
102 	this(float v, float min, float max){
103 		super(tostring("Range error (Value: %, min: %, max: %)", v, min, max));
104 	}
105 	
106 }