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