From 719a4108916616a872d0281a65e06d37adce6a34 Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sat, 11 Oct 2025 17:32:10 +0600 Subject: [PATCH 1/5] Use fixed popup % --- tui/src/pages/popups/choice.rs | 21 ++++++++++------- tui/src/pages/popups/info.rs | 8 +++---- tui/src/pages/popups/input.rs | 8 +++---- tui/src/pages/popups/models.rs | 2 +- tui/src/pages/popups/new_path.rs | 8 +++---- tui/src/pages/popups/reposition.rs | 10 +++++--- tui/src/utility/utils.rs | 37 +++++++++++++++++++----------- 7 files changed, 57 insertions(+), 37 deletions(-) diff --git a/tui/src/pages/popups/choice.rs b/tui/src/pages/popups/choice.rs index 320f09d..da0868d 100644 --- a/tui/src/pages/popups/choice.rs +++ b/tui/src/pages/popups/choice.rs @@ -6,12 +6,12 @@ use ratatui::widgets::{BorderType, Borders, Clear, Paragraph, Row, Table, Wrap}; use crate::page_handler::{BACKGROUND, BOX, TEXT}; use crate::pages::{ChoicePopup, ChoicePopupState}; -use crate::utility::{centered_rect, main_block, styled_block}; +use crate::utility::{centered_rect_exact, main_block, styled_block}; impl ChoicePopup { pub fn show_ui(&mut self, f: &mut Frame) { let size = f.area(); - let x_value = 40; + let mut x_value = 40; let mut y_value = 10; let title; @@ -34,7 +34,7 @@ impl ChoicePopup { title = "Configuration"; message = "Select an option to configure"; - y_value = 20; + y_value = 12; constraints = vec![ Constraint::Length(4), @@ -46,23 +46,28 @@ impl ChoicePopup { title = "Configuration"; message = "Please add at least 1 Transaction Method to get started. Example Transaction Method: Bank, Cash, Paypal"; - y_value = 20; + y_value = 10; + x_value = 60; constraints = vec![ Constraint::Length(4), Constraint::Min(1), - Constraint::Length(7), + Constraint::Length(3), ]; } ChoicePopupState::TxMethods => { title = "Rename Method"; message = "Select a method to rename"; - y_value = 20; + y_value = 5 + self.table.items.len() as u16 + 2; + + if y_value > 20 { + y_value = 20; + } constraints = vec![ Constraint::Length(4), - Constraint::Min(1), + Constraint::Length(1), Constraint::Length((self.table.items.len() + 2) as u16), ]; } @@ -77,7 +82,7 @@ impl ChoicePopup { .title(title) .borders(Borders::ALL); - let area = centered_rect(x_value, y_value, size); + let area = centered_rect_exact(x_value, y_value, size); let new_chunks = Layout::default() .direction(Direction::Vertical) diff --git a/tui/src/pages/popups/info.rs b/tui/src/pages/popups/info.rs index 17099b0..ee5f537 100644 --- a/tui/src/pages/popups/info.rs +++ b/tui/src/pages/popups/info.rs @@ -11,13 +11,13 @@ use crate::pages::{ InfoPopup, InfoPopupState, activity_help_text, add_tx_help_text, chart_help_text, choice_help, home_help_text, new_update_text, reposition_help, search_help_text, summary_help_text, }; -use crate::utility::{centered_rect, create_bolded_text, main_block}; +use crate::utility::{centered_rect_exact, create_bolded_text, main_block}; impl InfoPopup { pub fn show_ui(&mut self, f: &mut Frame) { let size = f.area(); - let mut x_value = 60; - let mut y_value = 60; + let mut x_value = 80; + let mut y_value = 30; let mut title = "Help"; let message; @@ -83,7 +83,7 @@ impl InfoPopup { let text = create_bolded_text(&message); - let area = centered_rect(x_value, y_value, size); + let area = centered_rect_exact(x_value, y_value, size); let block = main_block() .title(title) diff --git a/tui/src/pages/popups/input.rs b/tui/src/pages/popups/input.rs index 75bee9d..17c9e97 100644 --- a/tui/src/pages/popups/input.rs +++ b/tui/src/pages/popups/input.rs @@ -6,13 +6,13 @@ use ratatui::widgets::{BorderType, Borders, Clear, Paragraph}; use crate::page_handler::{BACKGROUND, TEXT}; use crate::pages::InputPopup; -use crate::utility::{centered_rect, create_bolded_text, main_block, styled_block}; +use crate::utility::{centered_rect_exact, create_bolded_text, main_block, styled_block}; impl InputPopup { pub fn show_ui(&mut self, f: &mut Frame) { let size = f.area(); - let x_value = 40; - let y_value = 10; + let x_value = 50; + let y_value = 7; let title = if self.modifying_method.is_none() { "New Method" @@ -31,7 +31,7 @@ impl InputPopup { .title(title) .borders(Borders::ALL); - let area = centered_rect(x_value, y_value, size); + let area = centered_rect_exact(x_value, y_value, size); let new_chunks = Layout::default() .direction(Direction::Vertical) diff --git a/tui/src/pages/popups/models.rs b/tui/src/pages/popups/models.rs index 0afae1e..159673b 100644 --- a/tui/src/pages/popups/models.rs +++ b/tui/src/pages/popups/models.rs @@ -498,7 +498,7 @@ impl PopupType { pub fn new_choice_methods(conn: &mut DbConn) -> Result { let tx_methods = conn.get_tx_methods_sorted(); - if tx_methods.len() <= 1 { + if tx_methods.is_empty() { return Err(anyhow!( "There needs to be at least 1 transaction method existing for this option" )); diff --git a/tui/src/pages/popups/new_path.rs b/tui/src/pages/popups/new_path.rs index c342853..d25520d 100644 --- a/tui/src/pages/popups/new_path.rs +++ b/tui/src/pages/popups/new_path.rs @@ -7,13 +7,13 @@ use std::fmt::Write; use crate::page_handler::{BACKGROUND, BLUE, BOX, TEXT}; use crate::pages::NewPathsPopup; -use crate::utility::{centered_rect, main_block, styled_block}; +use crate::utility::{centered_rect_exact, main_block, styled_block}; impl NewPathsPopup { pub fn show_ui(&mut self, f: &mut Frame) { let size = f.area(); - let x_value = 40; - let y_value = 30; + let x_value = 50; + let y_value = 20; let title = if self.new_location { "New Location" @@ -28,7 +28,7 @@ impl NewPathsPopup { .title(title) .borders(Borders::ALL); - let area = centered_rect(x_value, y_value, size); + let area = centered_rect_exact(x_value, y_value, size); let new_chunks = Layout::default() .direction(Direction::Vertical) diff --git a/tui/src/pages/popups/reposition.rs b/tui/src/pages/popups/reposition.rs index 09a5db1..d3d874c 100644 --- a/tui/src/pages/popups/reposition.rs +++ b/tui/src/pages/popups/reposition.rs @@ -6,13 +6,17 @@ use ratatui::widgets::{BorderType, Borders, Clear, Row, Table}; use crate::page_handler::{BLUE, BOX, TEXT}; use crate::pages::RepositionPopup; -use crate::utility::{centered_rect, main_block, styled_block}; +use crate::utility::{centered_rect_exact, main_block, styled_block}; impl RepositionPopup { pub fn show_ui(&mut self, f: &mut Frame) { let size = f.area(); let x_value = 40; - let y_value = 20; + let mut y_value = self.reposition_table.items.len() as u16 + 4 + 3; + + if y_value > 20 { + y_value = 20; + } let title = "Reposition Tx Methods"; @@ -23,7 +27,7 @@ impl RepositionPopup { .title(title) .borders(Borders::ALL); - let area = centered_rect(x_value, y_value, size); + let area = centered_rect_exact(x_value, y_value, size); let new_chunks = Layout::default() .direction(Direction::Vertical) diff --git a/tui/src/utility/utils.rs b/tui/src/utility/utils.rs index 39654a7..3219841 100644 --- a/tui/src/utility/utils.rs +++ b/tui/src/utility/utils.rs @@ -247,25 +247,36 @@ pub fn migrate_to_new_schema(old_conn_path: &Path, new_conn: &str) -> Result Rect { - let popup_layout = Layout::default() +pub fn centered_rect_exact(width: u16, height: u16, r: Rect) -> Rect { + let w = width.min(r.width); + let h = height.min(r.height); + + let horizontal_space = r.width.saturating_sub(w); + let vertical_space = r.height.saturating_sub(h); + + let left = horizontal_space / 2; + let top = vertical_space / 2; + + let right = horizontal_space - left; + let bottom = vertical_space - top; + + let vertical = Layout::default() .direction(Direction::Vertical) .constraints([ - Constraint::Percentage((100 - percent_y) / 2), - Constraint::Percentage(percent_y), - Constraint::Percentage((100 - percent_y) / 2), + Constraint::Length(top), + Constraint::Length(h), + Constraint::Length(bottom), ]) .split(r); - Layout::default() + let horizontal = Layout::default() .direction(Direction::Horizontal) .constraints([ - Constraint::Percentage((100 - percent_x) / 2), - Constraint::Percentage(percent_x), - Constraint::Percentage((100 - percent_x) / 2), + Constraint::Length(left), + Constraint::Length(w), + Constraint::Length(right), ]) - .split(popup_layout[1])[1] + .split(vertical[1]); + + horizontal[1] } From fac5a815b3f396d91da4200ecd2248f2ebcd1196 Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sat, 11 Oct 2025 17:32:44 +0600 Subject: [PATCH 2/5] Bump version --- Cargo.lock | 2 +- tui/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb42823..41c5e9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1963,7 +1963,7 @@ version = "0.1.0" [[package]] name = "rex-tui" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "atty", diff --git a/tui/Cargo.toml b/tui/Cargo.toml index 0b494a4..19971f3 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rex-tui" -version = "0.2.0" +version = "0.2.1" edition = "2024" authors = ["TheRustyPickle "] readme = "../README.md" From d393585bf38de3d5c2c4a69399ce85d41be7c16b Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sat, 11 Oct 2025 17:34:30 +0600 Subject: [PATCH 3/5] Clippy fix --- app/src/modifier/shared.rs | 4 ++-- db/src/lib.rs | 6 +++--- tui/src/key_checker/initial.rs | 17 +++++++---------- tui/src/page_handler/ui_handler.rs | 2 +- tui/src/pages/add_tx_ui.rs | 2 +- tui/src/pages/home_ui.rs | 2 +- tui/src/pages/popups/new_path.rs | 4 ++-- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/app/src/modifier/shared.rs b/app/src/modifier/shared.rs index d2efa0e..0d6ce69 100644 --- a/app/src/modifier/shared.rs +++ b/app/src/modifier/shared.rs @@ -113,11 +113,11 @@ pub fn parse_search_fields<'a>( let year = split_date[0].parse::()?; let start_date = NaiveDate::from_ymd_opt(year, 1, 1) - .ok_or_else(|| anyhow!("{} is an invalid year", year))? + .ok_or_else(|| anyhow!("{year} is an invalid year"))? .and_time(NaiveTime::MIN); let end_date = NaiveDate::from_ymd_opt(year + 1, 1, 1) - .ok_or_else(|| anyhow!("{} is an invalid year", year))? + .ok_or_else(|| anyhow!("{year} is an invalid year"))? .and_time(NaiveTime::MIN); Some(DateNature::ByYear { diff --git a/db/src/lib.rs b/db/src/lib.rs index 07dd756..e17bd77 100644 --- a/db/src/lib.rs +++ b/db/src/lib.rs @@ -29,14 +29,14 @@ impl Cache { .values() .find(|m| m.name == name) .map(|m| m.id) - .ok_or_else(|| anyhow!("method '{}' not found", name)) + .ok_or_else(|| anyhow!("method '{name}' not found")) } pub fn get_method_by_name(&self, name: &str) -> Result<&TxMethod> { self.tx_methods .values() .find(|m| m.name == name) - .ok_or_else(|| anyhow!("method '{}' not found", name)) + .ok_or_else(|| anyhow!("method '{name}' not found")) } pub fn get_method_by_name_mut(&mut self, name: &str) -> Result<&mut TxMethod> { @@ -50,7 +50,7 @@ impl Cache { .values() .find(|m| m.name == name) .map(|m| m.id) - .ok_or_else(|| anyhow!("tag '{}' not found", name)) + .ok_or_else(|| anyhow!("tag '{name}' not found")) } pub fn new_tags(&mut self, tags: Vec) { diff --git a/tui/src/key_checker/initial.rs b/tui/src/key_checker/initial.rs index 327d44a..af7c8ce 100644 --- a/tui/src/key_checker/initial.rs +++ b/tui/src/key_checker/initial.rs @@ -7,17 +7,14 @@ use crate::pages::PopupType; /// Tracks the keys of the Initial page and calls relevant function based on it pub fn initial_keys(handler: &mut InputKeyHandler) -> Result> { - match handler.popup_status { - PopupType::Nothing => match handler.key.code { - KeyCode::Char('q') => return Ok(Some(HandlingOutput::QuitUi)), - _ => handler.go_home(), - }, - _ => { - if let KeyCode::Char('q') = handler.key.code { - return Ok(Some(HandlingOutput::QuitUi)); - }; - return popup_keys(handler); + if let PopupType::Nothing = handler.popup_status { match handler.key.code { + KeyCode::Char('q') => return Ok(Some(HandlingOutput::QuitUi)), + _ => handler.go_home(), + } } else { + if let KeyCode::Char('q') = handler.key.code { + return Ok(Some(HandlingOutput::QuitUi)); } + return popup_keys(handler); } Ok(None) } diff --git a/tui/src/page_handler/ui_handler.rs b/tui/src/page_handler/ui_handler.rs index f05d7e0..48cb8f0 100644 --- a/tui/src/page_handler/ui_handler.rs +++ b/tui/src/page_handler/ui_handler.rs @@ -193,7 +193,7 @@ pub fn start_app( && let PopupType::Nothing = popup_status { popup_status = PopupType::new_choice_config_forced(); - }; + } // Passing out relevant data to the UI function terminal diff --git a/tui/src/pages/add_tx_ui.rs b/tui/src/pages/add_tx_ui.rs index 0c407f2..fba271f 100644 --- a/tui/src/pages/add_tx_ui.rs +++ b/tui/src/pages/add_tx_ui.rs @@ -157,7 +157,7 @@ pub fn add_tx_ui( .style(Style::default().fg(TEXT)) }); - let balance_area = Table::new(bal_data, width_data.to_owned()) + let balance_area = Table::new(bal_data, width_data.clone()) .block(styled_block("Balance Change")) .style(Style::default().fg(BOX)); diff --git a/tui/src/pages/home_ui.rs b/tui/src/pages/home_ui.rs index c920b2a..73ae6e3 100644 --- a/tui/src/pages/home_ui.rs +++ b/tui/src/pages/home_ui.rs @@ -210,7 +210,7 @@ pub fn home_ui( // Use the acquired width data to the allocated spaces // between columns on Balance widget. - let balance_area = Table::new(bal_data, width_data.to_owned()) + let balance_area = Table::new(bal_data, width_data.clone()) .block(styled_block("Balance")) .style(Style::default().fg(BOX)); diff --git a/tui/src/pages/popups/new_path.rs b/tui/src/pages/popups/new_path.rs index d25520d..a39cbba 100644 --- a/tui/src/pages/popups/new_path.rs +++ b/tui/src/pages/popups/new_path.rs @@ -47,8 +47,8 @@ impl NewPathsPopup { let mut path_text = String::new(); - for path in self.paths.iter() { - writeln!(path_text, "{}", path.display()).unwrap() + for path in &self.paths { + writeln!(path_text, "{}", path.display()).unwrap(); } let path_list = Paragraph::new(Text::from(path_text)) From 4ce6ae10775ebfc2e18a7cb39143dc3169d5f552 Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sat, 11 Oct 2025 17:42:50 +0600 Subject: [PATCH 4/5] Update versions --- Cargo.lock | 8 ++++---- Cargo.toml | 4 ++-- app/Cargo.toml | 4 ++-- db/Cargo.toml | 2 +- tui/Cargo.toml | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41c5e9a..d2a78ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1934,7 +1934,7 @@ dependencies = [ [[package]] name = "rex-app" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "chrono", @@ -1947,7 +1947,7 @@ dependencies = [ [[package]] name = "rex-db" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "chrono", @@ -1963,7 +1963,7 @@ version = "0.1.0" [[package]] name = "rex-tui" -version = "0.2.1" +version = "0.2.0" dependencies = [ "anyhow", "atty", @@ -2038,7 +2038,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6b3acf6..7d41bd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,8 @@ resolver = "2" [workspace.dependencies] rex-shared = "0.1.0" -rex-db = "0.1.0" -rex-app = "0.1.0" +rex-db = "0.1.1" +rex-app = "0.1.1" chrono = "0.4.42" diesel = { version = "2.3.2", default-features = false, features = [ "returning_clauses_for_sqlite_3_35", diff --git a/app/Cargo.toml b/app/Cargo.toml index 838b5ac..6850f78 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rex-app" -version = "0.1.0" +version = "0.1.1" edition = "2024" description = """ Core functionality for Rex @@ -10,7 +10,7 @@ repository = "https://github.com/TheRustyPickle/Rex" license = "MIT" [dependencies] -db = { package = "rex-db", version = "0.1.0" } +db = { package = "rex-db", version = "0.1.1" } shared = { package = "rex-shared", version = "0.1.0" } chrono.workspace = true anyhow.workspace = true diff --git a/db/Cargo.toml b/db/Cargo.toml index 6fcf67a..13d9b6c 100644 --- a/db/Cargo.toml +++ b/db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rex-db" -version = "0.1.0" +version = "0.1.1" edition = "2024" description = """ Rex database models using diesel diff --git a/tui/Cargo.toml b/tui/Cargo.toml index 19971f3..49f3dd0 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rex-tui" -version = "0.2.1" +version = "0.2.0" edition = "2024" authors = ["TheRustyPickle "] readme = "../README.md" @@ -21,7 +21,7 @@ test = false bench = false [dependencies] -app = { package = "rex-app", version = "0.1.0" } +app = { package = "rex-app", version = "0.1.1" } shared = { package = "rex-shared", version = "0.1.0" } anyhow.workspace = true crossterm = "0.29.0" From 38b4ade2f0ec844b03963cf0646983416c6702f2 Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sat, 11 Oct 2025 17:44:44 +0600 Subject: [PATCH 5/5] Formatting --- tui/src/key_checker/initial.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tui/src/key_checker/initial.rs b/tui/src/key_checker/initial.rs index af7c8ce..60e076c 100644 --- a/tui/src/key_checker/initial.rs +++ b/tui/src/key_checker/initial.rs @@ -7,10 +7,12 @@ use crate::pages::PopupType; /// Tracks the keys of the Initial page and calls relevant function based on it pub fn initial_keys(handler: &mut InputKeyHandler) -> Result> { - if let PopupType::Nothing = handler.popup_status { match handler.key.code { - KeyCode::Char('q') => return Ok(Some(HandlingOutput::QuitUi)), - _ => handler.go_home(), - } } else { + if let PopupType::Nothing = handler.popup_status { + match handler.key.code { + KeyCode::Char('q') => return Ok(Some(HandlingOutput::QuitUi)), + _ => handler.go_home(), + } + } else { if let KeyCode::Char('q') = handler.key.code { return Ok(Some(HandlingOutput::QuitUi)); }