From c25fe0a4f5c9b7b3c57876a07875dc433b5fca47 Mon Sep 17 00:00:00 2001 From: Adrian Wozniak Date: Fri, 4 Jan 2019 11:46:28 +0100 Subject: [PATCH] Shared config with Rc --- src/app/app_state.rs | 63 ++++++++++++++++++------------ src/app/mod.rs | 32 +++++++++------ src/renderer/mod.rs | 8 ++-- src/ui/caret.rs | 7 +++- src/ui/file/editor_file.rs | 19 +++++---- src/ui/file/editor_file_section.rs | 16 ++++---- src/ui/file/editor_file_token.rs | 17 ++++---- src/ui/menu_bar.rs | 15 ++++--- src/ui/mod.rs | 2 +- src/ui/text_character.rs | 12 +++--- 10 files changed, 115 insertions(+), 76 deletions(-) diff --git a/src/app/app_state.rs b/src/app/app_state.rs index de3b62d..4043fc8 100644 --- a/src/app/app_state.rs +++ b/src/app/app_state.rs @@ -6,33 +6,34 @@ use crate::renderer::Renderer; use crate::ui::*; use crate::ui::caret::Caret; use crate::ui::menu_bar::MenuBar; -use sdl2::rect::Point; use std::boxed::Box; use std::rc::Rc; use std::sync::Arc; -use sdl2::rect::Rect; +use sdl2::rect::{Rect, Point}; pub struct AppState { menu_bar: MenuBar, files: Vec, current_file: usize, caret: Caret, + config: Rc, } impl AppState { - pub fn new(config: &Config) -> Self { + pub fn new(config: Rc) -> Self { Self { - menu_bar: MenuBar::new(), + menu_bar: MenuBar::new(config.clone()), files: vec![], current_file: 0, - caret: Caret::new(config), + caret: Caret::new(config.clone()), + config, } } - pub fn open_file(&mut self, file_path: String, config: &Config) { + pub fn open_file(&mut self, file_path: String) { use std::fs::read_to_string; if let Ok(buffer) = read_to_string(&file_path) { - let file = EditorFile::new(file_path.clone(), buffer, config); + let file = EditorFile::new(file_path.clone(), buffer, self.config.clone()); self.current_file = self.files.len(); self.files.push(file); }; @@ -42,7 +43,7 @@ impl AppState { &mut self.caret } - pub fn delete_front(&mut self, config: &Config) { + pub fn delete_front(&mut self) { let file: &mut EditorFile = if let Some(file) = self.files.get_mut(self.current_file) { file } else { @@ -69,12 +70,12 @@ impl AppState { let new_file = EditorFile::new( file.path(), buffer, - config, + self.config.clone(), ); self.files[self.current_file] = new_file; } - pub fn delete_back(&mut self, config: &Config) { + pub fn delete_back(&mut self) { let file: &mut EditorFile = if let Some(file) = self.files.get_mut(self.current_file) { file } else { @@ -90,7 +91,7 @@ impl AppState { let new_file = EditorFile::new( file.path(), buffer, - config, + self.config.clone(), ); self.files[self.current_file] = new_file; } @@ -108,7 +109,7 @@ impl AppState { let new_file = EditorFile::new( file.path(), buffer, - renderer.config(), + self.config.clone(), ); if let Some(rect) = get_text_character_rect(character, renderer) { if let Some(current) = file.get_character_at(position) { @@ -120,6 +121,29 @@ impl AppState { } self.files[self.current_file] = new_file; } + + fn current_file(&mut self) -> Option<&mut EditorFile> { + self.files.get_mut(self.current_file) + } + + fn on_editor_clicked(&mut self, point: &Point) -> UpdateResult { + let current_file: &mut EditorFile = if let Some(current_file) = self.current_file() { + current_file + } else { + return UpdateResult::NoOp; + }; + if !current_file.is_left_click_target(point) { + return UpdateResult::NoOp; + } + match current_file.on_left_click(point) { + UpdateResult::MoveCaret(rect, position) => { + self.caret.move_caret(position, Point::new(rect.x(), rect.y())); + } + _ => (), + }; + + UpdateResult::NoOp + } } impl Render for AppState { @@ -145,20 +169,11 @@ impl Update for AppState { } impl ClickHandler for AppState { - fn on_left_click(&mut self, point: &Point, config: &Config) -> UpdateResult { + fn on_left_click(&mut self, point: &Point) -> UpdateResult { if self.menu_bar.is_left_click_target(point) { - return self.menu_bar.on_left_click(point, config); - } - if let Some(current_file) = self.files.get_mut(self.current_file) { - if current_file.is_left_click_target(point) { - match current_file.on_left_click(point, config) { - UpdateResult::MoveCaret(rect, position) => { - self.caret.move_caret(position, Point::new(rect.x(), rect.y())); - } - _ => (), - }; - } + return self.menu_bar.on_left_click(point); } + self.on_editor_clicked(point); UpdateResult::NoOp } diff --git a/src/app/mod.rs b/src/app/mod.rs index dcb3851..57fdfb8 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -4,7 +4,11 @@ use crate::renderer::Renderer; use crate::themes::*; use crate::ui::*; -use sdl2::{Sdl, TimerSubsystem}; +use std::thread::sleep; +use std::time::Duration; +use std::rc::Rc; + +use sdl2::{Sdl, VideoSubsystem, TimerSubsystem}; use sdl2::event::Event; use sdl2::EventPump; use sdl2::keyboard::{Keycode, Mod}; @@ -14,8 +18,7 @@ use sdl2::pixels::Color; use sdl2::rect::{Point, Rect}; use sdl2::render::Canvas; use sdl2::video::Window; -use std::thread::sleep; -use std::time::Duration; +use sdl2::ttf::Sdl2TtfContext; pub mod app_state; pub mod keyboard_handler; @@ -39,34 +42,39 @@ pub enum Task { } pub struct Application { - config: Config, + config: Rc, + clear_color: Color, sdl_context: Sdl, canvas: WindowCanvas, + video_subsystem: VideoSubsystem, tasks: Vec, - clear_color: Color, } impl Application { pub fn new() -> Self { - let config = Config::new(); + let config = Rc::new(Config::new()); let sdl_context = sdl2::init().unwrap(); hint::set("SDL_GL_MULTISAMPLEBUFFERS", "1"); hint::set("SDL_GL_MULTISAMPLESAMPLES", "8"); hint::set("SDL_GL_ACCELERATED_VISUAL", "1"); hint::set("SDL_HINT_RENDER_SCALE_QUALITY", "2"); hint::set("SDL_HINT_VIDEO_ALLOW_SCREENSAVER", "1"); + let video_subsystem = sdl_context.video().unwrap(); + let window = video_subsystem - .window("Editor", config.width(), config.height()) + .window("Rider", config.width(), config.height()) .position_centered() .opengl() .build() .unwrap(); let canvas = window.into_canvas().accelerated().build().unwrap(); +// let font_context = Rc::new(sdl2::ttf::init().unwrap()); Self { sdl_context, + video_subsystem, canvas, tasks: vec![], clear_color: config.theme().background().into(), @@ -84,7 +92,7 @@ impl Application { let font_context = sdl2::ttf::init().unwrap(); let texture_creator = self.canvas.texture_creator(); let sleep_time = Duration::new(0, 1_000_000_000u32 / 60); - let mut app_state = AppState::new(&self.config); + let mut app_state = AppState::new(self.config.clone()); let mut renderer = Renderer::new(self.config.clone(), &font_context, &texture_creator); 'running: loop { @@ -94,13 +102,13 @@ impl Application { UpdateResult::NoOp => (), UpdateResult::MoveCaret(_, _pos) => (), UpdateResult::MouseLeftClicked(point) => { - app_state.on_left_click(&point, renderer.config()); + app_state.on_left_click(&point); } UpdateResult::DeleteFront => { - app_state.delete_front(renderer.config()); + app_state.delete_front(); }, UpdateResult::DeleteBack => { - app_state.delete_back(renderer.config()); + app_state.delete_back(); }, UpdateResult::Input(text_character) => { app_state.insert_character(text_character, &mut renderer); @@ -110,7 +118,7 @@ impl Application { match task { Task::OpenFile { file_path } => { use crate::ui::file::editor_file::*; - app_state.open_file(file_path.clone(), renderer.config()); + app_state.open_file(file_path.clone()); } } } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 185edec..debdda6 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -2,16 +2,16 @@ use crate::app::WindowCanvas; use crate::config::Config; use crate::renderer::managers::{FontManager, TextureManager}; use crate::renderer::managers::TextDetails; +use std::rc::Rc; use sdl2::rect::{Point, Rect}; use sdl2::render::{Texture, TextureCreator}; use sdl2::ttf::Sdl2TtfContext; use sdl2::video::WindowContext; -use std::rc::Rc; pub mod managers; pub struct Renderer<'a> { - config: Config, + config: Rc, font_manager: FontManager<'a>, texture_manager: TextureManager<'a, WindowContext>, scroll: Point, @@ -19,7 +19,7 @@ pub struct Renderer<'a> { impl<'a> Renderer<'a> { pub fn new( - config: Config, + config: Rc, font_context: &'a Sdl2TtfContext, texture_creator: &'a TextureCreator, ) -> Self { @@ -31,7 +31,7 @@ impl<'a> Renderer<'a> { } } - pub fn config(&self) -> &Config { + pub fn config(&self) -> &Rc { &self.config } diff --git a/src/ui/caret.rs b/src/ui/caret.rs index 08eb7ae..780d8db 100644 --- a/src/ui/caret.rs +++ b/src/ui/caret.rs @@ -3,6 +3,7 @@ use crate::config::Config; use crate::renderer::Renderer; use crate::ui::*; use crate::ui::text_character::TextCharacter; +use std::rc::Rc; use sdl2::pixels::Color; use sdl2::rect::{Point, Rect}; use sdl2::render::Texture; @@ -17,6 +18,7 @@ pub struct Caret { pending: bool, text_position: usize, blink_delay: u8, + config: Rc, state: CaretState, dest: Rect, reset_position: Rect, @@ -25,7 +27,7 @@ pub struct Caret { } impl Caret { - pub fn new(config: &Config) -> Self { + pub fn new(config: Rc) -> Self { let bright_character_color = config.theme().caret().bright().color().into(); let blur_character_color = config.theme().caret().blur().color().into(); Self { @@ -47,6 +49,7 @@ impl Caret { blur_character_color, pending: true, text_position: 0, + config, } } @@ -121,7 +124,7 @@ impl Update for Caret { } impl ClickHandler for Caret { - fn on_left_click(&mut self, _point: &Point, _config: &Config) -> UpdateResult { + fn on_left_click(&mut self, _point: &Point) -> UpdateResult { // self.move_caret(Point::new(self.position.x(), self.position.y())); UpdateResult::NoOp } diff --git a/src/ui/file/editor_file.rs b/src/ui/file/editor_file.rs index bc74a40..b1e87d0 100644 --- a/src/ui/file/editor_file.rs +++ b/src/ui/file/editor_file.rs @@ -1,3 +1,4 @@ +use std::rc::Rc; use sdl2::rect::{Point, Rect}; use crate::app::{UpdateResult, WindowCanvas}; @@ -13,12 +14,13 @@ pub struct EditorFile { sections: Vec, render_position: Rect, buffer: String, + config: Rc } impl EditorFile { - pub fn new(path: String, buffer: String, config: &Config) -> Self { + pub fn new(path: String, buffer: String, config: Rc) -> Self { let sections = vec![ - EditorFileSection::new(buffer.clone(), config) + EditorFileSection::new(buffer.clone(), config.clone()) ]; let x = config.editor_left_margin(); let y = config.editor_top_margin(); @@ -26,7 +28,8 @@ impl EditorFile { path, sections, render_position: Rect::new(x, y, 0, 0), - buffer + buffer, + config } } @@ -47,10 +50,10 @@ impl EditorFile { None } - fn refresh_characters_position(&mut self, config: &Config) { + fn refresh_characters_position(&mut self) { let mut current: Rect = self.render_position.clone(); for section in self.sections.iter_mut() { - section.update_positions(&mut current, config); + section.update_positions(&mut current); } } } @@ -62,7 +65,7 @@ impl Render for EditorFile { res = section.render(canvas, renderer); } if res == UpdateResult::RefreshPositions { - self.refresh_characters_position(renderer.config()); + self.refresh_characters_position(); for section in self.sections.iter_mut() { section.render(canvas, renderer); } @@ -82,10 +85,10 @@ impl Update for EditorFile { } impl ClickHandler for EditorFile { - fn on_left_click(&mut self, point: &Point, config: &Config) -> UpdateResult { + fn on_left_click(&mut self, point: &Point) -> UpdateResult { for section in self.sections.iter_mut() { if section.is_left_click_target(point) { - return section.on_left_click(point, config); + return section.on_left_click(point); } } UpdateResult::NoOp diff --git a/src/ui/file/editor_file_section.rs b/src/ui/file/editor_file_section.rs index a00e8c7..1e9226a 100644 --- a/src/ui/file/editor_file_section.rs +++ b/src/ui/file/editor_file_section.rs @@ -1,3 +1,4 @@ +use std::rc::Rc; use sdl2::rect::{Point, Rect}; use crate::app::{UpdateResult, WindowCanvas}; @@ -12,25 +13,26 @@ use crate::ui::text_character::TextCharacter; pub struct EditorFileSection { tokens: Vec, language: Language, + config: Rc, } impl EditorFileSection { - pub fn new(buffer: String, config: &Config) -> Self { + pub fn new(buffer: String, config: Rc) -> Self { use crate::lexer; let lexer_tokens = lexer::parse(buffer.clone(), Language::PlainText); let mut tokens: Vec = vec![]; for token_type in lexer_tokens { - let token = EditorFileToken::new(token_type, config); + let token = EditorFileToken::new(token_type, config.clone()); tokens.push(token.clone()); } let language = Language::PlainText; - Self { tokens, language } + Self { tokens, language, config } } - pub fn update_positions(&mut self, current: &mut Rect, config: &Config) { + pub fn update_positions(&mut self, current: &mut Rect) { for c in self.tokens.iter_mut() { - c.update_position(current, config); + c.update_position(current); } } @@ -68,10 +70,10 @@ impl Update for EditorFileSection { } impl ClickHandler for EditorFileSection { - fn on_left_click(&mut self, point: &Point, config: &Config) -> UpdateResult { + fn on_left_click(&mut self, point: &Point) -> UpdateResult { for token in self.tokens.iter_mut() { if token.is_left_click_target(point) { - return token.on_left_click(point, config); + return token.on_left_click(point); } } UpdateResult::NoOp diff --git a/src/ui/file/editor_file_token.rs b/src/ui/file/editor_file_token.rs index 11cfbb9..74e613e 100644 --- a/src/ui/file/editor_file_token.rs +++ b/src/ui/file/editor_file_token.rs @@ -5,29 +5,31 @@ use crate::renderer::managers::{FontDetails, TextDetails}; use crate::renderer::Renderer; use crate::ui::*; use crate::ui::text_character::*; +use std::rc::Rc; use sdl2::pixels::Color; use sdl2::rect::{Point, Rect}; use sdl2::render::Texture; use sdl2::ttf::Font; -use std::rc::Rc; #[derive(Clone)] pub struct EditorFileToken { characters: Vec, token_type: TokenType, + config: Rc } impl EditorFileToken { - pub fn new(token_type: TokenType, _config: &Config) -> Self { + pub fn new(token_type: TokenType, config: Rc) -> Self { Self { characters: vec![], token_type, + config } } - pub fn update_position(&mut self, current: &mut Rect, config: &Config) { + pub fn update_position(&mut self, current: &mut Rect) { for text_character in self.characters.iter_mut() { - text_character.update_position(current, config); + text_character.update_position(current); } } @@ -58,7 +60,8 @@ impl EditorFileToken { c.clone(), self.token_type.start() + index, self.token_type.line(), - color.clone() + color.clone(), + self.config.clone() ); text_character.update_view(renderer); self.characters.push(text_character); @@ -97,10 +100,10 @@ impl Update for EditorFileToken { } impl ClickHandler for EditorFileToken { - fn on_left_click(&mut self, point: &Point, config: &Config) -> UpdateResult { + fn on_left_click(&mut self, point: &Point) -> UpdateResult { for text_character in self.characters.iter_mut() { if text_character.is_left_click_target(point) { - return text_character.on_left_click(point, config); + return text_character.on_left_click(point); } } UpdateResult::NoOp diff --git a/src/ui/menu_bar.rs b/src/ui/menu_bar.rs index 6361085..d7aa05c 100644 --- a/src/ui/menu_bar.rs +++ b/src/ui/menu_bar.rs @@ -2,19 +2,22 @@ use crate::app::{UpdateResult, WindowCanvas}; use crate::config::Config; use crate::renderer::Renderer; use crate::ui::*; +use std::rc::Rc; use sdl2::pixels::Color; -use sdl2::rect::Rect; +use sdl2::rect::{Rect, Point}; pub struct MenuBar { background_color: Color, dest: Rect, + config: Rc, } impl MenuBar { - pub fn new() -> Self { + pub fn new(config: Rc) -> Self { Self { background_color: Color::RGB(10, 10, 10), dest: Rect::new(0, 0, 0, 0), + config, } } @@ -28,9 +31,9 @@ impl MenuBar { } impl Render for MenuBar { - fn render(&mut self, canvas: &mut WindowCanvas, renderer: &mut Renderer) -> UpdateResult { - let width = renderer.config().width(); - let height = renderer.config().menu_height() as u32; + fn render(&mut self, canvas: &mut WindowCanvas, _renderer: &mut Renderer) -> UpdateResult { + let width = self.config.width(); + let height = self.config.menu_height() as u32; self.dest = Rect::new(0, 0, width, height); canvas.set_draw_color(self.background_color.clone()); canvas.draw_rect(self.dest.clone()).unwrap(); @@ -45,7 +48,7 @@ impl Update for MenuBar { } impl ClickHandler for MenuBar { - fn on_left_click(&mut self, _point: &Point, _config: &Config) -> UpdateResult { + fn on_left_click(&mut self, _point: &Point) -> UpdateResult { unimplemented!() } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 620ef81..d3a2103 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -44,7 +44,7 @@ pub trait Update { } pub trait ClickHandler { - fn on_left_click(&mut self, point: &Point, config: &Config) -> UpdateResult; + fn on_left_click(&mut self, point: &Point) -> UpdateResult; fn is_left_click_target(&self, point: &Point) -> bool; } diff --git a/src/ui/text_character.rs b/src/ui/text_character.rs index c009d60..6644792 100644 --- a/src/ui/text_character.rs +++ b/src/ui/text_character.rs @@ -6,11 +6,11 @@ use crate::renderer::managers::TextDetails; use crate::renderer::Renderer; use crate::ui::*; +use std::rc::Rc; use sdl2::pixels::Color; use sdl2::rect::{Rect, Point}; use sdl2::render::Texture; use sdl2::ttf::Font; -use std::rc::Rc; #[derive(Clone)] pub struct TextCharacter { @@ -21,10 +21,11 @@ pub struct TextCharacter { source: Rect, dest: Rect, color: Color, + config: Rc } impl TextCharacter { - pub fn new(text_character: char, position: usize, line: usize, color: Color) -> Self { + pub fn new(text_character: char, position: usize, line: usize, color: Color, config: Rc) -> Self { Self { pending: true, text_character, @@ -33,6 +34,7 @@ impl TextCharacter { source: Rect::new(0, 0, 0, 0), dest: Rect::new(0, 0, 0, 0), color, + config } } @@ -48,10 +50,10 @@ impl TextCharacter { &self.color } - pub fn update_position(&mut self, current: &mut Rect, config: &Config) { + pub fn update_position(&mut self, current: &mut Rect) { if self.is_new_line() { let y = self.source.height() as i32; - current.set_x(config.editor_left_margin()); + current.set_x(self.config.editor_left_margin()); current.set_y(current.y() + y); } else { self.dest.set_x(current.x()); @@ -145,7 +147,7 @@ impl Update for TextCharacter { } impl ClickHandler for TextCharacter { - fn on_left_click(&mut self, _point: &Point, _config: &Config) -> UpdateResult { + fn on_left_click(&mut self, _point: &Point) -> UpdateResult { UpdateResult::MoveCaret( self.dest().clone(), self.position()