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: NCIntField.cc 00020 00021 Author: Michael Andres <ma@suse.de> 00022 00023 /-*/ 00024 00025 #define YUILogComponent "ncurses" 00026 #include <yui/YUILog.h> 00027 #include "NCurses.h" 00028 #include "NCIntField.h" 00029 #include "NCPopupTextEntry.h" 00030 #include "stringutil.h" 00031 #include "stdutil.h" 00032 00033 using stdutil::numstring; 00034 00035 const unsigned NCIntField::taglen = 2; // "^v" 00036 00037 00038 NCIntField::NCIntField( YWidget * parent, 00039 const std::string & nlabel, 00040 int minV, int maxV, 00041 int initialV ) 00042 : YIntField( parent, nlabel, 00043 minV <= maxV ? minV : maxV, 00044 maxV >= minV ? maxV : minV ) 00045 , NCWidget( parent ) 00046 , lwin( 0 ) 00047 , twin( 0 ) 00048 , cvalue( initialV ) 00049 , vlen( 0 ) 00050 , vstart( 0 ) 00051 { 00052 yuiDebug() << std::endl; 00053 vlen = numstring( minValue() ).length(); 00054 unsigned tmpval = numstring( maxValue() ).length(); 00055 00056 if ( tmpval > vlen ) 00057 vlen = tmpval; 00058 00059 setLabel( nlabel ); 00060 hotlabel = &label; 00061 setValue( initialV ); 00062 } 00063 00064 00065 NCIntField::~NCIntField() 00066 { 00067 delete lwin; 00068 delete twin; 00069 yuiDebug() << std::endl; 00070 } 00071 00072 00073 int NCIntField::preferredWidth() 00074 { 00075 return wGetDefsze().W; 00076 } 00077 00078 00079 int NCIntField::preferredHeight() 00080 { 00081 return wGetDefsze().H; 00082 } 00083 00084 00085 void NCIntField::setEnabled( bool do_bv ) 00086 { 00087 NCWidget::setEnabled( do_bv ); 00088 YIntField::setEnabled( do_bv ); 00089 } 00090 00091 00092 void NCIntField::setSize( int newwidth, int newheight ) 00093 { 00094 wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); 00095 } 00096 00097 00098 void NCIntField::setDefsze() 00099 { 00100 unsigned cols = vlen + taglen; 00101 defsze = wsze( label.height() + 1, 00102 label.width() < cols ? cols : label.width() ); 00103 } 00104 00105 00106 void NCIntField::wCreate( const wrect & newrect ) 00107 { 00108 NCWidget::wCreate( newrect ); 00109 00110 if ( !win ) 00111 return; 00112 00113 wrect lrect( 0, wsze::min( newrect.Sze, 00114 wsze( label.height(), newrect.Sze.W ) ) ); 00115 00116 wrect trect( 0, wsze( 1, newrect.Sze.W ) ); 00117 00118 if ( lrect.Sze.H == newrect.Sze.H ) 00119 lrect.Sze.H -= 1; 00120 00121 trect.Pos.L = lrect.Sze.H > 0 ? lrect.Sze.H : 0; 00122 00123 lwin = new NCursesWindow( *win, 00124 lrect.Sze.H, lrect.Sze.W, 00125 lrect.Pos.L, lrect.Pos.C, 00126 'r' ); 00127 00128 twin = new NCursesWindow( *win, 00129 trect.Sze.H, trect.Sze.W, 00130 trect.Pos.L, trect.Pos.C, 00131 'r' ); 00132 00133 //vstart = ( vlen + 2 < ( unsigned )trect.Sze.W ) ? label.width() - vlen - 2 : 0; 00134 vstart = 0; 00135 // vstart is calculated from label width only if value length (+ tags) is smaller 00136 // than window width AND smaller than label width, otherwise start with 0 00137 // (bug #488757) 00138 if ( vlen + 2 < ( unsigned )trect.Sze.W && vlen + 2 < label.width() ) 00139 { 00140 vstart = label.width() - vlen - 2; 00141 } 00142 } 00143 00144 00145 void NCIntField::wDelete() 00146 { 00147 delete lwin; 00148 delete twin; 00149 lwin = 0; 00150 twin = 0; 00151 NCWidget::wDelete(); 00152 vstart = 0; 00153 } 00154 00155 00156 void NCIntField::setLabel( const std::string & nlabel ) 00157 { 00158 label = NCstring( nlabel ); 00159 label.stripHotkey(); 00160 setDefsze(); 00161 YIntField::setLabel( nlabel ); 00162 Redraw(); 00163 } 00164 00165 00166 void NCIntField::setValueInternal( int newValue ) 00167 { 00168 // checking newValue is done by YIntField 00169 // -> no checks required 00170 cvalue = newValue; 00171 tUpdate(); 00172 } 00173 00174 00175 bool NCIntField::Increment( const bool bigstep ) 00176 { 00177 unsigned dist = maxValue() - cvalue; 00178 00179 if ( !dist ) 00180 return false; 00181 00182 unsigned step = bigstep ? 10 : 1; 00183 00184 if ( step < dist ) 00185 setValue( cvalue + step ); 00186 else 00187 setValue( maxValue() ); 00188 00189 return true; 00190 } 00191 00192 00193 bool NCIntField::Decrement( const bool bigstep ) 00194 { 00195 unsigned dist = cvalue - minValue(); 00196 00197 if ( !dist ) 00198 return false; 00199 00200 unsigned step = bigstep ? 10 : 1; 00201 00202 if ( step < dist ) 00203 setValue( cvalue - step ); 00204 else 00205 setValue( minValue() ); 00206 00207 return true; 00208 } 00209 00210 00211 void NCIntField::wRedraw() 00212 { 00213 if ( !win ) 00214 return; 00215 00216 // label 00217 const NCstyle::StWidget & style( widgetStyle( true ) ); 00218 00219 lwin->bkgd( style.plain ); 00220 00221 lwin->clear(); 00222 00223 label.drawAt( *lwin, style ); 00224 00225 tUpdate(); 00226 } 00227 00228 00229 void NCIntField::tUpdate() 00230 { 00231 if ( !win ) 00232 return; 00233 00234 const NCstyle::StWidget & style( widgetStyle() ); 00235 00236 twin->bkgd( widgetStyle( true ).plain ); 00237 00238 twin->bkgdset( style.data ); 00239 00240 twin->printw( 0, vstart, " %*d ", vlen, cvalue ); 00241 00242 twin->bkgdset( style.scrl ); 00243 00244 twin->addch( 0, vstart, 00245 ( cvalue != minValue() ? ACS_DARROW : ' ' ) ); 00246 00247 twin->addch( 0, vstart + vlen + 1, 00248 ( cvalue != maxValue() ? ACS_UARROW : ' ' ) ); 00249 } 00250 00251 00252 NCursesEvent NCIntField::wHandleInput( wint_t key ) 00253 { 00254 NCursesEvent ret; 00255 bool beep = false; 00256 int ovlue = cvalue; 00257 00258 switch ( key ) 00259 { 00260 case KEY_UP: 00261 beep = !Increment(); 00262 break; 00263 00264 case KEY_DOWN: 00265 beep = !Decrement(); 00266 break; 00267 00268 case KEY_PPAGE: 00269 beep = !Increment( true ); 00270 break; 00271 00272 case KEY_NPAGE: 00273 beep = !Decrement( true ); 00274 break; 00275 00276 case KEY_HOME: 00277 00278 if ( cvalue != maxValue() ) 00279 setValue( maxValue() ); 00280 else 00281 beep = true; 00282 break; 00283 00284 case KEY_END: 00285 if ( cvalue != minValue() ) 00286 setValue( minValue() ); 00287 else 00288 beep = true; 00289 break; 00290 00291 case L'0': 00292 case L'1': 00293 case L'2': 00294 case L'3': 00295 case L'4': 00296 case L'5': 00297 case L'6': 00298 case L'7': 00299 case L'8': 00300 case L'9': 00301 case L'-': 00302 enterPopup( key ); 00303 break; 00304 00305 case L'+': 00306 enterPopup(); 00307 break; 00308 00309 case KEY_HOTKEY: 00310 break; 00311 00312 default: 00313 beep = true; 00314 break; 00315 } 00316 00317 if ( beep ) 00318 ::beep(); 00319 00320 if ( notify() && ovlue != cvalue ) 00321 ret = NCursesEvent::ValueChanged; 00322 00323 return ret; 00324 } 00325 00326 00327 int NCIntField::enterPopup( wchar_t first ) 00328 { 00329 std::wstring wch( &first ); 00330 std::string utf8; 00331 00332 wpos at( ScreenPos() + wpos( win->maxy() - 1, vstart + 1 ) ); 00333 std::string label( std::string( "[" ) + numstring( minValue() ) 00334 + "," + numstring( maxValue() ) + "]" ); 00335 00336 std::string text( 1, ( char )first ); 00337 NCPopupTextEntry * dialog = new NCPopupTextEntry( at, label, text, vlen, 0, 00338 NCInputField::NUMBER ); 00339 YUI_CHECK_NEW( dialog ); 00340 00341 while ( dialog->post() != -1 ) 00342 { 00343 int nval = atoi( dialog->value().c_str() ); 00344 00345 if ( nval < minValue() ) 00346 { 00347 dialog->setValue( numstring( minValue() ) ); 00348 } 00349 else if ( maxValue() < nval ) 00350 { 00351 dialog->setValue( numstring( maxValue() ) ); 00352 } 00353 else 00354 { 00355 setValue( nval ); 00356 break; 00357 } 00358 00359 ::beep(); 00360 } 00361 00362 YDialog::deleteTopmostDialog(); 00363 00364 return 0; 00365 }