// ----------------------------------------------------------------------------
void AddonsScreen::eventCallback(GUIEngine::Widget* widget, 
                                 const std::string& name, const int playerID)
{
    if (name == "back")
    {
        StateManager::get()->escapePressed();
    }

    else if (name == "reload")
    {
        if (!m_reloading)
        {
            m_reloading = true;
            INetworkHttp::get()->insertReInit();
            
            GUIEngine::ListWidget* w_list = 
            getWidget<GUIEngine::ListWidget>("list_addons");
            w_list->clear();
            
            w_list->addItem("spacer", L"");
            w_list->addItem("loading",
                            _("Please wait while addons are updated"),
                            m_icon_loading);
        }
    }

    else if (name == "list_addons")
    {
        GUIEngine::ListWidget* list = 
            getWidget<GUIEngine::ListWidget>("list_addons");
        std::string id = list->getSelectionInternalName();

        if (!id.empty() && addons_manager->getAddon(id) != NULL)
        {
            m_selected_index = list->getSelectionID();
            new AddonsLoading(0.8f, 0.8f, id);
        }
    }
    if (name == "category")
    {
        std::string selection = ((GUIEngine::RibbonWidget*)widget)
                         ->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str();
        if (selection == "tab_track")
        {
            m_type = "track";
            loadList();
        }
        else if (selection == "tab_kart")
        {
            m_type = "kart";
            loadList();
        }
        else if (selection == "tab_arena")
        {
            m_type = "arena";
            loadList();
        }
    }
}   // eventCallback
/** Selects the last selected item on the list (which is the item that
 *  is just being installed) again. This function is used from the
 *  addons_loading screen: when it is closed, it will reset the
 *  select item so that people can keep on installing from that
 *  point on.
*/
void AddonsScreen::setLastSelected()
{
    if(m_selected_index>-1)
    {
        GUIEngine::ListWidget* list = 
            getWidget<GUIEngine::ListWidget>("list_addons");
        list->setSelectionID(m_selected_index);
    }
}   // setLastSelected
Example #3
0
/** Selects the last selected item on the list (which is the item that
 *  is just being installed) again. This function is used from the
 *  addons_loading screen: when it is closed, it will reset the
 *  select item so that people can keep on installing from that
 *  point on.
*/
void AddonsScreen::setLastSelected()
{
    if(m_selected_index>-1)
    {
        GUIEngine::ListWidget* list =
            getWidget<GUIEngine::ListWidget>("list_addons");
        list->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
        list->setSelectionID(m_selected_index);
    }
}   // setLastSelected
void OptionsScreenInput::buildDeviceList()
{
    GUIEngine::ListWidget* devices = this->getWidget<GUIEngine::ListWidget>("devices");
    assert( devices != NULL );

    assert( m_icon_bank != NULL );
    devices->setIcons(m_icon_bank);

    const int keyboard_config_count = input_manager->getDeviceList()->getKeyboardConfigAmount();

    for (int i=0; i<keyboard_config_count; i++)
    {
        //KeyboardConfig *config = input_manager->getDeviceList()->getKeyboardConfig(i);

        std::ostringstream kbname;
        kbname << "keyboard" << i;
        const std::string internal_name = kbname.str();

        // since irrLicht's list widget has the nasty tendency to put the
        // icons very close to the text, I'm adding spaces to compensate.
        devices->addItem(internal_name, (core::stringw("   ") + _("Keyboard %i", i)).c_str(), 0 /* icon */);
    }

    const int gpad_config_count = input_manager->getDeviceList()->getGamePadConfigAmount();

    for (int i = 0; i < gpad_config_count; i++)
    {
        GamepadConfig *config = input_manager->getDeviceList()->getGamepadConfig(i);

        // Don't display the configuration if a matching device is not available
        if (config->isPlugged())
        {
            // since irrLicht's list widget has the nasty tendency to put the
            // icons very close to the text, I'm adding spaces to compensate.
            irr::core::stringw name = ("   " + config->getName()).c_str();

            if (config->getNumberOfDevices() > 1)
            {
                name += core::stringw(L" (x");
                name += config->getNumberOfDevices();
                name += core::stringw(L")");
            }

            std::ostringstream gpname;
            gpname << "gamepad" << i;
            const std::string internal_name = gpname.str();

            const int icon = (config->isEnabled() ? 1 : 2);

            devices->addItem(internal_name, name, icon);
        }   // if config->isPlugged
    }   // for i<gpad_config_count
}   // buildDeviceList
// ----------------------------------------------------------------------------
void OptionsScreenInput2::eventCallback(Widget* widget,
                                        const std::string& name,
                                        const int playerID)
{
    //const std::string& screen_name = getName();

    StateManager *sm = StateManager::get();
    if (name == "options_choice")
    {
        std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);

        Screen *screen = NULL;
        if (selection == "tab_audio")
            screen = OptionsScreenAudio::getInstance();
        //else if (selection == "tab_video")
        //    screen = OptionsScreenVideo::getInstance();
        else if (selection == "tab_players")
            screen = TabbedUserScreen::getInstance();
        //else if (selection == "tab_controls")
        //    screen = OptionsScreenInput::getInstance();
        else if (selection == "tab_ui")
            screen = OptionsScreenUI::getInstance();
        if(screen)
            StateManager::get()->replaceTopMostScreen(screen);
    }
    else if (name == "back_to_device_list")
    {
        sm->replaceTopMostScreen(OptionsScreenInput::getInstance());
    }
    else if (name == "back")
    {
        sm->replaceTopMostScreen(OptionsScreenInput::getInstance());
    }
    else if (name == "actions")
    {
        GUIEngine::ListWidget* actions =
            getWidget<GUIEngine::ListWidget>("actions");
        assert( actions != NULL );

        // a player action in the list was clicked. find which one
        const std::string& clicked = actions->getSelectionInternalName();
        for (int n=PA_BEFORE_FIRST+1; n<PA_COUNT; n++)
        {
            if (KartActionStrings[n] == clicked)
            {
                // we found which one. show the "press a key" dialog.
                if (UserConfigParams::logMisc())
                {
                    Log::info("OptionsScreenInput2", "Entering sensing mode for %s",
                         m_config->getName().c_str());
                }

                binding_to_set = (PlayerAction)n;

                new PressAKeyDialog(0.4f, 0.4f);

                if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD)
                {
                    input_manager->setMode(InputManager::INPUT_SENSE_KEYBOARD);
                }
                else if (m_config->getType() == DEVICE_CONFIG_TYPE_GAMEPAD)
                {
                    input_manager->setMode(InputManager::INPUT_SENSE_GAMEPAD);
                }
                else
                {
                    Log::error("OptionsScreenInput2", "Unknown selection device in options: %s",
                        m_config->getName().c_str());
                }
                break;
            }
        }
    }
    else if (name == "delete")
    {
        if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD)
        {
           // keyboard configs may be deleted
           //I18N: shown before deleting an input configuration
            new MessageDialog( _("Are you sure you want to permanently delete "
                                 "this configuration?"),
                MessageDialog::MESSAGE_DIALOG_CONFIRM, this, false );
        }
        else
        {
            // gamepad configs may be disabled
            if (m_config->isEnabled())  m_config->setEnabled(false);
            else                        m_config->setEnabled(true);

            // update widget label
            ButtonWidget* deleteBtn = getWidget<ButtonWidget>("delete");
            deleteBtn->setLabel(m_config->isEnabled() ? _("Disable Device")
                                                      : _("Enable Device")  );

            input_manager->getDeviceList()->serialize();
        }
    }

}   // eventCallback
void OptionsScreenInput2::updateInputButtons()
{
    assert(m_config != NULL);

    //TODO: detect duplicates

    GUIEngine::ListWidget* actions =
        getWidget<GUIEngine::ListWidget>("actions");
    assert( actions != NULL );

    int i = 0;
    i++; // section header

    //I18N: Key binding name
    renameRow(actions, i++, _("Steer Left"), PA_STEER_LEFT);

    //I18N: Key binding name
    renameRow(actions, i++, _("Steer Right"), PA_STEER_RIGHT);

    //I18N: Key binding name
    renameRow(actions, i++, _("Accelerate"), PA_ACCEL);

    //I18N: Key binding name
    renameRow(actions, i++, _("Brake"), PA_BRAKE);

    //I18N: Key binding name
    renameRow(actions, i++, _("Fire"), PA_FIRE);

    //I18N: Key binding name
    renameRow(actions, i++, _("Nitro"), PA_NITRO);

    //I18N: Key binding name
    renameRow(actions, i++, _("Skidding"), PA_DRIFT);

    //I18N: Key binding name
    renameRow(actions, i++, _("Look Back"), PA_LOOK_BACK);

    //I18N: Key binding name
    renameRow(actions, i++, _("Rescue"), PA_RESCUE);

    //I18N: Key binding name
    renameRow(actions, i++, _("Pause Game"), PA_PAUSE_RACE);

    i++; // section header

    //I18N: Key binding name
    renameRow(actions, i++, _("Up"), PA_MENU_UP);

    //I18N: Key binding name
    renameRow(actions, i++, _("Down"), PA_MENU_DOWN);

    //I18N: Key binding name
    renameRow(actions, i++, _("Left"), PA_MENU_LEFT);

    //I18N: Key binding name
    renameRow(actions, i++, _("Right"), PA_MENU_RIGHT);

    //I18N: Key binding name
    renameRow(actions, i++, _("Select"), PA_MENU_SELECT);

    //I18N: Key binding name
    renameRow(actions, i++, _("Cancel/Back"), PA_MENU_CANCEL);



    bool conflicts_between = false;
    bool conflicts_inside  = false;
    // ---- make sure there are no binding conflicts
    // (same key used for two actions)
    std::set<irr::core::stringw> currentlyUsedKeys;
    for (PlayerAction action = PA_FIRST_GAME_ACTION;
         action <= PA_LAST_GAME_ACTION;
         action=PlayerAction(action+1))
    {
        const irr::core::stringw item = m_config->getMappingIdString(action);
        if (currentlyUsedKeys.find(item) == currentlyUsedKeys.end())
        {
            currentlyUsedKeys.insert( item );
            if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD
                && conflictsBetweenKbdConfig(action, PA_FIRST_GAME_ACTION,
                                             PA_LAST_GAME_ACTION))
            {
                conflicts_between = true;
                actions->markItemBlue (KartActionStrings[action]);
            }
        }
        else
        {
            // binding conflict!
            actions->markItemRed( KartActionStrings[action] );

            // also mark others
            for (PlayerAction others = PA_FIRST_GAME_ACTION;
                 others < action; others=PlayerAction(others+1))
            {
                const irr::core::stringw others_item =
                    m_config->getMappingIdString(others);
                if (others_item == item)
                {
                    conflicts_inside = true;
                    actions->markItemRed( KartActionStrings[others] );
                }
            }

            //actions->renameItem( KartActionStrings[action],
            //                    _("Binding Conflict!") );
        }
    }

    // menu keys and game keys can overlap, no problem, so forget game keys
    // before checking menu keys
    currentlyUsedKeys.clear();
    for (PlayerAction action = PA_FIRST_MENU_ACTION;
         action <= PA_LAST_MENU_ACTION;
         action=PlayerAction(action+1))
    {
        const irr::core::stringw item = m_config->getBindingAsString(action);
        if (currentlyUsedKeys.find(item) == currentlyUsedKeys.end())
        {
            currentlyUsedKeys.insert( item );
            if (m_config->getType() == DEVICE_CONFIG_TYPE_KEYBOARD
                && conflictsBetweenKbdConfig(action, PA_FIRST_MENU_ACTION,
                                             PA_LAST_MENU_ACTION))
            {
                conflicts_between = true;
                actions->markItemBlue (KartActionStrings[action]);
            }
        }
        else
        {
            // binding conflict!
            actions->markItemRed( KartActionStrings[action] );

            // also mark others
            for (PlayerAction others = PA_FIRST_MENU_ACTION;
                 others < action; others=PlayerAction(others+1))
            {
                const irr::core::stringw others_item =
                    m_config->getBindingAsString(others);
                if (others_item == item)
                {
                    conflicts_inside = true;
                    actions->markItemRed( KartActionStrings[others] );
                }
            }

            //actions->renameItem( KartActionStrings[action],
            //                     _("Binding Conflict!") );
        }
    }

    GUIEngine::Widget* conflict_label =
        getWidget<GUIEngine::LabelWidget>("conflict");

    std::wostringstream oss;
    if (conflicts_between)
    {
        oss << _("* A blue item means a conflict with another configuration");
        if (conflicts_inside)
            oss << "\n";
    }
    if (conflicts_inside)
        oss << _("* A red item means a conflict in the current configuration");
    conflict_label->setText(oss.str().c_str());

}   // updateInputButtons
void OptionsScreenInput2::init()
{
    Screen::init();
    RibbonWidget* tabBar = getWidget<RibbonWidget>("options_choice");
    if (tabBar != NULL)  tabBar->select( "tab_controls",
                                        PLAYER_ID_GAME_MASTER );

    tabBar->getRibbonChildren()[0].setTooltip( _("Graphics") );
    tabBar->getRibbonChildren()[1].setTooltip( _("Audio") );
    tabBar->getRibbonChildren()[2].setTooltip( _("User Interface") );
    tabBar->getRibbonChildren()[3].setTooltip( _("Players") );


    ButtonWidget* deleteBtn = getWidget<ButtonWidget>("delete");
    if (m_config->getType() != DEVICE_CONFIG_TYPE_KEYBOARD)
    {
        core::stringw label = (m_config->isEnabled()
                            ? //I18N: button to disable a gamepad configuration
                              _("Disable Device")
                            : //I18N: button to enable a gamepad configuration
                              _("Enable Device"));

        // Make sure button is wide enough as the text is being changed away
        // from the original value
        core::dimension2d<u32> size =
            GUIEngine::getFont()->getDimension(label.c_str());
        const int needed = size.Width + deleteBtn->getWidthNeededAroundLabel();
        if (deleteBtn->m_w < needed) deleteBtn->m_w = needed;

        deleteBtn->setLabel(label);
    }
    else
    {
        deleteBtn->setLabel(_("Delete Configuration"));

        if (input_manager->getDeviceList()->getKeyboardAmount() < 2)
        {
            // don't allow deleting the last config
            deleteBtn->setDeactivated();
        }
        else
        {
            deleteBtn->setActivated();
        }
    }

    // Make the two buttons the same length, not strictly needed but will
    // look nicer...
    ButtonWidget* backBtn = getWidget<ButtonWidget>("back_to_device_list");
    if (backBtn->m_w < deleteBtn->m_w) backBtn->m_w   = deleteBtn->m_w;
    else                               deleteBtn->m_w = backBtn->m_w;

    backBtn->moveIrrlichtElement();
    deleteBtn->moveIrrlichtElement();

    LabelWidget* label = getWidget<LabelWidget>("title");
    label->setText( m_config->getName().c_str(), false );

    GUIEngine::ListWidget* actions =
        getWidget<GUIEngine::ListWidget>("actions");
    assert( actions != NULL );

    // ---- create list skeleton (right number of items, right internal names)
    //      their actualy contents will be adapted as needed after

    //I18N: Key binding section
    actions->addItem("game_keys_section", _("Game Keys") );
    actions->addItem(KartActionStrings[PA_STEER_LEFT],  L"" );
    actions->addItem(KartActionStrings[PA_STEER_RIGHT], L"" );
    actions->addItem(KartActionStrings[PA_ACCEL],       L"" );
    actions->addItem(KartActionStrings[PA_BRAKE],       L"" );
    actions->addItem(KartActionStrings[PA_FIRE],        L"" );
    actions->addItem(KartActionStrings[PA_NITRO],       L"" );
    actions->addItem(KartActionStrings[PA_DRIFT],       L"" );
    actions->addItem(KartActionStrings[PA_LOOK_BACK],   L"" );
    actions->addItem(KartActionStrings[PA_RESCUE],      L"" );
    actions->addItem(KartActionStrings[PA_PAUSE_RACE],  L"" );


    //I18N: Key binding section
    actions->addItem("menu_keys_section", _("Menu Keys") );
    actions->addItem(KartActionStrings[PA_MENU_UP],     L"" );
    actions->addItem(KartActionStrings[PA_MENU_DOWN],   L"" );
    actions->addItem(KartActionStrings[PA_MENU_LEFT],   L"" );
    actions->addItem(KartActionStrings[PA_MENU_RIGHT],  L"" );
    actions->addItem(KartActionStrings[PA_MENU_SELECT], L"");
    actions->addItem(KartActionStrings[PA_MENU_CANCEL], L"" );

    updateInputButtons();
}   // init