int GLUI_EditText::key_handler( unsigned char key,int modifiers ) { int i, regular_key; /* int has_selection; */ if ( NOT glui ) return false; if ( debug ) dump( stdout, "-> KEY HANDLER" ); regular_key = false; /* has_selection = (sel_start != sel_end); */ if ( key == 21 AND (modifiers & GLUT_ACTIVE_CTRL )!=0) { /* DEL all text */ /** This one (key==21) may not port!! */ insertion_pt = -1; text[0] = '\0'; sel_start = sel_end = -1; } else if ( key == 13 ) { /* RETURN */ /* glui->disactivate_current_control(); */ disactivate(); /** Force callbacks, etc **/ activate(GLUI_ACTIVATE_TAB); /** Reselect all text **/ translate_and_draw_front(); return true; } else if ( key == 27 ) { /* ESCAPE */ glui->disactivate_current_control(); return true; } else if ( key == 8 ) { /* BACKSPACE */ if ( sel_start == sel_end ) { /* no selection */ if ( insertion_pt > 0 ) { /*** See if we're deleting a period in a float data-type box ***/ if ( data_type == GLUI_EDITTEXT_FLOAT AND text[insertion_pt-1]=='.' ) num_periods--; /*** Shift over string first ***/ insertion_pt--; for( i=insertion_pt; i< (int)strlen( text ); i++ ) text[i] = text[i+1]; } } else { /* There is a selection */ clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } } else { /* Regular key */ regular_key = true; /** Check if we only accept numbers **/ if (data_type == GLUI_EDITTEXT_FLOAT ) { if ( (key < '0' OR key > '9') AND key != '.' AND key != '-' ) return true; if ( key == '-' ) { /* User typed a '-' */ /* If user has first character selected, then '-' is allowed */ if ( NOT ( MIN(sel_start,sel_end) == 0 AND MAX(sel_start,sel_end) > 0 ) ) { /* User does not have 1st char selected */ if (insertion_pt != 0 OR text[0] == '-' ) { return true; /* Can only place negative at beginning of text, and only one of them */ } } } if ( key == '.' ) { /*printf( "PERIOD: %d\n", num_periods ); */ if ( num_periods > 0 ) { /** We're trying to type a period, but the text already contains a period. Check whether the period is contained within is current selection (thus it will be safely replaced) **/ int period_found = false; if ( sel_start != sel_end ) { for( i=MIN(sel_end,sel_start); i<MAX(sel_start,sel_end); i++ ) { /* printf( "%c ", text[i] ); */ if ( text[i] == '.' ) { period_found = true; break; } } } /* printf( "found: %d num: %d\n", period_found, num_periods ); */ if ( NOT period_found ) return true; } } } else if (data_type == GLUI_EDITTEXT_INT) { if ( (key < '0' OR key > '9') AND key != '-' ) return true; if ( key == '-' ) { /* User typed a '-' */ /* If user has first character selected, then '-' is allowed */ if ( NOT ( MIN(sel_start,sel_end) == 0 AND MAX(sel_start,sel_end) > 0 ) ) { /* User does not have 1st char selected */ if (insertion_pt != 0 OR text[0] == '-' ) { return true; /* Can only place negative at beginning of text, and only one of them */ } } } } /** This is just to get rid of warnings - the flag regular_key is set if the key was not a backspace, return, whatever. But I believe if we're here, we know it was a regular key anyway */ if ( regular_key ) { } /**** If there's a current selection, erase it ******/ if ( sel_start != sel_end ) { clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } /******** check whether we have space ******/ if ( (int)strlen( text ) + 2 >= sizeof( GLUI_String )) return false; /******** We insert the character into the string ***/ /*** Shift over string first ***/ for( i=(int)strlen( text ); i >= insertion_pt; i-- ) text[i+1] = text[i]; /******** Now insert the character ********/ text[insertion_pt] = key; /******** Move the insertion point and substring_end one over ******/ insertion_pt++; substring_end++; sel_start = sel_end = insertion_pt; } /******** Now redraw text ***********/ /* Hack to prevent text box from being cleared first **/ /** int substring_change = update_substring_bounds(); draw_text_only = (NOT substring_change AND NOT has_selection AND regular_key ); */ draw_text_only = false; /** Well, hack is not yet working **/ update_and_draw_text(); draw_text_only = false; if ( debug ) dump( stdout, "<- KEY HANDLER" ); /*** Now look to see if this string has a period ***/ num_periods = 0; for( i=0; i<(int)strlen(text); i++ ) if ( text[i] == '.' ) num_periods++; return true; }
int GLUI_EditText::key_handler( unsigned char key,int modifiers ) { int i, regular_key; /* int has_selection; */ if ( NOT glui ) return false; if ( debug ) dump( stdout, "-> KEY HANDLER" ); regular_key = false; bool ctrl_down = (modifiers & GLUT_ACTIVE_CTRL)!=0; /* has_selection = (sel_start != sel_end); */ if ( key == CTRL('m') ) { /* RETURN */ /* glui->deactivate_current_control(); */ deactivate(); /** Force callbacks, etc **/ activate(GLUI_ACTIVATE_TAB); /** Reselect all text **/ redraw(); return true; } else if ( key == CTRL('[')) { /* ESCAPE */ glui->deactivate_current_control(); return true; } else if ( (key == 127 AND !ctrl_down) OR /* FORWARD DELETE */ ( key == CTRL('d') AND modifiers == GLUT_ACTIVE_CTRL) ) { if ( sel_start == sel_end ) { /* no selection */ if ( insertion_pt < (int)text.length() ) { /*** See if we're deleting a period in a float data-type box ***/ if ( ((data_type == GLUI_EDITTEXT_FLOAT) OR (data_type == GLUI_EDITTEXT_DOUBLE)) AND text[insertion_pt]=='.' ) num_periods--; /*** Shift over string first ***/ text.erase(insertion_pt,1); } } else { /* There is a selection */ clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } } else if ( ((key == 127) AND ctrl_down) OR // Delete word forward ((key == 'd') AND (modifiers == GLUT_ACTIVE_ALT)) ) { if ( sel_start == sel_end ) { /* no selection */ sel_start = insertion_pt; sel_end = find_word_break( insertion_pt, +1 ); } clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } else if ( key == CTRL('h') ) { /* BACKSPACE */ if ( sel_start == sel_end ) { /* no selection */ if ( insertion_pt > 0 ) { /*** See if we're deleting a period in a float data-type box ***/ if ( ((data_type == GLUI_EDITTEXT_FLOAT) OR (data_type == GLUI_EDITTEXT_DOUBLE)) AND text[insertion_pt-1]=='.' ) num_periods--; /*** Shift over string first ***/ insertion_pt--; text.erase(insertion_pt,1); } } else { /* There is a selection */ clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } } else if ( modifiers == GLUT_ACTIVE_CTRL ) /* CTRL ONLY */ { /* Ctrl-key bindings */ if ( key == CTRL('a') ) { return special_handler( GLUT_KEY_HOME, 0 ); } else if ( key == CTRL('e') ) { return special_handler( GLUT_KEY_END, 0 ); } else if ( key == CTRL('b') ) { return special_handler( GLUT_KEY_LEFT, 0 ); } else if ( key == CTRL('f') ) { return special_handler( GLUT_KEY_RIGHT, 0 ); } else if ( key == CTRL('p') ) { return special_handler( GLUT_KEY_UP, 0 ); } else if ( key == CTRL('n') ) { return special_handler( GLUT_KEY_DOWN, 0 ); } else if ( key == CTRL('u') ) { /* ERASE LINE */ insertion_pt = 0; text.erase(0,text.length()); sel_start = sel_end = 0; } else if ( key == CTRL('k') ) { /* KILL TO END OF LINE */ sel_start = sel_end = insertion_pt; text.erase(insertion_pt,GLUI_String::npos); } } else if ( modifiers == GLUT_ACTIVE_ALT ) /* ALT ONLY */ { if ( key == 'b' ) { // Backward word return special_handler ( GLUT_KEY_LEFT, GLUT_ACTIVE_CTRL ); } if ( key == 'f' ) { // Forward word return special_handler ( GLUT_KEY_RIGHT, GLUT_ACTIVE_CTRL ); } } else if ( (modifiers & GLUT_ACTIVE_CTRL) OR (modifiers & GLUT_ACTIVE_ALT) ) { /** ignore other keys with modifiers */ return true; } else { /* Regular key */ regular_key = true; /** Check if we only accept numbers **/ if ((data_type == GLUI_EDITTEXT_FLOAT ) OR (data_type == GLUI_EDITTEXT_DOUBLE)) { if ( (key < '0' OR key > '9') AND key != '.' AND key != '-' ) return true; if ( key == '-' ) { /* User typed a '-' */ /* If user has first character selected, then '-' is allowed */ if ( NOT ( MIN(sel_start,sel_end) == 0 AND MAX(sel_start,sel_end) > 0 ) ) { /* User does not have 1st char selected */ if (insertion_pt != 0 OR text[0] == '-' ) { return true; /* Can only place negative at beginning of text, and only one of them */ } } } if ( key == '.' ) { /*printf( "PERIOD: %d\n", num_periods ); */ if ( num_periods > 0 ) { /** We're trying to type a period, but the text already contains a period. Check whether the period is contained within is current selection (thus it will be safely replaced) **/ int period_found = false; if ( sel_start != sel_end ) { for( i=MIN(sel_end,sel_start); i<MAX(sel_start,sel_end); i++ ) { /* printf( "%c ", text[i] ); */ if ( text[i] == '.' ) { period_found = true; break; } } } /* printf( "found: %d num: %d\n", period_found, num_periods ); */ if ( NOT period_found ) return true; } } } else if (data_type == GLUI_EDITTEXT_INT) { if ( (key < '0' OR key > '9') AND key != '-' ) return true; if ( key == '-' ) { /* User typed a '-' */ /* If user has first character selected, then '-' is allowed */ if ( NOT ( MIN(sel_start,sel_end) == 0 AND MAX(sel_start,sel_end) > 0 ) ) { /* User does not have 1st char selected */ if (insertion_pt != 0 OR text[0] == '-' ) { return true; /* Can only place negative at beginning of text, and only one of them */ } } } } /** This is just to get rid of warnings - the flag regular_key is set if the key was not a backspace, return, whatever. But I believe if we're here, we know it was a regular key anyway */ if ( regular_key ) { } /**** If there's a current selection, erase it ******/ if ( sel_start != sel_end ) { clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } /******** We insert the character into the string ***/ text.insert(insertion_pt,1,key); /******** Move the insertion point and substring_end one over ******/ insertion_pt++; substring_end++; sel_start = sel_end = insertion_pt; } /******** Now redraw text ***********/ /* Hack to prevent text box from being cleared first **/ /** int substring_change = update_substring_bounds(); draw_text_only = (NOT substring_change AND NOT has_selection AND regular_key ); */ draw_text_only = false; /** Well, hack is not yet working **/ update_and_draw_text(); draw_text_only = false; if ( debug ) dump( stdout, "<- KEY HANDLER" ); /*** Now look to see if this string has a period ***/ num_periods = 0; for( i=0; i<(int)text.length(); i++ ) if ( text[i] == '.' ) num_periods++; return true; }
/****************************** GLUI_TextBox::key_handler() **********/ int GLUI_TextBox::key_handler( unsigned char key,int modifiers ) { /* int has_selection; */ if ( NOT glui ) return false; if ( debug ) dump( stdout, "-> KEY HANDLER" ); bool ctrl_down = (modifiers & GLUT_ACTIVE_CTRL)!=0; /* has_selection = (sel_start != sel_end); */ if ( key == CTRL('[')) { /* ESCAPE */ glui->deactivate_current_control(); return true; } else if ( (key == 127 AND !ctrl_down) OR /* FORWARD DELETE */ ( key == CTRL('d') AND modifiers == GLUT_ACTIVE_CTRL) ) { if ( sel_start == sel_end ) { /* no selection */ if ( insertion_pt < (int)text.length() ) { text.erase(insertion_pt,1); } } else { /* There is a selection */ clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } } else if ( ((key == 127) AND ctrl_down) OR // Delete word forward ((key == 'd') AND (modifiers == GLUT_ACTIVE_ALT)) ) { if ( sel_start == sel_end ) { /* no selection */ sel_start = insertion_pt; sel_end = find_word_break( insertion_pt, +1 ); } clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } else if ( key == CTRL('h') ) { /* BACKSPACE */ if ( sel_start == sel_end ) { /* no selection */ if ( insertion_pt > 0 ) { insertion_pt--; text.erase(insertion_pt,1); } } else { /* There is a selection */ clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } } else if ( modifiers == GLUT_ACTIVE_CTRL ) /* CTRL ONLY */ { /* Ctrl-key bindings */ if ( key == CTRL('a') ) { return special_handler( GLUT_KEY_HOME, 0 ); } else if ( key == CTRL('e') ) { return special_handler( GLUT_KEY_END, 0 ); } else if ( key == CTRL('b') ) { return special_handler( GLUT_KEY_LEFT, 0 ); } else if ( key == CTRL('f') ) { return special_handler( GLUT_KEY_RIGHT, 0 ); } else if ( key == CTRL('p') ) { return special_handler( GLUT_KEY_UP, 0 ); } else if ( key == CTRL('n') ) { return special_handler( GLUT_KEY_DOWN, 0 ); } else if ( key == CTRL('u') ) { /* ERASE LINE */ insertion_pt = 0; text.erase(0,text.length()); sel_start = sel_end = 0; } else if ( key == CTRL('k') ) { /* KILL TO END OF LINE */ sel_start = sel_end = insertion_pt; text.erase(insertion_pt,GLUI_String::npos); } } else if ( modifiers == GLUT_ACTIVE_ALT ) /* ALT ONLY */ { if ( key == 'b' ) { // Backward word return special_handler ( GLUT_KEY_LEFT, GLUT_ACTIVE_CTRL ); } if ( key == 'f' ) { // Forward word return special_handler ( GLUT_KEY_RIGHT, GLUT_ACTIVE_CTRL ); } } else if ( (modifiers & GLUT_ACTIVE_CTRL) OR (modifiers & GLUT_ACTIVE_ALT) ) { /** ignore other keys with modifiers */ return true; } else { /* Regular key */ if ( key == 13 ) /* RETURNS are written as newlines*/ key = '\n'; /**** If there's a current selection, erase it ******/ if ( sel_start != sel_end ) { clear_substring( MIN(sel_start,sel_end), MAX(sel_start,sel_end )); insertion_pt = MIN(sel_start,sel_end); sel_start = sel_end = insertion_pt; } /******** We insert the character into the string ***/ text.insert(insertion_pt,1,key); /******** Move the insertion point and substring_end one over ******/ insertion_pt++; substring_end++; sel_start = sel_end = insertion_pt; } /******** Now redraw text ***********/ /* Hack to prevent text box from being cleared first **/ /** int substring_change = update_substring_bounds(); draw_text_only = (NOT substring_change AND NOT has_selection AND regular_key ); */ draw_text_only = false; /** Well, hack is not yet working **/ update_and_draw_text(); draw_text_only = false; if ( debug ) dump( stdout, "<- KEY HANDLER" ); return true; }