This commit is contained in:
2024-10-21 13:42:24 +02:00
parent 9247cddf98
commit 5dbc5378d9
4 changed files with 88 additions and 55 deletions
+25 -20
View File
@@ -21,45 +21,45 @@ pub fn div() -> Component {
if let Some(v) = this.binds.get(&k.kind) { if let Some(v) = this.binds.get(&k.kind) {
match v.as_str() { match v.as_str() {
"up" => { "up" => {
this.active_child = closest_component( this.set_child(closest_component(
&this.children, &this.children,
this.active_child, this.child,
crate::utils::Direction::Up, crate::utils::Direction::Up,
); ));
} }
"down" => { "down" => {
this.active_child = closest_component( this.set_child(closest_component(
&this.children, &this.children,
this.active_child, this.child,
crate::utils::Direction::Down, crate::utils::Direction::Down,
); ));
} }
"left" => { "left" => {
this.active_child = closest_component( this.set_child(closest_component(
&this.children, &this.children,
this.active_child, this.child,
crate::utils::Direction::Left, crate::utils::Direction::Left,
); ));
} }
"right" => { "right" => {
this.active_child = closest_component( this.set_child(closest_component(
&this.children, &this.children,
this.active_child, this.child,
crate::utils::Direction::Right, crate::utils::Direction::Right,
); ));
} }
_ => { _ => {
if let Some(child) = this.get_active_child() { if let Some(child) = this.get_child() {
return (child.update)(child, k); return (child.update)(child, k);
} }
} }
} }
} else { } else {
if let Some(child) = this.get_active_child() { if let Some(child) = this.get_child() {
return (child.update)(child, k); return (child.update)(child, k);
} }
} }
@@ -67,16 +67,17 @@ pub fn div() -> Component {
UpdateResponse::None UpdateResponse::None
} }
fn render(s: &mut Component) -> String { fn render(this: &mut Component) -> String {
let mut frame: Vec<String> = create_frame!(s.width, s.height); let mut frame: Vec<String> = create_frame!(this.width, this.height);
for c in &mut s.children { for (i, c) in &mut this.children.iter_mut().enumerate() {
c.style.is_active = this.style.is_active && i == this.child;
render_to_frame(&mut frame, c); render_to_frame(&mut frame, c);
} }
frame.join("\n") frame.join("\n")
} }
fn tick(this: &mut Component, i: usize) { fn tick(this: &mut Component, i: usize) {
if let Some(child) = this.get_active_child() { if let Some(child) = this.get_child() {
return (child.tick)(child, i); return (child.tick)(child, i);
} }
} }
@@ -106,7 +107,8 @@ pub fn text() -> Component {
pub fn button() -> Component { pub fn button() -> Component {
let mut component = Component::new(); let mut component = Component::new();
component.style.hover_fg = crate::style::Color::Blue; component.style.clicked_fg = crate::style::Color::Red;
component.style.hover_fg = crate::style::Color::Green;
fn update(this: &mut Component, k: key::Key) -> UpdateResponse { fn update(this: &mut Component, k: key::Key) -> UpdateResponse {
if k.kind == KeyKind::Enter { if k.kind == KeyKind::Enter {
@@ -131,7 +133,10 @@ pub fn button() -> Component {
} }
fn render(this: &mut Component) -> String { fn render(this: &mut Component) -> String {
this.style.clone().write(&this.expr) if this.clicked {
return this.style.write_clicked(&this.expr);
}
this.style.write(&this.expr)
} }
component.update = update; component.update = update;
+6 -13
View File
@@ -19,7 +19,7 @@ pub struct Component {
pub height: usize, pub height: usize,
pub expr: String, pub expr: String,
pub children: Vec<Component>, pub children: Vec<Component>,
pub active_child: usize, pub child: usize,
pub clicked: bool, pub clicked: bool,
pub toggle: bool, pub toggle: bool,
pub binds: HashMap<key::KeyKind, String>, pub binds: HashMap<key::KeyKind, String>,
@@ -40,7 +40,7 @@ impl Component {
height: 0, height: 0,
expr: String::new(), expr: String::new(),
children: Vec::new(), children: Vec::new(),
active_child: 0, child: 0,
clicked: false, clicked: false,
toggle: false, toggle: false,
binds: HashMap::new(), binds: HashMap::new(),
@@ -48,26 +48,19 @@ impl Component {
} }
} }
pub fn get_active_child(&mut self) -> Option<&mut Component> { pub fn get_child(&mut self) -> Option<&mut Component> {
self.children.get_mut(self.active_child) self.children.get_mut(self.child)
} }
pub fn set_active_child(&mut self, idx: usize) { pub fn set_child(&mut self, idx: usize) {
let last_active = self.active_child;
if let Some(last_child) = self.children.get_mut(last_active) {
last_child.style.is_active = false;
}
if let Some(child) = self.children.get_mut(idx) { if let Some(child) = self.children.get_mut(idx) {
self.active_child = idx; self.child = idx;
if child.width == 0 { if child.width == 0 {
child.width = self.width; child.width = self.width;
} }
if child.height == 0 { if child.height == 0 {
child.height = self.height; child.height = self.height;
} }
child.style.is_active = self.style.is_active;
} else if let Some(last_child) = self.children.get_mut(last_active) {
last_child.style.is_active = true;
} }
} }
} }
+48 -19
View File
@@ -10,6 +10,11 @@ pub struct Style {
pub hover_outline: Color, pub hover_outline: Color,
pub hover_font: Font, pub hover_font: Font,
pub clicked_bg: Color,
pub clicked_fg: Color,
pub clicked_outline: Color,
pub clicked_font: Font,
pub is_active: bool, pub is_active: bool,
} }
@@ -26,36 +31,60 @@ impl Style {
hover_outline: Color::None, hover_outline: Color::None,
hover_font: Font::None, hover_font: Font::None,
clicked_bg: Color::None,
clicked_fg: Color::None,
clicked_outline: Color::None,
clicked_font: Font::None,
is_active: false, is_active: false,
} }
} }
pub fn get(self) -> String { pub fn get(&self) -> String {
if self.is_active { if self.is_active {
String::from( format!(
self.fg.prioritize(self.hover_fg).ansi() "{}{}{}",
+ &self.bg.prioritize(self.hover_bg).ansi_bg() self.fg.prioritize(&self.hover_fg).ansi(),
+ &self.font.prioritize(self.hover_font).ansi(), self.bg.prioritize(&self.hover_bg).ansi_bg(),
self.font.prioritize(&self.hover_font).ansi()
) )
} else { } else {
String::from(self.fg.ansi() + &self.bg.ansi_bg() + &self.font.ansi()) format!(
"{}{}{}",
self.fg.ansi(),
self.bg.ansi_bg(),
self.font.ansi()
)
} }
} }
pub fn get_outline(self) -> String { pub fn get_outline(&self) -> String {
if self.is_active { if self.is_active {
self.outline.prioritize(self.hover_outline).ansi() self.outline.prioritize(&self.hover_outline).ansi()
} else { } else {
self.outline.ansi() self.outline.ansi()
} }
} }
pub fn write(self, s: &str) -> String { pub fn get_clicked(&self) -> String {
format!("{}{}", self.get(), s) format!(
"{}{}{}",
self.fg.prioritize(&self.clicked_fg).ansi(),
self.bg.prioritize(&self.clicked_bg).ansi_bg(),
self.font.prioritize(&self.clicked_font).ansi()
)
} }
pub fn write_outline(self, s: &str) -> String { pub fn write(&self, s: &str) -> String {
format!("{}{}", self.get_outline(), s) format!("{}{}\x1b[0m", self.get(), s)
}
pub fn write_outline(&self, s: &str) -> String {
format!("{}{}\x1b[0m", self.get_outline(), s)
}
pub fn write_clicked(&self, s: &str) -> String {
format!("{}{}\x1b[0m", self.get_clicked(), s)
} }
} }
@@ -71,7 +100,7 @@ pub enum Font {
} }
impl Font { impl Font {
pub fn ansi(self) -> String { pub fn ansi(&self) -> String {
String::from(match self { String::from(match self {
Font::None => "", Font::None => "",
Font::Bold => "\x1b[1m", Font::Bold => "\x1b[1m",
@@ -89,8 +118,8 @@ impl Font {
}) })
} }
pub fn prioritize(self, secondary: Font) -> Font { pub fn prioritize<'a>(&'a self, secondary: &'a Font) -> &Font {
if secondary == Font::None { if secondary == &Font::None {
self self
} else { } else {
secondary secondary
@@ -113,7 +142,7 @@ pub enum Color {
} }
impl Color { impl Color {
pub fn ansi(self) -> String { pub fn ansi(&self) -> String {
String::from(match self { String::from(match self {
Color::None => "", Color::None => "",
Self::Rgb(r, g, b) => { Self::Rgb(r, g, b) => {
@@ -130,7 +159,7 @@ impl Color {
}) })
} }
pub fn ansi_bg(self) -> String { pub fn ansi_bg(&self) -> String {
String::from(match self { String::from(match self {
Color::None => "", Color::None => "",
Self::Rgb(r, g, b) => { Self::Rgb(r, g, b) => {
@@ -147,8 +176,8 @@ impl Color {
}) })
} }
pub fn prioritize(self, secondary: Color) -> Color { pub fn prioritize<'a>(&'a self, secondary: &'a Color) -> &Color {
if secondary == Color::None { if secondary == &Color::None {
self self
} else { } else {
secondary secondary
+9 -3
View File
@@ -46,11 +46,15 @@ pub fn compress_string(input: &str, re: &Regex) -> (String, HashMap<usize, Strin
/// Merges a frame withe a line by x /// Merges a frame withe a line by x
fn merge_line(frame_: &str, line_: &str, x: usize) -> String { fn merge_line(frame_: &str, line_: &str, x: usize) -> String {
let (frame_, fm) = compress_string(frame_, &ANSI); let (frame_, fm) = compress_string(frame_, &ANSI);
let (line_, lm) = compress_string(line_, &ANSI); let (mut line_, lm) = compress_string(line_, &ANSI);
if let Some(_) = lm.get(&line_.len()) {
line_.push('\n');
}
let mut res = String::new(); let mut res = String::new();
let frame: Vec<char> = frame_.chars().collect(); let frame: Vec<char> = frame_.chars().collect();
let line: Vec<char> = line_.chars().collect(); let line: Vec<char> = (line_).chars().collect();
let flen = frame.len(); let flen = frame.len();
let llen = line.len(); let llen = line.len();
@@ -60,7 +64,9 @@ fn merge_line(frame_: &str, line_: &str, x: usize) -> String {
if let Some(v) = lm.get(&(i - x)) { if let Some(v) = lm.get(&(i - x)) {
res.push_str(v); res.push_str(v);
} }
res.push(line[i - x]); if line[i - x] != '\n' {
res.push(line[i - x]);
}
} else { } else {
if let Some(v) = fm.get(&i) { if let Some(v) = fm.get(&i) {
res.push_str(v); res.push_str(v);