libyui-ncurses  2.44.1
 All Classes Functions Variables
NCWidget.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: NCWidget.cc
20 
21  Author: Michael Andres <ma@suse.de>
22 
23 /-*/
24 
25 #include <climits>
26 
27 #define YUILogComponent "ncurses"
28 #include <yui/YUILog.h>
29 #include "tnode.h"
30 #include "NCWidget.h"
31 #include <yui/YWidget.h>
32 
33 
34 NCWidget::NCWidget( YWidget * parent )
35  : tnode<NCWidget*>( this )
36  , magic( YWIDGET_MAGIC )
37  , grabedBy( 0 )
38  , win( 0 )
39  , defsze( 11, 45 )
40  , framedim( 0, 0 )
41  , inparent( -1, -1 )
42  , noUpdates( false )
43  , skipNoDimWin( true )
44  , wstate( NC::WSnormal )
45  , hotlabel( 0 )
46 {
47  NCWidget * myparent = dynamic_cast<NCWidget *>( parent );
48 
49  if ( myparent )
50  {
51  ReparentTo( *myparent );
52 
53  yuiDebug() << "CCC " << this << " parent " << myparent << std::endl;
54  }
55 }
56 
57 
58 NCWidget::NCWidget( NCWidget * myparent )
59  : tnode<NCWidget*>( this )
60  , magic( YWIDGET_MAGIC )
61  , grabedBy( 0 )
62  , win( 0 )
63  , defsze( 11, 45 )
64  , framedim( 0, 0 )
65  , inparent( -1, -1 )
66  , noUpdates( false )
67  , skipNoDimWin( true )
68  , wstate( NC::WSnormal )
69  , hotlabel( 0 )
70 {
71  if ( myparent )
72  {
73  ReparentTo( *myparent );
74  }
75 
76  yuiDebug() << "CCC " << this << " parent " << myparent << std::endl;
77 }
78 
79 
80 
81 NCWidget::~NCWidget()
82 {
83  yuiDebug() << "DD+ " << this << std::endl;
84  wDelete();
85 
86  while ( Fchild() )
87  Fchild()->Disconnect();
88 
89  Disconnect();
90 
91  invalidate();
92 
93  yuiDebug() << "DD- " << this << std::endl;
94 }
95 
96 
97 
98 
99 void NCWidget::PreDisconnect()
100 {
101  grabRelease( 0 );
102 }
103 
104 
105 
106 void NCWidget::PostDisconnect()
107 {}
108 
109 
110 
111 void NCWidget::PreReparent()
112 {}
113 
114 
115 
116 void NCWidget::PostReparent()
117 {}
118 
119 
120 
121 bool NCWidget::grabFocus()
122 {
123  return Top().Value()->wantFocus( *this );
124 }
125 
126 
127 
128 // Actualy perform sreen update.
129 void NCWidget::wUpdate( bool forced_br )
130 {
131  if ( !win )
132  return;
133 
134  if ( noUpdates && !forced_br )
135  return;
136 
137  NCurses::Update();
138 }
139 
140 
141 
142 // Redirect Update request to topmost widget
143 void NCWidget::Update()
144 {
145  if ( noUpdates )
146  return;
147 
148  if ( Parent() )
149  {
150  Parent()->Value()->Update();
151  }
152  else
153  {
154  wUpdate();
155  }
156 }
157 
158 
159 
160 NCursesWindow * NCWidget::ParentWin()
161 {
162  if ( !Parent() )
163  {
164  return 0;
165  }
166 
167  return Parent()->Value()->win;
168 }
169 
170 
171 
172 void NCWidget::wMoveChildTo( NCWidget & child, const wpos & newpos )
173 {
174  yuiDebug() << "mc+ " << DLOC << child << " -> " << newpos << " in " << this << std::endl;
175 
176  try
177  {
178  child.wMoveTo( newpos );
179  Redraw( true );
180  }
181  catch ( NCursesError & err )
182  {
183  yuiError() << DLOC << child << " -> " << newpos << " in " << this << std::endl;
184  yuiError() << err << std::endl;
185  ::endwin();
186  abort();
187  }
188 
189  yuiDebug() << "mc- " << DLOC << child << std::endl;
190 }
191 
192 
193 
194 void NCWidget::wRelocate( const wrect & newrect )
195 {
196  yuiDebug() << "rl+ " << this << " -> " << newrect << std::endl;
197 
198  try
199  {
200  if ( win )
201  {
202  wDelete();
203  }
204 
205  wCreate( newrect );
206  SetState( wstate, true );
207  }
208  catch ( NCursesError & err )
209  {
210  yuiError() << *this << std::endl;
211  yuiError() << err << std::endl;
212  ::endwin();
213  abort();
214  }
215 
216  yuiDebug() << "rl- " << this << std::endl;
217 }
218 
219 
220 
221 void NCWidget::wMoveTo( const wpos & newpos )
222 {
223  if ( !win )
224  {
225  yuiDebug() << "No win to move: " << this << " -> " << newpos << std::endl;
226  return;
227  }
228 
229  if ( !Parent() )
230  throw NCError( "wMoveTo: got no parent" );
231 
232  if ( skipNoDimWin && inparent.Sze.H == 0 )
233  {
234  yuiDebug() << "Skip widget with zero height: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
235  return;
236  }
237 
238  if ( skipNoDimWin && inparent.Sze.W == 0 )
239  {
240  yuiDebug() << "Skip widget with zero width: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
241  return;
242  }
243 
244  if ( inparent.Pos != newpos )
245  {
246  yuiDebug() << "mv+ " << this << " -> " << newpos << " par " << Parent()->Value() << std::endl;
247  NCWidget & p( *Parent()->Value() );
248  p.win->mvsubwin( win,
249  newpos.L + Parent()->Value()->framedim.Pos.L,
250  newpos.C + Parent()->Value()->framedim.Pos.C );
251  inparent.Pos = newpos;
252  yuiDebug() << "mv- " << this << std::endl;
253  }
254 }
255 
256 
257 
258 void NCWidget::wCreate( const wrect & newrect )
259 {
260  if ( win )
261  throw NCError( "wCreate: already have win" );
262 
263  if ( !Parent() )
264  throw NCError( "wCreate: got no parent" );
265 
266  inparent = newrect;
267 
268  if ( skipNoDimWin && inparent.Sze == wsze( 0, 0 ) )
269  {
270  yuiDebug() << "Skip nodim widget: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
271  return;
272  }
273 
274  if ( skipNoDimWin && inparent.Sze.H == 0 )
275  {
276  yuiDebug() << "Skip widget with zero height: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
277  return;
278  }
279 
280  if ( skipNoDimWin && inparent.Sze.W == 0 )
281  {
282  yuiDebug() << "Skip widget with zero width: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
283  return;
284  }
285 
286  NCursesWindow * parw = ParentWin();
287 
288  if ( Parent() && !parw )
289  {
290  yuiError() << "Can't create widget in nodim parent: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
291  inparent.Sze = wsze( 0, 0 );
292  return;
293  }
294 
295  yuiDebug() << "cw+ " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
296 
297  if ( parw )
298  {
299  try
300  {
301  win = new NCursesWindow( *parw,
302  inparent.Sze.H, inparent.Sze.W,
303  inparent.Pos.L + Parent()->Value()->framedim.Pos.L,
304  inparent.Pos.C + Parent()->Value()->framedim.Pos.C,
305  'r' );
306  }
307  catch ( ... )
308  {
309  try
310  {
311  win = new NCursesWindow( *parw,
312  inparent.Sze.H, inparent.Sze.W,
313  inparent.Pos.L,
314  inparent.Pos.C,
315  'r' );
316  }
317  catch ( ... )
318  {
319  inparent.Sze = wsze( 1, 1 );
320  inparent.Pos = wpos( 0, 0 );
321  win = new NCursesWindow( *parw, 1, 1, 0, 0, 'r' );
322  }
323  }
324  }
325  else
326  {
327  win = new NCursesWindow( inparent.Sze.H, inparent.Sze.W,
328  inparent.Pos.L, inparent.Pos.C );
329  }
330 
331  yuiDebug() << "cw- " << this << ' ' << inparent << std::endl;
332 }
333 
334 
335 
336 void NCWidget::wDelete()
337 {
338  if ( win )
339  {
340  yuiDebug() << "wd+ " << this << std::endl;
341 
342  for ( tnode<NCWidget *> * ch = Fchild(); ch; ch = ch->Nsibling() )
343  {
344  ch->Value()->wDelete();
345  }
346 
347  win->clear();
348 
349  delete win;
350  win = 0;
351  inparent = wrect( -1, -1 );
352  yuiDebug() << "wd- " << this << std::endl;
353  }
354 }
355 
356 
357 
358 wpos NCWidget::ScreenPos() const
359 {
360  if ( !win )
361  return -1;
362 
363  if ( Parent() )
364  {
365  return Parent()->Value()->ScreenPos() + inparent.Pos;
366  }
367 
368  return wsze( win->begy(), win->begx() );
369 }
370 
371 
372 
373 void NCWidget::SetState( const NC::WState newstate, const bool force )
374 {
375  if ( newstate != wstate || force )
376  {
377  yuiDebug() << DLOC << wstate << " -> " << newstate << std::endl;
378  wstate = newstate;
379 
380  if ( win )
381  {
382  win->bkgd( wStyle().getWidget( wstate ).plain );
383  }
384 
385  Redraw();
386  }
387 }
388 
389 
390 
391 void NCWidget::setEnabled( bool do_bv )
392 {
393  yuiDebug() << DLOC << this << ' ' << do_bv << ' ' << wstate << std::endl;
394 
395  tnode<NCWidget*> *c = this;
396 
397  // If widget has children ([HV]Boxes, alignments,...), disable all of
398  // them recursively (#256707).
399 
400  if ( c->HasChildren() )
401  {
402  yuiMilestone() << this << "setEnabled children recursively" << std::endl;
403 
404  for ( c = this->Next();
405  c && c->IsDescendantOf( this );
406  c = c->Next() )
407  {
408  if ( c->Value()->GetState() != NC::WSdumb )
409  c->Value()->setEnabled( do_bv );
410  }
411  }
412 
413  else
414  {
415  if ( wstate == NC::WSdumb )
416  return;
417 
418  if ( do_bv && wstate == NC::WSdisabeled )
419  {
420  SetState( NC::WSnormal );
421  }
422  else if ( !do_bv && wstate != NC::WSdisabeled )
423  {
424  if ( wstate == NC::WSactive )
425  grabRelease( 0 );
426 
427  SetState( NC::WSdisabeled );
428  }
429  }
430 }
431 
432 
433 
434 void NCWidget::Redraw( const bool sub )
435 {
436  if ( !win )
437  {
438  return;
439  }
440 
441  bool savNoUpdates = noUpdates;
442 
443  noUpdates = true;
444 
445  if ( sub )
446  {
447  win->clear();
448  wRedraw();
449 
450  for ( tnode<NCWidget *> * ch = Fchild(); ch; ch = ch->Nsibling() )
451  {
452  ch->Value()->Redraw( sub );
453  }
454  }
455  else
456  {
457  wRedraw();
458  }
459 
460  noUpdates = savNoUpdates;
461 
462  Update();
463 }
464 
465 
466 
467 void NCWidget::wRedraw()
468 {
469 }
470 
471 
472 
473 void NCWidget::Recoded()
474 {
475  if ( !win )
476  {
477  return;
478  }
479 
480  bool savNoUpdates = noUpdates;
481 
482  noUpdates = true;
483  wRecoded();
484 
485  for ( tnode<NCWidget *> * ch = Fchild(); ch; ch = ch->Nsibling() )
486  {
487  ch->Value()->Recoded();
488  }
489 
490  noUpdates = savNoUpdates;
491 
492  Update();
493 }
494 
495 
496 
497 void NCWidget::wRecoded()
498 {
499  wRedraw();
500 }
501 
502 
503 
504 bool NCWidget::HasHotkey( int key )
505 {
506  if ( key < 0 || UCHAR_MAX < key )
507  return false;
508 
509  if ( !( hotlabel && hotlabel->hasHotkey() ) )
510  return false;
511 
512  return( tolower( key ) == tolower( hotlabel->hotkey() ) );
513 }
514 
515 
516 
517 bool NCWidget::HasFunctionHotkey( int key ) const
518 {
519  const YWidget * w = dynamic_cast<const YWidget *>( this );
520 
521  if ( w )
522  {
523  if ( key < 0 || ( ! w->hasFunctionKey() ) )
524  return false;
525 
526  return( key == KEY_F( w->functionKey() ) );
527  }
528  else
529  {
530  yuiError() << "No YWidget" << std::endl;
531  return false;
532  }
533 }
534 
535 
536 
537 NCursesEvent NCWidget::wHandleHotkey( wint_t /*key*/ )
538 {
539  return wHandleInput( KEY_HOTKEY );
540 }
541 
542 
543 
544 NCursesEvent NCWidget::wHandleInput( wint_t /*key*/ )
545 {
546  return NCursesEvent::none;
547 }
548 
549 
550 std::ostream & operator<<( std::ostream & STREAM, const NCWidget * OBJ )
551 {
552  if ( OBJ && OBJ->isValid() )
553  return STREAM << *OBJ;
554 
555  return STREAM << "(NoNCWidget)";
556 }
557 
558 
559 std::ostream & operator<<( std::ostream & STREAM, const NCWidget & OBJ )
560 {
561  if ( OBJ.isValid() )
562  return STREAM << OBJ.location() << ( void* )&OBJ
563  << '(' << OBJ.win
564  << ' ' << OBJ.inparent
565  << ' ' << OBJ.wstate
566  << ')';
567 
568  return STREAM << "( invalid NCWidget)";
569 }
570 
571 
572 
573 void NCWidget::DumpOn( std::ostream & str, std::string prfx ) const
574 {
575  str
576  //<< prfx << "|" << std::endl
577  << prfx << "+-" << this << std::endl;
578  prfx += ( Nsibling() ? "| " : " " );
579 
580  for ( const tnode<NCWidget *> * ch = Fchild(); ch; ch = ch->Nsibling() )
581  {
582  ch->Value()->DumpOn( str, prfx );
583  }
584 }
585 
C++ class for windows.
Definition: ncursesw.h:904
Definition: tnode.h:31
NCursesWindow * parent()
Definition: ncursesw.h:1777
int bkgd(const chtype ch)
Definition: ncursesw.h:1443
Definition: position.h:109
int begy() const
Definition: ncursesw.h:1085
int begx() const
Definition: ncursesw.h:1080
virtual void setEnabled(bool do_bv)=0
Definition: NCWidget.cc:391
Definition: position.h:154