summaryrefslogtreecommitdiff
path: root/src/edit.rs
blob: 0e89097b3290ccf0a35e2440db29eb40213afec1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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        : (squares-primary.width / 8) - 12px;
                        height       : (squares-primary.width / 8) - 12px;
                        border-color : ptouch.has-hover ? #eeeeee : #333333;
                        border-width : 3px;

                        ptouch := TouchArea {
                        }

                        prect := Rectangle {
                            y            :  3px;
                            x            :  3px;
                            width        : psquare.width  - 6px;
                            height       : psquare.height - 6px;
                            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        : (squares-secondary.width / 8) - 12px;
                        height       : (squares-secondary.width / 8) - 12px;
                        border-color : stouch.has-hover ? #eeeeee : #333333;
                        border-width : 3px;

                        stouch := TouchArea {
                        }

                        srect := Rectangle {
                            y            :  3px;
                            x            :  3px;
                            width        : ssquare.width  - 6px;
                            height       : ssquare.height - 6px;
                            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(())
    }
}