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

# User Rev Content
1 sf-pippijn 1.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 sf-pippijn 1.7 * which should be included with libndk as the file COPYING.
7 sf-pippijn 1.1 */
8 sf-pippijn 1.7 #include <ndk/color.hh>
9     #include <ndk/packer.hh>
10     #include <ndk/palette.hh>
11     #include <ndk/text.hh>
12 sf-pippijn 1.1
13 sf-pippijn 1.7 #include <ndk/pen.hh>
14 sf-pippijn 1.2
15 sf-pippijn 1.1 using ndk::text;
16    
17 sf-pippijn 1.4 text::text (std::string const &title, ndk::panel *parent, wrap_type wrapping)
18     : ndk::frame (title, parent)
19 sf-pippijn 1.1 , x_ (0)
20     , y_ (0)
21     , wrapping_ (wrapping)
22     {
23 sf-pippijn 1.5 pen pen (pad_);
24 sf-pippijn 1.1
25 sf-pippijn 1.5 pen.fill (palette::instance ().find (colors::label)->second);
26 sf-pippijn 1.1
27     events ()->on_keyboard (slot (&text::at_keyboard, this));
28     }
29    
30     void
31 sf-pippijn 1.6 text::add_text (color c, std::string const &str)
32 sf-pippijn 1.1 {
33     bool at_bottom = y_ + height () >= pad_.height ();
34    
35     /* calculate new height */
36     pad_.resize ( wrapping_ == wrap
37 sf-pippijn 1.8 ? width () - 2
38 sf-pippijn 1.1 : std::max (pad_.width (), string_width (str) + 1)
39 sf-pippijn 1.5 , std::max (height (), pen (pad_).y () + string_height (str))
40 sf-pippijn 1.1 );
41 sf-pippijn 1.5 ndk::pen pen (pad_);
42 sf-pippijn 1.4 pen.set_color (c);
43     pen.write (str); /* add next text to the pad */
44 sf-pippijn 1.1
45     if (at_bottom)
46     while (down ())
47     ;
48     }
49    
50     void
51     text::draw () /**< draw frame on the panel */
52     {
53 sf-pippijn 1.4 frame::draw ();
54 sf-pippijn 1.1 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 sf-pippijn 1.3 text::at_keyboard (keyboard const &ev)
107 sf-pippijn 1.1 {
108     switch (ev.code ())
109     {
110     case key::right:
111 sf-pippijn 1.9 case key::l:
112 sf-pippijn 1.1 right ();
113     break;
114     case key::left:
115 sf-pippijn 1.9 case key::h:
116 sf-pippijn 1.1 left ();
117     break;
118     case key::up:
119 sf-pippijn 1.9 case key::k:
120 sf-pippijn 1.1 up ();
121     break;
122     case key::down:
123 sf-pippijn 1.9 case key::j:
124 sf-pippijn 1.1 down ();
125     break;
126     default:
127 sf-pippijn 1.3 return event::ignored;
128 sf-pippijn 1.1 }
129    
130 sf-pippijn 1.5 pen (*this).commit ();
131 sf-pippijn 1.3 emit (changed);
132    
133     return event::accepted;
134 sf-pippijn 1.1 }
135    
136     int
137 sf-pippijn 1.3 text::string_height (std::string const &str) /**< @return number of strings */
138 sf-pippijn 1.1 {
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 sf-pippijn 1.3 text::string_width (std::string const &str) /**< @return maximum string length */
156 sf-pippijn 1.1 {
157     std::string::const_iterator beg = str.begin ();
158 sf-pippijn 1.3 std::string::const_iterator end = str.end ();
159 sf-pippijn 1.1 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 sf-pippijn 1.5 std::distance (beg, curr) + ((need_fix) ? pen (pad_).x () : 0));
167 sf-pippijn 1.1 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 sf-pippijn 1.4 frame::resize (w, h);
179 sf-pippijn 1.1 /* 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 sf-pippijn 1.5 pen (pad_).clear ();
187 sf-pippijn 1.1 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 sf-pippijn 1.6 text::set_text (color c, std::string const &str)
196 sf-pippijn 1.1 {
197     clear ();
198 sf-pippijn 1.4 add_text (c, str);
199 sf-pippijn 1.1 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     }