diff --git a/es-app/src/CollectionSystemManager.cpp b/es-app/src/CollectionSystemManager.cpp index 301d009b2..3f015004a 100644 --- a/es-app/src/CollectionSystemManager.cpp +++ b/es-app/src/CollectionSystemManager.cpp @@ -348,9 +348,7 @@ void CollectionSystemManager::updateCollectionSystem(FileData* file, CollectionS // Select the first row of the gamelist (the game just played). IGameListView* gameList = ViewController::get()->getGameListView(getSystemToView(sysData.system)).get(); - FileData* firstRow = - gameList->getCursor()->getParent()->getChildrenListToDisplay()[0]; - gameList->setCursor(firstRow); + gameList->setCursor(gameList->getFirstEntry()); } else { ViewController::get()->onFileChanged(rootFolder, FILE_SORTED); @@ -924,9 +922,7 @@ void CollectionSystemManager::addEnabledCollectionsToDisplayedSystems( IGameListView* gameList = ViewController::get()-> getGameListView((it->second.system)).get(); if (!gameList->getCursor()->isPlaceHolder()) { - FileData* firstRow = gameList->getCursor()-> - getParent()->getChildrenListToDisplay().front(); - gameList->setCursor(firstRow); + gameList->setCursor(gameList->getFirstEntry()); } } } diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index 3a0e54b24..a600c1aea 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -50,7 +50,7 @@ GuiGamelistOptions::GuiGamelistOptions( // Jump to letter quick selector. row.elements.clear(); - // The letter index is generated in FileData during game system sorting. + // The letter index is generated in FileData during gamelist sorting. mFirstLetterIndex = file->getParent()->getFirstLetterIndex(); // Set the quick selector to the first character of the selected game. @@ -240,7 +240,7 @@ void GuiGamelistOptions::jumpToLetter() { char letter = mJumpToLetterList->getSelected().front(); - // Get first row of the gamelist. + // Get the gamelist. const std::vector& files = getGamelist()->getCursor()-> getParent()->getChildrenListToDisplay(); @@ -264,9 +264,7 @@ void GuiGamelistOptions::jumpToLetter() void GuiGamelistOptions::jumpToFirstRow() { // Get first row of the gamelist. - const std::vector& files = getGamelist()->getCursor()-> - getParent()->getChildrenListToDisplay(); - getGamelist()->setCursor(files.at(0)); + getGamelist()->setCursor(getGamelist()->getFirstEntry()); } bool GuiGamelistOptions::input(InputConfig* config, Input input) diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index aa3c4e630..dc3966222 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -338,8 +338,7 @@ void GuiMenu::openUISettings() // Jump to the first row of the gamelist. IGameListView* gameList = ViewController::get()->getGameListView((*it)).get(); - FileData* firstRow = gameList->getCursor()->getParent()->getChildrenListToDisplay()[0]; - gameList->setCursor(firstRow); + gameList->setCursor(gameList->getFirstEntry()); } }); diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index fc6ecf563..1b6e75c38 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -390,6 +390,22 @@ bool ViewController::input(InputConfig* config, Input input) if (!(UIModeController::getInstance()->isUIModeKid() && Settings::getInstance()->getBool("DisableKidStartMenu")) && config->isMappedTo("start", input) && input.value != 0) { + // If we don't stop the scrolling here, it will continue to + // run after closing the menu. + if (mSystemListView->isScrolling()) + mSystemListView->stopScrolling(); + // Finish the animation too, so that it doesn't continue + // to play when we've closed the menu. + if (mSystemListView->isAnimationPlaying(0)) + mSystemListView->finishAnimation(0); +// for (unsigned int i = 0; i > mGameListViews.size(); i++) +// mGameListViews[i].get()->finishAnimation(0); + + for (auto it = mGameListViews.begin(); it != mGameListViews.end(); it++) { + std::string teststring = it->second->getCursor()->getName(); + std::string teststring2; + } + mWindow->pushGui(new GuiMenu(mWindow)); return true; } diff --git a/es-app/src/views/gamelist/BasicGameListView.cpp b/es-app/src/views/gamelist/BasicGameListView.cpp index 0c88238d9..6fec0680f 100644 --- a/es-app/src/views/gamelist/BasicGameListView.cpp +++ b/es-app/src/views/gamelist/BasicGameListView.cpp @@ -107,6 +107,16 @@ void BasicGameListView::setCursor(FileData* cursor) } } +FileData* BasicGameListView::getFirstEntry() +{ + return mList.getFirst(); +} + +FileData* BasicGameListView::getLastEntry() +{ + return mList.getLast(); +} + void BasicGameListView::addPlaceholder() { // Empty list - add a placeholder. diff --git a/es-app/src/views/gamelist/BasicGameListView.h b/es-app/src/views/gamelist/BasicGameListView.h index 1eea37886..3d51fd8f4 100644 --- a/es-app/src/views/gamelist/BasicGameListView.h +++ b/es-app/src/views/gamelist/BasicGameListView.h @@ -23,6 +23,8 @@ public: virtual FileData* getCursor() override; virtual void setCursor(FileData* file) override; + virtual FileData* getFirstEntry() override; + virtual FileData* getLastEntry() override; virtual const char* getName() const override { return "basic"; } diff --git a/es-app/src/views/gamelist/GridGameListView.cpp b/es-app/src/views/gamelist/GridGameListView.cpp index e457e5c81..acb04d5c6 100644 --- a/es-app/src/views/gamelist/GridGameListView.cpp +++ b/es-app/src/views/gamelist/GridGameListView.cpp @@ -153,13 +153,22 @@ FileData* GridGameListView::getCursor() void GridGameListView::setCursor(FileData* file) { - if (!mGrid.setCursor(file)) - { + if (!mGrid.setCursor(file)) { populateList(file->getParent()->getChildrenListToDisplay()); mGrid.setCursor(file); } } +FileData* GridGameListView::getFirstEntry() +{ + return mGrid.getFirst();; +} + +FileData* GridGameListView::getLastEntry() +{ + return mGrid.getLast(); +} + std::string GridGameListView::getQuickSystemSelectRightButton() { return "rightshoulder"; diff --git a/es-app/src/views/gamelist/GridGameListView.h b/es-app/src/views/gamelist/GridGameListView.h index c8a19b806..f0bf01d87 100644 --- a/es-app/src/views/gamelist/GridGameListView.h +++ b/es-app/src/views/gamelist/GridGameListView.h @@ -27,6 +27,8 @@ public: virtual FileData* getCursor() override; virtual void setCursor(FileData*) override; + virtual FileData* getFirstEntry() override; + virtual FileData* getLastEntry() override; virtual bool input(InputConfig* config, Input input) override; diff --git a/es-app/src/views/gamelist/IGameListView.cpp b/es-app/src/views/gamelist/IGameListView.cpp index d37581af8..9bcf020aa 100644 --- a/es-app/src/views/gamelist/IGameListView.cpp +++ b/es-app/src/views/gamelist/IGameListView.cpp @@ -20,6 +20,7 @@ bool IGameListView::input(InputConfig* config, Input input) mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem())); return true; } + // Ctrl-R reloads the view when debugging. else if (Settings::getInstance()->getBool("Debug") && config->getDeviceId() == DEVICE_KEYBOARD && diff --git a/es-app/src/views/gamelist/IGameListView.h b/es-app/src/views/gamelist/IGameListView.h index 3ab837fae..e8dce4c27 100644 --- a/es-app/src/views/gamelist/IGameListView.h +++ b/es-app/src/views/gamelist/IGameListView.h @@ -43,6 +43,8 @@ public: virtual FileData* getCursor() = 0; virtual void setCursor(FileData*) = 0; + virtual FileData* getFirstEntry() = 0; + virtual FileData* getLastEntry() = 0; virtual bool input(InputConfig* config, Input input) override; virtual void remove(FileData* game, bool deleteFile) = 0; diff --git a/es-app/src/views/gamelist/ISimpleGameListView.cpp b/es-app/src/views/gamelist/ISimpleGameListView.cpp index be90c9740..c6eee5642 100644 --- a/es-app/src/views/gamelist/ISimpleGameListView.cpp +++ b/es-app/src/views/gamelist/ISimpleGameListView.cpp @@ -87,8 +87,6 @@ void ISimpleGameListView::onFileChanged(FileData* /*file*/, FileChangeType /*cha bool ISimpleGameListView::input(InputConfig* config, Input input) { - std::shared_ptr soundfile; - if (input.value != 0) { if (config->isMappedTo("a", input)) { FileData* cursor = getCursor(); diff --git a/es-core/src/InputConfig.cpp b/es-core/src/InputConfig.cpp index eb5e59cec..499dbcbae 100644 --- a/es-core/src/InputConfig.cpp +++ b/es-core/src/InputConfig.cpp @@ -126,6 +126,10 @@ bool InputConfig::isMappedLike(const std::string& name, Input input) return isMappedTo("leftshoulder", input) || isMappedTo("pageup", input); }else if(name == "rightshoulder"){ return isMappedTo("rightshoulder", input) || isMappedTo("pagedown", input); + }else if(name == "lefttrigger"){ + return isMappedTo("lefttrigger", input) || isMappedTo("home", input); + }else if(name == "righttrigger"){ + return isMappedTo("righttrigger", input) || isMappedTo("end", input); } return isMappedTo(name, input); } diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index 57c64b404..aa07aeddf 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -324,12 +324,16 @@ void InputManager::loadDefaultKBConfig() cfg->mapInput("right", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHT, 1, true)); cfg->mapInput("a", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RETURN, 1, true)); - cfg->mapInput("b", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_ESCAPE, 1, true)); + cfg->mapInput("b", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_BACKSPACE, 1, true)); + cfg->mapInput("x", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_DELETE, 1, true)); + cfg->mapInput("y", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_INSERT, 1, true)); cfg->mapInput("start", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F1, 1, true)); cfg->mapInput("select", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F2, 1, true)); - cfg->mapInput("leftshoulder", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFTBRACKET, 1, true)); - cfg->mapInput("rightshoulder", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHTBRACKET, 1, true)); + cfg->mapInput("leftshoulder", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_PAGEUP, 1, true)); + cfg->mapInput("rightshoulder", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_PAGEDOWN, 1, true)); + cfg->mapInput("lefttrigger", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_HOME, 1, true)); + cfg->mapInput("righttrigger", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_END, 1, true)); } void InputManager::writeDeviceConfig(InputConfig* config) diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index ecde5c112..c4bbe9e07 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -79,14 +79,26 @@ bool ComponentList::input(InputConfig* config, Input input) } // Input handler didn't consume the input - try to scroll. - if (config->isMappedLike("up", input)) + if (config->isMappedLike("up", input)) { return listInput(input.value != 0 ? -1 : 0); - else if (config->isMappedLike("down", input)) + } + else if (config->isMappedLike("down", input)) { return listInput(input.value != 0 ? 1 : 0); - else if (config->isMappedLike("leftshoulder", input)) + } + else if (config->isMappedLike("leftshoulder", input)) { return listInput(input.value != 0 ? -6 : 0); - else if (config->isMappedLike("rightshoulder", input)) + } + else if (config->isMappedLike("rightshoulder", input)) { return listInput(input.value != 0 ? 6 : 0); + } + else if (config->isMappedLike("lefttrigger", input)) { + mSelectorBarOffset = 0; + return listFirstRow(); + } + else if (config->isMappedLike("righttrigger", input)) { + mSelectorBarOffset = mEntries.size() - 1; + return listLastRow(); + } return false; } diff --git a/es-core/src/components/IList.h b/es-core/src/components/IList.h index b48fb5f98..4d1699886 100644 --- a/es-core/src/components/IList.h +++ b/es-core/src/components/IList.h @@ -129,6 +129,18 @@ public: return mEntries.at(mCursor).object; } + inline const UserData& getFirst() const + { + assert(size() > 0); + return mEntries.front().object; + } + + inline const UserData& getLast() const + { + assert(size() > 0); + return mEntries.back().object; + } + void setCursor(typename std::vector::const_iterator& it) { assert(it != mEntries.cend()); @@ -186,6 +198,19 @@ protected: mEntries.erase(it); } + bool listFirstRow() + { + mCursor = 0; + onCursorChanged(CURSOR_STOPPED); + return true; + } + + bool listLastRow() + { + mCursor = mEntries.size() - 1; + onCursorChanged(CURSOR_STOPPED); + return true; + } bool listInput(int velocity) // a velocity of 0 = stop scrolling { diff --git a/es-core/src/components/TextListComponent.h b/es-core/src/components/TextListComponent.h index 6ce797824..2270706ad 100644 --- a/es-core/src/components/TextListComponent.h +++ b/es-core/src/components/TextListComponent.h @@ -288,15 +288,29 @@ bool TextListComponent::input(InputConfig* config, Input input) listInput(-10); return true; } + + if (config->isMappedLike("righttrigger", input)) { + return this->listLastRow(); + } + + if (config->isMappedLike("lefttrigger", input)) { + return this->listFirstRow(); + } } else { if (config->isMappedLike("down", input) || config->isMappedLike("up", input) || config->isMappedLike("rightshoulder", input) || - config->isMappedLike("leftshoulder", input)) + config->isMappedLike("leftshoulder", input) || + config->isMappedLike("lefttrigger", input) || + config->isMappedLike("righttrigger", input)) stopScrolling(); } } + // Explicitly stop the scrolling, otherwise it will go forever in case + // the menu was openened or another gamelist was selected using the + // quick system selector etc. + stopScrolling(); return GuiComponent::input(config, input); } diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index 0ea60b095..61ee522f9 100755 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -15,7 +15,7 @@ struct InputConfigStructure const char* icon; }; -static const int inputCount = 25; +static const int inputCount = 22; static const InputConfigStructure GUI_INPUT_CONFIG_LIST[inputCount] = { { "Up", false, "D-PAD UP", ":/help/dpad_up.svg" }, @@ -32,8 +32,8 @@ static const InputConfigStructure GUI_INPUT_CONFIG_LIST[inputCount] = { "RightShoulder", true, "RIGHT SHOULDER", ":/help/button_r.svg" }, { "LeftTrigger", true, "LEFT TRIGGER", ":/help/button_lt.svg" }, { "RightTrigger", true, "RIGHT TRIGGER", ":/help/button_rt.svg" }, - { "LeftThumb", true, "LEFT THUMB", ":/help/analog_thumb.svg" }, - { "RightThumb", true, "RIGHT THUMB", ":/help/analog_thumb.svg" }, +// { "LeftThumb", true, "LEFT THUMB", ":/help/analog_thumb.svg" }, +// { "RightThumb", true, "RIGHT THUMB", ":/help/analog_thumb.svg" }, { "LeftAnalogUp", true, "LEFT ANALOG UP", ":/help/analog_up.svg" }, { "LeftAnalogDown", true, "LEFT ANALOG DOWN", ":/help/analog_down.svg" }, { "LeftAnalogLeft", true, "LEFT ANALOG LEFT", ":/help/analog_left.svg" }, @@ -42,7 +42,7 @@ static const InputConfigStructure GUI_INPUT_CONFIG_LIST[inputCount] = { "RightAnalogDown", true, "RIGHT ANALOG DOWN", ":/help/analog_down.svg" }, { "RightAnalogLeft", true, "RIGHT ANALOG LEFT", ":/help/analog_left.svg" }, { "RightAnalogRight", true, "RIGHT ANALOG RIGHT", ":/help/analog_right.svg" }, - { "HotKeyEnable", true, "HOTKEY ENABLE", ":/help/button_hotkey.svg" } +// { "HotKeyEnable", true, "HOTKEY ENABLE", ":/help/button_hotkey.svg" } }; //MasterVolUp and MasterVolDown are also hooked up, but do not appear on this screen. @@ -190,25 +190,27 @@ GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target, bool reconfi buttons.push_back(std::make_shared(mWindow, "OK", "ok", [this, okFunction] { // check if the hotkey enable button is set. if not prompt the user to use select or nothing. Input input; - if (!mTargetConfig->getInputByName("HotKeyEnable", &input)) { - mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), - "YOU DIDN'T CHOOSE A HOTKEY ENABLE BUTTON. THIS IS REQUIRED FOR EXITING GAMES WITH A CONTROLLER. DO YOU WANT TO USE THE SELECT BUTTON DEFAULT ? PLEASE ANSWER YES TO USE SELECT OR NO TO NOT SET A HOTKEY ENABLE BUTTON.", - "YES", [this, okFunction] { - Input input; - mTargetConfig->getInputByName("Select", &input); - mTargetConfig->mapInput("HotKeyEnable", input); - okFunction(); - }, - "NO", [this, okFunction] { - // for a disabled hotkey enable button, set to a key with id 0, - // so the input configuration script can be backwards compatible. - mTargetConfig->mapInput("HotKeyEnable", Input(DEVICE_KEYBOARD, TYPE_KEY, 0, 1, true)); - okFunction(); - } - )); - } else { - okFunction(); - } + okFunction(); + // Temporary comments, needs to be properly cleaned up later. +// if (!mTargetConfig->getInputByName("HotKeyEnable", &input)) { +// mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), +// "YOU DIDN'T CHOOSE A HOTKEY ENABLE BUTTON. THIS IS REQUIRED FOR EXITING GAMES WITH A CONTROLLER. DO YOU WANT TO USE THE SELECT BUTTON DEFAULT ? PLEASE ANSWER YES TO USE SELECT OR NO TO NOT SET A HOTKEY ENABLE BUTTON.", +// "YES", [this, okFunction] { +// Input input; +// mTargetConfig->getInputByName("Select", &input); +// mTargetConfig->mapInput("HotKeyEnable", input); +// okFunction(); +// }, +// "NO", [this, okFunction] { +// // for a disabled hotkey enable button, set to a key with id 0, +// // so the input configuration script can be backwards compatible. +// mTargetConfig->mapInput("HotKeyEnable", Input(DEVICE_KEYBOARD, TYPE_KEY, 0, 1, true)); +// okFunction(); +// } +// )); +// } else { +// okFunction(); +// } })); mButtonGrid = makeButtonGrid(mWindow, buttons); mGrid.setEntry(mButtonGrid, Vector2i(0, 6), true, false);