Skip to content

Commit

Permalink
WIP GenrePicker
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenAlex committed Jan 14, 2025
1 parent b3118b2 commit f0646b8
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 59 deletions.
33 changes: 27 additions & 6 deletions include/UI/Modals/GenrePicker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,31 @@
#include "bsml/shared/BSML/Components/CustomListTableData.hpp"


DECLARE_CLASS_CODEGEN(BetterSongSearch::UI::Modals, GenrePicker, UnityEngine::MonoBehaviour,
namespace BetterSongSearch::UI::Modals {
enum class GenreCellStatus {
None,
Include,
Exclude
};

struct GenreCellState {
std::string tag;
uint64_t mask;
GenreCellStatus status;
uint32_t songCount;
};
}


DECLARE_CLASS_CODEGEN_INTERFACES(BetterSongSearch::UI::Modals, GenrePicker, UnityEngine::MonoBehaviour, classof(HMUI::TableView::IDataSource*),

DECLARE_OVERRIDE_METHOD_MATCH(HMUI::TableCell*, CellForIdx, &HMUI::TableView::IDataSource::CellForIdx, HMUI::TableView* tableView, int idx);
DECLARE_OVERRIDE_METHOD_MATCH(float, CellSize, &HMUI::TableView::IDataSource::CellSize);
DECLARE_OVERRIDE_METHOD_MATCH(int, NumberOfCells, &HMUI::TableView::IDataSource::NumberOfCells);

DECLARE_INSTANCE_METHOD(void, OnEnable);
DECLARE_CTOR(ctor);
DECLARE_DTOR(dtor);

DECLARE_INSTANCE_METHOD(void, PostParse);

Expand All @@ -26,14 +48,13 @@ DECLARE_CLASS_CODEGEN(BetterSongSearch::UI::Modals, GenrePicker, UnityEngine::Mo


DECLARE_INSTANCE_METHOD(void, ClearGenre);

DECLARE_INSTANCE_METHOD(void, RefreshGenreList);
DECLARE_INSTANCE_FIELD(bool, initialized);

// Modals
DECLARE_INSTANCE_FIELD(UnityW<BSML::ModalView>, genrePickerModal);

public:
std::vector<std::string> selectedGenres;
std::vector<std::string> excludedGenres;
private:
std::vector<BetterSongSearch::UI::Modals::GenreCellState> genres;

)
20 changes: 14 additions & 6 deletions include/UI/Modals/GenrePickerCell.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,30 @@
#include "bsml/shared/macros.hpp"
#include "bsml/shared/BSML.hpp"
#include "bsml/shared/BSML/Components/CustomListTableData.hpp"
#include "bsml/shared/BSML/Components/ClickableText.hpp"
#include "HMUI/Touchable.hpp"
#include "HMUI/TableView.hpp"
#include "UnityEngine/UI/HorizontalOrVerticalLayoutGroup.hpp"
#include "assets.hpp"
#include "UI/Modals/GenrePicker.hpp"

DECLARE_CLASS_CODEGEN(BetterSongSearch::UI::Modals, GenrePickerCell, HMUI::TableCell,
DECLARE_OVERRIDE_METHOD_MATCH(void, SelectionDidChange, &HMUI::SelectableCell::SelectionDidChange, HMUI::SelectableCell::TransitionType transitionType);
DECLARE_OVERRIDE_METHOD_MATCH(void, HighlightDidChange, &HMUI::SelectableCell::HighlightDidChange, HMUI::SelectableCell::TransitionType transitionType);
DECLARE_OVERRIDE_METHOD_MATCH(void, WasPreparedForReuse, &HMUI::TableCell::WasPreparedForReuse);
DECLARE_INSTANCE_FIELD(TMPro::TextMeshProUGUI*, presetNameLabel);
DECLARE_INSTANCE_FIELD(HMUI::ImageView*, bgContainer);

DECLARE_INSTANCE_FIELD(UnityW<BSML::ClickableText>, includeButton);
DECLARE_INSTANCE_FIELD(UnityW<BSML::ClickableText>, excludeButton);

DECLARE_INSTANCE_METHOD(void, IncludeGenre);
DECLARE_INSTANCE_METHOD(void, ExcludeGenre);

DECLARE_INSTANCE_METHOD(void, Refresh);

public:
PresetsTableCell* PopulateWithPresetName(StringW presetName);
static PresetsTableCell *GetCell(HMUI::TableView *tableView);
BetterSongSearch::UI::Modals::GenrePickerCell* PopulateWithGenre(BetterSongSearch::UI::Modals::GenreCellState* state);
static BetterSongSearch::UI::Modals::GenrePickerCell *GetCell(HMUI::TableView *tableView);

private:
void RefreshBgState();
private:
BetterSongSearch::UI::Modals::GenreCellState* genre;
)
62 changes: 61 additions & 1 deletion src/UI/Modals/GenrePicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
#include "bsml/shared/BSML.hpp"

#include "UI/FlowCoordinators/BetterSongSearchFlowCoordinator.hpp"
#include "UI/Modals/GenrePickerCell.hpp"

#include "logging.hpp"
#include "assets.hpp"
#include "FilterOptions.hpp"
#include "DataHolder.hpp"


using namespace BetterSongSearch::UI;
using namespace BetterSongSearch::Util;
#define coro(coroutine) BSML::SharedCoroutineStarter::get_instance()->StartCoroutine(custom_types::Helpers::CoroutineHelper::New(coroutine))
Expand All @@ -35,6 +37,47 @@ void Modals::GenrePicker::ctor()
{
INVOKE_CTOR();
this->initialized = false;

// Subscribe to events
dataHolder.loadingFinished += {&Modals::GenrePicker::PostParse, this};
}
void Modals::GenrePicker::dtor()
{
// Unsub from events
dataHolder.loadingFinished -= {&Modals::GenrePicker::PostParse, this};
}

void Modals::GenrePicker::RefreshGenreList() {
if (!this->genrePickerModal) return;
if (!initialized) return;

auto table = this->genrePickerModal->get_transform()->Find("TableView")->GetComponent<HMUI::TableView*>();
if (!table) return;

if (dataHolder.tags.size() == 0) return;

// Recalculate preprocessed values
dataHolder.filterOptions.RecalculatePreprocessedValues();

std::vector<GenreCellState> tempGenres;
for (auto& genre : dataHolder.tags)
{
GenreCellStatus state = GenreCellStatus::None;
auto mask = genre.mask;

auto isExcluded = dataHolder.filterOptions._mapGenreExcludeBitfield & mask;
auto isIncluded = dataHolder.filterOptions._mapGenreBitfield & mask;

if (isExcluded) state = GenreCellStatus::Exclude;
if (isIncluded) state = GenreCellStatus::Include;

genres.push_back({genre.tag, mask, state, genre.songCount});
}

tempGenres.swap(genres);

table->SetDataSource(reinterpret_cast<HMUI::TableView::IDataSource *>(this), false);
table->ReloadData();
}

void Modals::GenrePicker::OpenModal()
Expand All @@ -44,6 +87,8 @@ void Modals::GenrePicker::OpenModal()
initialized = true;
}

RefreshGenreList();

INFO("Opening genre picker modal");
this->genrePickerModal->Show();

Expand All @@ -53,7 +98,6 @@ void Modals::GenrePicker::OpenModal()
if (!fv) return;

dataHolder.PreprocessTags();

}

void Modals::GenrePicker::ClearGenre()
Expand All @@ -73,4 +117,20 @@ void Modals::GenrePicker::ClearGenre()
fcInstance->FilterViewController->ForceRefreshUI();

this->genrePickerModal->Hide();
}

// Table stuff
HMUI::TableCell *Modals::GenrePicker::CellForIdx(HMUI::TableView *tableView, int idx)
{
return Modals::GenrePickerCell::GetCell(tableView)->PopulateWithGenre(&genres[idx]);
}

float Modals::GenrePicker::CellSize()
{
return 6.05f;
}

int Modals::GenrePicker::NumberOfCells()
{
return genres.size();
}
83 changes: 83 additions & 0 deletions src/UI/Modals/GenrePickerCell.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "UI/Modals/GenrePickerCell.hpp"


DEFINE_TYPE(BetterSongSearch::UI::Modals, GenrePickerCell);

const StringW GenrePickerCellReuseIdentifier = "REUSEGenreTableCell";

namespace BetterSongSearch::UI::Modals
{
void GenrePickerCell::Refresh()
{
if (genre == nullptr) return;

includeButton->set_fontStyle(
genre->status == GenreCellStatus::Exclude
? TMPro::FontStyles::Strikethrough
: TMPro::FontStyles::Normal
);

includeButton->set_color(
UnityEngine::Color(
genre->status == GenreCellStatus::Exclude ? 1.0f : 0.8f,
genre->status == GenreCellStatus::Include ? 1.0f : 0.7f,
0.8f,
get_highlighted() ? 1.0f : 0.8f
)
);

excludeButton->get_gameObject()->SetActive(highlighted && genre->status != GenreCellStatus::Exclude);
}

void GenrePickerCell::SelectionDidChange(HMUI::SelectableCell::TransitionType transitionType)
{
Refresh();
}

void GenrePickerCell::HighlightDidChange(HMUI::SelectableCell::TransitionType transitionType)
{
Refresh();
}

void GenrePickerCell::WasPreparedForReuse()
{
includeButton->set_text("");
genre = nullptr;
}

BetterSongSearch::UI::Modals::GenrePickerCell* GenrePickerCell::PopulateWithGenre(BetterSongSearch::UI::Modals::GenreCellState* state){
this->genre = state;
includeButton->set_text(state->tag);
Refresh();

return this;
}

BetterSongSearch::UI::Modals::GenrePickerCell *GenrePickerCell::GetCell(HMUI::TableView *tableView)
{
auto tableCell = tableView->DequeueReusableCellForIdentifier(GenrePickerCellReuseIdentifier);
if (!tableCell)
{
tableCell = UnityEngine::GameObject::New_ctor("GenrePickerCell")->AddComponent<GenrePickerCell *>();
tableCell->set_interactable(true);
tableCell->set_reuseIdentifier(GenrePickerCellReuseIdentifier);
BSML::parse_and_construct(Assets::GenrePickerCell_bsml, tableCell->get_transform(), tableCell);

// Weird hack cause HMUI touchable is not there for some reason, thanks RedBrumbler
tableCell->get_gameObject()->AddComponent<HMUI::Touchable *>();
}

return tableCell.cast<GenrePickerCell>();
}

void GenrePickerCell::IncludeGenre() {
if (genre == nullptr) return;
genre->status = genre->status == GenreCellStatus::Include ? GenreCellStatus::None : GenreCellStatus::Include;
Refresh();
}
void GenrePickerCell::ExcludeGenre() {
if (genre == nullptr) return;
genre->status = GenreCellStatus::Exclude;
Refresh();
}
}
Loading

0 comments on commit f0646b8

Please sign in to comment.