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 }