Shared config with Rc

This commit is contained in:
Adrian Wozniak 2019-01-04 11:46:28 +01:00
parent b092ef65e9
commit c25fe0a4f5
No known key found for this signature in database
GPG Key ID: 3B441F7808FC43C7
10 changed files with 115 additions and 76 deletions

View File

@ -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<EditorFile>,
current_file: usize,
caret: Caret,
config: Rc<Config>,
}
impl AppState {
pub fn new(config: &Config) -> Self {
pub fn new(config: Rc<Config>) -> 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
}

View File

@ -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<Config>,
clear_color: Color,
sdl_context: Sdl,
canvas: WindowCanvas,
video_subsystem: VideoSubsystem,
tasks: Vec<Task>,
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());
}
}
}

View File

@ -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<Config>,
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<Config>,
font_context: &'a Sdl2TtfContext,
texture_creator: &'a TextureCreator<WindowContext>,
) -> Self {
@ -31,7 +31,7 @@ impl<'a> Renderer<'a> {
}
}
pub fn config(&self) -> &Config {
pub fn config(&self) -> &Rc<Config> {
&self.config
}

View File

@ -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<Config>,
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<Config>) -> 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
}

View File

@ -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<EditorFileSection>,
render_position: Rect,
buffer: String,
config: Rc<Config>
}
impl EditorFile {
pub fn new(path: String, buffer: String, config: &Config) -> Self {
pub fn new(path: String, buffer: String, config: Rc<Config>) -> 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

View File

@ -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<EditorFileToken>,
language: Language,
config: Rc<Config>,
}
impl EditorFileSection {
pub fn new(buffer: String, config: &Config) -> Self {
pub fn new(buffer: String, config: Rc<Config>) -> Self {
use crate::lexer;
let lexer_tokens = lexer::parse(buffer.clone(), Language::PlainText);
let mut tokens: Vec<EditorFileToken> = 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

View File

@ -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<TextCharacter>,
token_type: TokenType,
config: Rc<Config>
}
impl EditorFileToken {
pub fn new(token_type: TokenType, _config: &Config) -> Self {
pub fn new(token_type: TokenType, config: Rc<Config>) -> 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

View File

@ -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<Config>,
}
impl MenuBar {
pub fn new() -> Self {
pub fn new(config: Rc<Config>) -> 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!()
}

View File

@ -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;
}

View File

@ -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<Config>
}
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<Config>) -> 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()