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

# User Rev Content
1 sf-pippijn 1.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 sf-pippijn 1.6 * which should be included with libndk as the file COPYING.
7 sf-pippijn 1.1 */
8 sf-pippijn 1.6 #include <ndk/application.hh>
9     #include <ndk/edit.hh>
10     #include <ndk/packer.hh>
11     #include <ndk/palette.hh>
12 sf-pippijn 1.1
13 sf-pippijn 1.6 #include <ndk/pen.hh>
14 sf-pippijn 1.1
15     #include <cctype>
16    
17    
18     using ndk::edit;
19    
20 sf-pippijn 1.3 edit::edit (std::string const &str, panel *parent, bool accept)
21 sf-pippijn 1.1 : 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 sf-pippijn 1.3 edit::set_text (std::string const &str)
38 sf-pippijn 1.1 {
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 sf-pippijn 1.5 pen (*this).set_color (palette::instance ().find (
54     state_ == engine::enter_focus
55     ? colors::edit_active
56     : colors::edit_inactive
57     )->second);
58 sf-pippijn 1.1 }
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 sf-pippijn 1.5 pen (*this).commit (); /* commit changes to the screen */
84 sf-pippijn 1.1 }
85    
86     ndk::event::result
87 sf-pippijn 1.3 edit::at_system (event const &ev)
88 sf-pippijn 1.1 {
89     event::result res = event::ignored;
90    
91     if (!ev.sender_)
92     {
93     if (engine::enter_focus == ev.type_)
94     {
95 sf-pippijn 1.5 app->cursor_on ();
96 sf-pippijn 1.1 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 sf-pippijn 1.5 app->cursor_off ();
102 sf-pippijn 1.1 res = event::accepted;
103     }
104     }
105     return res;
106     }
107    
108     ndk::event::result
109 sf-pippijn 1.3 edit::at_keyboard (keyboard const &ev)
110 sf-pippijn 1.1 {
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 sf-pippijn 1.5 return_unless (pen (*this).move (mode_ != no_echo ? current_ - begin_ : 0, 0));
219     pen (*this).commit ();
220 sf-pippijn 1.1 }
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     }