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

# 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     * 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 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     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 sf-pippijn 1.3 edit::at_system (event const &ev)
89 sf-pippijn 1.1 {
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 sf-pippijn 1.3 edit::at_keyboard (keyboard const &ev)
111 sf-pippijn 1.1 {
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 sf-pippijn 1.2 return_unless (ncurses::pen (*this).move (mode_ != no_echo ? current_ - begin_ : 0, 0));
220 sf-pippijn 1.1 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     }