1 // Written in the D programming language. 2 /++ 3 + Authors: KanzakiKino 4 + Copyright: KanzakiKino 2018 5 + License: LGPL-3.0 6 ++/ 7 module w4d.widget.image; 8 import w4d.style.color, 9 w4d.style.scalar, 10 w4d.task.window, 11 w4d.widget.base; 12 import g4d.element.shape.rect, 13 g4d.gl.texture, 14 g4d.shader.base, 15 g4d.util.bitmap; 16 import gl3n.linalg; 17 import std.algorithm, 18 std.math; 19 20 /// A widget of image. 21 class ImageWidget : Widget 22 { 23 protected RectElement _imageElm; 24 protected Tex2D _texture; 25 protected vec2 _imageSize; 26 protected vec2 _uv; 27 28 /// 29 override @property vec2 wantedSize () 30 { 31 return _imageSize; 32 } 33 34 /// 35 this () 36 { 37 super(); 38 39 _imageElm = new RectElement; 40 _texture = null; 41 _imageSize = vec2(0,0); 42 _uv = vec2(0,0); 43 } 44 45 /// Sets new image. 46 void setImage (B) ( B bmp, bool compress = true ) 47 if ( isBitmap!B ) 48 { 49 if ( !bmp ) { 50 _texture = null; 51 _imageSize = vec2(0,0); 52 _uv = vec2(0,0); 53 return; 54 } 55 56 _texture = new Tex2D( bmp, compress ); 57 58 _uv.x = bmp.width*1f / _texture.size.x; 59 _uv.y = bmp.rows *1f / _texture.size.y; 60 _imageSize = vec2(bmp.width,bmp.rows); 61 requestLayout(); 62 } 63 64 protected void resizeElement () 65 { 66 if ( _texture ) { 67 auto sz = style.box.clientSize; 68 _imageElm.resize( sz, _uv ); 69 } 70 } 71 /// 72 override vec2 layout ( vec2 pos, vec2 size ) 73 { 74 if ( style.box.size.width.isNone && style.box.size.height.isNone ) { 75 const w = _imageSize.x, h = _imageSize.y; 76 const ratio = w/h; 77 const maxsz = size; 78 79 size.x = ratio * size.y; 80 if ( size.x > maxsz.x ) { 81 size.x = maxsz.x; 82 size.y = (1f/ratio) * size.x; 83 } 84 } 85 86 scope(success) resizeElement(); 87 return super.layout( pos, size ); 88 } 89 /// 90 override void draw ( Window w, in ColorSet parent ) 91 { 92 super.draw( w, parent ); 93 94 if ( _texture ) { 95 auto shader = w.shaders.rgba3; 96 const saver = ShaderStateSaver( shader ); 97 const late = style.clientLeftTop + style.box.clientSize/2; 98 99 shader.use(); 100 shader.matrix.late = vec3( late, 0 ); 101 shader.matrix.rota = vec3( PI, 0, 0 ); 102 shader.uploadTexture( _texture ); 103 _imageElm.draw( shader ); 104 } 105 } 106 107 /// 108 override @property bool trackable () { return false; } 109 /// 110 override @property bool focusable () { return false; } 111 }