]> git.tdb.fi Git - libs/gltk.git/blob - source/entry.cpp
Support multiline text editing
[libs/gltk.git] / source / entry.cpp
1 /* $Id$
2
3 This file is part of libmspgltk
4 Copyright © 2007-2010  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/gl/matrix.h>
9 #include <msp/gl/texture.h>
10 #include <msp/gl/transform.h>
11 #include <msp/input/keys.h>
12 #include "entry.h"
13 #include "graphic.h"
14 #include "part.h"
15 #include "style.h"
16
17 using namespace std;
18
19 namespace Msp {
20 namespace GLtk {
21
22 Entry::Entry(const Resources &r, const string &t):
23         Widget(r),
24         text(),
25         multiline(false),
26         edit_pos(0)
27 {
28         update_style();
29         set_text(t);
30 }
31
32 void Entry::set_text(const string &t)
33 {
34         text=t;
35         edit_pos=text.size();
36 }
37
38 void Entry::set_multiline(bool m)
39 {
40         multiline = m;
41 }
42
43 void Entry::key_press(unsigned key, unsigned, wchar_t ch)
44 {
45         if(key==Input::KEY_LEFT)
46         {
47                 if(edit_pos>0)
48                         --edit_pos;
49         }
50         else if(key==Input::KEY_RIGHT)
51         {
52                 if(edit_pos<text.size())
53                         ++edit_pos;
54         }
55         else if(key==Input::KEY_DOWN && multiline)
56         {
57                 unsigned row, col;
58                 text.offset_to_coords(edit_pos, row, col);
59                 edit_pos=text.coords_to_offset(row+1, col);
60         }
61         else if(key==Input::KEY_UP && multiline)
62         {
63                 unsigned row, col;
64                 text.offset_to_coords(edit_pos, row, col);
65                 if(row>0)
66                         edit_pos=text.coords_to_offset(row-1, col);
67                 else
68                         edit_pos=0;
69         }
70         else if(key==Input::KEY_BACKSPACE)
71         {
72                 if(edit_pos>0)
73                         text.erase(--edit_pos, 1);
74         }
75         else if(key==Input::KEY_ENTER)
76         {
77                 if(multiline)
78                         text.insert(edit_pos++, "\n");
79                 else
80                         signal_enter.emit();
81         }
82         else if(ch>=' ')
83         {
84                 text.insert(edit_pos, Codecs::encode<Codecs::Utf8>(Codecs::ustring(1, ch)));
85                 ++edit_pos;
86         }
87 }
88
89 void Entry::render_special(const Part &part) const
90 {
91         if(part.get_name()=="text")
92                 text.render(part, geom);
93         else if(part.get_name()=="cursor")
94         {
95                 if(!part.get_graphic(state))
96                         return;
97
98                 unsigned row, col;
99                 text.offset_to_coords(edit_pos, row, col);
100
101                 Geometry rgeom=text.coords_to_geometry(row, col);
102                 part.get_alignment().apply(rgeom, geom, part.get_margin());
103
104                 GL::push_matrix();
105                 GL::translate(rgeom.x, rgeom.y, 0);
106                 part.get_graphic(state)->render(part.get_geometry().w, part.get_geometry().h);
107                 GL::pop_matrix();
108         }
109 }
110
111 void Entry::on_style_change()
112 {
113         text.set_style(style);
114 }
115
116
117 Entry::Loader::Loader(Entry &ent):
118         Widget::Loader(ent)
119 { }
120
121 } // namespace GLtk
122 } // namespace Msp