/// === PULSANTE 1.0 (31/01/2014) ==============================================
#include "pulsante.h"
static const char kPULSANTEErrMemoriaInsufficiente[] =
"classe PULSANTE, memoria insufficiente";
static const ARGB kColoriSfondoDflt[] =
{ 0xFF000000, 0xFFFF9900, 0xFF333333, 0xFF000000, 0xFF006600 };
static const ARGB kColoriTrattoDflt[] =
{ 0xFF666666, 0xFF000000, 0xFFFF9900, 0xFF33CC00, 0xFF000000 };
PULSANTE::PULSANTE() {
os = NULL;
t = NULL;
dimFont = 0.0f;
wBordo = 1;
allinOrizz = 0;
allinVert = 0;
set_colori_sfondo( kColoriSfondoDflt[0], kColoriSfondoDflt[1],
kColoriSfondoDflt[2], kColoriSfondoDflt[3],
kColoriSfondoDflt[4], FALSE );
set_colori_tratto( kColoriTrattoDflt[0], kColoriTrattoDflt[1],
kColoriTrattoDflt[2], kColoriTrattoDflt[3],
kColoriTrattoDflt[4], FALSE );
stato = kPULSANTENormale;
staGiu = 0;
set_rettangolo( 0, 0, 0, 0 );
set_titolo( NULL,FALSE );
}
PULSANTE::PULSANTE( int x, int y, int w, int h, const char *titolo ) {
os = NULL;
t = NULL;
dimFont = h/1.5f>0 ? w/15 : 1;
wBordo = 1;
allinOrizz = 0;
allinVert = 0;
set_colori_sfondo( kColoriSfondoDflt[0], kColoriSfondoDflt[1],
kColoriSfondoDflt[2], kColoriSfondoDflt[3],
kColoriSfondoDflt[4], FALSE );
set_colori_tratto( kColoriTrattoDflt[0], kColoriTrattoDflt[1],
kColoriTrattoDflt[2], kColoriTrattoDflt[3],
kColoriTrattoDflt[4], FALSE );
stato = kPULSANTENormale;
staGiu = 0;
set_rettangolo( x, y, w, h );
set_titolo( titolo,FALSE );
}
PULSANTE::~PULSANTE() {
delete[] t;
}
void PULSANTE::attiva( BOOL att, BOOL agg ) {
if( stato == kPULSANTEDisattivo && att ) {
stato = kPULSANTENormale;
if( agg ) traccia();
}
else if( stato != kPULSANTEDisattivo && !att ) {
stato = kPULSANTEDisattivo;
if( agg ) traccia();
}
}
void PULSANTE::seleziona( BOOL sel, BOOL agg ) {
if( stato != kPULSANTEDisattivo ) {
if( sel && staGiu )
stato = kPULSANTESelezionato;
else stato = kPULSANTENormale;
if( agg ) traccia();
}
}
void PULSANTE::set_rettangolo( int x, int y, int w, int h ) {
r.left = x; r.right = x+w;
r.top = y; r.bottom = y+h;
}
void PULSANTE::set_titolo( const char *titolo, BOOL agg ) {
try {
int i, lun = lstrlen(titolo);
WCHAR *temp = new WCHAR[lun+1];
if( titolo == NULL ) titolo = "";
for( i=0; i<lun; i++ )
temp[i] = (unsigned char)titolo[i];
temp[i] = 0;
delete[] t;
t = temp;
if( agg ) traccia();
} catch( ... ) {
throw kPULSANTEErrMemoriaInsufficiente;
}
}
void PULSANTE::set_dimensione_font( REAL dim, BOOL agg ) {
dimFont = dim>=0.0f ? dim : -dim;
if( agg ) traccia();
}
void PULSANTE::set_allineamento_orizzontale( int allineamento, BOOL agg ) {
if( allineamento < 0 )
allinOrizz = -1;
else if( allineamento > 0 )
allinOrizz = 1;
else allinOrizz = 0;
if( agg ) traccia();
}
void PULSANTE::set_allineamento_verticale( int allineamento, BOOL agg ) {
if( allineamento < 0 )
allinVert = -1;
else if( allineamento > 0 )
allinVert = 1;
else allinVert = 0;
if( agg ) traccia();
}
void PULSANTE::set_spessore_bordo( unsigned int spBordo, BOOL agg ) {
wBordo = spBordo;
if( agg ) traccia();
}
void PULSANTE::set_colori_sfondo( ARGB cDisattivo, ARGB cPremuto,
ARGB cSopra, ARGB cNormale, ARGB cSelezionato, BOOL agg ) {
sfondo[0] = cDisattivo;
sfondo[1] = cSelezionato;
sfondo[2] = cPremuto;
sfondo[3] = cSopra;
sfondo[4] = cNormale;
if( agg ) traccia();
}
void PULSANTE::set_colori_tratto( ARGB cDisattivo, ARGB cPremuto,
ARGB cSopra, ARGB cNormale, ARGB cSelezionato, BOOL agg ) {
tratto[0] = cDisattivo;
tratto[1] = cSelezionato;
tratto[2] = cPremuto;
tratto[3] = cSopra;
tratto[4] = cNormale;
if( agg ) traccia();
}
void PULSANTE::set_offscreen( OFFSCREEN *offscreen ) {
os = offscreen;
}
RECT *PULSANTE::get_rettangolo( RECT *rct ) {
if( rct == NULL ) return rct;
CopyRect( rct, &r );
return rct;
}
Rect *PULSANTE::get_rettangolo( Rect *rct ) {
if( rct == NULL ) return rct;
rct->X = r.left;
rct->Y = r.top;
rct->Width = r.right- r.left;
rct->Height = r.bottom - r.top;
return rct;
}
RectF *PULSANTE::get_rettangolo( RectF *rct ) {
if( rct == NULL ) return rct;
rct->X = r.left;
rct->Y = r.top;
rct->Width = r.right- r.left;
rct->Height = r.bottom - r.top;
return rct;
}
BOOL PULSANTE::in( LONG x, LONG y ) {
POINT pt = { x, y };
return PtInRect( &r, pt );
}
BOOL PULSANTE::sopra( LONG x, LONG y ) {
if( stato > kPULSANTEPremuto ) {
short exStato = stato;
BOOL dentro = in( x, y );
if( dentro )
stato = kPULSANTESopra;
else stato = kPULSANTENormale;
if( stato != exStato ) traccia();
return dentro;
}
return FALSE;
}
BOOL PULSANTE::click( LONG x, LONG y ) {
if( stato == kPULSANTESelezionato || stato > kPULSANTEPremuto ) {
if( in(x,y) ) return SeguiMouse( x, y );
}
return FALSE;
}
void PULSANTE::simula_click( void ) {
if( os == NULL ) return;
if( stato == kPULSANTESelezionato || stato > kPULSANTEPremuto ) {
short exStato = stato;
stato = kPULSANTEPremuto;
traccia();
Sleep( 150 );
if( !staGiu ) {
stato = exStato;
}
else {
if( exStato == kPULSANTESelezionato )
stato = kPULSANTENormale;
else stato = kPULSANTESelezionato;
}
traccia();
}
}
void PULSANTE::traccia( BOOL agg ) {
if( os == NULL ) return;
RectF rf( r.left, r.top, r.right-r.left, r.bottom-r.top );
Graphics gfx( os->get_dc() );
SolidBrush pennello( Colore(0) );
gfx.FillRectangle( &pennello, rf );
if( wBordo > 0 ) {
Pen penna( Colore(1), wBordo );
penna.SetAlignment( PenAlignmentInset );
gfx.DrawRectangle( &penna, rf );
}
pennello.SetColor( Colore(1) );
TracciaTitolo( &gfx, &pennello, &rf );
if( agg ) aggiorna();
}
void PULSANTE::aggiorna( void ) {
if( os != NULL ) {
os->invalida( &r );
os->aggiorna();
}
}
void PULSANTE::TracciaTitolo( Graphics *gfx, SolidBrush *pennello, RectF *rf ) {
FontFamily fontFamily( L"Arial" );
Font font( &fontFamily, dimFont, FontStyleBold, UnitPixel);
StringFormat sf;
if( allinOrizz < 0 )
sf.SetAlignment( StringAlignmentNear );
else if( allinOrizz > 0 )
sf.SetAlignment( StringAlignmentFar );
else sf.SetAlignment( StringAlignmentCenter );
if( allinVert < 0 )
sf.SetLineAlignment( StringAlignmentNear );
else if( allinVert > 0 )
sf.SetLineAlignment( StringAlignmentFar );
else sf.SetLineAlignment( StringAlignmentCenter );
gfx->SetTextRenderingHint( TextRenderingHintAntiAlias );
gfx->DrawString( t, -1, &font, *rf, &sf, pennello );
}
BOOL PULSANTE::SeguiMouse( LONG x, LONG y ) {
if( os == NULL ) return FALSE;
HWND hwnd = os->get_finestra();
int continua = 1;
MSG msg;
ZeroMemory( &msg, sizeof(MSG) );
short exStato = stato;
stato = kPULSANTEPremuto;
traccia();
SetCapture( hwnd );
do{
if( PeekMessage(&msg,hwnd,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) ) {
switch( msg.message ) {
case WM_LBUTTONUP:
ScreenToClient( hwnd, &msg.pt );
if( PtInRect(&r,msg.pt) ) {
if( !staGiu ) {
stato = exStato;
}
else {
if( exStato == kPULSANTESelezionato )
stato = kPULSANTENormale;
else stato = kPULSANTESelezionato;
}
}
else {
stato = exStato;
}
continua = 0;
break;
case WM_MOUSEMOVE:
ScreenToClient( hwnd, &msg.pt );
if( PtInRect(&r,msg.pt) )
stato = kPULSANTEPremuto;
else stato = exStato;
break;
default: break;
}
traccia();
}
} while( continua );
ReleaseCapture();
return PtInRect( &r, msg.pt );
}
ARGB PULSANTE::Colore( short tipo ) {
ARGB *c;
if( tipo == 0 ) c = sfondo; else c = tratto;
return c[stato+1];
}