1 ///A collection of immediate-mode UI widgets 2 module dgt.ui; 3 4 import dgt.geom : Rectangle, Vector; 5 import dgt.texture : Texture; 6 import dgt.window : Window; 7 8 ///A clickable button 9 struct Button 10 { 11 @disable this(); 12 13 public @nogc nothrow: 14 15 Rectangle area; 16 Vector position; 17 Texture tex, hover, press; 18 19 /** 20 Defines a button 21 22 Params: 23 area = The clickable region of the button 24 position = The spot to draw the button 25 tex = The default texture of the button 26 hover = The texture when the button is hovered over 27 press = The texture when the button is pressed down 28 */ 29 this(in Rectangle area, in Vector position, in Texture tex, in Texture hover, in Texture press) 30 { 31 this.area = area; 32 this.position = position; 33 this.tex = tex; 34 this.hover = hover; 35 this.press = press; 36 } 37 38 ///Draw a button and return if it is pressed 39 bool draw(ref scope Window window) const 40 { 41 bool mouseContained = area.contains(window.mouse); 42 window.draw(mouseContained ? (window.mouseLeftPressed ? press : hover) : tex, 43 position.x, position.y); 44 return mouseContained && window.mouseLeftReleased; 45 } 46 } 47 48 ///A slider that can be moved along a horizontal axis 49 struct Slider 50 { 51 public @nogc nothrow: 52 Rectangle area; 53 Texture slider; 54 55 @disable this(); 56 57 /** 58 Create a slider 59 60 Params: 61 area = The region the slider can move around in 62 sliderHead = The image to draw where the slider is currently pointing 63 */ 64 this(in Rectangle area, in Texture sliderHead) 65 { 66 this.area = area; 67 this.slider = sliderHead; 68 } 69 70 ///Draw a slider with a given normalized value and return its new value 71 float draw(ref scope Window window, in float current) const 72 { 73 window.draw(slider, -slider.size.width / 2 + area.x + current * area.width, 74 -slider.size.height / 2 + area.y + area.height / 2); 75 if (window.mouseLeftPressed && area.contains(window.mouse)) 76 return (window.mouse.x - area.x) / cast(float)(area.width); 77 else 78 return current; 79 } 80 81 } 82 83 ///A rotating selection of options 84 struct Carousel 85 { 86 @disable this(); 87 public @nogc nothrow: 88 Button left, right; 89 Vector position; 90 const(Texture[]) textures; 91 92 ///Create a carousel with a given set of options 93 this(in Button left, in Button right, in Vector currentItemPosition, in Texture[] textures) 94 { 95 this.left = left; 96 this.right = right; 97 this.position = currentItemPosition; 98 this.textures = textures; 99 } 100 101 ///Draw a carousel with a given current index and return the new index 102 int draw(ref scope Window window, in int current) const 103 { 104 int next = current; 105 if (left.draw(window)) 106 next --; 107 if (right.draw(window)) 108 next ++; 109 next = cast(int)((next + textures.length) % textures.length); 110 window.draw(textures[next], position.x, position.y); 111 return next; 112 } 113 }