#include "../include/xcv_license.h" //PCH namespace Widgets95 {//-. //<-' void ui::history::_history() //~history { int gmid = extra_data._glut_menu_id; if(-1!=gmid) glutDestroyMenu(gmid); for(int i=0;i_delete(); } bool ui::history::_activate(int how) { if(how&&how!=ACTIVATE_MOUSE) { if(_sel_end==_sel_start) { //HACK? Not (quite) yet activated. //if(e::set_caret(this,_sel_end)) { e.curr_caret_pt = _sel_end; find_insertion_xy(&e.caret_x,&e.caret_y); } } } return true; } /****************************** WIDGETS_95_CommandLine::key_handler() **********/ bool ui::history::_key_handler(int key, int modifiers) { _dump("-> CMD_TEXT KEY HANDLER"); if(key=='\r'||key==-'\r' &&_return_input_model==ui::ACTIVATE_OTHER) { add_to_history(_text); execute_callback(); e::set_edited(); //Reproduce textbox semantics? set_text(); return false; } bool ret = Super::_key_handler(key,modifiers); _dump("<- CMD_TEXT KEY HANDLER"); return ret; } /**************************** WIDGETS_95_CommandLine::special_handler() **********/ static bool xcv_history_context_menu = false; extern bool xcv_widgets_context_menu(int,int,int); bool ui::history::_special_handler(int key, int modifiers) { _dump("-> CMD_TEXT KEY SPECIAL"); bool ret = false; if(key==GLUT_KEY_UP||key==GLUT_KEY_DOWN) // PREVIOUS/NEXT HISTORY { if(key&2&&_curr_hist>=_newest_hist-1) //DOWN if(xcv_history_context_menu=glut::get_wxWidgets_enabled()) //HACK { //GLUT doesn't have its own manual menu system. int local_x = _x_abs+_x_lr; int local_y = _y_abs+_h-_y_off_bot; _mouse_over(true,local_x,local_y); xcv_widgets_context_menu(GLUT_RIGHT_BUTTON,local_x,local_y); _mouse_over(false,local_x,local_y); xcv_history_context_menu = false; goto resume; } scroll_history(key==GLUT_KEY_UP?-1:1); } else ret = Super::_special_handler(key,modifiers); //textbox resume: _dump("<- CMD_TEXT KEY SPECIAL"); return ret; } /**************************** WIDGETS_95_CommandLine::recall_history() ********/ bool ui::history::recall_history(int hist_num) { if(hist_num<_oldest_hist||hist_num>_newest_hist||hist_num==_curr_hist) { return false; } // Commit the current text first before we blow it away! if(_curr_hist==_newest_hist) { string* &s = history_str_ptr(_newest_hist); if(!s) s = &s->_dup(); s->assign(_text.c_str(),_text.size()); } _curr_hist = hist_num; set_text(history_str(_curr_hist)); special_handler(GLUT_KEY_END); update_and_draw_text(); return true; } /**************************** WIDGETS_95_CommandLine::add_to_history() ********/ bool ui::history::add_to_history(c_string cmp) { if(!cmp.str||!cmp.str[0]) return false; // don't add if it's empty string* &s = history_str_ptr(_newest_hist); //if(s==cmp.str) return false; if(s&&!strcmp(s->c_str(),cmp.str)) return false; // don't double stuff //FIX ME: Insert? int &gmid = extra_data._glut_menu_id; if(gmid!=-1) { glutDestroyMenu(gmid); gmid = -1; } _curr_hist = _newest_hist; //s = _text; // save previous command text if(!s) s = &s->_dup(); s->assign(_text.c_str(),_text.size()); _newest_hist = ++_curr_hist; if(_newest_hist>=_add_to_history_HIST_SIZE) { // bump oldest off the list //_hist_list.erase(_hist_list.begin()); //_hist_list.push_back(""); _hist_list[_oldest_hist_wrap]->clear(); ++_oldest_hist_wrap%=_add_to_history_HIST_SIZE; _oldest_hist++; } return true; } ///////// MENU SYSTEM /////////// static void xcv_history_glutCreateMenu_callback(int i) { ui::history *my = dynamic_cast(e.menu_control); if(!my){ assert(0); return; } e.set_menu(); //LEFT_BUTTON? //This is an alternative, simpler input model. //Command prompt style uses UP, whereas menus //use DOWN. my->recall_history(i); my->_curr_hist = my->_newest_hist; my->execute_callback(); } bool ui::history::_mouse_rdown_handler(int local_x, int local_y) { //spacebar_mouse_click? if(local_x>0&&!box_test(local_x,local_y)) return true; if(glut::get_wxWidgets_enabled()) //HACK { //GLUT doesn't have its own manual menu system. //TODO: Will need this to render button pressed. xcv_history_context_menu = true; int local_x = _x_abs+_x_lr; int local_y = _y_abs+_h-_y_off_bot; _mouse_over(true,local_x,local_y); xcv_widgets_context_menu(GLUT_RIGHT_BUTTON,local_x,local_y); _mouse_over(false,local_x,local_y); xcv_history_context_menu = false; } return false; } bool ui::history::_mouse_over(bool inside, int local_x, int local_y) { if(!xcv_history_context_menu &&glut::get_wxWidgets_enabled()) return true; int &gmid = extra_data._glut_menu_id; if(inside&&_enabled&&box_test(local_x,local_y)) { if(!xcv_history_context_menu) glutSetCursor(GLUT_CURSOR_TEXT); if(gmid<=0) //NEW { gmid = glutCreateMenu(xcv_history_glutCreateMenu_callback); for(int i=_oldest_hist,iN=_newest_hist;iempty()) glutAddMenuEntry(s->c_str(),i); } } glutSetMenu(gmid); //NEW glutAttachMenu(GLUT_RIGHT_BUTTON); //GLUT_LEFT_BUTTON e::set_menu(this); //LEFT_BUTTON? return false; } else if(-1!=gmid) { //See dropdown notes on what works. glutSetMenu(gmid); glutDetachMenu(GLUT_RIGHT_BUTTON); //GLUT_LEFT_BUTTON; e::set_menu(); //LEFT_BUTTON? } return true; } /*************************************** WIDGETS_95_CommandLine::_dump() **************/ #ifdef WIDGETS_95_DEBUG_STDOUT void ui::history::_dump(const char *name) { fprintf(_dump_FILE, "%s (commandline@%p): ins_pt:%d subs:%d/%d sel:%d/%d len:%d\n",name,this, e.curr_caret_pt,substr_start,substr_end,sel_start,sel_end,(int)text.size()); } #endif //---. }//<-'