1 module evael.graphics.gui.controls.PictureBox; 2 3 import evael.graphics.gui.controls.Control; 4 import evael.graphics.gui.controls.Panel; 5 import evael.graphics.gui.controls.TextBlock; 6 7 import evael.graphics.Texture; 8 9 import evael.utils.Math; 10 import evael.utils.Size; 11 import evael.utils.Color; 12 import evael.utils.Rectangle; 13 14 class PictureBox : Control 15 { 16 enum ScaleType 17 { 18 Center, 19 Fit 20 } 21 22 /// Scale type 23 private ScaleType m_scaleType; 24 25 public this(in float x, in float y, in int width, in int height) 26 { 27 this(vec2(x, y,), Size!int(width, height)); 28 } 29 30 public this()(in auto ref vec2 position, in auto ref Size!int size) 31 { 32 super(position, size); 33 34 this.m_name = "pictureBox"; 35 36 this.m_scaleType = ScaleType.Fit; 37 } 38 39 /** 40 * Renders the picturebox 41 */ 42 public override void draw(in float deltaTime) 43 { 44 if(!this.m_isVisible) 45 { 46 return; 47 } 48 49 super.draw(deltaTime); 50 51 if(this.m_texture is null) 52 { 53 return; 54 } 55 56 immutable x = this.m_realPosition.x; 57 immutable y = this.m_realPosition.y; 58 immutable w = this.m_size.width; 59 immutable h = this.m_size.height; 60 61 auto vg = this.m_nvg; 62 63 // https://github.com/memononen/nanovg/issues/348 64 // Aspect ratios of pixel in x and y dimensions. 65 // This allows us to scale the sprite to fill the whole rectangle. 66 immutable ax = cast(float)w / this.m_textureCoords.size.width; 67 immutable ay = cast(float)h / this.m_textureCoords.size.height; 68 69 // si w = 48 70 // ax = 1 71 // si w = 28 72 // ax = 0.58 73 NVGpaint imgPaint = nvgImagePattern(vg, x - this.m_textureCoords.left * ax, y - this.m_textureCoords.bottom * ay, 74 this.m_texture.size.width * ax , this.m_texture.size.height * ay, 0, this.m_texture.nvgId, this.m_opacity / 255.0f); 75 76 nvgBeginPath(vg); 77 nvgRoundedRect(vg, x, y, w, h, 3); 78 nvgFillPaint(vg, imgPaint); 79 nvgFill(vg); 80 } 81 82 /** 83 * Event called on mouse button click 84 * Params: 85 * mouseButton : mouse button 86 * mousePosition : mouse position 87 */ 88 public override void onMouseClick(in MouseButton mouseButton, in ref vec2 mousePosition) 89 { 90 super.onMouseClick(mouseButton, mousePosition); 91 this.switchState!(State.Clicked); 92 } 93 94 /** 95 * Event called on mouse button release 96 * Params: 97 * mouseButton : mouse button 98 */ 99 public override void onMouseUp(in MouseButton mouseButton) 100 { 101 super.onMouseUp(mouseButton); 102 this.switchState!(State.Hovered); 103 } 104 105 /** 106 * Event called when mouse enters in control's rect 107 * Params: 108 * mousePosition : mouse position 109 */ 110 public override void onMouseMove(in ref vec2 mousePosition) 111 { 112 if(this.hasFocus) 113 { 114 return; 115 } 116 117 super.onMouseMove(mousePosition); 118 119 if(this.isClicked) 120 { 121 this.switchState!(State.Clicked); 122 } 123 else 124 { 125 this.switchState!(State.Hovered); 126 } 127 } 128 129 /** 130 * Event called when mouse leaves in control's rect 131 */ 132 public override void onMouseLeave() 133 { 134 super.onMouseLeave(); 135 this.switchState!(State.Normal); 136 } 137 138 @property 139 { 140 public void scaleType(in ScaleType value) nothrow @nogc 141 { 142 this.m_scaleType = value; 143 } 144 } 145 }