initial commit
[ld42_outofspace] / src / goatkit / textbox.cc
1 /*
2 GoatKit - a themable/animated widget toolkit for games
3 Copyright (C) 2014  John Tsiombikas <nuclear@member.fsf.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <ctype.h>
19 #include <limits.h>
20 #include <string>
21 #include "textbox.h"
22
23 namespace goatkit {
24
25 struct TextBoxImpl {
26         std::string text;
27         int cursor;
28 };
29
30 TextBox::TextBox()
31 {
32         tbox = new TextBoxImpl;
33         tbox->cursor = 0;
34 }
35
36 TextBox::~TextBox()
37 {
38         delete tbox;
39 }
40
41 const char *TextBox::get_type_name() const
42 {
43         return "textbox";
44 }
45
46 bool TextBox::can_focus() const
47 {
48         return true;
49 }
50
51 void TextBox::clear()
52 {
53         tbox->text.clear();
54 }
55
56 void TextBox::set_text(const char *t)
57 {
58         tbox->text = std::string(t);
59 }
60
61 const char *TextBox::get_text() const
62 {
63         return tbox->text.c_str();
64 }
65
66 int TextBox::set_cursor(int idx)
67 {
68         int len = tbox->text.size();
69
70         if(idx < 0) {
71                 tbox->cursor = 0;
72         } else if(idx > len) {
73                 tbox->cursor = len;
74         } else {
75                 tbox->cursor = idx;
76         }
77         return tbox->cursor;
78 }
79
80 int TextBox::get_cursor() const
81 {
82         return tbox->cursor;
83 }
84
85 int TextBox::cursor_begin()
86 {
87         return tbox->cursor = 0;
88 }
89
90 int TextBox::cursor_end()
91 {
92         return set_cursor(INT_MAX);
93 }
94
95 int TextBox::cursor_prev()
96 {
97         return set_cursor(tbox->cursor - 1);
98 }
99
100 int TextBox::cursor_next()
101 {
102         return set_cursor(tbox->cursor + 1);
103 }
104
105 void TextBox::insert(char c)
106 {
107         int len = tbox->text.size();
108         if(tbox->cursor >= len) {
109                 tbox->text.push_back(c);
110                 tbox->cursor++;
111         } else {
112                 tbox->text.insert(tbox->cursor++, 1, c);
113         }
114 }
115
116 void TextBox::on_key(const KeyEvent &ev)
117 {
118         if(!ev.press) return;   // ignore key release events
119
120         switch(ev.key) {
121         case KEY_LEFT:
122                 cursor_prev();
123                 break;
124
125         case KEY_RIGHT:
126                 cursor_next();
127                 break;
128
129         case KEY_HOME:
130                 cursor_begin();
131                 break;
132
133         case KEY_END:
134                 cursor_end();
135                 break;
136
137         case KEY_DELETE:
138                 tbox->text.erase(tbox->cursor, 1);
139                 break;
140
141         case '\b':
142                 if(tbox->cursor > 0) {
143                         tbox->text.erase(--tbox->cursor, 1);
144                 }
145                 break;
146
147         case '\n':
148         case '\t':
149                 {
150                         Event ev;
151                         ev.type = EV_CHANGE;
152                         handle_event(ev);
153                 }
154                 break;
155
156         default:
157                 if(isprint(ev.key)) {
158                         insert(ev.key);
159                 }
160         }
161 }
162
163 void TextBox::on_click()
164 {
165         // TODO place cursor
166 }
167
168 }       // namespace goatkit