ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/dclient/src/backend/ndk/edit.cpp
Revision: 1.3
Committed: Mon Oct 18 15:34:23 2010 UTC (13 years, 8 months ago) by sf-pippijn
Branch: MAIN
Changes since 1.2: +4 -4 lines
Log Message:
first attempt to support maximising windows

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