Iced + Canvas + Update Function - How do I pass a message back to the main program

⚓ Rust    📅 2026-05-22    👤 surdeus    👁️ 2      

surdeus

I have an iced program that draws a line graph onto a canvas. It works. I want to be able to add button like functionality to the canvas so that when I click on some text I can redraw the graph with a different range of dates (the x axis values). I have added an update function to my canvas program and am able to capture mouse click events on the canvas and retrieve the x and y coordinates. With a little more code I think I can make it work. But in my testing mode I cannot figure out how to return a message to the main programs update function. The error message I get with the code below when attempting to return "Message::Welcome" is that Welcome is not known in the current scope. But my Message enum has a Welcome item and I have added the file with Message enum to this file using "use crate::utils::...::Message" but it is listed as in unused import. Any assistance will be appreciated.

#[derive(Debug, Clone)]
pub enum Message {
    // Increment,
    DisplayGraph,
    Welcome,
    UpdateStartDates(Vec<String>),
    Exit,
}

pub struct LineGraph {
    pub points: Vec<Point>,
    pub x_values: Vec<String>,
    pub y_values: Vec<String>,
    pub index_values: Vec<IndexDateClose>,
}

impl<Message> canvas::Program<Message> for LineGraph {

    type State = ();

    fn draw(
        &self,
        _state: &(),
        renderer: &Renderer,
        _theme: &Theme,
        bounds: iced::Rectangle,
        _cursor: iced::advanced::mouse::Cursor,
    ) -> Vec<canvas::Geometry<Renderer>> {

        let mut frame = canvas::Frame::new(renderer, bounds.size());
        draw_heading(&mut frame);
        draw_axis(&mut frame);
        draw_grid(&mut frame);
        draw_x_axis_ticks(&mut frame);
        draw_x_axis_labels(&mut frame, &self.x_values);
        draw_y_axis_ticks(&mut frame);
        draw_y_axis_labels(&mut frame, &self.y_values);
        draw_data_points(&mut frame, &self.points);
        draw_overlay(&mut frame, &self.points, &self.index_values);
        vec![frame.into_geometry()]
    } // end of function draw

    fn update(
        &self,
        _state: &mut Self::State,
        event: &iced::Event,
        bounds: Rectangle,
        cursor: Cursor,
    ) -> Option<iced::widget::Action<Message>>   {
            match event {
                canvas::Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
                    if let Some(mouse_position) = cursor.position_in(bounds) {
                        println!("--------------------------");
                        println!("clicked on canvas");
                        println!("point x = {}", mouse_position.x);
                        println!("point y = {}", mouse_position.y);
                        // None
                        Some(iced::widget::Action::publish(Message::Welcome))
                    } else {
                        None
                    }// end if let some
                }
                _ => None,
            }

    } // end update function
}

2 posts - 2 participants

Read full topic

🏷️ Rust_feed