xwords/xwords4/wince/ceclrsel.c
ehouse a6ecdd0f9e merge revisions 2443 2446 2447 2450 2451 2452 2454 2456 2469 2498 2499
2509 2513 2514 2515 2516 2517 2518 2519 2521 2522 2523 2524 2525 2526
2527 2528 2529 2530 2531 2532 2534 2535 2536 2537 2538 2539 2540 2541
2542 2543 and 2544 from trunk with the goal of adding localization
support to this branch so that it can be released before all the
networking stuff on trunk is debugged.
2009-05-09 16:01:44 +00:00

473 lines
13 KiB
C

/* -*- fill-column: 77; c-basic-offset: 4; compile-command: "make TARGET_OS=wince DEBUG=TRUE" -*- */
/*
* Copyright 2004-2008 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 <windowsx.h>
#include "stdafx.h"
#include <commdlg.h>
#include "ceclrsel.h"
#include "ceutil.h"
#include "cedebug.h"
#include "debhacks.h"
#include "ceresstr.h"
static void colorButton( DRAWITEMSTRUCT* dis, HBRUSH brush );
#ifdef MY_COLOR_SEL
typedef struct ClrEditDlgState {
CeDlgHdr dlgHdr;
HWND parent;
HWND sampleButton;
XP_U16 labelID;
XP_U8 red;
XP_U8 green;
XP_U8 blue;
XP_Bool inited;
XP_Bool cancelled;
} ClrEditDlgState;
static void
initEditAndSlider( HWND hDlg, XP_U16 sliderID, XP_U8 val )
{
SendDlgItemMessage( hDlg, sliderID, TBM_SETRANGE, TRUE,
MAKELONG(0,255) );
SendDlgItemMessage( hDlg, sliderID, TBM_SETPOS, TRUE,
(long)val );
ceSetDlgItemNum( hDlg, sliderID+1, val );
} /* initEditAndSlider */
static void
initChooseColor( ClrEditDlgState* eState, HWND hDlg )
{
initEditAndSlider( hDlg, CLREDT_SLIDER1, eState->red );
initEditAndSlider( hDlg, CLREDT_SLIDER2, eState->green );
initEditAndSlider( hDlg, CLREDT_SLIDER3, eState->blue );
} /* initChooseColor */
static XP_U8*
colorForSlider( ClrEditDlgState* eState, XP_U16 sliderID )
{
switch( sliderID ) {
case CLREDT_SLIDER1:
return &eState->red;
case CLREDT_SLIDER2:
return &eState->green;
case CLREDT_SLIDER3:
return &eState->blue;
default:
XP_LOGF( "huh???" );
return NULL;
}
} /* colorForSlider */
static void
updateForSlider( HWND hDlg, ClrEditDlgState* eState, XP_U16 sliderID )
{
XP_U8 newColor = (XP_U8)SendDlgItemMessage( hDlg, sliderID, TBM_GETPOS,
0, 0L );
XP_U8* colorPtr = colorForSlider( eState, sliderID );
if ( newColor != *colorPtr ) {
*colorPtr = newColor;
ceSetDlgItemNum( hDlg, sliderID+1, (XP_S32)newColor );
InvalidateRect( eState->sampleButton, NULL, TRUE /* erase */ );
}
} /* updateForSlider */
static void
updateForField( HWND hDlg, ClrEditDlgState* eState, XP_U16 fieldID )
{
XP_S32 newColor = ceGetDlgItemNum( hDlg, fieldID );
XP_U8* colorPtr = colorForSlider( eState, fieldID - 1 );
XP_Bool modified = XP_FALSE;;
if ( newColor > 255 ) {
newColor = 255;
modified = XP_TRUE;
} else if ( newColor < 0 ) {
newColor = 0;
modified = XP_TRUE;
}
if ( modified ) {
ceSetDlgItemNum( hDlg, fieldID, newColor );
}
if ( newColor != *colorPtr ) {
*colorPtr = (XP_U8)newColor;
SendDlgItemMessage( hDlg, fieldID-1, TBM_SETPOS, TRUE,
(long)newColor );
InvalidateRect( eState->sampleButton, NULL, FALSE );
}
} /* updateForField */
static void
colorButtonFromState( ClrEditDlgState* eState, DRAWITEMSTRUCT* dis )
{
COLORREF ref = RGB( eState->red, eState->green, eState->blue );
HBRUSH brush = CreateSolidBrush( ref );
colorButton( dis, brush );
DeleteObject( brush );
}
LRESULT CALLBACK
EditColorsDlg( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
ClrEditDlgState* eState;
XP_U16 wid;
XP_U16 notifyCode;
NMTOOLBAR* nmToolP;
if ( message == WM_INITDIALOG ) {
SetWindowLongPtr( hDlg, GWL_USERDATA, lParam );
eState = (ClrEditDlgState*)lParam;
eState->cancelled = XP_TRUE;
eState->inited = XP_FALSE;
ceDlgSetup( &eState->dlgHdr, hDlg, DLG_STATE_TRAPBACK );
wchar_t label[32];
XP_U16 len = SendDlgItemMessage( eState->parent, eState->labelID,
WM_GETTEXT, VSIZE(label),
(long)label );
if ( len > 0 ) {
label[len-1] = 0; /* hack: overwrite ':' */
}
wchar_t buf[64];
swprintf( buf, ceGetResStringL( eState->dlgHdr.globals,
IDS_EDITCOLOR_FORMAT ), label );
SendMessage( hDlg, WM_SETTEXT, 0, (LPARAM)buf );
eState->sampleButton = GetDlgItem( hDlg, CLSAMPLE_BUTTON_ID );
EnableWindow( eState->sampleButton, FALSE );
return TRUE;
} else {
eState = (ClrEditDlgState*)GetWindowLongPtr( hDlg, GWL_USERDATA );
if ( !eState ) {
return FALSE;
}
if ( !eState->inited ) {
/* set to true first! Messages will be generated by
initChooseColor call below */
eState->inited = XP_TRUE;
initChooseColor( eState, hDlg );
}
if ( ceDoDlgHandle( &eState->dlgHdr, message, wParam, lParam) ) {
return TRUE;
}
switch (message) {
case WM_DRAWITEM:
colorButtonFromState( eState, (DRAWITEMSTRUCT*)lParam );
return TRUE;
break;
case WM_NOTIFY:
nmToolP = (NMTOOLBAR*)lParam;
wid = nmToolP->hdr.idFrom;
switch ( wid ) {
case CLREDT_SLIDER1:
case CLREDT_SLIDER2:
case CLREDT_SLIDER3:
updateForSlider( hDlg, eState, wid );
break;
}
break;
case WM_COMMAND:
wid = LOWORD(wParam);
switch( wid ) {
case RED_EDIT:
case GREEN_EDIT:
case BLUE_EDIT:
notifyCode = HIWORD(wParam);
if ( notifyCode == EN_CHANGE ) {
updateForField( hDlg, eState, wid );
return TRUE;
}
break;
case IDOK:
eState->cancelled = XP_FALSE;
/* fallthrough */
case IDCANCEL:
EndDialog(hDlg, wid);
return TRUE;
}
}
}
return FALSE;
} /* EditColorsDlg */
static XP_Bool
myChooseColor( CeDlgHdr* dlgHdr, XP_U16 labelID, COLORREF* cref )
{
ClrEditDlgState state;
int result;
XP_MEMSET( &state, 0, sizeof(state) );
state.dlgHdr.globals = dlgHdr->globals;
state.red = GetRValue(*cref);
state.green = GetGValue(*cref);
state.blue = GetBValue(*cref);
state.labelID = labelID;
state.parent = dlgHdr->hDlg;
XP_LOGF( "setting up IDD_COLOREDITDLG" );
result = DialogBoxParam( dlgHdr->globals->locInst,
(LPCTSTR)IDD_COLOREDITDLG,
dlgHdr->hDlg, (DLGPROC)EditColorsDlg,
(long)&state );
XP_LOGF( "DialogBoxParam=>%d", result );
if ( !state.cancelled ) {
*cref = RGB( state.red, state.green, state.blue );
}
return !state.cancelled;
} /* myChooseColor */
#endif /* MY_COLOR_SEL */
static void
colorButton( DRAWITEMSTRUCT* dis, HBRUSH brush )
{
RECT rect = dis->rcItem;
Rectangle( dis->hDC, rect.left, rect.top, rect.right, rect.bottom );
InsetRect( &rect, 1, 1 );
FillRect( dis->hDC, &rect, brush );
}
typedef struct ColorsDlgState {
CeDlgHdr dlgHdr;
COLORREF* inColors;
COLORREF colors[CE_NUM_EDITABLE_COLORS];
HBRUSH brushes[CE_NUM_EDITABLE_COLORS];
HWND buttons[CE_NUM_EDITABLE_COLORS];
XP_Bool cancelled;
XP_Bool inited;
} ColorsDlgState;
#define FIRST_BUTTON DLBLTR_SAMPLE
#define LAST_BUTTON PLAYER4_SAMPLE
static void
initColorData( ColorsDlgState* cState )
{
XP_U16 i;
XP_ASSERT( (LAST_BUTTON - FIRST_BUTTON + 1) == CE_NUM_EDITABLE_COLORS );
for ( i = 0; i < CE_NUM_EDITABLE_COLORS; ++i ) {
COLORREF ref = cState->inColors[i];
HWND button = GetDlgItem( cState->dlgHdr.hDlg, FIRST_BUTTON + i );
cState->colors[i] = ref;
cState->brushes[i] = CreateSolidBrush( ref );
cState->buttons[i] = button;
EnableWindow( button, FALSE );
}
} /* initColorData */
static HBRUSH
brushForButton( ColorsDlgState* cState, HWND hwndButton )
{
XP_U16 i;
for ( i = 0; i < CE_NUM_EDITABLE_COLORS; ++i ) {
if ( cState->buttons[i] == hwndButton ) {
return cState->brushes[i];
}
}
return NULL;
} /* brushForButton */
static void
deleteButtonBrushes( ColorsDlgState* cState )
{
XP_U16 i;
for ( i = 0; i < CE_NUM_EDITABLE_COLORS; ++i ) {
DeleteObject( cState->brushes[i] );
}
} /* deleteButtonBrushes */
static XP_Bool
wrapChooseColor( ColorsDlgState* cState, XP_U16 button )
{
XP_Bool handled = XP_FALSE;
if ( button >= DLBLTR_BUTTON && button <= PLAYER4_BUTTON ) {
XP_U16 index = button - DLBLTR_BUTTON;
#ifdef MY_COLOR_SEL
XP_U16 labelID = button + CLRSEL_LABEL_OFFSET;
COLORREF clrref = cState->colors[index];
if ( myChooseColor( &cState->dlgHdr, labelID, &clrref ) ) {
cState->colors[index] = clrref;
DeleteObject( cState->brushes[index] );
cState->brushes[index] = CreateSolidBrush( clrref );
XP_LOGF( "%s: may need to invalidate the button since "
"color's changed", __func__ );
}
#else
CHOOSECOLOR ccs;
BOOL hitOk;
COLORREF arr[16];
XP_U16 i;
XP_MEMSET( &ccs, 0, sizeof(ccs) );
XP_MEMSET( &arr, 0, sizeof(arr) );
for ( i = 0; i < CE_NUM_EDITABLE_COLORS; ++i ) {
arr[i] = cState->colors[i];
}
ccs.lStructSize = sizeof(ccs);
ccs.hwndOwner = cState->dlgHdr.hDlg;
ccs.rgbResult = cState->colors[index];
ccs.lpCustColors = arr;
ccs.Flags = CC_ANYCOLOR | CC_RGBINIT | CC_FULLOPEN;
hitOk = ChooseColor( &ccs );
if ( hitOk ) {
cState->colors[index] = ccs.rgbResult;
DeleteObject( cState->brushes[index] );
cState->brushes[index] = CreateSolidBrush( ccs.rgbResult );
}
#endif
handled = XP_TRUE;
}
return handled;
} /* wrapChooseColor */
static void
ceDrawColorButton( ColorsDlgState* cState, DRAWITEMSTRUCT* dis )
{
HBRUSH brush = brushForButton( cState, dis->hwndItem );
XP_ASSERT( !!brush );
colorButton( dis, brush );
} /* ceDrawColorButton */
LRESULT CALLBACK
ColorsDlg( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
ColorsDlgState* state;
BOOL result = FALSE;
if ( message == WM_INITDIALOG ) {
SetWindowLongPtr( hDlg, GWL_USERDATA, lParam );
state = (ColorsDlgState*)lParam;
state->cancelled = XP_TRUE;
state->inited = XP_FALSE;
ceDlgSetup( &state->dlgHdr, hDlg, DLG_STATE_NONE );
result = TRUE;
} else {
state = (ColorsDlgState*)GetWindowLongPtr( hDlg, GWL_USERDATA );
if ( !!state ) {
XP_U16 wid;
if ( !state->inited ) {
initColorData( state );
state->inited = XP_TRUE;
}
/* XP_LOGF( "%s: event=%s (%d); wParam=0x%x; lParam=0x%lx", */
/* __func__, messageToStr(message), message, */
/* wParam, lParam ); */
if ( ceDoDlgHandle( &state->dlgHdr, message, wParam, lParam) ) {
result = TRUE;
} else {
switch (message) {
case WM_DRAWITEM:
ceDrawColorButton( state, (DRAWITEMSTRUCT*)lParam );
result = TRUE;
break;
case WM_COMMAND:
if ( BN_CLICKED == HIWORD(wParam) ) {
wid = LOWORD(wParam);
switch( wid ) {
case IDOK:
state->cancelled = XP_FALSE;
/* fallthrough */
case IDCANCEL:
deleteButtonBrushes( state );
EndDialog(hDlg, wid);
result = TRUE;
break;
default:
/* it's one of the color buttons. Set up with the
appropriate color and launch ChooseColor */
result = wrapChooseColor( state, wid );
break;
}
}
}
}
}
}
return result;
} /* ColorsDlg */
XP_Bool
ceDoColorsEdit( HWND hwnd, CEAppGlobals* globals, COLORREF* colors )
{
ColorsDlgState state;
XP_MEMSET( &state, 0, sizeof(state) );
state.dlgHdr.globals = globals;
state.inColors = colors;
(void)DialogBoxParam( globals->locInst, (LPCTSTR)IDD_COLORSDLG, hwnd,
(DLGPROC)ColorsDlg, (long)&state );
if ( !state.cancelled ) {
XP_U16 i;
for ( i = 0; i < CE_NUM_EDITABLE_COLORS; ++i ) {
colors[i] = state.colors[i];
}
}
return !state.cancelled;
} /* ceDoColorsEdit */