balance_wheel/IrrExtensions/gui/GUIGroupingPanel.cpp

207 lines
7.1 KiB
C++

// (c) 2015 Nicolaus Anderson
#ifndef GUI_GROUPING_PANEL_CPP
#define GUI_GROUPING_PANEL_CPP
#include "GUIGroupingPanel.h"
#include <IGUIFont.h>
#include <IGUISkin.h>
#include <IGUIEnvironment.h>
#include <ITexture.h>
#include <IVideoDriver.h>
namespace irr {
namespace gui {
using video::IVideoDriver;
using video::SColor;
using core::vector2di;
GUIGroupingPanel::GUIGroupingPanel( const wchar_t* pText, IGUIEnvironment* pEnvironment, IGUIElement* pParent, const recti& pRect, s32 id )
: IGUIElement( EGUIET_ELEMENT, pEnvironment, pParent, id, pRect )
, showBorder( true )
, borderRadius( 6 )
{
textSize = pEnvironment->getSkin()->getFont()->getDimension( pText );
Text = pText;
updateImageCache();
setTabGroup(true);
}
void GUIGroupingPanel::setText(const wchar_t* text)
{
Text = text;
textSize = Environment->getSkin()->getFont()->getDimension( text );
}
void GUIGroupingPanel::setShowBorder( bool pShow )
{
showBorder = pShow;
}
void GUIGroupingPanel::setBorderEdgeRadius( f32 pRadius )
{
borderRadius = pRadius;
updateImageCache();
}
recti GUIGroupingPanel::getClientArea()
{
return recti( borderRadius, borderRadius + textSize.Height, RelativeRect.getWidth() - borderRadius, RelativeRect.getHeight() - borderRadius );
}
//void GUIGroupingPanel::updateAbsolutePosition()
//{
//}
void GUIGroupingPanel::draw()
{
IVideoDriver* vid = Environment->getVideoDriver();
IGUISkin* skin = Environment->getSkin();
SColor color = skin->getColor( EGDC_3D_LIGHT );
SColor shadowColor = skin->getColor( EGDC_3D_SHADOW );
SColor textColor = skin->getColor( EGDC_BUTTON_TEXT );
s32 textPad = ( textSize.Width > 0 ) ? 3 : 0; // Padding is only needed when there is text
// Draw border corners
vector2di textPush(0, textSize.Height/2);
recti cornerSource( ULtexture->getSize() ); // Source rectangle for the images
vid->draw2DImage( ULtexture, AbsoluteRect.UpperLeftCorner + textPush, cornerSource, &AbsoluteClippingRect, SColor(-1), true );
vector2di corner2( AbsoluteRect.getWidth() - borderRadius, 0 );
vid->draw2DImage( URtexture, corner2 + AbsoluteRect.UpperLeftCorner + textPush, cornerSource, &AbsoluteClippingRect, SColor(-1), true );
vector2di corner( 0, AbsoluteRect.getHeight() - borderRadius );
vid->draw2DImage( LLtexture, corner + AbsoluteRect.UpperLeftCorner, cornerSource, &AbsoluteClippingRect, SColor(-1), true );
corner2 += vector2di( 0, AbsoluteRect.getHeight() - borderRadius ); // Use .move() in custom Irrlicht
vid->draw2DImage( LRtexture, corner2 + AbsoluteRect.UpperLeftCorner, cornerSource, &AbsoluteClippingRect, SColor(-1), true );
// Draw border walls
// Left side
vector2di vline( AbsoluteRect.UpperLeftCorner );
vline.Y += borderRadius + (textSize.Height / 2);
vector2di vlineEnd( AbsoluteRect.UpperLeftCorner.X, AbsoluteRect.LowerRightCorner.Y - borderRadius );
vid->draw2DLine( vline, vlineEnd, color );
vline.X += 1;
vlineEnd.X += 1;
vid->draw2DLine( vline, vlineEnd, shadowColor ); // Shadow
// Top side
vector2di hline( AbsoluteRect.UpperLeftCorner );
hline += vector2di( borderRadius + textPad*2 + textSize.Width, textSize.Height / 2 ); // Use .move() in custom Irrlicht
vector2di hlineEnd( AbsoluteRect.LowerRightCorner.X - borderRadius, AbsoluteRect.UpperLeftCorner.Y + (textSize.Height / 2) );
vid->draw2DLine( hline, hlineEnd, color );
hline.Y += 1;
hlineEnd.Y += 1;
vid->draw2DLine( hline, hlineEnd, shadowColor ); // Shadow
// Right side
vline.set( AbsoluteRect.LowerRightCorner.X, AbsoluteRect.UpperLeftCorner.Y + borderRadius + (textSize.Height / 2) );
vlineEnd.set( AbsoluteRect.LowerRightCorner );
vlineEnd.Y -= borderRadius;
vid->draw2DLine( vline, vlineEnd, color );
vline.X -= 1;
vlineEnd.X -= 1;
vid->draw2DLine( vline, vlineEnd, shadowColor ); // Shadow
// Bottom side
hline.set( AbsoluteRect.UpperLeftCorner.X + borderRadius, AbsoluteRect.LowerRightCorner.Y );
hlineEnd.set( AbsoluteRect.LowerRightCorner );
hlineEnd.X -= borderRadius;
vid->draw2DLine( hline, hlineEnd, color );
hline.Y -= 1;
hlineEnd.Y -= 1;
vid->draw2DLine( hline, hlineEnd, shadowColor ); // Shadow
// Draw label text
recti labelRect( borderRadius + 3, 0, borderRadius + textPad, textSize.Height );
Environment->getSkin()->getFont()->draw( Text.c_str(), labelRect + AbsoluteRect.UpperLeftCorner, textColor, false, false, &AbsoluteClippingRect );
// Draw child elements
IGUIElement::draw();
}
void GUIGroupingPanel::updateImageCache()
{
IVideoDriver* vid = Environment->getVideoDriver();
SColor color = Environment->getSkin()->getColor( EGDC_3D_LIGHT );
SColor shadowColor = Environment->getSkin()->getColor( EGDC_3D_SHADOW );
dimension2du imageSize( borderRadius, borderRadius );
// Produces cropped circles used as end-caps / corners
ULtexture = vid->addRenderTargetTexture( imageSize, "GUI_GROUPING_PANEL_CORNER_UL" );
if ( ULtexture )
{
// Irrlicht 5104
//vid->setRenderTarget( ULtexture );
// Irrlicht 5589
vid->setRenderTarget( ULtexture, u16(irr::video::ECBF_COLOR), SColor(0,0,0,0) );
vid->draw2DPolygon( vector2di( borderRadius+1 ), borderRadius, shadowColor, 40 );
vid->draw2DPolygon( vector2di( borderRadius, borderRadius ), borderRadius, color, 40 );
}
URtexture = vid->addRenderTargetTexture( imageSize, "GUI_GROUPING_PANEL_CORNER_UR" );
if ( URtexture )
{
// Irrlicht 5104
//vid->setRenderTarget( URtexture );
// Irrlicht 5589
vid->setRenderTarget( URtexture, u16(irr::video::ECBF_COLOR), SColor(0,0,0,0) );
vid->draw2DPolygon( vector2di( -1, borderRadius+1 ), borderRadius, shadowColor, 40 );
vid->draw2DPolygon( vector2di( 0, borderRadius ), borderRadius, color, 40 );
}
LLtexture = vid->addRenderTargetTexture( imageSize, "GUI_GROUPING_PANEL_CORNER_LL" );
if ( LLtexture )
{
// Irrlicht 5104
//vid->setRenderTarget( LLtexture );
// Irrlicht 5589
vid->setRenderTarget( LLtexture, u16(irr::video::ECBF_COLOR), SColor(0,0,0,0) );
vid->draw2DPolygon( vector2di( borderRadius+1, -1 ), borderRadius, shadowColor, 40 );
vid->draw2DPolygon( vector2di( borderRadius, 0 ), borderRadius, color, 40 );
}
LRtexture = vid->addRenderTargetTexture( imageSize, "GUI_GROUPING_PANEL_CORNER_LR" );
if ( LRtexture )
{
// Irrlicht 5104
//vid->setRenderTarget( LRtexture );
// Irrlicht 5589
vid->setRenderTarget( LRtexture, u16(irr::video::ECBF_COLOR), SColor(0,0,0,0) );
vid->draw2DPolygon( vector2di( -1 ), borderRadius, shadowColor, 40 );
vid->draw2DPolygon( vector2di( 0 ), borderRadius, color, 40 );
}
vid->setRenderTarget(0); // Should restore old target
}
void
GUIGroupingPanel::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const {
IGUIElement::serializeAttributes(out, options);
out->addBool("ShowBorder", showBorder );
out->addFloat("BorderRadius", borderRadius );
}
void
GUIGroupingPanel::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options) {
IGUIElement::deserializeAttributes(in, options);
// Required so that the text size can be precalculated - NO LONGER NEEDED
//setText( in->getAttributeAsString("Caption", L"") );
showBorder = in->getAttributeAsBool("ShowBorder", showBorder);
borderRadius = in->getAttributeAsFloat("BorderRadius", borderRadius);
}
}}
#endif // #ifndef GUI_GROUPING_PANEL_CPP