libyui-ncurses  2.44.1
/usr/src/RPM/BUILD/libyui-ncurses-2.44.1/src/NCPad.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:       NCPad.cc
00020 
00021    Author:     Michael Andres <ma@suse.de>
00022 
00023 /-*/
00024 
00025 #define  YUILogComponent "ncurses"
00026 #include <yui/YUILog.h>
00027 #include "NCPad.h"
00028 
00029 
00030 // PAD_PAGESIZE needs to be large enough to feed any destwin. We
00031 // get in throuble here if the terminal has more than 1024 lines.
00032 #define PAD_PAGESIZE 1024
00033 
00034 // Maximum height of the NCursesPad (e.g. in case it can't hold more
00035 // than 32768 lines). Larger pads need to page.
00036 //#define MAX_PAD_HEIGHT 100
00037 #define MAX_PAD_HEIGHT NCursesWindow::maxcoord()
00038 
00039 
00040 NCPad::NCPad( int lines, int cols, const NCWidget & p )
00041   : NCursesPad( lines > MAX_PAD_HEIGHT ? PAD_PAGESIZE : lines, cols )
00042   , _vheight( lines > MAX_PAD_HEIGHT ? lines : 0 )
00043   , parw( p )
00044   , destwin ( 0 )
00045   , maxdpos ( 0 )
00046   , maxspos ( 0 )
00047   , dclear  ( false )
00048   , dirty   ( false )
00049 {}
00050 
00051 
00052 void NCPad::Destwin( NCursesWindow * dwin )
00053 {
00054     if ( dwin != destwin )
00055     {
00056         destwin = dwin;
00057 
00058         if ( destwin )
00059         {
00060             wsze mysze( vheight(), width() );
00061 
00062             drect = wrect( 0, wsze( destwin->height(), destwin->width() ) );
00063             srect = wrect( 0, wsze::min( mysze, drect.Sze ) );
00064             maxdpos = drect.Pos + srect.Sze - 1;
00065             maxspos = mysze - srect.Sze;
00066 
00067             dclear = ( drect.Sze != srect.Sze );
00068             setpos( CurPos() );
00069         }
00070         else
00071         {
00072             drect = srect = wrect();
00073             maxdpos = maxspos = 0;
00074         }
00075     }
00076 }
00077 
00078 
00079 void NCPad::resize( wsze nsze )
00080 {
00081     SetPadSize( nsze ); // might be enlarged by NCPadWidget if redirected
00082 
00083     if ( nsze.H != vheight()
00084          || nsze.W != width() )
00085     {
00086         NCursesWindow * odest = Destwin();
00087 
00088         if ( odest )
00089             Destwin( 0 );
00090 
00091         if ( nsze.H > MAX_PAD_HEIGHT )
00092         {
00093           yuiDebug() << "TRUCNATE PAD: " << nsze.H << " > " << MAX_PAD_HEIGHT << std::endl;
00094           NCursesPad::resize( PAD_PAGESIZE, nsze.W );
00095           _vheight = nsze.H;
00096         }
00097         else
00098         {
00099         NCursesPad::resize( nsze.H, nsze.W );
00100           _vheight = 0;
00101         }
00102 
00103         yuiDebug() << "Pageing ?: " << pageing() << std::endl;
00104 
00105         if ( odest )
00106             Destwin( odest );
00107     }
00108 }
00109 
00110 
00111 void NCPad::updateScrollHint()
00112 {
00113     NCScrollHint::VSet( srect.Sze.H + maxspos.L, srect.Sze.H, srect.Pos.L );
00114     NCScrollHint::HSet( srect.Sze.W + maxspos.C, srect.Sze.W, srect.Pos.C );
00115 }
00116 
00117 
00118 int NCPad::update()
00119 {
00120     if ( destwin )
00121     {
00122         if ( dirty )
00123         {
00124             return dirtyPad();
00125         }
00126 
00127         if ( dclear )
00128             destwin->clear();
00129 
00130         updateScrollHint();
00131 
00132         if ( ! pageing() )
00133         {
00134         return copywin( *destwin,
00135                         srect.Pos.L, srect.Pos.C,
00136                         drect.Pos.L, drect.Pos.C,
00137                         maxdpos.L,   maxdpos.C,
00138                         false );
00139     }
00140 
00141         // Here: Table is pageing, so we must prepare the visible lines
00142         // on the Pad before we're copying them to the destwin:
00143         wsze lSze( 1, width() );
00144         for ( int i = 0; i <= maxdpos.L; ++i )
00145         {
00146             directDraw( *this, wrect( wpos( i, 0 ), lSze ), srect.Pos.L+i );
00147         }
00148         return copywin( *destwin,
00149                         0, srect.Pos.C,
00150                         drect.Pos.L, drect.Pos.C,
00151                         maxdpos.L,   maxdpos.C,
00152                         false );
00153     }
00154     return OK;
00155 }
00156 
00157 
00158 int NCPad::setpos( const wpos & newpos )
00159 {
00160     srect.Pos = newpos.between( 0, maxspos );
00161     return update();
00162 }
00163 
00164 
00165 void NCPad::wRecoded()
00166 {
00167     yuiDebug() << "NCPad::wRecoded" << std::endl;
00168 }
00169 
00170 
00171 bool NCPad::handleInput( wint_t key )
00172 {
00173     bool handled = true;
00174 
00175     switch ( key )
00176     {
00177         case KEY_UP:
00178             ScrlUp();
00179             break;
00180 
00181         case KEY_PPAGE:
00182             ScrlUp( destwin->maxy() );
00183             break;
00184 
00185         case KEY_HOME:
00186             ScrlUp( vheight() );
00187             break;
00188 
00189         case KEY_DOWN:
00190             ScrlDown();
00191             break;
00192 
00193         case KEY_NPAGE:
00194             ScrlDown( destwin->maxy() );
00195             break;
00196 
00197         case KEY_END:
00198             ScrlDown( vheight() );
00199             break;
00200 
00201         case KEY_LEFT:
00202         case KEY_SLEFT:
00203             ScrlLeft();
00204             break;
00205 
00206         case KEY_RIGHT:
00207         case KEY_SRIGHT:
00208             ScrlRight();
00209             break;
00210 
00211         default:
00212             handled = false;
00213             break;
00214     }
00215 
00216     return handled;
00217 }
 All Classes Functions Variables