1#![allow(clippy::derived_hash_with_manual_eq)] use std::{fmt::Debug, sync::Arc};
4
5use super::*;
6
7#[derive(Clone, Copy, Debug, Default, PartialEq)]
11#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
12pub struct Stroke {
13 pub width: f32,
14 pub color: Color32,
15}
16
17impl Stroke {
18 pub const NONE: Self = Self {
20 width: 0.0,
21 color: Color32::TRANSPARENT,
22 };
23
24 #[inline]
25 pub fn new(width: impl Into<f32>, color: impl Into<Color32>) -> Self {
26 Self {
27 width: width.into(),
28 color: color.into(),
29 }
30 }
31
32 #[inline]
34 pub fn is_empty(&self) -> bool {
35 self.width <= 0.0 || self.color == Color32::TRANSPARENT
36 }
37}
38
39impl<Color> From<(f32, Color)> for Stroke
40where
41 Color: Into<Color32>,
42{
43 #[inline(always)]
44 fn from((width, color): (f32, Color)) -> Self {
45 Self::new(width, color)
46 }
47}
48
49impl std::hash::Hash for Stroke {
50 #[inline(always)]
51 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
52 let Self { width, color } = *self;
53 emath::OrderedFloat(width).hash(state);
54 color.hash(state);
55 }
56}
57
58#[derive(Clone, Debug, Default, PartialEq)]
62#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
63pub struct PathStroke {
64 pub width: f32,
65 pub color: ColorMode,
66}
67
68impl PathStroke {
69 pub const NONE: Self = Self {
71 width: 0.0,
72 color: ColorMode::TRANSPARENT,
73 };
74
75 #[inline]
76 pub fn new(width: impl Into<f32>, color: impl Into<Color32>) -> Self {
77 Self {
78 width: width.into(),
79 color: ColorMode::Solid(color.into()),
80 }
81 }
82
83 #[inline]
87 pub fn new_uv(
88 width: impl Into<f32>,
89 callback: impl Fn(Rect, Pos2) -> Color32 + Send + Sync + 'static,
90 ) -> Self {
91 Self {
92 width: width.into(),
93 color: ColorMode::UV(Arc::new(callback)),
94 }
95 }
96
97 #[inline]
99 pub fn is_empty(&self) -> bool {
100 self.width <= 0.0 || self.color == ColorMode::TRANSPARENT
101 }
102}
103
104impl<Color> From<(f32, Color)> for PathStroke
105where
106 Color: Into<Color32>,
107{
108 #[inline(always)]
109 fn from((width, color): (f32, Color)) -> Self {
110 Self::new(width, color)
111 }
112}
113
114impl From<Stroke> for PathStroke {
115 fn from(value: Stroke) -> Self {
116 Self {
117 width: value.width,
118 color: ColorMode::Solid(value.color),
119 }
120 }
121}