skin info is now mostly read from a config file, making it cleaner and opening the door for futur modding capabilities
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3607 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
ee90eca26e
commit
a1044011d3
88
data/gui/glass.stkskin
Normal file
88
data/gui/glass.stkskin
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<skin name="Glass" author="Marianne Gagnon (Auria)">
|
||||||
|
|
||||||
|
<!-- Stateless -->
|
||||||
|
<element type="background" image="background.jpg" />
|
||||||
|
|
||||||
|
<element type="button" state="focused" image="glassbutton_focused.png"
|
||||||
|
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||||
|
preserve_h_aspect_ratios="true" />
|
||||||
|
|
||||||
|
<element type="button" state="neutral" image="glassbutton.png"
|
||||||
|
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||||
|
preserve_h_aspect_ratios="true" />
|
||||||
|
|
||||||
|
<!-- TODO : buttons could support 'pressed' state -->
|
||||||
|
|
||||||
|
|
||||||
|
<element type="tab" state="neutral" image="glasstab.png"
|
||||||
|
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||||
|
hborder_out_portion="0.2" />
|
||||||
|
|
||||||
|
<element type="tab" state="focused" image="glasstab_focus.png"
|
||||||
|
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||||
|
hborder_out_portion="0.2" />
|
||||||
|
|
||||||
|
<element type="tab" state="down" image="glasstab_down.png"
|
||||||
|
left_border="75" right_border="75" top_border="0" bottom_border="15"
|
||||||
|
hborder_out_portion="0.2" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Stateless -->
|
||||||
|
<element type="squareSelectionHalo" image="glass_square_focused.png"
|
||||||
|
left_border="6" right_border ="6" top_border="6" bottom_border="6"
|
||||||
|
hborder_out_portion="1.0" />
|
||||||
|
|
||||||
|
<!-- TODO : Allow elementning the selection bubble and focus halo too -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<element type="spinner" state="neutral" image="glassspinner.png"
|
||||||
|
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||||
|
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||||
|
|
||||||
|
<element type="spinner" state="focused" image="glassspinner_focus.png"
|
||||||
|
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||||
|
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||||
|
|
||||||
|
<!-- This one is a bit special. Only area(s) LEFT and/or RIGHT will be rendered. They will be overlaid
|
||||||
|
on top of the spinner's background -->
|
||||||
|
<element type="spinner" state="down" image="glassspinner_down.png"
|
||||||
|
left_border="110" right_border="110" top_border="0" bottom_border="36"
|
||||||
|
preserve_h_aspect_ratios="true" hborder_out_portion="0.0" />
|
||||||
|
|
||||||
|
<!-- For checkboxes, no splitting into 9 areas is done; the image is just stretched -->
|
||||||
|
<element type="checkbox" state="neutral+unchecked" image="glasscheckbox.png"/>
|
||||||
|
<element type="checkbox" state="neutral+checked" image="glasscheckbox_checked.png"/>
|
||||||
|
<element type="checkbox" state="focused+unchecked" image="glasscheckbox_focus.png"/>
|
||||||
|
<element type="checkbox" state="focused+checked" image="glasscheckbox_checked_focus.png"/>
|
||||||
|
|
||||||
|
<!-- Lists are always in neutral state for now -->
|
||||||
|
<element type="list" image="glass_section.png"
|
||||||
|
left_border="15" right_border="15" top_border="15" bottom_border="15"
|
||||||
|
hborder_out_portion="0.5" vborder_out_portion="1.0f" />
|
||||||
|
|
||||||
|
<element type="listitem" state="focused" image="glasssgauge_fill.png"
|
||||||
|
left_border="0" right_border="0" top_border="0" bottom_border="0"
|
||||||
|
hborder_out_portion="0.0" vborder_out_portion="0.0f" />
|
||||||
|
|
||||||
|
<element type="listitem" state="down" image="glassbutton.png"
|
||||||
|
left_border="80" right_border="80" top_border="0" bottom_border="36"
|
||||||
|
hborder_out_portion="1.0" vborder_out_portion="1.0f"
|
||||||
|
areas="body" />
|
||||||
|
|
||||||
|
<!-- Stateless -->
|
||||||
|
<element type="section" image="glass_section.png"
|
||||||
|
left_border="15" right_border="15" top_border="15" bottom_border="15"
|
||||||
|
hborder_out_portion="1.0" vborder_out_portion="0.2f" />
|
||||||
|
|
||||||
|
<!-- Stateless -->
|
||||||
|
<element type="window" image="glass_section.png"
|
||||||
|
left_border="15" right_border="15" top_border="15" bottom_border="15"
|
||||||
|
hborder_out_portion="1.0" vborder_out_portion="0.2f" />
|
||||||
|
|
||||||
|
<!-- Colors -->
|
||||||
|
<color type="text" state="neutral" r="0" g="0" b="0" />
|
||||||
|
<color type="text" state="focused" r="0" g="0" b="0" />
|
||||||
|
|
||||||
|
|
||||||
|
</skin>
|
BIN
data/gui/gnu.png
BIN
data/gui/gnu.png
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
367
src/gui/skin.cpp
367
src/gui/skin.cpp
@ -9,37 +9,118 @@
|
|||||||
|
|
||||||
using namespace GUIEngine;
|
using namespace GUIEngine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Small utility to read config file info from a XML file.
|
||||||
|
*/
|
||||||
|
namespace SkinConfig
|
||||||
|
{
|
||||||
|
static std::map<std::string, BoxRenderParams> m_render_params;
|
||||||
|
|
||||||
|
|
||||||
|
static void parseElement(const XMLNode* node)
|
||||||
|
{
|
||||||
|
std::string type;
|
||||||
|
std::string state = "neutral";
|
||||||
|
std::string image;
|
||||||
|
int leftborder = 0, rightborder=0, topborder=0, bottomborder=0;
|
||||||
|
float hborder_out_portion = 0.5f, vborder_out_portion = 1.0f;
|
||||||
|
bool preserve_h_aspect_ratios = false;
|
||||||
|
std::string areas;
|
||||||
|
|
||||||
|
if(node->get("type", &type) == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Error in skin : All elements must have a type\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node->get("state", &state);
|
||||||
|
|
||||||
|
if(node->get("image", &image) == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Error in skin : All elements must have an image\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->get("left_border", &leftborder);
|
||||||
|
node->get("right_border", &rightborder);
|
||||||
|
node->get("top_border", &topborder);
|
||||||
|
node->get("bottom_border", &bottomborder);
|
||||||
|
|
||||||
|
node->get("hborder_out_portion", &hborder_out_portion);
|
||||||
|
node->get("vborder_out_portion", &vborder_out_portion);
|
||||||
|
|
||||||
|
node->get("preserve_h_aspect_ratios", &preserve_h_aspect_ratios);
|
||||||
|
|
||||||
|
node->get("areas", &areas);
|
||||||
|
|
||||||
|
|
||||||
|
BoxRenderParams newParam;
|
||||||
|
// TODO : look for images in a skin-specific directory
|
||||||
|
newParam.image = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/" + image).c_str() );
|
||||||
|
newParam.left_border = leftborder;
|
||||||
|
newParam.right_border = rightborder;
|
||||||
|
newParam.top_border = topborder;
|
||||||
|
newParam.bottom_border = bottomborder;
|
||||||
|
newParam.hborder_out_portion = hborder_out_portion;
|
||||||
|
newParam.vborder_out_portion = vborder_out_portion;
|
||||||
|
newParam.preserve_h_aspect_ratios = preserve_h_aspect_ratios;
|
||||||
|
|
||||||
|
if(areas.size() > 0)
|
||||||
|
{
|
||||||
|
newParam.areas = 0;
|
||||||
|
if(areas.find("body") != std::string::npos) newParam.areas |= BoxRenderParams::BODY;
|
||||||
|
if(areas.find("top") != std::string::npos) newParam.areas |= BoxRenderParams::TOP;
|
||||||
|
if(areas.find("bottom") != std::string::npos) newParam.areas |= BoxRenderParams::BOTTOM;
|
||||||
|
if(areas.find("left") != std::string::npos) newParam.areas |= BoxRenderParams::LEFT;
|
||||||
|
if(areas.find("right") != std::string::npos) newParam.areas |= BoxRenderParams::RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_render_params[type+"::"+state] = newParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parseColor(const XMLNode* node)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadFromFile(std::string file)
|
||||||
|
{
|
||||||
|
XMLNode* root = file_manager->createXMLTree(file);
|
||||||
|
const int amount = root->getNumNodes();
|
||||||
|
for(int i=0; i<amount; i++)
|
||||||
|
{
|
||||||
|
const XMLNode* node = root->getNode(i);
|
||||||
|
|
||||||
|
if(node->getName() == "element")
|
||||||
|
{
|
||||||
|
parseElement(node);
|
||||||
|
}
|
||||||
|
else if(node->getName() == "color")
|
||||||
|
{
|
||||||
|
parseColor(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Unknown node in XML file : " << node->getName().c_str() << std::endl;
|
||||||
|
}
|
||||||
|
}// nend for
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Skin::Skin(IGUISkin* fallback_skin)
|
Skin::Skin(IGUISkin* fallback_skin)
|
||||||
{
|
{
|
||||||
|
SkinConfig::loadFromFile(file_manager->getGUIDir() + "/glass.stkskin" );
|
||||||
|
|
||||||
m_fallback_skin = fallback_skin;
|
m_fallback_skin = fallback_skin;
|
||||||
m_fallback_skin->grab();
|
m_fallback_skin->grab();
|
||||||
assert(fallback_skin != NULL);
|
assert(fallback_skin != NULL);
|
||||||
|
|
||||||
|
|
||||||
m_tex_button = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glassbutton.png").c_str() );
|
|
||||||
m_tex_fbutton = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glassbutton_focused.png").c_str() );
|
|
||||||
|
|
||||||
m_tex_spinner = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glassspinner.png").c_str() );
|
|
||||||
m_tex_fspinner = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glassspinner_focus.png").c_str() );
|
|
||||||
m_tex_dspinner = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glassspinner_down.png").c_str() );
|
|
||||||
|
|
||||||
m_tex_tab = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasstab.png").c_str() );
|
|
||||||
m_tex_ftab = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasstab_focus.png").c_str() );
|
|
||||||
m_tex_dtab = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasstab_down.png").c_str() );
|
|
||||||
|
|
||||||
m_tex_ficonhighlight = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glass_iconhighlight_focus.png").c_str() );
|
m_tex_ficonhighlight = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glass_iconhighlight_focus.png").c_str() );
|
||||||
m_tex_squarefocus = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glass_square_focused.png").c_str() );
|
|
||||||
|
|
||||||
m_tex_gaugefill = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasssgauge_fill.png").c_str() );
|
m_tex_gaugefill = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasssgauge_fill.png").c_str() );
|
||||||
|
|
||||||
m_tex_bubble = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/bubble.png").c_str() );
|
m_tex_bubble = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/bubble.png").c_str() );
|
||||||
|
|
||||||
m_tex_checkbox = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasscheckbox.png").c_str() );
|
|
||||||
m_tex_fcheckbox = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasscheckbox_focus.png").c_str() );
|
|
||||||
m_tex_dcheckbox = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasscheckbox_checked.png").c_str() );
|
|
||||||
m_tex_dfcheckbox = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glasscheckbox_checked_focus.png").c_str() );
|
|
||||||
|
|
||||||
m_tex_section = GUIEngine::getDriver()->getTexture( (file_manager->getGUIDir() + "/glass_section.png").c_str() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Skin::~Skin()
|
Skin::~Skin()
|
||||||
@ -65,8 +146,9 @@ BoxRenderParams::BoxRenderParams()
|
|||||||
vertical_flip = false;
|
vertical_flip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skin::drawBoxFromStretchableTexture(const core::rect< s32 > &dest, ITexture* source, const BoxRenderParams& params)
|
void Skin::drawBoxFromStretchableTexture(const core::rect< s32 > &dest, const BoxRenderParams& params)
|
||||||
{
|
{
|
||||||
|
ITexture* source = params.image;
|
||||||
const int left_border = params.left_border;
|
const int left_border = params.left_border;
|
||||||
const int right_border = params.right_border;
|
const int right_border = params.right_border;
|
||||||
const int top_border = params.top_border;
|
const int top_border = params.top_border;
|
||||||
@ -309,46 +391,14 @@ X.LowerRightCorner.Y = y1;}
|
|||||||
|
|
||||||
void Skin::drawButton(const core::rect< s32 > &rect, const bool pressed, const bool focused)
|
void Skin::drawButton(const core::rect< s32 > &rect, const bool pressed, const bool focused)
|
||||||
{
|
{
|
||||||
static BoxRenderParams params;
|
if(focused)
|
||||||
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["button::focused"]);
|
||||||
// FIXME - move these numbers to a config file
|
else
|
||||||
params.left_border = 80;
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["button::neutral"]);
|
||||||
params.right_border = 80;
|
|
||||||
params.top_border = 0;
|
|
||||||
params.bottom_border = 36;
|
|
||||||
|
|
||||||
params.preserve_h_aspect_ratios = true;
|
|
||||||
|
|
||||||
drawBoxFromStretchableTexture(rect, (focused ? m_tex_fbutton : m_tex_button), params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skin::drawRibbon(const core::rect< s32 > &rect, const Widget* widget, const bool pressed, bool focused)
|
void Skin::drawRibbon(const core::rect< s32 > &rect, const Widget* widget, const bool pressed, bool focused)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
// only combo ribbons need a border
|
|
||||||
if ( ((RibbonWidget*)widget)->getRibbonType() != RIBBON_COMBO ) return;
|
|
||||||
|
|
||||||
bool draw_border = focused;
|
|
||||||
|
|
||||||
// check if one of its children has focus (will happen when directly clicking on them)
|
|
||||||
const int amount = widget->m_children.size();
|
|
||||||
for(int n=0; n<amount; n++)
|
|
||||||
{
|
|
||||||
if(GUIEngine::getGUIEnv()->hasFocus(widget->m_children[n].m_element))
|
|
||||||
{
|
|
||||||
draw_border = true;
|
|
||||||
focused = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!draw_border) return;
|
|
||||||
|
|
||||||
if(focused)
|
|
||||||
GUIEngine::getDriver()->draw2DRectangle( SColor(255, 150, 0, 0), rect );
|
|
||||||
else
|
|
||||||
GUIEngine::getDriver()->draw2DRectangle( SColor(255, 0, 150, 0), rect );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skin::drawRibbonChild(const core::rect< s32 > &rect, const Widget* widget, const bool pressed, bool focused)
|
void Skin::drawRibbonChild(const core::rect< s32 > &rect, const Widget* widget, const bool pressed, bool focused)
|
||||||
@ -363,30 +413,21 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, const Widget* widget,
|
|||||||
/* tab-bar ribbons */
|
/* tab-bar ribbons */
|
||||||
if(type == RIBBON_TABS)
|
if(type == RIBBON_TABS)
|
||||||
{
|
{
|
||||||
// ribbons containing buttons are actually tabs
|
BoxRenderParams* params;
|
||||||
|
|
||||||
|
if(mark_selected && (focused || parent_focused))
|
||||||
|
params = &SkinConfig::m_render_params["tab::focused"];
|
||||||
|
else if(mark_selected)
|
||||||
|
params = &SkinConfig::m_render_params["tab::down"];
|
||||||
|
else
|
||||||
|
params = &SkinConfig::m_render_params["tab::neutral"];
|
||||||
|
|
||||||
static BoxRenderParams params;
|
|
||||||
// FIXME - specify in file, don't hardcode
|
|
||||||
params.left_border = 75;
|
|
||||||
params.right_border = 75;
|
|
||||||
params.top_border = 0;
|
|
||||||
params.bottom_border = 15;
|
|
||||||
|
|
||||||
// automatically guess from position on-screen if tabs go up or down
|
// automatically guess from position on-screen if tabs go up or down
|
||||||
const bool vertical_flip = rect.UpperLeftCorner.Y < GUIEngine::getDriver()->getCurrentRenderTargetSize().Height/2;
|
const bool vertical_flip = rect.UpperLeftCorner.Y < GUIEngine::getDriver()->getCurrentRenderTargetSize().Height/2;
|
||||||
float portion_out = 0.2f;
|
params->vertical_flip = vertical_flip;
|
||||||
|
|
||||||
/* when not using plain buttons, it's probably icons, so we need more space */
|
|
||||||
if(widget->m_type != WTYPE_BUTTON)
|
|
||||||
{
|
|
||||||
//border_below = 40;
|
|
||||||
}
|
|
||||||
|
|
||||||
core::rect< s32 > rect2 = rect;
|
core::rect< s32 > rect2 = rect;
|
||||||
|
|
||||||
params.hborder_out_portion = portion_out;
|
|
||||||
params.vertical_flip = vertical_flip;
|
|
||||||
|
|
||||||
if (mark_selected)
|
if (mark_selected)
|
||||||
{
|
{
|
||||||
// selected tab should be slighlty bigger than others
|
// selected tab should be slighlty bigger than others
|
||||||
@ -394,24 +435,11 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, const Widget* widget,
|
|||||||
rect2.UpperLeftCorner.Y -= 10;
|
rect2.UpperLeftCorner.Y -= 10;
|
||||||
else
|
else
|
||||||
rect2.LowerRightCorner.Y += 10;
|
rect2.LowerRightCorner.Y += 10;
|
||||||
|
|
||||||
drawBoxFromStretchableTexture(rect2, (focused || parent_focused ? m_tex_ftab : m_tex_dtab), params);
|
|
||||||
|
|
||||||
/*
|
|
||||||
GUIEngine::getDriver()->draw2DLine( core::position2d< s32 >(rect2.UpperLeftCorner.X,rect2.LowerRightCorner.Y),
|
|
||||||
core::position2d< s32 >(rect2.LowerRightCorner.X,rect2.LowerRightCorner.Y),
|
|
||||||
SColor(255,255,0,0) );
|
|
||||||
GUIEngine::getDriver()->draw2DLine( core::position2d< s32 >(rect2.UpperLeftCorner.X,rect2.UpperLeftCorner.Y),
|
|
||||||
core::position2d< s32 >(rect2.LowerRightCorner.X,rect2.UpperLeftCorner.Y),
|
|
||||||
SColor(255,255,0,0) );
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
drawBoxFromStretchableTexture(rect2, m_tex_tab, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawBoxFromStretchableTexture(rect2, *params);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/* icon ribbons */
|
/* icon ribbons */
|
||||||
else
|
else
|
||||||
@ -448,6 +476,7 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, const Widget* widget,
|
|||||||
|
|
||||||
core::rect<s32> source_area = core::rect<s32>(0, 0, texture_w, texture_h);
|
core::rect<s32> source_area = core::rect<s32>(0, 0, texture_w, texture_h);
|
||||||
|
|
||||||
|
// TODO : read from skin file
|
||||||
GUIEngine::getDriver()->draw2DImage(m_tex_bubble, rect2, source_area,
|
GUIEngine::getDriver()->draw2DImage(m_tex_bubble, rect2, source_area,
|
||||||
0 /* no clipping */, 0, true /* alpha */);
|
0 /* no clipping */, 0, true /* alpha */);
|
||||||
}
|
}
|
||||||
@ -482,6 +511,7 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, const Widget* widget,
|
|||||||
glow_center_x + 45 + grow,
|
glow_center_x + 45 + grow,
|
||||||
glow_center_y + 25 + grow/2);
|
glow_center_y + 25 + grow/2);
|
||||||
|
|
||||||
|
// TODO : read from skin file
|
||||||
GUIEngine::getDriver()->draw2DImage(m_tex_ficonhighlight, rect2, source_area,
|
GUIEngine::getDriver()->draw2DImage(m_tex_ficonhighlight, rect2, source_area,
|
||||||
0 /* no clipping */, 0, true /* alpha */);
|
0 /* no clipping */, 0, true /* alpha */);
|
||||||
}
|
}
|
||||||
@ -492,19 +522,11 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, const Widget* widget,
|
|||||||
|
|
||||||
if(!always_show_selection && !show_focus) return;
|
if(!always_show_selection && !show_focus) return;
|
||||||
|
|
||||||
const int texture_w = m_tex_squarefocus->getSize().Width;
|
//const int texture_w = m_tex_squarefocus->getSize().Width;
|
||||||
const int texture_h = m_tex_squarefocus->getSize().Height;
|
//const int texture_h = m_tex_squarefocus->getSize().Height;
|
||||||
|
//core::rect<s32> source_area = core::rect<s32>(0, 0, texture_w, texture_h);
|
||||||
|
|
||||||
core::rect<s32> source_area = core::rect<s32>(0, 0, texture_w, texture_h);
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["squareSelectionHalo::neutral"]);
|
||||||
|
|
||||||
static BoxRenderParams params;
|
|
||||||
params.left_border = 6;
|
|
||||||
params.right_border = 6;
|
|
||||||
params.top_border = 6;
|
|
||||||
params.bottom_border = 6;
|
|
||||||
params.hborder_out_portion = 1.0;
|
|
||||||
|
|
||||||
drawBoxFromStretchableTexture(rect, m_tex_squarefocus, params);
|
|
||||||
}
|
}
|
||||||
} // end if mark_focused
|
} // end if mark_focused
|
||||||
|
|
||||||
@ -530,25 +552,15 @@ void Skin::drawSpinnerBody(const core::rect< s32 > &rect, const Widget* widget,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BoxRenderParams params;
|
|
||||||
// FIXME - move these numbers to a config file
|
|
||||||
params.left_border = 110;
|
|
||||||
params.right_border = 110;
|
|
||||||
params.top_border = 0;
|
|
||||||
params.bottom_border = 36;
|
|
||||||
|
|
||||||
params.preserve_h_aspect_ratios = true;
|
BoxRenderParams& params = (focused || pressed) ? SkinConfig::m_render_params["spinner::focused"] :
|
||||||
params.hborder_out_portion = 0.0f;
|
SkinConfig::m_render_params["spinner::neutral"];
|
||||||
|
drawBoxFromStretchableTexture(rect, params);
|
||||||
drawBoxFromStretchableTexture(rect, (focused || pressed ? m_tex_fspinner : m_tex_spinner), params);
|
|
||||||
|
|
||||||
const SpinnerWidget* w = dynamic_cast<const SpinnerWidget*>(widget);
|
const SpinnerWidget* w = dynamic_cast<const SpinnerWidget*>(widget);
|
||||||
if( w->isGauge() )
|
if( w->isGauge() )
|
||||||
{
|
{
|
||||||
// the width of an handle is about 0.84 the height in the current skin. FIXME - don't hardcode.
|
const int handle_size = (int)( widget->h*params.left_border/(float)params.image->getSize().Height );
|
||||||
const int handle_size = (int)( widget->h*0.84f );
|
|
||||||
|
|
||||||
|
|
||||||
const float value = (float)(w->getValue() - w->getMin()) / (w->getMax() - w->getMin());
|
const float value = (float)(w->getValue() - w->getMin()) / (w->getMax() - w->getMin());
|
||||||
|
|
||||||
|
|
||||||
@ -563,6 +575,7 @@ void Skin::drawSpinnerBody(const core::rect< s32 > &rect, const Widget* widget,
|
|||||||
const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
||||||
|
|
||||||
|
|
||||||
|
// TODO : make configurable through skin config file
|
||||||
GUIEngine::getDriver()->draw2DImage(m_tex_gaugefill, dest_area, source_area,
|
GUIEngine::getDriver()->draw2DImage(m_tex_gaugefill, dest_area, source_area,
|
||||||
0 /* no clipping */, 0, true /* alpha */);
|
0 /* no clipping */, 0, true /* alpha */);
|
||||||
|
|
||||||
@ -587,18 +600,10 @@ void Skin::drawSpinnerChild(const core::rect< s32 > &rect, Widget* widget, const
|
|||||||
spinner->x + spinner->w,
|
spinner->x + spinner->w,
|
||||||
spinner->y + spinner->h );
|
spinner->y + spinner->h );
|
||||||
|
|
||||||
static BoxRenderParams params;
|
BoxRenderParams& params = SkinConfig::m_render_params["spinner::down"];
|
||||||
// FIXME - move these numbers to a config file
|
|
||||||
params.left_border = 110;
|
|
||||||
params.right_border = 110;
|
|
||||||
params.top_border = 0;
|
|
||||||
params.bottom_border = 36;
|
|
||||||
|
|
||||||
params.preserve_h_aspect_ratios = true;
|
|
||||||
params.hborder_out_portion = 0.0f;
|
|
||||||
params.areas = areas;
|
params.areas = areas;
|
||||||
|
drawBoxFromStretchableTexture(rect, params);
|
||||||
|
|
||||||
drawBoxFromStretchableTexture(rect2, m_tex_dspinner, params);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,72 +613,44 @@ void Skin::drawCheckBox(const core::rect< s32 > &rect, Widget* widget, bool focu
|
|||||||
{
|
{
|
||||||
CheckBoxWidget* w = dynamic_cast<CheckBoxWidget*>(widget);
|
CheckBoxWidget* w = dynamic_cast<CheckBoxWidget*>(widget);
|
||||||
|
|
||||||
const int texture_w = m_tex_checkbox->getSize().Width;
|
ITexture* texture;
|
||||||
const int texture_h = m_tex_checkbox->getSize().Height;
|
|
||||||
|
|
||||||
const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(w->getState() == true)
|
if(w->getState() == true)
|
||||||
{
|
{
|
||||||
GUIEngine::getDriver()->draw2DImage( focused ? m_tex_dfcheckbox : m_tex_dcheckbox, rect, source_area,
|
if(focused)
|
||||||
0 /* no clipping */, 0, true /* alpha */);
|
texture = SkinConfig::m_render_params["checkbox::focused+checked"].image;
|
||||||
|
else
|
||||||
|
texture = SkinConfig::m_render_params["checkbox::neutral+checked"].image;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUIEngine::getDriver()->draw2DImage( focused ? m_tex_fcheckbox : m_tex_checkbox, rect, source_area,
|
if(focused)
|
||||||
0 /* no clipping */, 0, true /* alpha */);
|
texture = SkinConfig::m_render_params["checkbox::focused+unchecked"].image;
|
||||||
|
else
|
||||||
|
texture = SkinConfig::m_render_params["checkbox::neutral+unchecked"].image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int texture_w = texture->getSize().Width;
|
||||||
|
const int texture_h = texture->getSize().Height;
|
||||||
|
|
||||||
|
const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h);
|
||||||
|
|
||||||
|
GUIEngine::getDriver()->draw2DImage( texture, rect, source_area,
|
||||||
|
0 /* no clipping */, 0, true /* alpha */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Skin::drawList(const core::rect< s32 > &rect, Widget* widget, bool focused)
|
void Skin::drawList(const core::rect< s32 > &rect, Widget* widget, bool focused)
|
||||||
{
|
{
|
||||||
static BoxRenderParams params;
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["list::neutral"]);
|
||||||
params.left_border = 15;
|
|
||||||
params.right_border = 15;
|
|
||||||
params.top_border = 15;
|
|
||||||
params.bottom_border = 15;
|
|
||||||
|
|
||||||
params.hborder_out_portion = 1.0;
|
|
||||||
params.vborder_out_portion = 1.0f;
|
|
||||||
|
|
||||||
drawBoxFromStretchableTexture( rect, m_tex_section, params );
|
|
||||||
}
|
}
|
||||||
void Skin::drawListSelection(const core::rect< s32 > &rect, Widget* widget, bool focused)
|
void Skin::drawListSelection(const core::rect< s32 > &rect, Widget* widget, bool focused)
|
||||||
{
|
{
|
||||||
// focused render params
|
|
||||||
static BoxRenderParams focusparams;
|
|
||||||
focusparams.left_border = 0;
|
|
||||||
focusparams.right_border = 0;
|
|
||||||
focusparams.top_border = 0;
|
|
||||||
focusparams.bottom_border = 0;
|
|
||||||
|
|
||||||
focusparams.hborder_out_portion = 0.0f;
|
|
||||||
focusparams.vborder_out_portion = 0.0f;
|
|
||||||
|
|
||||||
// non-focused render params
|
|
||||||
static BoxRenderParams params;
|
|
||||||
params.left_border = 80;
|
|
||||||
params.right_border = 80;
|
|
||||||
params.top_border = 0;
|
|
||||||
params.bottom_border = 36;
|
|
||||||
|
|
||||||
params.preserve_h_aspect_ratios = true;
|
|
||||||
params.areas = BoxRenderParams::BODY;
|
|
||||||
params.hborder_out_portion = 1.0f;
|
|
||||||
params.vborder_out_portion = 1.0f;
|
|
||||||
|
|
||||||
// adjust render area
|
|
||||||
core::rect< s32 > rect2 = rect;
|
|
||||||
rect2.UpperLeftCorner.X -= 10;
|
|
||||||
rect2.LowerRightCorner.X += 10;
|
|
||||||
|
|
||||||
if(focused)
|
if(focused)
|
||||||
drawBoxFromStretchableTexture( rect2, m_tex_gaugefill, focusparams );
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["listitem::focused"]);
|
||||||
else
|
else
|
||||||
drawBoxFromStretchableTexture( rect2, m_tex_button, params );
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["listitem::down"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** recusrive function to render all sections (recursion allows to easily travesre the tree of children and sub-children) */
|
/** recusrive function to render all sections (recursion allows to easily travesre the tree of children and sub-children) */
|
||||||
@ -692,29 +669,7 @@ void Skin::renderSections(ptr_vector<Widget>* within_vector)
|
|||||||
if(widget.m_show_bounding_box)
|
if(widget.m_show_bounding_box)
|
||||||
{
|
{
|
||||||
core::rect< s32 > rect = core::rect<s32>( widget.x, widget.y, widget.x + widget.w, widget.y + widget.h );
|
core::rect< s32 > rect = core::rect<s32>( widget.x, widget.y, widget.x + widget.w, widget.y + widget.h );
|
||||||
//getDriver()->draw2DImage(g_skin->m_tex_section, rect, source_area,
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["section::neutral"]);
|
||||||
// 0 /* no clipping */, 0, true /* alpha */);
|
|
||||||
|
|
||||||
static BoxRenderParams params;
|
|
||||||
params.left_border = 15;
|
|
||||||
params.right_border = 15;
|
|
||||||
params.top_border = 15;
|
|
||||||
params.bottom_border = 15;
|
|
||||||
|
|
||||||
params.hborder_out_portion = 1.0;
|
|
||||||
params.vborder_out_portion = 0.2f;
|
|
||||||
|
|
||||||
drawBoxFromStretchableTexture( rect, m_tex_section, params );
|
|
||||||
|
|
||||||
/*
|
|
||||||
void drawBoxFromStretchableTexture(const core::rect< s32 > &dest, ITexture* source,
|
|
||||||
const int left_border, const int right_border,
|
|
||||||
const int top_border, const int bottom_border,
|
|
||||||
const bool preserve_h_aspect_ratios=false,
|
|
||||||
const float hborder_out_portion = 0.5,
|
|
||||||
int areas = BODY | LEFT | RIGHT | TOP | BOTTOM,
|
|
||||||
const bool vertical_flip=false);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -831,23 +786,9 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor, bool f
|
|||||||
|
|
||||||
core::rect< s32 > Skin::draw3DWindowBackground (IGUIElement *element, bool drawTitleBar, video::SColor titleBarColor, const core::rect< s32 > &rect, const core::rect< s32 > *clip)
|
core::rect< s32 > Skin::draw3DWindowBackground (IGUIElement *element, bool drawTitleBar, video::SColor titleBarColor, const core::rect< s32 > &rect, const core::rect< s32 > *clip)
|
||||||
{
|
{
|
||||||
// fade out background
|
|
||||||
GUIEngine::getDriver()->draw2DRectangle( SColor(150, 255, 255, 255),
|
|
||||||
core::rect< s32 >(position2d< s32 >(0,0) , GUIEngine::getDriver()->getCurrentRenderTargetSize()) );
|
|
||||||
|
|
||||||
static BoxRenderParams params;
|
|
||||||
params.left_border = 15;
|
|
||||||
params.right_border = 15;
|
|
||||||
params.top_border = 15;
|
|
||||||
params.bottom_border = 15;
|
|
||||||
|
|
||||||
params.hborder_out_portion = 1.0;
|
|
||||||
params.vborder_out_portion = 0.2f;
|
|
||||||
|
|
||||||
// draw frame (since it's transluscent, draw many times to get opacity)
|
// draw frame (since it's transluscent, draw many times to get opacity)
|
||||||
drawBoxFromStretchableTexture(rect, m_tex_section, params);
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["window::neutral"]);
|
||||||
drawBoxFromStretchableTexture(rect, m_tex_section, params);
|
drawBoxFromStretchableTexture(rect, SkinConfig::m_render_params["window::neutral"]);
|
||||||
|
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ namespace GUIEngine
|
|||||||
class BoxRenderParams
|
class BoxRenderParams
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
ITexture* image;
|
||||||
int left_border, right_border, top_border, bottom_border;
|
int left_border, right_border, top_border, bottom_border;
|
||||||
bool preserve_h_aspect_ratios;
|
bool preserve_h_aspect_ratios;
|
||||||
float hborder_out_portion, vborder_out_portion;
|
float hborder_out_portion, vborder_out_portion;
|
||||||
@ -41,26 +42,13 @@ namespace GUIEngine
|
|||||||
{
|
{
|
||||||
IGUISkin* m_fallback_skin;
|
IGUISkin* m_fallback_skin;
|
||||||
|
|
||||||
/* f : focused; d : down state */
|
|
||||||
ITexture* m_tex_button;
|
|
||||||
ITexture* m_tex_fbutton;
|
|
||||||
ITexture* m_tex_spinner;
|
|
||||||
ITexture* m_tex_fspinner;
|
|
||||||
ITexture* m_tex_dspinner;
|
|
||||||
ITexture* m_tex_tab;
|
|
||||||
ITexture* m_tex_ftab;
|
|
||||||
ITexture* m_tex_dtab;
|
|
||||||
ITexture* m_tex_ficonhighlight;
|
ITexture* m_tex_ficonhighlight;
|
||||||
ITexture* m_tex_bubble;
|
ITexture* m_tex_bubble;
|
||||||
ITexture* m_tex_squarefocus;
|
|
||||||
ITexture* m_tex_gaugefill;
|
ITexture* m_tex_gaugefill;
|
||||||
|
|
||||||
ITexture* m_tex_checkbox;
|
|
||||||
ITexture* m_tex_fcheckbox;
|
|
||||||
ITexture* m_tex_dcheckbox;
|
|
||||||
ITexture* m_tex_dfcheckbox;
|
|
||||||
|
|
||||||
void drawBoxFromStretchableTexture(const core::rect< s32 > &dest, ITexture* source, const BoxRenderParams& params);
|
void drawBoxFromStretchableTexture(const core::rect< s32 > &dest, const BoxRenderParams& params);
|
||||||
|
|
||||||
// my utility methods, to work around irrlicht's very Windows-95-like-look-enforcing skin system
|
// my utility methods, to work around irrlicht's very Windows-95-like-look-enforcing skin system
|
||||||
void process3DPane(IGUIElement *element, const core::rect< s32 > &rect, const bool pressed);
|
void process3DPane(IGUIElement *element, const core::rect< s32 > &rect, const bool pressed);
|
||||||
@ -76,8 +64,6 @@ namespace GUIEngine
|
|||||||
void drawListSelection(const core::rect< s32 > &rect, Widget* widget, bool focused);
|
void drawListSelection(const core::rect< s32 > &rect, Widget* widget, bool focused);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ITexture* m_tex_section;
|
|
||||||
|
|
||||||
Skin(IGUISkin* fallback_skin);
|
Skin(IGUISkin* fallback_skin);
|
||||||
~Skin();
|
~Skin();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user