0

I want to create a selectable and editable title for a folder in eframe/egui with the function egui::TextEdti::singleline(). But it needs mutable reference to string (&mut String). If I declare a variable in the function like this: let response = ui.add(egui::TextEdit::singleline(&mut "Add Folder".to_string())); I can edit the text but when I do it changes in this frame but in the next frame it becomes "Add Folder" again. I can't find a place to declare a &mut String variable. My code:

use eframe::{App, egui, Frame, NativeOptions, run_native};
use eframe::egui::{CentralPanel, Color32, Context, SidePanel, Visuals};
use crate::egui::RichText;

#[derive(Default)]
struct MyApp { add_folder_button_x: f32, add_folder_button_y: f32 }

impl MyApp {
    fn new(cc: &eframe::CreationContext<'_>) -> Self {
        Self { add_folder_button_x: 100., add_folder_button_y: 50. }
    }
}

impl App for MyApp {
    fn update(&mut self, ctx: &Context, frame: &mut Frame) {
        SidePanel::left("LeftPanel").show(ctx, |ui| unsafe {
            ctx.set_visuals(Visuals { panel_fill: Color32::from_rgb(111, 255, 203), ..Visuals::default() });
// The problem is here -------------------------------------VV
            let response = ui.add(egui::TextEdit::singleline());
            if response.changed() {}
            ui.put(egui::Rect::from_points(&[egui::Pos2::new(self.add_folder_button_x, self.add_folder_button_y)]), egui::Button::new("➕").fill(Color32::RED).wrap(false));
        });
        CentralPanel::default().show(ctx, |ui| {
            ctx.set_visuals(Visuals { panel_fill: Color32::from_rgb(111, 200, 203), ..Visuals::default() });
        });
        SidePanel::left("SecondLeft").show(ctx, |ui| {
            ctx.set_visuals(Visuals { panel_fill: Color32::from_rgb(100, 200, 180), ..Visuals::default() });
            if ui.button("Clicker").clicked() {}
            if ui.add(egui::Button::new("➕").fill(Color32::RED)).clicked() {}
            if ui.button(RichText::new("delete").color(Color32::RED)).clicked() {}
        });
    }
}

fn main() -> eframe::Result<()> {
    let native_options = NativeOptions::default();
    run_native("TASK", native_options, Box::new(|cc| Box::new(MyApp::new(cc))))
}

fn text_edit() -> String {
    let mut single_line = "Add Folder".to_string();
    single_line
}

I tried to create a function that returns (&'static mut String) but it had an error:

fn text_edit() -> &'static mut String {
    let mut single_line = "Add Folder".to_string();
    &mut single_line
//  ^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function error[E0515]

And i tried to declare a static variable that returns &mut String. But that also had an error:

static SINGLE_LINE: &mut String = &mut String::from("Add Folder");
//                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const From<&str>` is not implemented for `String`

And I looked in this post:text but it is doing it in loop in the "main" function, I am doing it in the implementation of App for MyApp so I cannot declare a variable outside of the fn update().

Vecrix
  • 5
  • 1

1 Answers1

0

The issue you are facing is related to lifetimes and ownership in Rust. In your current implementation, you are trying to return a mutable reference to a local variable from the text_edit() function, which is not allowed as the local variable's lifetime is limited to the function scope.

To solve this problem, you can use a mutable String field within your MyApp struct to store the editable title. Here's how you can modify your code to achieve this:

use eframe::{App, egui, Frame, NativeOptions, run_native};

#[derive(Default)]
struct MyApp {
    add_folder_button_x: f32,
    add_folder_button_y: f32,
    folder_title: String, // Add a field to store the folder title
}

impl MyApp {
    fn new(cc: &eframe::CreationContext<'_>) -> Self {
        Self {
            add_folder_button_x: 100.,
            add_folder_button_y: 50.,
            folder_title: "Add Folder".to_string(), // Initialize the folder title here
        }
    }
}

impl App for MyApp {
    fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) {
        SidePanel::left("LeftPanel").show(ctx, |ui| unsafe {
            ctx.set_visuals(Visuals {
                panel_fill: Color32::from_rgb(111, 255, 203),
                ..Visuals::default()
            });

            // Use the folder_title field here
            let response = ui.add(egui::TextEdit::singleline(&mut self.folder_title));
            if response.changed() {}

            ui.put(
                egui::Rect::from_points(&[egui::Pos2::new(
                    self.add_folder_button_x,
                    self.add_folder_button_y,
                )]),
                egui::Button::new("➕").fill(Color32::RED).wrap(false),
            );
        });

        // ... Other parts of your update function ...

        // If you want to access the folder_title from outside the closure, you can clone it.
        let folder_title_clone = self.folder_title.clone();
        // Do something with folder_title_clone...
    }
}

fn main() -> eframe::Result<()> {
    let native_options = NativeOptions::default();
    run_native("TASK", native_options, Box::new(|cc| Box::new(MyApp::new(cc))))
}

By using the folder_title field in your MyApp struct, you can now have a mutable reference to the string and maintain its state between frames. When the user edits the text using the egui::TextEdit::singleline widget, the changes will persist across frames, and you can access the updated title through the folder_title field in your MyApp struct.

Remember that when working with mutable references, you need to be mindful of ownership and lifetimes to avoid common issues like borrowing and ownership conflicts.

  • Hi, Leonardo Boiardi! Your answer appears likely to have been written (entirely or partially) by AI (e.g., ChatGPT). A heads-up that [posting AI-generated content is not allowed here](//meta.stackoverflow.com/q/421831). If you used an AI tool to assist with any answer, I would encourage you to delete it. We do hope you'll be a part of our community and contribute with *your own*, quality posts in the future. Thanks! – NotTheDr01ds Jul 21 '23 at 00:11
  • 1
    **Readers should review this answer carefully and critically, as AI-generated information often contains fundamental errors and misinformation.** If you observe quality issues and/or have reason to believe that this answer was generated by AI, please leave feedback accordingly. – NotTheDr01ds Jul 21 '23 at 00:12