]> git.tdb.fi Git - libs/gltk.git/blob - source/table.cpp
Add Table widget
[libs/gltk.git] / source / table.cpp
1 /* $Id$
2
3 This file is part of libmspgltk
4 Copyright © 2008  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/gl/matrix.h>
9 #include <msp/gl/transform.h>
10 #include "part.h"
11 #include "style.h"
12 #include "table.h"
13
14 using namespace std;
15
16 namespace Msp {
17 namespace GLtk {
18
19 Table::Table(const Resources &r):
20         Widget(r),
21         rows(1),
22         columns(1),
23         data(1),
24         col_w(1)
25 {
26         update_style();
27 }
28
29 void Table::set_rows(unsigned r)
30 {
31         rows=r;
32         data.resize(rows*columns);
33 }
34
35 void Table::set_columns(unsigned c)
36 {
37         vector<string> new_data(rows*c);
38         for(unsigned i=0; i<rows; ++i)
39                 for(unsigned j=0; j<min(c, columns); ++j)
40                         new_data[i*c+j].swap(data[i*columns+j]);
41         data.swap(new_data);
42         columns=c;
43
44         col_w.resize(columns);
45 }
46
47 void Table::set_column_width(unsigned c, unsigned w)
48 {
49         if(c>=columns)
50                 throw InvalidParameterValue("Column index out of bounds");
51         col_w[c]=w;
52 }
53
54 void Table::set_cell_text(unsigned r, unsigned c, const string &t)
55 {
56         if(r>=rows || c>=columns)
57                 throw InvalidParameterValue("Cell coordinates out of bounds");
58
59         data[r*columns+c]=t;
60 }
61
62 void Table::render_special(const Part &part) const
63 {
64         if(part.get_name()=="cells")
65         {
66                 const GL::Font *const font=style->get_font();
67                 const float font_size=font->get_default_size();
68
69                 unsigned free_width=geom.w;
70                 for(unsigned i=0; i<columns; ++i)
71                         free_width-=col_w[i];
72
73                 Geometry cgeom;
74                 cgeom.h=geom.h/rows;
75                 cgeom.y=geom.h-cgeom.h;
76
77                 for(unsigned i=0; i<rows; ++i)
78                 {
79                         cgeom.x=0;
80                         for(unsigned j=0; j<columns; ++j)
81                         {
82                                 if(col_w[j])
83                                         cgeom.w=col_w[j];
84                                 else
85                                         cgeom.w=free_width/columns;
86
87                                 const string &text=data[i*columns+j];
88                                 Geometry rgeom;
89                                 rgeom.x=cgeom.x;
90                                 rgeom.y=cgeom.y;
91                                 rgeom.w=static_cast<unsigned>(font->get_string_width(text)*font_size);
92                                 rgeom.h=static_cast<unsigned>((font->get_ascent()-font->get_descent())*font_size);
93
94                                 part.get_alignment().apply(rgeom, cgeom, part.get_margin());
95
96                                 GL::push_matrix();
97                                 GL::translate(rgeom.x, rgeom.y, 0);
98                                 GL::scale_uniform(font_size);
99                                 font->draw_string(text);
100                                 GL::pop_matrix();
101
102                                 cgeom.x+=cgeom.w;
103                         }
104
105                         cgeom.y-=cgeom.h;
106                 }
107         }
108 }
109
110 void Table::on_style_change()
111 {
112 }
113
114
115 Table::Loader::Loader(Table &t):
116         Widget::Loader(t)
117 {
118         add("cell_text",    &Loader::cell_text);
119         add("column_width", &Loader::column_width);
120         add("columns",      &Loader::columns);
121         add("rows",         &Loader::rows);
122 }
123
124 void Table::Loader::cell_text(unsigned r, unsigned c, const string &t)
125 {
126         static_cast<Table &>(wdg).set_cell_text(r, c, t);
127 }
128
129 void Table::Loader::column_width(unsigned c, unsigned w)
130 {
131         static_cast<Table &>(wdg).set_column_width(c, w);
132 }
133
134 void Table::Loader::columns(unsigned c)
135 {
136         static_cast<Table &>(wdg).set_columns(c);
137 }
138
139 void Table::Loader::rows(unsigned r)
140 {
141         static_cast<Table &>(wdg).set_rows(r);
142 }
143
144 } // namespace GLtk
145 } // namespace Msp