ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/dclient/src/backend/ndk/edit.cpp
Revision: 1.6
Committed: Sun Oct 24 20:31:50 2010 UTC (13 years, 8 months ago) by sf-pippijn
Branch: MAIN
Changes since 1.5: +6 -6 lines
Log Message:
use EV and plain sockets instead of asio

File Contents

# Content
1 /* edit.cc
2 * This file is part of NDK++ library
3 * Copyright (c) 2003,2004 by Stanislav Ievlev
4 *
5 * This file is covered by the GNU Library General Public License,
6 * which should be included with libndk as the file COPYING.
7 */
8 #include <ndk/application.hh>
9 #include <ndk/edit.hh>
10 #include <ndk/packer.hh>
11 #include <ndk/palette.hh>
12
13 #include <ndk/pen.hh>
14
15 #include <cctype>
16
17
18 using ndk::edit;
19
20 edit::edit (std::string const &str, panel *parent, bool accept)
21 : button (str, parent, accept)
22 , current_ (0)
23 , begin_ (0)
24 , mode_ (normal)
25 {
26 events ()->on_keyboard (slot (&edit::at_keyboard, this));
27 events ()->on_system (slot (&edit::at_system, this));
28 }
29
30 void
31 edit::resize (int size)
32 {
33 button::resize (size, 1);
34 }
35
36 void
37 edit::set_text (std::string const &str)
38 {
39 label::set_text (str);
40 current_ = text_.length ();
41 draw ();
42 }
43
44 void
45 edit::set_mode (echo_mode mode)
46 {
47 mode_ = mode;
48 }
49
50 void
51 edit::change_color ()
52 {
53 pen (*this).set_color (palette::instance ().find (
54 state_ == engine::enter_focus
55 ? colors::edit_active
56 : colors::edit_inactive
57 )->second);
58 }
59
60 void
61 edit::draw ()
62 {
63 /* first process flags */
64 std::string out;
65
66 switch (mode_)
67 {
68 case normal:
69 out.assign (text ());
70 break;
71 case no_echo:
72 out.assign ("");
73 break;
74 case password:
75 out.assign (std::string (text ().size (), '*'));
76 break;
77 default:
78 break;
79 }
80
81 label::draw (out, begin_); /* and draw */
82 set_cursor (); /* and finally update cursor position */
83 pen (*this).commit (); /* commit changes to the screen */
84 }
85
86 ndk::event::result
87 edit::at_system (event const &ev)
88 {
89 event::result res = event::ignored;
90
91 if (!ev.sender_)
92 {
93 if (engine::enter_focus == ev.type_)
94 {
95 app->cursor_on ();
96 set_cursor (); /* only set cursor position, don't need full redraw */
97 res = event::accepted;
98 }
99 else if (engine::leave_focus == ev.type_)
100 {
101 app->cursor_off ();
102 res = event::accepted;
103 }
104 }
105 return res;
106 }
107
108 ndk::event::result
109 edit::at_keyboard (keyboard const &ev)
110 {
111 event::result res = event::ignored;
112 unsigned int pos = current_;
113
114 switch (ev.code ())
115 {
116 case key::right:
117 (scroll_right ()) ? draw () : set_cursor ();
118 res = event::accepted;
119 break;
120 case key::left:
121 (scroll_left ()) ? draw () : set_cursor ();
122 res = event::accepted;
123 break;
124 case key::backspace:
125 --pos; /* try to go to previous position */
126 if (pos < text_.length ())
127 {
128 erase (pos);
129 scroll_left (); /* scroll all view to the left */
130 draw (); /* we always need full redraw */
131 res = event::accepted;
132 }
133 break;
134 case key::dc:
135 if (pos < text_.length ())
136 {
137 erase (pos);
138 draw (); /* we always need full redraw */
139 res = event::accepted;
140 }
141 break;
142 case key::home:
143 begin_ = 0;
144 current_ = 0;
145 draw ();
146 res = event::accepted;
147 break;
148 case key::end:
149 current_ = text_.length ();
150 (recalibrate ()) ? draw () : set_cursor ();
151 res = event::accepted;
152 break;
153 case '\r':
154 on_commit_ (text_);
155 break;
156 case '\t': /* don't beep on tab */
157 break;
158 default: /* enter key to the string */
159 if (std::isprint (int (ev.code ())))
160 {
161 insert (pos, char (ev.code ()));
162 scroll_right ();
163 draw (); /* we always need full redraw */
164 res = event::accepted;
165 }
166 #if 0
167 else
168 throw ev.code ();
169 #endif
170 break;
171 }
172
173 return res;
174 }
175
176 bool
177 edit::scroll_right ()
178 {
179 if (current_ < int (text_.length ()))
180 ++current_; /* increase current */
181 /* recalibrate begin, decide are we need to redraw */
182 return recalibrate ();
183 }
184
185 bool
186 edit::scroll_left ()
187 {
188 if (current_ > 0)
189 --current_; /* decrease current */
190 /* recalibrate begin, decide are we need to redraw */
191 return recalibrate ();
192 }
193
194 bool
195 edit::recalibrate ()
196 {
197 bool res = false;
198
199 if ((begin_ < current_) && ((current_ - begin_) > (width () - 1)))
200 {
201 /* may be cursor is over(after) edit screen? */
202 begin_ = current_ - width () + 1;
203 res = true;
204 }
205 else if (begin_ > current_)
206 {
207 /* may be cursor is over(before) edit screen? */
208 begin_ = current_;
209 res = true;
210 }
211 return res;
212 }
213
214 void
215 edit::set_cursor ()
216 {
217 /* always move to zero position in no_echo mode */
218 return_unless (pen (*this).move (mode_ != no_echo ? current_ - begin_ : 0, 0));
219 pen (*this).commit ();
220 }
221
222 void
223 edit::insert (int pos, char sym)
224 {
225 text_.insert (text_.begin () + pos, sym); /* default mode is insert mode */
226 }
227
228 void
229 edit::erase (int pos)
230 {
231 text_.erase (text_.begin () + pos);
232 }