Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core][cmdr] Update lolcat api to accept a TuiStyle #376

Merged
merged 1 commit into from
Dec 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -880,12 +880,16 @@ exhaustively tested and is able to handle many more corner cases.

### v_next_release_r3bl_core

This release does not have any major changes.
This release does not have any major changes. Here are the highlights:
1. Add a new declarative macro to effortlessly create global mutable thread safe
singletons (without using `unsafe`).
2. Replace all the ignored doc tests with `no_run` (just compile) or compile and run. For
all Rust source files (in the entire monorepo, and not just this crate / folder).
3. Here's the [PR](https://github.com/r3bl-org/r3bl-open-core/pull/370).
4. There's a new converter `convert_to_ansi_color_styles` which converts a `TuiStyle` into
a `Vec` of `r3bl_ansi_term::Style`. This is for `lolcat_api` enhancements which now
allow for an optional default style to be passed in, that will be applied to the
generated lolcat output.

Changed:
- Fix all the Rust doc tests that were marked with `ignore`. Remove the `ignore` with
Expand All @@ -897,6 +901,11 @@ Changed:
replace them with doc comments that compile successfully.

- Added:
- `lolcat_api` enhancements that now allow for an optional default style to be passed in
to `ColorWheel::lolcat_into_string` and `ColorWheel::colorize_into_string`, that will
be applied to the generated lolcat output.
- `convert_to_ansi_color_styles` module that adds the ability to convert a `TuiStyle`
into a `Vec` of `r3bl_ansi_term::Style`.
- A new declarative macro `create_global_singleton!` that takes a struct (which must
implement `Default` trait) and allows it to be simply turned into a singleton.
- You can still use the struct directly. Or just use the supplied generated associated
Expand Down
3 changes: 2 additions & 1 deletion cmdr/src/bin/edi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub mod edi_ui_templates {
&UnicodeString::from("New version of edi is available 📦."),
GradientGenerationPolicy::ReuseExistingGradientAndResetIndex,
TextColorizationPolicy::ColorEachCharacter(None),
None,
)
};

Expand Down Expand Up @@ -168,7 +169,7 @@ pub mod edi_ui_templates {

let plain_text_exit_msg = format!("{goodbye_to_user}\n{please_star_us}");

ColorWheel::lolcat_into_string(&plain_text_exit_msg)
ColorWheel::lolcat_into_string(&plain_text_exit_msg, None)
});
}
}
Expand Down
3 changes: 2 additions & 1 deletion cmdr/src/giti/branch/giti_ui_templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ pub fn show_exit_message() {
&UnicodeString::from(plain_text_exit_msg),
GradientGenerationPolicy::ReuseExistingGradientAndResetIndex,
TextColorizationPolicy::ColorEachCharacter(None),
None,
)
});
} else {
Expand All @@ -123,7 +124,7 @@ pub fn show_exit_message() {
let please_star_us = PleaseStarUs.to_string();
let plain_text_exit_msg = format!("{goodbye_to_user}\n{please_star_us}");

ColorWheel::lolcat_into_string(&plain_text_exit_msg)
ColorWheel::lolcat_into_string(&plain_text_exit_msg, None)
});
}
}
Expand Down
31 changes: 14 additions & 17 deletions core/src/tui_core/color_wheel/color_wheel_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* limitations under the License.
*/

use std::ops::AddAssign;

use r3bl_ansi_color::AnsiStyledText;
use serde::{Deserialize, Serialize};

