libyui-ncurses  2.55.0
NCTableItem.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: NCTableItem.cc
20 
21  Author: Michael Andres <ma@suse.de>
22 
23 /-*/
24 
25 #define YUILogComponent "ncurses"
26 #include <yui/YUILog.h>
27 #include "NCTableItem.h"
28 #include "stringutil.h"
29 #include "stdutil.h"
30 
31 using stdutil::form;
32 
33 
34 NCTableCol::NCTableCol( const NCstring & l, STYLE st )
35  : label( l )
36  , style( st )
37 {
38 }
39 
40 
41 NCTableCol::~NCTableCol()
42 {
43 }
44 
45 
46 chtype NCTableCol::setBkgd( NCursesWindow & w,
47  NCTableStyle & tableStyle,
48  NCTableLine::STATE linestate,
49  STYLE colstyle ) const
50 {
51  chtype bkgdstyle = tableStyle.getBG( linestate, colstyle );
52 
53  if ( bkgdstyle != NCTableStyle::currentBG )
54  w.bkgdset( bkgdstyle );
55  else
56  bkgdstyle = w.getbkgd();
57 
58  return bkgdstyle;
59 }
60 
61 
62 void NCTableCol::DrawAt( NCursesWindow & w, const wrect at,
63  NCTableStyle & tableStyle,
64  NCTableLine::STATE linestate,
65  unsigned colidx ) const
66 {
67  chtype bg = setBkgd( w, tableStyle, linestate, style );
68  chtype hbg = tableStyle.hotBG( linestate, colidx );
69 
70  if ( hbg == NCTableStyle::currentBG )
71  hbg = bg;
72 
73  label.drawAt( w, bg, hbg, at, tableStyle.ColAdjust( colidx ) );
74 }
75 
76 
77 std::ostream & operator<<( std::ostream & str, const NCTableCol & obj )
78 {
79  return str << obj.label;
80 }
81 
82 
83 
84 
85 
86 NCTableLine::NCTableLine( unsigned cols, int idx, const unsigned s )
87  : Items( cols, (NCTableCol *) 0 )
88  , state( s )
89  , index( idx )
90  , yitem( 0 )
91  , vstate( S_HIDDEN )
92 {
93 }
94 
95 
96 NCTableLine::NCTableLine( std::vector<NCTableCol*> & nItems, int idx, const unsigned s )
97  : Items( nItems )
98  , state( s )
99  , index( idx )
100  , yitem( 0 )
101  , vstate( S_HIDDEN )
102 {
103 }
104 
105 
106 void NCTableLine::setOrigItem( YTableItem *it )
107 {
108  yitem = it;
109  yitem->setData( this ) ;
110 }
111 
112 
113 NCTableLine::~NCTableLine()
114 {
115  ClearLine();
116 }
117 
118 
119 void NCTableLine::assertCol( unsigned idx )
120 {
121  if ( idx >= Cols() )
122  SetCols( idx + 1 );
123 }
124 
125 
126 void NCTableLine::SetCols( unsigned idx )
127 {
128  if ( idx == Cols() )
129  return;
130 
131  if ( idx < Cols() )
132  {
133  for ( unsigned i = idx; i < Cols(); ++i )
134  {
135  delete Items[i];
136  }
137  }
138 
139  Items.resize( idx, 0 );
140 }
141 
142 
143 void NCTableLine::stripHotkeys()
144 {
145  for ( unsigned i = 0; i < Cols(); ++i )
146  {
147  if ( Items[i] )
148  Items[i]->stripHotkey();
149  }
150 }
151 
152 
153 
154 void NCTableLine::SetCols( std::vector<NCTableCol*> & nItems )
155 {
156  SetCols( 0 );
157  Items = nItems;
158 }
159 
160 
161 void NCTableLine::AddCol( unsigned idx, NCTableCol * item )
162 {
163  assertCol( idx );
164  delete Items[idx];
165  Items[idx] = item;
166 }
167 
168 
169 void NCTableLine::DelCol( unsigned idx )
170 {
171  if ( idx < Cols() )
172  {
173  delete Items[idx];
174  Items[idx] = 0;
175  }
176 }
177 
178 
179 NCTableCol * NCTableLine::GetCol( unsigned idx )
180 {
181  if ( idx < Cols() )
182  return Items[idx];
183 
184  return 0;
185 }
186 
187 
188 void NCTableLine::UpdateFormat( NCTableStyle & tableStyle )
189 {
190  tableStyle.AssertMinCols( Cols() );
191 
192  for ( unsigned c = 0; c < Cols(); ++c )
193  {
194  if ( !Items[c] )
195  continue;
196 
197  tableStyle.MinColWidth( c, Items[c]->Size().W );
198  }
199 }
200 
201 
202 void NCTableLine::DrawAt( NCursesWindow & w, const wrect at,
203  NCTableStyle & tableStyle,
204  bool active ) const
205 {
206  vstate = S_HIDDEN;
207 
208  if ( isVisible() )
209  {
210  if ( isDisabeled() )
211  vstate = S_DISABELED;
212  else
213  vstate = active ? S_ACTIVE : S_NORMAL;
214  }
215 
216  w.bkgdset( tableStyle.getBG( vstate ) );
217 
218  for ( int l = 0; l < at.Sze.H; ++l )
219  {
220  w.move( at.Pos.L + l, at.Pos.C );
221  w.clrtoeol();
222  }
223 
224  DrawItems( w, at, tableStyle, active );
225 }
226 
227 
228 void NCTableLine::DrawItems( NCursesWindow & w, const wrect at,
229  NCTableStyle & tableStyle,
230  bool active ) const
231 {
232  if ( !( at.Sze > wsze( 0 ) ) )
233  return;
234 
235  wrect lRect( at );
236 
237  unsigned destWidth;
238 
239  for ( unsigned c = 0; c < Cols(); ++c )
240  {
241 
242  if ( c && tableStyle.ColSepwidth() )
243  {
244  // draw centered
245  destWidth = tableStyle.ColSepwidth() / 2;
246 
247  if ( destWidth < ( unsigned )lRect.Sze.W )
248  {
249  w.bkgdset( tableStyle.getBG( vstate, NCTableCol::SEPARATOR ) );
250  w.vline( lRect.Pos.L, lRect.Pos.C + destWidth,
251  lRect.Sze.H, tableStyle.ColSepchar() );
252  // skip over
253  destWidth = tableStyle.ColSepwidth();
254 
255  if (( unsigned )lRect.Sze.W <= destWidth )
256  break;
257 
258  lRect.Pos.C += destWidth;
259 
260  lRect.Sze.W -= destWidth;
261  }
262  }
263 
264  destWidth = tableStyle.ColWidth( c );
265 
266  wrect cRect( lRect );
267  // adjust remaining linespace
268  lRect.Pos.C += destWidth;
269  lRect.Sze.W -= destWidth;
270  // adjust destinated width
271 
272  if ( lRect.Sze.W < 0 )
273  cRect.Sze.W = destWidth + lRect.Sze.W;
274  else
275  cRect.Sze.W = destWidth;
276 
277  // draw item
278  if ( Items[c] )
279  {
280  Items[c]->DrawAt( w, cRect, tableStyle, vstate, c );
281  }
282  }
283 }
284 
285 
286 std::ostream & operator<<( std::ostream & str, const NCTableLine & obj )
287 {
288  str << "Line: cols " << obj.Cols() << std::endl;
289 
290  for ( unsigned idx = 0; idx < obj.Cols(); ++idx )
291  {
292  str << " " << idx << " ";
293  const NCTableCol * ci = obj.GetCol( idx );
294 
295  if ( ci )
296  str << *ci;
297  else
298  str << "NO_ITEM";
299 
300  str << std::endl;
301  }
302 
303  return str;
304 }
305 
306 
307 
308 
309 
310 
311 void NCTableHead::DrawAt( NCursesWindow & w, const wrect at,
312  NCTableStyle & tableStyle,
313  bool active ) const
314 {
315  vstate = S_HEADLINE;
316 
317  w.bkgdset( tableStyle.getBG( vstate ) );
318 
319  for ( int l = 0; l < at.Sze.H; ++l )
320  {
321  w.move( at.Pos.L + l, at.Pos.C );
322  w.clrtoeol();
323  }
324 
325  DrawItems( w, at, tableStyle, active );
326 }
327 
328 
329 
330 
331 
332 
333 NCTableStyle::NCTableStyle( const NCWidget & p )
334  : headline( 0 )
335  , colWidth( 0 )
336  , colAdjust( 0 )
337  , parw( p )
338  , colSepwidth( 1 )
339  , colSepchar( ACS_VLINE )
340  , hotCol(( unsigned ) - 1 )
341 {
342 }
343 
344 
345 bool NCTableStyle::SetStyleFrom( const std::vector<NCstring> & head )
346 {
347  unsigned ncols = head.size();
348 
349  headline.ClearLine();
350  headline.SetCols( ncols );
351 
352  colWidth.clear();
353  colAdjust.clear();
354  AssertMinCols( ncols );
355 
356  bool hasContent = false;
357 
358  for ( unsigned i = 0; i < head.size(); ++i )
359  {
360  const std::wstring & entry( head[i].str() );
361  bool strip = false;
362 
363  if ( entry.length() )
364  {
365  switch ( entry[0] )
366  {
367  case 'R':
368  strip = true;
369  colAdjust[i] = NC::RIGHT;
370  break;
371 
372  case 'C':
373  strip = true;
374  colAdjust[i] = NC::CENTER;
375  break;
376 
377  case 'L':
378  strip = true;
379  colAdjust[i] = NC::LEFT;
380  break;
381 
382  default:
383  yuiWarning() << "No style char [LRC] at beginning of '" << entry << "'" << std::endl;
384  break;
385  }
386  }
387 
388  NCstring coltxt = strip ? entry.substr( 1 ) : entry;
389  headline.AddCol( i, new NCTableCol( coltxt ) );
390 
391  if ( ! hasContent && coltxt.str().length() )
392  hasContent = true;
393  }
394 
395  return hasContent;
396 }
397 
398 
399 chtype NCTableStyle::highlightBG( const NCTableLine::STATE lstate,
400  const NCTableCol::STYLE cstyle,
401  const NCTableCol::STYLE dstyle ) const
402 {
403  return getBG( lstate, cstyle );
404  // unused:
405 
406  if ( lstate == NCTableLine::S_ACTIVE
407  &&
408  parw.GetState() == NC::WSactive )
409  return getBG( lstate, cstyle );
410 
411  return getBG( lstate, dstyle );
412 }
413 
414 
415 chtype NCTableStyle::getBG( const NCTableLine::STATE lstate,
416  const NCTableCol::STYLE cstyle ) const
417 {
418  switch ( lstate )
419  {
420  case NCTableLine::S_NORMAL:
421 
422  switch ( cstyle )
423  {
424  case NCTableCol::PLAIN:
425  return listStyle().item.plain;
426 
427  case NCTableCol::DATA:
428  return listStyle().item.data;
429 
430  case NCTableCol::ACTIVEDATA:
431  return listStyle().item.plain;
432 
433  case NCTableCol::HINT:
434  return listStyle().item.hint;
435 
436  case NCTableCol::SEPARATOR:
437  return listStyle().item.plain;
438 
439  case NCTableCol::NONE:
440  return currentBG;
441  }
442  break;
443 
444 
445  case NCTableLine::S_ACTIVE:
446 
447  switch ( cstyle )
448  {
449  case NCTableCol::PLAIN:
450  return listStyle().selected.plain;
451 
452  case NCTableCol::DATA:
453  return listStyle().selected.data;
454 
455  case NCTableCol::ACTIVEDATA:
456  return listStyle().selected.data;
457 
458  case NCTableCol::HINT:
459  return listStyle().selected.hint;
460 
461  case NCTableCol::SEPARATOR:
462  return listStyle().selected.plain;
463 
464  case NCTableCol::NONE:
465  return currentBG;
466  }
467  break;
468 
469  case NCTableLine::S_DISABELED:
470 
471  switch ( cstyle )
472  {
473  case NCTableCol::PLAIN:
474  return parw.wStyle().disabledList.item.plain;
475 
476  case NCTableCol::DATA:
477  return parw.wStyle().disabledList.item.data;
478 
479  case NCTableCol::ACTIVEDATA:
480  return parw.wStyle().disabledList.item.plain;
481 
482  case NCTableCol::HINT:
483  return parw.wStyle().disabledList.item.hint;
484 
485  case NCTableCol::SEPARATOR:
486  return listStyle().item.plain;
487 
488  case NCTableCol::NONE:
489  return currentBG;
490  }
491  break;
492 
493 
494  case NCTableLine::S_HEADLINE:
495  return listStyle().title;
496  break;
497 
498  case NCTableLine::S_HIDDEN:
499  return currentBG;
500  break;
501  }
502 
503  return currentBG;
504 }
505 
506 
507 std::ostream & operator<<( std::ostream & str, const NCTableStyle & obj )
508 {
509  str << form( "cols %d, sep %d (%lx)\n",
510  obj.Cols(), obj.ColSepwidth(), (unsigned long)obj.ColSepchar() );
511 
512  for ( unsigned i = 0; i < obj.Cols(); ++i )
513  {
514  str << form( "%2d %d(%3d) ", i, obj.ColAdjust( i ), obj.ColWidth( i ) );
515 
516  if ( obj.Headline().GetCol( i ) )
517  str << obj.Headline().GetCol( i )->Label();
518 
519  str << std::endl;
520  }
521 
522  return str;
523 }
524 
wsze
Definition: position.h:155
NCstring
Definition: NCstring.h:33
NCTableCol
Definition: NCTableItem.h:147
NCursesWindow
C++ class for windows.
Definition: ncursesw.h:904
NCursesWindow::getbkgd
chtype getbkgd() const
Get current background setting.
Definition: ncursesw.h:1437
NCWidget
Definition: NCWidget.h:46
NCursesWindow::clrtoeol
int clrtoeol()
Clear to the end of the line.
Definition: ncursesw.h:1537
NCursesWindow::move
int move(int y, int x)
Move cursor the this position.
Definition: ncursesw.h:1154
NCursesWindow::vline
int vline(int len, chtype ch=0)
Draw a vertical line of len characters with the given character.
Definition: ncursesw.h:1498
NCTableLine
Definition: NCTableItem.h:40
NCTableStyle
Definition: NCTableItem.h:223
wrect
Definition: position.h:198
NCursesWindow::bkgdset
void bkgdset(chtype ch)
Set the background property.
Definition: ncursesw.h:1447