1 ///
2 module glui.image_view;
3 
4 import raylib;
5 
6 import glui.node;
7 import glui.utils;
8 import glui.style;
9 
10 alias imageView = simpleConstructor!GluiImageView;
11 
12 @safe:
13 
14 /// A node specifically to display images.
15 ///
16 /// The image will automatically scale to fit available space. It will keep aspect ratio by default and will be
17 /// displayed in the middle of the available box.
18 class GluiImageView : GluiNode {
19 
20     mixin DefineStyles;
21 
22     /// Texture for this node.
23     protected {
24 
25         Texture _texture;
26         Rectangle _targetArea;  // Rectangle occupied by this node after all calculations
27 
28     }
29 
30     static foreach (index; 0 .. BasicNodeParamLength) {
31 
32         /// Create an image node from given texture or filename.
33         /// Params:
34         ///     source  = `Texture` raylib struct to use, or a filename to load from.
35         ///     minSize = Minimum size of the node
36         this(T)(BasicNodeParam!index sup, T source, Vector2 minSize = Vector2(0, 0)) {
37 
38             super(sup);
39             texture = source;
40             super.minSize = minSize;
41 
42         }
43 
44     }
45 
46     @property {
47 
48         /// Set the texture.
49         Texture texture(Texture texture) {
50 
51             return this._texture = texture;
52 
53         }
54 
55         /// Load the texture from a filename.
56         string texture(string filename) @trusted {
57 
58             import std..string : toStringz;
59 
60             texture = LoadTexture(filename.toStringz);
61             updateSize();
62 
63             return filename;
64 
65         }
66 
67         /// Get the current texture.
68         const(Texture) texture() const {
69 
70             return _texture;
71 
72         }
73 
74     }
75 
76     /// Minimum size of the image.
77     @property
78     ref inout(Vector2) minSize() inout {
79 
80         return super.minSize;
81 
82     }
83 
84     /// Area on the screen the image was last drawn to.
85     @property
86     Rectangle targetArea() const {
87 
88         return _targetArea;
89 
90     }
91 
92     override protected void resizeImpl(Vector2 space) {
93 
94     }
95 
96     override protected void drawImpl(Rectangle, Rectangle rect) @trusted {
97 
98         import std.algorithm : min;
99 
100         // Get the scale
101         const scale = min(
102             rect.width / texture.width,
103             rect.height / texture.height
104         );
105 
106         const source = Rectangle(0, 0, texture.width, texture.height);
107         const size   = Vector2(texture.width * scale, texture.height * scale);
108 
109         _targetArea = Rectangle(
110             rect.x + rect.w/2 - size.x/2, rect.y + rect.h/2 - size.y/2,
111             size.x, size.y
112         );
113 
114         DrawTexturePro(texture, source, _targetArea, Vector2(0, 0), 0, Colors.WHITE);
115 
116     }
117 
118     override protected bool hoveredImpl(Rectangle, Vector2 mouse) const {
119 
120         return _targetArea.contains(mouse);
121 
122     }
123 
124     override const(Style) pickStyle() const {
125 
126         return null;
127 
128     }
129 
130 }