ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/backend/ndk/text.cpp
Revision: 1.5
Committed: Tue Oct 19 09:45:09 2010 UTC (16 years ago) by sf-pippijn
Branch: MAIN
Changes since 1.4: +8 -8 lines
Log Message:
- use wchar_t for single characters (glyphs and line drawing)
- merge ncurses and ndk wrappers
- simplify colour caching

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     * which should be included with libndk++ as the file COPYING.
7     */
8 sf-pippijn 1.4 #include <ndk++/color.hh>
9     #include <ndk++/packer.hh>
10 sf-pippijn 1.1 #include <ndk++/palette.hh>
11     #include <ndk++/text.hh>
12    
13 sf-pippijn 1.5 #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.4 text::add_text (color const &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     ? width ()
38     : 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     right ();
112     break;
113     case key::left:
114     left ();
115     break;
116     case key::up:
117     up ();
118     break;
119     case key::down:
120     down ();
121     break;
122     default:
123 sf-pippijn 1.3 return event::ignored;
124 sf-pippijn 1.1 }
125    
126 sf-pippijn 1.5 pen (*this).commit ();
127 sf-pippijn 1.3 emit (changed);
128    
129     return event::accepted;
130 sf-pippijn 1.1 }
131    
132     int
133 sf-pippijn 1.3 text::string_height (std::string const &str) /**< @return number of strings */
134 sf-pippijn 1.1 {
135     int count = 0;
136    
137     if (wrapping_ == wrap)
138     /* in wrap mode we need additional recalculations of the string height */
139     count = str.length () / width () + (str.length () % width () != 0 ? 1 : 0);
140     else
141     /* not wrap mode: only calculate number of '\n' */
142     count = std::count (str.begin (), str.end (), '\n');
143    
144     /* we also need an additional space below if line have '\n' at the end */
145     if (*(str.end () - 1) == '\n')
146     ++count; /* grow width if nesessary */
147     return count;
148     }
149    
150     int
151 sf-pippijn 1.3 text::string_width (std::string const &str) /**< @return maximum string length */
152 sf-pippijn 1.1 {
153     std::string::const_iterator beg = str.begin ();
154 sf-pippijn 1.3 std::string::const_iterator end = str.end ();
155 sf-pippijn 1.1 ptrdiff_t max_len = 0;
156     bool need_fix = true;
157    
158     do
159     {
160     std::string::const_iterator curr (std::find (beg, str.end (), '\n'));
161     max_len = std::max (max_len,
162 sf-pippijn 1.5 std::distance (beg, curr) + ((need_fix) ? pen (pad_).x () : 0));
163 sf-pippijn 1.1 beg = (curr == end) ? curr : (curr + 1);
164     need_fix = false;
165     }
166     while (beg != end);
167    
168     return max_len;
169     }
170    
171     void
172     text::resize (int w, int h)
173     {
174 sf-pippijn 1.4 frame::resize (w, h);
175 sf-pippijn 1.1 /* grow size of the text if we need it */
176     pad_.resize (std::max (pad_.width (), w + 1), std::max (pad_.height (), h));
177     }
178    
179     void
180     text::clear ()
181     {
182 sf-pippijn 1.5 pen (pad_).clear ();
183 sf-pippijn 1.1 x_ = 0;
184     y_ = 0;
185     /* truncate buffer to viewport size */
186     pad_.resize (this->width (), this->height ());
187     draw ();
188     }
189    
190     void
191 sf-pippijn 1.4 text::set_text (color const &c, std::string const &str)
192 sf-pippijn 1.1 {
193     clear ();
194 sf-pippijn 1.4 add_text (c, str);
195 sf-pippijn 1.1 draw ();
196     }
197    
198     int
199     text::length () const
200     {
201     return pad_.height ();
202     }
203    
204     int
205     text::last_line () const
206     {
207     return y_ + height ();
208     }