ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/dclient/src/backend/ndk/edit.cpp
Revision: 1.4
Committed: Mon Oct 18 16:38:03 2010 UTC (13 years, 8 months ago) by sf-pippijn
Branch: MAIN
Changes since 1.3: +0 -1 lines
Log Message:
support msg colours

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 <ncurses/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 ncurses::pen (*this).set_color (palette::instance ()
54 [
55 state_ == engine::enter_focus
56 ? colors::edit_active
57 : colors::edit_inactive
58 ]);
59 }
60
61 void
62 edit::draw ()
63 {
64 /* first process flags */
65 std::string out;
66
67 switch (mode_)
68 {
69 case normal:
70 out.assign (text ());
71 break;
72 case no_echo:
73 out.assign ("");
74 break;
75 case password:
76 out.assign (std::string (text ().size (), '*'));
77 break;
78 default:
79 break;
80 }
81
82 label::draw (out, begin_); /* and draw */
83 set_cursor (); /* and finally update cursor position */
84 ncurses::pen (*this).commit (); /* commit changes to the screen */
85 }
86
87 ndk::event::result
88 edit::at_system (event const &ev)
89 {
90 event::result res = event::ignored;
91
92 if (!ev.sender_)
93 {
94 if (engine::enter_focus == ev.type_)
95 {
96 app ().cursor_on ();
97 set_cursor (); /* only set cursor position, don't need full redraw */
98 res = event::accepted;
99 }
100 else if (engine::leave_focus == ev.type_)
101 {
102 app ().cursor_off ();
103 res = event::accepted;
104 }
105 }
106 return res;
107 }
108
109 ndk::event::result
110 edit::at_keyboard (keyboard const &ev)
111 {
112 event::result res = event::ignored;
113 unsigned int pos = current_;
114
115 switch (ev.code ())
116 {
117 case key::right:
118 (scroll_right ()) ? draw () : set_cursor ();
119 res = event::accepted;
120 break;
121 case key::left:
122 (scroll_left ()) ? draw () : set_cursor ();
123 res = event::accepted;
124 break;
125 case key::backspace:
126 --pos; /* try to go to previous position */
127 if (pos < text_.length ())
128 {
129 erase (pos);
130 scroll_left (); /* scroll all view to the left */
131 draw (); /* we always need full redraw */
132 res = event::accepted;
133 }
134 break;
135 case key::dc:
136 if (pos < text_.length ())
137 {
138 erase (pos);
139 draw (); /* we always need full redraw */
140 res = event::accepted;
141 }
142 break;
143 case key::home:
144 begin_ = 0;
145 current_ = 0;
146 draw ();
147 res = event::accepted;
148 break;
149 case key::end:
150 current_ = text_.length ();
151 (recalibrate ()) ? draw () : set_cursor ();
152 res = event::accepted;
153 break;
154 case '\r':
155 on_commit_ (text_);
156 break;
157 case '\t': /* don't beep on tab */
158 break;
159 default: /* enter key to the string */
160 if (std::isprint (int (ev.code ())))
161 {
162 insert (pos, char (ev.code ()));
163 scroll_right ();
164 draw (); /* we always need full redraw */
165 res = event::accepted;
166 }
167 #if 0
168 else
169 throw ev.code ();
170 #endif
171 break;
172 }
173
174 return res;
175 }
176
177 bool
178 edit::scroll_right ()
179 {
180 if (current_ < int (text_.length ()))
181 ++current_; /* increase current */
182 /* recalibrate begin, decide are we need to redraw */
183 return recalibrate ();
184 }
185
186 bool
187 edit::scroll_left ()
188 {
189 if (current_ > 0)
190 --current_; /* decrease current */
191 /* recalibrate begin, decide are we need to redraw */
192 return recalibrate ();
193 }
194
195 bool
196 edit::recalibrate ()
197 {
198 bool res = false;
199
200 if ((begin_ < current_) && ((current_ - begin_) > (width () - 1)))
201 {
202 /* may be cursor is over(after) edit screen? */
203 begin_ = current_ - width () + 1;
204 res = true;
205 }
206 else if (begin_ > current_)
207 {
208 /* may be cursor is over(before) edit screen? */
209 begin_ = current_;
210 res = true;
211 }
212 return res;
213 }
214
215 void
216 edit::set_cursor ()
217 {
218 /* always move to zero position in no_echo mode */
219 return_unless (ncurses::pen (*this).move (mode_ != no_echo ? current_ - begin_ : 0, 0));
220 ncurses::pen (*this).commit ();
221 }
222
223 void
224 edit::insert (int pos, char sym)
225 {
226 text_.insert (text_.begin () + pos, sym); /* default mode is insert mode */
227 }
228
229 void
230 edit::erase (int pos)
231 {
232 text_.erase (text_.begin () + pos);
233 }