Skip to content

Commit

Permalink
implemented basic scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
TheTrio committed May 1, 2022
1 parent b824d11 commit 5dc4c65
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 15 deletions.
22 changes: 15 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use tui::{
backend::{Backend, CrosstermBackend},
Frame, Terminal,
};
use ui::HORIZONTAL_MARGIN;
use webbrowser::Browser;

const TICK_RATE_MS: u64 = 100;
Expand All @@ -31,7 +32,7 @@ const TICK_RATE_MS: u64 = 100;
#[clap(version, about, long_about= None)]
pub struct Cli {
/// number of words to use in test
#[clap(short = 'w', long, default_value_t = 15)]
#[clap(short = 'w', long, default_value_t = 2000)]
number_of_words: usize,

/// number of seconds to run test
Expand Down Expand Up @@ -146,8 +147,7 @@ fn start_tui<B: Backend>(

loop {
let mut exit_type: ExitType = ExitType::Quit;
terminal.draw(|f| ui(app, f))?;

terminal.draw(|f| ui(app, f, false))?;
loop {
let app = &mut app;

Expand All @@ -159,13 +159,14 @@ fn start_tui<B: Backend>(
if app.thok.has_finished() {
app.thok.calc_results();
}
terminal.draw(|f| ui(app, f))?;
terminal.draw(|f| ui(app, f, false))?;
}
}
ThokEvent::Resize => {
terminal.draw(|f| ui(app, f))?;
terminal.draw(|f| ui(app, f, false))?;
}
ThokEvent::Key(key) => {
let mut is_space = false;
match key.code {
KeyCode::Esc => {
break;
Expand All @@ -185,6 +186,9 @@ fn start_tui<B: Backend>(
}
KeyCode::Char(c) => match app.thok.has_finished() {
false => {
if c == ' ' {
is_space = true;
}
app.thok.write(c);
if app.thok.has_finished() {
app.thok.calc_results();
Expand All @@ -210,7 +214,7 @@ fn start_tui<B: Backend>(
},
_ => {}
}
terminal.draw(|f| ui(app, f))?;
terminal.draw(|f| ui(app, f, is_space))?;
}
}
}
Expand Down Expand Up @@ -267,6 +271,10 @@ fn get_thok_events(should_tick: bool) -> mpsc::Receiver<ThokEvent> {
rx
}

fn ui<B: Backend>(app: &mut App, f: &mut Frame<B>) {
fn ui<B: Backend>(app: &mut App, f: &mut Frame<B>, is_space: bool) {
if is_space {
app.thok
.get_skip_count((f.size().width - HORIZONTAL_MARGIN * 2).into());
}
f.render_widget(&app.thok, f.size());
}
33 changes: 31 additions & 2 deletions src/thok.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::util::std_dev;
use crate::TICK_RATE_MS;
use chrono::prelude::*;
use directories::ProjectDirs;
use itertools::Itertools;
use itertools::{any, Itertools};
use std::fs::OpenOptions;
use std::io::{self, Write};
use std::{char, collections::HashMap, time::SystemTime};
Expand Down Expand Up @@ -35,10 +35,13 @@ pub struct Thok {
pub wpm: f64,
pub accuracy: f64,
pub std_dev: f64,
pub skip: usize,
pub line: usize,
}

impl Thok {
pub fn new(prompt: String, number_of_words: usize, number_of_secs: Option<f64>) -> Self {
// let prompt = prompt.replace(" ", "*");
Self {
prompt,
input: vec![],
Expand All @@ -52,6 +55,8 @@ impl Thok {
wpm: 0.0,
accuracy: 0.0,
std_dev: 0.0,
skip: 0,
line: 0,
}
}

Expand Down Expand Up @@ -151,7 +156,7 @@ impl Thok {
}

pub fn backspace(&mut self) {
if self.cursor_pos > 0 {
if self.cursor_pos > 0 && self.cursor_pos > self.skip {
self.input.remove(self.cursor_pos - 1);
self.decrement_cursor();
}
Expand Down Expand Up @@ -234,4 +239,28 @@ impl Thok {

Ok(())
}

pub fn get_skip_count(&mut self, max_width: usize) {
if any(&self.input[self.skip..], |x| {
x.outcome == Outcome::Incorrect
}) {
return;
}
let count = self.cursor_pos - self.skip;
if count == 0 {
self.skip += max_width;
self.line += 1;
return;
}
let rest = &self.prompt[self.cursor_pos..];
let index = rest.find(' ');
if let Some(index) = index {
let next_word = &rest[..index];
let next_word_len = next_word.len();
if count + next_word_len > max_width {
self.skip += count;
self.line += 1;
}
}
}
}
10 changes: 4 additions & 6 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use webbrowser::Browser;

use crate::thok::{Outcome, Thok};

const HORIZONTAL_MARGIN: u16 = 5;
pub const HORIZONTAL_MARGIN: u16 = 5;
const VERTICAL_MARGIN: u16 = 2;

impl Widget for &Thok {
Expand Down Expand Up @@ -40,11 +40,9 @@ impl Widget for &Thok {
((self.prompt.width() as f64 / max_chars_per_line as f64).ceil() + 1.0) as u16;

let time_left_lines = if self.number_of_secs.is_some() { 2 } else { 0 };

if self.prompt.width() <= max_chars_per_line as usize {
prompt_occupied_lines = 1;
}

let chunks = Layout::default()
.direction(Direction::Vertical)
.horizontal_margin(HORIZONTAL_MARGIN)
Expand All @@ -54,22 +52,22 @@ impl Widget for &Thok {
((area.height as f64 - prompt_occupied_lines as f64) / 2.0) as u16,
),
Constraint::Length(time_left_lines),
Constraint::Length(prompt_occupied_lines),
Constraint::Length(3),
Constraint::Length(
((area.height as f64 - prompt_occupied_lines as f64) / 2.0) as u16,
),
]
.as_ref(),
)
.split(area);

let mut spans = self
.input
.iter()
.skip(self.skip)
.enumerate()
.map(|(idx, input)| {
Span::styled(
self.get_expected_char(idx).to_string(),
self.get_expected_char(self.skip + idx).to_string(),
match input.outcome {
Outcome::Correct => green_bold_style,
Outcome::Incorrect => red_bold_style,
Expand Down

0 comments on commit 5dc4c65

Please sign in to comment.