summaryrefslogtreecommitdiff
path: root/lib/nes/app/ui
diff options
context:
space:
mode:
authorHannes Schulze <haschu0103@outlook.de>2025-02-04 19:25:03 +0100
committerHannes Schulze <haschu0103@outlook.de>2025-02-04 19:25:03 +0100
commite791ac9a46095e0241181da89c35a7c702982c21 (patch)
treed959c79c24ae03282f1b00ec9bcb2ccf86d9c96c /lib/nes/app/ui
parent0f22ed2ef160eef2da6080782943b22c9539650d (diff)
clean up path logic a bit
Diffstat (limited to 'lib/nes/app/ui')
-rw-r--r--lib/nes/app/ui/screen-browser.cc82
-rw-r--r--lib/nes/app/ui/screen-browser.hh10
2 files changed, 63 insertions, 29 deletions
diff --git a/lib/nes/app/ui/screen-browser.cc b/lib/nes/app/ui/screen-browser.cc
index daca18e..6a18d3c 100644
--- a/lib/nes/app/ui/screen-browser.cc
+++ b/lib/nes/app/ui/screen-browser.cc
@@ -3,7 +3,6 @@
#include "nes/app/graphics/color.hh"
#include "nes/app/graphics/tiles/icons.hh"
#include "nes/app/input/input-device-keyboard.hh"
-#include "nes/common/string-builder.hh"
#include "nes/common/path-view.hh"
namespace nes::app
@@ -23,23 +22,37 @@ namespace nes::app
.set_max_width(width - 2));
}
- auto screen_browser::selection_impl::load_page(item (&items)[8], u32 const page) -> u32
+ auto screen_browser::selection_impl::load_page(item (&items)[page_size], u32 const page) -> u32
{
- auto offset = u32{ 0 };
- if (page == 0 && file_browser_.get_path().get_component_count() > 0)
+ auto count = u32{ 0 };
+ auto position = page * page_size;
+ if (!file_browser_.get_path().is_empty())
{
- items[0].is_parent = true;
- items[0].data = file_browser::item{ file_browser::item_type::directory, "[Parent Directory]" };
- offset = 1;
+ if (page == 0)
+ {
+ items[count].is_parent = true;
+ items[count].data = file_browser::item{ file_browser::item_type::directory, "[Parent Directory]" };
+ count += 1;
+ }
+ else
+ {
+ // First page has been missing an item, offset by one.
+ position -= 1;
+ }
}
- file_browser::item buffer[8];
- auto const count = file_browser_.read_items(page * 8, buffer, 8 - offset);
- for (auto i = u32{ 0 }; i < count; ++i)
+
+ file_browser_.seek(position);
+ while (count < page_size)
{
- items[i + offset].is_parent = false;
- items[i + offset].data = buffer[i];
+ auto item = file_browser::item{};
+ if (!file_browser_.read_next(&item)) { break; }
+
+ items[count].is_parent = false;
+ items[count].data = item;
+ count += 1;
}
- return count + offset;
+
+ return count;
}
screen_browser::screen_browser(input_device_keyboard& keyboard, file_browser& file_browser)
@@ -47,7 +60,7 @@ namespace nes::app
, file_browser_{ file_browser }
, selection_{ file_browser }
{
- selection_.set_page_count(std::max(u32{ 1 }, (file_browser_.read_item_count() + 7) / 8));
+ refresh();
}
auto screen_browser::render(renderer& renderer) -> void
@@ -59,16 +72,9 @@ namespace nes::app
30, 1, color::foreground_secondary, text_attributes{}.set_alignment(text_alignment::right),
"Page {}/{}", selection_.get_current_page() + 1, selection_.get_page_count());
- char path_buffer[32];
- auto path_builder = string_builder{ path_buffer, sizeof(path_buffer) };
- for (auto const component : file_browser_.get_path())
- {
- path_builder.append_format("> {} ", component);
- }
- path_builder.append_string(">");
renderer.render_text(
- 2, 1, path_builder.get_result(), color::foreground_primary,
- text_attributes{}.set_max_width(26 - page_length).set_ellipsize_mode(ellipsize_mode::end));
+ 2, 1, file_browser_.get_path().get_path(), color::foreground_primary,
+ text_attributes{}.set_max_width(26 - page_length).set_ellipsize_mode(ellipsize_mode::middle));
selection_.render(renderer);
}
@@ -91,17 +97,27 @@ namespace nes::app
}
else if (event == input_event::key_down(key::backspace))
{
- return action::go_to_title();
+ if (navigation_steps_ > 0)
+ {
+ file_browser_.navigate_up();
+ refresh();
+ navigation_steps_ -= 1;
+ }
+ else
+ {
+ return action::go_to_title();
+ }
}
else if (event == input_event::key_down(key::enter))
{
- auto selected = selection_.get_selected();
+ auto const selected = selection_.get_selected();
if (selected)
{
if (selected->is_parent)
{
file_browser_.navigate_up();
- selection_.set_page_count(std::max(u32{ 1 }, (file_browser_.read_item_count() + 7) / 8));
+ refresh();
+ if (navigation_steps_ > 0) { navigation_steps_ -= 1; }
}
else
{
@@ -109,7 +125,8 @@ namespace nes::app
{
case file_browser::item_type::directory:
file_browser_.navigate(selected->data.get_name());
- selection_.set_page_count(std::max(u32{ 1 }, (file_browser_.read_item_count() + 7) / 8));
+ refresh();
+ navigation_steps_ += 1;
break;
case file_browser::item_type::file:
return action::launch_game(selected->data.get_name());
@@ -121,4 +138,15 @@ namespace nes::app
return action{};
}
+
+ auto screen_browser::refresh() -> void
+ {
+ file_browser_.seek(0);
+ auto count = u32{ 0 };
+ while (file_browser_.read_next(nullptr)) { count += 1; }
+ // Round up to get page count.
+ auto const page_count = (count + (page_size - 1)) / page_size;
+ // Always show at least one page.
+ selection_.set_page_count(std::max(u32{ 1 }, page_count));
+ }
} // namespace nes::app \ No newline at end of file
diff --git a/lib/nes/app/ui/screen-browser.hh b/lib/nes/app/ui/screen-browser.hh
index 7a711c5..3870f02 100644
--- a/lib/nes/app/ui/screen-browser.hh
+++ b/lib/nes/app/ui/screen-browser.hh
@@ -11,13 +11,15 @@ namespace nes::app
/// An interface which allows the user to browse the filesystem for a game.
class screen_browser final : public screen
{
+ static constexpr auto page_size = u32{ 8 };
+
struct item
{
bool is_parent{ false };
file_browser::item data{ file_browser::item_type::directory, "" };
};
- class selection_impl final : public selection<item, 8>
+ class selection_impl final : public selection<item, page_size>
{
file_browser& file_browser_;
@@ -30,17 +32,21 @@ namespace nes::app
protected:
auto render_item(renderer&, item const&, i32 x, i32 y, u32 width, color) const -> void override;
- auto load_page(item(&)[8], u32 page) -> u32 override;
+ auto load_page(item(&)[page_size], u32 page) -> u32 override;
};
input_device_keyboard& keyboard_;
file_browser& file_browser_;
selection_impl selection_;
+ u32 navigation_steps_{ 0 };
public:
explicit screen_browser(input_device_keyboard&, file_browser&);
auto render(renderer&) -> void override;
auto process_events() -> action override;
+
+ private:
+ auto refresh() -> void;
};
} // namespace nes::app \ No newline at end of file