diff --git a/xwords4/linux/cursesask.c b/xwords4/linux/cursesask.c index bc5c62285..463c622dc 100644 --- a/xwords4/linux/cursesask.c +++ b/xwords4/linux/cursesask.c @@ -45,14 +45,14 @@ cursesask( CursesAppGlobals* globals, char* question, short numButtons, FormatInfo fi; int len; - measureAskText( question, &fi ); + getmaxyx(globals->boardWin, y, x); + + measureAskText( question, x-2, &fi ); len = fi.maxLen; if ( len < MIN_WIDTH ) { len = MIN_WIDTH; } - getmaxyx(globals->boardWin, y, x); - rows = fi.nLines; maxWidth = x - (PAD*2) - 2; /* 2 for two borders */ @@ -64,7 +64,7 @@ cursesask( CursesAppGlobals* globals, char* question, short numButtons, nLines = ASK_HEIGHT + rows - 1; confWin = newwin( nLines, len+(PAD*2), (y/2) - (nLines/2), (x-len-2)/2 ); - + keypad( confWin, TRUE ); wclear( confWin ); box( confWin, '|', '-'); @@ -82,19 +82,24 @@ cursesask( CursesAppGlobals* globals, char* question, short numButtons, curSelButton=newSelButton, &button1 ); } - ch = fgetc( stdin ); + ch = wgetch( confWin ); switch ( ch ) { - case '\t': case 'L': + case KEY_RIGHT: + case 525: newSelButton = (curSelButton+1) % numButtons; break; case 'H': + case '\t': + case KEY_LEFT: + case 524: newSelButton = (numButtons+curSelButton-1) % numButtons; break; case EOF: case 4: /* C-d */ case 27: /* ESC */ curSelButton = 0; /* should be the cancel case */ + case KEY_B2: /* "center of keypad" */ case '\r': case '\n': dismissed = XP_TRUE; diff --git a/xwords4/linux/cursesdlgutil.c b/xwords4/linux/cursesdlgutil.c index b6cfe474f..04238b663 100644 --- a/xwords4/linux/cursesdlgutil.c +++ b/xwords4/linux/cursesdlgutil.c @@ -22,39 +22,54 @@ #include "cursesdlgutil.h" void -measureAskText( XP_UCHAR* question, FormatInfo* fip ) +measureAskText( const XP_UCHAR* question, int width, FormatInfo* fip ) { - XP_U16 i; - XP_U16 maxWidth = 0; + int i; + XP_U16 maxLen = 0; XP_Bool done = XP_FALSE; + int len = strlen(question); + const char* end = question + len; + const char* cur = question; for ( i = 0; i < MAX_LINES && !done; ++i ) { - XP_UCHAR* next = strstr( question, XP_CR ); - XP_U16 thisWidth; + len = strlen(cur); - fip->line[i].substr = question; - - if ( !!next ) { - thisWidth = next - question; - } else { - thisWidth = strlen(question); - done = XP_TRUE; + if ( len == 0 ) { + assert( i > 0 ); + fip->nLines = i; + fip->maxLen = maxLen; + break; } - fip->line[i].len = thisWidth; - if ( thisWidth > maxWidth ) { - maxWidth = thisWidth; + fip->line[i].substr = cur; + + /* Now we need to break the line if 1) there's a ; or 2) it's too + long. */ + const char* cr = strstr( cur, "\n" ); + if ( NULL != cr && (cr - cur) < width ) { + len = cr - cur; + } else if ( len > width ) { + char* s = cur + width; + while ( *s != ' ' && s > cur ) { + --s; + } + assert( s > cur ); /* deal with this!! */ + len = s - cur; + } + fip->line[i].len = len; + if ( maxLen < len ) { + maxLen = len; + } + + cur += len + 1; /* skip the /space */ + if ( cur > end ) { + cur = end; } - - question = next + strlen(XP_CR); } - - fip->nLines = i; - fip->maxLen = maxWidth; } /* measureAskText */ void -drawButtons( WINDOW* confWin, XP_U16 line, short spacePerButton, +drawButtons( WINDOW* win, XP_U16 line, short spacePerButton, short numButtons, short curSelButton, char** button1 ) { short i; @@ -62,16 +77,16 @@ drawButtons( WINDOW* confWin, XP_U16 line, short spacePerButton, short len = strlen( *button1 ); if ( i == curSelButton ) { - wstandout( confWin ); + wstandout( win ); } - mvwprintw( confWin, line, ((i+1) * spacePerButton) - (len/2), + mvwprintw( win, line, ((i+1) * spacePerButton) - (len/2), "[%s]", *button1 ); if ( i == curSelButton ) { - wstandend( confWin ); + wstandend( win ); } ++button1; } - wrefresh( confWin ); + wrefresh( win ); } /* drawButtons */ #endif diff --git a/xwords4/linux/cursesdlgutil.h b/xwords4/linux/cursesdlgutil.h index cefade7d7..4cdc1f72b 100644 --- a/xwords4/linux/cursesdlgutil.h +++ b/xwords4/linux/cursesdlgutil.h @@ -41,7 +41,7 @@ typedef struct FormatInfo { } FormatInfo; -void measureAskText( XP_UCHAR* question, FormatInfo* fip ); +void measureAskText( const XP_UCHAR* question, int maxWidth, FormatInfo* fip ); void drawButtons( WINDOW* confWin, XP_U16 line, short spacePerButton, short numButtons, short curSelButton, char** button1 ); diff --git a/xwords4/linux/cursesletterask.c b/xwords4/linux/cursesletterask.c index 6e0f065c9..d014197f6 100644 --- a/xwords4/linux/cursesletterask.c +++ b/xwords4/linux/cursesletterask.c @@ -1,4 +1,5 @@ -/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */ +/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE"; -*- */ + /* * Copyright 2003 by Eric House (xwords@eehouse.org). All rights reserved. * @@ -26,9 +27,8 @@ #define MAX_TILE_BUTTON_WIDTH (sizeof(XP_UCHAR4) + 2) static void -sizeTextsAsButtons( const XP_UCHAR4* XP_UNUSED(texts), XP_U16 maxLen, - XP_U16 nTiles, XP_U16* textsCols, XP_U16* textsRows, - XP_U16* textsOffsets ) +sizeTextsAsButtons( XP_U16 maxLen, XP_U16 nTiles, XP_U16* textsCols, + XP_U16* textsRows, XP_U16* textsOffsets ) { XP_U16 nCols = maxLen / MAX_TILE_BUTTON_WIDTH; XP_U16 nRows = (nTiles + nCols - 1) / nCols; @@ -69,16 +69,14 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query, textPtrs[i] = (char*)&texts[i]; } - getmaxyx(globals->boardWin, y, x); - XP_DEBUGF( "getmaxyx=>x=%d,y=%d", x, y ); + getmaxyx( globals->boardWin, y, x ); numCtlButtons = VSIZE(ctlButtons); - measureAskText( query, &fi ); - - sizeTextsAsButtons( texts, x, nTiles, - &textsCols, &textsRows, textsOffsets ); + maxWidth = x - (PAD*2) - 2; /* 2 for two borders */ + measureAskText( query, maxWidth, &fi ); + sizeTextsAsButtons( x, nTiles, &textsCols, &textsRows, textsOffsets ); len = XP_MAX( fi.maxLen, textsCols * MAX_TILE_BUTTON_WIDTH ); if ( len < MIN_WIDTH ) { @@ -86,7 +84,6 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query, } rows = fi.nLines + textsRows + 1; - maxWidth = x - (PAD*2) - 2; /* 2 for two borders */ XP_DEBUGF( "set maxWidth=%d", maxWidth ); @@ -103,6 +100,7 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query, XP_ASSERT( y >= nLines ); confWin = newwin( nLines, len,//+(PAD*2), (y/2) - (nLines/2), (x-len-2)/2 ); + keypad( confWin, TRUE ); XP_ASSERT( !!confWin ); wclear( confWin ); @@ -150,18 +148,35 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query, curSelButton = newSelButton; } - ch = fgetc( stdin ); + ch = wgetch( confWin ); + int incr = 0; switch ( ch ) { case '\t': - newSelButton = (curSelButton+1) % (numCtlButtons + nTiles); - if ( newSelButton < nTiles ) { - result = newSelButton; - } + case 'R': + case KEY_RIGHT: + case 525: + incr = 1; break; + case 'L': + case KEY_LEFT: + case 524: + incr = -1; + break; + + case KEY_DOWN: + case 526: + incr = textsCols; + break; + case KEY_UP: + case 523: + incr = -textsCols; + break; + case EOF: case 4: /* C-d */ case 27: /* ESC */ curSelButton = 0; /* should be the cancel case */ + case KEY_B2: /* "center of keypad" */ case '\r': case '\n': dismissed = XP_TRUE; @@ -178,11 +193,17 @@ curses_askLetter( CursesAppGlobals* globals, XP_UCHAR* query, break; } } + } + if ( incr != 0 ) { + newSelButton = curSelButton + incr; + if ( newSelButton < 0 ) { + newSelButton = 0; + } else if ( newSelButton >= numCtlButtons + nTiles ) { + newSelButton = numCtlButtons + nTiles - 1; + } } - XP_DEBUGF( "newSelButton=%d", newSelButton ); - } delwin( confWin ); diff --git a/xwords4/linux/cursesmain.c b/xwords4/linux/cursesmain.c index 76c2ef914..bee613618 100644 --- a/xwords4/linux/cursesmain.c +++ b/xwords4/linux/cursesmain.c @@ -106,14 +106,16 @@ static XP_Bool handleToggleValues( CursesAppGlobals* globals ); static XP_Bool handleBackspace( CursesAppGlobals* globals ); static XP_Bool handleUndo( CursesAppGlobals* globals ); static XP_Bool handleReplace( CursesAppGlobals* globals ); -static XP_Bool handleRootKeyShow( CursesAppGlobals* globals ); -static XP_Bool handleRootKeyHide( CursesAppGlobals* globals ); static XP_Bool handleJuggle( CursesAppGlobals* globals ); static XP_Bool handleHide( CursesAppGlobals* globals ); static XP_Bool handleAltLeft( CursesAppGlobals* globals ); static XP_Bool handleAltRight( CursesAppGlobals* globals ); static XP_Bool handleAltUp( CursesAppGlobals* globals ); static XP_Bool handleAltDown( CursesAppGlobals* globals ); +#ifdef CURSES_SMALL_SCREEN +static XP_Bool handleRootKeyShow( CursesAppGlobals* globals ); +static XP_Bool handleRootKeyHide( CursesAppGlobals* globals ); +#endif MenuList g_sharedMenuList[] = { @@ -226,8 +228,9 @@ curses_util_userPickTile( XW_UtilCtxt* uc, const PickInfo* XP_UNUSED(pi), XP_S16 index; char* playerName = globals->cGlobals.params->gi.players[playerNum].name; - sprintf( query, "Pick tile for %s! (Tab or type letter to select\n" - "then hit .)", playerName ); + snprintf( query, sizeof(query), + "Pick tile for %s! (Tab or type letter to select " + "then hit .)", playerName ); index = curses_askLetter( globals, query, texts, nTiles ); return index;