]> git.tdb.fi Git - libs/gltk.git/blob - source/image.cpp
Add a datafile statement to set an icon for an Image
[libs/gltk.git] / source / image.cpp
1 #include <msp/gl/meshbuilder.h>
2 #include "image.h"
3 #include "part.h"
4 #include "resources.h"
5 #include "root.h"
6 #include "style.h"
7
8 using namespace std;
9
10 namespace Msp {
11 namespace GLtk {
12
13 Image::Image(const GL::Texture2D *i):
14         image(i),
15         keep_aspect(true)
16 {
17 }
18
19 void Image::autosize_special(const Part &part, Geometry &ageom) const
20 {
21         if(part.get_name()=="image")
22         {
23                 const Sides &margin = part.get_margin();
24                 if(image)
25                 {
26                         ageom.w = max(ageom.w, image->get_width()+margin.left+margin.right);
27                         ageom.h = max(ageom.h, image->get_height()+margin.top+margin.bottom);
28                 }
29                 else
30                 {
31                         ageom.w = max(ageom.w, margin.left+margin.right);
32                         ageom.h = max(ageom.h, margin.top+margin.bottom);
33                 }
34         }
35 }
36
37 void Image::set_image(const GL::Texture2D *i)
38 {
39         image = i;
40         icon_name = string();
41         signal_autosize_changed.emit();
42         rebuild();
43 }
44
45 void Image::set_icon(const string &n)
46 {
47         icon_name = n;
48         update_icon();
49 }
50
51 void Image::set_keep_aspect(bool ka)
52 {
53         keep_aspect = ka;
54         rebuild();
55 }
56
57 void Image::update_icon()
58 {
59         if(style)
60         {
61                 Root *root = find_ancestor<Root>();
62                 if(root)
63                 {
64                         if(icon_name.empty())
65                                 image = 0;
66                         else
67                                 image = &root->get_resources().get<GL::Texture2D>(icon_name);
68                         signal_autosize_changed.emit();
69                         rebuild();
70                         return;
71                 }
72         }
73
74         image = 0;
75 }
76
77 void Image::rebuild_special(const Part &part)
78 {
79         if(part.get_name()=="image")
80         {
81                 if(!image)
82                         return;
83
84                 const Alignment &align = part.get_alignment();
85                 Geometry rgeom = part.get_geometry();
86                 align.apply(rgeom, geom, part.get_margin());
87
88                 if(keep_aspect)
89                 {
90                         float aspect = static_cast<float>(image->get_width())/image->get_height();
91                         if(rgeom.w<rgeom.h*aspect)
92                         {
93                                 unsigned h = static_cast<unsigned>(rgeom.w/aspect);
94                                 rgeom.y += (rgeom.h-h)*align.y;
95                                 rgeom.h = h;
96                         }
97                         else
98                         {
99                                 unsigned w = static_cast<unsigned>(rgeom.h*aspect);
100                                 rgeom.x += (rgeom.w-w)*align.x;
101                                 rgeom.w = w;
102                         }
103                 }
104
105                 GL::MeshBuilder bld(part_cache.create_mesh(part, *image));
106                 bld.color(1.0f, 1.0f, 1.0f);
107                 bld.begin(GL::TRIANGLE_STRIP);
108                 bld.texcoord(0.0, 1.0);
109                 bld.vertex(rgeom.x, rgeom.y+rgeom.h);
110                 bld.texcoord(0.0, 0.0);
111                 bld.vertex(rgeom.x, rgeom.y);
112                 bld.texcoord(1.0, 1.0);
113                 bld.vertex(rgeom.x+rgeom.w, rgeom.y+rgeom.h);
114                 bld.texcoord(1.0, 0.0);
115                 bld.vertex(rgeom.x+rgeom.w, rgeom.y);
116                 bld.end();
117         }
118 }
119
120 void Image::on_style_change()
121 {
122         if(!icon_name.empty())
123                 update_icon();
124 }
125
126 void Image::on_reparent()
127 {
128         if(!icon_name.empty())
129                 update_icon();
130 }
131
132
133 Image::Loader::Loader(Image &img):
134         DataFile::DerivedObjectLoader<Image, Widget::Loader>(img)
135 {
136         add("icon", &Image::icon_name);
137 }
138
139 } // namespace GLtk
140 } // namespace Msp