From: <au...@us...> - 2009-08-27 20:18:13
|
Revision: 3935 http://supertuxkart.svn.sourceforge.net/supertuxkart/?rev=3935&view=rev Author: auria Date: 2009-08-27 20:17:59 +0000 (Thu, 27 Aug 2009) Log Message: ----------- More work towards independant focus for players (breaking some of what i committed previously but i'm on the right path) Modified Paths: -------------- main/branches/irrlicht/src/guiengine/engine.cpp main/branches/irrlicht/src/guiengine/engine.hpp main/branches/irrlicht/src/guiengine/skin.cpp main/branches/irrlicht/src/guiengine/widget.cpp main/branches/irrlicht/src/guiengine/widget.hpp main/branches/irrlicht/src/guiengine/widgets/ribbon_grid_widget.cpp main/branches/irrlicht/src/guiengine/widgets/ribbon_grid_widget.hpp main/branches/irrlicht/src/guiengine/widgets/ribbon_widget.cpp main/branches/irrlicht/src/guiengine/widgets/ribbon_widget.hpp main/branches/irrlicht/src/states_screens/kart_selection.cpp Modified: main/branches/irrlicht/src/guiengine/engine.cpp =================================================================== --- main/branches/irrlicht/src/guiengine/engine.cpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/engine.cpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -31,6 +31,8 @@ namespace GUIEngine { + Widget* g_focus_for_player[32]; // unused for player 0, player 0's focus is tracked by irrlicht + IGUIEnvironment* g_env; Skin* g_skin = NULL; IGUIFont* g_font; @@ -153,6 +155,11 @@ g_driver = driver_a; g_state_manager = state_manager; + for (int n=0; n<32; n++) + { + g_focus_for_player[n] = NULL; + } + /* To make the g_font a little bit nicer, we load an external g_font and set it as the new default g_font in the g_skin. Modified: main/branches/irrlicht/src/guiengine/engine.hpp =================================================================== --- main/branches/irrlicht/src/guiengine/engine.hpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/engine.hpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -214,6 +214,8 @@ namespace GUIEngine { + extern Widget* g_focus_for_player[32]; // unused for player 0, player 0's focus is tracked by irrlicht; + class Screen; class Widget; Modified: main/branches/irrlicht/src/guiengine/skin.cpp =================================================================== --- main/branches/irrlicht/src/guiengine/skin.cpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/skin.cpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -573,7 +573,8 @@ const bool parent_focused = GUIEngine::getGUIEnv()->getFocus() == widget->m_event_handler->m_element; - RibbonType type = ((RibbonWidget*)widget->m_event_handler)->getRibbonType(); + RibbonWidget* parentRibbon = (RibbonWidget*)widget->m_event_handler; + RibbonType type = parentRibbon->getRibbonType(); /* tab-bar ribbons */ if(type == RIBBON_TABS) @@ -704,40 +705,44 @@ } // end if mark_focused // ---- Draw selection for other players than player 1 - if (parent_focused) - { - if (widget->isFocusedForPlayer(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) { - if (nPlayersOnThisItem > 0) - { - 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(w, rect2, SkinConfig::m_render_params["squareFocusHalo2::neutral"]); - } - else - { - drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["squareFocusHalo2::neutral"]); - } - - nPlayersOnThisItem++; + // 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(w, rect2, SkinConfig::m_render_params["squareFocusHalo2::neutral"]); } - - if (widget->isFocusedForPlayer(2)) + else { - drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["squareFocusHalo3::neutral"]); - nPlayersOnThisItem++; + drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["squareFocusHalo2::neutral"]); } - if (widget->isFocusedForPlayer(3)) - { - drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["squareFocusHalo4::neutral"]); - } + nPlayersOnThisItem++; } + if (parentRibbon->isFocusedForPlayer(2) && parentRibbon->getSelectionIDString(2) == widget->m_properties[PROP_ID]) + { + drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["squareFocusHalo3::neutral"]); + nPlayersOnThisItem++; + } + + if (parentRibbon->isFocusedForPlayer(3) && parentRibbon->getSelectionIDString(3) == widget->m_properties[PROP_ID]) + { + drawBoxFromStretchableTexture(w, rect, SkinConfig::m_render_params["squareFocusHalo4::neutral"]); + } + } // end if icon ribbons } Modified: main/branches/irrlicht/src/guiengine/widget.cpp =================================================================== --- main/branches/irrlicht/src/guiengine/widget.cpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/widget.cpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -81,7 +81,8 @@ for (int n=0; n<32; n++) { - m_special_focus[n] = false; + m_player_focus[n] = false; + GUIEngine::g_focus_for_player[n] = false; } if (reserve_id) @@ -99,19 +100,34 @@ * Since the code tracks focus from main player, this will most likely be used only * for additionnal players */ -void Widget::setFocusForPlayer(const int playerID, const bool focused) +void Widget::setFocusForPlayer(const int playerID) { - m_special_focus[playerID] = focused; + std::cout << "=========== setFocusForPlayer " << playerID << " : " << m_properties[PROP_ID].c_str() << " =============\n"; + + // Unset focus flag on previous widget that had focus + if (GUIEngine::g_focus_for_player[playerID] != NULL) + { + GUIEngine::g_focus_for_player[playerID]->m_player_focus[playerID] = false; + } + + m_player_focus[playerID] = true; + GUIEngine::g_focus_for_player[playerID] = this; } + /** * \param playerID ID of the player you want to set/unset focus for, starting from 0 */ bool Widget::isFocusedForPlayer(const int playerID) { - return m_special_focus[playerID]; + return m_player_focus[playerID]; } - + +void Widget::requestFocus() +{ + GUIEngine::getGUIEnv()->setFocus(m_element); +} + /** * Receives as string the raw property value retrieved from XML file. * Will try to make sense of it, as an absolute value or a percentage. Modified: main/branches/irrlicht/src/guiengine/widget.hpp =================================================================== --- main/branches/irrlicht/src/guiengine/widget.hpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/widget.hpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -168,7 +168,7 @@ /** Usually, only one widget at a time can be focused. There is however a special case where all players can move through the screen. This variable will then be used as a bitmask to contain which players beyong player 1 have this widget focused. */ - bool m_special_focus[32]; // FIXME : the 32 there is arbitrary, settle for a max number of players + bool m_player_focus[32]; // FIXME : the 32 there is arbitrary, settle for a max number of players public: /** @@ -244,7 +244,7 @@ /** * \param playerID ID of the player you want to set/unset focus for, starting from 0 */ - void setFocusForPlayer(const int playerID, const bool focused); + void setFocusForPlayer(const int playerID); /** * \param playerID ID of the player you want to set/unset focus for, starting from 0 @@ -259,6 +259,8 @@ bool isSelected() const { return m_selected; } + void requestFocus(); + /** * Override in children to possibly receive updates (you may need to register to Modified: main/branches/irrlicht/src/guiengine/widgets/ribbon_grid_widget.cpp =================================================================== --- main/branches/irrlicht/src/guiengine/widgets/ribbon_grid_widget.cpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/widgets/ribbon_grid_widget.cpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -18,6 +18,9 @@ #include "guiengine/engine.hpp" #include "guiengine/widgets/ribbon_grid_widget.hpp" #include "io/file_manager.hpp" + +#include <sstream> + using namespace GUIEngine; #ifndef round @@ -176,7 +179,7 @@ m_right_widget->m_element->setVisible(true); } - // add rows + // ---- add rows for (int n=0; n<m_row_amount; n++) { RibbonWidget* ribbon; @@ -195,7 +198,10 @@ ribbon->w = w - m_arrows_w*2; ribbon->h = (int)(row_height); ribbon->m_type = WTYPE_RIBBON; - ribbon->m_properties[PROP_ID] = this->m_properties[PROP_ID]; + + std::stringstream name; + name << this->m_properties[PROP_ID] << "_row" << n; + ribbon->m_properties[PROP_ID] = name.str(); ribbon->m_event_handler = this; // add columns @@ -238,7 +244,7 @@ const std::string& RibbonGridWidget::getSelectionIDString(const int playerID) { - RibbonWidget* row = (RibbonWidget*)(m_rows.size() == 1 ? m_rows.get(0) : getSelectedRibbon()); + RibbonWidget* row = (RibbonWidget*)(m_rows.size() == 1 ? m_rows.get(0) : getSelectedRibbon(playerID)); if(row != NULL) return row->getSelectionIDString(playerID); @@ -248,7 +254,7 @@ // ----------------------------------------------------------------------------- const std::string& RibbonGridWidget::getSelectionText(const int playerID) { - RibbonWidget* row = (RibbonWidget*)(m_rows.size() == 1 ? m_rows.get(0) : getSelectedRibbon()); + RibbonWidget* row = (RibbonWidget*)(m_rows.size() == 1 ? m_rows.get(0) : getSelectedRibbon(playerID)); if(row != NULL) return row->getSelectionText(playerID); @@ -271,18 +277,34 @@ return NULL; } // ----------------------------------------------------------------------------- -RibbonWidget* RibbonGridWidget::getSelectedRibbon() const -{ - const int row_amount = m_rows.size(); - for(int n=0; n<row_amount; n++) +RibbonWidget* RibbonGridWidget::getSelectedRibbon(const int playerID) const +{ + if (playerID == 0) { - const RibbonWidget* row = &m_rows[n]; - if(row != NULL) + const int row_amount = m_rows.size(); + for(int n=0; n<row_amount; n++) { - if( GUIEngine::getGUIEnv()->hasFocus(row->m_element) || - m_element->isMyChild( GUIEngine::getGUIEnv()->getFocus() ) ) return (RibbonWidget*)row; + const RibbonWidget* row = &m_rows[n]; + if(row != NULL) + { + if( GUIEngine::getGUIEnv()->hasFocus(row->m_element) || + m_element->isMyChild( GUIEngine::getGUIEnv()->getFocus() ) ) return (RibbonWidget*)row; + } } } + else + { + const int row_amount = m_rows.size(); + for(int n=0; n<row_amount; n++) + { + const RibbonWidget* row = &m_rows[n]; + if (row == GUIEngine::g_focus_for_player[playerID]) + { + return (RibbonWidget*)row; + } + } + + } return NULL; } @@ -299,7 +321,7 @@ // ----------------------------------------------------------------------------- bool RibbonGridWidget::rightPressed(const int playerID) { - RibbonWidget* w = getSelectedRibbon(); + RibbonWidget* w = getSelectedRibbon(playerID); if (w != NULL) { updateLabel(); @@ -309,7 +331,7 @@ const int listenerAmount = m_hover_listeners.size(); for (int n=0; n<listenerAmount; n++) { - m_hover_listeners[n].onSelectionChanged(this, getSelectedRibbon()->getSelectionIDString(playerID), playerID); + m_hover_listeners[n].onSelectionChanged(this, getSelectedRibbon(playerID)->getSelectionIDString(playerID), playerID); } } @@ -320,7 +342,7 @@ // ----------------------------------------------------------------------------- bool RibbonGridWidget::leftPressed(const int playerID) { - RibbonWidget* w = getSelectedRibbon(); + RibbonWidget* w = getSelectedRibbon(playerID); if (w != NULL) { updateLabel(); @@ -355,7 +377,7 @@ // find selection in current ribbon if (m_combo) { - RibbonWidget* selected_ribbon = (RibbonWidget*)getSelectedRibbon(); + RibbonWidget* selected_ribbon = (RibbonWidget*)getSelectedRibbon(playerID); if (selected_ribbon != NULL) { m_selected_item[playerID] = selected_ribbon->m_selection[playerID] + m_scroll_offset; @@ -371,14 +393,15 @@ updateLabel(); propagateSelection(); - if (getSelectedRibbon() != NULL) + // FIXME: don't hardcode player 0 + const int playerID = 0; + + if (getSelectedRibbon(playerID) != NULL) { const int listenerAmount = m_hover_listeners.size(); for (int n=0; n<listenerAmount; n++) { - // FIXME: don't hardcode player 0 - const int playerID = 0; - m_hover_listeners[n].onSelectionChanged(this, getSelectedRibbon()->getSelectionIDString(playerID), playerID); + m_hover_listeners[n].onSelectionChanged(this, getSelectedRibbon(playerID)->getSelectionIDString(playerID), playerID); } } @@ -395,7 +418,7 @@ { // FIXME: don't hardcode player 0 const int playerID = 0; - m_hover_listeners[n].onSelectionChanged(this, getSelectedRibbon()->getSelectionIDString(playerID), playerID); + m_hover_listeners[n].onSelectionChanged(this, getSelectedRibbon(playerID)->getSelectionIDString(playerID), playerID); } } // ----------------------------------------------------------------------------- @@ -450,12 +473,12 @@ used to ensure that all children ribbons always select the same column */ void RibbonGridWidget::propagateSelection() { - // find selection in current ribbon - RibbonWidget* selected_ribbon = (RibbonWidget*)getSelectedRibbon(); - if (selected_ribbon == NULL) return; - for (int p=0; p<32; p++) { + // find selection in current ribbon + RibbonWidget* selected_ribbon = (RibbonWidget*)getSelectedRibbon(p); + if (selected_ribbon == NULL) continue; + const int relative_selection = selected_ribbon->m_selection[p]; if (m_combo) @@ -483,11 +506,13 @@ { if (!m_has_label) return; - RibbonWidget* row = from_this_ribbon ? from_this_ribbon : (RibbonWidget*)getSelectedRibbon(); + // FIXME? Don't hardcode player 0 (even though label can only work with a single player) + const int playerID = 0; + + RibbonWidget* row = from_this_ribbon ? from_this_ribbon : (RibbonWidget*)getSelectedRibbon(playerID); if (row == NULL) return; - // FIXME? Don't hardcode player 0 (even though label can only work with a single player) - std::string selection_id = row->getSelectionIDString(0); + std::string selection_id = row->getSelectionIDString(playerID); const int amount = m_items.size(); for (int n=0; n<amount; n++) @@ -587,5 +612,32 @@ void RibbonGridWidget::setSelection(int item_id, const int playerID) { m_selected_item[playerID] = item_id; + + + const std::string& name = m_items[item_id].m_code_name; + + int row = -1; + int id; + + for (int r=0; r<m_row_amount; r++) + { + id = m_rows[r].findItemNamed(name.c_str()); + if (id > -1) + { + row = r; + break; + } + } + + if (row == -1) + { + std::cerr << "RibbonGridWidget::setSelection cannot find item " << item_id << " (" << name.c_str() << ")\n"; + return; + } + + std::cout << "Player " << playerID << " has kart " << item_id << " (" << name.c_str() << ") in row " << row << std::endl; + m_rows[row].setSelection(id, playerID); + m_rows[row].setFocusForPlayer(playerID); + propagateSelection(); } Modified: main/branches/irrlicht/src/guiengine/widgets/ribbon_grid_widget.hpp =================================================================== --- main/branches/irrlicht/src/guiengine/widgets/ribbon_grid_widget.hpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/widgets/ribbon_grid_widget.hpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -59,10 +59,6 @@ virtual ~RibbonGridWidget() {} - /** Reference pointers only, the actual instances are owned by m_children. Used to create mtultiple-row - ribbons (what appears to be a grid of icons is actually a vector of stacked basic ribbons) */ - ptr_vector<RibbonWidget, REF> m_rows; - /** Used for ribbon grids that have a label at the bottom */ bool m_has_label; IGUIStaticText* m_label; @@ -110,7 +106,7 @@ Widget* m_right_widget; /** Returns the currently selected row */ - RibbonWidget* getSelectedRibbon() const; + RibbonWidget* getSelectedRibbon(const int playerID) const; /** Returns the row */ RibbonWidget* getRowContaining(Widget* w) const; @@ -146,6 +142,10 @@ public: RibbonGridWidget(const bool combo=false, const int max_rows=4); + /** Reference pointers only, the actual instances are owned by m_children. Used to create mtultiple-row + ribbons (what appears to be a grid of icons is actually a vector of stacked basic ribbons) */ + ptr_vector<RibbonWidget, REF> m_rows; + /** Dynamically add an item to the ribbon's list of items (will not be visible until you call 'updateItemDisplay' or 'add') */ void addItem( std::string user_name, std::string code_name, std::string image_file ); Modified: main/branches/irrlicht/src/guiengine/widgets/ribbon_widget.cpp =================================================================== --- main/branches/irrlicht/src/guiengine/widgets/ribbon_widget.cpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/widgets/ribbon_widget.cpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -288,7 +288,16 @@ updateSelection(); return false; } + // ----------------------------------------------------------------------------- +const std::string& RibbonWidget::getSelectionIDString(const int playerID) +{ + static std::string empty; + if (m_selection[playerID] == -1) return empty; + return m_children[m_selection[playerID]].m_properties[PROP_ID]; +} + +// ----------------------------------------------------------------------------- void RibbonWidget::updateSelection() { const int subbuttons_amount = m_children.size(); @@ -297,15 +306,6 @@ { // Player 0 selection m_children[i].m_selected = (i == m_selection[0]); - - // Other player selection (FIXME: merge with player 0 selection) - for (int n=1; n<32; n++) - { - if (i == m_selection[n]) - m_children[i].setFocusForPlayer(n, true); - else - m_children[i].setFocusForPlayer(n, false); - } } // FIXME: don't hardcode player 0 @@ -341,3 +341,13 @@ assert(id < m_labels.size()); m_labels[id].setText( stringw(new_name.c_str()).c_str() ); } +// ----------------------------------------------------------------------------- +int RibbonWidget::findItemNamed(const char* internalName) +{ + const int size = m_children.size(); + for (int n=0; n<size; n++) + { + if (m_children[n].m_properties[PROP_ID] == internalName) return n; + } + return -1; +} Modified: main/branches/irrlicht/src/guiengine/widgets/ribbon_widget.hpp =================================================================== --- main/branches/irrlicht/src/guiengine/widgets/ribbon_widget.hpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/guiengine/widgets/ribbon_widget.hpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -82,7 +82,7 @@ int getSelection(const int playerID) const { return m_selection[playerID]; } /** Returns the string ID (internal name) of the selection */ - const std::string& getSelectionIDString(const int playerID) { return m_children[m_selection[playerID]].m_properties[PROP_ID]; } + const std::string& getSelectionIDString(const int playerID); /** Returns the user-visible text of the selection */ const std::string& getSelectionText(const int playerID) { return m_children[m_selection[playerID]].m_properties[PROP_TEXT]; } @@ -99,6 +99,8 @@ superclasses/wrappers of this do.) */ void setLabel(const int id, std::string new_name); + /** Returns the ID of the item, or -1 if not found */ + int findItemNamed(const char* internalName); }; } Modified: main/branches/irrlicht/src/states_screens/kart_selection.cpp =================================================================== --- main/branches/irrlicht/src/states_screens/kart_selection.cpp 2009-08-27 19:00:10 UTC (rev 3934) +++ main/branches/irrlicht/src/states_screens/kart_selection.cpp 2009-08-27 20:17:59 UTC (rev 3935) @@ -399,30 +399,6 @@ public: void onSelectionChanged(RibbonGridWidget* theWidget, const std::string& selectionID, const int playerID) { - std::cout << "Player " << playerID << " selected kart " << selectionID.c_str() << std::endl; - /* - InputDevice *device; - ActivePlayer *player; - int pKartIndex = -1; - //std::cout << "hovered " << selectionID.c_str() << std::endl; - - - device = input_manager->getDeviceList()->getLatestUsedDevice(); - if (selectionID.size() == 0) return; - if ((player = device->getPlayer()) == NULL) return; - - for (int n = 0; (n < g_player_karts.size() && pKartIndex == -1); n++) - { - if (g_player_karts[n].m_associatedPlayer == player) - pKartIndex = n; - } - if (pKartIndex == -1) - { - fprintf(stderr, "onSelectionChanged(): Unable to determine kart associated with device\n"); - return; - } - */ - ModelViewWidget* w3 = g_player_karts[playerID].modelView; assert( w3 != NULL ); @@ -631,6 +607,7 @@ w->addItem(prop->getName().c_str(), prop->getIdent().c_str(), icon_path.c_str()); } } + getCurrentScreen()->m_inited = true; } @@ -661,6 +638,10 @@ w->updateItemDisplay(); } + // Player 0 select first kart (Tux) + w->setSelection(0, 0); + w->m_rows[0].requestFocus(); + getCurrentScreen()->m_inited = true; } // end if init This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |