diff --git a/src/game/GameList.cpp b/src/game/GameList.cpp index 180f255..476ec92 100644 --- a/src/game/GameList.cpp +++ b/src/game/GameList.cpp @@ -82,7 +82,7 @@ int32_t GameList::readGameList() { } for (auto title_candidate : titles) { - if(true || (title_candidate.titleId & 0xFFFFFFFF00000000L) == 0x0005000000000000L) { + if((title_candidate.titleId & 0xFFFFFFFF00000000L) == 0x0005000000000000L) { gameInfo* newGameInfo = new gameInfo; newGameInfo->titleId = title_candidate.titleId; newGameInfo->gamePath = title_candidate.path; diff --git a/src/gui/GuiIconGrid.cpp b/src/gui/GuiIconGrid.cpp index a25662e..8692c32 100644 --- a/src/gui/GuiIconGrid.cpp +++ b/src/gui/GuiIconGrid.cpp @@ -51,7 +51,8 @@ GuiIconGrid::GuiIconGrid(int32_t w, int32_t h, uint64_t GameIndex,bool sortByNam , arrowRightButton(arrowRightImage.getWidth(), arrowRightImage.getHeight()) , arrowLeftButton(arrowLeftImage.getWidth(), arrowLeftImage.getHeight()) , noIcon(Resources::GetFile("noGameIcon.png"), Resources::GetFileSize("noGameIcon.png"), GX2_TEX_CLAMP_MODE_MIRROR) - , emptyIcon(Resources::GetFile("iconEmpty.png"), Resources::GetFileSize("iconEmpty.png"), GX2_TEX_CLAMP_MODE_MIRROR) { + , emptyIcon(Resources::GetFile("iconEmpty.png"), Resources::GetFileSize("iconEmpty.png"), GX2_TEX_CLAMP_MODE_MIRROR) + , dragListener(w,h) { particleBgImage.setParent(this); setSelectedGame(GameIndex); @@ -107,6 +108,12 @@ GuiIconGrid::GuiIconGrid(int32_t w, int32_t h, uint64_t GameIndex,bool sortByNam GameIcon * image = new GameIcon(&emptyIcon); emptyIcons.push_back(image); } + + dragListener.setTrigger(&touchTrigger); + dragListener.setTrigger(&wpadTouchTrigger); + dragListener.dragged.connect(this, &GuiIconGrid::OnDrag); + + append(&dragListener); } GuiIconGrid::~GuiIconGrid() { @@ -140,7 +147,6 @@ void GuiIconGrid::setSelectedGame(uint64_t idx) { this->selectedGame = idx; containerMutex.lock(); - GameInfoContainer * container = NULL; for (auto const& x : gameInfoContainers) { container = x.second; @@ -201,8 +207,6 @@ void GuiIconGrid::OnGameTitleListUpdated(GameList * gameList) { break; } } - - if(container == NULL) { OnGameTitleAdded(info); } @@ -321,6 +325,31 @@ void GuiIconGrid::OnLaunchClick(GuiButton *button, const GuiController *controll } +void GuiIconGrid::OnGameButtonHeld(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) { + if(currentlyHeld == NULL) { + currentlyHeld = button; + } + if(currentlyHeld != NULL && currentlyHeld != button) { + dragTarget = button; + } +} + +void GuiIconGrid::OnGameButtonPointedOn(GuiButton *button, const GuiController *controller) { + +} + +void GuiIconGrid::OnGameButtonPointedOff(GuiButton *button, const GuiController *controller) { + +} + +void GuiIconGrid::OnDrag(GuiDragListener * element, const GuiController *controller, GuiTrigger *trigger, int32_t dx, int32_t dy) { + if(currentlyHeld != NULL) { + currentlyHeld->setPosition(currentlyHeld->getOffsetX() + dx, currentlyHeld->getOffsetY() + dy); + } + // reset the target when we move. + dragTarget = NULL; +} + void GuiIconGrid::OnGameButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger) { containerMutex.lock(); for (auto const& x : gameInfoContainers) { @@ -361,6 +390,11 @@ void GuiIconGrid::OnGameTitleAdded(gameInfo * info) { //button->setClickable( (idx < gameList->size()) ); //button->setSelectable( (idx < gameList->size()) ); button->clicked.connect(this, &GuiIconGrid::OnGameButtonClick); + button->setHoldable(true); + button->held.connect(this, &GuiIconGrid::OnGameButtonHeld); + button->pointedOn.connect(this, &GuiIconGrid::OnGameButtonPointedOn); + button->pointedOff.connect(this, &GuiIconGrid::OnGameButtonPointedOff); + //button->dragged.connect(this, &GuiIconGrid::OnGameButtonDragged); GameInfoContainer * container = new GameInfoContainer(button, image, info); containerMutex.lock(); @@ -368,6 +402,8 @@ void GuiIconGrid::OnGameTitleAdded(gameInfo * info) { containerMutex.unlock(); this->append(button); + position.push_back(info->titleId); + bUpdatePositions = true; } void GuiIconGrid::OnGameTitleUpdated(gameInfo * info) { @@ -392,6 +428,53 @@ void GuiIconGrid::OnGameTitleUpdated(gameInfo * info) { } void GuiIconGrid::process() { + if(currentlyHeld != NULL) { + if(!currentlyHeld->isStateSet(GuiElement::STATE_HELD)) { + DEBUG_FUNCTION_LINE("Not held anymore\n"); + + if(dragTarget) { + DEBUG_FUNCTION_LINE("Let's swap\n"); + + std::vector> vec; + containerMutex.lock(); + // copy key-value pairs from the map to the vector + std::copy(gameInfoContainers.begin(), gameInfoContainers.end(), std::back_inserter>>(vec)); + containerMutex.unlock(); + uint64_t targetTitleId = 0; + for (auto const& x : vec) { + if(x.second->button == dragTarget) { + targetTitleId = x.first; + } + } + + if(targetTitleId > 0) { + for(uint32_t i = 0; i< position.size(); i++) { + if(position[i] == targetTitleId) { + position[i] = currentlyHeldTitleId; + } + } + } + + if(currentlyHeldPosition >= 0 && currentlyHeldPosition <= (int32_t) position.size()) { + position[currentlyHeldPosition] = targetTitleId; + } + dragTarget = NULL; + } else { + if(currentlyHeldPosition >= 0 && currentlyHeldPosition <= (int32_t) position.size()) { + position[currentlyHeldPosition] = currentlyHeldTitleId; + } + } + currentlyHeld = NULL; + currentlyHeldTitleId = 0; + + currentlyHeldPosition = -1; + bUpdatePositions = true; + } else { + //DEBUG_FUNCTION_LINE("Holding it\n"); + bUpdatePositions = true; + } + } + if(currentLeftPosition < targetLeftPosition) { currentLeftPosition += 35; @@ -440,6 +523,9 @@ void GuiIconGrid::updateButtonPositions() { containerMutex.unlock(); for (auto const& x : vec) { + if(x.second->button == currentlyHeld) { + currentlyHeldTitleId = x.first; + } remove(x.second->button); } @@ -459,9 +545,13 @@ void GuiIconGrid::updateButtonPositions() { // TODO somehow be able to adjust the positions. - position.clear(); - for(auto const & x: vec) { - position.push_back(x.first); + + //position.clear(); + for(uint32_t i = 0; i 0) { - GameInfoContainer * container = gameInfoContainers[titleID]; + GameInfoContainer * container = NULL; + containerMutex.lock(); + if(gameInfoContainers.find(titleID) != gameInfoContainers.end()) { + container = gameInfoContainers[titleID]; + } + containerMutex.unlock(); if(container != NULL) { element = container->button; } @@ -534,10 +629,12 @@ void GuiIconGrid::updateButtonPositions() { row = 0; } } + if(currentlyHeld != NULL) { + append(currentlyHeld); + } } void GuiIconGrid::draw(CVideo *pVideo) { - //! the BG needs to be rendered to stencil pVideo->setStencilRender(true); particleBgImage.draw(pVideo); diff --git a/src/gui/GuiIconGrid.h b/src/gui/GuiIconGrid.h index 3e7102f..a121d3a 100644 --- a/src/gui/GuiIconGrid.h +++ b/src/gui/GuiIconGrid.h @@ -19,6 +19,7 @@ #include #include "gui/GuiTitleBrowser.h" #include "gui/GameIcon.h" +#include "gui/GuiDragListener.h" #include #include "utils/AsyncExecutor.h" #include "utils/logger.h" @@ -74,6 +75,8 @@ private: GuiImageData noIcon; GuiImageData emptyIcon; + GuiDragListener dragListener; + void OnLeftArrowClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger); void OnRightArrowClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger); @@ -84,6 +87,10 @@ private: void OnLaunchClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger); void OnGameButtonClick(GuiButton *button, const GuiController *controller, GuiTrigger *trigger); + void OnGameButtonHeld(GuiButton *button, const GuiController *controller, GuiTrigger *trigger); + void OnGameButtonPointedOn(GuiButton *button, const GuiController *controller); + void OnGameButtonPointedOff(GuiButton *button, const GuiController *controller); + void OnDrag(GuiDragListener *button, const GuiController *controller, GuiTrigger *trigger, int32_t dx, int32_t dy); void updateButtonPositions(); int32_t offsetForTitleId(uint64_t titleId); @@ -95,6 +102,10 @@ private: int32_t targetLeftPosition; uint32_t gameLaunchTimer; bool bUpdatePositions = false; + GuiButton * currentlyHeld = NULL; + uint64_t currentlyHeldTitleId = 0; + int32_t currentlyHeldPosition = -1; + GuiButton * dragTarget = NULL; class GameInfoContainer { public: