1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2025-03-14 02:16:10 +00:00

overflow list in progress (#145)

This commit is contained in:
jugeeya 2020-08-21 17:36:51 -07:00 committed by GitHub
parent aa757da61d
commit 0daba036c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 88 deletions

View file

@ -1,33 +0,0 @@
#pragma once
#include <switch.h>
class FsDirIterator
{
private:
FsDir m_dir;
FsDirectoryEntry entry;
s64 count;
public:
FsDirIterator() = default;
FsDirIterator(FsDir dir);
~FsDirIterator() = default;
const FsDirectoryEntry& operator*() const;
const FsDirectoryEntry* operator->() const;
FsDirIterator& operator++();
bool operator!=(const FsDirIterator& rhs);
};
inline FsDirIterator begin(FsDirIterator iter) noexcept
{
return iter;
}
inline FsDirIterator end(FsDirIterator) noexcept
{
return FsDirIterator();
}

View file

@ -0,0 +1,124 @@
#include <tesla.hpp>
class OverflowList : public tsl::elm::List {
public:
OverflowList() : tsl::elm::List() {}
virtual tsl::elm::Element* requestFocus(tsl::elm::Element *oldFocus, tsl::FocusDirection direction) override {
tsl::elm::Element *newFocus = nullptr;
if (this->m_clearList || this->m_itemsToAdd.size() > 0)
return nullptr;
if (direction == tsl::FocusDirection::None) {
u16 i = 0;
if (oldFocus == nullptr) {
s32 elementHeight = 0;
while (elementHeight < this->m_offset && i < this->m_items.size() - 1) {
i++;
elementHeight += this->m_items[i]->getHeight();
}
}
for (; i < this->m_items.size(); i++) {
newFocus = this->m_items[i]->requestFocus(oldFocus, direction);
if (newFocus != nullptr) {
this->m_focusedIndex = i;
this->updateScrollOffset();
return newFocus;
}
}
} else {
if (direction == tsl::FocusDirection::Down) {
for (u16 i = this->m_focusedIndex + 1; i < this->m_items.size(); i++) {
newFocus = this->m_items[i]->requestFocus(oldFocus, direction);
if (newFocus != nullptr && newFocus != oldFocus) {
this->m_focusedIndex = i;
this->updateScrollOffset();
return newFocus;
}
}
if (this->m_focusedIndex == this->m_items.size() - 1) {
for (u16 i = 0; i < this->m_items.size(); i++) {
newFocus = this->m_items[i]->requestFocus(oldFocus, direction);
if (newFocus != nullptr && newFocus != oldFocus) {
this->m_focusedIndex = i;
this->updateScrollOffset();
return newFocus;
}
}
}
return oldFocus;
} else if (direction == tsl::FocusDirection::Up) {
if (this->m_focusedIndex > 0) {
for (u16 i = this->m_focusedIndex - 1; i >= 0; i--) {
if (i > this->m_items.size() || this->m_items[i] == nullptr)
return oldFocus;
else
newFocus = this->m_items[i]->requestFocus(oldFocus, direction);
if (newFocus != nullptr && newFocus != oldFocus) {
this->m_focusedIndex = i;
this->updateScrollOffset();
return newFocus;
}
}
}
for (u16 i = this->m_items.size() - 1; i >= 0; i--) {
if (i <= this->m_items.size() && this->m_items[i] != nullptr)
newFocus = this->m_items[i]->requestFocus(oldFocus, direction);
if (newFocus != nullptr && newFocus != oldFocus) {
this->m_focusedIndex = i;
this->updateScrollOffset();
return newFocus;
}
}
return oldFocus;
}
}
return oldFocus;
}
private:
virtual void updateScrollOffset() {
if (this->getInputMode() != tsl::InputMode::Controller)
return;
if (this->m_listHeight <= this->getHeight()) {
this->m_nextOffset = 0;
this->m_offset = 0;
return;
}
this->m_nextOffset = 0;
for (u16 i = 0; i < this->m_focusedIndex; i++)
this->m_nextOffset += this->m_items[i]->getHeight();
this->m_nextOffset -= this->getHeight() / 3;
if (this->m_nextOffset < 0)
this->m_nextOffset = 0;
if (this->m_nextOffset > (this->m_listHeight - this->getHeight()) + 50)
this->m_nextOffset = (this->m_listHeight - this->getHeight() + 50);
}
};

View file

@ -0,0 +1,24 @@
#include <tesla.hpp>
class OverlayFrameWithHelp : public tsl::elm::OverlayFrame
{
public:
OverlayFrameWithHelp(const std::string& title, const std::string& subtitle) : tsl::elm::OverlayFrame(title, subtitle)
{}
virtual void draw(tsl::gfx::Renderer* renderer) override
{
renderer->fillScreen(a(tsl::style::color::ColorFrameBackground));
renderer->drawRect(tsl::cfg::FramebufferWidth - 1, 0, 1, tsl::cfg::FramebufferHeight, a(0xF222));
renderer->drawString(this->m_title.c_str(), false, 20, 50, 30, a(tsl::style::color::ColorText));
renderer->drawString(this->m_subtitle.c_str(), false, 20, 70, 15, a(tsl::style::color::ColorDescription));
renderer->drawRect(15, tsl::cfg::FramebufferHeight - 73, tsl::cfg::FramebufferWidth - 30, 1, a(tsl::style::color::ColorText));
renderer->drawString("\uE0E1 Back \uE0E0 OK \uE0E3 Help", false, 30, 693, 23, a(tsl::style::color::ColorText));
if (this->m_contentElement != nullptr)
this->m_contentElement->frame(renderer);
}
};

View file

@ -1,27 +0,0 @@
#include "dir_iterator.hpp"
FsDirIterator::FsDirIterator(FsDir dir) : m_dir(dir)
{
if(R_FAILED(fsDirRead(&this->m_dir, &this->count, 1, &this->entry))) this->count = 0;
}
const FsDirectoryEntry& FsDirIterator::operator*() const
{
return this->entry;
}
const FsDirectoryEntry* FsDirIterator::operator->() const
{
return &**this;
}
FsDirIterator& FsDirIterator::operator++()
{
if(R_FAILED(fsDirRead(&this->m_dir, &this->count, 1, &this->entry))) this->count = 0;
return *this;
}
bool FsDirIterator::operator!=(const FsDirIterator& __rhs)
{
return this->count > 0;
}

View file

@ -1,6 +1,8 @@
#include <tesla.hpp>
#include "gui_main.hpp"
#include "gui_help.hpp"
#include "overflow_list.hpp"
#include "overlay_frame_with_help.hpp"
#include "value_list_item.hpp"
#include "clickable_list_item.hpp"
#include "taunt_toggles.hpp"
@ -271,29 +273,6 @@ public:
FsFileSystem m_fs;
};
class OverlayFrameWithHelp : public tsl::elm::OverlayFrame
{
public:
OverlayFrameWithHelp(const std::string& title, const std::string& subtitle) : tsl::elm::OverlayFrame(title, subtitle)
{}
virtual void draw(tsl::gfx::Renderer* renderer) override
{
renderer->fillScreen(a(tsl::style::color::ColorFrameBackground));
renderer->drawRect(tsl::cfg::FramebufferWidth - 1, 0, 1, tsl::cfg::FramebufferHeight, a(0xF222));
renderer->drawString(this->m_title.c_str(), false, 20, 50, 30, a(tsl::style::color::ColorText));
renderer->drawString(this->m_subtitle.c_str(), false, 20, 70, 15, a(tsl::style::color::ColorDescription));
renderer->drawRect(15, tsl::cfg::FramebufferHeight - 73, tsl::cfg::FramebufferWidth - 30, 1, a(tsl::style::color::ColorText));
renderer->drawString("\uE0E1 Back \uE0E0 OK \uE0E3 Help", false, 30, 693, 23, a(tsl::style::color::ColorText));
if (this->m_contentElement != nullptr)
this->m_contentElement->frame(renderer);
}
};
namespace
{
template<typename T> tsl::elm::ListItem* createBitFlagOption(T* option, const std::string& name, const std::string& help, GuiMain* guiMain)
@ -305,7 +284,7 @@ template<typename T> tsl::elm::ListItem* createBitFlagOption(T* option, const st
if(keys & KEY_A)
{
tsl::changeTo<GuiLambda>([option, name, help]() -> tsl::elm::Element* {
auto toggleList = new tsl::elm::List();
auto toggleList = new OverflowList();
std::vector<tsl::elm::ToggleListItem*> items;
for(auto& [flag, str] : detail::EnumArray<FlagType>::values)
{
@ -345,7 +324,7 @@ tsl::elm::Element* GuiMain::createUI()
snprintf(buffer, 256, "Version %s", VERSION);
OverlayFrameWithHelp* rootFrame = new OverlayFrameWithHelp("Training Modpack", buffer);
auto list = new tsl::elm::List();
auto list = new OverflowList();
Result rc;
Handle debug;
@ -391,7 +370,9 @@ tsl::elm::Element* GuiMain::createUI()
{
svcCloseHandle(debug);
list->addItem(new tsl::elm::CategoryHeader("Mash", true));
// Remove because it breaks scrolling up to the bottom of the
// menu, because CategoryHeaders can't requestFocus?
// list->addItem(new tsl::elm::CategoryHeader("Mash", true));
list->addItem(createBitFlagOption(&menu.MASH_STATE, "Mash Toggles", mash_help, this));
list->addItem(createBitFlagOption(&menu.FOLLOW_UP, "Followup Toggles", follow_up_help, this));

View file

@ -1,4 +1,6 @@
#include "gui_sublist.hpp"
#include "overflow_list.hpp"
#include "overlay_frame_with_help.hpp"
#include "gui_help.hpp"
#include "clickable_list_item.hpp"
#include "taunt_toggles.hpp"
@ -16,9 +18,9 @@ GuiSublist::~GuiSublist() {}
tsl::elm::Element* GuiSublist::createUI()
{
tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame(title, "Press \uE0E3 for help with these options.");
tsl::elm::OverlayFrame* rootFrame = new OverlayFrameWithHelp(title, "Press \uE0E3 for help with these options.");
auto list = new tsl::elm::List();
auto list = new OverflowList();
for(size_t i = 0; i < menuItems.size(); i++)
{