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