Expand All @@ -24,7 +26,7 @@ use super::{ColorWheelConfig,
GradientKind,
GradientLengthKind};
use crate::{ch,
convert_tui_color_into_r3bl_ansi_color,
convert_to_ansi_color_styles,
generate_random_truecolor_gradient,
generate_truecolor_gradient,
get_gradient_array_for,
Expand Down Expand Up @@ -334,11 +336,15 @@ impl ColorWheel {
}

/// Simplified version of [ColorWheel::colorize_into_string] with some defaults.
pub fn lolcat_into_string(text: &str) -> String {
pub fn lolcat_into_string(
text: &str,
maybe_default_style: Option<TuiStyle>,
) -> String {
ColorWheel::default().colorize_into_string(
&UnicodeString::from(text),
GradientGenerationPolicy::ReuseExistingGradientAndResetIndex,
TextColorizationPolicy::ColorEachCharacter(None),
maybe_default_style,
)
}

Expand All @@ -348,6 +354,7 @@ impl ColorWheel {
unicode_string: &UnicodeString,
gradient_generation_policy: GradientGenerationPolicy,
text_colorization_policy: TextColorizationPolicy,
maybe_default_style: Option<TuiStyle>,
) -> String {
let it = self.colorize_into_styled_texts(
unicode_string,
Expand All @@ -358,26 +365,15 @@ impl ColorWheel {
let mut acc_vec = vec![];

for TuiStyledText {
style,
mut style,
text: unicode_string,
} in it.inner
{
let maybe_src_color_fg = style.color_fg;
let maybe_src_color_bg = style.color_bg;

let mut acc_style = vec![];

if let Some(src_color_fg) = maybe_src_color_fg {
acc_style.push(r3bl_ansi_color::Style::Foreground(
convert_tui_color_into_r3bl_ansi_color(src_color_fg),
));
if let Some(default_style) = maybe_default_style {
style.add_assign(default_style);
}

if let Some(src_color_bg) = maybe_src_color_bg {
acc_style.push(r3bl_ansi_color::Style::Background(
convert_tui_color_into_r3bl_ansi_color(src_color_bg),
));
}
let acc_style = convert_to_ansi_color_styles::from_tui_style(style);

let ansi_styled_text = AnsiStyledText {
style: &acc_style,
Expand Down Expand Up @@ -935,6 +931,7 @@ mod tests_color_wheel_rgb {
&unicode_string,
GradientGenerationPolicy::RegenerateGradientAndIndexBasedOnTextLength,
TextColorizationPolicy::ColorEachCharacter(None),
None,
);

println!("ansi_styled_string: {}", ansi_styled_string);
Expand Down
164 changes: 164 additions & 0 deletions core/src/tui_core/tui_style/tui_style_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,167 @@ mod test_style {
assert!(!style.reverse);
}
}

pub mod convert_to_ansi_color_styles {
use super::*;
use crate::convert_tui_color_into_r3bl_ansi_color;

pub fn from_tui_style(tui_style: TuiStyle) -> Vec<r3bl_ansi_color::Style> {
let mut acc_style: Vec<r3bl_ansi_color::Style> = vec![];

if let Some(color_fg) = tui_style.color_fg {
acc_style.push(r3bl_ansi_color::Style::Foreground(
convert_tui_color_into_r3bl_ansi_color(color_fg),
));
}

if let Some(color_bg) = tui_style.color_bg {
acc_style.push(r3bl_ansi_color::Style::Background(
convert_tui_color_into_r3bl_ansi_color(color_bg),
));
}

if tui_style.bold {
acc_style.push(r3bl_ansi_color::Style::Bold);
}

if tui_style.dim {
acc_style.push(r3bl_ansi_color::Style::Dim);
}

if tui_style.italic {
acc_style.push(r3bl_ansi_color::Style::Italic);
}

if tui_style.underline {
acc_style.push(r3bl_ansi_color::Style::Underline);
}

if tui_style.reverse {
acc_style.push(r3bl_ansi_color::Style::Invert);
}

if tui_style.hidden {
acc_style.push(r3bl_ansi_color::Style::Hidden);
}

if tui_style.strikethrough {
acc_style.push(r3bl_ansi_color::Style::Strikethrough);
}

acc_style
}

#[cfg(test)]
mod tests_style {
use super::*;
use crate::{assert_eq2, color, ANSIBasicColor};

#[test]
fn test_all_fields_in_style() {
let style = TuiStyle {
id: 1,
bold: true,
dim: true,
underline: true,
reverse: true,
hidden: true,
strikethrough: true,
color_fg: color!(@red).into(),
color_bg: color!(0, 0, 0).into(),
padding: Some(ch!(10)),
..TuiStyle::default()
};

assert!(!style.computed);
assert_eq2!(style.id, 1);
assert!(style.bold);
assert!(style.dim);
assert!(style.underline);
assert!(style.reverse);
assert!(style.hidden);
assert!(style.strikethrough);
assert_eq2!(style.color_fg, color!(@red).into());
assert_eq2!(style.color_bg, color!(0, 0, 0).into());
assert_eq2!(style.padding, Some(ch!(10)));
}

#[test]
fn test_style() {
let style = TuiStyle {
id: 1,
color_fg: color!(0, 0, 0).into(),
color_bg: color!(0, 0, 0).into(),
bold: true,
dim: true,
italic: true,
..TuiStyle::default()
};

dbg!(&style);

assert!(style.bold);
assert!(style.dim);
assert!(style.italic);
assert!(!style.underline);
assert!(!style.strikethrough);
assert!(!style.reverse);
}

#[test]
fn test_add_styles() {
let style1 = TuiStyle {
bold: true,
color_fg: color!(@red).into(),
..TuiStyle::default()
};

let style2 = TuiStyle {
italic: true,
color_bg: color!(0, 0, 0).into(),
..TuiStyle::default()
};

let combined_style = style1 + style2;

assert!(combined_style.bold);
assert!(combined_style.italic);
assert_eq2!(combined_style.color_fg, color!(@red).into());
assert_eq2!(combined_style.color_bg, color!(0, 0, 0).into());
}

#[test]
fn test_add_assign_styles() {
let mut style1 = TuiStyle {
bold: true,
color_fg: color!(@red).into(),
..TuiStyle::default()
};

let style2 = TuiStyle {
italic: true,
color_bg: color!(0, 0, 0).into(),
..TuiStyle::default()
};

style1 += style2;

assert!(style1.bold);
assert!(style1.italic);
assert_eq2!(style1.color_fg, color!(@red).into());
assert_eq2!(style1.color_bg, color!(0, 0, 0).into());
}

#[test]
fn test_remove_bg_color() {
let mut style = TuiStyle {
color_bg: color!(0, 0, 0).into(),
..TuiStyle::default()
};

style.remove_bg_color();

assert!(style.color_bg.is_none());
}
}
}
Loading