Skip to content

Commit

Permalink
refactor: widget macro
Browse files Browse the repository at this point in the history
  • Loading branch information
Beastwick18 committed Jun 3, 2024
1 parent 378bb55 commit ac32e52
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 89 deletions.
4 changes: 0 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ license = "GPL-3.0-or-later"
strip = true
lto = true

[features]
default = []
unstable-captcha = []

[dependencies]
reqwest = { version = "0.11.27", features = [
"gzip",
Expand Down
128 changes: 43 additions & 85 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::{
user::UserPopup,
Widget,
},
widgets,
};

#[cfg(unix)]
Expand All @@ -62,22 +63,6 @@ pub enum LoadType {
Downloading,
}

impl Display for LoadType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
LoadType::Sourcing => "Sourcing",
LoadType::Searching => "Searching",
LoadType::SolvingCaptcha(_) => "Solving",
LoadType::Sorting => "Sorting",
LoadType::Filtering => "Filtering",
LoadType::Categorizing => "Categorizing",
LoadType::Batching => "Downloading Batch",
LoadType::Downloading => "Downloading",
};
write!(f, "{}", s)
}
}

#[derive(PartialEq, Clone)]
pub enum Mode {
Normal,
Expand All @@ -97,6 +82,42 @@ pub enum Mode {
Captcha,
}

widgets! {
Widgets;
batch: [Mode::Batch] => BatchWidget,
search: [Mode::Search] => SearchWidget,
results: [Mode::Normal] => ResultsWidget,
notification: NotificationWidget,
[popups]: {
category: [Mode::Category] => CategoryPopup,
sort: [Mode::Sort(_)] => SortPopup,
filter: [Mode::Filter] => FilterPopup,
theme: [Mode::Theme] => ThemePopup,
sources: [Mode::Sources] => SourcesPopup,
clients: [Mode::Clients] => ClientsPopup,
page: [Mode::Page] => PagePopup,
user: [Mode::User] => UserPopup,
help: [Mode::Help] => HelpPopup,
captcha: [Mode::Captcha] => CaptchaPopup,
}
}

impl Display for LoadType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
LoadType::Sourcing => "Sourcing",
LoadType::Searching => "Searching",
LoadType::SolvingCaptcha(_) => "Solving",
LoadType::Sorting => "Sorting",
LoadType::Filtering => "Filtering",
LoadType::Categorizing => "Categorizing",
LoadType::Batching => "Downloading Batch",
LoadType::Downloading => "Downloading",
};
write!(f, "{}", s)
}
}

impl Display for Mode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Expand Down Expand Up @@ -199,24 +220,6 @@ impl Default for Context {
}
}

#[derive(Default)]
pub struct Widgets {
pub notification: NotificationWidget,
pub batch: BatchWidget,
pub category: CategoryPopup,
pub sort: SortPopup,
pub filter: FilterPopup,
pub theme: ThemePopup,
pub sources: SourcesPopup,
pub clients: ClientsPopup,
pub search: SearchWidget,
pub results: ResultsWidget,
pub page: PagePopup,
pub user: UserPopup,
pub help: HelpPopup,
pub captcha: CaptchaPopup,
}

