// SuperTuxKart - a fun racing game with go-kart // Copyright (C) 2009 Marianne Gagnon // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 3 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config/user_config.hpp" #include "guiengine/skin.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" #include "guiengine/screen.hpp" #include "guiengine/widget.hpp" #include "io/file_manager.hpp" #include #include using namespace GUIEngine; using namespace irr; using namespace core; using namespace scene; using namespace video; using namespace io; using namespace gui; const bool ID_DEBUG = false; /** * Small utility to read config file info from a XML file. */ namespace SkinConfig { static std::map m_render_params; static std::map m_colors; 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; 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; // call last since it calculates coords considering all other parameters newParam.setTexture( irr_driver->getTexture( (file_manager->getGUIDir() + "/skins/" + image).c_str() ) ); 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) { std::string type; std::string state = "neutral"; int r = 0, g = 0, b = 0; if(node->get("type", &type) == 0) { std::cerr << "Error in skin : All elements must have a type\n"; return; } node->get("state", &state); node->get("r", &r); node->get("g", &g); node->get("b", &b); int a = 255; node->get("a", &a); SColor color = SColor(a, r, g, b); m_colors[type+"::"+state] = color; } static void loadFromFile(std::string file) { XMLNode* root = file_manager->createXMLTree(file); if(!root) { std::cerr << "Could not read XML file " << file.c_str() << std::endl; } const int amount = root->getNumNodes(); for (int i=0; igetNode(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 delete root; } }; #if 0 #pragma mark - #endif /** load default values */ BoxRenderParams::BoxRenderParams() { left_border = 0; right_border = 0; top_border = 0; bottom_border = 0; preserve_h_aspect_ratios = false; hborder_out_portion = 0.5; vborder_out_portion = 1.0; areas = BODY | LEFT | RIGHT | TOP | BOTTOM; vertical_flip = false; y_flip_set = false; } void BoxRenderParams::setTexture(ITexture* image) { this->image = image; /* The source texture is split this way to allow for a stretchable center and borders that don't stretch : +----+--------------------+----+ | | | | +----a--------------------b----+ <-- top_border | | | | | | | | +----c--------------------d----+ <-- height - bottom-border | | | | +----+--------------------+----+ */ const int texture_w = image->getSize().Width; const int texture_h = image->getSize().Height; const int ax = left_border; const int ay = top_border; const int bx = texture_w - right_border; const int by = top_border; const int cx = left_border; const int cy = texture_h - bottom_border; const int dx = texture_w - right_border; const int dy = texture_h - bottom_border; source_area_left = core::rect(0, ay, cx, cy); source_area_center = core::rect(ax, ay, dx, dy); source_area_right = core::rect(bx, top_border, texture_w, dy); source_area_top = core::rect(ax, 0, bx, by); source_area_bottom = core::rect(cx, cy, dx, texture_h); source_area_top_left = core::rect(0, 0, ax, ay); source_area_top_right = core::rect(bx, 0, texture_w, top_border); source_area_bottom_left = core::rect(0, cy, cx, texture_h); source_area_bottom_right = core::rect(dx, dy, texture_w, texture_h); } void BoxRenderParams::calculateYFlipIfNeeded() { if(y_flip_set) return; #define FLIP_Y( X ) { const int y1 = X.UpperLeftCorner.Y; \ const int y2 = X.LowerRightCorner.Y; \ X##_yflip = X; \ X##_yflip.UpperLeftCorner.Y = y2;\ X##_yflip.LowerRightCorner.Y = y1;} FLIP_Y(source_area_left) FLIP_Y(source_area_center) FLIP_Y(source_area_right) FLIP_Y(source_area_top) FLIP_Y(source_area_bottom) FLIP_Y(source_area_top_left) FLIP_Y(source_area_top_right) FLIP_Y(source_area_bottom_left) FLIP_Y(source_area_bottom_right) #undef FLIP_Y y_flip_set = true; } #if 0 #pragma mark - #endif Skin::Skin(IGUISkin* fallback_skin) { std::string skin_name = file_manager->getGUIDir(); skin_name += "/skins/"; skin_name += UserConfigParams::m_skin_file.c_str(); SkinConfig::loadFromFile( skin_name ); bg_image = NULL; m_fallback_skin = fallback_skin; m_fallback_skin->grab(); assert(fallback_skin != NULL); m_dialog = false; m_dialog_size = 0.0f; } Skin::~Skin() { m_fallback_skin->drop(); } void Skin::drawBgImage() { // ---- background image // on one end, making these static is not too clean. // on another end, these variables are really only used locally, // and making them static avoids doing the same stupid computations every frame static core::rect dest; static core::rect source_area; if(bg_image == NULL) { int texture_w, texture_h; // TODO/FIXME? - user preferences still include a background image choice bg_image = SkinConfig::m_render_params["background::neutral"].getImage(); assert(bg_image != NULL); texture_w = bg_image->getSize().Width; texture_h = bg_image->getSize().Height; source_area = core::rect(0, 0, texture_w, texture_h); core::dimension2d frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize(); const int screen_w = frame_size.Width; const int screen_h = frame_size.Height; // stretch image vertically to fit float ratio = (float)screen_h / texture_h; // check that with the vertical stretching, it still fits horizontally while(texture_w*ratio < screen_w) ratio += 0.1f; texture_w = (int)(texture_w*ratio); texture_h = (int)(texture_h*ratio); const int clipped_x_space = (texture_w - screen_w); dest = core::rect(-clipped_x_space/2, 0, screen_w+clipped_x_space/2, texture_h); } GUIEngine::getDriver()->draw2DImage(bg_image, dest, source_area, 0 /* no clipping */, 0, false /* alpha */); } void Skin::drawBoxFromStretchableTexture(SkinWidgetContainer* w, const core::rect< s32 > &dest, BoxRenderParams& params, bool deactivated) { // check if widget moved. if so, recalculate coords if(w->x != dest.UpperLeftCorner.X || w->y != dest.UpperLeftCorner.Y || w->w != dest.getWidth() || w->h != dest.getHeight()) { w->dest_areas_inited = false; w->dest_areas_yflip_inited = false; w->x = dest.UpperLeftCorner.X; w->y = dest.UpperLeftCorner.Y; w->w = dest.getWidth(); w->h = dest.getHeight(); //std::cout << "widget moved, calculating again\n"; } const ITexture* source = params.getImage(); const int left_border = params.left_border; const int right_border = params.right_border; const int top_border = params.top_border; const int bottom_border = params.bottom_border; const bool preserve_h_aspect_ratios = params.preserve_h_aspect_ratios; const float hborder_out_portion = params.hborder_out_portion; const float vborder_out_portion = params.vborder_out_portion; int areas = params.areas; const bool vertical_flip = params.vertical_flip; const int texture_h = source->getSize().Height; /* The dest area is split this way. Borders can go a bit beyond the given area so components inside don't go over the borders (how much it exceeds horizontally is specified in 'hborder_out_portion'. vertically is always the totality) a----b--------------------c----+ | | | | d----e--------------------f----g <-- top_border | | | | | | | | | | | | h----i--------------------j----k <-- height - bottom-border | | | | +----l--------------------m----n */ if (!w->dest_areas_inited) { w->dest_x = dest.UpperLeftCorner.X; w->dest_y = dest.UpperLeftCorner.Y; w->dest_x2 = dest.LowerRightCorner.X; w->dest_y2 = dest.LowerRightCorner.Y; //const float xscale = (float)(dest_x2-dest_x)/texture_w; const float yscale = (float)(w->dest_y2 - w->dest_y)/texture_h; int dest_left_border, dest_right_border; // scale and keep aspect ratio if(preserve_h_aspect_ratios) { dest_left_border = (int)(left_border * (w->dest_y2 - w->dest_y) / texture_h ); dest_right_border = (int)(right_border * (w->dest_y2 - w->dest_y) / texture_h); } else { dest_left_border = (int)(left_border *std::min(yscale, 1.0)); dest_right_border = (int)(right_border *std::min(yscale, 1.0)); } int dest_top_border = (int)(top_border *std::min(yscale, 1.0)); int dest_bottom_border = (int)(bottom_border*std::min(yscale, 1.0)); const float hborder_in_portion = 1 - hborder_out_portion; const float vborder_in_portion = 1 - vborder_out_portion; const int ax = (int)(w->dest_x - dest_left_border*hborder_out_portion); const int ay = (int)(w->dest_y - dest_top_border*vborder_out_portion); const int bx = (int)(w->dest_x + dest_left_border*hborder_in_portion); const int by = ay; const int cx = (int)(w->dest_x2 - dest_right_border*hborder_in_portion); const int cy = ay; const int dx = ax; const int dy = (int)(w->dest_y + dest_top_border*vborder_in_portion); const int ex = bx; const int ey = dy; const int fx = cx; const int fy = dy; const int gx = (int)(w->dest_x2 + dest_right_border*hborder_out_portion); const int gy = dy; const int hx = ax; const int hy = (int)(w->dest_y2 - dest_bottom_border*vborder_in_portion); const int ix = bx; const int iy = hy; const int jx = cx; const int jy = hy; const int kx = gx; const int ky = hy; const int lx = bx; const int ly = (int)(w->dest_y2 + dest_bottom_border*vborder_out_portion); const int mx = cx; const int my = ly; const int nx = gx; const int ny = ly; w->dest_area_left = core::rect(dx, dy, ix, iy); w->dest_area_center = core::rect(ex, ey, jx, jy); w->dest_area_right = core::rect(fx, fy, kx, ky); w->dest_area_top = core::rect(bx, by, fx, fy); w->dest_area_bottom = core::rect(ix, iy, mx, my); w->dest_area_top_left = core::rect(ax, ay, ex, ey); w->dest_area_top_right = core::rect(cx, cy, gx, gy); w->dest_area_bottom_left = core::rect(hx, hy, lx, ly); w->dest_area_bottom_right = core::rect(jx, jy, nx, ny); w->dest_areas_inited = true; } if (vertical_flip) { if (!w->dest_areas_yflip_inited) { #define FLIP_Y( X ) { const int y1 = X.UpperLeftCorner.Y - w->dest_y; \ const int y2 = X.LowerRightCorner.Y - w->dest_y; \ X##_yflip = X; \ X##_yflip.UpperLeftCorner.Y = w->dest_y + (w->dest_y2 - w->dest_y) - y2;\ X##_yflip.LowerRightCorner.Y = w->dest_y + (w->dest_y2 - w->dest_y) - y1;} FLIP_Y(w->dest_area_left) FLIP_Y(w->dest_area_center) FLIP_Y(w->dest_area_right) FLIP_Y(w->dest_area_top) FLIP_Y(w->dest_area_bottom) FLIP_Y(w->dest_area_top_left) FLIP_Y(w->dest_area_top_right) FLIP_Y(w->dest_area_bottom_left) FLIP_Y(w->dest_area_bottom_right) #undef FLIP_Y } w->dest_areas_yflip_inited = true; params.calculateYFlipIfNeeded(); } #define GET_AREA( X ) X = (vertical_flip ? params.X##_yflip : params.X) core::rect& GET_AREA(source_area_left); core::rect& GET_AREA(source_area_center); core::rect& GET_AREA(source_area_right); core::rect& GET_AREA(source_area_top); core::rect& GET_AREA(source_area_bottom); core::rect& GET_AREA(source_area_top_left); core::rect& GET_AREA(source_area_top_right); core::rect& GET_AREA(source_area_bottom_left); core::rect& GET_AREA(source_area_bottom_right); #undef GET_AREA #define GET_AREA( X ) X = (vertical_flip ? w->X##_yflip : w->X) core::rect& GET_AREA(dest_area_left); core::rect& GET_AREA(dest_area_center); core::rect& GET_AREA(dest_area_right); core::rect& GET_AREA(dest_area_top); core::rect& GET_AREA(dest_area_bottom); core::rect& GET_AREA(dest_area_top_left); core::rect& GET_AREA(dest_area_top_right); core::rect& GET_AREA(dest_area_bottom_left); core::rect& GET_AREA(dest_area_bottom_right); #undef GET_AREA SColor* colorptr = NULL; // create a color object if ( (w->r != -1 && w->g != -1 && w->b != -1) || ID_DEBUG || deactivated) { SColor thecolor(255, w->r, w->g, w->b); colorptr = new SColor[4](); colorptr[0] = thecolor; colorptr[1] = thecolor; colorptr[2] = thecolor; colorptr[3] = thecolor; } // set it to transluscent if (ID_DEBUG || deactivated) { colorptr[0].setAlpha(100); colorptr[1].setAlpha(100); colorptr[2].setAlpha(100); colorptr[3].setAlpha(100); } if ((areas & BoxRenderParams::LEFT) != 0) { GUIEngine::getDriver()->draw2DImage(source, dest_area_left, source_area_left, 0 /* no clipping */, colorptr, true /* alpha */); } if ((areas & BoxRenderParams::BODY) != 0) { GUIEngine::getDriver()->draw2DImage(source, dest_area_center, source_area_center, 0 /* no clipping */, colorptr, true /* alpha */); } if ((areas & BoxRenderParams::RIGHT) != 0) { GUIEngine::getDriver()->draw2DImage(source, dest_area_right, source_area_right, 0 /* no clipping */, colorptr, true /* alpha */); } if ((areas & BoxRenderParams::TOP) != 0) { GUIEngine::getDriver()->draw2DImage(source, dest_area_top, source_area_top, 0 /* no clipping */, colorptr, true /* alpha */); } if ((areas & BoxRenderParams::BOTTOM) != 0) { GUIEngine::getDriver()->draw2DImage(source, dest_area_bottom, source_area_bottom, 0 /* no clipping */, colorptr, true /* alpha */); } if ( ((areas & BoxRenderParams::LEFT) != 0) && ((areas & BoxRenderParams::TOP) != 0) ) { GUIEngine::getDriver()->draw2DImage(source, dest_area_top_left, source_area_top_left, 0 /* no clipping */, colorptr, true /* alpha */); } if ( ((areas & BoxRenderParams::RIGHT) != 0) && ((areas & BoxRenderParams::TOP) != 0) ) { GUIEngine::getDriver()->draw2DImage(source, dest_area_top_right, source_area_top_right, 0 /* no clipping */, colorptr, true /* alpha */); } if ( ((areas & BoxRenderParams::LEFT) != 0) && ((areas & BoxRenderParams::BOTTOM) != 0) ) { GUIEngine::getDriver()->draw2DImage(source, dest_area_bottom_left, source_area_bottom_left, 0 /* no clipping */, colorptr, true /* alpha */); } if ( ((areas & BoxRenderParams::RIGHT) != 0) && ((areas & BoxRenderParams::BOTTOM) != 0) ) { GUIEngine::getDriver()->draw2DImage(source, dest_area_bottom_right, source_area_bottom_right, 0 /* no clipping */, colorptr, true /* alpha */); } if (colorptr != NULL) { delete[] colorptr; } } void Skin::drawButton(Widget* w, const core::rect< s32 > &rect, const bool pressed, const bool focused) { // if within an appearing dialog, grow if (m_dialog && m_dialog_size < 1.0f && w->m_parent != NULL && w->m_parent->getType() == gui::EGUIET_WINDOW) { core::rect< s32 > sized_rect = rect; core::position2d center = core::position2d(irr_driver->getFrameSize()/2); const float texture_size = sin(m_dialog_size*M_PI*0.5f); sized_rect.UpperLeftCorner.X = center.X + (int)(((int)rect.UpperLeftCorner.X - (int)center.X)*texture_size); sized_rect.UpperLeftCorner.Y = center.Y + (int)(((int)rect.UpperLeftCorner.Y - (int)center.Y)*texture_size); sized_rect.LowerRightCorner.X = center.X + (int)(((int)rect.LowerRightCorner.X - (int)center.X)*texture_size); sized_rect.LowerRightCorner.Y = center.Y + (int)(((int)rect.LowerRightCorner.Y - (int)center.Y)*texture_size); if (focused) { drawBoxFromStretchableTexture(w, sized_rect, SkinConfig::m_render_params["button::focused"], w->m_deactivated); } else { drawBoxFromStretchableTexture(w, sized_rect, SkinConfig::m_render_params["button::neutral"], w->m_deactivated); } } else { if (focused) { drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["button::focused"], w->m_deactivated); } else { drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["button::neutral"], w->m_deactivated); } } } void Skin::drawRibbon(const core::rect< s32 > &rect, Widget* widget, const bool pressed, bool focused) { } void Skin::drawRibbonChild(const core::rect< s32 > &rect, Widget* widget, const bool pressed, bool focused) { //TODO: do something better than hide it when a widget is deactivated? if (widget->m_deactivated) return; const int playerID = 0; // FIXME : don't hardcode player 0 ? bool mark_selected = widget->isSelected(playerID); bool always_show_selection = false; IGUIElement* focusedElem = NULL; if (GUIEngine::getFocusForPlayer(playerID) != NULL) { focusedElem = GUIEngine::getFocusForPlayer(playerID)->getIrrlichtElement(); } const bool parent_focused = (focusedElem == widget->m_event_handler->m_element); RibbonWidget* parentRibbon = (RibbonWidget*)widget->m_event_handler; RibbonType type = parentRibbon->getRibbonType(); /* tab-bar ribbons */ if (type == RIBBON_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"]; // automatically guess from position on-screen if tabs go up or down const bool vertical_flip = (unsigned int)rect.UpperLeftCorner.Y < GUIEngine::getDriver()->getCurrentRenderTargetSize().Height/2; params->vertical_flip = vertical_flip; core::rect< s32 > rect2 = rect; if (mark_selected) { // selected tab should be slighlty bigger than others if (vertical_flip) rect2.UpperLeftCorner.Y -= 10; else rect2.LowerRightCorner.Y += 10; } drawBoxFromStretchableTexture(widget, rect2, *params, parentRibbon->m_deactivated); } /* icon ribbons */ else { bool use_glow = true; if (widget->m_event_handler != NULL && widget->m_event_handler->m_properties[PROP_SQUARE] == "true") use_glow = false; if (widget->m_event_handler != NULL && widget->m_event_handler->m_event_handler != NULL && widget->m_event_handler->m_event_handler->m_properties[PROP_SQUARE] == "true") use_glow = false; /* in combo ribbons, always show selection */ RibbonWidget* parentRibbonWidget = NULL; if (widget->m_event_handler != NULL && widget->m_event_handler->m_type == WTYPE_RIBBON) { parentRibbonWidget = dynamic_cast(widget->m_event_handler); if(parentRibbonWidget->getRibbonType() == RIBBON_COMBO) always_show_selection = true; } const bool mark_focused = focused || (parent_focused && parentRibbonWidget != NULL && parentRibbonWidget->m_mouse_focus == widget) || (mark_selected && !always_show_selection && parent_focused); /* draw "selection bubble" if relevant */ if (always_show_selection && mark_selected) { ITexture* tex_bubble = SkinConfig::m_render_params["selectionHalo::neutral"].getImage(); const int texture_w = tex_bubble->getSize().Width; const int texture_h = tex_bubble->getSize().Height; const float aspectRatio = (float)texture_w / (float)texture_h; core::rect source_area = core::rect(0, 0, texture_w, texture_h); const float outgrow = 0.35f; // make slightly bigger than the icon it's on const int rectHeight = (int)(rect.getHeight() * (1.0f + outgrow)); const int rectWidth = (int)(rectHeight * aspectRatio); const int x_gap = (rect.getWidth() - rectWidth)/2; const int y_shift_up = (int)(rect.getHeight() * (outgrow/2.0f)); core::rect< s32 > rect2( position2d< s32 >(rect.UpperLeftCorner.X + x_gap, rect.UpperLeftCorner.Y - y_shift_up), dimension2d< s32 >(rectWidth, rectHeight) ); GUIEngine::getDriver()->draw2DImage(tex_bubble, rect2, source_area, 0 /* no clipping */, 0, true /* alpha */); } // if multiple player selected the same ribbon item, we need to know to make it visible int nPlayersOnThisItem = 0; if (mark_focused) { if (use_glow) { int grow = 45; static float glow_effect = 0; const float dt = GUIEngine::getLatestDt(); glow_effect += dt*3; if (glow_effect > 6.2832f /* 2*PI */) glow_effect -= 6.2832f; grow = (int)(45 + 10*sin(glow_effect)); const int glow_center_x = rect.UpperLeftCorner.X + rect.getWidth()/2; const int glow_center_y = rect.UpperLeftCorner.Y + rect.getHeight() - 5; ITexture* tex_ficonhighlight = SkinConfig::m_render_params["focusHalo::neutral"].getImage(); const int texture_w = tex_ficonhighlight->getSize().Width; const int texture_h = tex_ficonhighlight->getSize().Height; core::rect source_area = core::rect(0, 0, texture_w, texture_h); const core::rect< s32 > rect2 = core::rect< s32 >(glow_center_x - 45 - grow, glow_center_y - 25 - grow/2, glow_center_x + 45 + grow, glow_center_y + 25 + grow/2); GUIEngine::getDriver()->draw2DImage(tex_ficonhighlight, rect2, source_area, 0 /* no clipping */, 0, true /* alpha */); } // if we're not using glow, draw square focus instead else { const bool show_focus = (focused || parent_focused); if (!always_show_selection && !show_focus) return; // don't mark filler items as focused if (widget->m_properties[PROP_ID] == DynamicRibbonWidget::NO_ITEM_ID) return; //const int texture_w = m_tex_squarefocus->getSize().Width; //const int texture_h = m_tex_squarefocus->getSize().Height; //core::rect source_area = core::rect(0, 0, texture_w, texture_h); drawBoxFromStretchableTexture(parentRibbonWidget, rect, SkinConfig::m_render_params["squareFocusHalo::neutral"]); nPlayersOnThisItem++; } } // end if mark_focused // ---- Draw selection for other players than player 1 //if (parentRibbon->isFocusedForPlayer(1)) //{ //std::cout << //parentRibbon->getSelectionIDString(1) << " vs " << widget->m_properties[PROP_ID].c_str() << std::endl; //} if (parentRibbon->isFocusedForPlayer(1) && parentRibbon->getSelectionIDString(1) == widget->m_properties[PROP_ID]) { if (nPlayersOnThisItem > 0) { // TODO: use the same stretching got players 2, 3, etc. core::rect< s32 > rect2 = rect; const int enlarge = nPlayersOnThisItem*6; rect2.UpperLeftCorner.X -= enlarge; rect2.UpperLeftCorner.Y -= enlarge; rect2.LowerRightCorner.X += enlarge; rect2.LowerRightCorner.Y += enlarge; drawBoxFromStretchableTexture(parentRibbonWidget, rect2, SkinConfig::m_render_params["squareFocusHalo2::neutral"]); } else { drawBoxFromStretchableTexture(parentRibbonWidget, rect, SkinConfig::m_render_params["squareFocusHalo2::neutral"]); } nPlayersOnThisItem++; } if (parentRibbon->isFocusedForPlayer(2) && parentRibbon->getSelectionIDString(2) == widget->m_properties[PROP_ID]) { drawBoxFromStretchableTexture(parentRibbonWidget, rect, SkinConfig::m_render_params["squareFocusHalo3::neutral"]); nPlayersOnThisItem++; } if (parentRibbon->isFocusedForPlayer(3) && parentRibbon->getSelectionIDString(3) == widget->m_properties[PROP_ID]) { drawBoxFromStretchableTexture(parentRibbonWidget, rect, SkinConfig::m_render_params["squareFocusHalo4::neutral"]); } drawIconButton(rect, widget, pressed, focused); } // end if icon ribbons } void Skin::drawSpinnerBody(const core::rect< s32 > &rect, Widget* widget, const bool pressed, bool focused) { if (!focused) { IGUIElement* focused_widget = NULL; const int playerID = 0; if (GUIEngine::getFocusForPlayer(playerID) != NULL) { focused_widget = GUIEngine::getFocusForPlayer(playerID)->getIrrlichtElement(); } if (focused_widget != NULL && widget->m_children.size()>2) { if (widget->m_children[0].id == focused_widget->getID() || widget->m_children[1].id == focused_widget->getID() || widget->m_children[2].id == focused_widget->getID()) { focused = true; } } } BoxRenderParams& params = (focused || pressed) ? SkinConfig::m_render_params["spinner::focused"] : SkinConfig::m_render_params["spinner::neutral"]; if (widget->isFocusedForPlayer(1)) { core::rect< s32 > rect2 = rect; rect2.UpperLeftCorner.X += 2; rect2.UpperLeftCorner.Y -= 3; rect2.LowerRightCorner.X -= 2; rect2.LowerRightCorner.Y += 5; drawBoxFromStretchableTexture(widget, rect2, SkinConfig::m_render_params["squareFocusHalo2::neutral"]); } else if (widget->isFocusedForPlayer(2)) { core::rect< s32 > rect2 = rect; rect2.UpperLeftCorner.X += 2; rect2.UpperLeftCorner.Y -= 3; rect2.LowerRightCorner.X -= 2; rect2.LowerRightCorner.Y += 5; drawBoxFromStretchableTexture(widget, rect2, SkinConfig::m_render_params["squareFocusHalo3::neutral"]); } else if (widget->isFocusedForPlayer(3)) { core::rect< s32 > rect2 = rect; rect2.UpperLeftCorner.X += 2; rect2.UpperLeftCorner.Y -= 3; rect2.LowerRightCorner.X -= 2; rect2.LowerRightCorner.Y += 5; drawBoxFromStretchableTexture(widget, rect2, SkinConfig::m_render_params["squareFocusHalo4::neutral"]); } core::rect< s32 > sized_rect = rect; if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL && widget->m_parent->getType() == gui::EGUIET_WINDOW) { core::position2d center = core::position2d(irr_driver->getFrameSize()/2); const float texture_size = sin(m_dialog_size*M_PI*0.5f); sized_rect.UpperLeftCorner.X = center.X + (int)(((int)rect.UpperLeftCorner.X - (int)center.X)*texture_size); sized_rect.UpperLeftCorner.Y = center.Y + (int)(((int)rect.UpperLeftCorner.Y - (int)center.Y)*texture_size); //std::cout << "y is " << center.Y << " + (" << rect.UpperLeftCorner.Y << " - " << center.Y << ")*" << texture_size << " = " // << center.Y + (int)((rect.UpperLeftCorner.Y - center.Y)*texture_size) << std::endl; sized_rect.LowerRightCorner.X = center.X + (int)(((int)rect.LowerRightCorner.X - (int)center.X)*texture_size); sized_rect.LowerRightCorner.Y = center.Y + (int)(((int)rect.LowerRightCorner.Y - (int)center.Y)*texture_size); } drawBoxFromStretchableTexture(widget, sized_rect, params, widget->m_deactivated); // ---- If this spinner is of "gauge" type, draw filling const SpinnerWidget* w = dynamic_cast(widget); if (w->isGauge() && !w->m_deactivated) { const int handle_size = (int)( widget->h*params.left_border/(float)params.getImage()->getSize().Height ); const float value = (float)(w->getValue() - w->getMin()) / (w->getMax() - w->getMin()); const core::rect< s32 > dest_area = core::rect< s32 >(widget->x + handle_size, widget->y, widget->x + handle_size + (int)((widget->w - 2*handle_size)*value), widget->y + widget->h); const ITexture* texture = SkinConfig::m_render_params["gaugefill::neutral"].getImage(); 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, dest_area, source_area, 0 /* no clipping */, 0, true /* alpha */); } } void Skin::drawSpinnerChild(const core::rect< s32 > &rect, Widget* widget, const bool pressed, bool focused) { if (pressed) { Widget* spinner = widget->m_event_handler; int areas = 0; //std::cout << "drawing spinner child " << widget->m_properties[PROP_ID].c_str() << std::endl; if (widget->m_properties[PROP_ID] == "left") areas = BoxRenderParams::LEFT; else if (widget->m_properties[PROP_ID] == "right") areas = BoxRenderParams::RIGHT; else return; core::rect< s32 > rect2 = core::rect< s32 >( spinner->x, spinner->y, spinner->x + spinner->w, spinner->y + spinner->h ); BoxRenderParams& params = SkinConfig::m_render_params["spinner::down"]; params.areas = areas; drawBoxFromStretchableTexture(widget, rect, params, widget->m_deactivated); } } void Skin::drawIconButton(const core::rect< s32 > &rect, Widget* widget, const bool pressed, bool focused) { //TODO: do something better than hide it when a widget is deactivated? if (widget->m_deactivated) return; if (focused) { int grow = 45; static float glow_effect = 0; const float dt = GUIEngine::getLatestDt(); glow_effect += dt*3; if (glow_effect > 6.2832f /* 2*PI */) glow_effect -= 6.2832f; grow = (int)(45 + 10*sin(glow_effect)); const int glow_center_x = rect.UpperLeftCorner.X + rect.getWidth()/2; const int glow_center_y = rect.LowerRightCorner.Y; ITexture* tex_ficonhighlight = SkinConfig::m_render_params["focusHalo::neutral"].getImage(); const int texture_w = tex_ficonhighlight->getSize().Width; const int texture_h = tex_ficonhighlight->getSize().Height; core::rect source_area = core::rect(0, 0, texture_w, texture_h); const core::rect< s32 > rect2 = core::rect< s32 >(glow_center_x - 45 - grow, glow_center_y - 25 - grow/2, glow_center_x + 45 + grow, glow_center_y + 25 + grow/2); GUIEngine::getDriver()->draw2DImage(tex_ficonhighlight, rect2, source_area, 0 /* no clipping */, 0, true /* alpha */); } core::rect< s32 > sized_rect = rect; if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL && widget->m_parent->getType() == gui::EGUIET_WINDOW) { core::position2d center = core::position2d(irr_driver->getFrameSize()/2); const float texture_size = sin(m_dialog_size*M_PI*0.5f); sized_rect.UpperLeftCorner.X = center.X + (int)(((int)rect.UpperLeftCorner.X - (int)center.X)*texture_size); sized_rect.UpperLeftCorner.Y = center.Y + (int)(((int)rect.UpperLeftCorner.Y - (int)center.Y)*texture_size); //std::cout << "y is " << center.Y << " + (" << rect.UpperLeftCorner.Y << " - " << center.Y << ")*" << texture_size << " = " // << center.Y + (int)((rect.UpperLeftCorner.Y - center.Y)*texture_size) << std::endl; sized_rect.LowerRightCorner.X = center.X + (int)(((int)rect.LowerRightCorner.X - (int)center.X)*texture_size); sized_rect.LowerRightCorner.Y = center.Y + (int)(((int)rect.LowerRightCorner.Y - (int)center.Y)*texture_size); /* std::cout << texture_size << " : " << rect.UpperLeftCorner.X << ", " << rect.UpperLeftCorner.Y << " : " << rect.LowerRightCorner.X << ", " << rect.LowerRightCorner.Y << " ---> " << sized_rect.UpperLeftCorner.X << ", " << sized_rect.UpperLeftCorner.Y << " : " << sized_rect.LowerRightCorner.X << ", " << sized_rect.LowerRightCorner.Y << std::endl; */ } IconButtonWidget* icon_widget = (IconButtonWidget*) widget; GUIEngine::getDriver()->draw2DImage(icon_widget->m_texture, sized_rect, core::rect(0,0,icon_widget->m_texture_w, icon_widget->m_texture_h), 0 /* no clipping */, 0, true /* alpha */); } void Skin::drawCheckBox(const core::rect< s32 > &rect, Widget* widget, bool focused) { //TODO: do something better than hide it when a widget is deactivated? if (widget->m_deactivated) return; CheckBoxWidget* w = dynamic_cast(widget); ITexture* texture; if (w->getState() == true) { if (focused) texture = SkinConfig::m_render_params["checkbox::focused+checked"].getImage(); else texture = SkinConfig::m_render_params["checkbox::neutral+checked"].getImage(); } else { if (focused) texture = SkinConfig::m_render_params["checkbox::focused+unchecked"].getImage(); else texture = SkinConfig::m_render_params["checkbox::neutral+unchecked"].getImage(); } 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) { drawBoxFromStretchableTexture(widget, rect, SkinConfig::m_render_params["list::neutral"]); } void Skin::drawListSelection(const core::rect< s32 > &rect, Widget* widget, bool focused) { ListWidget* list = dynamic_cast(widget); assert(list != NULL); if(focused) drawBoxFromStretchableTexture(&list->m_selection_skin_info, rect, SkinConfig::m_render_params["listitem::focused"]); else drawBoxFromStretchableTexture(&list->m_selection_skin_info, 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) */ void Skin::renderSections(ptr_vector* within_vector) { if (within_vector == NULL) within_vector = &getCurrentScreen()->m_widgets; const unsigned short widgets_amount = within_vector->size(); for(int n=0; n rect = core::rect( widget.x, widget.y, widget.x + widget.w, widget.y + widget.h ); drawBoxFromStretchableTexture(&widget, rect, SkinConfig::m_render_params["section::neutral"]); } else { renderSections( &widget.m_children ); } } } // next } #if 0 #pragma mark - #pragma mark irrlicht skin functions #endif void Skin::draw2DRectangle (IGUIElement *element, const video::SColor &color, const core::rect< s32 > &rect, const core::rect< s32 > *clip) { if (GUIEngine::getStateManager()->getGameState() == GUIEngine::GAME) return; // ignore in game mode const int id = element->getID(); Widget* widget = GUIEngine::getWidget(id); if (widget == NULL) return; const int playerID = 0; // FIXME: don't hardcode player 0? const bool focused = GUIEngine::isFocusedForPlayer(widget, playerID); const WidgetType type = widget->m_type; if(type == WTYPE_LIST) { // list selection background drawListSelection(rect, widget, focused); } } // ----------------------------------------------------------------------------- void Skin::process3DPane(IGUIElement *element, const core::rect< s32 > &rect, const bool pressed) { const int id = element->getID(); Widget* widget = NULL; if (id != -1) widget = GUIEngine::getWidget(id); if (widget == NULL) return; const int playerID = 0; // FIXME: don't hardcode player 0? const bool focused = GUIEngine::isFocusedForPlayer(widget, playerID); /* std::cout << "Skin (3D Pane) : " << (widget == NULL ? "NULL!!" : widget->m_properties[PROP_ID].c_str()) << std::endl; if (widget == NULL) std::cout << "Null widget: ID=" << id << " type=" << element->getTypeName() << " x=" << rect.UpperLeftCorner.X << " y=" << rect.UpperLeftCorner.Y << " w=" << rect.getWidth() << " h=" << rect.getHeight() << std::endl; */ if (widget == NULL) return; const WidgetType type = widget->m_type; // buttons are used for other uses than plain clickable buttons because irrLicht // does not have widgets for everything we need. so at render time, we just check // which type this button represents and render accordingly if (widget->m_event_handler != NULL && widget->m_event_handler->m_type == WTYPE_RIBBON) { drawRibbonChild(rect, widget, pressed, focused); } else if (widget->m_event_handler != NULL && widget->m_event_handler->m_type == WTYPE_SPINNER) { if (!widget->m_event_handler->m_deactivated) drawSpinnerChild(rect, widget, pressed, focused); } else if (type == WTYPE_ICON_BUTTON || type == WTYPE_MODEL_VIEW) { drawIconButton(rect, widget, pressed, focused); } else if(type == WTYPE_BUTTON) { drawButton(widget, rect, pressed, focused); } else if(type == WTYPE_RIBBON) { drawRibbon(rect, widget, pressed, focused); } else if(type == WTYPE_SPINNER) { drawSpinnerBody(rect, widget, pressed, focused); } else if(type == WTYPE_CHECKBOX) { drawCheckBox(rect, widget, focused); } if (ID_DEBUG && id != -1) { irr::core::stringw idstring; idstring += id; SColor color(255, 255, 0, 0); GUIEngine::getFont()->draw(idstring.c_str(), rect, color, true, true); } if (widget->m_badges != 0) { drawBadgeOn(widget, rect); } } // ----------------------------------------------------------------------------- void doDrawBadge(ITexture* texture, const core::rect& rect, float max_icon_size, bool badge_at_left) { const core::dimension2d& texture_size = texture->getSize(); const float aspectRatio = (float)texture_size.Width / (float)texture_size.Height; const int h = rect.getHeight() <= 50 ? rect.getHeight() : std::min( (int)(rect.getHeight()*max_icon_size), (int)(texture_size.Height) ); int w = (int)(aspectRatio*h); const core::rect source_area = core::rect(0, 0, texture_size.Width, texture_size.Height); const core::rect< s32 > rect2 = core::rect< s32 >(badge_at_left ? rect.UpperLeftCorner.X : rect.LowerRightCorner.X - w, rect.LowerRightCorner.Y - h, badge_at_left ? rect.UpperLeftCorner.X + w : rect.LowerRightCorner.X, rect.LowerRightCorner.Y); GUIEngine::getDriver()->draw2DImage(texture, rect2, source_area, 0 /* no clipping */, 0, true /* alpha */); } void Skin::drawBadgeOn(const Widget* widget, const core::rect& rect) { if (widget->m_badges & LOCKED_BADGE) { video::ITexture* texture = irr_driver->getTexture(file_manager->getTextureFile("gui_lock.png")); float max_icon_size = 0.5f; // Lock badge can be quite big doDrawBadge(texture, rect, max_icon_size, true); } if (widget->m_badges & OK_BADGE) { video::ITexture* texture = irr_driver->getTexture(file_manager->getTextureFile("green_check.png")); float max_icon_size = 0.35f; doDrawBadge(texture, rect, max_icon_size, true); } if (widget->m_badges & BAD_BADGE) { video::ITexture* texture = irr_driver->getTexture(file_manager->getTextureFile("red_mark.png")); float max_icon_size = 0.35f; doDrawBadge(texture, rect, max_icon_size, false); } if (widget->m_badges & TROPHY_BADGE) { float max_icon_size = 0.43f; video::ITexture* texture = irr_driver->getTexture(file_manager->getTextureFile("cup_bronze.png")); doDrawBadge(texture, rect, max_icon_size, false); } } // ----------------------------------------------------------------------------- void Skin::draw3DButtonPanePressed (IGUIElement *element, const core::rect< s32 > &rect, const core::rect< s32 > *clip) { process3DPane(element, rect, true /* pressed */ ); } // ----------------------------------------------------------------------------- void Skin::draw3DButtonPaneStandard (IGUIElement *element, const core::rect< s32 > &rect, const core::rect< s32 > *clip) { process3DPane(element, rect, false /* pressed */ ); } // ----------------------------------------------------------------------------- void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor, bool flat, bool fillBackGround, const core::rect< s32 > &rect, const core::rect< s32 > *clip) { const int id = element->getID(); Widget* widget = GUIEngine::getWidget(id); if (widget == NULL) return; const WidgetType type = widget->m_type; const int playerID = 0; // FIXME : don't hardcode player 0 ? IGUIElement* focusedElem = NULL; if (GUIEngine::getFocusForPlayer(playerID) != NULL) { focusedElem = GUIEngine::getFocusForPlayer(playerID)->getIrrlichtElement(); } const bool focused = (focusedElem == element); if (element->getType()==gui::EGUIET_EDIT_BOX) { SColor& color = SkinConfig::m_colors["text_field::neutral"]; SColor& colorFocus = SkinConfig::m_colors["text_field::focused"]; if (focused) { core::rect< s32 > borderArea = rect; borderArea.UpperLeftCorner -= position2d< s32 >( 2, 2 ); borderArea.LowerRightCorner += position2d< s32 >( 2, 2 ); // if within an appearing dialog, grow if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL && widget->m_parent->getType() == gui::EGUIET_WINDOW) { core::position2d center = core::position2d(irr_driver->getFrameSize()/2); const float texture_size = sin(m_dialog_size*M_PI*0.5f); borderArea.UpperLeftCorner.X = center.X + (int)(((int)rect.UpperLeftCorner.X - (int)center.X)*texture_size); borderArea.UpperLeftCorner.Y = center.Y + (int)(((int)rect.UpperLeftCorner.Y - (int)center.Y)*texture_size); borderArea.LowerRightCorner.X = center.X + (int)(((int)rect.LowerRightCorner.X - (int)center.X)*texture_size); borderArea.LowerRightCorner.Y = center.Y + (int)(((int)rect.LowerRightCorner.Y - (int)center.Y)*texture_size); } GUIEngine::getDriver()->draw2DRectangle( colorFocus, borderArea ); core::rect< s32 > innerArea = borderArea; innerArea.UpperLeftCorner += position2d< s32 >( 2, 2 ); innerArea.LowerRightCorner -= position2d< s32 >( 2, 2 ); GUIEngine::getDriver()->draw2DRectangle( color, innerArea ); } else { // if within an appearing dialog, grow if (m_dialog && m_dialog_size < 1.0f && widget->m_parent != NULL && widget->m_parent->getType() == gui::EGUIET_WINDOW) { core::position2d center = core::position2d(irr_driver->getFrameSize()/2); const float texture_size = sin(m_dialog_size*M_PI*0.5f); core::rect< s32 > sizedRect; sizedRect.UpperLeftCorner.X = center.X + (int)(((int)rect.UpperLeftCorner.X - (int)center.X)*texture_size); sizedRect.UpperLeftCorner.Y = center.Y + (int)(((int)rect.UpperLeftCorner.Y - (int)center.Y)*texture_size); sizedRect.LowerRightCorner.X = center.X + (int)(((int)rect.LowerRightCorner.X - (int)center.X)*texture_size); sizedRect.LowerRightCorner.Y = center.Y + (int)(((int)rect.LowerRightCorner.Y - (int)center.Y)*texture_size); GUIEngine::getDriver()->draw2DRectangle( color, sizedRect ); } else { GUIEngine::getDriver()->draw2DRectangle( color, rect ); } } return; } else if (type == WTYPE_LIST) { drawList(rect, widget, focused); } //if(focused) // GUIEngine::getDriver()->draw2DRectangle( SColor(255, 150, 0, 0), rect ); //else // GUIEngine::getDriver()->draw2DRectangle( SColor(255, 0, 150, 0), rect ); } // ----------------------------------------------------------------------------- void Skin::drawBGFadeColor() { // fade out background SColor color = SkinConfig::m_colors["dialog_background::neutral"]; if (m_dialog_size < 1.0f) color.setAlpha( (unsigned int)(color.getAlpha()*m_dialog_size )); GUIEngine::getDriver()->draw2DRectangle( color, core::rect< s32 >(position2d< s32 >(0,0) , GUIEngine::getDriver()->getCurrentRenderTargetSize()) ); } // ----------------------------------------------------------------------------- #if (IRRLICHT_VERSION_MAJOR == 1) && (IRRLICHT_VERSION_MINOR==7) core::rect< s32 > Skin::draw3DWindowBackground(IGUIElement *element, bool drawTitleBar, video::SColor titleBarColor, const core::rect< s32 > &rect, const core::rect< s32 > *clip, core::rect* checkClientArea) #else core::rect< s32 > Skin::draw3DWindowBackground(IGUIElement *element, bool drawTitleBar, video::SColor titleBarColor, const core::rect< s32 > &rect, const core::rect< s32 > *clip) #endif { drawBGFadeColor(); // draw frame if (m_dialog_size < 1.0f) { core::rect< s32 > sized_rect = rect; core::position2d center = sized_rect.getCenter(); const int w = sized_rect.getWidth(); const int h = sized_rect.getHeight(); const float texture_size = sin(m_dialog_size*M_PI*0.5f); sized_rect.UpperLeftCorner.X = (int)(center.X - (w/2.0f)*texture_size); sized_rect.UpperLeftCorner.Y = (int)(center.Y - (h/2.0f)*texture_size); sized_rect.LowerRightCorner.X = (int)(center.X + (w/2.0f)*texture_size); sized_rect.LowerRightCorner.Y = (int)(center.Y + (h/2.0f)*texture_size); drawBoxFromStretchableTexture( ModalDialog::getCurrent(), sized_rect, SkinConfig::m_render_params["window::neutral"]); m_dialog_size += GUIEngine::getLatestDt()*5; } else { drawBoxFromStretchableTexture( ModalDialog::getCurrent(), rect, SkinConfig::m_render_params["window::neutral"]); } return rect; } // ----------------------------------------------------------------------------- void Skin::draw3DMenuPane (IGUIElement *element, const core::rect< s32 > &rect, const core::rect< s32 > *clip) { //printf("draw menu pane\n"); } // ----------------------------------------------------------------------------- void Skin::draw3DTabBody (IGUIElement *element, bool border, bool background, const core::rect< s32 > &rect, const core::rect< s32 > *clip, s32 tabHeight, gui::EGUI_ALIGNMENT alignment) { //printf("draw tab body\n"); } // ----------------------------------------------------------------------------- void Skin::draw3DTabButton (IGUIElement *element, bool active, const core::rect< s32 > &rect, const core::rect< s32 > *clip, gui::EGUI_ALIGNMENT alignment) { //printf("draw tab button\n"); } // ----------------------------------------------------------------------------- void Skin::draw3DToolBar (IGUIElement *element, const core::rect< s32 > &rect, const core::rect< s32 > *clip) { } // ----------------------------------------------------------------------------- void Skin::drawIcon (IGUIElement *element, EGUI_DEFAULT_ICON icon, const core::position2di position, u32 starttime, u32 currenttime, bool loop, const core::rect< s32 > *clip) { // we won't let irrLicht decide when to call this, we draw them ourselves. /* m_fallback_skin->drawIcon(element, icon, position, starttime, currenttime, loop, clip); */ } // ----------------------------------------------------------------------------- video::SColor Skin::getColor (EGUI_DEFAULT_COLOR color) const { /* EGDC_3D_DARK_SHADOW Dark shadow for three-dimensional display elements. EGDC_3D_SHADOW Shadow color for three-dimensional display elements (for edges facing away from the light source). EGDC_3D_FACE Face color for three-dimensional display elements and for dialog box backgrounds. EGDC_3D_HIGH_LIGHT Highlight color for three-dimensional display elements (for edges facing the light source.). EGDC_3D_LIGHT Light color for three-dimensional display elements (for edges facing the light source.). EGDC_ACTIVE_BORDER Active window border. EGDC_ACTIVE_CAPTION Active window title bar text. EGDC_APP_WORKSPACE Background color of multiple document interface (MDI) applications. EGDC_BUTTON_TEXT Text on a button. EGDC_GRAY_TEXT Grayed (disabled) text. EGDC_HIGH_LIGHT Item(s) selected in a control. EGDC_HIGH_LIGHT_TEXT Text of item(s) selected in a control. EGDC_INACTIVE_BORDER Inactive window border. EGDC_INACTIVE_CAPTION Inactive window caption. EGDC_TOOLTIP Tool tip text color. EGDC_TOOLTIP_BACKGROUND Tool tip background color. EGDC_SCROLLBAR Scrollbar gray area. EGDC_WINDOW Window background. EGDC_WINDOW_SYMBOL Window symbols like on close buttons, scroll bars and check boxes. EGDC_ICON Icons in a list or tree. EGDC_ICON_HIGH_LIGHT Selected icons in a list or tree. */ switch(color) { case EGDC_GRAY_TEXT: return SkinConfig::m_colors["text::neutral"]; case EGDC_HIGH_LIGHT: case EGDC_ICON_HIGH_LIGHT: case EGDC_HIGH_LIGHT_TEXT: return SkinConfig::m_colors["text::focused"]; case EGDC_BUTTON_TEXT: default: return SkinConfig::m_colors["text::neutral"]; } } // ----------------------------------------------------------------------------- const wchar_t* Skin::getDefaultText (EGUI_DEFAULT_TEXT text) const { // No idea what this is for return L"SuperTuxKart"; } // ----------------------------------------------------------------------------- IGUIFont* Skin::getFont (EGUI_DEFAULT_FONT which) const { return GUIEngine::getFont(); } // ----------------------------------------------------------------------------- u32 Skin::getIcon (EGUI_DEFAULT_ICON icon) const { //return m_fallback_skin->getIcon(icon); // return m_fallback_skin->getIcon(irr::gui::EGUI_DEFAULT_ICON); return 0; } // ----------------------------------------------------------------------------- s32 Skin::getSize (EGUI_DEFAULT_SIZE texture_size) const { return m_fallback_skin->getSize(texture_size); } // ----------------------------------------------------------------------------- IGUISpriteBank* Skin::getSpriteBank () const { return m_fallback_skin->getSpriteBank(); } // ----------------------------------------------------------------------------- void Skin::setColor (EGUI_DEFAULT_COLOR which, video::SColor newColor) { m_fallback_skin->setColor(which, newColor); } // ----------------------------------------------------------------------------- void Skin::setDefaultText (EGUI_DEFAULT_TEXT which, const wchar_t *newText) { m_fallback_skin->setDefaultText(which, newText); } // ----------------------------------------------------------------------------- void Skin::setFont (IGUIFont *font, EGUI_DEFAULT_FONT which) { m_fallback_skin->setFont(font, which); } // ----------------------------------------------------------------------------- void Skin::setIcon (EGUI_DEFAULT_ICON icon, u32 index) { m_fallback_skin->setIcon(icon, index); } // ----------------------------------------------------------------------------- void Skin::setSize (EGUI_DEFAULT_SIZE which, s32 texture_size) { m_fallback_skin->setSize(which, texture_size); //printf("setting size\n"); } // ----------------------------------------------------------------------------- void Skin::setSpriteBank (IGUISpriteBank *bank) { //printf("setting sprite bank\n"); m_fallback_skin->setSpriteBank(bank); //this->m_bank = bank; }