bool ProcTitle::OnInit(irr::IrrlichtDevice& device) { device.setWindowCaption(L"Artistic Controlled Car - title"); IGUIEnvironment* env = device.getGUIEnvironment(); IGUIButton* pButton = env->addButton(rect<s32>(10, 240, 200, 240+100), 0, GUI_ID_START_BUTTON, L"Start", L"Start Game"); pButton->setDrawBorder(false); IVideoDriver* pDriver = IrrDvc.GetDriver(); video::ITexture* pTexture = pDriver->getTexture("Rsrc/hero.tga"); // refcount = 1 pButton->setImage(pTexture); // refcount += 2, means when button released refcount will be 1 pButton->setUseAlphaChannel(true); // 1 will be decreased pDriver->removeAllTextures(); { ITexture* pTexture = pDriver->getTexture("Rsrc/map.bmp"); pButton->setPressedImage(pTexture); } // sound test IrrSnd.GetSndEngine()->play2D("Rsrc/getout.ogg", true); return true; }
// ---------------------------------------------------------------------------- void RibbonWidget::add() { assert(m_magic_number == 0xCAFEC001); assert(m_x > -10.0f); assert(m_y > -10.0f); assert(m_w > 0.0f); assert(m_h > 0.0f); m_labels.clearWithoutDeleting(); rect<s32> widget_size = rect<s32>(m_x, m_y, m_x + m_w, m_y + m_h); int id = (m_reserved_id == -1 ? getNewID() : m_reserved_id); IGUIButton * btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, id, L""); m_element = btn; m_active_children.clearWithoutDeleting(); // Is just a copy of m_children without the deactivated children. m_children takes care of memory. for (unsigned int i=0; i<m_children.size(); i++) { if (m_children[i].isVisible()) { m_active_children.push_back(m_children.get(i)); } } const int subbuttons_amount = m_active_children.size(); // For some ribbon types, we can have unequal sizes depending on whether // items have labels or not int with_label = 0; int without_label = 0; // ---- check how much space each child button will take and fit // them within available space int total_needed_space = 0; for (int i=0; i<subbuttons_amount; i++) { // FIXME: why do I manually invoke the Layout Manager here? LayoutManager::readCoords(m_active_children.get(i)); LayoutManager::applyCoords(m_active_children.get(i), NULL, this); if (m_active_children[i].m_type != WTYPE_ICON_BUTTON && m_active_children[i].m_type != WTYPE_BUTTON) { Log::warn("RiggonWidget", "Ribbon widgets can only have " "(icon)button widgets as children"); continue; } // ribbon children must not be keyboard navigatable, the parent // ribbon takes care of that if (m_active_children[i].m_type == WTYPE_ICON_BUTTON) { IconButtonWidget* icon = ((IconButtonWidget*)m_active_children.get(i)); icon->m_tab_stop = false; } bool has_label_underneath = m_active_children[i].m_text.size() > 0; if (m_active_children[i].m_properties[PROP_LABELS_LOCATION].size() > 0) { has_label_underneath = false; } if (has_label_underneath) with_label++; else without_label++; total_needed_space += m_active_children[i].m_w; } //int biggest_y = 0; const int button_y = 10; const int one_button_space = int(roundf((float)m_w / (float)subbuttons_amount)); int widget_x = -1; // ---- add children for (int i=0; i<subbuttons_amount; i++) { // ---- tab ribbons if (getRibbonType() == RIBBON_TABS) { const int large_tab = (int)((with_label + without_label) *one_button_space / (with_label + without_label/2.0f)); const int small_tab = large_tab/2; stringw& message = m_active_children[i].m_text; if (message.size() == 0) { if (widget_x == -1) widget_x = small_tab/2; else widget_x += small_tab/2; } else { if (widget_x == -1) widget_x = large_tab/2; else widget_x += large_tab/2; } IGUIButton * subbtn = NULL; rect<s32> subsize = rect<s32>(widget_x - large_tab/2+2, 0, widget_x + large_tab/2-2, m_h); if (message.size() == 0) { subsize = rect<s32>(widget_x - small_tab/2+2, 0, widget_x + small_tab/2-2, m_h); } if (m_active_children[i].m_type == WTYPE_BUTTON) { subbtn = GUIEngine::getGUIEnv() ->addButton(subsize, btn, getNewNoFocusID(), message.c_str(), L""); subbtn->setTabStop(false); subbtn->setTabGroup(false); if ((int)GUIEngine::getFont()->getDimension(message.c_str()) .Width > subsize.getWidth() && message.findFirst(L' ') == -1 && message.findFirst(L'\u00AD') == -1 ) { // if message too long and contains no space and no soft // hyphen, make the font smaller subbtn->setOverrideFont(GUIEngine::getSmallFont()); } } else if (m_active_children[i].m_type == WTYPE_ICON_BUTTON) { rect<s32> icon_part = rect<s32>(15, 0, subsize.getHeight()+15, subsize.getHeight()); if (message.size() == 0) { const int x = subsize.getWidth()/2 - subsize.getHeight()/2; // no label, only icon, so center the icon icon_part = rect<s32>(x, 0, x + subsize.getHeight(), subsize.getHeight()); } // label at the *right* of the icon (for tabs) rect<s32> label_part = rect<s32>(subsize.getHeight()+15, 0, subsize.getWidth()-15, subsize.getHeight()); // use the same ID for all subcomponents; since event handling // is done per-ID, no matter which one your hover, this // widget will get it int same_id = getNewNoFocusID(); subbtn = GUIEngine::getGUIEnv()->addButton(subsize, btn, same_id, L"", L""); IGUIButton* icon = GUIEngine::getGUIEnv()->addButton(icon_part, subbtn, same_id, L""); icon->setScaleImage(true); std::string filename = file_manager->getAsset( m_active_children[i].m_properties[PROP_ICON]); icon->setImage( irr_driver->getTexture(filename.c_str()) ); icon->setUseAlphaChannel(true); icon->setDrawBorder(false); icon->setTabStop(false); IGUIStaticText* label = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), label_part, false /* border */, true /* word wrap */, subbtn, same_id); if ((int)GUIEngine::getFont()->getDimension(message.c_str()) .Width > label_part.getWidth()&& message.findFirst(L' ') == -1 && message.findFirst(L'\u00AD') == -1 ) { // if message too long and contains no space and no soft // hyphen, make the font smaller label->setOverrideFont(GUIEngine::getSmallFont()); } label->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); label->setTabStop(false); label->setNotClipped(true); label->setRightToLeft(translations->isRTLText(message)); m_labels.push_back(label); subbtn->setTabStop(false); subbtn->setTabGroup(false); } else { Log::error("RibbonWidget", "Invalid tab bar contents"); } m_active_children[i].m_element = subbtn; if (message.size() == 0) widget_x += small_tab/2; else widget_x += large_tab/2; } // ---- icon ribbons else if (m_active_children[i].m_type == WTYPE_ICON_BUTTON) { if (widget_x == -1) widget_x = one_button_space/2; // find how much space to keep for the label under the button. // consider font size, whether the label is multiline, etc... bool has_label = m_active_children[i].m_text.size() > 0; if (m_active_children[i].m_properties[PROP_LABELS_LOCATION].size() > 0) { has_label = false; } const int needed_space_under_button = has_label ? GUIEngine::getFontHeight() : 10; float imageRatio = (float)m_active_children[i].m_w / (float)m_active_children[i].m_h; // calculate the size of the image std::string filename = file_manager->getAsset(m_active_children[i].m_properties[PROP_ICON]); video::ITexture* image = irr_driver->getTexture((filename).c_str()); if(!image) { std::string file = file_manager->getAsset(FileManager::GUI,"main_help.png"); image = irr_driver->getTexture(file); if(!image) Log::fatal("RibbonWidget", "Can't find fallback texture 'gui/main_help.png, aborting."); } float image_h = (float)image->getSize().Height; float image_w = image_h*imageRatio; float zoom = (float) (m_h - button_y - needed_space_under_button) / image_h; float zoom_x = (float) one_button_space / image_w; if(zoom_x < zoom) zoom = zoom_x; // ---- add bitmap button part // backup and restore position in case the same object is added // multiple times (FIXME: unclean) int old_x = m_active_children[i].m_x; int old_y = m_active_children[i].m_y; int old_w = m_active_children[i].m_w; int old_h = m_active_children[i].m_h; m_active_children[i].m_x = widget_x - int(image_w*zoom/2.0f); m_active_children[i].m_y = button_y; m_active_children[i].m_w = int(image_w*zoom); m_active_children[i].m_h = int(image_h*zoom); IconButtonWidget* icon = ((IconButtonWidget*)m_active_children.get(i)); if (icon->m_properties[PROP_EXTEND_LABEL].size() == 0) { icon->m_properties[PROP_EXTEND_LABEL] = StringUtils::toString(one_button_space - icon->m_w); } m_active_children.get(i)->m_parent = btn; m_active_children.get(i)->add(); // restore backuped size and location (see above for more info) m_active_children[i].m_x = old_x; m_active_children[i].m_y = old_y; m_active_children[i].m_w = old_w; m_active_children[i].m_h = old_h; // the label itself will be added by the icon widget. since it // adds the label outside of the widget area it is assigned to, // the label will appear in the area we want at the bottom widget_x += one_button_space; } else { Log::warn("RiggonWidget", "Invalid contents type in ribbon"); } //m_children[i].id = subbtn->getID(); m_active_children[i].m_event_handler = this; }// next sub-button id = m_element->getID(); m_element->setTabOrder(id); m_element->setTabGroup(false); updateSelection(); if (!m_is_visible) setVisible(false); } // add
void RibbonWidget::add() { m_labels.clearWithoutDeleting(); rect<s32> widget_size = rect<s32>(m_x, m_y, m_x + m_w, m_y + m_h); int id = (m_reserved_id == -1 ? getNewID() : m_reserved_id); IGUIButton * btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, id, L""); m_element = btn; const int subbuttons_amount = m_children.size(); // ---- check how much space each child button will take and fit them within available space int total_needed_space = 0; for (int i=0; i<subbuttons_amount; i++) { // FIXME: a little unclean to invoke layout code here? LayoutManager::readCoords(m_children.get(i), NULL, this); if (m_children[i].m_type != WTYPE_ICON_BUTTON && m_children[i].m_type != WTYPE_BUTTON) { std::cerr << "/!\\ Warning /!\\ : ribbon widgets can only have (icon)button widgets as children " << std::endl; continue; } // ribbon children must not be keyboard navigatable, the parent ribbon takes care of that if (m_children[i].m_type == WTYPE_ICON_BUTTON) { IconButtonWidget* icon = ((IconButtonWidget*)m_children.get(i)); icon->m_tab_stop = false; } total_needed_space += m_children[i].m_w; } int free_w_space = m_w - total_needed_space; //int biggest_y = 0; const int button_y = 10; float global_zoom = 1; const int min_free_space = 50; global_zoom = (float)m_w / (float)( m_w - free_w_space + min_free_space ); //free_w_space = (int)(m_w - total_needed_space*global_zoom); const int one_button_space = (int)round((float)m_w / (float)subbuttons_amount); // ---- add children for (int i=0; i<subbuttons_amount; i++) { const int widget_x = one_button_space*(i+1) - one_button_space/2; // ---- tab ribbons if (getRibbonType() == RIBBON_TABS) { IGUIButton * subbtn = NULL; rect<s32> subsize = rect<s32>(widget_x - one_button_space/2+2, 0, widget_x + one_button_space/2-2, m_h); stringw& message = m_children[i].m_text; if (m_children[i].m_type == WTYPE_BUTTON) { subbtn = GUIEngine::getGUIEnv()->addButton(subsize, btn, getNewNoFocusID(), message.c_str(), L""); subbtn->setTabStop(false); subbtn->setTabGroup(false); } else if (m_children[i].m_type == WTYPE_ICON_BUTTON) { rect<s32> icon_part = rect<s32>(15, 0, subsize.getHeight()+15, subsize.getHeight()); // label at the *right* of the icon (for tabs) rect<s32> label_part = rect<s32>(subsize.getHeight()+15, 0, subsize.getWidth()-15, subsize.getHeight()); // use the same ID for all subcomponents; since event handling is done per-ID, no matter // which one your hover, this widget will get it int same_id = getNewNoFocusID(); subbtn = GUIEngine::getGUIEnv()->addButton(subsize, btn, same_id, L"", L""); //MyGUIButton* icon = new MyGUIButton(GUIEngine::getGUIEnv(), subbtn, same_id, icon_part, true); IGUIButton* icon = GUIEngine::getGUIEnv()->addButton(icon_part, subbtn, same_id, L""); icon->setScaleImage(true); icon->setImage( irr_driver->getTexture((file_manager->getDataDir() + "/" + m_children[i].m_properties[PROP_ICON]).c_str()) ); icon->setUseAlphaChannel(true); icon->setDrawBorder(false); icon->setTabStop(false); IGUIStaticText* label = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), label_part, false /* border */, true /* word wrap */, subbtn, same_id); label->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); label->setTabStop(false); label->setNotClipped(true); m_labels.push_back(label); subbtn->setTabStop(false); subbtn->setTabGroup(false); } else { std::cerr << "Invalid tab bar contents\n"; } m_children[i].m_element = subbtn; } // ---- icon ribbons else if (m_children[i].m_type == WTYPE_ICON_BUTTON) { // find how much space to keep for the label under the button. // consider font size, whether the label is multiline, etc... const bool has_label = m_children[i].m_text.size() > 0; const int needed_space_under_button = has_label ? GUIEngine::getFontHeight() : 10; float imageRatio = (float)m_children[i].m_w / (float)m_children[i].m_h; // calculate the size of the image video::ITexture* image = irr_driver->getTexture((file_manager->getDataDir() + "/" + m_children[i].m_properties[PROP_ICON]).c_str()); float image_h = (float)image->getSize().Height; float image_w = image_h*imageRatio; // scale to fit (FIXME: calculate the right value directly...) float zoom = global_zoom; if (button_y + image_h*zoom + needed_space_under_button > m_h) { // scale down while (button_y + image_h*zoom + needed_space_under_button > m_h) zoom -= 0.01f; } else { // scale up while (button_y + image_h*zoom + needed_space_under_button < m_h) zoom += 0.01f; } // ---- add bitmap button part // backup and restore position in case the same object is added multiple times (FIXME: unclean) int old_x = m_children[i].m_x; int old_y = m_children[i].m_y; int old_w = m_children[i].m_w; int old_h = m_children[i].m_h; m_children[i].m_x = widget_x - (int)(image_w*zoom/2.0f); m_children[i].m_y = button_y; m_children[i].m_w = (int)(image_w*zoom); m_children[i].m_h = (int)(image_h*zoom); IconButtonWidget* icon = ((IconButtonWidget*)m_children.get(i)); icon->m_properties[PROP_EXTEND_LABEL] = StringUtils::toString(one_button_space - icon->m_w); m_children.get(i)->m_parent = btn; m_children.get(i)->add(); // restore backuped size and location (see above for more info) m_children[i].m_x = old_x; m_children[i].m_y = old_y; m_children[i].m_w = old_w; m_children[i].m_h = old_h; // the label itself will be added by the icon widget. since it adds the label outside of the // widget area it is assigned to, the label will appear in the area we want at the bottom } else { std::cerr << "/!\\ Warning /!\\ : Invalid contents type in ribbon" << std::endl; } //m_children[i].id = subbtn->getID(); m_children[i].m_event_handler = this; }// next sub-button id = m_element->getID(); m_element->setTabOrder(id); m_element->setTabGroup(false); updateSelection(); }
bool ProcTitle::OnInit(irr::IrrlichtDevice& device) { device.setWindowCaption(L"Pair - title"); //device.getCursorControl()->setVisible(false); u32 width = IrrDvc.GetDriver()->getScreenSize().Width; u32 height = IrrDvc.GetDriver()->getScreenSize().Height; scene::ISceneManager* pSmgr = IrrDvc.GetSmgr(); IVideoDriver* pDriver = IrrDvc.GetDriver(); // camera setting { irr::scene::ICameraSceneNode* pCamera = pSmgr->addCameraSceneNode(0, core::vector3df(0,0,-100), core::vector3df(0,0,0)); //f32 zNear = 1; //f32 zFar = 3000; //f32 zNear = pCamera->getNearValue(); //f32 zFar = pCamera->getFarValue(); #if 0 CMatrix4<f32> matOrtho; matOrtho.buildProjectionMatrixOrthoLH(width, height, zNear, zFar); pCamera->setProjectionMatrix(matOrtho, true); #else //CMatrix4<f32> matPerspective; //matPerspective.buildProjectionMatrixPerspectiveLH((f32)width, (f32)height, zNear, zFar); //pCamera->setProjectionMatrix(matPerspective, false); #endif } // title { m_p2DSprite = pSmgr->addBillboardSceneNode(); video::ITexture* pTexture = pDriver->getTexture("Rsrc/title.png"); m_p2DSprite->setMaterialTexture(0, pTexture); m_p2DSprite->setMaterialFlag(video::EMF_LIGHTING, false); m_p2DSprite->setMaterialFlag(video::EMF_ZBUFFER, true); m_p2DSprite->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); m_p2DSprite->setMaterialFlag(video::EMF_ANTI_ALIASING, true); m_p2DSprite->setMaterialFlag(video::EMF_BILINEAR_FILTER, true); m_p2DSprite->setSize(dimension2df((f32)width, (f32)height)); m_p2DSprite->setPosition(vector3df(0.f, 0.f, 300.f)); m_p2DSprite->setID(1004); m_p2DSprite->getMaterial(0).getTextureMatrix(0).setTextureScale(1.0f, 1.0f); // animation test //scene::ISceneNodeAnimator* pAni = pSmgr->createFlyCircleAnimator(core::vector3df(0,0,200), 20.0f); //m_p2DSprite->addAnimator(pAni); } // card { for (int i = 0; i < 3; i++) { IMeshSceneNode* pCard = pSmgr->addCubeSceneNode(); char buff[20]; sprintf_s(buff, 20, "Rsrc/card%d.png", i); video::ITexture* pTexture = pDriver->getTexture(buff); pCard->setMaterialTexture(0, pTexture); pCard->setScale(vector3df(4.f, 4.f * 1.618f, 0.1f)); pCard->setPosition(vector3df(-60.f + 60.f * i, 0.f, 0.f)); pCard->setMaterialFlag(video::EMF_LIGHTING, false); // animation test scene::ISceneNodeAnimator* pAni = pSmgr->createRotationAnimator(vector3df(0.f, 1.f, 0.f)); pCard->addAnimator(pAni); pAni->drop(); } } // mesh { IAnimatedMesh* mesh = pSmgr->getMesh("Rsrc/sydney.md2"); IAnimatedMeshSceneNode* pNode = pSmgr->addAnimatedMeshSceneNode(mesh); if (pNode) { //pNode->setScale(vector3df(10.f, 10.f, 10.f)); pNode->setMaterialFlag(EMF_LIGHTING, false); //pNode->setMaterialFlag(EMF_ZBUFFER, false); pNode->setMD2Animation(scene::EMAT_STAND); pNode->setMaterialTexture( 0, pDriver->getTexture("Rsrc/sydney.bmp") ); pNode->setPosition(vector3df(0.0f, -5.f, -55.f)); } } // button { IGUIEnvironment* env = device.getGUIEnvironment(); video::ITexture* pTexture = pDriver->getTexture("Rsrc/new_game_btn_normal.PNG"); // refcount = 1 dimension2d<u32> dim = pTexture->getOriginalSize(); s32 offsetX = width / 2 - dim.Width / 2; s32 offsetY = height - dim.Height * 3; IGUIButton* pButton = env->addButton(rect<s32>(offsetX, offsetY, offsetX + dim.Width, offsetY + dim.Height), 0, GUI_ID_START_BUTTON); pButton->setDrawBorder(false); pButton->setImage(pTexture); // refcount += 2, means when button released refcount will be 1 pButton->setUseAlphaChannel(true); // 1 will be decreased pDriver->removeAllTextures(); { ITexture* pTexture = pDriver->getTexture("Rsrc/new_game_btn_pressed.PNG"); pButton->setPressedImage(pTexture); } } // sound test IrrSnd.GetSndEngine()->play2D("Rsrc/getout.ogg", true); return true; }