impl App {
pub async fn run_app<B: Backend, S: EventSync + Clone, C: ConfigManager, const TEST: bool>(
&mut self,
Expand Down Expand Up @@ -254,13 +257,6 @@ impl App {
let mut last_load_abort: Option<AbortHandle> = None;
let mut last_time: Option<Instant> = None;

// let bytes = client.get("https://torrentgalaxy.to/captcha/cpt_show.pnp?v=txlight&62fd4c746843c74b53ca60277192fb48").send().await?.bytes().await?;
// let mut picker = Picker::new((1, 2));
// picker.protocol_type = ProtocolType::Halfblocks;
// let dyn_image = image::load_from_memory(&bytes[..])?;
// let image = picker.new_resize_protocol(dyn_image);
// self.widgets.captcha.image = Some(image);

while !ctx.should_quit {
if ctx.should_save_config {
if let Err(e) = C::store(&ctx.config) {
Expand Down Expand Up @@ -450,7 +446,9 @@ impl App {
let layout_horizontal = Layout::new(
Direction::Horizontal,
match ctx.mode {
Mode::Batch => [Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)],
Mode::Batch | Mode::Help => {
[Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)]
}
_ => [Constraint::Ratio(3, 4), Constraint::Ratio(1, 4)],
},
)
Expand All @@ -459,19 +457,7 @@ impl App {
self.widgets.batch.draw(f, ctx, layout_horizontal[1]);
}
}
match ctx.mode {
Mode::Category => self.widgets.category.draw(f, ctx, f.size()),
Mode::Sort(_) => self.widgets.sort.draw(f, ctx, f.size()),
Mode::Filter => self.widgets.filter.draw(f, ctx, f.size()),
Mode::Theme => self.widgets.theme.draw(f, ctx, f.size()),
Mode::Help => self.widgets.help.draw(f, ctx, f.size()),
Mode::Page => self.widgets.page.draw(f, ctx, f.size()),
Mode::User => self.widgets.user.draw(f, ctx, f.size()),
Mode::Sources => self.widgets.sources.draw(f, ctx, f.size()),
Mode::Clients => self.widgets.clients.draw(f, ctx, f.size()),
Mode::Captcha => self.widgets.captcha.draw(f, ctx, f.size()),
Mode::KeyCombo(_) | Mode::Normal | Mode::Search | Mode::Loading(_) | Mode::Batch => {}
}
self.widgets.draw_popups(ctx, f);
self.widgets.notification.draw(f, ctx, f.size());
}

Expand Down Expand Up @@ -511,21 +497,9 @@ impl App {
};
}
match ctx.mode.to_owned() {
Mode::Category => self.widgets.category.handle_event(ctx, evt),
Mode::Sort(_) => self.widgets.sort.handle_event(ctx, evt),
Mode::Normal => self.widgets.results.handle_event(ctx, evt),
Mode::Batch => self.widgets.batch.handle_event(ctx, evt),
Mode::Search => self.widgets.search.handle_event(ctx, evt),
Mode::Filter => self.widgets.filter.handle_event(ctx, evt),
Mode::Theme => self.widgets.theme.handle_event(ctx, evt),
Mode::Page => self.widgets.page.handle_event(ctx, evt),
Mode::User => self.widgets.user.handle_event(ctx, evt),
Mode::Help => self.widgets.help.handle_event(ctx, evt),
Mode::Sources => self.widgets.sources.handle_event(ctx, evt),
Mode::Clients => self.widgets.clients.handle_event(ctx, evt),
Mode::Captcha => self.widgets.captcha.handle_event(ctx, evt),
Mode::KeyCombo(keys) => self.on_combo(ctx, keys, evt),
Mode::Loading(_) => {}
_ => self.widgets.handle_event(ctx, evt),
}
if ctx.mode != Mode::Help {
self.on_help(evt, ctx);
Expand All @@ -552,23 +526,7 @@ impl App {
}

fn get_help(&mut self, ctx: &Context) {
let help = match ctx.mode {
Mode::Category => CategoryPopup::get_help(),
Mode::Sort(_) => SortPopup::get_help(),
Mode::Normal => ResultsWidget::get_help(),
Mode::Batch => BatchWidget::get_help(),
Mode::Search => SearchWidget::get_help(),
Mode::Filter => FilterPopup::get_help(),
Mode::Theme => ThemePopup::get_help(),
Mode::Page => PagePopup::get_help(),
Mode::User => UserPopup::get_help(),
Mode::Sources => SourcesPopup::get_help(),
Mode::Clients => ClientsPopup::get_help(),
Mode::Captcha => CaptchaPopup::get_help(),
Mode::Help => None,
Mode::KeyCombo(_) => None,
Mode::Loading(_) => None,
};
let help = self.widgets.get_help(&ctx.mode);
if let Some(msg) = help {
self.widgets.help.with_items(msg, ctx.mode.clone());
self.widgets.help.table.select(0);
Expand Down
71 changes: 71 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,74 @@
#[macro_export]
macro_rules! widgets {
(
$name:ident;
$(
$widget:ident:
$(
[$mode:pat_param]
=>
)?
$struc:ident,
)+
[popups]: {
$(
$pwidget:ident:
$(
[$pmode:pat_param]
=>
)?
$pstruc:ident,
)+
}
) => {
#[derive(Default)]
pub struct $name {
$(
pub $widget: $struc,
)+
$(
pub $pwidget: $pstruc,
)+
}

impl $name {
fn draw_popups(&mut self, ctx: &$crate::app::Context, f: &mut ratatui::Frame) {
match ctx.mode {
$(
$($pmode => self.$pwidget.draw(f, ctx, f.size()),)?
)+
_ => {}
}

}

fn get_help(&self, mode: &$crate::app::Mode) -> Option<Vec<(&'static str, &'static str)>> {
match mode {
$(
$($mode => $struc::get_help(),)?
)+
$(
$($pmode => $pstruc::get_help(),)?
)+
_ => None,
}
}

fn handle_event(&mut self, ctx: &mut $crate::app::Context, evt: &crossterm::event::Event) {
match ctx.mode {
$(
$($mode => self.$widget.handle_event(ctx, evt),)?
)+
$(
$($pmode => self.$pwidget.handle_event(ctx, evt),)?
)+
_ => {}
};
}
}
}
}

#[macro_export]
macro_rules! cats {
(
Expand Down
20 changes: 20 additions & 0 deletions src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,26 @@ impl TitlePosition {
}
}

pub fn dim_buffer(area: Rect, buf: &mut Buffer, amt: f32) {
for r in area.top()..area.bottom() {
for c in area.left()..area.right() {
let cell = buf.get_mut(c, r);
if let Color::Rgb(r, g, b) = cell.fg {
let r = (r as f32 * amt) as u8;
let g = (g as f32 * amt) as u8;
let b = (b as f32 * amt) as u8;
cell.fg = Color::Rgb(r, g, b);
}
if let Color::Rgb(r, g, b) = cell.bg {
let r = (r as f32 * amt) as u8;
let g = (g as f32 * amt) as u8;
let b = (b as f32 * amt) as u8;
cell.bg = Color::Rgb(r, g, b);
}
}
}
}

pub fn centered_rect(mut x_len: u16, mut y_len: u16, r: Rect) -> Rect {
x_len = min(x_len, r.width);
y_len = min(y_len, r.height);
Expand Down
1 change: 1 addition & 0 deletions src/widget/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ impl Widget for FilterPopup {
true => Row::new(vec![format!("  {}", item.to_owned())]),
false => Row::new(vec![format!(" {}", item.to_owned())]),
});
// super::dim_buffer(area, f.buffer_mut(), 0.5);
super::clear(center, f.buffer_mut(), ctx.theme.bg);
Table::new(items, [Constraint::Percentage(100)])
.block(border_block(&ctx.theme, true).title(title!("Filter")))
Expand Down

0 comments on commit ac32e52

Please sign in to comment.