scroll/
scroll.rs

1// Copyright 2019 The Druid Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Shows a scroll widget, and also demonstrates how widgets that paint
16//! outside their bounds can specify their paint region.
17
18// On Windows platform, don't show a console when opening the app.
19#![windows_subsystem = "windows"]
20
21use druid::kurbo::Circle;
22use druid::piet::RadialGradient;
23use druid::widget::prelude::*;
24use druid::widget::{Flex, Padding};
25use druid::{AppLauncher, Data, Insets, LocalizedString, Rect, WidgetExt, WindowDesc};
26
27pub fn main() {
28    let window = WindowDesc::new(build_widget())
29        .title(LocalizedString::new("scroll-demo-window-title").with_placeholder("Scroll demo"));
30    AppLauncher::with_window(window)
31        .log_to_console()
32        .launch(0u32)
33        .expect("launch failed");
34}
35
36fn build_widget() -> impl Widget<u32> {
37    let mut col = Flex::column();
38    for i in 0..30 {
39        col.add_child(Padding::new(3.0, OverPainter(i)));
40    }
41    col.scroll()
42}
43
44/// A widget that paints outside of its bounds.
45struct OverPainter(u64);
46
47const INSETS: Insets = Insets::uniform(50.);
48
49impl<T: Data> Widget<T> for OverPainter {
50    fn event(&mut self, _: &mut EventCtx, _: &Event, _: &mut T, _: &Env) {}
51
52    fn lifecycle(&mut self, _: &mut LifeCycleCtx, _: &LifeCycle, _: &T, _: &Env) {}
53
54    fn update(&mut self, _: &mut UpdateCtx, _: &T, _: &T, _: &Env) {}
55
56    fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, _: &T, _: &Env) -> Size {
57        ctx.set_paint_insets(INSETS);
58        bc.constrain(Size::new(100., 100.))
59    }
60
61    fn paint(&mut self, ctx: &mut PaintCtx, _: &T, env: &Env) {
62        let rect = Rect::ZERO.with_size(ctx.size());
63        let color = env.get_debug_color(self.0);
64        let radius = (rect + INSETS).size().height / 2.0;
65        let circle = Circle::new(rect.center(), radius);
66        let grad = RadialGradient::new(1.0, (color, color.with_alpha(0.0)));
67        ctx.fill(circle, &grad);
68        ctx.stroke(rect, &color, 2.0);
69    }
70}