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
use devotee::app;
use devotee::app::config;
use devotee::app::context::Context;
use devotee::app::input::key_mouse::{KeyMouse, VirtualKeyCode};
use devotee::app::root::Root;
use devotee::app::setup;
use devotee::util::vector::Vector;
use devotee::visual::canvas::Canvas;
use devotee::visual::color;
use devotee::visual::prelude::*;

fn main() {
    let init_config = setup::Setup::<Config>::new(
        Canvas::with_resolution(Color([0, 0, 0]), 128, 128),
        Default::default(),
        |_| Invert::new(),
    )
    .with_title("invert")
    .with_scale(2);
    let app = app::App::with_setup(init_config).unwrap();

    app.run();
}

struct Config;

impl config::Config for Config {
    type Root = Invert;
    type Converter = Converter;
    type Input = KeyMouse;
    type RenderTarget = Canvas<Color>;

    fn converter() -> Self::Converter {
        Converter
    }

    fn background_color() -> Color {
        Color([0, 0, 0])
    }
}

struct Invert {
    position: Vector<f64>,
    canvas: Canvas<bool>,
}

impl Invert {
    fn new() -> Self {
        let position = Vector::new(12.0, 12.0);
        let mut canvas = Canvas::with_resolution(false, 32, 32);

        let mut painter = canvas.painter();
        painter.line((0, 0), (31, 0), paint(true));
        painter.line((0, 0), (0, 31), paint(true));
        painter.line((0, 31), (31, 31), paint(true));
        painter.line((31, 0), (31, 31), paint(true));
        painter.line((0, 0), (31, 31), paint(true));
        painter.line((31, 0), (0, 31), paint(true));

        let mut counter = 0;
        painter.rect_f((4, 4), (32 - 4, 32 - 4), move |_, _, _| {
            counter += 1;
            counter % 5 == 0 || counter % 7 == 0
        });

        Self { position, canvas }
    }
}

impl Root<Config> for Invert {
    fn update(&mut self, update: &mut Context<Config>) {
        if update.input().keys().just_pressed(VirtualKeyCode::Escape) {
            update.shutdown();
        }
        let delta = 16.0 * update.delta().as_secs_f64();
        if update.input().keys().is_pressed(VirtualKeyCode::Left) {
            *self.position.x_mut() -= delta;
        }
        if update.input().keys().is_pressed(VirtualKeyCode::Right) {
            *self.position.x_mut() += delta;
        }
        if update.input().keys().is_pressed(VirtualKeyCode::Up) {
            *self.position.y_mut() -= delta;
        }
        if update.input().keys().is_pressed(VirtualKeyCode::Down) {
            *self.position.y_mut() += delta;
        }
    }

    fn render(&self, render: &mut Canvas<Color>) {
        let mut painter = render.painter();
        painter.clear(Color([0, 0, 0]));
        drop(painter);
        for x in 8..(render.width() - 8) {
            for y in 8..(render.height() - 8) {
                unsafe {
                    *Image::pixel_mut_unsafe(render, (x, y).into()) =
                        Color([2 * x as u8, 2 * y as u8, 0x00]);
                }
            }
        }

        let mut painter = render.painter();
        let (x, y) = (self.position.x() as i32, self.position.y() as i32);
        painter.image((x, y), &self.canvas, |_, _, value, _, _, invert| {
            if invert {
                Color([0xff - value.0[0], 0xff - value.0[1], 0xff - value.0[2]])
            } else {
                value
            }
        });
    }
}

#[derive(Clone, Copy, Default)]
struct Color([u8; 3]);

struct Converter;

impl color::Converter for Converter {
    type Palette = Color;
    fn convert(&self, color: &Self::Palette) -> u32 {
        ((color.0[0] as u32) << 16) | ((color.0[1] as u32) << 8) | color.0[2] as u32
    }
}