Skip to content

Commit 2c153a6

Browse files
committed
[FEAT] make queue and album panes scrollable
1 parent a46bc88 commit 2c153a6

5 files changed

Lines changed: 66 additions & 15 deletions

File tree

include/inlimbo/frontend/ftxui/ui/screens/Main.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ class MainScreen
1818

1919
void attachAudioService(audio::Service& audio) { m_audioPtr = &audio; }
2020

21+
ftxui::Component container;
22+
2123
private:
2224
state::library::LibraryState& m_state;
2325
audio::Service* m_audioPtr;
2426

2527
ftxui::Component artist_menu;
2628
ftxui::Component album_content;
27-
ftxui::Component album_scroller;
28-
ftxui::Component container;
29+
ftxui::Component album_view;
30+
float album_scroll;
31+
float album_scroll_target = 0.0f;
2932
ftxui::Component root_renderer;
3033

3134
bool focus_on_artists{true};

include/inlimbo/frontend/ftxui/ui/screens/Queue.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ class QueueScreen
2323
state::queue::QueueState& m_state;
2424

2525
ftxui::Component queue_content;
26+
ftxui::Component queue_view;
2627
ftxui::Component meta_content;
2728
ftxui::Component container;
29+
30+
float queue_scroll = 0.0f;
31+
float queue_scroll_target = 0.0f;
2832
};
2933

3034
} // namespace frontend::tui::ui::screens

src/frontend/ftxui/state/library/Impl.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void LibraryState::buildAlbumViewForArtist(const Artist& artist)
6060
query::songmap::read::forEachSongInArtist(
6161
*m_songMapTS, artist,
6262
[&](const Album& album, const Disc disc, const Track track, const ino_t,
63-
const std::shared_ptr<Song>& song)
63+
const std::shared_ptr<Song>& song) -> void
6464
{
6565
if (album != current_album)
6666
{

src/frontend/ftxui/ui/screens/Main.cc

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include "frontend/ftxui/ui/screens/Main.hpp"
2-
#include "frontend/ftxui/components/scroll/Scrollable.hpp"
32
#include "frontend/ftxui/state/library/Impl.hpp"
43

54
using namespace ftxui;
@@ -12,20 +11,43 @@ MainScreen::MainScreen(state::library::LibraryState& state) : m_state(state)
1211
artist_menu = Menu(&m_state.artists, &m_state.selected_artist) | vscroll_indicator;
1312

1413
album_content =
15-
Renderer([&]() mutable -> Element { return vbox(m_state.returnAlbumElements()); });
14+
Renderer([&]() -> Element { return vbox(m_state.returnAlbumElements()) | vscroll_indicator; });
1615

17-
album_scroller =
18-
Scroller(album_content, &m_state.selected_album_index, Color::Green, Color::GrayDark);
16+
album_scroll = 0.0f;
17+
album_scroll_target = 0.0f;
1918

20-
container = Container::Horizontal({artist_menu, album_scroller});
19+
album_view = Renderer(album_content,
20+
[&]() -> Element
21+
{
22+
const auto& elems = m_state.returnAlbumElements();
23+
24+
if (!elems.empty())
25+
{
26+
album_scroll_target = float(m_state.selected_album_index) /
27+
float(std::max<int>(1, elems.size() - 1));
28+
}
29+
30+
constexpr float smoothing = 0.15f; // 0.1 = slow, 0.25 = fast
31+
album_scroll += (album_scroll_target - album_scroll) * smoothing;
32+
33+
album_scroll = std::clamp(album_scroll, 0.0f, 1.0f);
34+
35+
return album_content->Render() |
36+
focusPositionRelative(0.0f, album_scroll) | frame | flex;
37+
});
38+
39+
container = Container::Horizontal({
40+
artist_menu,
41+
album_view,
42+
});
2143
}
2244

2345
void MainScreen::syncFocus()
2446
{
2547
if (m_state.focusOnArtists())
2648
artist_menu->TakeFocus();
2749
else
28-
album_scroller->TakeFocus();
50+
album_view->TakeFocus();
2951
}
3052

3153
auto MainScreen::component() -> Component { return container; }
@@ -51,7 +73,7 @@ auto MainScreen::render() -> Element
5173
auto artist_inner = window(text(" Artists ") | bold, artist_menu->Render() | frame | flex) |
5274
size(WIDTH, EQUAL, half_width);
5375

54-
auto album_inner = window(text(" Songs ") | bold, album_scroller->Render() | frame | flex) |
76+
auto album_inner = window(text(" Songs ") | bold, album_view->Render() | frame | flex) |
5577
size(WIDTH, EQUAL, term.dimx - half_width);
5678

5779
Color artist_border_color = m_state.focusOnArtists() ? Color::Green : Color::GrayDark;

src/frontend/ftxui/ui/screens/Queue.cc

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@ QueueScreen::QueueScreen(state::queue::QueueState& state) : m_state(state)
2222

2323
for (size_t i = 0; i < size; ++i)
2424
{
25-
auto metaOpt = m_audioPtr->getMetadataAt(i);
26-
27-
std::string title = metaOpt ? metaOpt->title : "<unknown>";
25+
auto metaOpt = m_audioPtr->getMetadataAt(i);
26+
std::string title = metaOpt ? metaOpt->title : "<unknown>";
2827

2928
Element row = hbox({
3029
text(i == current ? "" : " "),
@@ -34,7 +33,7 @@ QueueScreen::QueueScreen(state::queue::QueueState& state) : m_state(state)
3433
if ((int)i == m_state.selected())
3534
row = row | bgcolor(Color::RGB(40, 60, 90)) | color(Color::White) | bold;
3635

37-
rows.push_back(row | frame);
36+
rows.push_back(row);
3837
}
3938

4039
if (rows.empty())
@@ -43,6 +42,29 @@ QueueScreen::QueueScreen(state::queue::QueueState& state) : m_state(state)
4342
return vbox(rows);
4443
});
4544

45+
queue_view = Renderer(
46+
queue_content,
47+
[&]() -> Element
48+
{
49+
const size_t size = m_audioPtr->getPlaylistSize();
50+
51+
if (size > 1)
52+
{
53+
queue_scroll_target = float(m_state.selected()) / float(std::max<size_t>(1, size - 1));
54+
}
55+
56+
// ---- smoothing ----
57+
constexpr float smoothing = 0.15f;
58+
queue_scroll += (queue_scroll_target - queue_scroll) * smoothing;
59+
60+
if (std::abs(queue_scroll_target - queue_scroll) < 0.001f)
61+
queue_scroll = queue_scroll_target;
62+
63+
queue_scroll = std::clamp(queue_scroll, 0.0f, 1.0f);
64+
65+
return queue_content->Render() | focusPositionRelative(0.0f, queue_scroll) | frame | flex;
66+
});
67+
4668
meta_content = Renderer(
4769
[&]() -> Element
4870
{
@@ -141,7 +163,7 @@ auto QueueScreen::render() -> Element
141163
auto term = Terminal::Size();
142164
int half_width = term.dimx / 2;
143165

144-
auto queue_inner = window(text(" Queue ") | bold, queue_content->Render() | frame | flex) |
166+
auto queue_inner = window(text(" Queue ") | bold, queue_view->Render() | frame | flex) |
145167
size(WIDTH, EQUAL, half_width);
146168

147169
auto meta_inner = window(text(" Track Info ") | bold, meta_content->Render() | frame | flex) |

0 commit comments

Comments
 (0)