]> git.tdb.fi Git - libs/gltk.git/blob - source/table.cpp
More flexible storage for Lsit and Dropdown items
[libs/gltk.git] / source / table.cpp
1 #include <stdexcept>
2 #include <msp/gl/matrix.h>
3 #include <msp/gl/meshbuilder.h>
4 #include "part.h"
5 #include "style.h"
6 #include "table.h"
7
8 using namespace std;
9
10 namespace Msp {
11 namespace GLtk {
12
13 Table::Table():
14         rows(1),
15         columns(1),
16         data(1),
17         col_w(1)
18 {
19         focusable = false;
20 }
21
22 void Table::set_rows(unsigned r)
23 {
24         rows = r;
25         data.resize(rows*columns);
26 }
27
28 void Table::set_columns(unsigned c)
29 {
30         vector<string> new_data(rows*c);
31         for(unsigned i=0; i<rows; ++i)
32                 for(unsigned j=0; j<min(c, columns); ++j)
33                         new_data[i*c+j].swap(data[i*columns+j]);
34         data.swap(new_data);
35         columns = c;
36
37         col_w.resize(columns);
38 }
39
40 void Table::set_column_width(unsigned c, unsigned w)
41 {
42         if(c>=columns)
43                 throw invalid_argument("Table::set_column_width");
44         col_w[c] = w;
45 }
46
47 void Table::set_cell_text(unsigned r, unsigned c, const string &t)
48 {
49         if(r>=rows || c>=columns)
50                 throw out_of_range("Table::set_cell_text");
51
52         data[r*columns+c] = t;
53 }
54
55 void Table::rebuild_special(const Part &part, CachedPart &cache)
56 {
57         if(part.get_name()=="cells")
58         {
59                 const GL::Font &font = style->get_font();
60                 float font_size = style->get_font_size();
61
62                 unsigned free_width = geom.w;
63                 for(unsigned i=0; i<columns; ++i)
64                         free_width -= col_w[i];
65
66                 Geometry cgeom;
67                 cgeom.h = geom.h/rows;
68                 cgeom.y = geom.h-cgeom.h;
69
70                 cache.texture = &font.get_texture();
71                 cache.clear_mesh();
72
73                 GL::MeshBuilder bld(*cache.mesh);
74                 for(unsigned i=0; i<rows; ++i)
75                 {
76                         cgeom.x = 0;
77                         for(unsigned j=0; j<columns; ++j)
78                         {
79                                 if(col_w[j])
80                                         cgeom.w = col_w[j];
81                                 else
82                                         cgeom.w = free_width/columns;
83
84                                 const string &text = data[i*columns+j];
85                                 Geometry rgeom;
86                                 rgeom.x = cgeom.x;
87                                 rgeom.y = cgeom.y;
88                                 rgeom.w = static_cast<unsigned>(font.get_string_width(text)*font_size);
89                                 rgeom.h = static_cast<unsigned>((font.get_ascent()-font.get_descent())*font_size);
90
91                                 part.get_alignment().apply(rgeom, cgeom, part.get_margin());
92
93                                 GL::MatrixStack::Push _push(bld.matrix());
94                                 bld.matrix() *= GL::Matrix::translation(rgeom.x, rgeom.y, 0);
95                                 bld.matrix() *= GL::Matrix::scaling(font_size);
96                                 font.draw_string(text);
97
98                                 cgeom.x += cgeom.w;
99                         }
100
101                         cgeom.y -= cgeom.h;
102                 }
103         }
104 }
105
106 void Table::on_style_change()
107 {
108 }
109
110
111 Table::Loader::Loader(Table &t):
112         Widget::Loader(t)
113 {
114         add("cell_text",    &Loader::cell_text);
115         add("column_width", &Loader::column_width);
116         add("columns",      &Loader::columns);
117         add("rows",         &Loader::rows);
118 }
119
120 void Table::Loader::cell_text(unsigned r, unsigned c, const string &t)
121 {
122         static_cast<Table &>(obj).set_cell_text(r, c, t);
123 }
124
125 void Table::Loader::column_width(unsigned c, unsigned w)
126 {
127         static_cast<Table &>(obj).set_column_width(c, w);
128 }
129
130 void Table::Loader::columns(unsigned c)
131 {
132         static_cast<Table &>(obj).set_columns(c);
133 }
134
135 void Table::Loader::rows(unsigned r)
136 {
137         static_cast<Table &>(obj).set_rows(r);
138 }
139
140 } // namespace GLtk
141 } // namespace Msp