Expand description
2D vector (double precision)
Usually used as either a coordinate or a difference of coordinates, but may have some other uses.
Vectors are partially ordered and support component-wise comparison via
methods like lhs.lt(rhs)
. The PartialOrd
trait is not implemented since
it implements lhs ≤ rhs
as lhs < rhs || lhs == rhs
which is wrong for
vectors (consider for lhs = (0, 1), rhs = (1, 0)
).
Tuple Fields§
§0: f64
§1: f64
Implementations§
source§impl DVec2
impl DVec2
sourcepub const NEG_INFINITY: DVec2 = _
pub const NEG_INFINITY: DVec2 = _
Negative infinity
sourcepub const fn splat(value: f64) -> Self
pub const fn splat(value: f64) -> Self
Constructs a new instance with each element initialized to value
.
sourcepub fn complex_mul(self, rhs: Self) -> Self
pub fn complex_mul(self, rhs: Self) -> Self
Multiply two vectors as if they are complex numbers
Examples found in repository?
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
pub fn update(&mut self, shell: &mut dyn ShellWindow, widget: &mut dyn Widget) -> TkAction {
let old_hover_icon = self.hover_icon;
let mut mgr = EventMgr {
state: self,
shell,
messages: vec![],
scroll: Scroll::None,
action: TkAction::empty(),
};
while let Some((parent, wid)) = mgr.popup_removed.pop() {
mgr.send_event(widget, parent, Event::PopupRemoved(wid));
}
if let Some((id, event)) = mgr.mouse_grab().and_then(|g| g.flush_move()) {
mgr.send_event(widget, id, event);
}
for i in 0..mgr.touch_grab.len() {
if let Some((id, event)) = mgr.touch_grab[i].flush_move() {
mgr.send_event(widget, id, event);
}
}
for gi in 0..mgr.pan_grab.len() {
let grab = &mut mgr.pan_grab[gi];
debug_assert!(grab.mode != GrabMode::Grab);
assert!(grab.n > 0);
// Terminology: pi are old coordinates, qi are new coords
let (p1, q1) = (DVec2::conv(grab.coords[0].0), DVec2::conv(grab.coords[0].1));
grab.coords[0].0 = grab.coords[0].1;
let alpha;
let delta;
if grab.mode == GrabMode::PanOnly || grab.n == 1 {
alpha = DVec2(1.0, 0.0);
delta = q1 - p1;
} else {
// We don't use more than two touches: information would be
// redundant (although it could be averaged).
let (p2, q2) = (DVec2::conv(grab.coords[1].0), DVec2::conv(grab.coords[1].1));
grab.coords[1].0 = grab.coords[1].1;
let (pd, qd) = (p2 - p1, q2 - q1);
alpha = match grab.mode {
GrabMode::PanFull => qd.complex_div(pd),
GrabMode::PanScale => DVec2((qd.sum_square() / pd.sum_square()).sqrt(), 0.0),
GrabMode::PanRotate => {
let a = qd.complex_div(pd);
a / a.sum_square().sqrt()
}
_ => unreachable!(),
};
// Average delta from both movements:
delta = (q1 - alpha.complex_mul(p1) + q2 - alpha.complex_mul(p2)) * 0.5;
}
let id = grab.id.clone();
if alpha != DVec2(1.0, 0.0) || delta != DVec2::ZERO {
let event = Event::Pan { alpha, delta };
mgr.send_event(widget, id, event);
}
}
// Warning: infinite loops are possible here if widgets always queue a
// new pending event when evaluating one of these:
while let Some(item) = mgr.pending.pop_front() {
log::trace!(target: "kas_core::event::manager", "update: handling Pending::{item:?}");
let (id, event) = match item {
Pending::SetNavFocus(id, key_focus) => (id, Event::NavFocus(key_focus)),
Pending::MouseHover(id) => (id, Event::MouseHover),
Pending::LostNavFocus(id) => (id, Event::LostNavFocus),
Pending::LostMouseHover(id) => {
mgr.hover_icon = Default::default();
(id, Event::LostMouseHover)
}
Pending::LostCharFocus(id) => (id, Event::LostCharFocus),
Pending::LostSelFocus(id) => (id, Event::LostSelFocus),
};
mgr.send_event(widget, id, event);
}
let action = mgr.action;
drop(mgr);
if self.hover_icon != old_hover_icon && self.mouse_grab.is_none() {
shell.set_cursor_icon(self.hover_icon);
}
let action = action | self.action;
self.action = TkAction::empty();
action
}
sourcepub fn complex_div(self, rhs: Self) -> Self
pub fn complex_div(self, rhs: Self) -> Self
Divide by a second vector as if they are complex numbers
Examples found in repository?
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
pub fn update(&mut self, shell: &mut dyn ShellWindow, widget: &mut dyn Widget) -> TkAction {
let old_hover_icon = self.hover_icon;
let mut mgr = EventMgr {
state: self,
shell,
messages: vec![],
scroll: Scroll::None,
action: TkAction::empty(),
};
while let Some((parent, wid)) = mgr.popup_removed.pop() {
mgr.send_event(widget, parent, Event::PopupRemoved(wid));
}
if let Some((id, event)) = mgr.mouse_grab().and_then(|g| g.flush_move()) {
mgr.send_event(widget, id, event);
}
for i in 0..mgr.touch_grab.len() {
if let Some((id, event)) = mgr.touch_grab[i].flush_move() {
mgr.send_event(widget, id, event);
}
}
for gi in 0..mgr.pan_grab.len() {
let grab = &mut mgr.pan_grab[gi];
debug_assert!(grab.mode != GrabMode::Grab);
assert!(grab.n > 0);
// Terminology: pi are old coordinates, qi are new coords
let (p1, q1) = (DVec2::conv(grab.coords[0].0), DVec2::conv(grab.coords[0].1));
grab.coords[0].0 = grab.coords[0].1;
let alpha;
let delta;
if grab.mode == GrabMode::PanOnly || grab.n == 1 {
alpha = DVec2(1.0, 0.0);
delta = q1 - p1;
} else {
// We don't use more than two touches: information would be
// redundant (although it could be averaged).
let (p2, q2) = (DVec2::conv(grab.coords[1].0), DVec2::conv(grab.coords[1].1));
grab.coords[1].0 = grab.coords[1].1;
let (pd, qd) = (p2 - p1, q2 - q1);
alpha = match grab.mode {
GrabMode::PanFull => qd.complex_div(pd),
GrabMode::PanScale => DVec2((qd.sum_square() / pd.sum_square()).sqrt(), 0.0),
GrabMode::PanRotate => {
let a = qd.complex_div(pd);
a / a.sum_square().sqrt()
}
_ => unreachable!(),
};
// Average delta from both movements:
delta = (q1 - alpha.complex_mul(p1) + q2 - alpha.complex_mul(p2)) * 0.5;
}
let id = grab.id.clone();
if alpha != DVec2(1.0, 0.0) || delta != DVec2::ZERO {
let event = Event::Pan { alpha, delta };
mgr.send_event(widget, id, event);
}
}
// Warning: infinite loops are possible here if widgets always queue a
// new pending event when evaluating one of these:
while let Some(item) = mgr.pending.pop_front() {
log::trace!(target: "kas_core::event::manager", "update: handling Pending::{item:?}");
let (id, event) = match item {
Pending::SetNavFocus(id, key_focus) => (id, Event::NavFocus(key_focus)),
Pending::MouseHover(id) => (id, Event::MouseHover),
Pending::LostNavFocus(id) => (id, Event::LostNavFocus),
Pending::LostMouseHover(id) => {
mgr.hover_icon = Default::default();
(id, Event::LostMouseHover)
}
Pending::LostCharFocus(id) => (id, Event::LostCharFocus),
Pending::LostSelFocus(id) => (id, Event::LostSelFocus),
};
mgr.send_event(widget, id, event);
}
let action = mgr.action;
drop(mgr);
if self.hover_icon != old_hover_icon && self.mouse_grab.is_none() {
shell.set_cursor_icon(self.hover_icon);
}
let action = action | self.action;
self.action = TkAction::empty();
action
}
sourcepub fn complex_inv(self) -> Self
pub fn complex_inv(self) -> Self
Take the complex reciprocal
sourcepub fn sum_square(self) -> f64
pub fn sum_square(self) -> f64
Return the sum of the square of the terms
Examples found in repository?
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
pub fn update(&mut self, shell: &mut dyn ShellWindow, widget: &mut dyn Widget) -> TkAction {
let old_hover_icon = self.hover_icon;
let mut mgr = EventMgr {
state: self,
shell,
messages: vec![],
scroll: Scroll::None,
action: TkAction::empty(),
};
while let Some((parent, wid)) = mgr.popup_removed.pop() {
mgr.send_event(widget, parent, Event::PopupRemoved(wid));
}
if let Some((id, event)) = mgr.mouse_grab().and_then(|g| g.flush_move()) {
mgr.send_event(widget, id, event);
}
for i in 0..mgr.touch_grab.len() {
if let Some((id, event)) = mgr.touch_grab[i].flush_move() {
mgr.send_event(widget, id, event);
}
}
for gi in 0..mgr.pan_grab.len() {
let grab = &mut mgr.pan_grab[gi];
debug_assert!(grab.mode != GrabMode::Grab);
assert!(grab.n > 0);
// Terminology: pi are old coordinates, qi are new coords
let (p1, q1) = (DVec2::conv(grab.coords[0].0), DVec2::conv(grab.coords[0].1));
grab.coords[0].0 = grab.coords[0].1;
let alpha;
let delta;
if grab.mode == GrabMode::PanOnly || grab.n == 1 {
alpha = DVec2(1.0, 0.0);
delta = q1 - p1;
} else {
// We don't use more than two touches: information would be
// redundant (although it could be averaged).
let (p2, q2) = (DVec2::conv(grab.coords[1].0), DVec2::conv(grab.coords[1].1));
grab.coords[1].0 = grab.coords[1].1;
let (pd, qd) = (p2 - p1, q2 - q1);
alpha = match grab.mode {
GrabMode::PanFull => qd.complex_div(pd),
GrabMode::PanScale => DVec2((qd.sum_square() / pd.sum_square()).sqrt(), 0.0),
GrabMode::PanRotate => {
let a = qd.complex_div(pd);
a / a.sum_square().sqrt()
}
_ => unreachable!(),
};
// Average delta from both movements:
delta = (q1 - alpha.complex_mul(p1) + q2 - alpha.complex_mul(p2)) * 0.5;
}
let id = grab.id.clone();
if alpha != DVec2(1.0, 0.0) || delta != DVec2::ZERO {
let event = Event::Pan { alpha, delta };
mgr.send_event(widget, id, event);
}
}
// Warning: infinite loops are possible here if widgets always queue a
// new pending event when evaluating one of these:
while let Some(item) = mgr.pending.pop_front() {
log::trace!(target: "kas_core::event::manager", "update: handling Pending::{item:?}");
let (id, event) = match item {
Pending::SetNavFocus(id, key_focus) => (id, Event::NavFocus(key_focus)),
Pending::MouseHover(id) => (id, Event::MouseHover),
Pending::LostNavFocus(id) => (id, Event::LostNavFocus),
Pending::LostMouseHover(id) => {
mgr.hover_icon = Default::default();
(id, Event::LostMouseHover)
}
Pending::LostCharFocus(id) => (id, Event::LostCharFocus),
Pending::LostSelFocus(id) => (id, Event::LostSelFocus),
};
mgr.send_event(widget, id, event);
}
let action = mgr.action;
drop(mgr);
if self.hover_icon != old_hover_icon && self.mouse_grab.is_none() {
shell.set_cursor_icon(self.hover_icon);
}
let action = action | self.action;
self.action = TkAction::empty();
action
}
sourcepub fn extract<D: Directional>(self, dir: D) -> f64
pub fn extract<D: Directional>(self, dir: D) -> f64
Extract one component, based on a direction
This merely extracts the horizontal or vertical component. It never negates it, even if the axis is reversed.
Trait Implementations§
source§impl AddAssign<DVec2> for DVec2
impl AddAssign<DVec2> for DVec2
source§fn add_assign(&mut self, rhs: DVec2)
fn add_assign(&mut self, rhs: DVec2)
+=
operation. Read moresource§impl AddAssign<f64> for DVec2
impl AddAssign<f64> for DVec2
source§fn add_assign(&mut self, rhs: f64)
fn add_assign(&mut self, rhs: f64)
+=
operation. Read moresource§impl ConvApprox<DVec2> for Coord
impl ConvApprox<DVec2> for Coord
source§fn try_conv_approx(arg: DVec2) -> Result<Self>
fn try_conv_approx(arg: DVec2) -> Result<Self>
source§fn conv_approx(x: T) -> Self
fn conv_approx(x: T) -> Self
source§impl ConvApprox<DVec2> for Offset
impl ConvApprox<DVec2> for Offset
source§fn try_conv_approx(arg: DVec2) -> Result<Self>
fn try_conv_approx(arg: DVec2) -> Result<Self>
source§fn conv_approx(x: T) -> Self
fn conv_approx(x: T) -> Self
source§impl ConvApprox<DVec2> for Size
impl ConvApprox<DVec2> for Size
source§fn try_conv_approx(arg: DVec2) -> Result<Self>
fn try_conv_approx(arg: DVec2) -> Result<Self>
source§fn conv_approx(x: T) -> Self
fn conv_approx(x: T) -> Self
source§impl ConvApprox<DVec2> for Vec2
impl ConvApprox<DVec2> for Vec2
source§impl ConvFloat<DVec2> for Coord
impl ConvFloat<DVec2> for Coord
source§fn try_conv_trunc(x: DVec2) -> Result<Self>
fn try_conv_trunc(x: DVec2) -> Result<Self>
source§fn conv_trunc(x: T) -> Self
fn conv_trunc(x: T) -> Self
source§fn conv_nearest(x: T) -> Self
fn conv_nearest(x: T) -> Self
source§fn conv_floor(x: T) -> Self
fn conv_floor(x: T) -> Self
source§impl ConvFloat<DVec2> for Offset
impl ConvFloat<DVec2> for Offset
source§fn try_conv_trunc(x: DVec2) -> Result<Self>
fn try_conv_trunc(x: DVec2) -> Result<Self>
source§fn conv_trunc(x: T) -> Self
fn conv_trunc(x: T) -> Self
source§fn conv_nearest(x: T) -> Self
fn conv_nearest(x: T) -> Self
source§fn conv_floor(x: T) -> Self
fn conv_floor(x: T) -> Self
source§impl ConvFloat<DVec2> for Size
impl ConvFloat<DVec2> for Size
source§fn try_conv_trunc(x: DVec2) -> Result<Self>
fn try_conv_trunc(x: DVec2) -> Result<Self>
source§fn conv_trunc(x: T) -> Self
fn conv_trunc(x: T) -> Self
source§fn conv_nearest(x: T) -> Self
fn conv_nearest(x: T) -> Self
source§fn conv_floor(x: T) -> Self
fn conv_floor(x: T) -> Self
source§impl<'de> Deserialize<'de> for DVec2
impl<'de> Deserialize<'de> for DVec2
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
source§impl PartialEq<DVec2> for DVec2
impl PartialEq<DVec2> for DVec2
source§impl SubAssign<DVec2> for DVec2
impl SubAssign<DVec2> for DVec2
source§fn sub_assign(&mut self, rhs: DVec2)
fn sub_assign(&mut self, rhs: DVec2)
-=
operation. Read moresource§impl SubAssign<f64> for DVec2
impl SubAssign<f64> for DVec2
source§fn sub_assign(&mut self, rhs: f64)
fn sub_assign(&mut self, rhs: f64)
-=
operation. Read more