Skip to main content

egui_charts/config/drawing_tool/
mod.rs

1//! Drawing tool identifiers and creation behavior.
2//!
3//! Use [`DrawingToolType`] to select a tool and inspect its category, interaction
4//! mode and required points when composing a host picker.
5
6mod behavior;
7mod categories;
8mod display;
9mod interaction_mode;
10
11use serde::{Deserialize, Serialize};
12
13pub use display::ParseToolTypeError;
14pub use interaction_mode::DrawingInteractionMode;
15
16/// Enumeration of all drawing tool types available in the charting engine.
17///
18/// Identifies a drawing's rendering behavior, interaction mode, required point
19/// count and toolbar placement. Use [`categories`](Self::categories) and
20/// [`by_category`](Self::by_category) to build a categorized picker.
21///
22/// # Interaction modes
23///
24/// [`interaction_mode`](Self::interaction_mode) describes how a tool captures
25/// points; [`required_points`](Self::required_points) gives its completion count,
26/// or `None` for tools without a fixed count.
27///
28/// # Parsing
29///
30/// `DrawingToolType` implements [`FromStr`](std::str::FromStr) with flexible
31/// case-insensitive matching, including common abbreviations:
32///
33/// ```
34/// # use egui_charts::config::DrawingToolType;
35/// let tool: DrawingToolType = "fib".parse().unwrap();
36/// assert_eq!(tool, DrawingToolType::FibonacciRetracement);
37/// ```
38///
39/// Serde writes and reads the variant name (`"FibonacciRetracement"`), which
40/// stays stable when display names change.
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
42#[non_exhaustive]
43pub enum DrawingToolType {
44    // ============ CURSORS (4 tools) ============
45    /// Crosshair cursor overlay -- not a drawing, provides precision targeting.
46    CrossCursor,
47    /// Dot cursor overlay -- minimal cursor for clean chart views.
48    DotCursor,
49    /// Standard arrow/pointer cursor.
50    ArrowCursor,
51    /// Eraser tool -- click on drawings to delete them.
52    Eraser,
53
54    // ============ LINES (9 tools) ============
55    /// A line segment between two points (click-click interaction).
56    TrendLine,
57    /// A ray starting at a point and extending infinitely in one direction.
58    Ray,
59    /// An info line showing distance, angle, and bar count between two points.
60    InfoLine,
61    /// A line that extends infinitely in both directions through two points.
62    ExtendedLine,
63    /// A horizontal line at a specific price level, extending across the chart.
64    HorizontalLine,
65    /// A horizontal ray extending from a point to the right edge of the chart.
66    HorizontalRay,
67    /// A vertical line at a specific bar/time, extending top to bottom.
68    VerticalLine,
69    /// Combined horizontal + vertical crosshair lines at a single point.
70    CrossLine,
71    /// A trend line that displays the angle of the line in degrees.
72    TrendAngle,
73
74    // ============ CHANNELS (4 tools) ============
75    /// Two parallel lines defining a price channel (3-point: two on baseline, one for width).
76    ParallelChannel,
77    /// Linear regression channel with standard deviation bands.
78    RegressionTrend,
79    /// A trend line through the first two anchors and a horizontal line at the third anchor's price.
80    FlatTopBottom,
81    /// Two lines over the first two anchors' bars with opposite slopes; the third anchor
82    /// positions the mirrored line.
83    DisjointChannel,
84
85    // ============ PITCHFORKS (4 tools) ============
86    /// Andrews' Pitchfork -- median line with parallel support/resistance (3-point).
87    Pitchfork,
88    /// Schiff Pitchfork variant with adjusted median line start point.
89    SchiffPitchfork,
90    /// Modified Schiff Pitchfork with further median line adjustment.
91    ModifiedSchiffPitchfork,
92    /// Inside Pitchfork -- median line drawn inside the price action.
93    InsidePitchfork,
94
95    // ============ FIBONACCI (11 tools) ============
96    /// Fibonacci retracement levels between two price points (drag-to-draw).
97    FibonacciRetracement,
98    /// Trend-based Fibonacci extension projecting levels beyond the measured move.
99    FibonacciExtension,
100    /// Fibonacci channel with parallel lines at Fibonacci ratios.
101    FibonacciChannel,
102    /// Vertical time zones at Fibonacci number intervals from a start point.
103    FibonacciTimeZones,
104    /// Fibonacci speed/resistance fan with diagonal lines at Fibonacci angles.
105    FibonacciSpeedFan,
106    /// Trend-based Fibonacci time projections using price swing timing.
107    TrendBasedFibTime,
108    /// Concentric circles at Fibonacci ratio radii.
109    FibonacciCircles,
110    /// Golden spiral (logarithmic spiral based on the golden ratio).
111    FibonacciSpiral,
112    /// Arcs at Fibonacci speed/resistance levels.
113    FibonacciSpeedResistanceArcs,
114    /// Fibonacci wedge -- converging lines at Fibonacci angles.
115    FibonacciWedge,
116    /// Pitch fan -- fan lines at specific angle ratios from a pivot point.
117    Pitchfan,
118
119    // ============ GANN (4 tools) ============
120    /// Gann Box -- a grid of price/time squares using Gann ratios.
121    GannBox,
122    /// Gann Square -- W.D. Gann's square of nine overlay.
123    GannSquare,
124    /// Gann Square Fixed -- fixed-size Gann grid.
125    GannFixed,
126    /// Gann Fan -- fan lines at standard Gann angles (1x1, 1x2, 2x1, etc.).
127    GannFan,
128
129    // ============ PATTERNS (6 tools) ============
130    /// XABCD harmonic pattern (5-point: Gartley, Butterfly, Bat, Crab, etc.).
131    XABCDPattern,
132    /// Cypher harmonic pattern (5-point variant with specific ratio rules).
133    CypherPattern,
134    /// Head and Shoulders reversal pattern (7-point).
135    HeadAndShoulders,
136    /// ABCD harmonic pattern (4-point geometric price pattern).
137    ABCDPattern,
138    /// Triangle chart pattern (ascending, descending, or symmetrical; 7-point).
139    TrianglePattern,
140    /// Three Drives harmonic pattern (6-point repeating impulse pattern).
141    ThreeDrivesPattern,
142
143    // ============ ELLIOTT WAVES (5 tools) ============
144    /// Elliott impulse wave: a start point and waves 1 to 5 (6 points).
145    ElliottImpulse,
146    /// Elliott correction wave: a start point and waves A, B and C (4 points).
147    ElliottCorrection,
148    /// Elliott triangle: a start point and waves A to E (6 points).
149    ElliottTriangle,
150    /// Elliott double combination: a start point and waves W, X and Y (4 points).
151    ElliottDoubleCombo,
152    /// Elliott triple combination: a start point and waves W, X, Y, X and Z (6 points).
153    ElliottTripleCombo,
154
155    // ============ CYCLES (3 tools) ============
156    /// Evenly-spaced vertical lines highlighting cyclic time intervals.
157    CyclicLines,
158    /// Circular time cycle arcs projected from a start point.
159    TimeCycles,
160    /// Sine wave curve between two points, for cyclical analysis.
161    SineLine,
162
163    // ============ PROJECTION (6 tools) ============
164    /// Long position risk/reward tool showing entry, stop loss, and take profit.
165    LongPos,
166    /// Short position risk/reward tool showing entry, stop loss, and take profit.
167    ShortPos,
168    /// Forecast/prediction zone projected from two points.
169    Forecast,
170    /// Bars pattern -- copy and project a price pattern forward in time.
171    BarsPattern,
172    /// Ghost feed -- translucent historical price overlay for comparison.
173    GhostFeed,
174    /// Generic projection tool for price/time forecasting.
175    ProjectionTool,
176
177    // ============ VOLUME-BASED (3 tools) ============
178    /// Anchored VWAP (Volume-Weighted Average Price) from a user-selected bar.
179    AnchoredVWAP,
180    /// Fixed-range volume profile histogram between two time points.
181    FixedRangeVolumeProfile,
182    /// Anchored volume profile starting from a user-selected bar.
183    AnchoredVolumeProfile,
184
185    // ============ MEASURERS (4 tools) ============
186    /// Ruler/measure tool showing distance, bars, and percentage between two points.
187    Measure,
188    /// Price range highlight (vertical span at a price zone).
189    PriceRange,
190    /// Date range highlight (horizontal span across a time period).
191    DateRange,
192    /// Combined date-and-price range rectangle.
193    DateAndPriceRange,
194
195    // ============ BRUSHES (2 tools) ============
196    /// Freehand drawing brush (continuous-draw interaction). Drawings saved with the former
197    /// `Paintbrush` tool, which drew the same, load as brushes.
198    #[serde(alias = "Paintbrush")]
199    Brush,
200    /// Semi-transparent highlighter brush for marking chart regions.
201    Highlighter,
202
203    // ============ ARROWS (6 tools) ============
204    /// Two-point directional arrow marker.
205    ArrowMarker,
206    /// Two-point arrow with customizable head styles.
207    Arrow,
208    /// Upward arrow marker (single-click, bullish signal).
209    ArrowMarkUp,
210    /// Downward arrow marker (single-click, bearish signal).
211    ArrowMarkDown,
212
213    /// Leftward arrow mark placed with one click at its tip.
214    ArrowMarkLeft,
215    /// Rightward arrow mark placed with one click at its tip.
216    ArrowMarkRight,
217
218    // ============ SHAPES (11 tools) ============
219    /// Axis-aligned rectangle defined by two corner points.
220    Rect,
221    /// Rectangle that can be rotated to any angle.
222    RotatedRect,
223    /// Multi-segment path ending in an arrowhead.
224    Path,
225    /// Circle defined by center and edge point.
226    Circle,
227    /// Ellipse defined by bounding rectangle corners.
228    Ellipse,
229    /// Open polyline with unlimited points (double-click to finish).
230    Polyline,
231    /// Triangle defined by three corner points.
232    Triangle,
233    /// Circular sector: center, radius endpoint, then end ray, swept clockwise on screen.
234    Sector,
235    /// Circular arc between two points with adjustable curvature.
236    Arc,
237    /// Quadratic Bezier curve (3 control points: start, control, end).
238    Curve,
239    /// Cubic Bezier curve (4 control points).
240    DoubleCurve,
241
242    // ============ ANNOTATIONS (11 tools) ============
243    /// Simple text label placed on the chart.
244    TextLabel,
245    /// Text label anchored to screen position (doesn't move with pan).
246    AnchoredText,
247    /// Note: a text label joined to the bar and price it annotates by a thin line.
248    Note,
249    /// Price note: the anchor's price and any text in a solid label, joined to the anchor by a
250    /// thin line.
251    PriceNote,
252    /// Pin: a marker on a bar and price, with its text in a popup while selected.
253    AnchoredNote,
254    /// Data table overlay on the chart.
255    Table,
256    /// Callout with arrow pointing to a chart location.
257    Callout,
258    /// Comment: its text in one bubble with a corner on the anchor.
259    Comment,
260    /// Price label: the anchor's price in a badge beside the point, with a pointer to it.
261    PriceLabel,
262    /// Signpost: a label on a thin pole above or below its bar.
263    Signpost,
264    /// Flag/mark note at a specific chart location.
265    FlagNote,
266
267    // ============ CONTENT (3 tools - placeholders) ============
268    /// Image embed identifier; built-in rendering draws a frame without loading an image.
269    Image,
270    /// Social post embed identifier; built-in rendering draws a card without fetching content.
271    Tweet,
272    /// Idea embed identifier; built-in rendering draws a badge without fetching content.
273    Idea,
274
275    // ============ ICONS (2 tools) ============
276    /// Bundled vector icon or Unicode emoji placed at a single point.
277    FontIcon,
278    /// Bundled illustrated sticker placed with one click, sized by `Drawing::font_size`.
279    Sticker,
280}
281
282#[cfg(test)]
283mod tests {
284    use super::*;
285
286    #[test]
287    fn test_cursor_detection() {
288        assert!(DrawingToolType::CrossCursor.is_cursor());
289        assert!(DrawingToolType::Eraser.is_cursor());
290        assert!(!DrawingToolType::TrendLine.is_cursor());
291        assert!(!DrawingToolType::FibonacciRetracement.is_cursor());
292    }
293
294    #[test]
295    fn test_from_str() {
296        assert_eq!(
297            "trendline".parse::<DrawingToolType>().unwrap(),
298            DrawingToolType::TrendLine
299        );
300        assert_eq!(
301            "fib".parse::<DrawingToolType>().unwrap(),
302            DrawingToolType::FibonacciRetracement
303        );
304        let unparsed: Vec<_> = DrawingToolType::all()
305            .iter()
306            .filter(|tool| {
307                let name = tool.as_str();
308                name.parse() != Ok(**tool) || name.to_uppercase().parse() != Ok(**tool)
309            })
310            .map(|tool| tool.as_str())
311            .collect();
312        assert!(unparsed.is_empty(), "{unparsed:?}");
313    }
314
315    #[test]
316    fn test_interaction_modes() {
317        assert_eq!(
318            DrawingToolType::CrossCursor.interaction_mode(),
319            DrawingInteractionMode::NotDrawing
320        );
321        assert_eq!(
322            DrawingToolType::Rect.interaction_mode(),
323            DrawingInteractionMode::DragToDraw
324        );
325        assert_eq!(
326            DrawingToolType::Brush.interaction_mode(),
327            DrawingInteractionMode::ContinuousDraw
328        );
329    }
330}