Struct Point

Source
pub struct Point {
    pub x: f64,
    pub y: f64,
}
Expand description

A 2D point.

This type represents a point in 2D space. It has the same layout as Vec2, but its meaning is different: Vec2 represents a change in location (for example velocity).

In general, kurbo overloads math operators where it makes sense, for example implementing Affine * Point as the point under the affine transformation. However Point + Point and f64 * Point are not implemented, because the operations do not make geometric sense. If you need to apply these operations, then 1) check what you’re doing makes geometric sense, then 2) use Point::to_vec2 to convert the point to a Vec2.

Fields§

§x: f64

The x coordinate.

§y: f64

The y coordinate.

Implementations§

Source§

impl Point

Source

pub const ZERO: Point

The point (0, 0).

Source

pub const ORIGIN: Point

The point at the origin; (0, 0).

Source

pub const fn new(x: f64, y: f64) -> Point

Create a new Point with the provided x and y coordinates.

Examples found in repository?
examples/anim.rs (line 76)
74    fn paint(&mut self, ctx: &mut PaintCtx, _data: &(), _env: &Env) {
75        let t = self.t;
76        let center = Point::new(50.0, 50.0);
77        ctx.paint_with_z_index(1, move |ctx| {
78            let ambit = center + 45.0 * Vec2::from_angle((0.75 + t) * 2.0 * PI);
79            ctx.stroke(Line::new(center, ambit), &Color::WHITE, 1.0);
80        });
81
82        ctx.fill(Circle::new(center, 50.0), &Color::BLACK);
83    }
More examples
Hide additional examples
examples/input_region.rs (line 136)
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    }
Source

pub const fn to_vec2(self) -> Vec2

Convert this point into a Vec2.

Examples found in repository?
examples/sub_window.rs (line 147)
99    fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
100        let wait_duration = Duration::from_millis(500);
101        let resched_dur = Duration::from_millis(50);
102        let cursor_size = Size::new(15., 15.);
103        let now = Instant::now();
104        let new_state = match &self.state {
105            TooltipState::Fresh => match event {
106                Event::MouseMove(me) if ctx.is_hot() => Some(TooltipState::Waiting {
107                    last_move: now,
108                    timer_expire: now + wait_duration,
109                    token: ctx.request_timer(wait_duration),
110                    position_in_window_coordinates: me.window_pos,
111                }),
112                _ => None,
113            },
114            TooltipState::Waiting {
115                last_move,
116                timer_expire,
117                token,
118                position_in_window_coordinates,
119            } => match event {
120                Event::MouseMove(me) if ctx.is_hot() => {
121                    let (cur_token, cur_expire) = if *timer_expire - now < resched_dur {
122                        (ctx.request_timer(wait_duration), now + wait_duration)
123                    } else {
124                        (*token, *timer_expire)
125                    };
126                    Some(TooltipState::Waiting {
127                        last_move: now,
128                        timer_expire: cur_expire,
129                        token: cur_token,
130                        position_in_window_coordinates: me.window_pos,
131                    })
132                }
133                Event::Timer(tok) if tok == token => {
134                    let deadline = *last_move + wait_duration;
135                    ctx.set_handled();
136                    if deadline > now {
137                        let wait_for = deadline - now;
138                        tracing::info!("Waiting another {:?}", wait_for);
139                        Some(TooltipState::Waiting {
140                            last_move: *last_move,
141                            timer_expire: deadline,
142                            token: ctx.request_timer(wait_for),
143                            position_in_window_coordinates: *position_in_window_coordinates,
144                        })
145                    } else {
146                        let tooltip_position_in_window_coordinates =
147                            (position_in_window_coordinates.to_vec2() + cursor_size.to_vec2())
148                                .to_point();
149                        let win_id = ctx.new_sub_window(
150                            WindowConfig::default()
151                                .show_titlebar(false)
152                                .window_size_policy(WindowSizePolicy::Content)
153                                .set_level(WindowLevel::Tooltip(ctx.window().clone()))
154                                .set_position(tooltip_position_in_window_coordinates),
155                            Label::<()>::new(self.tip.clone()),
156                            (),
157                            env.clone(),
158                        );
159                        Some(TooltipState::Showing(win_id))
160                    }
161                }
162                _ => None,
163            },
164            TooltipState::Showing(win_id) => {
165                match event {
166                    Event::MouseMove(me) if !ctx.is_hot() => {
167                        // TODO another timer on leaving
168                        tracing::info!("Sending close window for {:?}", win_id);
169                        ctx.submit_command(CLOSE_WINDOW.to(*win_id));
170                        Some(TooltipState::Waiting {
171                            last_move: now,
172                            timer_expire: now + wait_duration,
173                            token: ctx.request_timer(wait_duration),
174                            position_in_window_coordinates: me.window_pos,
175                        })
176                    }
177                    _ => None,
178                }
179            }
180        };
181
182        if let Some(state) = new_state {
183            self.state = state;
184        }
185
186        if !ctx.is_handled() {
187            child.event(ctx, event, data, env);
188        }
189    }
190
191    fn lifecycle(
192        &mut self,
193        child: &mut W,
194        ctx: &mut LifeCycleCtx,
195        event: &LifeCycle,
196        data: &T,
197        env: &Env,
198    ) {
199        if let LifeCycle::HotChanged(false) = event {
200            if let TooltipState::Showing(win_id) = self.state {
201                ctx.submit_command(CLOSE_WINDOW.to(win_id));
202            }
203            self.state = TooltipState::Fresh;
204        }
205        child.lifecycle(ctx, event, data, env)
206    }
207}
208
209struct DragWindowController {
210    init_pos: Option<Point>,
211    //dragging: bool
212}
213
214impl DragWindowController {
215    pub fn new() -> Self {
216        DragWindowController { init_pos: None }
217    }
218}
219
220impl<T, W: Widget<T>> Controller<T, W> for DragWindowController {
221    fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
222        match event {
223            Event::MouseDown(me) if me.buttons.has_left() => {
224                ctx.set_active(true);
225                self.init_pos = Some(me.window_pos)
226            }
227            Event::MouseMove(me) if ctx.is_active() && me.buttons.has_left() => {
228                if let Some(init_pos) = self.init_pos {
229                    let within_window_change = me.window_pos.to_vec2() - init_pos.to_vec2();
230                    let old_pos = ctx.window().get_position();
231                    let new_pos = old_pos + within_window_change;
232                    tracing::info!(
233                        "Drag {:?} ",
234                        (
235                            init_pos,
236                            me.window_pos,
237                            within_window_change,
238                            old_pos,
239                            new_pos
240                        )
241                    );
242                    ctx.window().set_position(new_pos)
243                }
244            }
245            Event::MouseUp(_me) if ctx.is_active() => {
246                self.init_pos = None;
247                ctx.set_active(false)
248            }
249            _ => (),
250        }
251        child.event(ctx, event, data, env)
252    }
253}
254
255struct ScreenThing;
256
257impl Widget<()> for ScreenThing {
258    fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut (), _env: &Env) {}
259
260    fn lifecycle(&mut self, _ctx: &mut LifeCycleCtx, _event: &LifeCycle, _data: &(), _env: &Env) {}
261
262    fn update(&mut self, _ctx: &mut UpdateCtx, _old_data: &(), _data: &(), _env: &Env) {}
263
264    fn layout(
265        &mut self,
266        _ctx: &mut LayoutCtx,
267        bc: &BoxConstraints,
268        _data: &(),
269        _env: &Env,
270    ) -> Size {
271        bc.constrain(Size::new(800.0, 600.0))
272    }
273
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    }
Source

