Move caret right
This commit is contained in:
parent
9460b6931a
commit
3a5587dbcc
@ -5,6 +5,8 @@ use crate::ui::caret::Caret;
|
|||||||
use crate::ui::file::editor_file::EditorFile;
|
use crate::ui::file::editor_file::EditorFile;
|
||||||
use crate::ui::file::*;
|
use crate::ui::file::*;
|
||||||
use crate::ui::menu_bar::MenuBar;
|
use crate::ui::menu_bar::MenuBar;
|
||||||
|
use crate::ui::caret::{CaretPosition, MoveDirection};
|
||||||
|
use crate::ui::text_character::TextCharacter;
|
||||||
use crate::ui::*;
|
use crate::ui::*;
|
||||||
use sdl2::rect::{Point, Rect};
|
use sdl2::rect::{Point, Rect};
|
||||||
use sdl2::VideoSubsystem;
|
use sdl2::VideoSubsystem;
|
||||||
@ -52,15 +54,29 @@ impl AppState {
|
|||||||
};
|
};
|
||||||
let mut buffer: String = file.buffer();
|
let mut buffer: String = file.buffer();
|
||||||
let caret: &mut Caret = &mut self.caret;
|
let caret: &mut Caret = &mut self.caret;
|
||||||
let position: usize = caret.text_position();
|
let position: CaretPosition = caret.position().clone();
|
||||||
if position == 0 {
|
if position.text_position() == 0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buffer.remove(position - 1);
|
let c: char = buffer.chars().collect::<Vec<char>>()[position.text_position() - 1];
|
||||||
match file.get_character_at(position - 1) {
|
buffer.remove(position.text_position() - 1);
|
||||||
|
let position = match c {
|
||||||
|
'\n' => CaretPosition::new(
|
||||||
|
position.text_position() - 1,
|
||||||
|
position.line_number() - 1,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
_ => CaretPosition::new(
|
||||||
|
position.text_position() - 1,
|
||||||
|
position.line_number(),
|
||||||
|
position.line_position(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
match file.get_character_at(position.text_position()) {
|
||||||
Some(character) => {
|
Some(character) => {
|
||||||
let dest: &Rect = character.dest();
|
let dest: &Rect = character.dest();
|
||||||
caret.move_caret(position - 1, Point::new(dest.x(), dest.y()));
|
caret.move_caret(position, Point::new(dest.x(), dest.y()));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
caret.reset_caret();
|
caret.reset_caret();
|
||||||
@ -101,12 +117,16 @@ impl AppState {
|
|||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
let mut pos = Point::new(current.dest().x(), current.dest().y());
|
let mut pos = Point::new(current.dest().x(), current.dest().y());
|
||||||
let mut position: usize = caret.text_position();
|
let mut position: CaretPosition = caret.position().clone();
|
||||||
for character in text.chars() {
|
for character in text.chars() {
|
||||||
buffer.insert(position, character);
|
buffer.insert(position.text_position(), character);
|
||||||
if let Some(rect) = get_text_character_rect(character, renderer) {
|
if let Some(rect) = get_text_character_rect(character, renderer) {
|
||||||
pos = pos + Point::new(rect.width() as i32, 0);
|
pos = pos + Point::new(rect.width() as i32, 0);
|
||||||
position += 1;
|
position = CaretPosition::new(
|
||||||
|
position.text_position() + 1,
|
||||||
|
position.line_number(),
|
||||||
|
position.line_position(),
|
||||||
|
);
|
||||||
caret.move_caret(position, pos.clone());
|
caret.move_caret(position, pos.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,9 +135,42 @@ impl AppState {
|
|||||||
self.files[self.current_file] = new_file;
|
self.files[self.current_file] = new_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn current_file(&self) -> Option<&EditorFile> {
|
pub fn insert_new_line(&mut self, renderer: &mut Renderer) {
|
||||||
// self.files.get(self.current_file)
|
let file: &mut EditorFile = if let Some(file) = self.files.get_mut(self.current_file) {
|
||||||
// }
|
file
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let mut buffer: String = file.buffer();
|
||||||
|
let caret: &mut Caret = &mut self.caret;
|
||||||
|
|
||||||
|
let current = match file.get_character_at(caret.text_position()) {
|
||||||
|
Some(c) => c,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
let mut pos = Point::new(current.dest().x(), current.dest().y());
|
||||||
|
let mut position: CaretPosition = caret.position().clone();
|
||||||
|
buffer.insert(position.text_position(), '\n');
|
||||||
|
if let Some(rect) = get_text_character_rect('\n', renderer) {
|
||||||
|
pos = Point::new(
|
||||||
|
self.config.editor_left_margin(),
|
||||||
|
pos.y() + rect.height() as i32,
|
||||||
|
);
|
||||||
|
position = CaretPosition::new(
|
||||||
|
position.text_position(),
|
||||||
|
position.line_number() + 1,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
caret.move_caret(position, pos.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_file = EditorFile::new(file.path(), buffer, self.config.clone());
|
||||||
|
self.files[self.current_file] = new_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_file(&self) -> Option<&EditorFile> {
|
||||||
|
self.files.get(self.current_file)
|
||||||
|
}
|
||||||
|
|
||||||
fn current_file_mut(&mut self) -> Option<&mut EditorFile> {
|
fn current_file_mut(&mut self) -> Option<&mut EditorFile> {
|
||||||
self.files.get_mut(self.current_file)
|
self.files.get_mut(self.current_file)
|
||||||
@ -147,6 +200,54 @@ impl AppState {
|
|||||||
|
|
||||||
UpdateResult::NoOp
|
UpdateResult::NoOp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_caret(&mut self, dir: MoveDirection) {
|
||||||
|
match dir {
|
||||||
|
MoveDirection::Left => {}
|
||||||
|
MoveDirection::Right =>
|
||||||
|
self.move_caret_right(),
|
||||||
|
MoveDirection::Up => {}
|
||||||
|
MoveDirection::Down => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_caret_right(&mut self) {
|
||||||
|
let file: &EditorFile = match self.current_file() {
|
||||||
|
None => return,
|
||||||
|
Some(f) => f,
|
||||||
|
};
|
||||||
|
let line = self.caret.line_number().clone();
|
||||||
|
let characters: Vec<&TextCharacter> = match file.get_line(&line) {
|
||||||
|
None =>
|
||||||
|
return,
|
||||||
|
Some(characters) => characters,
|
||||||
|
};
|
||||||
|
let mut idx = 0;
|
||||||
|
for (i, c) in characters.iter().enumerate() {
|
||||||
|
if c.position() == self.caret.text_position() {
|
||||||
|
idx = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let text_character: &TextCharacter = match characters.get(idx) {
|
||||||
|
Some(text_character) => text_character,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
let line = text_character.line() - self.caret.line_number();
|
||||||
|
let pos = self.caret
|
||||||
|
.position()
|
||||||
|
.moved(1, line, 0);
|
||||||
|
let mut d: Rect = text_character.dest().clone();
|
||||||
|
if text_character.is_new_line() {
|
||||||
|
let prev = match characters.get(idx - 1) {
|
||||||
|
Some(c) => c,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
d = prev.dest().clone();
|
||||||
|
d.set_x(d.x() + d.width() as i32);
|
||||||
|
}
|
||||||
|
self.caret.move_caret(pos, Point::new(d.x(), d.y()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for AppState {
|
impl Render for AppState {
|
||||||
|
@ -3,6 +3,7 @@ use crate::config::Config;
|
|||||||
use crate::renderer::Renderer;
|
use crate::renderer::Renderer;
|
||||||
use crate::themes::*;
|
use crate::themes::*;
|
||||||
use crate::ui::*;
|
use crate::ui::*;
|
||||||
|
use crate::ui::caret::{CaretPosition,MoveDirection};
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
@ -30,10 +31,15 @@ pub enum UpdateResult {
|
|||||||
Stop,
|
Stop,
|
||||||
RefreshPositions,
|
RefreshPositions,
|
||||||
MouseLeftClicked(Point),
|
MouseLeftClicked(Point),
|
||||||
MoveCaret(Rect, usize),
|
MoveCaret(Rect, CaretPosition),
|
||||||
DeleteFront,
|
DeleteFront,
|
||||||
DeleteBack,
|
DeleteBack,
|
||||||
Input(String),
|
Input(String),
|
||||||
|
InsertNewLine,
|
||||||
|
MoveCaretLeft,
|
||||||
|
MoveCaretRight,
|
||||||
|
MoveCaretUp,
|
||||||
|
MoveCaretDown,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Task {
|
pub enum Task {
|
||||||
@ -109,9 +115,23 @@ impl Application {
|
|||||||
app_state.delete_back();
|
app_state.delete_back();
|
||||||
}
|
}
|
||||||
UpdateResult::Input(text) => {
|
UpdateResult::Input(text) => {
|
||||||
println!("text input: {}", text);
|
|
||||||
app_state.insert_text(text, &mut renderer);
|
app_state.insert_text(text, &mut renderer);
|
||||||
}
|
}
|
||||||
|
UpdateResult::InsertNewLine => {
|
||||||
|
app_state.insert_new_line(&mut renderer);
|
||||||
|
}
|
||||||
|
UpdateResult::MoveCaretLeft => {
|
||||||
|
app_state.move_caret(MoveDirection::Left);
|
||||||
|
}
|
||||||
|
UpdateResult::MoveCaretRight => {
|
||||||
|
app_state.move_caret(MoveDirection::Right);
|
||||||
|
}
|
||||||
|
UpdateResult::MoveCaretUp => {
|
||||||
|
app_state.move_caret(MoveDirection::Up);
|
||||||
|
}
|
||||||
|
UpdateResult::MoveCaretDown => {
|
||||||
|
app_state.move_caret(MoveDirection::Down);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for task in self.tasks.iter() {
|
for task in self.tasks.iter() {
|
||||||
match task {
|
match task {
|
||||||
@ -165,6 +185,11 @@ impl Application {
|
|||||||
match keycode {
|
match keycode {
|
||||||
Keycode::Backspace => return UpdateResult::DeleteFront,
|
Keycode::Backspace => return UpdateResult::DeleteFront,
|
||||||
Keycode::Delete => return UpdateResult::DeleteBack,
|
Keycode::Delete => return UpdateResult::DeleteBack,
|
||||||
|
Keycode::KpEnter | Keycode::Return => return UpdateResult::InsertNewLine,
|
||||||
|
Keycode::Left => return UpdateResult::MoveCaretLeft,
|
||||||
|
Keycode::Right => return UpdateResult::MoveCaretRight,
|
||||||
|
Keycode::Up => return UpdateResult::MoveCaretUp,
|
||||||
|
Keycode::Down => return UpdateResult::MoveCaretDown,
|
||||||
_ => UpdateResult::NoOp,
|
_ => UpdateResult::NoOp,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
194
src/ui/caret.rs
194
src/ui/caret.rs
@ -7,6 +7,7 @@ use sdl2::pixels::Color;
|
|||||||
use sdl2::rect::{Point, Rect};
|
use sdl2::rect::{Point, Rect};
|
||||||
use sdl2::render::Texture;
|
use sdl2::render::Texture;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum CaretState {
|
enum CaretState {
|
||||||
@ -15,25 +16,138 @@ enum CaretState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Caret {
|
pub enum MoveDirection {
|
||||||
pending: bool,
|
Left,
|
||||||
|
Right,
|
||||||
|
Up,
|
||||||
|
Down
|
||||||
|
}
|
||||||
|
|
||||||
|
//#[derive(Clone, Debug, PartialEq)]
|
||||||
|
//pub enum CaretLocation {
|
||||||
|
// FirstLineFirstCharacter,
|
||||||
|
// FirstLine(usize), // with character location
|
||||||
|
// LastLineFirstCharacter,
|
||||||
|
// LastLine(usize), // with character location
|
||||||
|
// FirstCharacter(usize),// with line number
|
||||||
|
// LastCharacter(usize), // with line number
|
||||||
|
// Other(usize, usize), // with line number and character number
|
||||||
|
//}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub struct CaretPosition {
|
||||||
text_position: usize,
|
text_position: usize,
|
||||||
blink_delay: u8,
|
line_number: usize,
|
||||||
// config: Rc<Config>,
|
line_position: usize,
|
||||||
state: CaretState,
|
}
|
||||||
|
|
||||||
|
impl CaretPosition {
|
||||||
|
pub fn new(text_position: usize, line_number: usize, line_position: usize,) -> Self {
|
||||||
|
Self {
|
||||||
|
text_position,
|
||||||
|
line_number,
|
||||||
|
line_position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text_position(&self) -> usize {
|
||||||
|
self.text_position.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn line_number(&self) -> usize {
|
||||||
|
self.line_number.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn line_position(&self) -> usize {
|
||||||
|
self.line_position.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.text_position = 0;
|
||||||
|
self.line_number = 0;
|
||||||
|
self.line_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_text_position(&mut self, n: usize) {
|
||||||
|
self.text_position = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_line_number(&mut self, n: usize) {
|
||||||
|
self.line_number = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_line_position(&mut self, n: usize) {
|
||||||
|
self.line_position = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn moved(&self, text_position: usize, line_number: usize, line_position: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
text_position: self.text_position + text_position,
|
||||||
|
line_number: self.line_number + line_number,
|
||||||
|
line_position: self.line_position + line_position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct CaretRenderPosition {
|
||||||
dest: Rect,
|
dest: Rect,
|
||||||
reset_position: Rect,
|
reset_position: Rect,
|
||||||
bright_character_color: Color,
|
}
|
||||||
blur_character_color: Color,
|
|
||||||
|
impl CaretRenderPosition {
|
||||||
|
pub fn dest(&self) -> &Rect {
|
||||||
|
&self.dest
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset_position(&self) -> &Rect {
|
||||||
|
&self.reset_position
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.dest = self.reset_position.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_to(&mut self, p: &Point) {
|
||||||
|
self.dest.set_x(p.x());
|
||||||
|
self.dest.set_y(p.y());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct CaretColor {
|
||||||
|
bright: Color,
|
||||||
|
blur: Color,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CaretColor {
|
||||||
|
pub fn bright(&self) -> &Color {
|
||||||
|
&self.bright
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blur(&self) -> &Color {
|
||||||
|
&self.blur
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct Caret {
|
||||||
|
pending: bool,
|
||||||
|
blink_delay: u8,
|
||||||
|
state: CaretState,
|
||||||
|
position: CaretPosition,
|
||||||
|
render_position: CaretRenderPosition,
|
||||||
|
colors: CaretColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Caret {
|
impl Caret {
|
||||||
pub fn new(config: Rc<Config>) -> Self {
|
pub fn new(config: Rc<Config>) -> Self {
|
||||||
let bright_character_color = config.theme().caret().bright().color().into();
|
let bright = config.theme().caret().bright().color().into();
|
||||||
let blur_character_color = config.theme().caret().blur().color().into();
|
let blur = config.theme().caret().blur().color().into();
|
||||||
Self {
|
Self {
|
||||||
state: CaretState::Bright,
|
state: CaretState::Bright,
|
||||||
blink_delay: 0,
|
blink_delay: 0,
|
||||||
|
render_position: CaretRenderPosition {
|
||||||
dest: Rect::new(
|
dest: Rect::new(
|
||||||
config.editor_left_margin(),
|
config.editor_left_margin(),
|
||||||
config.editor_top_margin(),
|
config.editor_top_margin(),
|
||||||
@ -46,10 +160,14 @@ impl Caret {
|
|||||||
4,
|
4,
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
bright_character_color,
|
},
|
||||||
blur_character_color,
|
colors: CaretColor { bright, blur },
|
||||||
pending: true,
|
pending: true,
|
||||||
|
position: CaretPosition {
|
||||||
text_position: 0,
|
text_position: 0,
|
||||||
|
line_number: 0,
|
||||||
|
line_position: 0,
|
||||||
|
},
|
||||||
// config,
|
// config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,44 +181,48 @@ impl Caret {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_caret(&mut self) {
|
pub fn reset_caret(&mut self) {
|
||||||
self.dest = self.reset_position.clone();
|
self.render_position.reset();
|
||||||
self.text_position = 0;
|
self.position.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_caret(&mut self, position: usize, pos: Point) {
|
pub fn move_caret(&mut self, position: CaretPosition, pos: Point) {
|
||||||
self.text_position = position;
|
self.position = position;
|
||||||
self.dest.set_x(pos.x());
|
self.render_position.move_to(&pos);
|
||||||
self.dest.set_y(pos.y());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_position(&self) -> usize {
|
pub fn position(&self) -> &CaretPosition {
|
||||||
self.text_position
|
&self.position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Caret {
|
||||||
|
type Target = CaretPosition;
|
||||||
|
|
||||||
|
fn deref(&self) -> &<Self as Deref>::Target {
|
||||||
|
self.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for Caret {
|
impl Render for Caret {
|
||||||
fn render(&mut self, canvas: &mut WindowCanvas, renderer: &mut Renderer) -> UpdateResult {
|
fn render(&mut self, canvas: &mut WindowCanvas, renderer: &mut Renderer) -> UpdateResult {
|
||||||
if self.pending {
|
if self.pending {
|
||||||
use crate::renderer::managers::FontDetails;
|
if let Some(rect) = get_text_character_rect('W', renderer) {
|
||||||
let config = renderer.config().clone();
|
let mut dest = self.render_position.dest().clone();
|
||||||
let font = renderer
|
dest.set_height(rect.height());
|
||||||
.font_manager()
|
let reset_position = dest.clone();
|
||||||
.load(&FontDetails {
|
self.render_position = CaretRenderPosition {
|
||||||
path: config.editor_config().font_path().clone(),
|
dest,
|
||||||
size: config.editor_config().character_size(),
|
reset_position,
|
||||||
})
|
};
|
||||||
.unwrap_or_else(|_| panic!("Unable to load font"));
|
|
||||||
if let Ok((_, h)) = font.size_of_char('W') {
|
|
||||||
self.dest.set_height(h);
|
|
||||||
self.reset_position = self.dest.clone();
|
|
||||||
}
|
}
|
||||||
self.pending = false;
|
self.pending = false;
|
||||||
}
|
}
|
||||||
let start = Point::new(self.dest.x(), self.dest.y());
|
let dest = self.render_position.dest();
|
||||||
let end = Point::new(self.dest.x(), self.dest.y() + self.dest.height() as i32);
|
let start = Point::new(dest.x(), dest.y());
|
||||||
|
let end = Point::new(dest.x(), dest.y() + dest.height() as i32);
|
||||||
let color = match self.state {
|
let color = match self.state {
|
||||||
CaretState::Bright => &self.bright_character_color,
|
CaretState::Bright => self.colors.bright(),
|
||||||
CaretState::Blur => &self.blur_character_color,
|
CaretState::Blur => self.colors.blur(),
|
||||||
};
|
};
|
||||||
canvas.set_draw_color(color.clone());
|
canvas.set_draw_color(color.clone());
|
||||||
canvas
|
canvas
|
||||||
@ -128,6 +250,6 @@ impl ClickHandler for Caret {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_left_click_target(&self, point: &Point) -> bool {
|
fn is_left_click_target(&self, point: &Point) -> bool {
|
||||||
is_in_rect(point, &self.dest)
|
is_in_rect(point, &self.render_position.dest())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,23 @@ impl EditorFile {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_line(&self, line: &usize) -> Option<Vec<&TextCharacter>> {
|
||||||
|
let mut vec: Vec<&TextCharacter> = vec![];
|
||||||
|
|
||||||
|
for section in self.sections.iter() {
|
||||||
|
match section.get_line(line) {
|
||||||
|
Some(v) => vec.append(&mut v.clone()),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if vec.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(vec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn refresh_characters_position(&mut self) {
|
fn refresh_characters_position(&mut self) {
|
||||||
let mut current: Rect = self.render_position.clone();
|
let mut current: Rect = self.render_position.clone();
|
||||||
for section in self.sections.iter_mut() {
|
for section in self.sections.iter_mut() {
|
||||||
|
@ -48,6 +48,21 @@ impl EditorFileSection {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_line(&self, line: &usize) -> Option<Vec<&TextCharacter>> {
|
||||||
|
let mut vec: Vec<&TextCharacter> = vec![];
|
||||||
|
for token in self.tokens.iter() {
|
||||||
|
match token.get_line(line) {
|
||||||
|
Some(v) => vec.append(&mut v.clone()),
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if vec.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(vec)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for EditorFileSection {
|
impl Render for EditorFileSection {
|
||||||
|
@ -42,6 +42,33 @@ impl EditorFileToken {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_line(&self, line: &usize) -> Option<Vec<&TextCharacter>> {
|
||||||
|
let mut vec: Vec<&TextCharacter> = vec![];
|
||||||
|
for c in self.characters.iter() {
|
||||||
|
let _tmp = (line.clone(), c.line().clone(), self.token_type.is_new_line(), c.text_character());
|
||||||
|
match (line.clone(), c.line().clone(), self.token_type.is_new_line()) {
|
||||||
|
(0, 0, true) => {
|
||||||
|
vec.push(c);
|
||||||
|
},
|
||||||
|
(a, b, true) if (a + 1) == b => {
|
||||||
|
vec.push(c);
|
||||||
|
},
|
||||||
|
(a, b, true) if a != (b + 1) =>
|
||||||
|
(),
|
||||||
|
(a, b, false) if a == b => {
|
||||||
|
vec.push(c);
|
||||||
|
}
|
||||||
|
_t =>
|
||||||
|
(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vec.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(vec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_view(&mut self, renderer: &mut Renderer) -> UpdateResult {
|
fn update_view(&mut self, renderer: &mut Renderer) -> UpdateResult {
|
||||||
let config = renderer.config().theme().code_highlighting();
|
let config = renderer.config().theme().code_highlighting();
|
||||||
let color: Color = match self.token_type {
|
let color: Color = match self.token_type {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::app::{UpdateResult, WindowCanvas};
|
use crate::app::{UpdateResult, WindowCanvas};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::lexer::TokenType;
|
use crate::lexer::TokenType;
|
||||||
use crate::renderer::managers::FontDetails;
|
use crate::renderer::managers::{TextDetails, FontDetails};
|
||||||
use crate::renderer::managers::TextDetails;
|
|
||||||
use crate::renderer::Renderer;
|
use crate::renderer::Renderer;
|
||||||
use crate::ui::*;
|
use crate::ui::*;
|
||||||
|
use crate::ui::caret::CaretPosition;
|
||||||
|
|
||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
use sdl2::rect::{Point, Rect};
|
use sdl2::rect::{Point, Rect};
|
||||||
@ -79,7 +79,11 @@ impl TextCharacter {
|
|||||||
.load(&font_details)
|
.load(&font_details)
|
||||||
.unwrap_or_else(|_| panic!("Font not found {:?}", font_details));
|
.unwrap_or_else(|_| panic!("Font not found {:?}", font_details));
|
||||||
|
|
||||||
if let Some(rect) = get_text_character_rect(self.text_character.clone(), renderer) {
|
let c = match self.text_character {
|
||||||
|
'\n' => 'W',
|
||||||
|
c => c,
|
||||||
|
};
|
||||||
|
if let Some(rect) = get_text_character_rect(c, renderer) {
|
||||||
self.source = rect.clone();
|
self.source = rect.clone();
|
||||||
self.dest = rect.clone();
|
self.dest = rect.clone();
|
||||||
}
|
}
|
||||||
@ -98,7 +102,7 @@ impl TextCharacter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_new_line(&self) -> bool {
|
pub fn is_new_line(&self) -> bool {
|
||||||
self.text_character == '\n'
|
self.text_character == '\n'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +114,14 @@ impl TextCharacter {
|
|||||||
pub fn position(&self) -> usize {
|
pub fn position(&self) -> usize {
|
||||||
self.position
|
self.position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn line(&self) -> usize {
|
||||||
|
self.line
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text_character(&self) -> char {
|
||||||
|
self.text_character.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for TextCharacter {
|
impl Render for TextCharacter {
|
||||||
@ -154,7 +166,14 @@ impl Update for TextCharacter {
|
|||||||
|
|
||||||
impl ClickHandler for TextCharacter {
|
impl ClickHandler for TextCharacter {
|
||||||
fn on_left_click(&mut self, _point: &Point) -> UpdateResult {
|
fn on_left_click(&mut self, _point: &Point) -> UpdateResult {
|
||||||
UpdateResult::MoveCaret(self.dest().clone(), self.position())
|
UpdateResult::MoveCaret(
|
||||||
|
self.dest().clone(),
|
||||||
|
CaretPosition::new(
|
||||||
|
self.position(),
|
||||||
|
self.line(),
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_left_click_target(&self, point: &Point) -> bool {
|
fn is_left_click_target(&self, point: &Point) -> bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user