跳转至

Add Multi-line Input

Keywords: iced::widget::text_editor, iced::widget::container.

本节我们将text控件替换为text_editor控件,以实现多行文本的输入。

iced库版本

text_editor控件尚未在正式版本中发布,需要使用git仓库中的代码。

[dependencies]
iced = { git = "https://github.com/iced-rs/iced.git", rev = "refs/tags/text-editor" }

首先,将引入的iced::widget::text替换为iced::widget::text_editortext_editor是有状态的,需要在new中初始化空间状态,并且在view中根据状态更新控件内容。

struct Editor {
    content: text_editor::Content
}

// ...

impl Sandbox for Editor {
    type Message = Message;

    fn new() -> Self {
        Editor {
            content: text_editor::Content::new() // Initialize the content
        }
    }

    // ...

    fn view(&self) -> Element<'_, Message> {
        text_editor(&self.content).into() // Link the content state
    }
}

默认情况下,into方法会使控件充满整个窗口,我们可以使用container包围text_editor控件辅助布局。

use iced::widget::container;

// ...

impl Sandbox for Editor {
    // ...
    fn view(&self) -> Element<'_, Message> {
        let editor = text_editor(&self.content);
        container(editor).padding(10).into() // Add padding and wrap the editor
    }
}

此时,多行文本输入框的布局已经完成。但由于输入框没有绑定事件处理,因此目前无法输入文本。text_editor控件支持的事件有

pub enum Action {
    Move(Motion),
    Select(Motion),
    SelectWord,
    SelectLine,
    Edit(Edit),
    Click(Point),
    Drag(Point),
    Scroll { lines: i32 },
}

我们需要将Edit事件在updateview中进行处理,同时更新Message枚举类型。

#[derive(Debug, Clone)]
enum Message {
    EditorEdit(text_editor::Action)
}

// ...

impl Sandbox for Editor {
    // ...
    fn update(&mut self, message: Message) {
        match message {
            Message::EditorEdit(action) => {
                self.content = self.content.edit(action);
            }
        }
    }

    fn view(&self) -> Element<'_, Message> {
        let editor = text_editor(&self.content).on_edit(Message::EditorEdit); // Bind the edit event
        container(editor).padding(10).into() // Add padding and wrap the editor
    }
}

以下为完整的main.rs文件内容:

Download source code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
use iced::{Element, Sandbox, Settings};
use iced::widget::{text_editor, container};

fn main() -> iced::Result {
    Editor::run(Settings::default())
}

struct Editor {
    content: text_editor::Content
}

#[derive(Debug, Clone)]
enum Message {
    EditorEdit(text_editor::Action)
}

impl Sandbox for Editor {
    type Message = Message; // Define the type of messages

    fn new() -> Self {
        Self {
            content: text_editor::Content::new()
        }
    }

    fn title(&self) -> String {
        String::from("A text editor")
    }

    fn update(&mut self, message: Message) {
        // Handle messages here
        match message {
            Message::EditorEdit(action) => {
                self.content.edit(action);
            }
        }
    }

    fn view(&self) -> Element<'_, Message> {
        // Create the user interface here
        let editor = text_editor(&self.content).on_edit(Message::EditorEdit);
        container(editor).padding(10).into()
    }
}

评论