Krolyxon
Commit 9e2b51c

rmptui9e2b51c

use tabs instead of layouts

Author
krolxon
Date
2024-04-24 15:49 +0530
Parent
044101b
Commit
9e2b51c8e698d8216f680b61dd3908d2f1823b38

+145 −55

4 files changed

  1. M src/app.rs +28 −1
  2. M src/connection.rs +10 −8
  3. M src/handler.rs +67 −28
  4. M src/ui.rs +40 −18
M src/app.rs View
@@ -1,7 +1,6 @@
11 use crate::connection::Connection;
22 use crate::list::ContentList;
33 use mpd::Client;
4−use std::collections::VecDeque;
54
65 // Application result type
76 pub type AppResult<T> = std::result::Result<T, Box<dyn std::error::Error>>;
@@ -15,6 +14,25 @@ pub struct App {
1514 pub song_list: ContentList<String>,
1615 pub queue_list: ContentList<String>,
1716 pub pl_list: ContentList<String>,
17+ pub selected_tab: SelectedTab,
18+}
19+
20+
21+#[derive(Debug, PartialEq, Clone)]
22+pub enum SelectedTab {
23+ SongList,
24+ Queue,
25+ Playlists,
26+}
27+
28+impl SelectedTab {
29+ fn as_usize(&self) {
30+ match self {
31+ SelectedTab::SongList => 0,
32+ SelectedTab::Queue => 1,
33+ SelectedTab::Playlists => 2,
34+ };
35+ }
1836 }
1937
2038 impl App {
@@ -35,6 +53,7 @@ impl App {
3553 song_list,
3654 queue_list,
3755 pl_list,
56+ selected_tab: SelectedTab::SongList,
3857 })
3958 }
4059
@@ -73,4 +92,12 @@ impl App {
7392 Self::get_playlist(&mut self.conn.conn)?;
7493 Ok(())
7594 }
95+
96+ pub fn cycle_tabls(&mut self) {
97+ self.selected_tab = match self.selected_tab {
98+ SelectedTab::SongList => SelectedTab::Queue,
99+ SelectedTab::Queue => SelectedTab::Playlists,
100+ SelectedTab::Playlists=> SelectedTab::SongList,
101+ };
102+ }
76103 }
M src/connection.rs View
@@ -158,15 +158,17 @@ impl Connection {
158158 }
159159
160160 // Volume controls
161− /// Sets the volume
162− pub fn set_volume(&mut self, u: String) {
161+ pub fn inc_volume(&mut self, v: i8) {
163162 let cur = self.conn.status().unwrap().volume;
164− let sym = u.get(0..1).unwrap();
165− let u: i8 = u.parse::<i8>().unwrap();
166− if sym == "+" || sym == "-" {
167− self.conn.volume(cur + u).unwrap();
168− } else {
169− self.conn.volume(u).unwrap();
163+ if cur + v <= 100 {
164+ self.conn.volume(cur + v).unwrap();
165+ }
166+ }
167+
168+ pub fn dec_volume(&mut self, v: i8) {
169+ let cur = self.conn.status().unwrap().volume;
170+ if cur - v >= 0 {
171+ self.conn.volume(cur - v).unwrap();
170172 }
171173 }
172174 }
M src/handler.rs View
@@ -1,7 +1,8 @@
11 use std::time::Duration;
22
3−use crate::app::{App, AppResult};
3+use crate::app::{App, AppResult, SelectedTab};
44 use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
5+use ratatui::style::Modifier;
56
67 pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
78 match key_event.code {
@@ -12,36 +13,53 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
1213 }
1314 }
1415
15− KeyCode::Char('j') => {
16− app.song_list.next();
17− }
16+ KeyCode::Char('j') | KeyCode::Down => match app.selected_tab {
17+ SelectedTab::SongList => app.song_list.next(),
18+ SelectedTab::Queue => app.queue_list.next(),
19+ SelectedTab::Playlists => app.pl_list.next(),
20+ },
1821
19− KeyCode::Char('k') => {
20− app.song_list.prev();
21− }
22+ KeyCode::Char('k') | KeyCode::Up => match app.selected_tab {
23+ SelectedTab::SongList => app.song_list.prev(),
24+ SelectedTab::Queue => app.queue_list.prev(),
25+ SelectedTab::Playlists => app.pl_list.prev(),
26+ },
2227
2328 KeyCode::Enter | KeyCode::Char('l') => {
24− let song = app.conn.get_song_with_only_filename(
25− app.conn.songs_filenames.get(app.song_list.index).unwrap(),
26− );
27− app.conn.push(&song)?;
2829 // app.update_queue();
30+
31+ match app.selected_tab {
32+ SelectedTab::SongList => {
33+ let song = app.conn.get_song_with_only_filename(
34+ app.conn.songs_filenames.get(app.song_list.index).unwrap(),
35+ );
36+ app.conn.push(&song)?;
37+ }
38+ SelectedTab::Queue => {}
39+ SelectedTab::Playlists => {
40+ app.conn
41+ .push_playlist(app.pl_list.list.get(app.pl_list.index).unwrap())?;
42+ }
43+ }
2944 }
3045
3146 // Playback controls
3247 // Toggle Pause
3348 KeyCode::Char('p') => {
3449 app.conn.toggle_pause();
50+ app.conn.update_state();
3551 }
3652
3753 // Pause
3854 KeyCode::Char('s') => {
3955 app.conn.pause();
56+ app.conn.update_state();
4057 }
4158
42− // Clearn Queue
59+ // Clear Queue
4360 KeyCode::Char('x') => {
4461 app.conn.conn.clear()?;
62+ app.conn.update_state();
4563 // app.update_queue();
4664 }
4765
@@ -49,22 +67,6 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
4967 app.conn.play_dmenu()?;
5068 }
5169
52− KeyCode::Down => {
53− if key_event.modifiers == KeyModifiers::SHIFT {
54− app.queue_list.next();
55− } else {
56− app.pl_list.next();
57− }
58− }
59−
60− KeyCode::Up => {
61− if key_event.modifiers == KeyModifiers::SHIFT {
62− app.queue_list.prev();
63− } else {
64− app.pl_list.prev();
65− }
66− }
67−
6870 KeyCode::Right => {
6971 app.conn
7072 .push_playlist(app.pl_list.list.get(app.pl_list.index).unwrap())?;
@@ -83,6 +85,43 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
8385 let pos = Duration::from_secs(pos.as_secs().wrapping_add(2));
8486 app.conn.conn.seek(place, pos)?;
8587 }
88+
89+ KeyCode::Tab => {
90+ app.cycle_tabls();
91+ }
92+
93+ KeyCode::Char('1') => {
94+ app.selected_tab = SelectedTab::SongList;
95+ }
96+
97+ KeyCode::Char('2') => {
98+ app.selected_tab = SelectedTab::Queue;
99+ }
100+
101+ KeyCode::Char('3') => {
102+ app.selected_tab = SelectedTab::Playlists;
103+ }
104+
105+
106+ KeyCode::Char('n') => {
107+ app.conn.conn.next()?;
108+ }
109+
110+ KeyCode::Char('N') => {
111+ app.conn.conn.prev()?;
112+ }
113+
114+ // Volume controls
115+ KeyCode::Char('=') => {
116+ app.conn.inc_volume(2);
117+ }
118+
119+ KeyCode::Char('-') => {
120+ app.conn.dec_volume(2);
121+ }
122+
123+
124+
86125 _ => {}
87126 }
88127
M src/ui.rs View
@@ -1,6 +1,7 @@
1−use crate::app::{App, AppResult};
1+use crate::app::{App, AppResult, SelectedTab};
22 use ratatui::{
33 prelude::*,
4+ style::palette::tailwind,
45 widgets::{block::Title, *},
56 };
67
@@ -12,25 +13,45 @@ pub fn render(app: &mut App, frame: &mut Frame) {
1213 // - https://github.com/ratatui-org/ratatui/tree/master/examples
1314
1415 // Layout
15− let main_layout = Layout::default()
16+ let layout = Layout::default()
1617 .direction(Direction::Vertical)
17− .constraints(vec![Constraint::Percentage(93), Constraint::Percentage(7)])
18+ .constraints(vec![
19+ Constraint::Percentage(5),
20+ Constraint::Percentage(88),
21+ Constraint::Percentage(7),
22+ ])
1823 .split(frame.size());
19−
20− let outer_layout = Layout::default()
21− .direction(Direction::Horizontal)
22− .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
23− .split(main_layout[0]);
24−
25− let inner_layout = Layout::default()
26− .direction(Direction::Vertical)
27− .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
28− .split(outer_layout[1]);
29−
30− draw_song_list(frame, app, outer_layout[0]);
31− draw_queue(frame, app, inner_layout[0]);
32− draw_playlists(frame, app, inner_layout[1]);
33− draw_progress_bar(frame, app, main_layout[1]);
24+ //
25+ // let outer_layout = Layout::default()
26+ // .direction(Direction::Horizontal)
27+ // .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
28+ // .split(main_layout[1]);
29+ //
30+ // let inner_layout = Layout::default()
31+ // .direction(Direction::Vertical)
32+ // .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
33+ // .split(outer_layout[1]);
34+
35+ // draw_song_list(frame, app, outer_layout[0]);
36+ // draw_queue(frame, app, inner_layout[0]);
37+ // draw_playlists(frame, app, inner_layout[1]);
38+ draw_progress_bar(frame, app, layout[2]);
39+
40+ let highlight_style = (Color::default(), tailwind::YELLOW.c700);
41+ let tab = Tabs::new(vec!["Songs List", "Play Queue", "Playlists"])
42+ .block(Block::default().title("Tabs").borders(Borders::ALL))
43+ .style(Style::default().white())
44+ .highlight_style(highlight_style)
45+ .divider(" ")
46+ .select(app.selected_tab.clone() as usize)
47+ .padding("", "");
48+ frame.render_widget(tab, layout[0]);
49+
50+ match app.selected_tab {
51+ SelectedTab::SongList => draw_song_list(frame, app, layout[1]),
52+ SelectedTab::Queue => draw_queue(frame, app, layout[1]),
53+ SelectedTab::Playlists => draw_playlists(frame, app, layout[1]),
54+ }
3455 }
3556
3657 /// draws list of songs
@@ -98,6 +119,7 @@ fn draw_progress_bar(frame: &mut Frame, app: &mut App, size: Rect) {
98119 let title = Block::default()
99120 .title(Title::from(format!("{}: ", state).red().bold()))
100121 .title(Title::from(song.green().bold()));
122+ // .title(Title::from(app.conn.conn.status().unwrap_or_default().volume.to_string().yellow())).title_alignment(Alignment::Right);
101123 let progress_bar = LineGauge::default()
102124 .block(title.borders(Borders::ALL))
103125 .gauge_style(