pub struct Rect {
pub x0: f64,
pub y0: f64,
pub x1: f64,
pub y1: f64,
}Expand description
A rectangle.
Fields§
§x0: f64The minimum x coordinate (left edge).
y0: f64The minimum y coordinate (top edge in y-down spaces).
x1: f64The maximum x coordinate (right edge).
y1: f64The maximum y coordinate (bottom edge in y-down spaces).
Implementations§
Source§impl Rect
impl Rect
Sourcepub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Rect
pub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Rect
A new rectangle from minimum and maximum coordinates.
Examples found in repository?
62fn build_root_widget() -> impl Widget<HelloState> {
63 // Draw red circle, and two semi-transparent rectangles
64 let circle_and_rects = Painter::new(|ctx, _data, _env| {
65 let boundaries = ctx.size().to_rect();
66 let center = (boundaries.width() / 2., boundaries.height() / 2.);
67 let circle = Circle::new(center, center.0.min(center.1));
68 ctx.fill(circle, &Color::RED);
69
70 let rect1 = Rect::new(0., 0., boundaries.width() / 2., boundaries.height() / 2.);
71 ctx.fill(rect1, &Color::rgba8(0x0, 0xff, 0, 125));
72
73 let rect2 = Rect::new(
74 boundaries.width() / 2.,
75 boundaries.height() / 2.,
76 boundaries.width(),
77 boundaries.height(),
78 );
79 ctx.fill(rect2, &Color::rgba8(0x0, 0x0, 0xff, 125));
80 });
81
82 // This textbox modifies the label, idea here is to test that the background
83 // invalidation works when you type to the textbox
84 let textbox = TextBox::new()
85 .with_placeholder("Type to test clearing")
86 .with_text_size(18.0)
87 .lens(HelloState::name)
88 .fix_width(250.);
89
90 let label = Label::new(|data: &HelloState, _env: &Env| {
91 if data.name.is_empty() {
92 "Text: ".to_string()
93 } else {
94 format!("Text: {}!", data.name)
95 }
96 })
97 .with_text_color(Color::RED)
98 .with_text_size(32.0);
99
100 Flex::column()
101 .with_flex_child(circle_and_rects.expand().controller(DragController), 10.0)
102 .with_spacer(4.0)
103 .with_child(textbox)
104 .with_spacer(4.0)
105 .with_child(label)
106}More examples
120 fn layout(
121 &mut self,
122 ctx: &mut druid::LayoutCtx,
123 bc: &druid::BoxConstraints,
124 data: &AppState,
125 env: &druid::Env,
126 ) -> druid::Size {
127 let mut interactable_area = Region::EMPTY;
128 let smaller_bc = BoxConstraints::new(
129 Size::new(0.0, 0.0),
130 Size::new(bc.max().width - 100.0, bc.max().height - 100.0),
131 );
132 let full_bc = BoxConstraints::new(Size::new(0.0, 0.0), bc.max());
133 let _label_size = self.info_label.layout(ctx, &smaller_bc, data, env);
134 let controls_size = self.controls.layout(ctx, &full_bc, data, env);
135
136 let text_origin_point = Point::new(50.0, 50.0 + controls_size.height);
137 self.info_label.set_origin(ctx, text_origin_point);
138 let controls_origin_point = Point::new(EXAMPLE_BORDER_SIZE, EXAMPLE_BORDER_SIZE);
139 self.controls.set_origin(ctx, controls_origin_point);
140
141 // Add side rects to clarify the dimensions of the window.
142 let left_rect = Rect::new(0.0, 0.0, EXAMPLE_BORDER_SIZE, bc.max().height);
143 let right_rect = Rect::new(
144 bc.max().width - EXAMPLE_BORDER_SIZE,
145 0.0,
146 bc.max().width,
147 bc.max().height,
148 );
149 let bottom_rect = Rect::new(
150 0.0,
151 bc.max().height - EXAMPLE_BORDER_SIZE,
152 bc.max().width,
153 bc.max().height,
154 );
155 interactable_area.add_rect(left_rect);
156 interactable_area.add_rect(right_rect);
157 interactable_area.add_rect(bottom_rect);
158 interactable_area.add_rect(self.info_label.layout_rect());
159 interactable_area.add_rect(self.controls.layout_rect());
160
161 if data.limit_input_region {
162 ctx.window().set_input_region(Some(interactable_area));
163 } else {
164 ctx.window().set_input_region(None);
165 }
166
167 bc.max()
168 }
169
170 fn paint(&mut self, ctx: &mut druid::PaintCtx, data: &AppState, env: &druid::Env) {
171 let window_area = ctx.size();
172 let left_rect = Rect::new(0.0, 0.0, EXAMPLE_BORDER_SIZE, window_area.height);
173 let right_rect = Rect::new(
174 window_area.width - EXAMPLE_BORDER_SIZE,
175 0.0,
176 window_area.width,
177 window_area.height,
178 );
179 let bottom_rect = Rect::new(
180 0.0,
181 window_area.height - EXAMPLE_BORDER_SIZE,
182 window_area.width,
183 window_area.height,
184 );
185
186 ctx.fill(left_rect, &Color::rgba(1.0, 0., 0., 0.7));
187 ctx.fill(right_rect, &Color::rgba(1.0, 0., 0., 0.7));
188 ctx.fill(bottom_rect, &Color::rgba(1.0, 0., 0., 0.7));
189 self.info_label.paint(ctx, data, env);
190 self.controls.paint(ctx, data, env);
191 }Sourcepub fn from_points(p0: impl Into<Point>, p1: impl Into<Point>) -> Rect
pub fn from_points(p0: impl Into<Point>, p1: impl Into<Point>) -> Rect
A new rectangle from two points.
The result will have non-negative width and height.
Sourcepub fn from_origin_size(origin: impl Into<Point>, size: impl Into<Size>) -> Rect
pub fn from_origin_size(origin: impl Into<Point>, size: impl Into<Size>) -> Rect
A new rectangle from origin and size.
The result will have non-negative width and height.
Examples found in repository?
297 fn paint(&mut self, ctx: &mut PaintCtx, data: &AppData, _env: &Env) {
298 let size: Size = ctx.size();
299 let w0 = size.width / GRID_SIZE as f64;
300 let h0 = size.height / GRID_SIZE as f64;
301 let cell_size = Size {
302 width: w0,
303 height: h0,
304 };
305 self.cell_size = cell_size;
306 for row in 0..GRID_SIZE {
307 for col in 0..GRID_SIZE {
308 let pos = GridPos { row, col };
309 if data.grid[pos] {
310 let point = Point {
311 x: w0 * row as f64,
312 y: h0 * col as f64,
313 };
314 let rect = Rect::from_origin_size(point, cell_size);
315
316 // We divide by 2 so that the colour changes every 2 positions instead of every 1
317 ctx.fill(
318 rect,
319 &COLOURS[((pos.row * GRID_SIZE + pos.col) / 2) % COLOURS.len()],
320 );
321 }
322 }
323 }
324 }More examples
77 fn paint(&mut self, ctx: &mut PaintCtx, data: &String, env: &Env) {
78 // Clear the whole widget with the color of your choice
79 // (ctx.size() returns the size of the layout rect we're painting in)
80 // Note: ctx also has a `clear` method, but that clears the whole context,
81 // and we only want to clear this widget's area.
82 let size = ctx.size();
83 let rect = size.to_rect();
84 ctx.fill(rect, &Color::WHITE);
85
86 // We can paint with a Z index, this indicates that this code will be run
87 // after the rest of the painting. Painting with z-index is done in order,
88 // so first everything with z-index 1 is painted and then with z-index 2 etc.
89 // As you can see this(red) curve is drawn on top of the green curve
90 ctx.paint_with_z_index(1, move |ctx| {
91 let mut path = BezPath::new();
92 path.move_to((0.0, size.height));
93 path.quad_to((40.0, 50.0), (size.width, 0.0));
94 // Create a color
95 let stroke_color = Color::rgb8(128, 0, 0);
96 // Stroke the path with thickness 1.0
97 ctx.stroke(path, &stroke_color, 5.0);
98 });
99
100 // Create an arbitrary bezier path
101 let mut path = BezPath::new();
102 path.move_to(Point::ORIGIN);
103 path.quad_to((40.0, 50.0), (size.width, size.height));
104 // Create a color
105 let stroke_color = Color::rgb8(0, 128, 0);
106 // Stroke the path with thickness 5.0
107 ctx.stroke(path, &stroke_color, 5.0);
108
109 // Rectangles: the path for practical people
110 let rect = Rect::from_origin_size((10.0, 10.0), (100.0, 100.0));
111 // Note the Color:rgba8 which includes an alpha channel (7F in this case)
112 let fill_color = Color::rgba8(0x00, 0x00, 0x00, 0x7F);
113 ctx.fill(rect, &fill_color);
114
115 // Text is easy; in real use TextLayout should either be stored in the
116 // widget and reused, or a label child widget to manage it all.
117 // This is one way of doing it, you can also use a builder-style way.
118 let mut layout = TextLayout::<String>::from_text(data);
119 layout.set_font(FontDescriptor::new(FontFamily::SERIF).with_size(24.0));
120 layout.set_text_color(fill_color);
121 layout.rebuild_if_needed(ctx.text(), env);
122
123 // Let's rotate our text slightly. First we save our current (default) context:
124 ctx.with_save(|ctx| {
125 // Now we can rotate the context (or set a clip path, for instance):
126 // This makes it so that anything drawn after this (in the closure) is
127 // transformed.
128 // The transformation is in radians, but be aware it transforms the canvas,
129 // not just the part you are drawing. So we draw at (80.0, 40.0) on the rotated
130 // canvas, this is NOT the same position as (80.0, 40.0) on the original canvas.
131 ctx.transform(Affine::rotate(std::f64::consts::FRAC_PI_4));
132 layout.draw(ctx, (80.0, 40.0));
133 });
134 // When we exit with_save, the original context's rotation is restored
135
136 // This is the builder-style way of drawing text.
137 let text = ctx.text();
138 let layout = text
139 .new_text_layout(data.clone())
140 .font(FontFamily::SERIF, 24.0)
141 .text_color(Color::rgb8(128, 0, 0))
142 .build()
143 .unwrap();
144 ctx.draw_text(&layout, (100.0, 25.0));
145
146 // Let's burn some CPU to make a (partially transparent) image buffer
147 let image_data = make_image_data(256, 256);
148 let image = ctx
149 .make_image(256, 256, &image_data, ImageFormat::RgbaSeparate)
150 .unwrap();
151 // The image is automatically scaled to fit the rect you pass to draw_image
152 ctx.draw_image(&image, size.to_rect(), InterpolationMode::Bilinear);
153 }Sourcepub fn from_center_size(center: impl Into<Point>, size: impl Into<Size>) -> Rect
pub fn from_center_size(center: impl Into<Point>, size: impl Into<Size>) -> Rect
A new rectangle from center and size.
Sourcepub fn with_origin(self, origin: impl Into<Point>) -> Rect
pub fn with_origin(self, origin: impl Into<Point>) -> Rect
Create a new Rect with the same size as self and a new origin.
Sourcepub fn with_size(self, size: impl Into<Size>) -> Rect
pub fn with_size(self, size: impl Into<Size>) -> Rect
Create a new Rect with the same origin as self and a new size.
Sourcepub fn inset(self, insets: impl Into<Insets>) -> Rect
pub fn inset(self, insets: impl Into<Insets>) -> Rect
Create a new Rect by applying the Insets.
This will not preserve negative width and height.
§Examples
use kurbo::Rect;
let inset_rect = Rect::new(0., 0., 10., 10.,).inset(2.);
assert_eq!(inset_rect.width(), 14.0);
assert_eq!(inset_rect.x0, -2.0);
assert_eq!(inset_rect.x1, 12.0);Examples found in repository?
121fn op_button_label(op: char, label: String) -> impl Widget<CalcState> {
122 let painter = Painter::new(|ctx, _, env| {
123 let bounds = ctx.size().to_rect();
124
125 ctx.fill(bounds, &env.get(theme::PRIMARY_DARK));
126
127 if ctx.is_hot() {
128 ctx.stroke(bounds.inset(-0.5), &Color::WHITE, 1.0);
129 }
130
131 if ctx.is_active() {
132 ctx.fill(bounds, &env.get(theme::PRIMARY_LIGHT));
133 }
134 });
135
136 Label::new(label)
137 .with_text_size(24.)
138 .center()
139 .background(painter)
140 .expand()
141 .on_click(move |_ctx, data: &mut CalcState, _env| data.op(op))
142}
143
144fn op_button(op: char) -> impl Widget<CalcState> {
145 op_button_label(op, op.to_string())
146}
147
148fn digit_button(digit: u8) -> impl Widget<CalcState> {
149 let painter = Painter::new(|ctx, _, env| {
150 let bounds = ctx.size().to_rect();
151
152 ctx.fill(bounds, &env.get(theme::BACKGROUND_LIGHT));
153
154 if ctx.is_hot() {
155 ctx.stroke(bounds.inset(-0.5), &Color::WHITE, 1.0);
156 }
157
158 if ctx.is_active() {
159 ctx.fill(bounds, &Color::rgb8(0x71, 0x71, 0x71));
160 }
161 });
162
163 Label::new(format!("{digit}"))
164 .with_text_size(24.)
165 .center()
166 .background(painter)
167 .expand()
168 .on_click(move |_ctx, data: &mut CalcState, _env| data.digit(digit))
169}Sourcepub fn width(&self) -> f64
pub fn width(&self) -> f64
The width of the rectangle.
Note: nothing forbids negative width.
Examples found in repository?
274 fn paint(&mut self, ctx: &mut PaintCtx, _data: &(), env: &Env) {
275 let sz = ctx.size();
276
277 let monitors = Screen::get_monitors();
278 let all = monitors
279 .iter()
280 .map(|x| x.virtual_rect())
281 .fold(Rect::ZERO, |s, r| r.union(s));
282 if all.width() > 0. && all.height() > 0. {
283 let trans = Affine::scale(f64::min(sz.width / all.width(), sz.height / all.height()))
284 * Affine::translate(all.origin().to_vec2()).inverse();
285 let font = env.get(theme::UI_FONT).family;
286
287 for (i, mon) in monitors.iter().enumerate() {
288 let vr = mon.virtual_rect();
289 let tr = trans.transform_rect_bbox(vr);
290 ctx.stroke(tr, &Color::WHITE, 1.0);
291
292 if let Ok(tl) = ctx
293 .text()
294 .new_text_layout(format!(
295 "{}:{}x{}@{},{}",
296 i,
297 vr.width(),
298 vr.height(),
299 vr.x0,
300 vr.y0
301 ))
302 .max_width(tr.width() - 5.)
303 .font(font.clone(), env.get(theme::TEXT_SIZE_NORMAL))
304 .text_color(Color::WHITE)
305 .build()
306 {
307 ctx.draw_text(&tl, tr.center() - tl.size().to_vec2() * 0.5);
308 }
309 }
310 }
311 }More examples
62fn build_root_widget() -> impl Widget<HelloState> {
63 // Draw red circle, and two semi-transparent rectangles
64 let circle_and_rects = Painter::new(|ctx, _data, _env| {
65 let boundaries = ctx.size().to_rect();
66 let center = (boundaries.width() / 2., boundaries.height() / 2.);
67 let circle = Circle::new(center, center.0.min(center.1));
68 ctx.fill(circle, &Color::RED);
69
70 let rect1 = Rect::new(0., 0., boundaries.width() / 2., boundaries.height() / 2.);
71 ctx.fill(rect1, &Color::rgba8(0x0, 0xff, 0, 125));
72
73 let rect2 = Rect::new(
74 boundaries.width() / 2.,
75 boundaries.height() / 2.,
76 boundaries.width(),
77 boundaries.height(),
78 );
79 ctx.fill(rect2, &Color::rgba8(0x0, 0x0, 0xff, 125));
80 });
81
82 // This textbox modifies the label, idea here is to test that the background
83 // invalidation works when you type to the textbox
84 let textbox = TextBox::new()
85 .with_placeholder("Type to test clearing")
86 .with_text_size(18.0)
87 .lens(HelloState::name)
88 .fix_width(250.);
89
90 let label = Label::new(|data: &HelloState, _env: &Env| {
91 if data.name.is_empty() {
92 "Text: ".to_string()
93 } else {
94 format!("Text: {}!", data.name)
95 }
96 })
97 .with_text_color(Color::RED)
98 .with_text_size(32.0);
99
100 Flex::column()
101 .with_flex_child(circle_and_rects.expand().controller(DragController), 10.0)
102 .with_spacer(4.0)
103 .with_child(textbox)
104 .with_spacer(4.0)
105 .with_child(label)
106}31fn build_app() -> impl Widget<()> {
32 let gradient = LinearGradient::new(
33 UnitPoint::TOP_LEFT,
34 UnitPoint::BOTTOM_RIGHT,
35 (DARKER_GREY, LIGHTER_GREY),
36 );
37
38 // a custom background
39 let polka_dots = Painter::new(|ctx, _, _| {
40 let bounds = ctx.size().to_rect();
41 let dot_diam = bounds.width().max(bounds.height()) / 20.;
42 let dot_spacing = dot_diam * 1.8;
43 for y in 0..((bounds.height() / dot_diam).ceil() as usize) {
44 for x in 0..((bounds.width() / dot_diam).ceil() as usize) {
45 let x_offset = (y % 2) as f64 * (dot_spacing / 2.0);
46 let x = x as f64 * dot_spacing + x_offset;
47 let y = y as f64 * dot_spacing;
48 let circ = Circle::new((x, y), dot_diam / 2.0);
49 let purp = Color::rgb(1.0, 0.22, 0.76);
50 ctx.fill(circ, &purp);
51 }
52 }
53 });
54
55 Flex::column()
56 .with_flex_child(
57 Flex::row()
58 .with_flex_child(
59 Label::new("top left")
60 .center()
61 .border(DARK_GREY, 4.0)
62 .padding(10.0),
63 1.0,
64 )
65 .with_flex_child(
66 Label::new("top right")
67 .center()
68 .background(DARK_GREY)
69 .padding(10.0),
70 1.0,
71 ),
72 1.0,
73 )
74 .with_flex_child(
75 Flex::row()
76 .with_flex_child(
77 Label::new("bottom left")
78 .center()
79 .background(gradient)
80 .rounded(10.0)
81 .padding(10.0),
82 1.0,
83 )
84 .with_flex_child(
85 Label::new("bottom right")
86 .center()
87 .border(LIGHTER_GREY, 4.0)
88 .background(polka_dots)
89 .rounded(10.0)
90 .padding(10.0),
91 1.0,
92 ),
93 1.0,
94 )
95}Sourcepub fn height(&self) -> f64
pub fn height(&self) -> f64
The height of the rectangle.
Note: nothing forbids negative height.
Examples found in repository?
274 fn paint(&mut self, ctx: &mut PaintCtx, _data: &(), env: &Env) {
275 let sz = ctx.size();
276
277 let monitors = Screen::get_monitors();
278 let all = monitors
279 .iter()
280 .map(|x| x.virtual_rect())
281 .fold(Rect::ZERO, |s, r| r.union(s));
282 if all.width() > 0. && all.height() > 0. {
283 let trans = Affine::scale(f64::min(sz.width / all.width(), sz.height / all.height()))
284 * Affine::translate(all.origin().to_vec2()).inverse();
285 let font = env.get(theme::UI_FONT).family;
286
287 for (i, mon) in monitors.iter().enumerate() {
288 let vr = mon.virtual_rect();
289 let tr = trans.transform_rect_bbox(vr);
290 ctx.stroke(tr, &Color::WHITE, 1.0);
291
292 if let Ok(tl) = ctx
293 .text()
294 .new_text_layout(format!(
295 "{}:{}x{}@{},{}",
296 i,
297 vr.width(),
298 vr.height(),
299 vr.x0,
300 vr.y0
301 ))
302 .max_width(tr.width() - 5.)
303 .font(font.clone(), env.get(theme::TEXT_SIZE_NORMAL))
304 .text_color(Color::WHITE)
305 .build()
306 {
307 ctx.draw_text(&tl, tr.center() - tl.size().to_vec2() * 0.5);
308 }
309 }
310 }
311 }More examples
62fn build_root_widget() -> impl Widget<HelloState> {
63 // Draw red circle, and two semi-transparent rectangles
64 let circle_and_rects = Painter::new(|ctx, _data, _env| {
65 let boundaries = ctx.size().to_rect();
66 let center = (boundaries.width() / 2., boundaries.height() / 2.);
67 let circle = Circle::new(center, center.0.min(center.1));
68 ctx.fill(circle, &Color::RED);
69
70 let rect1 = Rect::new(0., 0., boundaries.width() / 2., boundaries.height() / 2.);
71 ctx.fill(rect1, &Color::rgba8(0x0, 0xff, 0, 125));
72
73 let rect2 = Rect::new(
74 boundaries.width() / 2.,
75 boundaries.height() / 2.,
76 boundaries.width(),
77 boundaries.height(),
78 );
79 ctx.fill(rect2, &Color::rgba8(0x0, 0x0, 0xff, 125));
80 });
81
82 // This textbox modifies the label, idea here is to test that the background
83 // invalidation works when you type to the textbox
84 let textbox = TextBox::new()
85 .with_placeholder("Type to test clearing")
86 .with_text_size(18.0)
87 .lens(HelloState::name)
88 .fix_width(250.);
89
90 let label = Label::new(|data: &HelloState, _env: &Env| {
91 if data.name.is_empty() {
92 "Text: ".to_string()
93 } else {
94 format!("Text: {}!", data.name)
95 }
96 })
97 .with_text_color(Color::RED)
98 .with_text_size(32.0);
99
100 Flex::column()
101 .with_flex_child(circle_and_rects.expand().controller(DragController), 10.0)
102 .with_spacer(4.0)
103 .with_child(textbox)
104 .with_spacer(4.0)
105 .with_child(label)
106}31fn build_app() -> impl Widget<()> {
32 let gradient = LinearGradient::new(
33 UnitPoint::TOP_LEFT,
34 UnitPoint::BOTTOM_RIGHT,
35 (DARKER_GREY, LIGHTER_GREY),
36 );
37
38 // a custom background
39 let polka_dots = Painter::new(|ctx, _, _| {
40 let bounds = ctx.size().to_rect();
41 let dot_diam = bounds.width().max(bounds.height()) / 20.;
42 let dot_spacing = dot_diam * 1.8;
43 for y in 0..((bounds.height() / dot_diam).ceil() as usize) {
44 for x in 0..((bounds.width() / dot_diam).ceil() as usize) {
45 let x_offset = (y % 2) as f64 * (dot_spacing / 2.0);
46 let x = x as f64 * dot_spacing + x_offset;
47 let y = y as f64 * dot_spacing;
48 let circ = Circle::new((x, y), dot_diam / 2.0);
49 let purp = Color::rgb(1.0, 0.22, 0.76);
50 ctx.fill(circ, &purp);
51 }
52 }
53 });
54
55 Flex::column()
56 .with_flex_child(
57 Flex::row()
58 .with_flex_child(
59 Label::new("top left")
60 .center()
61 .border(DARK_GREY, 4.0)
62 .padding(10.0),
63 1.0,
64 )
65 .with_flex_child(
66 Label::new("top right")
67 .center()
68 .background(DARK_GREY)
69 .padding(10.0),
70 1.0,
71 ),
72 1.0,
73 )
74 .with_flex_child(
75 Flex::row()
76 .with_flex_child(
77 Label::new("bottom left")
78 .center()
79 .background(gradient)
80 .rounded(10.0)
81 .padding(10.0),
82 1.0,
83 )
84 .with_flex_child(
85 Label::new("bottom right")
86 .center()
87 .border(LIGHTER_GREY, 4.0)
88 .background(polka_dots)
89 .rounded(10.0)
90 .padding(10.0),
91 1.0,
92 ),
93 1.0,
94 )
95}Sourcepub fn origin(&self) -> Point
pub fn origin(&self) -> Point
The origin of the rectangle.
This is the top left corner in a y-down space and with non-negative width and height.
Examples found in repository?
274 fn paint(&mut self, ctx: &mut PaintCtx, _data: &(), env: &Env) {
275 let sz = ctx.size();
276
277 let monitors = Screen::get_monitors();
278 let all = monitors
279 .iter()
280 .map(|x| x.virtual_rect())
281 .fold(Rect::ZERO, |s, r| r.union(s));
282 if all.width() > 0. && all.height() > 0. {
283 let trans = Affine::scale(f64::min(sz.width / all.width(), sz.height / all.height()))
284 * Affine::translate(all.origin().to_vec2()).inverse();
285 let font = env.get(theme::UI_FONT).family;
286
287 for (i, mon) in monitors.iter().enumerate() {
288 let vr = mon.virtual_rect();
289 let tr = trans.transform_rect_bbox(vr);
290 ctx.stroke(tr, &Color::WHITE, 1.0);
291
292 if let Ok(tl) = ctx
293 .text()
294 .new_text_layout(format!(
295 "{}:{}x{}@{},{}",
296 i,
297 vr.width(),
298 vr.height(),
299 vr.x0,
300 vr.y0
301 ))
302 .max_width(tr.width() - 5.)
303 .font(font.clone(), env.get(theme::TEXT_SIZE_NORMAL))
304 .text_color(Color::WHITE)
305 .build()
306 {
307 ctx.draw_text(&tl, tr.center() - tl.size().to_vec2() * 0.5);
308 }
309 }
310 }
311 }Sourcepub fn size(&self) -> Size
pub fn size(&self) -> Size
The size of the rectangle.
Examples found in repository?
More examples
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether this rectangle has zero area.
Note: a rectangle with negative area is not considered empty.
Sourcepub fn center(&self) -> Point
pub fn center(&self) -> Point
The center point of the rectangle.
Examples found in repository?
More examples
274 fn paint(&mut self, ctx: &mut PaintCtx, _data: &(), env: &Env) {
275 let sz = ctx.size();
276
277 let monitors = Screen::get_monitors();
278 let all = monitors
279 .iter()
280 .map(|x| x.virtual_rect())
281 .fold(Rect::ZERO, |s, r| r.union(s));
282 if all.width() > 0. && all.height() > 0. {
283 let trans = Affine::scale(f64::min(sz.width / all.width(), sz.height / all.height()))
284 * Affine::translate(all.origin().to_vec2()).inverse();
285 let font = env.get(theme::UI_FONT).family;
286
287 for (i, mon) in monitors.iter().enumerate() {
288 let vr = mon.virtual_rect();
289 let tr = trans.transform_rect_bbox(vr);
290 ctx.stroke(tr, &Color::WHITE, 1.0);
291
292 if let Ok(tl) = ctx
293 .text()
294 .new_text_layout(format!(
295 "{}:{}x{}@{},{}",
296 i,
297 vr.width(),
298 vr.height(),
299 vr.x0,
300 vr.y0
301 ))
302 .max_width(tr.width() - 5.)
303 .font(font.clone(), env.get(theme::TEXT_SIZE_NORMAL))
304 .text_color(Color::WHITE)
305 .build()
306 {
307 ctx.draw_text(&tl, tr.center() - tl.size().to_vec2() * 0.5);
308 }
309 }
310 }
311 }Sourcepub fn abs(&self) -> Rect
pub fn abs(&self) -> Rect
Take absolute value of width and height.
The resulting rect has the same extents as the original, but is guaranteed to have non-negative width and height.
Sourcepub fn union(&self, other: Rect) -> Rect
pub fn union(&self, other: Rect) -> Rect
The smallest rectangle enclosing two rectangles.
Results are valid only if width and height are non-negative.
Examples found in repository?
274 fn paint(&mut self, ctx: &mut PaintCtx, _data: &(), env: &Env) {
275 let sz = ctx.size();
276
277 let monitors = Screen::get_monitors();
278 let all = monitors
279 .iter()
280 .map(|x| x.virtual_rect())
281 .fold(Rect::ZERO, |s, r| r.union(s));
282 if all.width() > 0. && all.height() > 0. {
283 let trans = Affine::scale(f64::min(sz.width / all.width(), sz.height / all.height()))
284 * Affine::translate(all.origin().to_vec2()).inverse();
285 let font = env.get(theme::UI_FONT).family;
286
287 for (i, mon) in monitors.iter().enumerate() {
288 let vr = mon.virtual_rect();
289 let tr = trans.transform_rect_bbox(vr);
290 ctx.stroke(tr, &Color::WHITE, 1.0);
291
292 if let Ok(tl) = ctx
293 .text()
294 .new_text_layout(format!(
295 "{}:{}x{}@{},{}",
296 i,
297 vr.width(),
298 vr.height(),
299 vr.x0,
300 vr.y0
301 ))
302 .max_width(tr.width() - 5.)
303 .font(font.clone(), env.get(theme::TEXT_SIZE_NORMAL))
304 .text_color(Color::WHITE)
305 .build()
306 {
307 ctx.draw_text(&tl, tr.center() - tl.size().to_vec2() * 0.5);
308 }
309 }
310 }
311 }Sourcepub fn union_pt(&self, pt: Point) -> Rect
pub fn union_pt(&self, pt: Point) -> Rect
Compute the union with one point.
This method includes the perimeter of zero-area rectangles.
Thus, a succession of union_pt operations on a series of
points yields their enclosing rectangle.
Results are valid only if width and height are non-negative.
Sourcepub fn intersect(&self, other: Rect) -> Rect
pub fn intersect(&self, other: Rect) -> Rect
The intersection of two rectangles.
The result is zero-area if either input has negative width or height. The result always has non-negative width and height.
Sourcepub fn inflate(&self, width: f64, height: f64) -> Rect
pub fn inflate(&self, width: f64, height: f64) -> Rect
Expand a rectangle by a constant amount in both directions.
The logic simply applies the amount in each direction. If rectangle area or added dimensions are negative, this could give odd results.
Sourcepub fn round(self) -> Rect
pub fn round(self) -> Rect
Returns a new Rect,
with each coordinate value rounded to the nearest integer.
§Examples
use kurbo::Rect;
let rect = Rect::new(3.3, 3.6, 3.0, -3.1).round();
assert_eq!(rect.x0, 3.0);
assert_eq!(rect.y0, 4.0);
assert_eq!(rect.x1, 3.0);
assert_eq!(rect.y1, -3.0);Sourcepub fn ceil(self) -> Rect
pub fn ceil(self) -> Rect
Returns a new Rect,
with each coordinate value rounded up to the nearest integer,
unless they are already an integer.
§Examples
use kurbo::Rect;
let rect = Rect::new(3.3, 3.6, 3.0, -3.1).ceil();
assert_eq!(rect.x0, 4.0);
assert_eq!(rect.y0, 4.0);
assert_eq!(rect.x1, 3.0);
assert_eq!(rect.y1, -3.0);Sourcepub fn floor(self) -> Rect
pub fn floor(self) -> Rect
Returns a new Rect,
with each coordinate value rounded down to the nearest integer,
unless they are already an integer.
§Examples
use kurbo::Rect;
let rect = Rect::new(3.3, 3.6, 3.0, -3.1).floor();
assert_eq!(rect.x0, 3.0);
assert_eq!(rect.y0, 3.0);
assert_eq!(rect.x1, 3.0);
assert_eq!(rect.y1, -4.0);Sourcepub fn expand(self) -> Rect
pub fn expand(self) -> Rect
Returns a new Rect,
with each coordinate value rounded away from the center of the Rect
to the nearest integer, unless they are already an integer.
That is to say this function will return the smallest possible Rect
with integer coordinates that is a superset of self.
§Examples
use kurbo::Rect;
// In positive space
let rect = Rect::new(3.3, 3.6, 5.6, 4.1).expand();
assert_eq!(rect.x0, 3.0);
assert_eq!(rect.y0, 3.0);
assert_eq!(rect.x1, 6.0);
assert_eq!(rect.y1, 5.0);
// In both positive and negative space
let rect = Rect::new(-3.3, -3.6, 5.6, 4.1).expand();
assert_eq!(rect.x0, -4.0);
assert_eq!(rect.y0, -4.0);
assert_eq!(rect.x1, 6.0);
assert_eq!(rect.y1, 5.0);
// In negative space
let rect = Rect::new(-5.6, -4.1, -3.3, -3.6).expand();
assert_eq!(rect.x0, -6.0);
assert_eq!(rect.y0, -5.0);
assert_eq!(rect.x1, -3.0);
assert_eq!(rect.y1, -3.0);
// Inverse orientation
let rect = Rect::new(5.6, -3.6, 3.3, -4.1).expand();
assert_eq!(rect.x0, 6.0);
assert_eq!(rect.y0, -3.0);
assert_eq!(rect.x1, 3.0);
assert_eq!(rect.y1, -5.0);Sourcepub fn trunc(self) -> Rect
pub fn trunc(self) -> Rect
Returns a new Rect,
with each coordinate value rounded towards the center of the Rect
to the nearest integer, unless they are already an integer.
That is to say this function will return the biggest possible Rect
with integer coordinates that is a subset of self.
§Examples
use kurbo::Rect;
// In positive space
let rect = Rect::new(3.3, 3.6, 5.6, 4.1).trunc();
assert_eq!(rect.x0, 4.0);
assert_eq!(rect.y0, 4.0);
assert_eq!(rect.x1, 5.0);
assert_eq!(rect.y1, 4.0);
// In both positive and negative space
let rect = Rect::new(-3.3, -3.6, 5.6, 4.1).trunc();
assert_eq!(rect.x0, -3.0);
assert_eq!(rect.y0, -3.0);
assert_eq!(rect.x1, 5.0);
assert_eq!(rect.y1, 4.0);
// In negative space
let rect = Rect::new(-5.6, -4.1, -3.3, -3.6).trunc();
assert_eq!(rect.x0, -5.0);
assert_eq!(rect.y0, -4.0);
assert_eq!(rect.x1, -4.0);
assert_eq!(rect.y1, -4.0);
// Inverse orientation
let rect = Rect::new(5.6, -3.6, 3.3, -4.1).trunc();
assert_eq!(rect.x0, 5.0);
assert_eq!(rect.y0, -4.0);
assert_eq!(rect.x1, 4.0);
assert_eq!(rect.y1, -4.0);Sourcepub fn scale_from_origin(self, factor: f64) -> Rect
pub fn scale_from_origin(self, factor: f64) -> Rect
Scales the Rect by factor with respect to the origin (the point (0, 0)).
§Examples
use kurbo::Rect;
let rect = Rect::new(2., 2., 4., 6.).scale_from_origin(2.);
assert_eq!(rect.x0, 4.);
assert_eq!(rect.x1, 8.);Sourcepub fn to_rounded_rect(self, radii: impl Into<RoundedRectRadii>) -> RoundedRect
pub fn to_rounded_rect(self, radii: impl Into<RoundedRectRadii>) -> RoundedRect
Creates a new RoundedRect from this Rect and the provided
corner radius.
Sourcepub fn to_ellipse(self) -> Ellipse
pub fn to_ellipse(self) -> Ellipse
Returns the Ellipse that is bounded by this Rect.
Sourcepub fn aspect_ratio(&self) -> f64
pub fn aspect_ratio(&self) -> f64
The aspect ratio of the Rect.
This is defined as the height divided by the width. It measures the
“squareness” of the rectangle (a value of 1 is square).
If the width is 0 the output will be sign(y1 - y0) * infinity.
If The width and height are 0, the result will be NaN.
Sourcepub fn contained_rect_with_aspect_ratio(&self, aspect_ratio: f64) -> Rect
pub fn contained_rect_with_aspect_ratio(&self, aspect_ratio: f64) -> Rect
Returns the largest possible Rect that is fully contained in self
with the given aspect_ratio.
The aspect ratio is specified fractionally, as height / width.
The resulting rectangle will be centered if it is smaller than the input rectangle.
For the special case where the aspect ratio is 1.0, the resulting
Rect will be square.
§Examples
let outer = Rect::new(0.0, 0.0, 10.0, 20.0);
let inner = outer.contained_rect_with_aspect_ratio(1.0);
// The new `Rect` is a square centered at the center of `outer`.
assert_eq!(inner, Rect::new(0.0, 5.0, 10.0, 15.0));Trait Implementations§
Source§impl Mul<Rect> for TranslateScale
impl Mul<Rect> for TranslateScale
Source§impl Scalable for Rect
impl Scalable for Rect
Source§impl Shape for Rect
impl Shape for Rect
Source§fn winding(&self, pt: Point) -> i32
fn winding(&self, pt: Point) -> i32
Note: this function is carefully designed so that if the plane is tiled with rectangles, the winding number will be nonzero for exactly one of them.
Source§type PathElementsIter<'iter> = RectPathIter
type PathElementsIter<'iter> = RectPathIter
path_elements method.Source§fn path_elements(&self, _tolerance: f64) -> RectPathIter
fn path_elements(&self, _tolerance: f64) -> RectPathIter
Source§fn bounding_box(&self) -> Rect
fn bounding_box(&self) -> Rect
Source§fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter<'_>> ⓘ
fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter<'_>> ⓘ
Source§fn as_rounded_rect(&self) -> Option<RoundedRect>
fn as_rounded_rect(&self) -> Option<RoundedRect>
Source§impl ValueType for Rect
impl ValueType for Rect
Source§fn try_from_value(value: &Value) -> Result<Self, ValueTypeError>
fn try_from_value(value: &Value) -> Result<Self, ValueTypeError>
Value into this type.