pub fn lerp(self, other: Point, t: f64) -> Point

Linearly interpolate between two points.

Source

pub fn midpoint(self, other: Point) -> Point

Determine the midpoint of two points.

Source

pub fn distance(self, other: Point) -> f64

Euclidean distance.

Source

pub fn distance_squared(self, other: Point) -> f64

Squared Euclidean distance.

Source

pub fn round(self) -> Point

Returns a new Point, with x and y rounded to the nearest integer.

§Examples
use kurbo::Point;
let a = Point::new(3.3, 3.6).round();
let b = Point::new(3.0, -3.1).round();
assert_eq!(a.x, 3.0);
assert_eq!(a.y, 4.0);
assert_eq!(b.x, 3.0);
assert_eq!(b.y, -3.0);
Source

pub fn ceil(self) -> Point

Returns a new Point, with x and y rounded up to the nearest integer, unless they are already an integer.

§Examples
use kurbo::Point;
let a = Point::new(3.3, 3.6).ceil();
let b = Point::new(3.0, -3.1).ceil();
assert_eq!(a.x, 4.0);
assert_eq!(a.y, 4.0);
assert_eq!(b.x, 3.0);
assert_eq!(b.y, -3.0);
Source

pub fn floor(self) -> Point

Returns a new Point, with x and y rounded down to the nearest integer, unless they are already an integer.

§Examples
use kurbo::Point;
let a = Point::new(3.3, 3.6).floor();
let b = Point::new(3.0, -3.1).floor();
assert_eq!(a.x, 3.0);
assert_eq!(a.y, 3.0);
assert_eq!(b.x, 3.0);
assert_eq!(b.y, -4.0);
Source

pub fn expand(self) -> Point

Returns a new Point, with x and y rounded away from zero to the nearest integer, unless they are already an integer.

