diff --git a/src/complex.rs b/src/complex.rs index e21e1b4..901f003 100644 --- a/src/complex.rs +++ b/src/complex.rs @@ -1,4 +1,4 @@ -use std::process::exit; +//! flags that require more complex rendering than just scaling colored stripes use termion::{ terminal_size, @@ -7,7 +7,7 @@ use termion::{ }; use crate::color::*; -use crate::draw; +use crate::draw::{ self, Flag }; use crate::flag; /// vertically stacking eighths @@ -24,7 +24,7 @@ pub static TRIANGLE_21: [char; 3] = ['', '🭬', '']; /// 2/3 slope slant pub static SLANT_23: [char; 2] = ['🭒', '🭏']; -pub fn progress(small: bool) -> Colors { +pub fn progress(small: bool) -> Flag { let red = bg(0xE50000); let orange = bg(0xFF8D00); let yellow = bg(0xFFEE00); @@ -41,23 +41,68 @@ pub fn progress(small: bool) -> Colors { let (height, width) = if small { (6, 18) } else { terminal_size().unwrap() }; + // create color slices and line buffer let stripes = [red, orange, yellow, green, blue, purple]; let chevrons = [white, pink, ltblue, brown, black]; let mut lines: Vec = Vec::new(); - //let mut lines = draw::bg_stripes(stripes, width, height); - /* i think i'm stuck having to write stripes here too. it'll - * be easier to just generate the stripes on alongside the - * chevrons than to figure out where to move the ansi bg code + // set up stripe index + let mut stripe_index = 0; + + /* ok, coming up with procedure: + * - can't rely on bg_stripes; line count, threshold, etc., will need to happen here + * - line count will always be the largest multiple of 6 smaller than height; c = h - (h % 6) + * - chevrons may have larger widths: TODO calc + * - depth will be funky; line depth will need to use "full" depth; (Df - Dl) / Wc = Ic (TODO verify?) + * - switch stripe index on *absolute* line number rather than n + * - chevron building will be BLOCK.repeat(width) + TRIANGLE_21[0] (fg Ic, bg Ic + 1) + * - chevrons[len - 1] will need unique handling to draw stripes */ - let stripe_index = 0; - let chevron_index = 5; // chevrons are funky :) + // set up constraints + let linecount = height - (height % 6); // largest multiple of 6 smaller than height + let full_depth = linecount / 2; + let corner = linecount % 2 == 1; + let chevron_width = 0; // chevron width (TODO) + let thresh = height / linecount; // stripe threshold; no bg_stripes call! + let mut line_no = 0; // absolute line number; n is relative - + // piecewise functions: ascent -> peak -> descent + for n in 0..full_depth { + // advance stripe color at stripe threshold by line number + if line_no != 0 && line_no % thresh == 0 { stripe_index += 1; } - draw::lines(lines, !small); - exit(0); + // init current line + let line = String::new(); + + // get this line's depth? + // get chevron start: (full_depth - line_depth) / chevron_width = chevron_start + + // for chevron_index in chevron_start..5 + // if chevron_index = 4, draw stripe after (stripe width = width - line_depth - 1) + // else, draw BLOCK.repeat(chevron_width) + TRIANGLE_21[0] + + lines.push(line); + line_no += 1; + } + if corner { + if line_no % thresh == 0 { stripe_index += 1; } + + let line = String::new(); + + lines.push(line); + line_no += 1; + } + for n in 0..full_depth { + if line_no % thresh == 0 { stripe_index += 1; } + + let line = String::new(); + + lines.push(line); + line_no += 1; + } + + Flag::Lines(lines) } // everything below this point is in alphabetical order @@ -80,6 +125,7 @@ fn demi_orientation_render(middle: Bg, bottom: Bg, width: u16, height: let linecount = lines.len(); let depth = linecount / 2; let corner = linecount % 2 == 1; + // piecewise functions: ascending -> peak -> descending for n in 0..depth { let line = lines[n].clone(); @@ -104,26 +150,24 @@ fn demi_orientation_render(middle: Bg, bottom: Bg, width: u16, height: lines } -pub fn demiromantic(small: bool) -> Colors { +pub fn demiromantic(small: bool) -> Flag { let green = bg(0x3DA542); let gray = bg(0xD2D2D2); let (width, height) = if small { (15, 5) } else { terminal_size().unwrap() }; let lines = demi_orientation_render(green, gray, width, height); - draw::lines(lines, !small); - exit(0); + Flag::Lines(lines) } -pub fn demisexual(small: bool) -> Colors { +pub fn demisexual(small: bool) -> Flag { let purple = bg(0x832FA8); let grey = bg(0x7B868C); let (width, height) = if small { (15, 5) } else { terminal_size().unwrap() }; let lines = demi_orientation_render(purple, grey, width, height); - draw::lines(lines, !small); - exit(0); + Flag::Lines(lines) } pub fn disability() { @@ -138,9 +182,10 @@ pub fn disability() { let stripes = [red, yellow, white, blue, green]; // 2/3 slant stripes with gray background + } -pub fn intersex() -> Colors { +pub fn intersex() -> Flag { let yellow = bg(0xFFDA00); let purple = rgb(0x7A00AC); @@ -154,8 +199,7 @@ pub fn intersex() -> Colors { format!("{stripe}") ]; - draw::lines(lines, false); - exit(0); + Flag::Lines(lines) } pub fn polyamorous() { diff --git a/src/draw.rs b/src/draw.rs index 40f071f..6e6de37 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -62,7 +62,7 @@ pub fn small(colors: Colors) { stdout.flush().ok(); } -pub fn lines(lines: Vec, hold: bool) { +pub fn draw_lines(lines: Vec, hold: bool) { let mut stdout = io::stdout().into_raw_mode().unwrap(); let count = lines.len() as u16; @@ -133,3 +133,27 @@ pub fn bg_stripes(colors: Vec>, width: u16, height: u16) -> Vec output } +pub enum Flag { + Stripes(Colors), + Lines(Vec) +} +impl Flag { + pub fn draw(self, hold: bool) { + let lines = match self { + Flag::Stripes(colors) + => { + let (width, height); + if hold { (width, height) = terminal_size().unwrap(); } + else { + height = colors.len() as u16; + width = height * 3; + } + fg_stripes(colors, width, height) + }, + Flag::Lines(lines) + => lines + }; + draw_lines(lines, hold); + } +} + diff --git a/src/flag.rs b/src/flag.rs index 943ee83..ca1e62c 100644 --- a/src/flag.rs +++ b/src/flag.rs @@ -1,7 +1,8 @@ use crate::color::*; +use crate::draw::Flag; -pub fn pride() -> Colors { +pub fn pride() -> Flag { let red = rgb(0xE50000); let orange = rgb(0xFF8D00); let yellow = rgb(0xFFEE00); @@ -9,108 +10,108 @@ pub fn pride() -> Colors { let blue = rgb(0x004CFF); let purple = rgb(0x770088); - vec![red, orange, yellow, green, blue, purple] + Flag::Stripes(vec![red, orange, yellow, green, blue, purple]) } -pub fn transgender() -> Colors { +pub fn transgender() -> Flag { let pink = rgb(0x7ACBF5); let blue = rgb(0xEAACB8); - vec![pink, blue, WHITE, blue, pink] + Flag::Stripes(vec![pink, blue, WHITE, blue, pink]) } // everything below here is alphabetical -pub fn agender() -> Colors { +pub fn agender() -> Flag { let gray = rgb(0xB9B9B9); let green = rgb(0xB8F483); - vec![BLACK, gray, WHITE, green, WHITE, gray, BLACK] + Flag::Stripes(vec![BLACK, gray, WHITE, green, WHITE, gray, BLACK]) } -pub fn aromantic() -> Colors { +pub fn aromantic() -> Flag { let green = rgb(0x3BA740); let lime = rgb(0xA8D47A); let grey = rgb(0xABABAB); - vec![green, lime, WHITE, grey, BLACK] + Flag::Stripes(vec![green, lime, WHITE, grey, BLACK]) } -pub fn asexual() -> Colors { +pub fn asexual() -> Flag { let grey = rgb(0xA4A4A4); let purple = rgb(0x810081); - vec![BLACK, grey, WHITE, purple] + Flag::Stripes(vec![BLACK, grey, WHITE, purple]) } -pub fn bigender() -> Colors { +pub fn bigender() -> Flag { let pink = rgb(0xE676A6); let yellow = rgb(0xF9F04C); let purple = rgb(0xAB6BBB); let blue = rgb(0x6D96DC); - vec![pink, yellow, WHITE, purple, blue] + Flag::Stripes(vec![pink, yellow, WHITE, purple, blue]) } -pub fn bisexual() -> Colors { +pub fn bisexual() -> Flag { let magenta = rgb(0xC42A6F); let purple = rgb(0x915392); let blue = rgb(0x1437A2); - vec![magenta, magenta, purple, blue, blue] + Flag::Stripes(vec![magenta, magenta, purple, blue, blue]) } -pub fn genderfluid() -> Colors { +pub fn genderfluid() -> Flag { let pink = rgb(0xFF75A2); let violet = rgb(0xBE18D6); let blue = rgb(0x333EBD); - vec![pink, WHITE, violet, BLACK, blue] + Flag::Stripes(vec![pink, WHITE, violet, BLACK, blue]) } -pub fn genderqueer() -> Colors { +pub fn genderqueer() -> Flag { let purple = rgb(0xB899DF); let green = rgb(0x6B8E3B); - vec![purple, WHITE, green] + Flag::Stripes(vec![purple, WHITE, green]) } -pub fn gendervoid() -> Colors { +pub fn gendervoid() -> Flag { let navy = rgb(0x08114A); let gray = rgb(0x4A484B); - vec![navy, gray, BLACK, gray, navy] + Flag::Stripes(vec![navy, gray, BLACK, gray, navy]) } -pub fn lesbian() -> Colors { +pub fn lesbian() -> Flag { let red = rgb(0xD62800); let orange = rgb(0xFF9B56); let pink = rgb(0xD462A6); let magenta = rgb(0xA40062); - vec![red, orange, WHITE, pink, magenta] + Flag::Stripes(vec![red, orange, WHITE, pink, magenta]) } -pub fn multigender() -> Colors { +pub fn multigender() -> Flag { let blue = rgb(0x3F47CC); let ltblue = rgb(0x01A4E9); let orange = rgb(0xFB7F27); - vec![blue, ltblue, orange, ltblue, blue] + Flag::Stripes(vec![blue, ltblue, orange, ltblue, blue]) } -pub fn nonbinary() -> Colors { +pub fn nonbinary() -> Flag { let yellow = rgb(0xFFF433); let purple = rgb(0x9B59D0); - vec![yellow, WHITE, purple, BLACK] + Flag::Stripes(vec![yellow, WHITE, purple, BLACK]) } -pub fn pansexual() -> Colors { +pub fn pansexual() -> Flag { let magenta = rgb(0xFF1B8D); let yellow = rgb(0xFFDA00); let cyan = rgb(0x1BB3FF); - vec![magenta, yellow, cyan] + Flag::Stripes(vec![magenta, yellow, cyan]) } diff --git a/src/main.rs b/src/main.rs index 8fac60b..9d1c208 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ mod draw; mod flag; mod variant; -use crate::color::Colors; +use crate::draw::Flag; static VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -38,7 +38,7 @@ fn main() { let subcommand = args.subcommand().unwrap(); - let colors: Colors = match subcommand.as_deref() { + let flag: Flag = match subcommand.as_deref() { Some("pride" | "gay") => { let variant = args.subcommand().unwrap_or(None); @@ -115,8 +115,7 @@ fn main() { _ => { help_text(); exit(1) } }; - if small { draw::small(colors); } - else { draw::full(colors); } + flag.draw(!small); } diff --git a/src/variant.rs b/src/variant.rs index 127d71d..daa2076 100644 --- a/src/variant.rs +++ b/src/variant.rs @@ -1,10 +1,11 @@ use crate::{ color::*, + draw::Flag, flag }; -pub fn gilbert_baker() -> Colors { +pub fn gilbert_baker() -> Flag { let pink = rgb(0xFF69B4); // sex let red = rgb(0xFF0000); // life let orange = rgb(0xFF8F00); // healing @@ -14,16 +15,22 @@ pub fn gilbert_baker() -> Colors { let indigo = rgb(0x3E0099); // serenity let purple = rgb(0x8F008F); // spirit - vec![pink, red, orange, yellow, green, cyan, indigo, purple] + Flag::Stripes(vec![pink, red, orange, yellow, green, cyan, indigo, purple]) } -pub fn philadelphia() -> Colors { +pub fn philadelphia() -> Flag { let brown = rgb(0x784F17); - let mut output = flag::pride(); - output.insert(0, BLACK); - output.insert(1, brown); + let base = flag::pride(); + let mut colors = match base { + Flag::Stripes(inner) + => inner, + _ + => { panic!("impossible enum variant"); } + }; + colors.insert(0, BLACK); + colors.insert(1, brown); - output + Flag::Stripes(colors) }