libyui-ncurses  2.44.1
 All Classes Functions Variables
NCPadWidget.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: NCPadWidget.cc
20 
21  Author: Michael Andres <ma@suse.de>
22 
23 /-*/
24 
25 #define YUILogComponent "ncurses"
26 #include <yui/YUILog.h>
27 #include "NCPadWidget.h"
28 
29 
31 {
32 public:
33 
34  enum orientation { HORZ, VERT };
35 
36 private:
37 
38  chtype ch_forward;
39  chtype ch_backward;
40  chtype ch_barbeg;
41  chtype ch_barend;
42  chtype ch_barone;
43 
44  const NCWidget & parw;
45  NCursesWindow * win;
46  orientation type;
47  unsigned len;
48 
49  unsigned total;
50  unsigned visible;
51  unsigned at;
52 
53 private:
54 
55  void adjust()
56  {
57  if ( visible > total )
58  {
59  yuiDebug() << "adjust visible " << visible << " > total " << total << std::endl;
60  visible = total;
61  }
62 
63  if ( at + visible > total )
64  {
65  yuiDebug() << "adjust at " << at << " + visible " << visible << " > total " << total << std::endl;
66  at = total - visible;
67  }
68  }
69 
70  void draw_line( unsigned p, unsigned l, chtype ch = 0 )
71  {
72  if ( !l )
73  return;
74 
75  if ( type == HORZ )
76  win->hline( 0, p, l, ch );
77  else
78  win->vline( p, 0, l, ch );
79  }
80 
81  void draw_bar( unsigned p, unsigned l )
82  {
83  if ( !l )
84  return;
85 
86  if ( l == 1 )
87  {
88  if ( type == HORZ )
89  win->addch( 0, p, ch_barone );
90  else
91  win->addch( p, 0, ch_barone );
92 
93  return;
94  }
95 
96  unsigned e = p + l - 1; // barend
97 
98  l -= 2; // inner bar
99 
100  if ( type == HORZ )
101  {
102  win->addch( 0, p, ch_barbeg );
103  win->addch( 0, e, ch_barend );
104 
105  if ( l )
106  win->hline( 0, p + 1, l );
107  }
108  else
109  {
110  win->addch( p, 0, ch_barbeg );
111  win->addch( e, 0, ch_barend );
112 
113  if ( l )
114  win->vline( p + 1, 0, l );
115  }
116  }
117 
118  void draw()
119  {
120  if ( !win )
121  return;
122 
123  bool topvis = ( at == 0 );
124 
125  bool botvis = ( at + visible == total );
126 
127  const NCstyle::StWidget & style( parw.frameStyle() );
128 
129  win->bkgdset( style.plain );
130 
131  draw_line( 0, len );
132 
133  if ( topvis && botvis )
134  {
135  // no scroll at all
136  return;
137  }
138 
139  switch ( len )
140  {
141  case 1:
142  win->bkgdset( style.scrl );
143 
144  if ( topvis == botvis )
145  {
146  // both == false; otherwise handled above
147  win->addch( 0, 0, ch_barone );
148  }
149  else
150  {
151  win->addch( 0, 0, ( topvis ? ch_forward : ch_backward ) );
152  }
153 
154  break;
155 
156  case 2:
157  win->bkgdset( style.scrl );
158 
159  if ( !topvis )
160  win->addch( 0, 0, ch_backward );
161 
162  if ( !botvis )
163  win->addch( win->maxy(), win->maxx(), ch_forward );
164 
165  break;
166 
167  default:
168 
169  case 3:
170  {
171  unsigned blen;
172  unsigned bat;
173 
174  if ( visible + 1 == total )
175  {
176  // just one invisible line
177  blen = len - 1;
178  bat = at ? 1 : 0;
179  }
180  else
181  {
182  blen = ( visible * ( len - 2 ) / total ) + 1;
183 
184  if ( topvis == botvis )
185  {
186  // both == false; otherwise handled above
187  bat = ( at * ( len - 2 ) / total ) + 1;
188  }
189  else
190  {
191  bat = ( topvis ? 0 : len - blen );
192  }
193  }
194 
195  win->bkgdset( style.plain );
196 
197  draw_line( 0, len );
198  win->bkgdset( style.scrl );
199  draw_bar( bat, blen );
200  }
201 
202  break;
203  }
204  }
205 
206 public:
207 
208  NCScrollbar( const NCWidget & parwid, NCursesWindow & par, wpos p, unsigned l, orientation orient )
209  : ch_forward( orient == HORZ ? ACS_RARROW : ACS_DARROW )
210  , ch_backward( orient == HORZ ? ACS_LARROW : ACS_UARROW )
211  , ch_barbeg( orient == HORZ ? ACS_LTEE : ACS_TTEE )
212  , ch_barend( orient == HORZ ? ACS_RTEE : ACS_BTEE )
213  , ch_barone( orient == HORZ ? ACS_VLINE : ACS_HLINE )
214  , parw( parwid )
215  , win( 0 )
216  , type( orient )
217  , len( l ? l : 1 )
218  , total( 0 )
219  , visible( 0 )
220  , at( 0 )
221  {
222  try
223  {
224  win = new NCursesWindow( par,
225  ( type == HORZ ? 1 : len ), // height
226  ( type == VERT ? 1 : len ), // width
227  p.L, p.C,
228  'r' );
229  }
230  catch ( NCursesException & err )
231  {
232  yuiDebug() << "NCScrollbar: " << err.message
233  << ": at " << p << " len " << len << " in " << par << std::endl;
234  return;
235  }
236  }
237 
238  virtual ~NCScrollbar()
239  {
240  delete win;
241  }
242 
243 public:
244 
245  void set( unsigned tot, unsigned vis, unsigned start )
246  {
247  total = tot;
248  visible = vis;
249  at = start;
250  adjust();
251  draw();
252  }
253 
254 };
255 
256 
257 
258 
259 NCPadWidget::NCPadWidget( NCWidget * myparent )
260  : NCWidget( myparent )
261  , padwin( 0 )
262  , hsb( 0 )
263  , vsb( 0 )
264  , multidraw( false )
265  , pad( 0 )
266  , hasHeadline( false )
267  , activeLabelOnly( false )
268 {
269  yuiDebug() << std::endl;
270  hotlabel = &label;
271  defsze = wsze( 3, 10 ) + 2;
272 }
273 
274 
275 NCPadWidget::NCPadWidget( YWidget * myparent )
276  : NCWidget( myparent )
277  , padwin( 0 )
278  , hsb( 0 )
279  , vsb( 0 )
280  , multidraw( false )
281  , pad( 0 )
282  , hasHeadline( false )
283  , activeLabelOnly( false )
284 {
285  yuiDebug() << std::endl;
286  hotlabel = &label;
287  defsze = wsze( 3, 10 ) + 2;
288 }
289 
290 
291 NCPadWidget::~NCPadWidget()
292 {
293  delete pad;
294 
295  if ( padwin != win )
296  delete padwin;
297 
298  yuiDebug() << std::endl;
299 }
300 
301 
302 void NCPadWidget::wCreate( const wrect & newrect )
303 {
304  NCWidget::wCreate( newrect );
305 
306  if ( win )
307  {
308  wrect padrect( newrect.inside() );
309 
310  if ( hasHeadline )
311  {
312  if ( padrect.Sze.H > 1 )
313  {
314  padrect.Pos.L += 1;
315  padrect.Sze.H -= 1;
316  }
317  else
318  hasHeadline = false;
319  }
320 
321  padwin = new NCursesWindow( *win,
322 
323  padrect.Sze.H, padrect.Sze.W,
324  padrect.Pos.L, padrect.Pos.C,
325  'r' );
326  hsb = new NCScrollbar( *this, *win, wpos( win->maxy(), 1 ), win->width() - 2, NCScrollbar::HORZ );
327  vsb = new NCScrollbar( *this, *win, wpos( 1, win->maxx() ), win->height() - 2, NCScrollbar::VERT );
328  }
329  else
330  {
331  padwin = 0;
332  hsb = 0;
333  vsb = 0;
334  }
335 }
336 
337 
338 void NCPadWidget::wDelete()
339 {
340  if ( pad )
341  {
342  pad->Destwin( 0 );
343  }
344 
345  if ( padwin )
346  {
347  if ( padwin != win )
348  {
349  delete padwin;
350  }
351 
352  padwin = 0;
353  }
354 
355  delete hsb;
356 
357  hsb = 0;
358  delete vsb;
359  vsb = 0;
360  NCWidget::wDelete();
361 }
362 
363 
364 void NCPadWidget::InitPad()
365 {
366  if ( pad )
367  return;
368 
369  pad = CreatePad();
370  pad->SendSchrollCB( this );
371  AdjustPad( wsze( pad->height(), pad->width() ) );
372  DrawPad();
373 }
374 
375 
376 void NCPadWidget::AdjustPadSize( wsze & minsze )
377 {
378  minPadSze = minsze;
379  minsze = wsze::max( minsze, defPadSze() );
380 }
381 
382 
383 void NCPadWidget::AdjustPad( wsze nsze )
384 {
385  if ( !pad )
386  return;
387 
388  pad->resize( nsze );
389 }
390 
391 
392 void NCPadWidget::DelPad()
393 {
394  delete pad;
395  pad = 0;
396 }
397 
398 
399 void NCPadWidget::setLabel( const NClabel & nlabel )
400 {
401  label = nlabel;
402  label.stripHotkey();
403  Redraw();
404 }
405 
406 
407 void NCPadWidget::wRedraw()
408 {
409  if ( !win )
410  return;
411 
412  yuiDebug() << "wRedraw called for: " << win << std::endl;
413 
414  const NCstyle::StWidget & style( frameStyle() );
415 
416  win->bkgdset( style.plain );
417 
418  win->box();
419 
420  if ( !activeLabelOnly || GetState() == NC::WSactive )
421  label.drawAt( *win, style, wpos( 0, 1 ),
422  wsze( 1, win->width() - 2 ), NC::TOPLEFT, false );
423 
424  InitPad();
425 
426  if ( !pad->Destwin() )
427  {
428  AdjustPad( minPadSze );
429  pad->Destwin( padwin );
430  }
431  else
432  {
433  pad->setDirty();
434  pad->setpos();
435  pad->SendHead();
436  }
437 }
438 
439 
440 void NCPadWidget::wRecoded()
441 {
442  if ( pad )
443  pad->wRecoded();
444 
445  wRedraw();
446 }
447 
448 
449 void NCPadWidget::HScroll( unsigned total, unsigned visible, unsigned start )
450 {
451  hsb->set( total, visible, start );
452 }
453 
454 
455 void NCPadWidget::VScroll( unsigned total, unsigned visible, unsigned start )
456 {
457  vsb->set( total, visible, start );
458 }
459 
460 
461 void NCPadWidget::ScrollHead( NCursesWindow & w, unsigned ccol )
462 {
463  if ( hasHeadline && win )
464  {
465  w.copywin( *win, 0, ccol, 1, 1, 1, win->width() - 2, false );
466  }
467 }
468 
469 
470 NCPad * NCPadWidget::CreatePad()
471 {
472  wsze psze( defPadSze() );
473  NCPad * npad = new NCPad( psze.H, psze.W, *this );
474  npad->bkgd( wStyle().list.item.plain );
475 
476  return npad;
477 }
478 
479 
480 void NCPadWidget::DrawPad()
481 {
482  if ( pad && !inMultidraw() )
483  {
484  pad->update();
485  Redraw();
486  }
487 }
488 
489 
490 bool NCPadWidget::handleInput( wint_t key )
491 {
492  return pad->handleInput( key );
493 }
C++ class for windows.
Definition: ncursesw.h:904
int vline(int len, chtype ch=0)
Definition: ncursesw.h:1499
int bkgd(const chtype ch)
Definition: ncursesw.h:1443
void bkgdset(chtype ch)
Definition: ncursesw.h:1448
int maxx() const
Definition: ncursesw.h:1090
Definition: NCPad.h:93
int hline(int len, chtype ch=0)
Definition: ncursesw.h:1485
Definition: position.h:109
int copywin(NCursesWindow &win, int sminrow, int smincol, int dminrow, int dmincol, int dmaxrow, int dmaxcol, bool overlay=TRUE)
Definition: ncursesw.h:1740
int height() const
Definition: ncursesw.h:1070
int addch(const char ch)
Definition: ncursesw.h:1228
int maxy() const
Definition: ncursesw.h:1095
Definition: NCtext.h:81
Definition: position.h:154
int width() const
Definition: ncursesw.h:1075