libyui-ncurses  2.44.1
/usr/src/RPM/BUILD/libyui-ncurses-2.44.1/src/NCIntField.cc
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 }
 All Classes Functions Variables