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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#![windows_subsystem = "windows"]
use std::sync::Arc;
use druid::widget::{Flex, Label, TextBox};
use druid::{
AppLauncher, Color, Data, Env, Lens, LocalizedString, Menu, Widget, WidgetExt, WindowDesc,
WindowId,
};
const WINDOW_TITLE: LocalizedString<AppState> = LocalizedString::new("Text Options");
const EXPLAINER: &str = "\
This example demonstrates some of the possible configurations \
of the TextBox widget.\n\
The top textbox allows a single line of input, with horizontal scrolling \
but no scrollbars. The bottom textbox allows mutliple lines of text, wrapping \
words to fit the width, and allowing vertical scrolling when it runs out \
of room to grow vertically.";
#[derive(Clone, Data, Lens)]
struct AppState {
multi: Arc<String>,
single: Arc<String>,
}
pub fn main() {
let main_window = WindowDesc::new(build_root_widget())
.title(WINDOW_TITLE)
.menu(make_menu)
.window_size((400.0, 600.0));
let initial_state = AppState {
single: "".to_string().into(),
multi: "".to_string().into(),
};
AppLauncher::with_window(main_window)
.log_to_console()
.launch(initial_state)
.expect("Failed to launch application");
}
fn build_root_widget() -> impl Widget<AppState> {
let blurb = Label::new(EXPLAINER)
.with_line_break_mode(druid::widget::LineBreaking::WordWrap)
.padding(8.0)
.border(Color::grey(0.6), 2.0)
.rounded(5.0);
Flex::column()
.cross_axis_alignment(druid::widget::CrossAxisAlignment::Start)
.with_child(blurb)
.with_spacer(24.0)
.with_child(
TextBox::new()
.with_placeholder("Single")
.lens(AppState::single),
)
.with_default_spacer()
.with_flex_child(
TextBox::multiline()
.with_placeholder("Multi")
.lens(AppState::multi)
.expand_width(),
1.0,
)
.padding(8.0)
}
#[allow(unused_assignments, unused_mut)]
fn make_menu<T: Data>(_window: Option<WindowId>, _data: &AppState, _env: &Env) -> Menu<T> {
let mut base = Menu::empty();
#[cfg(target_os = "macos")]
{
base = base.entry(druid::platform_menus::mac::application::default())
}
#[cfg(any(target_os = "windows", target_os = "linux"))]
{
base = base.entry(druid::platform_menus::win::file::default());
}
base.entry(
Menu::new(LocalizedString::new("common-menu-edit-menu"))
.entry(druid::platform_menus::common::undo())
.entry(druid::platform_menus::common::redo())
.separator()
.entry(druid::platform_menus::common::cut())
.entry(druid::platform_menus::common::copy())
.entry(druid::platform_menus::common::paste()),
)
}