ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/backend/ndk/text.cpp
Revision: 1.9
Committed: Fri Jan 21 21:56:36 2011 UTC (15 years, 9 months ago) by sf-pippijn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +4 -0 lines
Log Message:
add some hjkl controls

patch by Jonathan Neuschäfer <j.neuschaefer@gmx.net>

File Contents

# Content
1 /* text.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/color.hh>
9 #include <ndk/packer.hh>
10 #include <ndk/palette.hh>
11 #include <ndk/text.hh>
12
13 #include <ndk/pen.hh>
14
15 using ndk::text;
16
17 text::text (std::string const &title, ndk::panel *parent, wrap_type wrapping)
18 : ndk::frame (title, parent)
19 , x_ (0)
20 , y_ (0)
21 , wrapping_ (wrapping)
22 {
23 pen pen (pad_);
24
25 pen.fill (palette::instance ().find (colors::label)->second);
26
27 events ()->on_keyboard (slot (&text::at_keyboard, this));
28 }
29
30 void
31 text::add_text (color c, std::string const &str)
32 {
33 bool at_bottom = y_ + height () >= pad_.height ();
34
35 /* calculate new height */
36 pad_.resize ( wrapping_ == wrap
37 ? width () - 2
38 : std::max (pad_.width (), string_width (str) + 1)
39 , std::max (height (), pen (pad_).y () + string_height (str))
40 );
41 ndk::pen pen (pad_);
42 pen.set_color (c);
43 pen.write (str); /* add next text to the pad */
44
45 if (at_bottom)
46 while (down ())
47 ;
48 }
49
50 void
51 text::draw () /**< draw frame on the panel */
52 {
53 frame::draw ();
54 pad_.draw (*this, x_, y_); /* draw pad content in the viewport */
55 }
56
57 bool
58 text::right ()
59 {
60 if (x_ + width () < pad_.width () - 1)
61 {
62 ++x_;
63 draw ();
64 return true;
65 }
66 return false;
67 }
68
69 bool
70 text::left ()
71 {
72 if (x_ > 0)
73 {
74 --x_;
75 draw ();
76 return true;
77 }
78 return false;
79 }
80
81 bool
82 text::down ()
83 {
84 if (y_ + height () < pad_.height ())
85 {
86 ++y_;
87 draw ();
88 return true;
89 }
90 return false;
91 }
92
93 bool
94 text::up ()
95 {
96 if (y_ > 0)
97 {
98 --y_;
99 draw ();
100 return true;
101 }
102 return false;
103 }
104
105 ndk::event::result
106 text::at_keyboard (keyboard const &ev)
107 {
108 switch (ev.code ())
109 {
110 case key::right:
111 case key::l:
112 right ();
113 break;
114 case key::left:
115 case key::h:
116 left ();
117 break;
118 case key::up:
119 case key::k:
120 up ();
121 break;
122 case key::down:
123 case key::j:
124 down ();
125 break;
126 default:
127 return event::ignored;
128 }
129
130 pen (*this).commit ();
131 emit (changed);
132
133 return event::accepted;
134 }
135
136 int
137 text::string_height (std::string const &str) /**< @return number of strings */
138 {
139 int count = 0;
140
141 if (wrapping_ == wrap)
142 /* in wrap mode we need additional recalculations of the string height */
143 count = str.length () / width () + (str.length () % width () != 0 ? 1 : 0);
144 else
145 /* not wrap mode: only calculate number of '\n' */
146 count = std::count (str.begin (), str.end (), '\n');
147
148 /* we also need an additional space below if line have '\n' at the end */
149 if (*(str.end () - 1) == '\n')
150 ++count; /* grow width if nesessary */
151 return count;
152 }
153
154 int
155 text::string_width (std::string const &str) /**< @return maximum string length */
156 {
157 std::string::const_iterator beg = str.begin ();
158 std::string::const_iterator end = str.end ();
159 ptrdiff_t max_len = 0;
160 bool need_fix = true;
161
162 do
163 {
164 std::string::const_iterator curr (std::find (beg, str.end (), '\n'));
165 max_len = std::max (max_len,
166 std::distance (beg, curr) + ((need_fix) ? pen (pad_).x () : 0));
167 beg = (curr == end) ? curr : (curr + 1);
168 need_fix = false;
169 }
170 while (beg != end);
171
172 return max_len;
173 }
174
175 void
176 text::resize (int w, int h)
177 {
178 frame::resize (w, h);
179 /* grow size of the text if we need it */
180 pad_.resize (std::max (pad_.width (), w + 1), std::max (pad_.height (), h));
181 }
182
183 void
184 text::clear ()
185 {
186 pen (pad_).clear ();
187 x_ = 0;
188 y_ = 0;
189 /* truncate buffer to viewport size */
190 pad_.resize (this->width (), this->height ());
191 draw ();
192 }
193
194 void
195 text::set_text (color c, std::string const &str)
196 {
197 clear ();
198 add_text (c, str);
199 draw ();
200 }
201
202 int
203 text::length () const
204 {
205 return pad_.height ();
206 }
207
208 int
209 text::last_line () const
210 {
211 return y_ + height ();
212 }