From 9bf9105bf4c9f7063c261d15b5f8326bf7c20439 Mon Sep 17 00:00:00 2001 From: "H.G. Muller" Date: Wed, 6 Apr 2011 21:20:30 +0200 Subject: [PATCH] Implement sweep selection as alternative for the piece menu When the option -pieceMenu is off, the piece menu will no longer appear on right-clicks in Edit Position mode. In stead a Pawn of the chosen color will appear immediately in the clicked square, and vertical movement of the mouse with the right button down will cycle through all other pieces defined in the pieceToCharTable of the current variant. Setting the side to move is acheived by clicking the correspondig clock. Clear board can be effected by clicking the clock of the side that already has the move. --- args.h | 1 + backend.c | 58 +++++++++++++++++++++++++++++++++++++++++-------------- common.h | 1 + xboard.c | 1 + 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/args.h b/args.h index 0822aa70..b91d02d2 100644 --- a/args.h +++ b/args.h @@ -211,6 +211,7 @@ ArgDescriptor argDescriptors[] = { { "pasteSelection", ArgBoolean, (void *) &appData.pasteSelection, XBOARD, (ArgIniType) FALSE }, { "dropMenu", ArgBoolean, (void *) &appData.dropMenu, TRUE, (ArgIniType) FALSE }, + { "pieceMenu", ArgBoolean, (void *) &appData.pieceMenu, TRUE, (ArgIniType) TRUE }, { "remoteShell", ArgFilename, (void *) &appData.remoteShell, FALSE, (ArgIniType) REMOTE_SHELL }, { "rsh", ArgFilename, (void *) &appData.remoteShell, FALSE, INVALID }, { "remoteUser", ArgString, (void *) &appData.remoteUser, FALSE, INVALID }, diff --git a/backend.c b/backend.c index 4044175c..ea0d9774 100644 --- a/backend.c +++ b/backend.c @@ -267,6 +267,7 @@ char chatPartner[MAX_CHAT][MSG_SIZ]; /* [HGM] chat: list of chatting partners */ extern int chatCount; int chattingPartner; char marker[BOARD_RANKS][BOARD_FILES]; /* [HGM] marks for target squares */ +ChessSquare pieceSweep = EmptySquare; /* States for ics_getting_history */ #define H_FALSE 0 @@ -4811,6 +4812,20 @@ ProcessICSInitScript(f) } +void +NextPiece(int step) +{ + ChessSquare piece = boards[currentMove][toY][toX]; + do { + pieceSweep += step; + if(pieceSweep == EmptySquare) pieceSweep = WhitePawn; // wrap + if((int)pieceSweep == -1) pieceSweep = BlackKing; + if(!step) step = 1; + } while(PieceToChar(pieceSweep) == '.'); + boards[currentMove][toY][toX] = pieceSweep; + DrawPosition(FALSE, boards[currentMove]); + boards[currentMove][toY][toX] = piece; +} /* [HGM] Shogi move preprocessor: swap digits for letters, vice versa */ void AlphaRank(char *move, int n) @@ -5063,15 +5078,18 @@ UnLoadPV() void MovePV(int x, int y, int h) { // step through PV based on mouse coordinates (called on mouse move) - int margin = h>>3, step = 0; + int margin = h>>3, step = 0, dist; - if(endPV < 0) return; // we must somehow check if right button is still down (might be released off board!) - if(y < margin && (abs(x - lastX) > 6 || abs(y - lastY) > 6)) step = 1; else - if(y > h - margin && (abs(x - lastX) > 6 || abs(y - lastY) > 6)) step = -1; else - if( y > lastY + 6 ) step = -1; else if(y < lastY - 6) step = 1; + if(abs(x - lastX) < 7 && abs(y - lastY) < 7) return; + if( y > lastY + 2 ) step = -1; else if(y < lastY - 2) step = 1; if(!step) return; lastX = x; lastY = y; + + if(pieceSweep != EmptySquare) { NextPiece(step); return; } + if(endPV < 0) return; + if(y < margin) step = 1; else + if(y > h - margin) step = -1; if(currentMove + step > endPV || currentMove + step < forwardMostMove) step = 0; currentMove += step; if(currentMove == forwardMostMove) ClearPremoveHighlights(); else @@ -5731,12 +5749,11 @@ HasPromotionChoice(int fromX, int fromY, int toX, int toY, char *promoChoice) *promoChoice = PieceToChar(BlackQueen); // Queen as good as any return FALSE; } - if(autoQueen) { // predetermined - if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantLosers) - *promoChoice = PieceToChar(BlackKing); // in Suicide Q is the last thing we want - else *promoChoice = PieceToChar(BlackQueen); - return FALSE; - } + // give caller the default choice even if we will not make it + if(gameInfo.variant == VariantSuicide || gameInfo.variant == VariantGiveaway) + *promoChoice = PieceToChar(BlackKing); // in Suicide Q is the last thing we want + else *promoChoice = PieceToChar(BlackQueen); + if(autoQueen) return FALSE; // predetermined // suppress promotion popup on illegal moves that are not premoves premove = gameMode == IcsPlayingWhite && !WhiteOnMove(currentMove) || @@ -6613,16 +6630,25 @@ int RightClick(ClickType action, int x, int y, int *fromX, int *fromY) xSqr = EventToSquare(x, BOARD_WIDTH); ySqr = EventToSquare(y, BOARD_HEIGHT); - if (action == Release) UnLoadPV(); // [HGM] pv + if (action == Release) { + if(pieceSweep != EmptySquare) { + EditPositionMenuEvent(pieceSweep, toX, toY); + pieceSweep = EmptySquare; + } else UnLoadPV(); // [HGM] pv + } if (action != Press) return -2; // return code to be ignored switch (gameMode) { case IcsExamining: if(xSqr < BOARD_LEFT || xSqr >= BOARD_RGHT) return -1; case EditPosition: if (xSqr == BOARD_LEFT-1 || xSqr == BOARD_RGHT) return -1; - if (xSqr < 0 || ySqr < 0) return -1; - whichMenu = 0; // edit-position menu - break; + if (xSqr < 0 || ySqr < 0) return -1; + if(appData.pieceMenu) { whichMenu = 0; break; } // edit-position menu + pieceSweep = shiftKey ? BlackPawn : WhitePawn; // [HGM] sweep: prepare selecting piece by mouse sweep + toX = xSqr; toY = ySqr; lastX = x, lastY = y; + if(flipView) toX = BOARD_WIDTH - 1 - toX; else toY = BOARD_HEIGHT - 1 - toY; + NextPiece(0); + return -2; case IcsObserving: if(!appData.icsEngineAnalyze) return -1; case IcsPlayingWhite: @@ -12614,6 +12640,7 @@ ClockClick(int which) { // [HGM] code moved to back-end from winboard.c if(which) { // black clock if (gameMode == EditPosition || gameMode == IcsExamining) { + if(!appData.pieceMenu && blackPlaysFirst) EditPositionMenuEvent(ClearBoard, 0, 0); SetBlackToPlayEvent(); } else if (gameMode == EditGame || shiftKey) { AdjustClock(which, -1); @@ -12623,6 +12650,7 @@ ClockClick(int which) } } else { // white clock if (gameMode == EditPosition || gameMode == IcsExamining) { + if(!appData.pieceMenu && !blackPlaysFirst) EditPositionMenuEvent(ClearBoard, 0, 0); SetWhiteToPlayEvent(); } else if (gameMode == EditGame || shiftKey) { AdjustClock(which, -1); diff --git a/common.h b/common.h index 23f8811b..a82fc13a 100644 --- a/common.h +++ b/common.h @@ -656,6 +656,7 @@ typedef struct { int nrVariations; /* [HGM] multivar */ Boolean dropMenu; /* [HGM] pv */ Boolean markers; /* [HGM] markers */ + Boolean pieceMenu; } AppData, *AppDataPtr; /* PGN tags (for showing in the game list) */ diff --git a/xboard.c b/xboard.c index 5f4cb0c9..079d42b1 100644 --- a/xboard.c +++ b/xboard.c @@ -3951,6 +3951,7 @@ void PieceMenuPopup(w, event, params, num_params) Cardinal *num_params; { String whichMenu; int menuNr; + shiftKey = strcmp(params[0], "menuW"); // used to indicate black if (event->type == ButtonRelease) menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY); else if (event->type == ButtonPress) -- 2.17.1