~raph/blurrr

ref: fa3bce5fbcf5640b1414c10ef93c57d4db41793e blurrr/src/main.rs -rw-r--r-- 3.2 KiB
fa3bce5fRaph Levien All parameters automatically tuned 1 year, 7 months ago
                                                                                
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
use druid::piet::InterpolationMode;
use druid::widget::prelude::*;
use druid::widget::{Flex, Slider};
use druid::{AppLauncher, Data, Lens, LocalizedString, Widget, WidgetExt, WindowDesc};

mod distfield;
mod image;
mod integration;
mod math;

#[derive(Clone, Data, Lens)]
struct AppState {
    width: f64,
    height: f64,
    radius: f64,
    std_dev: f64,

    /*
    // extra parameters for distance field renderer
    r_mul: f64,
    exponent: f64,
    */
}

struct BlurWidget;

const IM_WIDTH: usize = 256;
const IM_HEIGHT: usize = 256;

impl Widget<AppState> for BlurWidget {
    fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut AppState, _env: &Env) {}

    fn lifecycle(
        &mut self,
        _ctx: &mut LifeCycleCtx,
        _event: &LifeCycle,
        _data: &AppState,
        _env: &Env,
    ) {
    }

    fn update(&mut self, _ctx: &mut UpdateCtx, _old_data: &AppState, _data: &AppState, _env: &Env) {
    }

    fn layout(
        &mut self,
        _layout_ctx: &mut LayoutCtx,
        bc: &BoxConstraints,
        _data: &AppState,
        _env: &Env,
    ) -> Size {
        bc.max()
    }

    fn paint(&mut self, ctx: &mut PaintCtx, data: &AppState, _env: &Env) {
        let radius = data.radius.min(0.5 * data.width.min(data.height));
        let d0 = distfield::gen_distfield(
            IM_WIDTH,
            IM_HEIGHT,
            data.width,
            data.height,
            radius,
            data.std_dev,
        );
        let d1 = integration::gen_integrate(
            IM_WIDTH,
            IM_HEIGHT,
            data.width,
            data.height,
            radius,
            data.std_dev,
        );
        let image = image::make_image_two(ctx, IM_WIDTH, IM_HEIGHT, &d0, &d1);
        //let image = image::make_image_one(ctx, IM_WIDTH, IM_HEIGHT, &d0);
        let scale = (ctx.size().width / IM_WIDTH as f64).min(ctx.size().height / IM_HEIGHT as f64);
        let rect = (Size::new(IM_WIDTH as f64, IM_HEIGHT as f64) * scale).to_rect();
        ctx.draw_image(&image, rect, InterpolationMode::NearestNeighbor);
    }
}

fn ui_builder() -> impl Widget<AppState> {
    Flex::column()
        .with_spacer(5.0)
        .with_child(Slider::new().with_range(0.0, 250.0).lens(AppState::width))
        .with_spacer(5.0)
        .with_child(Slider::new().with_range(0.0, 250.0).lens(AppState::height))
        .with_spacer(5.0)
        .with_child(Slider::new().with_range(0.0, 50.0).lens(AppState::radius))
        .with_spacer(5.0)
        .with_child(Slider::new().with_range(0.0, 50.0).lens(AppState::std_dev))
        /*
        .with_spacer(5.0)
        .with_child(Slider::new().with_range(1.0, 5.0).lens(AppState::r_mul))
        .with_spacer(5.0)
        .with_child(Slider::new().with_range(2.0, 10.0).lens(AppState::exponent))
        */
        .with_spacer(5.0)
        .with_flex_child(BlurWidget, 1.0)
}

fn main() {
    let data = AppState {
        width: 100.0,
        height: 80.0,
        radius: 5.0,
        std_dev: 5.0,

        /*
        r_mul: 1.0,
        exponent: 2.0,
        */
    };
    let main_window = WindowDesc::new(ui_builder).title(LocalizedString::new("blur toy"));
    AppLauncher::with_window(main_window).launch(data).unwrap();
}