diff options
| -rw-r--r-- | src/edit.rs | 184 | ||||
| -rw-r--r-- | src/lib.rs | 50 | ||||
| -rw-r--r-- | src/vtcol.rs | 4 | 
3 files changed, 235 insertions, 3 deletions
diff --git a/src/edit.rs b/src/edit.rs new file mode 100644 index 0000000..a166ce4 --- /dev/null +++ b/src/edit.rs @@ -0,0 +1,184 @@ +use vtcol::{Palette, Rgb, Scheme}; + +use std::rc::Rc; + +use anyhow::{anyhow, Result}; + +use slint::{Color, VecModel}; + +slint::slint! { +    import { HorizontalBox, VerticalBox } from "std-widgets.slint"; + +    export global Aux := { +        callback format-rgb-hex(color) -> string; +    } + +    GuiEdit := Window { +        property scheme-name <=> name.text; + +        property <[color]> primary: [ +            rgb(  0,   0,   0), +        ]; + +        property <[color]> secondary: [ +            rgb(255, 255, 255), +        ]; + +        VerticalBox { +            alignment: start; + +            status := HorizontalBox { +                width : 100%; + +                name := Text { +                    text        : "<unnamed>"; +                    color       : #a0a0a0; +                    font-weight : 700; +                } +            } + +            primary-colors := Rectangle { +                width        : 100%; +                background   : #aaaaaa; +                border-width : 2px; + +                squares-primary := HorizontalBox { +                    width      : 100%; +                    height     : 20px; + +                    for col[i] in primary : psquare := Rectangle { +                        property <color> current-color : col; +                        width        : 86px; +                        height       : 86px; +                        border-color : ptouch.has-hover ? #eeeeee : #333333; +                        border-width : 3px; + +                        ptouch := TouchArea { +                        } + +                        prect := Rectangle { +                            y            :  3px; +                            x            :  3px; +                            width        : 80px; +                            height       : 80px; +                            background   : current-color; + +                            VerticalBox { +                                pdesc := Text { +                                    text : i; +                                } +                                Rectangle { +                                    background : ptouch.has-hover ? #ffffff77 : #cccccc33; +                                    pval := Text { +                                        text      : Aux.format-rgb-hex(current-color); +                                        font-size : 9pt; +                                    } +                                } +                                Rectangle { } +                            } +                        } +                    } +                } +            } + +            secondary-colors := Rectangle { +                width        : 100%; +                background   : #bbbbbb; +                border-width : 2px; + +                squares-secondary := HorizontalBox { +                    width      : 100%; +                    height     : 20px; + +                    for col[i] in secondary : ssquare := Rectangle { +                        property <color> current-color : col; +                        property <int> i2 : i + 8; +                        width        : 86px; +                        height       : 86px; +                        border-color : stouch.has-hover ? #eeeeee : #333333; +                        border-width : 3px; + +                        stouch := TouchArea { +                        } + +                        srect := Rectangle { +                            y            :  3px; +                            x            :  3px; +                            width        : 80px; +                            height       : 80px; +                            background   : current-color; + +                            VerticalBox { +                                sdesc := Text { +                                    text : i; +                                } +                                Rectangle { +                                    background : stouch.has-hover ? #ffffff77 : #cccccc33; +                                    sval := Text { +                                        text      : Aux.format-rgb-hex(current-color); +                                        font-size : 9pt; +                                    } +                                } +                                Rectangle { } +                            } +                        } +                    } +                } +            } +        } +    } +} + +pub struct Edit +{ +    name:   Option<String>, +    scheme: Scheme, +} + +impl Edit +{ +    pub fn new(name: Option<String>, scheme: Scheme) -> Self +    { +        Self { name, scheme } +    } + +    pub fn run(self) -> Result<()> +    { +        let Self { name, scheme } = self; + +        let pal = Palette::try_from(&scheme)?.iter().collect::<Vec<Rgb>>(); + +        let primary = pal[0..8] +            .iter() +            .map(|Rgb(r, g, b)| Color::from_rgb_u8(*r, *g, *b)) +            .collect::<Vec<Color>>(); + +        let secondary = pal[8..] +            .iter() +            .map(|Rgb(r, g, b)| Color::from_rgb_u8(*r, *g, *b)) +            .collect::<Vec<Color>>(); + +        let primary = Rc::new(VecModel::from(primary)); +        let secondary = Rc::new(VecModel::from(secondary)); + +        let gui = GuiEdit::new(); + +        gui.global::<Aux>().on_format_rgb_hex(|col| { +            let x = (col.red() as u32) << 2 +                | (col.green() as u32) << 1 +                | (col.blue() as u32); +            format!("#{:06x}", x).into() +        }); + +        if let Some(name) = name { +            gui.set_scheme_name(name.into()); +        } + +        gui.set_primary(primary.into()); +        gui.set_secondary(secondary.into()); + +        gui.run(); + +        Ok(()) +    } +} @@ -846,14 +846,17 @@ macro_rules! byte_of_hex {      };  } -struct Rgb(u8, u8, u8); +pub struct Rgb(pub u8, pub u8, pub u8);  impl Rgb  { +    #[inline]      fn r(&self) -> u8 { self.0 } +    #[inline]      fn g(&self) -> u8 { self.1 } +    #[inline]      fn b(&self) -> u8 { self.2 }  } @@ -871,6 +874,18 @@ impl TryFrom<&[u8; 6]> for Rgb      }  } +impl From<[u8; 3]> for Rgb +{ +    fn from(bytes: [u8; 3]) -> Self +    { +        let r = bytes[0]; +        let g = bytes[1]; +        let b = bytes[2]; + +        Self(r, g, b) +    } +} +  impl From<u32> for Rgb  {      fn from(rgb: u32) -> Self @@ -1028,6 +1043,7 @@ impl Palette          Ok(res)      } +    pub fn iter(&self) -> PaletteIterator { PaletteIterator::new(&self) }      /* [Palette::from_stdin] */  } /* [impl Palette] */ @@ -1109,6 +1125,38 @@ impl From<&RawPalette> for Palette      }  } +pub struct PaletteIterator +{ +    pal: Palette, +    cur: usize, +} + +impl PaletteIterator +{ +    fn new(pal: &Palette) -> Self { Self { pal: pal.clone(), cur: 0 } } +} + +impl Iterator for PaletteIterator +{ +    type Item = Rgb; + +    fn next(&mut self) -> Option<Self::Item> +    { +        if self.cur >= PALETTE_SIZE { +            None +        } else { +            let off = self.cur * 3; +            let rgb = Rgb::from([ +                self.pal.0[off], +                self.pal.0[off + 1], +                self.pal.0[off + 2], +            ]); +            self.cur += 1; +            Some(rgb) +        } +    } +} +  const CONSOLE_PATHS: [&str; 6] = [      "/proc/self/fd/0",      "/dev/tty", diff --git a/src/vtcol.rs b/src/vtcol.rs index f12af09..feb8f0b 100644 --- a/src/vtcol.rs +++ b/src/vtcol.rs @@ -330,9 +330,9 @@ impl ColorJob      fn edit(name: Option<String>, scm: Scheme) -> Result<()>      {          vrb!("Launching color scheme editor for scheme {}", scm); -        let editor = crate::edit::Edit::new(); +        let editor = crate::edit::Edit::new(name, scm); -        editor.run(name, scm) +        editor.run()      }      #[cfg(not(feature = "gui"))]  | 
