00001 #include "base_control.h" 00002 #include "cursive.h" 00003 #include "curses.h" 00004 00005 namespace crs { 00006 00007 void base_control::init() { 00008 updateParentCoord(); 00009 if( mParent ) { 00010 parentHandle = mParent->registerControl( this ); 00011 } 00012 resize(); 00013 } 00014 00015 base_control::base_control( base_control *Parent, window_events *Events, 00016 const unsigned int Left, const unsigned int Top, const unsigned int Width, const unsigned int Height ): 00017 name(""), 00018 mCursorpos(0,0), 00019 events(Events), 00020 mParent(Parent), 00021 buffer( ' ', Width, Height ), 00022 mLeft(Left), 00023 mTop(Top), 00024 mWidth(Width), 00025 mHeight(Height), 00026 mVisible(false), 00027 top ( this, &base_control::getTop, &base_control::setTop ), 00028 left ( this, &base_control::getLeft, &base_control::setLeft ), 00029 width ( this, &base_control::getWidth, &base_control::setWidth ), 00030 height ( this, &base_control::getHeight, &base_control::setHeight ), 00031 parent ( this, &base_control::getParent, &base_control::setParent ), 00032 visible ( this, &base_control::getVisible, &base_control::setVisible ), 00033 curpos ( this, &base_control::getCurPos, &base_control::setCurPos ), 00034 controls ( this, &base_control::getControls ) { 00035 init(); 00036 } 00037 00038 base_control::~base_control() { 00039 if( mParent ) 00040 for( controllist::iterator i = mControls.begin(); i != mControls.end(); i++ ){ 00041 (*i)->freeRegistration(); 00042 } 00043 if( mParent ) { 00044 mParent->deregisterControl( parentHandle ); 00045 } 00046 } 00047 00048 base_control::controllist::iterator base_control::registerControl( base_control *control ) { 00049 return mControls.insert( mControls.end(), control ); 00050 } 00051 00052 void base_control::deregisterControl( controllist::iterator &i ) { 00053 mControls.erase( i ); 00054 } 00055 00056 void base_control::freeRegistration() { 00057 mParent = 0; 00058 } 00059 00060 void base_control::resize() { 00061 buffer.resize( mWidth, mHeight ); 00062 draw(); 00063 } 00064 00065 void base_control::draw_on_screen() { 00066 draw(); 00067 for( unsigned int x = 0; x < mWidth; x++ ) 00068 for( unsigned int y = 0; y < mHeight; y++ ) { 00069 mvaddch( y + mTop + parentTop, x + mLeft + parentLeft, buffer[ x + y * mWidth ] ); 00070 } 00071 } 00072 00073 void base_control::draw() { 00074 buffer.fill( ' ' ); 00075 for( controllist::iterator i = mControls.begin(); i != mControls.end(); i++ ) { 00076 (*i)->draw(); 00077 } 00078 } 00079 00080 void base_control::flush( chtype *parentWin, const unsigned int parentWidth, const unsigned int parentHeight ) { 00081 if( mVisible ) { 00082 for( controllist::iterator i = mControls.begin(); i != mControls.end(); i++ ) { 00083 (*i)->flush( &buffer[0], mWidth, mHeight ); 00084 } 00085 for( unsigned int y = 0; y < mHeight && y + mTop < parentHeight; y++ ) { 00086 std::memcpy( 00087 &parentWin[ ( y + mTop ) * parentWidth + mLeft ], 00088 &buffer[ y * mWidth ], 00089 mWidth * sizeof( chtype ) ); 00090 } 00091 } 00092 } 00093 00094 const base_control::controllist &base_control::getControls() { 00095 return mControls; 00096 } 00097 00098 void base_control::updateParentCoord() { 00099 if( mParent ) { 00100 parentTop = mParent->top; 00101 parentLeft = mParent->left; 00102 parentWidth = mParent->width; 00103 parentHeight = mParent->height; 00104 } else { 00105 parentWidth = parentHeight = parentTop = parentLeft = 0; 00106 } 00107 } 00108 00109 const bool &base_control::getVisible() { 00110 return mVisible; 00111 } 00112 00113 void base_control::setVisible( const bool &is ) { 00114 if( is != mVisible ) { 00115 if( is ) { 00116 doShow(); 00117 } else { 00118 doHide(); 00119 } 00120 mVisible = is; 00121 } 00122 } 00123 00124 void base_control::doHide() { 00125 if( events ) 00126 events->onHide( *this ); 00127 } 00128 00129 void base_control::doShow() { 00130 if( events ) 00131 events->onShow( *this ); 00132 } 00133 00134 const position &base_control::getCurPos() { 00135 return mCursorpos; 00136 } 00137 00138 void base_control::setCurPos( const position &new_pos ) { 00139 if( new_pos.x < mWidth && new_pos.y < mHeight ) { 00140 mCursorpos.x = new_pos.x; 00141 mCursorpos.y = new_pos.y; 00142 } 00143 } 00144 00145 int base_control::getAbsTop() const { 00146 return mParent ? mParent->getAbsTop() + mTop : mTop; 00147 } 00148 00149 int base_control::getAbsLeft() const { 00150 return mParent ? mParent->getAbsLeft() + mLeft : mLeft; 00151 } 00152 00153 const int &base_control::getTop() { 00154 return mTop; 00155 } 00156 00157 void base_control::setTop( const int &val ) { 00158 if( val >= 0 && val + mHeight <= parentHeight) { 00159 doMove( position( mLeft, mTop ), position( mLeft, val ) ); 00160 mTop = val; 00161 } 00162 } 00163 00164 const int &base_control::getLeft() { 00165 return mLeft; 00166 } 00167 00168 void base_control::setLeft( const int &val ) { 00169 if( val >= 0 && val + mWidth <= parentWidth ) { 00170 doMove( position( mLeft, mTop ), position( val, mTop ) ); 00171 mLeft = val; 00172 } 00173 } 00174 00175 const base_control &base_control::getParent() { 00176 return *mParent; 00177 } 00178 00179 void base_control::setParent( const base_control &win ) { 00180 mParent = const_cast<base_control*>(&win); 00181 } 00182 00183 const unsigned int &base_control::getWidth() { 00184 return mWidth; 00185 } 00186 00187 void base_control::setWidth( const unsigned int &val ) { 00188 doResize( getBounds(), bounds( mLeft, mTop, val, mHeight ) ); 00189 mWidth = val; 00190 resize(); 00191 } 00192 00193 const unsigned int &base_control::getHeight() { 00194 return mHeight; 00195 } 00196 00197 void base_control::setHeight( const unsigned int &val ) { 00198 doResize( getBounds(), bounds( mLeft, mTop, mWidth, val ) ); 00199 mHeight = val; 00200 resize(); 00201 } 00202 00203 const bounds &base_control::getBounds() { 00204 return *std::auto_ptr<bounds>( new bounds( mLeft, mTop, mWidth, mHeight ) ); 00205 } 00206 00207 void base_control::doMove( const position &old_pos, const position &new_pos ){ 00208 if( events ) 00209 events->onMove( *this, old_pos, new_pos ); 00210 } 00211 00212 void base_control::doResize( const bounds &old_bounds, const bounds &new_bounds ){ 00213 if( events ) 00214 events->onResize( *this, old_bounds, new_bounds ); 00215 } 00216 00217 void base_control::putPixel( const char ch, const unsigned int x, const unsigned int y ) { 00218 if( x <= mWidth && y <= mHeight ) { 00219 buffer[ x * y ] = ch; 00220 } 00221 } 00222 00223 void base_control::fill( const char ch ) { 00224 for( unsigned int x = 0; x < mWidth; x++ ){ 00225 for( unsigned int y = 0; y < mHeight; y++ ) { 00226 mvaddch( parentLeft + mLeft + x, parentTop + mTop + y, ch ); 00227 } 00228 } 00229 } 00230 00231 void base_control::setText( const std::string &text, const unsigned int x, const unsigned int y ) { 00232 buffer.setText( text, x, y ); 00233 } 00234 00235 focused_ctrl::focused_ctrl(base_control *Parent, window_events *Events, 00236 const unsigned int Left, const unsigned int Top, const unsigned int Width, const unsigned int Height ): 00237 base_control( Parent, Events, Left, Top, Width, Height ) { 00238 focusHandle = crsv.registerFocusable( this ); 00239 } 00240 00241 focused_ctrl::~focused_ctrl() { 00242 crsv.deregisterFocusable( focusHandle ); 00243 } 00244 00245 const style::styles &styled_ctrl::getStyle() { 00246 return mStyle; 00247 } 00248 00249 void styled_ctrl::setStyle( const style::styles &Style ) { 00250 mStyle = Style; 00251 } 00252 00253 styled_ctrl::styled_ctrl( style::styles Style, chtype clb, chtype crb ): 00254 mStyle(Style), custom_left_border(clb), custom_right_border(crb), 00255 style( this, &styled_ctrl::getStyle, &styled_ctrl::setStyle ) { 00256 } 00257 00258 } 00259