1 module ws.gui.scroller;
2 
3 import
4 	std.math,
5 	std.algorithm,
6 	std.conv,
7 	ws.time,
8 	ws.gui.base;
9 
10 
11 class Scroller: Base {
12 	
13 	double scroll = 0;
14 	double scrollSpeed = 0;
15 	double frameTime;
16 	double frameLast;
17 	
18 	override void resize(int[2] size){
19 		super.resize(size);
20 		update;
21 	}
22 
23 	void update(){
24 		if(!children.length)
25 			return;
26 		foreach(c; children){
27 			c.move([pos.x, pos.y+size.h-c.size.h+scroll.to!int]);
28 			c.resize([size.w, c.size.h]);
29 		}
30 		onMouseMove(cursorPos.x, cursorPos.y);
31 		
32 	}
33 
34 	override void resizeRequest(Base child, int[2] size){
35 		child.resize(size);
36 		scroll = scroll.min(size.h - this.size.h).max(0);
37 		update;
38 	}
39 
40 	override void onMouseButton(Mouse.button button, bool pressed, int x, int y){
41 		if(!children.length)
42 			return;
43 		auto maxOffset = (children[0].size.h - size.h).max(0);
44 		if(button == Mouse.wheelDown && scroll < maxOffset){
45 			if(pressed){
46 				scrollSpeed += 25+scrollSpeed.abs;
47 				return;
48 			}
49 		}else if(button == Mouse.wheelUp && scroll > 0){
50 			if(pressed){
51 				scrollSpeed -= 25+scrollSpeed.abs;
52 				return;
53 			}
54 		}else
55 			super.onMouseButton(button, pressed, x, y);
56 	}
57 
58 	override void onDraw(){
59 		if(hidden)
60 			return;
61 		frameTime = now-frameLast;
62 		frameLast = now;
63 		if(scrollSpeed){
64 			scroll = (scroll + scrollSpeed*frameTime*30).min(children[0].size.h - size.h).max(0);
65 			scrollSpeed = scrollSpeed.eerp(0, frameTime*15, frameTime*7.5, frameTime/50);
66 			update;
67 		}
68 		draw.clip(pos, size);
69 		super.onDraw();
70 		draw.noclip;
71 	}
72 
73 }
74 
75 
76 double eerp(double current, double target, double a, double b, double c){
77 	auto dir = current < target ? 1 : -1;
78 	auto diff = (current-target).abs;
79 	return current + (dir*(c*diff^^2 + b*diff + a)).min(diff).max(-diff);
80 }
81