/*
* TButton.cc
*
* Turbo Vision - Version 2.0
*
* Copyright (c) 1994 by Borland International
* All Rights Reserved.
*
* Modified by Sergio Sigala <sergio@sigala.it>
*/
#define Uses_TButton
#define Uses_TDrawBuffer
#define Uses_TEvent
#define Uses_TRect
#define Uses_TGroup
#define Uses_opstream
#define Uses_ipstream
#include <tvision/tv.h>
#include <ctype.h>
#include <string.h>
const
int cmGrabDefault = 61,
cmReleaseDefault = 62;
#define cpButton "\x0A\x0B\x0C\x0D\x0E\x0E\x0E\x0F"
TButton::TButton( const TRect& bounds,
const char *aTitle,
ushort aCommand,
ushort aFlags) :
TView( bounds ),
title( newStr( aTitle ) ),
command( aCommand ),
flags( aFlags ),
amDefault( Boolean( (aFlags & bfDefault) != 0 ) )
{
options |= ofSelectable | ofFirstClick | ofPreProcess | ofPostProcess;
eventMask |= evBroadcast;
if( !commandEnabled(aCommand) )
state |= sfDisabled;
}
TButton::~TButton()
{
delete (char *)title;
}
void TButton::draw()
{
drawState(False);
}
void TButton::drawTitle( TDrawBuffer &b,
int s,
int i,
ushort cButton,
Boolean down
)
{
int l, scOff;
if( (flags & bfLeftJust) != 0 )
l = 1;
else
{
l = (s - cstrlen(title) - 1)/2;
if( l < 1 )
l = 1;
}
b.moveCStr( i+l, title, cButton );
if( showMarkers == True && !down )
{
if( (state & sfSelected) != 0 )
scOff = 0;
else if( amDefault )
scOff = 2;
else
scOff = 4;
b.putChar( 0, specialChars[scOff] );
b.putChar( s, specialChars[scOff+1] );
}
}
void TButton::drawState(Boolean down)
{
ushort cButton, cShadow;
char ch = ' ';
int i;
TDrawBuffer b;
if( (state & sfDisabled) != 0 )
cButton = getColor(0x0404);
else
{
cButton = getColor(0x0501);
if( (state & sfActive) != 0 )
if( (state & sfSelected) != 0 )
cButton = getColor(0x0703);
else if( amDefault )
cButton = getColor(0x0602);
}
cShadow = getColor(8);
int s = size.x-1;
int T = size.y / 2 - 1;
for( int y = 0; y <= size.y-2; y++ )
{
b.moveChar( 0, ' ', cButton, size.x );
b.putAttribute( 0, cShadow );
if( down )
{
b.putAttribute( 1, cShadow );
ch = ' ';
i = 2;
}
else
{
b.putAttribute( s, cShadow );
if( showMarkers == True )
ch = ' ';
else
{
if( y == 0 )
b.putChar( s, shadows[0] );
else
b.putChar( s, shadows[1] );
ch = shadows[2];
}
i = 1;
}
if( y == T && title != 0 )
drawTitle( b, s, i, cButton, down );
if( showMarkers && !down )
{
b.putChar( 1, markers[0] );
b.putChar( s-1, markers[1] );
}
writeLine( 0, y, size.x, 1, b );
}
b.moveChar( 0, ' ', cShadow, 2 );
b.moveChar( 2, ch, cShadow, s-1 );
writeLine( 0, size.y-1, size.x, 1, b );
}
TPalette& TButton::getPalette() const
{
static TPalette palette( cpButton, sizeof( cpButton )-1 );
return palette;
}
void TButton::handleEvent( TEvent& event )
{
TPoint mouse;
TRect clickRect;
clickRect = getExtent();
clickRect.a.x++;
clickRect.b.x--;
clickRect.b.y--;
if( event.what == evMouseDown )
{
mouse = makeLocal( event.mouse.where );
if( !clickRect.contains(mouse) )
clearEvent( event );
}
if (flags & bfGrabFocus)
TView::handleEvent(event);
char c = hotKey( title );
switch( event.what )
{
case evMouseDown:
if ((state & sfDisabled) == 0)
{
clickRect.b.x++;
Boolean down = False;
do {
mouse = makeLocal( event.mouse.where );
if( down != clickRect.contains( mouse ) )
{
down = Boolean( !down );
drawState( down );
}
} while( mouseEvent( event, evMouseMove ) );
if( down )
{
press();
drawState( False );
}
}
clearEvent( event );
break;
case evKeyDown:
if( event.keyDown.keyCode == getAltCode(c) ||
( owner->phase == phPostProcess &&
c != 0 &&
toupper(event.keyDown.charScan.charCode) == (uchar)c
) ||
( (state & sfFocused) != 0 &&
event.keyDown.charScan.charCode == ' '
)
)
{
press();
clearEvent( event );
}
break;
case evBroadcast:
switch( event.message.command )
{
case cmDefault:
if( amDefault && !(state & sfDisabled) )
{
press();
clearEvent(event);
}
break;
case cmGrabDefault:
case cmReleaseDefault:
if( (flags & bfDefault) != 0 )
{
amDefault = Boolean(event.message.command == cmReleaseDefault);
drawView();
}
break;
case cmCommandSetChanged:
setState(sfDisabled,Boolean(!commandEnabled(command)));
drawView();
break;
}
break;
}
}
void TButton::makeDefault( Boolean enable )
{
if( (flags & bfDefault) == 0 )
{
message( owner,
evBroadcast,
(enable == True) ? cmGrabDefault : cmReleaseDefault,
this
);
amDefault = enable;
drawView();
}
}
void TButton::setState( ushort aState, Boolean enable )
{
TView::setState(aState, enable);
if( aState & (sfSelected | sfActive) )
#ifndef __UNPATCHED
{
if(!enable)
{ // BUG FIX - EFW - Thu 10/19/95
state &= ~sfFocused;
makeDefault(False);
}
drawView();
}
#else
drawView();
#endif
if( (aState & sfFocused) != 0 )
makeDefault( enable );
}
void TButton::press()
{
message( owner, evBroadcast, cmRecordHistory, 0 );
if( (flags & bfBroadcast) != 0 )
message( owner, evBroadcast, command, this );
else
{
TEvent e;
e.what = evCommand;
e.message.command = command;
e.message.infoPtr = this;
putEvent( e );
}
}
#if !defined(NO_STREAMABLE)
void TButton::write( opstream& os )
{
TView::write( os );
os.writeString( title );
os << command << flags << (int)amDefault;
}
void *TButton::read( ipstream& is )
{
TView::read( is );
title = is.readString();
int temp;
is >> command >> flags >> temp;
amDefault = Boolean(temp);
if( TButton::commandEnabled( command ) )
state &= ~sfDisabled;
else
state |= sfDisabled;
return this;
}
TStreamable *TButton::build()
{
return new TButton( streamableInit );
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1