#define Uses_TRect
#define Uses_TMenu
#define Uses_TMenuItem
#define Uses_TMenuBox
#include <tvision/tv.h>
#if !defined( __STRING_H )
#include <string.h>
#endif // __STRING_H
static
TRect getRect(
const
TRect& bounds, TMenu *aMenu )
{
short
w = 10;
short
h = 2;
if
( aMenu != 0 )
{
for
( TMenuItem *p = aMenu->items; p != 0; p = p->next )
{
if
( p->name != 0 )
{
short
l = cstrlen(p->name) + 6;
if
( p->command == 0 )
l += 3;
else
if
( p->param != 0 )
l += cstrlen(p->param) + 2;
w = max( l, w );
}
h++;
}
}
TRect r( bounds );
if
( r.a.x + w < r.b.x )
r.b.x = r.a.x + w;
else
r.a.x = r.b.x - w;
if
(r.a.y + h < r.b.y)
r.b.y = r.a.y + h;
else
r.a.y = r.b.y - h;
return
r;
}
TMenuBox::TMenuBox(
const
TRect& bounds,
TMenu *aMenu,
TMenuView *aParentMenu )
noexcept
:
TMenuView( getRect( bounds, aMenu ), aMenu, aParentMenu )
{
state |= sfShadow;
options |= ofPreProcess;
}
static
thread_local
TAttrPair cNormal, color;
void
TMenuBox::frameLine( TDrawBuffer& b,
short
n )
{
b.moveBuf( 0, &frameChars[n], cNormal, 2 );
b.moveChar( 2, frameChars[n+2], color, size.x - 4 );
b.moveBuf( size.x-2, &frameChars[n+3], cNormal, 2 );
}
void
TMenuBox::draw()
{
TDrawBuffer b;
cNormal = getColor(0x0301);
TAttrPair cSelect = getColor(0x0604);
TAttrPair cNormDisabled = getColor(0x0202);
TAttrPair cSelDisabled = getColor(0x0505);
short
y = 0;
color = cNormal;
frameLine( b, 0 );
writeBuf( 0, y++, size.x, 1, b );
if
( menu != 0 )
{
for
( TMenuItem *p = menu->items; p != 0; p = p->next )
{
color = cNormal;
if
( p->name == 0 )
frameLine( b, 15 );
else
{
if
( p->disabled )
if
( p == current )
color = cSelDisabled;
else
color = cNormDisabled;
else
if
( p == current )
color = cSelect;
frameLine( b, 10 );
b.moveCStr( 3, p->name, color );
if
( p->command == 0 )
b.putChar( size.x-4, 16 );
else
if
( p->param != 0 )
b.moveCStr( size.x-3-cstrlen(p->param),
p->param,
color);
}
writeBuf( 0, y++, size.x, 1, b );
}
}
color = cNormal;
frameLine( b, 5 );
writeBuf( 0, y, size.x, 1, b );
}
TRect TMenuBox::getItemRect( TMenuItem *item )
{
short
y = 1;
TMenuItem *p = menu->items;
while
( p != item )
{
y++;
p = p->next;
}
return
TRect( 2, y, size.x-2, y+1 );
}
#if !defined(NO_STREAMABLE)
TStreamable *TMenuBox::build()
{
return
new
TMenuBox( streamableInit );
}
TMenuBox::TMenuBox( StreamableInit )
noexcept
: TMenuView( streamableInit )
{
}
#endif