00001 #include "cursive.h"
00002 #include "except.h"
00003 #include "debug_ctrl.h"
00004 #include <ncurses.h>
00005 #include <memory>
00006
00007 #include <sstream>
00008
00010
00015 namespace crs {
00016
00017 namespace sc {
00018 chtype LowerLeftCorner = ACS_LLCORNER;
00019 chtype LowerRightCorner = ACS_LRCORNER;
00020 chtype UpperLeftCorner = ACS_ULCORNER;
00021 chtype UpperRightCorner = ACS_URCORNER;
00022 chtype HorizontalLine = ACS_HLINE;
00023 chtype VerticalLine = ACS_VLINE;
00024 chtype getLeftBorder( unsigned char num, chtype custom ) {
00025 if( num > 4 )
00026 return '[';
00027 if( num == 4 )
00028 return custom;
00029 static const chtype left_border[4] = { '[', '(', '{', '<' };
00030 return left_border[ num ];
00031 }
00032 chtype getRightBorder( unsigned char num, chtype custom ) {
00033 if( num > 4 )
00034 return '[';
00035 if( num == 4 )
00036 return custom;
00037 static const chtype right_border[4] = { ']', ')', '}', '>' };
00038 return right_border[ num ];
00039 }
00040 }
00041
00042 cursive crsv;
00043
00044 cursive::screen_ctrl::screen_ctrl( cursive *Crs ):
00045 base_control( 0, 0 ),
00046 crs(Crs) {
00047 int w, h;
00048 getmaxyx( stdscr, h, w );
00049 mHeight = h;
00050 mWidth = w;
00051 resize();
00052 }
00053
00054 cursive::cursive(): focused(0) {
00055 if( ::initscr() == 0 ) {
00056 throw except::syscall( "initscr()", 0 );
00057 }
00058 ::nonl();
00059 ::keypad( stdscr, TRUE );
00060 ::cbreak();
00061 ::noecho();
00062 ::notimeout( stdscr, TRUE );
00063 sc::LowerLeftCorner = ACS_LLCORNER;
00064 sc::LowerRightCorner = ACS_LRCORNER;
00065 sc::UpperLeftCorner = ACS_ULCORNER;
00066 sc::UpperRightCorner = ACS_URCORNER;
00067 sc::HorizontalLine = ACS_HLINE;
00068 sc::VerticalLine = ACS_VLINE;
00069 mScreen = new screen_ctrl( this );
00070 }
00071
00072 cursive::~cursive(){
00073 delete mScreen;
00074 ::endwin();
00075 }
00076
00077 int cursive::mainloop() {
00078 int key = 0;
00079 bool end = false;
00080 mScreen->finalflush();
00081 while ( !end ) {
00082 key = ::getch();
00083 switch( key ) {
00084 case '\t':
00085 if( ++focused_it != focusable.end() )
00086 setFocus( *focused_it );
00087 else
00088 setFocus( *( focusable.begin() ) );
00089 break;
00090 }
00091 if( *focused_it ) {
00092 if( focused->keyPress( key ) ) {
00093
00094 switch( key ) {
00095 case 'q':
00096 end = true;
00097 break;
00098 }
00099 }
00100 }
00101 mScreen->finalflush();
00102 }
00103 return 0;
00104 }
00105
00106 void cursive::screen_ctrl::drawall() {
00107 draw();
00108 for( controllist::iterator i = mControls.begin(); i != mControls.end(); i++ ) {
00109 (*i)->draw();
00110 }
00111 }
00112
00113 void cursive::screen_ctrl::finalflush() {
00114 draw();
00115 for( controllist::iterator i = mControls.begin(); i != mControls.end(); i++ ) {
00116 (*i)->draw();
00117 (*i)->flush( &buffer[0], mWidth, mHeight );
00118 }
00119
00120 for( unsigned int x = 0; x < mWidth; x++ )
00121 for( unsigned int y = 0; y < mHeight; y++ )
00122 mvaddch( y, x, buffer[ x + ( y * mWidth ) ] );
00123 if( crsv.focused ) {
00124 unsigned int fabstop = crsv.focused->getAbsTop();
00125 unsigned int fabsleft = crsv.focused->getAbsLeft();
00126 for( unsigned int y = crsv.getFocused()->getAbsTop();
00127 y <= fabstop + crsv.getFocused()->height.get() - 1; y++ )
00128 mvchgat( y, fabsleft, crsv.focused->width.get(), A_BOLD, 0, 0 );
00129 mvaddstr( fabstop + crsv.focused->curpos.get().y, fabsleft + crsv.focused->curpos.get().x, "" );
00130 }
00131 }
00132
00133 void cursive::screen_ctrl::deregisterControl( base_control::controllist::iterator &i ) {
00134 if( *i == crs->focused )
00135 crs->focused = *(crs->focusable.begin());
00136 base_control::deregisterControl( i );
00137 }
00138
00139 focused_ctrl::focuslist::iterator cursive::registerFocusable( focused_ctrl *control ) {
00140 if( !focused ) {
00141 focused = control;
00142 focused_it = focusable.insert( focusable.end(), control );
00143 return focused_it;
00144 } else {
00145 return focusable.insert( focusable.end(), control );
00146 }
00147 }
00148
00149 void cursive::deregisterFocusable( focused_ctrl::focuslist::iterator &i ) {
00150 focusable.erase( i );
00151 }
00152
00153 }
00154