mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-03 23:04:08 +01:00
885e7f0192
Call it when turn changes, new game is begun, and hint feature has been used. Currently menuitem is duplicated. Goal is to remove the item being attached to the left button and to replace it when another is chosen.
419 lines
12 KiB
C
Executable file
419 lines
12 KiB
C
Executable file
/* -*- fill-column: 77; c-basic-offset: 4; compile-command: "make TARGET_OS=wince DEBUG=TRUE" -*- */
|
|
/*
|
|
* Copyright 2002-2004 by Eric House (xwords@eehouse.org). All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include <commctrl.h>
|
|
|
|
#include "ceutil.h"
|
|
#include "cedefines.h"
|
|
|
|
#define BUF_SIZE 128
|
|
#define VPADDING 4
|
|
#define HPADDING_L 2
|
|
#define HPADDING_R 3
|
|
|
|
void
|
|
ceSetDlgItemText( HWND hDlg, XP_U16 id, const XP_UCHAR* buf )
|
|
{
|
|
wchar_t widebuf[BUF_SIZE];
|
|
XP_U16 len;
|
|
|
|
XP_ASSERT( buf != NULL );
|
|
|
|
len = (XP_U16)XP_STRLEN( buf );
|
|
|
|
if ( len >= BUF_SIZE ) {
|
|
len = BUF_SIZE - 1;
|
|
}
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, buf, len, widebuf, len );
|
|
widebuf[len] = 0;
|
|
SendDlgItemMessage( hDlg, id, WM_SETTEXT, 0, (long)widebuf );
|
|
} /* ceSetDlgItemText */
|
|
|
|
void
|
|
ceSetDlgItemFileName( HWND hDlg, XP_U16 id, XP_UCHAR* str )
|
|
{
|
|
XP_UCHAR* stripstart;
|
|
XP_UCHAR buf[BUF_SIZE];
|
|
XP_U16 len = XP_STRLEN(str);
|
|
|
|
if ( len >= BUF_SIZE ) {
|
|
len = BUF_SIZE - 1;
|
|
}
|
|
|
|
XP_MEMCPY( buf, str, len );
|
|
buf[len] = '\0';
|
|
|
|
stripstart = strrchr( (const char*)buf, '.' );
|
|
if ( !!stripstart ) {
|
|
*stripstart = '\0';
|
|
}
|
|
|
|
ceSetDlgItemText( hDlg, id, buf );
|
|
} /* ceSetDlgItemFileName */
|
|
|
|
void
|
|
ceGetDlgItemText( HWND hDlg, XP_U16 id, XP_UCHAR* buf, XP_U16* bLen )
|
|
{
|
|
XP_U16 len = *bLen;
|
|
XP_U16 gotLen;
|
|
wchar_t wbuf[BUF_SIZE];
|
|
|
|
XP_ASSERT( len <= BUF_SIZE );
|
|
|
|
gotLen = (XP_U16)SendDlgItemMessage( hDlg, id, WM_GETTEXT, len,
|
|
(long)wbuf );
|
|
if ( gotLen > 0 ) {
|
|
XP_ASSERT( gotLen < len );
|
|
if ( gotLen >= len ) {
|
|
gotLen = len - 1;
|
|
}
|
|
gotLen = WideCharToMultiByte( CP_ACP, 0, wbuf, gotLen,
|
|
buf, len, NULL, NULL );
|
|
*bLen = gotLen;
|
|
buf[gotLen] = '\0';
|
|
} else {
|
|
buf[0] = '\0';
|
|
*bLen = 0;
|
|
}
|
|
} /* ceGetDlgItemText */
|
|
|
|
void
|
|
ceSetDlgItemNum( HWND hDlg, XP_U16 id, XP_S32 num )
|
|
{
|
|
XP_UCHAR buf[20];
|
|
XP_SNPRINTF( buf, sizeof(buf), "%ld", num );
|
|
ceSetDlgItemText( hDlg, id, buf );
|
|
} /* ceSetDlgItemNum */
|
|
|
|
XP_S32
|
|
ceGetDlgItemNum( HWND hDlg, XP_U16 id )
|
|
{
|
|
XP_S32 result = 0;
|
|
XP_UCHAR buf[24];
|
|
XP_U16 len = sizeof(buf);
|
|
ceGetDlgItemText( hDlg, id, buf, &len );
|
|
|
|
result = atoi( buf );
|
|
return result;
|
|
} /* ceGetDlgItemNum */
|
|
|
|
void
|
|
ce_selectAndShow( HWND hDlg, XP_U16 resID, XP_U16 index )
|
|
{
|
|
SendDlgItemMessage( hDlg, resID, LB_SETCURSEL, index, 0 );
|
|
SendDlgItemMessage( hDlg, resID, LB_SETANCHORINDEX, index, 0 );
|
|
} /* ce_selectAndShow */
|
|
|
|
void
|
|
ceShowOrHide( HWND hDlg, XP_U16 resID, XP_Bool visible )
|
|
{
|
|
HWND itemH = GetDlgItem( hDlg, resID );
|
|
if ( !!itemH ) {
|
|
ShowWindow( itemH, visible? SW_SHOW: SW_HIDE );
|
|
}
|
|
} /* ceShowOrHide */
|
|
|
|
void
|
|
ceEnOrDisable( HWND hDlg, XP_U16 resID, XP_Bool enable )
|
|
{
|
|
HWND itemH = GetDlgItem( hDlg, resID );
|
|
if ( !!itemH ) {
|
|
EnableWindow( itemH, enable );
|
|
}
|
|
} /* ceShowOrHide */
|
|
|
|
void
|
|
ceSetChecked( HWND hDlg, XP_U16 resID, XP_Bool check )
|
|
{
|
|
SendDlgItemMessage( hDlg, resID, BM_SETCHECK,
|
|
check? BST_CHECKED:BST_UNCHECKED, 0L );
|
|
} /* ceSetBoolCheck */
|
|
|
|
XP_Bool
|
|
ceGetChecked( HWND hDlg, XP_U16 resID )
|
|
{
|
|
XP_U16 checked;
|
|
checked = (XP_U16)SendDlgItemMessage( hDlg, resID, BM_GETCHECK, 0, 0L );
|
|
return checked == BST_CHECKED;
|
|
} /* ceGetChecked */
|
|
|
|
/* Return dlg-relative rect.
|
|
*/
|
|
static void
|
|
GetItemRect( HWND hDlg, XP_U16 resID, RECT* rect )
|
|
{
|
|
RECT dlgRect;
|
|
HWND itemH = GetDlgItem( hDlg, resID );
|
|
XP_U16 clientHt, winHt;
|
|
|
|
GetClientRect( hDlg, &dlgRect );
|
|
clientHt = dlgRect.bottom;
|
|
GetWindowRect( hDlg, &dlgRect );
|
|
winHt = dlgRect.bottom - dlgRect.top;
|
|
GetWindowRect( itemH, rect );
|
|
|
|
/* GetWindowRect includes the title bar, but functions like MoveWindow
|
|
set relative to the client area below it. So subtract out the
|
|
difference between window ht and client rect ht -- the title bar --
|
|
when returning the item's rect. */
|
|
(void)OffsetRect( rect, -dlgRect.left,
|
|
-(dlgRect.top + winHt - clientHt) );
|
|
} /* GetItemRect */
|
|
|
|
void
|
|
ceCenterCtl( HWND hDlg, XP_U16 resID )
|
|
{
|
|
RECT buttonR, dlgR;
|
|
HWND itemH = GetDlgItem( hDlg, resID );
|
|
XP_U16 newX, buttonWidth;
|
|
|
|
GetClientRect( hDlg, &dlgR );
|
|
XP_ASSERT( dlgR.left == 0 && dlgR.top == 0 );
|
|
|
|
GetItemRect( hDlg, resID, &buttonR );
|
|
|
|
buttonWidth = buttonR.right - buttonR.left;
|
|
newX = ( dlgR.right - buttonWidth ) / 2;
|
|
|
|
if ( !MoveWindow( itemH, newX, buttonR.top,
|
|
buttonWidth,
|
|
buttonR.bottom - buttonR.top, TRUE ) ) {
|
|
XP_LOGF( "MoveWindow=>%d", GetLastError() );
|
|
}
|
|
} /* ceCenterCtl */
|
|
|
|
XP_Bool
|
|
ceIsLandscape( CEAppGlobals* globals )
|
|
{
|
|
XP_U16 width, height;
|
|
XP_Bool landscape;
|
|
|
|
XP_ASSERT( !!globals );
|
|
XP_ASSERT( !!globals->hWnd );
|
|
|
|
if ( 0 ) {
|
|
#if defined DEBUG && !defined _WIN32_WCE
|
|
} else if ( globals->dbWidth != 0 ) {
|
|
width = globals->dbWidth;
|
|
height = globals->dbHeight;
|
|
#endif
|
|
} else {
|
|
RECT rect;
|
|
GetClientRect( globals->hWnd, &rect );
|
|
width = (XP_U16)(rect.right - rect.left);
|
|
height = (XP_U16)(rect.bottom - rect.top);
|
|
}
|
|
|
|
landscape = (height - CE_SCORE_HEIGHT)
|
|
< (width - CE_MIN_SCORE_WIDTH);
|
|
return landscape;
|
|
} /* ceIsLandscape */
|
|
|
|
/* Can't figure out how to do this on CE. IsWindowVisible doesn't work, and
|
|
GetWindowInfo isn't even there. */
|
|
static XP_Bool
|
|
ceIsVisible( HWND XP_UNUSED_CE(hwnd) )
|
|
{
|
|
#ifdef _WIN32_WCE /* GetWindowInfo isn't on CE */
|
|
return XP_TRUE;
|
|
#else
|
|
XP_Bool visible = XP_FALSE;
|
|
WINDOWINFO wi;
|
|
wi.cbSize = sizeof(wi);
|
|
|
|
if ( !!hwnd && GetWindowInfo( hwnd, &wi ) ) {
|
|
visible = (wi.dwStyle & WS_VISIBLE) != 0;
|
|
}
|
|
|
|
return visible;
|
|
#endif
|
|
} /* ceIsVisible */
|
|
|
|
#ifdef _WIN32_WCE
|
|
static XP_Bool
|
|
mkFullscreenWithSoftkeys( CEAppGlobals* globals, HWND hDlg )
|
|
{
|
|
/* XP_Bool fullScreen = XP_FALSE; /\* probably want this TRUE for */
|
|
/* small-screened smartphones only. *\/ */
|
|
/* if ( fullScreen ) { */
|
|
/* SHINITDLGINFO info; */
|
|
|
|
/* info.dwMask = SHIDIM_FLAGS; */
|
|
/* info.dwFlags = SHIDIF_SIZEDLG */
|
|
/* /\* | SHIDIF_DONEBUTTON *\/ */
|
|
/* | SHIDIF_WANTSCROLLBAR; */
|
|
/* info.hDlg = hDlg; */
|
|
|
|
/* BOOL b = SHInitDialog( &info ); */
|
|
/* XP_LOGF( "SHInitDialog=>%d", (int)b ); */
|
|
/* } */
|
|
|
|
XP_Bool success = XP_FALSE;
|
|
SHMENUBARINFO mbi;
|
|
|
|
XP_MEMSET( &mbi, 0, sizeof(mbi) );
|
|
mbi.cbSize = sizeof(mbi);
|
|
mbi.hwndParent = hDlg;
|
|
mbi.nToolBarId = IDM_OKCANCEL_MENUBAR;
|
|
mbi.hInstRes = globals->hInst;
|
|
success = SHCreateMenuBar( &mbi );
|
|
if ( !success ) {
|
|
XP_LOGF( "SHCreateMenuBar failed" );
|
|
}
|
|
return success;
|
|
} /* mkFullscreenWithSoftkeys */
|
|
#endif
|
|
|
|
void
|
|
ceStackButtonsRight( CEAppGlobals* globals, HWND hDlg )
|
|
{
|
|
XP_Bool justRemove = XP_FALSE;
|
|
XP_ASSERT( !!globals );
|
|
|
|
#ifdef _WIN32_WCE
|
|
if ( mkFullscreenWithSoftkeys( globals, hDlg ) ) {
|
|
justRemove = XP_TRUE;
|
|
}
|
|
#endif
|
|
|
|
if ( justRemove || ceIsLandscape( globals ) ) {
|
|
XP_U16 resIDs[] = { IDOK, IDCANCEL };
|
|
RECT wrect, crect;
|
|
XP_U16 left, top;
|
|
XP_U16 butWidth, butHeight;
|
|
XP_U16 barHt, i, nButtons, spacing;
|
|
XP_U16 newWidth, mainWidth;
|
|
|
|
/* First, figure height and width to use */
|
|
butHeight = 0;
|
|
butWidth = 0;
|
|
nButtons = 0;
|
|
for ( i = 0; i < VSIZE(resIDs); ++i ) {
|
|
HWND itemH = GetDlgItem( hDlg, resIDs[i] );
|
|
if ( ceIsVisible( itemH ) ) {
|
|
RECT buttonRect;
|
|
GetClientRect( itemH, &buttonRect );
|
|
|
|
if ( butWidth < buttonRect.right ) {
|
|
butWidth = buttonRect.right;
|
|
}
|
|
if ( butHeight < buttonRect.bottom ) {
|
|
butHeight = buttonRect.bottom;
|
|
}
|
|
++nButtons;
|
|
}
|
|
}
|
|
|
|
GetWindowRect( globals->hWnd, &wrect );
|
|
mainWidth = wrect.right - wrect.left;
|
|
|
|
/* Make sure we're not proposing to make the dialog wider than the
|
|
screen */
|
|
GetWindowRect( hDlg, &wrect );
|
|
newWidth = wrect.right - wrect.left +
|
|
butWidth + HPADDING_L + HPADDING_R;
|
|
|
|
if ( justRemove || (newWidth <= mainWidth) ) {
|
|
|
|
GetClientRect( hDlg, &crect );
|
|
barHt = wrect.bottom - wrect.top - crect.bottom;
|
|
|
|
spacing = crect.bottom - (nButtons * (butHeight + (VPADDING*2)));
|
|
spacing /= nButtons + 1;
|
|
|
|
top = spacing - (butHeight / 2) + VPADDING;
|
|
left = crect.right + HPADDING_L;
|
|
|
|
for ( i = 0; i < VSIZE(resIDs); ++i ) {
|
|
HWND itemH = GetDlgItem( hDlg, resIDs[i] );
|
|
if ( ceIsVisible( itemH ) ) {
|
|
(void)MoveWindow( itemH, left, top, butWidth, butHeight,
|
|
TRUE );
|
|
top += butHeight + spacing + (VPADDING * 2);
|
|
}
|
|
}
|
|
|
|
if ( justRemove ) {
|
|
MoveWindow( hDlg, wrect.left, wrect.top,
|
|
wrect.right - wrect.left, wrect.bottom - wrect.top - butHeight - 2,
|
|
FALSE );
|
|
} else {
|
|
butWidth += HPADDING_L + HPADDING_R;
|
|
MoveWindow( hDlg, wrect.left - (butWidth/2), wrect.top,
|
|
newWidth, wrect.bottom - wrect.top - butHeight - 2,
|
|
FALSE );
|
|
}
|
|
}
|
|
}
|
|
} /* ceStackButtonsRight */
|
|
|
|
#ifdef _WIN32_WCE
|
|
void
|
|
ceSetLeftSoftkey( CEAppGlobals* globals, XP_U16 id )
|
|
{
|
|
HMENU menu;
|
|
XP_U16 curItem = globals->softkey.curItem;
|
|
/* temporary!! */
|
|
if ( curItem == 0 ) {
|
|
curItem = ID_MOVE_TURNDONE;
|
|
}
|
|
|
|
TBBUTTONINFO info;
|
|
XP_MEMSET( &info, 0, sizeof(info) );
|
|
info.cbSize = sizeof(info);
|
|
|
|
/* Also temporary!! */
|
|
const wchar_t* txt = L"Mine";
|
|
switch( id ) {
|
|
case ID_MOVE_TURNDONE:
|
|
txt = L"Turn done";
|
|
break;
|
|
case ID_FILE_NEWGAME:
|
|
txt = L"New game";
|
|
break;
|
|
case ID_MOVE_NEXTHINT:
|
|
txt = L"Next hint";
|
|
break;
|
|
default:
|
|
XP_ASSERT(0);
|
|
}
|
|
|
|
info.dwMask = TBIF_LPARAM;
|
|
SendMessage( globals->hwndCB, TB_GETBUTTONINFO, IDM_MENU, (LPARAM)&info );
|
|
menu = (HMENU)info.lParam; /* Use to remove item being installed in
|
|
left button */
|
|
|
|
|
|
/* First put any existing menu item back in the main menu! */
|
|
|
|
/* Then find, remember and remove the new */
|
|
|
|
/* Make it the button */
|
|
|
|
info.dwMask = TBIF_TEXT | TBIF_COMMAND;
|
|
info.idCommand = id;
|
|
info.pszText = txt;
|
|
SendMessage( globals->hwndCB, TB_SETBUTTONINFO, curItem, (LPARAM)&info );
|
|
|
|
/* Save for next time */
|
|
globals->softkey.curItem = id;
|
|
} /* ceSetLeftSoftkey */
|
|
#endif
|