finished progress flag
This commit is contained in:
parent
b318c96734
commit
b238dbeecb
3 changed files with 127 additions and 23 deletions
|
@ -9,7 +9,8 @@ use termion::{
|
||||||
use crate::{
|
use crate::{
|
||||||
color::*,
|
color::*,
|
||||||
draw,
|
draw,
|
||||||
flag::{ self, Flag }
|
flag::{ self, Flag },
|
||||||
|
util::{ ansi_len, ansi_substr }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// vertically stacking eighths
|
/// vertically stacking eighths
|
||||||
|
@ -38,18 +39,18 @@ pub fn progress(small: bool) -> Flag {
|
||||||
let black: u32 = 0;
|
let black: u32 = 0;
|
||||||
let brown: u32 = 0x784F17;
|
let brown: u32 = 0x784F17;
|
||||||
let ltblue: u32 = 0xEAACB8;
|
let ltblue: u32 = 0xEAACB8;
|
||||||
let pink: u32 = 0xEAACB8;
|
let pink: u32 = 0x7ACBF5;
|
||||||
let white: u32 = 0xFFFFFF;
|
let white: u32 = 0xFFFFFF;
|
||||||
|
|
||||||
let (width, height) = if small { (18, 6) } else { terminal_size().unwrap() };
|
let (width, height) = if small { (18, 6) } else { terminal_size().unwrap() };
|
||||||
|
|
||||||
// create color slices and line buffer
|
// create color slices and line buffer
|
||||||
let stripes = [red, orange, yellow, green, blue, purple];
|
let stripes = [red, orange, yellow, green, blue, purple];
|
||||||
let chevrons = [white, pink, ltblue, brown, black];
|
let chevrons = [white, ltblue, pink, brown, black];
|
||||||
let mut lines: Vec<String> = Vec::new();
|
let mut lines: Vec<String> = Vec::new();
|
||||||
|
|
||||||
// set up stripe index
|
// set up stripe index
|
||||||
let mut stripe_index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
/* ok, coming up with procedure:
|
/* ok, coming up with procedure:
|
||||||
* - can't rely on bg_stripes; line count, threshold, etc., will need to happen here
|
* - can't rely on bg_stripes; line count, threshold, etc., will need to happen here
|
||||||
|
@ -63,43 +64,93 @@ pub fn progress(small: bool) -> Flag {
|
||||||
|
|
||||||
// set up constraints
|
// set up constraints
|
||||||
let linecount = height - (height % 6); // largest multiple of 6 smaller than height
|
let linecount = height - (height % 6); // largest multiple of 6 smaller than height
|
||||||
let full_depth = linecount / 2;
|
let full_depth = width / 3;
|
||||||
|
let chevron_width = (full_depth / 6) - 1;
|
||||||
|
let direction_thresh = linecount / 2;
|
||||||
let corner = linecount % 2 == 1;
|
let corner = linecount % 2 == 1;
|
||||||
let chevron_width = 0; // chevron width (TODO)
|
|
||||||
let thresh = height / linecount; // stripe threshold; no bg_stripes call!
|
let thresh = linecount / 6; // stripe threshold; no bg_stripes call!
|
||||||
let mut line_no = 0; // absolute line number; n is relative
|
let mut line_no = 0; // absolute line number; n is relative
|
||||||
|
|
||||||
|
// chevron helper
|
||||||
|
let build_chevron = | separator: char | -> String {
|
||||||
|
let mut output = format!(
|
||||||
|
"{fg}{bg}{stripe}{separator}",
|
||||||
|
fg = rgb(chevrons[0]),
|
||||||
|
bg = bg(chevrons[1]),
|
||||||
|
stripe = draw::BLOCK.repeat( usize::max(chevron_width as usize * 2, 1) )
|
||||||
|
);
|
||||||
|
let stripe = draw::BLOCK.repeat(chevron_width as usize);
|
||||||
|
for i in 1..4 {
|
||||||
|
output += &format!(
|
||||||
|
"{fg}{bg}{stripe}{separator}",
|
||||||
|
fg = rgb(chevrons[i]),
|
||||||
|
bg = bg(chevrons[i + 1])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
output += &format!(
|
||||||
|
"{fg}{stripe}",
|
||||||
|
fg = rgb(chevrons[4])
|
||||||
|
);
|
||||||
|
|
||||||
|
output
|
||||||
|
};
|
||||||
|
|
||||||
// piecewise functions: ascent -> peak -> descent
|
// piecewise functions: ascent -> peak -> descent
|
||||||
for n in 0..full_depth {
|
let mut base = build_chevron(TRIANGLE_21[0]);
|
||||||
|
let base_length = base.len();
|
||||||
|
let display_length = ansi_len(&base) + 1; // chevron width will always stay the same; add 1 for the last separator
|
||||||
|
for n in 0..direction_thresh {
|
||||||
// advance stripe color at stripe threshold by line number
|
// advance stripe color at stripe threshold by line number
|
||||||
if line_no != 0 && line_no % thresh == 0 { stripe_index += 1; }
|
if line_no != 0 && line_no % thresh == 0 { index += 1; }
|
||||||
|
|
||||||
// init current line
|
// grab our substring constraints
|
||||||
let line = String::new();
|
let start = (direction_thresh - n) as usize - 1;
|
||||||
|
let diff = display_length - start;
|
||||||
|
|
||||||
// get this line's depth?
|
// take substring of chevron line...
|
||||||
// get chevron start: (full_depth - line_depth) / chevron_width = chevron_start
|
let mut line = ansi_substr(&base, start as usize, base_length);
|
||||||
let start: i16 = 2 - (n as i16);
|
// ... and add the colored stripe
|
||||||
|
line += &format!(
|
||||||
// for chevron_index in chevron_start..5
|
"{stripe}{separator}{line}",
|
||||||
// if chevron_index = 4, draw stripe after (stripe width = width - line_depth - 1)
|
stripe = stripes[index],
|
||||||
// else, draw <fg:chevron_index,bg:chevron_index+1>BLOCK.repeat(chevron_width) + TRIANGLE_21[0]
|
separator = TRIANGLE_21[0],
|
||||||
|
line = " ".repeat(width as usize - diff)
|
||||||
|
);
|
||||||
|
|
||||||
lines.push(line);
|
lines.push(line);
|
||||||
line_no += 1;
|
line_no += 1;
|
||||||
}
|
}
|
||||||
if corner {
|
if corner {
|
||||||
if line_no % thresh == 0 { stripe_index += 1; }
|
if line_no % thresh == 0 { index += 1; }
|
||||||
|
|
||||||
let line = String::new();
|
let base = build_chevron(TRIANGLE_21[1]);
|
||||||
|
let mut line = ansi_substr(&base, 0, base_length);
|
||||||
|
line += &format!(
|
||||||
|
"{stripe}{separator}{line}",
|
||||||
|
stripe = stripes[index],
|
||||||
|
separator = TRIANGLE_21[1],
|
||||||
|
line = " ".repeat(width as usize - display_length)
|
||||||
|
);
|
||||||
|
|
||||||
lines.push(line);
|
lines.push(line);
|
||||||
line_no += 1;
|
line_no += 1;
|
||||||
}
|
}
|
||||||
for n in 0..full_depth {
|
base = build_chevron(TRIANGLE_21[2]);
|
||||||
if line_no % thresh == 0 { stripe_index += 1; }
|
for n in 0..direction_thresh {
|
||||||
|
if line_no % thresh == 0 { index += 1; }
|
||||||
|
if index > 5 { break; }
|
||||||
|
|
||||||
let line = String::new();
|
let start = n as usize;
|
||||||
|
let diff = display_length - start;
|
||||||
|
|
||||||
|
let mut line = ansi_substr(&base, start, base_length);
|
||||||
|
line += &format!(
|
||||||
|
"{stripe}{separator}{line}",
|
||||||
|
stripe = stripes[index],
|
||||||
|
separator = TRIANGLE_21[2],
|
||||||
|
line = " ".repeat(width as usize - diff)
|
||||||
|
);
|
||||||
|
|
||||||
lines.push(line);
|
lines.push(line);
|
||||||
line_no += 1;
|
line_no += 1;
|
||||||
|
|
|
@ -6,6 +6,7 @@ mod color;
|
||||||
mod complex;
|
mod complex;
|
||||||
mod draw;
|
mod draw;
|
||||||
mod flag;
|
mod flag;
|
||||||
|
mod util;
|
||||||
mod variant;
|
mod variant;
|
||||||
|
|
||||||
use crate::flag::Flag;
|
use crate::flag::Flag;
|
||||||
|
|
52
src/util.rs
Normal file
52
src/util.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
/// gets the substring of displayed characters of an ANSI formatted string
|
||||||
|
pub fn ansi_substr(source: &str, start: usize, end: usize) -> String {
|
||||||
|
// init output string
|
||||||
|
let mut output = String::new();
|
||||||
|
|
||||||
|
// trackers
|
||||||
|
let mut escaped = false;
|
||||||
|
let mut index = 0;
|
||||||
|
for character in source.chars() {
|
||||||
|
// escape character delimits start and end of ansi sequences
|
||||||
|
if character == '\u{1B}' {
|
||||||
|
escaped = true;
|
||||||
|
output.push(character);
|
||||||
|
}
|
||||||
|
// push ALL escaped characters
|
||||||
|
if escaped {
|
||||||
|
output.push(character);
|
||||||
|
// and unset esc on m
|
||||||
|
if character == 'm' { escaped = false; }
|
||||||
|
}
|
||||||
|
// non-escaped characters must obey bounds
|
||||||
|
else {
|
||||||
|
if index < start {
|
||||||
|
index += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push(character);
|
||||||
|
index += 1;
|
||||||
|
|
||||||
|
if index > end { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
|
/// gets the number of displayed characters in an ANSI formatted string
|
||||||
|
pub fn ansi_len(source: &str) -> usize {
|
||||||
|
let mut output = 0;
|
||||||
|
let mut escaped = false;
|
||||||
|
|
||||||
|
for character in source.chars() {
|
||||||
|
if character == '\u{1B}' { escaped = true; }
|
||||||
|
|
||||||
|
if !escaped { output += 1; }
|
||||||
|
else if character == 'm' { escaped = false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue