diff --git a/src/gui/kart_selection.cpp b/src/gui/kart_selection.cpp index 12a942b71..718c75536 100644 --- a/src/gui/kart_selection.cpp +++ b/src/gui/kart_selection.cpp @@ -49,12 +49,16 @@ namespace StateManager class PlayerKartWidget : public Widget { + ActivePlayer* m_associatedPlayer; public: LabelWidget* playerIDLabel; SpinnerWidget* playerName; ModelViewWidget* modelView; LabelWidget* kartName; + int playerID; + std::string spinnerID; + int player_id_x, player_id_y, player_id_w, player_id_h; int player_name_x, player_name_y, player_name_w, player_name_h; int model_x, model_y, model_w, model_h; @@ -62,8 +66,12 @@ namespace StateManager int target_x, target_y, target_w, target_h; - PlayerKartWidget(Widget* area, const int playerID) : Widget() + PlayerKartWidget(ActivePlayer* associatedPlayer, Widget* area, const int playerID) : Widget() { + m_associatedPlayer = associatedPlayer; + + this->playerID = playerID; + // FIXME : if a player removes itself, all IDs need to be updated this->m_properties[PROP_ID] = StringUtils::insert_values("@p%i", playerID); @@ -90,14 +98,18 @@ namespace StateManager playerName->w = player_name_w; playerName->h = player_name_h; + spinnerID = StringUtils::insert_values("@p%i_spinner", playerID); + const int playerAmount = UserConfigParams::m_player.size(); playerName->m_properties[PROP_MIN_VALUE] = "0"; playerName->m_properties[PROP_MAX_VALUE] = (playerAmount-1); - playerName->m_properties[PROP_ID] = StringUtils::insert_values("@p%i_spinner", playerID); + playerName->m_properties[PROP_ID] = spinnerID; //playerName->setParent(this); m_children.push_back(playerName); + playerName->m_event_handler = this; + modelView = new ModelViewWidget(); modelView->x = model_x; @@ -227,6 +239,35 @@ namespace StateManager } + virtual bool transmitEvent(Widget* w, std::string& originator) + { + if (w->m_event_handler != NULL && w->m_event_handler != this) + { + if (!w->m_event_handler->transmitEvent(w, originator)) return false; + } + + Widget* topmost = w; + /* Find topmost parent. Stop looping if a widget event handler's is itself, to not fall + in an infinite loop (this can happen e.g. in checkboxes, where they need to be + notified of clicks onto themselves so they can toggle their state. ) + */ + while(topmost->m_event_handler != NULL && topmost->m_event_handler != topmost) + { + topmost = topmost->m_event_handler; + + std::string name = topmost->m_properties[PROP_ID]; + + if (name == spinnerID) + { + m_associatedPlayer->setPlayer( UserConfigParams::m_player.get(playerName->getValue()) ); + return false; // do not continue propagating the event + } + + } + + return true; // continue propagating the event + } + void setSize(const int x, const int y, const int w, const int h) { this->x = x; @@ -314,12 +355,16 @@ void firePressedOnNewDevice(InputDevice* device) Widget rightarea = *getCurrentScreen()->getWidget("playerskarts"); rightarea.x = irr_driver->getFrameSize().Width; + ActivePlayer* aplayer = new ActivePlayer( UserConfigParams::m_player.get(0) ); + // FIXME : player ID needs to be synced with active player list - PlayerKartWidget* newPlayer = new PlayerKartWidget(&rightarea, g_player_karts.size()); + PlayerKartWidget* newPlayer = new PlayerKartWidget(aplayer, &rightarea, g_player_karts.size()); getCurrentScreen()->manualAddWidget(newPlayer); g_player_karts.push_back(newPlayer); newPlayer->add(); + StateManager::addActivePlayer(aplayer); + const int amount = g_player_karts.size(); Widget* fullarea = getCurrentScreen()->getWidget("playerskarts"); @@ -351,7 +396,6 @@ void setPlayer0Device(InputDevice* device) std::cout << "Player 0 is using a gamepad\n"; } - // TODO : support more than 1 player ActivePlayer* newPlayer = new ActivePlayer(UserConfigParams::m_player.get(0)); StateManager::addActivePlayer( newPlayer ); newPlayer->setDevice(device); @@ -407,8 +451,8 @@ void menuEventKarts(Widget* widget, std::string& name) w->addItem(prop->getName().c_str(), prop->getIdent().c_str(), icon_path.c_str()); } - - PlayerKartWidget* playerKart1 = new PlayerKartWidget(area, 0 /* first player */); + + PlayerKartWidget* playerKart1 = new PlayerKartWidget(StateManager::getActivePlayers().get(0), area, 0 /* first player */); getCurrentScreen()->manualAddWidget(playerKart1); playerKart1->add(); g_player_karts.push_back(playerKart1); @@ -426,6 +470,14 @@ void menuEventKarts(Widget* widget, std::string& name) RibbonGridWidget* w = getCurrentScreen()->getWidget("karts"); assert( w != NULL ); + ptr_vector< ActivePlayer, HOLD >& players = StateManager::getActivePlayers(); + std::cout << "==========\n" << players.size() << " players :\n"; + for(int n=0; ngetName() << std::endl; + } + std::cout << "==========\n"; + g_player_karts.clearWithoutDeleting(); race_manager->setLocalKartInfo(0, w->getSelectionIDString()); diff --git a/src/gui/state_manager.cpp b/src/gui/state_manager.cpp index dbe42a879..18f82485d 100644 --- a/src/gui/state_manager.cpp +++ b/src/gui/state_manager.cpp @@ -56,7 +56,7 @@ namespace StateManager */ ptr_vector g_active_players; - const ptr_vector& getActivePlayers() + ptr_vector& getActivePlayers() { return g_active_players; } diff --git a/src/gui/state_manager.hpp b/src/gui/state_manager.hpp index 4d4c3e4d0..d34f89160 100644 --- a/src/gui/state_manager.hpp +++ b/src/gui/state_manager.hpp @@ -37,7 +37,7 @@ namespace StateManager bool isGameState(); void reshowTopMostMenu(); - const ptr_vector& getActivePlayers(); + ptr_vector& getActivePlayers(); /** * Adds a new player to the list of active players. StateManager takes ownership of the object diff --git a/src/gui/widget.hpp b/src/gui/widget.hpp index 88d880579..bbcc47dac 100644 --- a/src/gui/widget.hpp +++ b/src/gui/widget.hpp @@ -99,10 +99,6 @@ namespace GUIEngine virtual bool rightPressed() { return false; } virtual bool leftPressed() { return false; } - /** used when you set parents - see m_event_handler explainations below. - returns whether main event callback should be notified or not */ - virtual bool transmitEvent(Widget* w, std::string& originator) { return true; } - /** used when you set eventSupervisors - see m_event_handler explainations below called when one of a widget's children is hovered. Returns 'true' if main event handler should be notified of a change. */ @@ -113,16 +109,6 @@ namespace GUIEngine void readCoords(Widget* parent=NULL); - /** - * This is set to NULL by default; set to something else in a widget to mean - * that events happening on this widget should not go straight into the - * event handler. Instead, they will first be passed to m_event_handler->transmitEvent, - * which is usually the parent analysing events from its children. - * This is especially useful with logical widgets built with more than - * one irrlicht widgets (e.g. Spinner, Ribbon) - */ - Widget* m_event_handler; - IGUIElement* m_parent; static bool convertToCoord(std::string& x, int* absolute, int* percentage); @@ -133,6 +119,16 @@ namespace GUIEngine IGUIElement* m_element; public: + /** + * This is set to NULL by default; set to something else in a widget to mean + * that events happening on this widget should not go straight into the + * event handler. Instead, they will first be passed to m_event_handler->transmitEvent, + * which is usually the parent analysing events from its children. + * This is especially useful with logical widgets built with more than + * one irrlicht widgets (e.g. Spinner, Ribbon) + */ + Widget* m_event_handler; + Widget(); virtual ~Widget() {} @@ -144,6 +140,10 @@ namespace GUIEngine virtual void update(float delta) { } + /** used when you set parents - see m_event_handler explainations below. + returns whether main event callback should be notified or not */ + virtual bool transmitEvent(Widget* w, std::string& originator) { return true; } + /** * Create and add the irrLicht widget(s) associated with this object. * Call after Widget was read from XML file and laid out. diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index a4f4544fc..932b75e4f 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -104,4 +104,4 @@ void CheckStructure::activateNewLapCheck(int kart_index) { if(m_check_type==CT_NEW_LAP) m_is_active[kart_index] = true; -} // resetNewLap \ No newline at end of file +} // resetNewLap