@@ -36,8 +36,8 @@ void helpCommands(RenderPassState* state) {
3636 // TODO use lines filled state or remove it entirely
3737 // move(state->linesFilled, 0);
3838 printw (" Commands:\n " );
39- printw (" Q - quit the program \n " );
40- printw (" CTRL + Q - quit the program but retain a visible crosshair\n " );
39+ printw (" Q - quit RivaCross \n " );
40+ printw (" CTRL + Q - quit RivaCross but retain a visible crosshair\n " );
4141 printw (" CTRL + O - load an existing config\n " );
4242 printw (" T - set the crosshair character/text\n " );
4343 printw (" NUM- and NUM+ - change the crosshair size\n " );
@@ -403,35 +403,121 @@ bool processTintUserAction(CrossActionArgs* args, RTSSCrossConfig* config, Rende
403403 // we expect some lines to wrap so we get the actual number of lines written from curses
404404 int cursorX, cursorY;
405405 getsyx (cursorY, cursorX);
406- state->linesFilled + = cursorY - state-> linesFilled ;
406+ state->linesFilled = cursorY;
407407 args->action = CrossActionType::None;
408408 // indicate if an update of RTSS memory is required
409409 return changed;
410410}
411411bool processMoveUserAction (CrossActionArgs* args, RTSSCrossConfig* config, RenderPassState* state) {
412- bool changed = false ;
413- // get user input
414412 printw (" Current position is %i, %i\n " , config->position [0 ], config->position [1 ]);
413+ printw (" Use the direction keys and exit with ENTER or\n " );
415414 printw (" Enter new position (x, y): " );
416415 refresh ();
417- char inputBuffer[256 ];
418- echo ();
419- getnstr (inputBuffer, sizeof (inputBuffer)-1 );
420- state->linesFilled += 2 ;
421- // process user input
422- int posX, posY;
423- if (sscanf (inputBuffer, " %i,%i" , &posX, &posY) < 2 ) {
424- printw (" Wrong format! Please specify your desired position as " );
425- printw (" two comma separated integers (e.g. 477, 245)\n " );
426- } else {
427- config->position [0 ] = posX;
428- config->position [1 ] = posY;
429- changed = true ;
430- printw (" New position is %i, %i\n " , config->position [0 ], config->position [1 ]);
416+
417+ // get user input
418+ // first allow crosshair movement with the direction keys
419+ // but enter number input mode as soon as a number key is pressed
420+ const int ctrlMod = 0x60 ;
421+ bool numberStarted = false ;
422+ bool moveOrdered = false ;
423+ bool moveAborted = false ;
424+ nodelay (stdscr, true );
425+ while (!numberStarted && !moveOrdered && !moveAborted) {
426+ int input = getch ();
427+ // scan for direction keys
428+ // these also activate if the console window is out of focus
429+ bool moved = false ;
430+ int modifier = 1 ;
431+ if (GetKeyState (VK_CONTROL) & 0x8000 ) {
432+ modifier = 10 ;
433+ }
434+ if (GetKeyState (VK_LEFT) & 0x8000 ) {
435+ args->deltaX = -modifier;
436+ moved = true ;
437+ }
438+ if (GetKeyState (VK_RIGHT) & 0x8000 ) {
439+ args->deltaX = modifier;
440+ moved = true ;
441+ }
442+ if (GetKeyState (VK_UP) & 0x8000 ) {
443+ args->deltaY = -modifier;
444+ moved = true ;
445+ }
446+ if (GetKeyState (VK_DOWN) & 0x8000 ) {
447+ args->deltaY = modifier;
448+ moved = true ;
449+ }
450+ if (GetKeyState (VK_RETURN) & 0x8000 ) {
451+ moveAborted = true ;
452+ }
453+ // process the details outside this function
454+ // but come back to it (action type is still MOVE)
455+ if (moved) {
456+ flushinp (); // throw away repeated direction keys from the input queue
457+ ungetch (' m' ); // put something in the queue so that this function is called again
458+ moveOrdered = true ;
459+ } else {
460+ switch (input) {
461+ case ' q' :
462+ case ' \n ' :
463+ case KEY_ENTER:
464+ case (ctrlMod^' c' ):
465+ // end position modification with CTRL+C, Q and ENTER
466+ moveAborted = true ;
467+ break ;
468+ case ' 0' : case ' 1' :
469+ case ' 2' : case ' 3' :
470+ case ' 4' : case ' 5' :
471+ case ' 6' : case ' 7' :
472+ case ' 8' : case ' 9' :
473+ // jump to manual specification below
474+ ungetch (input);
475+ numberStarted = true ;
476+ break ;
477+ default :
478+ // ignore everything else
479+ break ;
480+ }
481+ }
482+ Sleep (50 ); // wait some more so that the user easily do single steps
483+ }
484+ nodelay (stdscr, false );
485+ if (moveAborted) {
486+ args->action = CrossActionType::None;
487+ return false ;
488+ }
489+ if (moveOrdered) {
490+ return true ;
491+ }
492+ if (numberStarted) {
493+ // a number key was pressed
494+ // continue to read number input until the user hits enter
495+ bool changed = false ;
496+ char inputBuffer[256 ];
497+ echo ();
498+ getnstr (inputBuffer, sizeof (inputBuffer)-1 );
499+ state->linesFilled += 2 ;
500+ // process user input
501+ int posX, posY;
502+ if (sscanf (inputBuffer, " %i,%i" , &posX, &posY) < 2 ) {
503+ printw (" Wrong format! Please specify your desired position as " );
504+ printw (" two comma separated integers (e.g. 477, 245)\n " );
505+ } else if (posX < 0 || posY < 0 ) {
506+ printw (" Wrong format! Please use only positive valus\n " );
507+ } else {
508+ config->position [0 ] = posX;
509+ config->position [1 ] = posY;
510+ changed = true ;
511+ printw (" New position is %i, %i\n " , config->position [0 ], config->position [1 ]);
512+ }
513+ int cursorX, cursorY;
514+ getsyx (cursorY, cursorX);
515+ state->linesFilled = cursorY;
516+ args->action = CrossActionType::None;
517+ return changed;
431518 }
432- state->linesFilled += 1 ;
433519 args->action = CrossActionType::None;
434- return changed ;
520+ return false ;
435521}
436522bool processScaleUserAction (CrossActionArgs* args, RTSSCrossConfig* config, RenderPassState* state) {
437523 bool changed = false ;
0 commit comments