libyui-ncurses
2.44.1
|
00001 /* 00002 Copyright (C) 2000-2012 Novell, Inc 00003 This library is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU Lesser General Public License as 00005 published by the Free Software Foundation; either version 2.1 of the 00006 License, or (at your option) version 3.0 of the License. This library 00007 is distributed in the hope that it will be useful, but WITHOUT ANY 00008 WARRANTY; without even the implied warranty of MERCHANTABILITY or 00009 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00010 License for more details. You should have received a copy of the GNU 00011 Lesser General Public License along with this library; if not, write 00012 to the Free Software Foundation, Inc., 51 Franklin Street, Fifth 00013 Floor, Boston, MA 02110-1301 USA 00014 */ 00015 00016 00017 /*-/ 00018 00019 File: NCTableItem.cc 00020 00021 Author: Michael Andres <ma@suse.de> 00022 00023 /-*/ 00024 00025 #define YUILogComponent "ncurses" 00026 #include <yui/YUILog.h> 00027 #include "NCTableItem.h" 00028 #include "stringutil.h" 00029 #include "stdutil.h" 00030 00031 using stdutil::form; 00032 00033 00034 NCTableCol::NCTableCol( const NCstring & l, const STYLE & st ) 00035 : label( l ) 00036 , style( st ) 00037 { 00038 } 00039 00040 00041 NCTableCol::~NCTableCol() 00042 { 00043 } 00044 00045 00046 chtype NCTableCol::setBkgd( NCursesWindow & w, 00047 NCTableStyle & tableStyle, 00048 NCTableLine::STATE linestate, 00049 STYLE colstyle ) const 00050 { 00051 chtype bkgdstyle = tableStyle.getBG( linestate, colstyle ); 00052 00053 if ( bkgdstyle != NCTableStyle::currentBG ) 00054 w.bkgdset( bkgdstyle ); 00055 else 00056 bkgdstyle = w.getbkgd(); 00057 00058 return bkgdstyle; 00059 } 00060 00061 00062 void NCTableCol::DrawAt( NCursesWindow & w, const wrect at, 00063 NCTableStyle & tableStyle, 00064 NCTableLine::STATE linestate, 00065 unsigned colidx ) const 00066 { 00067 chtype bg = setBkgd( w, tableStyle, linestate, style ); 00068 chtype hbg = tableStyle.hotBG( linestate, colidx ); 00069 00070 if ( hbg == NCTableStyle::currentBG ) 00071 hbg = bg; 00072 00073 label.drawAt( w, bg, hbg, at, tableStyle.ColAdjust( colidx ) ); 00074 } 00075 00076 00077 std::ostream & operator<<( std::ostream & STREAM, const NCTableCol & OBJ ) 00078 { 00079 return STREAM << OBJ.label; 00080 } 00081 00082 00083 00084 00085 00086 NCTableLine::NCTableLine( unsigned cols, int idx, const unsigned s ) 00087 : Items( cols, ( NCTableCol* )0 ) 00088 , state( s ) 00089 , index( idx ) 00090 , vstate( S_HIDDEN ) 00091 { 00092 } 00093 00094 00095 NCTableLine::NCTableLine( std::vector<NCTableCol*> & nItems, int idx, const unsigned s ) 00096 : Items( nItems ) 00097 , state( s ) 00098 , index( idx ) 00099 , vstate( S_HIDDEN ) 00100 { 00101 } 00102 00103 00104 void NCTableLine::setOrigItem( YTableItem *it ) 00105 { 00106 yitem = it; 00107 yitem->setData( this ) ; 00108 } 00109 00110 00111 NCTableLine::~NCTableLine() 00112 { 00113 ClearLine(); 00114 } 00115 00116 00117 void NCTableLine::assertCol( unsigned idx ) 00118 { 00119 if ( idx >= Cols() ) 00120 SetCols( idx + 1 ); 00121 } 00122 00123 00124 void NCTableLine::SetCols( unsigned idx ) 00125 { 00126 if ( idx == Cols() ) 00127 return; 00128 00129 if ( idx < Cols() ) 00130 { 00131 for ( unsigned i = idx; i < Cols(); ++i ) 00132 { 00133 delete Items[i]; 00134 } 00135 } 00136 00137 Items.resize( idx, 0 ); 00138 } 00139 00140 00141 void NCTableLine::stripHotkeys() 00142 { 00143 for ( unsigned i = 0; i < Cols(); ++i ) 00144 { 00145 if ( Items[i] ) 00146 Items[i]->stripHotkey(); 00147 } 00148 } 00149 00150 00151 00152 void NCTableLine::SetCols( std::vector<NCTableCol*> & nItems ) 00153 { 00154 SetCols( 0 ); 00155 Items = nItems; 00156 } 00157 00158 00159 void NCTableLine::AddCol( unsigned idx, NCTableCol * item ) 00160 { 00161 assertCol( idx ); 00162 delete Items[idx]; 00163 Items[idx] = item; 00164 } 00165 00166 00167 void NCTableLine::DelCol( unsigned idx ) 00168 { 00169 if ( idx < Cols() ) 00170 { 00171 delete Items[idx]; 00172 Items[idx] = 0; 00173 } 00174 } 00175 00176 00177 NCTableCol * NCTableLine::GetCol( unsigned idx ) 00178 { 00179 if ( idx < Cols() ) 00180 return Items[idx]; 00181 00182 return 0; 00183 } 00184 00185 00186 void NCTableLine::UpdateFormat( NCTableStyle & tableStyle ) 00187 { 00188 tableStyle.AssertMinCols( Cols() ); 00189 00190 for ( unsigned c = 0; c < Cols(); ++c ) 00191 { 00192 if ( !Items[c] ) 00193 continue; 00194 00195 tableStyle.MinColWidth( c, Items[c]->Size().W ); 00196 } 00197 } 00198 00199 00200 void NCTableLine::DrawAt( NCursesWindow & w, const wrect at, 00201 NCTableStyle & tableStyle, 00202 bool active ) const 00203 { 00204 vstate = S_HIDDEN; 00205 00206 if ( isVisible() ) 00207 { 00208 if ( isDisabeled() ) 00209 vstate = S_DISABELED; 00210 else 00211 vstate = active ? S_ACTIVE : S_NORMAL; 00212 } 00213 00214 w.bkgdset( tableStyle.getBG( vstate ) ); 00215 00216 for ( int l = 0; l < at.Sze.H; ++l ) 00217 { 00218 w.move( at.Pos.L + l, at.Pos.C ); 00219 w.clrtoeol(); 00220 } 00221 00222 DrawItems( w, at, tableStyle, active ); 00223 } 00224 00225 00226 void NCTableLine::DrawItems( NCursesWindow & w, const wrect at, 00227 NCTableStyle & tableStyle, 00228 bool active ) const 00229 { 00230 if ( !( at.Sze > wsze( 0 ) ) ) 00231 return; 00232 00233 wrect lRect( at ); 00234 00235 unsigned destWidth; 00236 00237 for ( unsigned c = 0; c < Cols(); ++c ) 00238 { 00239 00240 if ( c && tableStyle.ColSepwidth() ) 00241 { 00242 // draw centered 00243 destWidth = tableStyle.ColSepwidth() / 2; 00244 00245 if ( destWidth < ( unsigned )lRect.Sze.W ) 00246 { 00247 w.bkgdset( tableStyle.getBG( vstate, NCTableCol::SEPARATOR ) ); 00248 w.vline( lRect.Pos.L, lRect.Pos.C + destWidth, 00249 lRect.Sze.H, tableStyle.ColSepchar() ); 00250 // skip over 00251 destWidth = tableStyle.ColSepwidth(); 00252 00253 if (( unsigned )lRect.Sze.W <= destWidth ) 00254 break; 00255 00256 lRect.Pos.C += destWidth; 00257 00258 lRect.Sze.W -= destWidth; 00259 } 00260 } 00261 00262 destWidth = tableStyle.ColWidth( c ); 00263 00264 wrect cRect( lRect ); 00265 // adjust remaining linespace 00266 lRect.Pos.C += destWidth; 00267 lRect.Sze.W -= destWidth; 00268 // adjust destinated width 00269 00270 if ( lRect.Sze.W < 0 ) 00271 cRect.Sze.W = destWidth + lRect.Sze.W; 00272 else 00273 cRect.Sze.W = destWidth; 00274 00275 // draw item 00276 if ( Items[c] ) 00277 { 00278 Items[c]->DrawAt( w, cRect, tableStyle, vstate, c ); 00279 } 00280 } 00281 } 00282 00283 00284 std::ostream & operator<<( std::ostream & STREAM, const NCTableLine & OBJ ) 00285 { 00286 STREAM << "Line: cols " << OBJ.Cols() << std::endl; 00287 00288 for ( unsigned idx = 0; idx < OBJ.Cols(); ++idx ) 00289 { 00290 STREAM << " " << idx << " "; 00291 const NCTableCol * ci = OBJ.GetCol( idx ); 00292 00293 if ( ci ) 00294 STREAM << *ci; 00295 else 00296 STREAM << "NO_ITEM"; 00297 00298 STREAM << std::endl; 00299 } 00300 00301 return STREAM; 00302 } 00303 00304 00305 00306 00307 00308 00309 void NCTableHead::DrawAt( NCursesWindow & w, const wrect at, 00310 NCTableStyle & tableStyle, 00311 bool active ) const 00312 { 00313 vstate = S_HEADLINE; 00314 00315 w.bkgdset( tableStyle.getBG( vstate ) ); 00316 00317 for ( int l = 0; l < at.Sze.H; ++l ) 00318 { 00319 w.move( at.Pos.L + l, at.Pos.C ); 00320 w.clrtoeol(); 00321 } 00322 00323 DrawItems( w, at, tableStyle, active ); 00324 } 00325 00326 00327 00328 00329 00330 00331 NCTableStyle::NCTableStyle( const NCWidget & p ) 00332 : headline( 0 ) 00333 , colWidth( 0 ) 00334 , colAdjust( 0 ) 00335 , parw( p ) 00336 , colSepwidth( 1 ) 00337 , colSepchar( ACS_VLINE ) 00338 , hotCol(( unsigned ) - 1 ) 00339 { 00340 } 00341 00342 00343 bool NCTableStyle::SetStyleFrom( const std::vector<NCstring> & head ) 00344 { 00345 unsigned ncols = head.size(); 00346 00347 headline.ClearLine(); 00348 headline.SetCols( ncols ); 00349 00350 colWidth.clear(); 00351 colAdjust.clear(); 00352 AssertMinCols( ncols ); 00353 00354 bool hasContent = false; 00355 00356 for ( unsigned i = 0; i < head.size(); ++i ) 00357 { 00358 const std::wstring & entry( head[i].str() ); 00359 bool strip = false; 00360 00361 if ( entry.length() ) 00362 { 00363 switch ( entry[0] ) 00364 { 00365 case 'R': 00366 strip = true; 00367 colAdjust[i] = NC::RIGHT; 00368 break; 00369 00370 case 'C': 00371 strip = true; 00372 colAdjust[i] = NC::CENTER; 00373 break; 00374 00375 case 'L': 00376 strip = true; 00377 colAdjust[i] = NC::LEFT; 00378 break; 00379 00380 default: 00381 yuiWarning() << "No style char [LRC] at beginning of '" << entry << "'" << std::endl; 00382 break; 00383 } 00384 } 00385 00386 NCstring coltxt = strip ? entry.substr( 1 ) : entry; 00387 headline.AddCol( i, new NCTableCol( coltxt ) ); 00388 00389 if ( ! hasContent && coltxt.str().length() ) 00390 hasContent = true; 00391 } 00392 00393 return hasContent; 00394 } 00395 00396 00397 chtype NCTableStyle::highlightBG( const NCTableLine::STATE lstate, 00398 const NCTableCol::STYLE cstyle, 00399 const NCTableCol::STYLE dstyle ) const 00400 { 00401 return getBG( lstate, cstyle ); 00402 // unused: 00403 00404 if ( lstate == NCTableLine::S_ACTIVE 00405 && 00406 parw.GetState() == NC::WSactive ) 00407 return getBG( lstate, cstyle ); 00408 00409 return getBG( lstate, dstyle ); 00410 } 00411 00412 00413 chtype NCTableStyle::getBG( const NCTableLine::STATE lstate, 00414 const NCTableCol::STYLE cstyle ) const 00415 { 00416 switch ( lstate ) 00417 { 00418 case NCTableLine::S_NORMAL: 00419 00420 switch ( cstyle ) 00421 { 00422 case NCTableCol::PLAIN: 00423 return listStyle().item.plain; 00424 00425 case NCTableCol::DATA: 00426 return listStyle().item.data; 00427 00428 case NCTableCol::ACTIVEDATA: 00429 return listStyle().item.plain; 00430 00431 case NCTableCol::HINT: 00432 return listStyle().item.hint; 00433 00434 case NCTableCol::SEPARATOR: 00435 return listStyle().item.plain; 00436 00437 case NCTableCol::NONE: 00438 return currentBG; 00439 } 00440 break; 00441 00442 00443 case NCTableLine::S_ACTIVE: 00444 00445 switch ( cstyle ) 00446 { 00447 case NCTableCol::PLAIN: 00448 return listStyle().selected.plain; 00449 00450 case NCTableCol::DATA: 00451 return listStyle().selected.data; 00452 00453 case NCTableCol::ACTIVEDATA: 00454 return listStyle().selected.data; 00455 00456 case NCTableCol::HINT: 00457 return listStyle().selected.hint; 00458 00459 case NCTableCol::SEPARATOR: 00460 return listStyle().selected.plain; 00461 00462 case NCTableCol::NONE: 00463 return currentBG; 00464 } 00465 break; 00466 00467 case NCTableLine::S_DISABELED: 00468 00469 switch ( cstyle ) 00470 { 00471 case NCTableCol::PLAIN: 00472 return parw.wStyle().disabledList.item.plain; 00473 00474 case NCTableCol::DATA: 00475 return parw.wStyle().disabledList.item.data; 00476 00477 case NCTableCol::ACTIVEDATA: 00478 return parw.wStyle().disabledList.item.plain; 00479 00480 case NCTableCol::HINT: 00481 return parw.wStyle().disabledList.item.hint; 00482 00483 case NCTableCol::SEPARATOR: 00484 return listStyle().item.plain; 00485 00486 case NCTableCol::NONE: 00487 return currentBG; 00488 } 00489 break; 00490 00491 00492 case NCTableLine::S_HEADLINE: 00493 return listStyle().title; 00494 break; 00495 00496 case NCTableLine::S_HIDDEN: 00497 return currentBG; 00498 break; 00499 } 00500 00501 return currentBG; 00502 } 00503 00504 00505 std::ostream & operator<<( std::ostream & STREAM, const NCTableStyle & OBJ ) 00506 { 00507 STREAM << form( "cols %d, sep %d (%lx)\n", 00508 OBJ.Cols(), OBJ.ColSepwidth(), (unsigned long)OBJ.ColSepchar() ); 00509 00510 for ( unsigned i = 0; i < OBJ.Cols(); ++i ) 00511 { 00512 STREAM << form( "%2d %d(%3d) ", i, OBJ.ColAdjust( i ), OBJ.ColWidth( i ) ); 00513 00514 if ( OBJ.Headline().GetCol( i ) ) 00515 STREAM << OBJ.Headline().GetCol( i )->Label(); 00516 00517 STREAM << std::endl; 00518 } 00519 00520 return STREAM; 00521 } 00522