From e32d0c9da598873ba75c473919359bd9df7f59cb Mon Sep 17 00:00:00 2001 From: chris west Date: Mon, 27 Jan 2020 19:33:47 -0800 Subject: [PATCH] views remember their wide mode setting --- src/menu.rs | 22 +++++++++++++++------- src/text.rs | 22 ++++++++++++++++------ src/ui.rs | 16 ++++++++++------ src/ui/view.rs | 8 ++++++-- 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/menu.rs b/src/menu.rs index 85a59eb..2a062a4 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -158,14 +158,22 @@ impl View for Menu { self.raw.as_ref() } - fn render(&mut self, cfg: &Config) -> String { - self.render_lines(cfg) + fn render(&mut self) -> String { + self.render_lines() } fn respond(&mut self, key: Key) -> Action { self.process_key(key) } + fn set_wide(&mut self, wide: bool) { + self.wide = wide; + } + + fn wide(&mut self) -> bool { + self.wide + } + fn term_size(&mut self, cols: usize, rows: usize) { self.size = (cols, rows); } @@ -178,10 +186,12 @@ impl View for Menu { impl Menu { /// Create a representation of a Gopher Menu from a raw Gopher /// response and a few options. - pub fn from(url: &str, response: String, tls: bool, tor: bool) -> Menu { + pub fn from(url: &str, response: String, config: &Config, tls: bool) -> Menu { Menu { tls, - tor, + tor: config.tor, + wide: config.wide, + mode: config.mode, ..parse(url, response) } } @@ -256,9 +266,7 @@ impl Menu { Some((x as u16, y as u16)) } - fn render_lines(&mut self, cfg: &Config) -> String { - self.wide = cfg.wide; - self.mode = cfg.mode; + fn render_lines(&mut self) -> String { let mut out = String::new(); let limit = if self.mode == ui::Mode::Run { // only show as many lines as screen rows minus one diff --git a/src/text.rs b/src/text.rs index ece446e..4d951e0 100644 --- a/src/text.rs +++ b/src/text.rs @@ -28,6 +28,8 @@ pub struct Text { pub tls: bool, /// Retrieved via Tor? pub tor: bool, + /// UI mode. Interactive (Run), Printing, Raw mode... + mode: ui::Mode, /// Currently in wide mode? pub wide: bool, } @@ -59,6 +61,14 @@ impl View for Text { self.size = (cols, rows); } + fn set_wide(&mut self, wide: bool) { + self.wide = wide; + } + + fn wide(&mut self) -> bool { + self.wide + } + fn respond(&mut self, c: Key) -> Action { match c { Key::Home => { @@ -108,8 +118,7 @@ impl View for Text { } } - fn render(&mut self, cfg: &Config) -> String { - self.wide = cfg.wide; + fn render(&mut self) -> String { let (cols, rows) = self.size; let mut out = String::new(); let longest = if self.longest > MAX_COLS { @@ -124,7 +133,7 @@ impl View for Text { } else { String::from("") }; - let limit = if cfg.mode == ui::Mode::Run { + let limit = if self.mode == ui::Mode::Run { rows - 1 } else { self.lines @@ -161,7 +170,7 @@ impl View for Text { impl Text { /// Create a Text View from a raw Gopher response and a few options. - pub fn from(url: &str, response: String, tls: bool, tor: bool) -> Text { + pub fn from(url: &str, response: String, config: &Config, tls: bool) -> Text { let mut lines = 0; let mut longest = 0; for line in response.split_terminator('\n') { @@ -179,9 +188,10 @@ impl Text { lines, longest, size: (0, 0), + mode: config.mode, tls, - tor, - wide: false, + tor: config.tor, + wide: config.wide, } } diff --git a/src/ui.rs b/src/ui.rs index 3aac556..2065e4c 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -251,8 +251,8 @@ impl UI { }; let typ = gopher::type_for_url(&url); match typ { - Type::Menu | Type::Search => Ok(Box::new(Menu::from(url, res, tls, tor))), - Type::Text | Type::HTML => Ok(Box::new(Text::from(url, res, tls, tor))), + Type::Menu | Type::Search => Ok(Box::new(Menu::from(url, res, &self.config, tls))), + Type::Text | Type::HTML => Ok(Box::new(Text::from(url, res, &self.config, tls))), _ => Err(error!("Unsupported Gopher Response: {:?}", typ)), } } @@ -263,7 +263,7 @@ impl UI { &url.trim_start_matches("gopher://phetch/") .trim_start_matches("1/"), ) { - Ok(Box::new(Menu::from(url, source, false, false))) + Ok(Box::new(Menu::from(url, source, &self.config, false))) } else { Err(error!("phetch URL not found: {}", url)) } @@ -330,7 +330,7 @@ impl UI { if !self.views.is_empty() && self.focused < self.views.len() { if let Some(page) = self.views.get_mut(self.focused) { page.term_size(cols as usize, rows as usize); - return Ok(page.render(&self.config)); + return Ok(page.render()); } } Err(error!( @@ -595,7 +595,7 @@ impl UI { if let Some(page) = self.views.get(self.focused) { let url = page.url(); let raw = page.raw().to_string(); - let mut text = Text::from(url, raw, page.is_tls(), page.is_tor()); + let mut text = Text::from(url, raw, &self.config, page.is_tls()); text.wide = true; self.add_page(Box::new(text)); } @@ -632,7 +632,11 @@ impl UI { } 'w' => { self.config.wide = !self.config.wide; - self.dirty = true; + if let Some(view) = self.views.get_mut(self.focused) { + let w = view.wide(); + view.set_wide(!w); + self.dirty = true; + } } 'q' => self.running = false, c => return Err(error!("Unknown keypress: {}", c)), diff --git a/src/ui/view.rs b/src/ui/view.rs index 852360b..f4bff94 100644 --- a/src/ui/view.rs +++ b/src/ui/view.rs @@ -1,4 +1,4 @@ -use crate::{config::Config, ui}; +use crate::ui; use std::fmt; /// Views represent what's on screen, a Gopher Menu/Text/etc item. @@ -8,7 +8,7 @@ pub trait View: fmt::Display { fn respond(&mut self, key: ui::Key) -> ui::Action; /// Create a String of the current view's state that can be /// printed to the screen. - fn render(&mut self, cfg: &Config) -> String; + fn render(&mut self) -> String; /// Was this View's content fetched using TLS? fn is_tls(&self) -> bool; /// Was this View's content fetched over Tor? @@ -17,6 +17,10 @@ pub trait View: fmt::Display { fn url(&self) -> &str; /// The raw Gopher representation of this View. fn raw(&self) -> &str; + /// Set wide mode on this view. + fn set_wide(&mut self, wide: bool); + /// In wide mode? + fn wide(&mut self) -> bool; /// Set the current screen size. fn term_size(&mut self, cols: usize, rows: usize); }