§Examples
use kurbo::Point;
let a = Point::new(3.3, 3.6).expand();
let b = Point::new(3.0, -3.1).expand();
assert_eq!(a.x, 4.0);
assert_eq!(a.y, 4.0);
assert_eq!(b.x, 3.0);
assert_eq!(b.y, -4.0);
Source

pub fn trunc(self) -> Point

Returns a new Point, with x and y rounded towards zero to the nearest integer, unless they are already an integer.

§Examples
use kurbo::Point;
let a = Point::new(3.3, 3.6).trunc();
let b = Point::new(3.0, -3.1).trunc();
assert_eq!(a.x, 3.0);
assert_eq!(a.y, 3.0);
assert_eq!(b.x, 3.0);
assert_eq!(b.y, -3.0);
Source

pub fn is_finite(self) -> bool

Is this point finite?

Source

pub fn is_nan(self) -> bool

Is this point NaN?

Trait Implementations§

Source§

impl Add<(f64, f64)> for Point

Source§

type Output = Point

The resulting type after applying the + operator.
Source§

fn add(self, _: (f64, f64)) -> Point

Performs the + operation. Read more
Source§

impl Add<Vec2> for Point

Source§

type Output = Point

The resulting type after applying the + operator.
Source§

fn add(self, other: Vec2) -> Point

Performs the + operation. Read more
Source§

impl AddAssign<(f64, f64)> for Point

Source§

fn add_assign(&mut self, _: (f64, f64))

Performs the += operation. Read more
Source§

impl AddAssign<Vec2> for Point

Source§

fn add_assign(&mut self, other: Vec2)

Performs the += operation. Read more
Source§

impl Clone for Point

Source§

fn clone(&self) -> Point

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Data for Point

Source§

fn same(&self, other: &Self) -> bool

Determine whether two values are the same. Read more
Source§

impl Debug for Point

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for Point

Source§

fn default() -> Point

Returns the “default value” for a type. Read more
Source§

impl Display for Point

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl From<(f64, f64)> for Point

Source§

fn from(v: (f64, f64)) -> Point

Converts to this type from the input type.
Source§

impl From<Point> for Value

Source§

fn from(val: Point) -> Value

Converts to this type from the input type.
Source§

impl Mul<Point> for Affine

Source§

type Output = Point

The resulting type after applying the * operator.
Source§

fn mul(self, other: Point) -> Point

Performs the * operation. Read more
Source§

impl Mul<Point> for TranslateScale

Source§

type Output = Point

The resulting type after applying the * operator.
Source§

fn mul(self, other: Point) -> Point

Performs the * operation. Read more
Source§

impl PartialEq for Point

Source§

fn eq(&self, other: &Point) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Scalable for Point

Source§

fn to_px(&self, scale: Scale) -> Point

Converts a Point from display points into pixels, using the x axis scale factor for x and the y axis scale factor for y.

Source§

fn to_dp(&self, scale: Scale) -> Point

Converts a Point from pixels into display points, using the x axis scale factor for x and the y axis scale factor for y.

Source§

impl Sub<(f64, f64)> for Point

Source§

type Output = Point

The resulting type after applying the - operator.
Source§

fn sub(self, _: (f64, f64)) -> Point

Performs the - operation. Read more
Source§

impl Sub<Vec2> for Point

Source§

type Output = Point

The resulting type after applying the - operator.
Source§

fn sub(self, other: Vec2) -> Point

Performs the - operation. Read more
Source§

impl Sub for Point

Source§

type Output = Vec2

The resulting type after applying the - operator.
Source§

fn sub(self, other: Point) -> Vec2

Performs the - operation. Read more
Source§

impl SubAssign<(f64, f64)> for Point

Source§

fn sub_assign(&mut self, _: (f64, f64))

Performs the -= operation. Read more
Source§

impl SubAssign<Vec2> for Point

Source§

fn sub_assign(&mut self, other: Vec2)

Performs the -= operation. Read more
Source§

impl ValueType for Point

Source§

fn try_from_value(value: &Value) -> Result<Self, ValueTypeError>

Attempt to convert the generic Value into this type.
Source§

impl Copy for Point

Source§

impl StructuralPartialEq for Point

Auto Trait Implementations§

§

impl Freeze for Point

§

impl RefUnwindSafe for Point

§

impl Send for Point

§

impl Sync for Point

§

impl Unpin for Point

§

impl UnwindSafe for Point

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AnyEq for T
where T: Any + PartialEq,

Source§

fn equals(&self, other: &(dyn Any + 'static)) -> bool

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IsDefault for T
where T: Default + PartialEq + Copy,

Source§

fn is_default(&self) -> bool

Checks that type has a default value.
Source§

impl<T> RoundFrom<T> for T

Source§

fn round_from(x: T) -> T

Performs the conversion.
Source§

impl<T, U> RoundInto<U> for T
where U: RoundFrom<T>,

Source§

fn round_into(self) -> U

Performs the conversion.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more