Merge pull request #1744 from JungleTryne/disable-text-input
Add functionality to make `TextInput` disabled
This commit is contained in:
commit
ce8e92ca7a
16 changed files with 143 additions and 95 deletions
|
|
@ -12,4 +12,5 @@ pub enum Interaction {
|
||||||
Grabbing,
|
Grabbing,
|
||||||
ResizingHorizontally,
|
ResizingHorizontally,
|
||||||
ResizingVertically,
|
ResizingVertically,
|
||||||
|
NotAllowed,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,8 +141,8 @@ mod numeric_input {
|
||||||
.map(u32::to_string)
|
.map(u32::to_string)
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.unwrap_or(""),
|
.unwrap_or(""),
|
||||||
Event::InputChanged,
|
|
||||||
)
|
)
|
||||||
|
.on_input(Event::InputChanged)
|
||||||
.padding(10),
|
.padding(10),
|
||||||
button("+", Event::IncrementPressed),
|
button("+", Event::IncrementPressed),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -100,11 +100,10 @@ impl Program for Controls {
|
||||||
.size(14)
|
.size(14)
|
||||||
.style(Color::WHITE),
|
.style(Color::WHITE),
|
||||||
)
|
)
|
||||||
.push(text_input(
|
.push(
|
||||||
"Placeholder",
|
text_input("Placeholder", text)
|
||||||
text,
|
.on_input(Message::TextChanged),
|
||||||
Message::TextChanged,
|
),
|
||||||
)),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
|
|
|
||||||
|
|
@ -214,12 +214,9 @@ impl Sandbox for App {
|
||||||
column![
|
column![
|
||||||
scrollable(options).height(Length::Fill),
|
scrollable(options).height(Length::Fill),
|
||||||
row![
|
row![
|
||||||
text_input(
|
text_input("Add a new option", &self.input)
|
||||||
"Add a new option",
|
.on_input(Message::InputChanged)
|
||||||
&self.input,
|
.on_submit(Message::AddItem(self.input.clone())),
|
||||||
Message::InputChanged,
|
|
||||||
)
|
|
||||||
.on_submit(Message::AddItem(self.input.clone())),
|
|
||||||
button(text(format!("Toggle Order ({})", self.order)))
|
button(text(format!("Toggle Order ({})", self.order)))
|
||||||
.on_press(Message::ToggleOrder)
|
.on_press(Message::ToggleOrder)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -133,18 +133,16 @@ impl Application for App {
|
||||||
column![
|
column![
|
||||||
column![
|
column![
|
||||||
text("Email").size(12),
|
text("Email").size(12),
|
||||||
text_input(
|
text_input("abc@123.com", &self.email,)
|
||||||
"abc@123.com",
|
.on_input(Message::Email)
|
||||||
&self.email,
|
.on_submit(Message::Submit)
|
||||||
Message::Email
|
.padding(5),
|
||||||
)
|
|
||||||
.on_submit(Message::Submit)
|
|
||||||
.padding(5),
|
|
||||||
]
|
]
|
||||||
.spacing(5),
|
.spacing(5),
|
||||||
column![
|
column![
|
||||||
text("Password").size(12),
|
text("Password").size(12),
|
||||||
text_input("", &self.password, Message::Password)
|
text_input("", &self.password)
|
||||||
|
.on_input(Message::Password)
|
||||||
.on_submit(Message::Submit)
|
.on_submit(Message::Submit)
|
||||||
.password()
|
.password()
|
||||||
.padding(5),
|
.padding(5),
|
||||||
|
|
|
||||||
|
|
@ -49,13 +49,11 @@ impl Sandbox for QRGenerator {
|
||||||
.size(70)
|
.size(70)
|
||||||
.style(Color::from([0.5, 0.5, 0.5]));
|
.style(Color::from([0.5, 0.5, 0.5]));
|
||||||
|
|
||||||
let input = text_input(
|
let input =
|
||||||
"Type the data of your QR code here...",
|
text_input("Type the data of your QR code here...", &self.data)
|
||||||
&self.data,
|
.on_input(Message::DataChanged)
|
||||||
Message::DataChanged,
|
.size(30)
|
||||||
)
|
.padding(15);
|
||||||
.size(30)
|
|
||||||
.padding(15);
|
|
||||||
|
|
||||||
let mut content = column![title, input]
|
let mut content = column![title, input]
|
||||||
.width(700)
|
.width(700)
|
||||||
|
|
|
||||||
|
|
@ -90,13 +90,10 @@ impl Sandbox for Styling {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let text_input = text_input(
|
let text_input = text_input("Type something...", &self.input_value)
|
||||||
"Type something...",
|
.on_input(Message::InputChanged)
|
||||||
&self.input_value,
|
.padding(10)
|
||||||
Message::InputChanged,
|
.size(20);
|
||||||
)
|
|
||||||
.padding(10)
|
|
||||||
.size(20);
|
|
||||||
|
|
||||||
let button = button("Submit")
|
let button = button("Submit")
|
||||||
.padding(10)
|
.padding(10)
|
||||||
|
|
|
||||||
|
|
@ -119,13 +119,15 @@ impl Application for App {
|
||||||
column![
|
column![
|
||||||
subtitle(
|
subtitle(
|
||||||
"Title",
|
"Title",
|
||||||
text_input("", &self.editing.title, Message::Title)
|
text_input("", &self.editing.title)
|
||||||
|
.on_input(Message::Title)
|
||||||
.on_submit(Message::Add)
|
.on_submit(Message::Add)
|
||||||
.into()
|
.into()
|
||||||
),
|
),
|
||||||
subtitle(
|
subtitle(
|
||||||
"Message",
|
"Message",
|
||||||
text_input("", &self.editing.body, Message::Body)
|
text_input("", &self.editing.body)
|
||||||
|
.on_input(Message::Body)
|
||||||
.on_submit(Message::Add)
|
.on_submit(Message::Add)
|
||||||
.into()
|
.into()
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -204,15 +204,12 @@ impl Application for Todos {
|
||||||
.style(Color::from([0.5, 0.5, 0.5]))
|
.style(Color::from([0.5, 0.5, 0.5]))
|
||||||
.horizontal_alignment(alignment::Horizontal::Center);
|
.horizontal_alignment(alignment::Horizontal::Center);
|
||||||
|
|
||||||
let input = text_input(
|
let input = text_input("What needs to be done?", input_value)
|
||||||
"What needs to be done?",
|
.id(INPUT_ID.clone())
|
||||||
input_value,
|
.on_input(Message::InputChanged)
|
||||||
Message::InputChanged,
|
.on_submit(Message::CreateTask)
|
||||||
)
|
.padding(15)
|
||||||
.id(INPUT_ID.clone())
|
.size(30);
|
||||||
.padding(15)
|
|
||||||
.size(30)
|
|
||||||
.on_submit(Message::CreateTask);
|
|
||||||
|
|
||||||
let controls = view_controls(tasks, *filter);
|
let controls = view_controls(tasks, *filter);
|
||||||
let filtered_tasks =
|
let filtered_tasks =
|
||||||
|
|
@ -375,14 +372,12 @@ impl Task {
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
TaskState::Editing => {
|
TaskState::Editing => {
|
||||||
let text_input = text_input(
|
let text_input =
|
||||||
"Describe your task...",
|
text_input("Describe your task...", &self.description)
|
||||||
&self.description,
|
.id(Self::text_input_id(i))
|
||||||
TaskMessage::DescriptionEdited,
|
.on_input(TaskMessage::DescriptionEdited)
|
||||||
)
|
.on_submit(TaskMessage::FinishEdition)
|
||||||
.id(Self::text_input_id(i))
|
.padding(10);
|
||||||
.on_submit(TaskMessage::FinishEdition)
|
|
||||||
.padding(10);
|
|
||||||
|
|
||||||
row![
|
row![
|
||||||
text_input,
|
text_input,
|
||||||
|
|
|
||||||
|
|
@ -570,13 +570,10 @@ impl<'a> Step {
|
||||||
bytes: include_bytes!("../fonts/icons.ttf"),
|
bytes: include_bytes!("../fonts/icons.ttf"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut text_input = text_input(
|
let mut text_input = text_input("Type something to continue...", value)
|
||||||
"Type something to continue...",
|
.on_input(StepMessage::InputChanged)
|
||||||
value,
|
.padding(10)
|
||||||
StepMessage::InputChanged,
|
.size(30);
|
||||||
)
|
|
||||||
.padding(10)
|
|
||||||
.size(30);
|
|
||||||
|
|
||||||
if is_showing_icon {
|
if is_showing_icon {
|
||||||
text_input = text_input.icon(text_input::Icon {
|
text_input = text_input.icon(text_input::Icon {
|
||||||
|
|
|
||||||
|
|
@ -125,12 +125,9 @@ impl Application for WebSocket {
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_message_input = {
|
let new_message_input = {
|
||||||
let mut input = text_input(
|
let mut input = text_input("Type a message...", &self.new_message)
|
||||||
"Type a message...",
|
.on_input(Message::NewMessageChanged)
|
||||||
&self.new_message,
|
.padding(10);
|
||||||
Message::NewMessageChanged,
|
|
||||||
)
|
|
||||||
.padding(10);
|
|
||||||
|
|
||||||
let mut button = button(
|
let mut button = button(
|
||||||
text("Send")
|
text("Send")
|
||||||
|
|
|
||||||
|
|
@ -171,14 +171,13 @@ where
|
||||||
pub fn text_input<'a, Message, Renderer>(
|
pub fn text_input<'a, Message, Renderer>(
|
||||||
placeholder: &str,
|
placeholder: &str,
|
||||||
value: &str,
|
value: &str,
|
||||||
on_change: impl Fn(String) -> Message + 'a,
|
|
||||||
) -> widget::TextInput<'a, Message, Renderer>
|
) -> widget::TextInput<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Message: Clone,
|
Message: Clone,
|
||||||
Renderer: crate::text::Renderer,
|
Renderer: crate::text::Renderer,
|
||||||
Renderer::Theme: widget::text_input::StyleSheet,
|
Renderer::Theme: widget::text_input::StyleSheet,
|
||||||
{
|
{
|
||||||
widget::TextInput::new(placeholder, value, on_change)
|
widget::TextInput::new(placeholder, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new [`Slider`].
|
/// Creates a new [`Slider`].
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,8 @@ pub use iced_style::text_input::{Appearance, StyleSheet};
|
||||||
/// let input = TextInput::new(
|
/// let input = TextInput::new(
|
||||||
/// "This is the placeholder...",
|
/// "This is the placeholder...",
|
||||||
/// value,
|
/// value,
|
||||||
/// Message::TextInputChanged,
|
|
||||||
/// )
|
/// )
|
||||||
|
/// .on_input(Message::TextInputChanged)
|
||||||
/// .padding(10);
|
/// .padding(10);
|
||||||
/// ```
|
/// ```
|
||||||
/// 
|
/// 
|
||||||
|
|
@ -65,7 +65,7 @@ where
|
||||||
width: Length,
|
width: Length,
|
||||||
padding: Padding,
|
padding: Padding,
|
||||||
size: Option<f32>,
|
size: Option<f32>,
|
||||||
on_change: Box<dyn Fn(String) -> Message + 'a>,
|
on_input: Option<Box<dyn Fn(String) -> Message + 'a>>,
|
||||||
on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>,
|
on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>,
|
||||||
on_submit: Option<Message>,
|
on_submit: Option<Message>,
|
||||||
icon: Option<Icon<Renderer::Font>>,
|
icon: Option<Icon<Renderer::Font>>,
|
||||||
|
|
@ -82,12 +82,8 @@ where
|
||||||
///
|
///
|
||||||
/// It expects:
|
/// It expects:
|
||||||
/// - a placeholder,
|
/// - a placeholder,
|
||||||
/// - the current value, and
|
/// - the current value
|
||||||
/// - a function that produces a message when the [`TextInput`] changes.
|
pub fn new(placeholder: &str, value: &str) -> Self {
|
||||||
pub fn new<F>(placeholder: &str, value: &str, on_change: F) -> Self
|
|
||||||
where
|
|
||||||
F: 'a + Fn(String) -> Message,
|
|
||||||
{
|
|
||||||
TextInput {
|
TextInput {
|
||||||
id: None,
|
id: None,
|
||||||
placeholder: String::from(placeholder),
|
placeholder: String::from(placeholder),
|
||||||
|
|
@ -97,7 +93,7 @@ where
|
||||||
width: Length::Fill,
|
width: Length::Fill,
|
||||||
padding: Padding::new(5.0),
|
padding: Padding::new(5.0),
|
||||||
size: None,
|
size: None,
|
||||||
on_change: Box::new(on_change),
|
on_input: None,
|
||||||
on_paste: None,
|
on_paste: None,
|
||||||
on_submit: None,
|
on_submit: None,
|
||||||
icon: None,
|
icon: None,
|
||||||
|
|
@ -117,6 +113,25 @@ where
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the message that should be produced when some text is typed into
|
||||||
|
/// the [`TextInput`].
|
||||||
|
///
|
||||||
|
/// If this method is not called, the [`TextInput`] will be disabled.
|
||||||
|
pub fn on_input<F>(mut self, callback: F) -> Self
|
||||||
|
where
|
||||||
|
F: 'a + Fn(String) -> Message,
|
||||||
|
{
|
||||||
|
self.on_input = Some(Box::new(callback));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the message that should be produced when the [`TextInput`] is
|
||||||
|
/// focused and the enter key is pressed.
|
||||||
|
pub fn on_submit(mut self, message: Message) -> Self {
|
||||||
|
self.on_submit = Some(message);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the message that should be produced when some text is pasted into
|
/// Sets the message that should be produced when some text is pasted into
|
||||||
/// the [`TextInput`].
|
/// the [`TextInput`].
|
||||||
pub fn on_paste(
|
pub fn on_paste(
|
||||||
|
|
@ -159,13 +174,6 @@ where
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the message that should be produced when the [`TextInput`] is
|
|
||||||
/// focused and the enter key is pressed.
|
|
||||||
pub fn on_submit(mut self, message: Message) -> Self {
|
|
||||||
self.on_submit = Some(message);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the style of the [`TextInput`].
|
/// Sets the style of the [`TextInput`].
|
||||||
pub fn style(
|
pub fn style(
|
||||||
mut self,
|
mut self,
|
||||||
|
|
@ -198,6 +206,7 @@ where
|
||||||
&self.placeholder,
|
&self.placeholder,
|
||||||
self.size,
|
self.size,
|
||||||
&self.font,
|
&self.font,
|
||||||
|
self.on_input.is_none(),
|
||||||
self.is_secure,
|
self.is_secure,
|
||||||
self.icon.as_ref(),
|
self.icon.as_ref(),
|
||||||
&self.style,
|
&self.style,
|
||||||
|
|
@ -220,6 +229,18 @@ where
|
||||||
tree::State::new(State::new())
|
tree::State::new(State::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn diff(&self, tree: &mut Tree) {
|
||||||
|
let state = tree.state.downcast_mut::<State>();
|
||||||
|
|
||||||
|
// Unfocus text input if it becomes disabled
|
||||||
|
if self.on_input.is_none() {
|
||||||
|
state.last_click = None;
|
||||||
|
state.is_focused = None;
|
||||||
|
state.is_pasting = None;
|
||||||
|
state.is_dragging = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn width(&self) -> Length {
|
fn width(&self) -> Length {
|
||||||
self.width
|
self.width
|
||||||
}
|
}
|
||||||
|
|
@ -277,7 +298,7 @@ where
|
||||||
self.size,
|
self.size,
|
||||||
&self.font,
|
&self.font,
|
||||||
self.is_secure,
|
self.is_secure,
|
||||||
self.on_change.as_ref(),
|
self.on_input.as_deref(),
|
||||||
self.on_paste.as_deref(),
|
self.on_paste.as_deref(),
|
||||||
&self.on_submit,
|
&self.on_submit,
|
||||||
|| tree.state.downcast_mut::<State>(),
|
|| tree.state.downcast_mut::<State>(),
|
||||||
|
|
@ -304,6 +325,7 @@ where
|
||||||
&self.placeholder,
|
&self.placeholder,
|
||||||
self.size,
|
self.size,
|
||||||
&self.font,
|
&self.font,
|
||||||
|
self.on_input.is_none(),
|
||||||
self.is_secure,
|
self.is_secure,
|
||||||
self.icon.as_ref(),
|
self.icon.as_ref(),
|
||||||
&self.style,
|
&self.style,
|
||||||
|
|
@ -318,7 +340,7 @@ where
|
||||||
_viewport: &Rectangle,
|
_viewport: &Rectangle,
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
mouse_interaction(layout, cursor_position)
|
mouse_interaction(layout, cursor_position, self.on_input.is_none())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -492,7 +514,7 @@ pub fn update<'a, Message, Renderer>(
|
||||||
size: Option<f32>,
|
size: Option<f32>,
|
||||||
font: &Renderer::Font,
|
font: &Renderer::Font,
|
||||||
is_secure: bool,
|
is_secure: bool,
|
||||||
on_change: &dyn Fn(String) -> Message,
|
on_input: Option<&dyn Fn(String) -> Message>,
|
||||||
on_paste: Option<&dyn Fn(String) -> Message>,
|
on_paste: Option<&dyn Fn(String) -> Message>,
|
||||||
on_submit: &Option<Message>,
|
on_submit: &Option<Message>,
|
||||||
state: impl FnOnce() -> &'a mut State,
|
state: impl FnOnce() -> &'a mut State,
|
||||||
|
|
@ -505,7 +527,8 @@ where
|
||||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
|
||||||
| Event::Touch(touch::Event::FingerPressed { .. }) => {
|
| Event::Touch(touch::Event::FingerPressed { .. }) => {
|
||||||
let state = state();
|
let state = state();
|
||||||
let is_clicked = layout.bounds().contains(cursor_position);
|
let is_clicked =
|
||||||
|
layout.bounds().contains(cursor_position) && on_input.is_some();
|
||||||
|
|
||||||
state.is_focused = if is_clicked {
|
state.is_focused = if is_clicked {
|
||||||
state.is_focused.or_else(|| {
|
state.is_focused.or_else(|| {
|
||||||
|
|
@ -635,6 +658,8 @@ where
|
||||||
let state = state();
|
let state = state();
|
||||||
|
|
||||||
if let Some(focus) = &mut state.is_focused {
|
if let Some(focus) = &mut state.is_focused {
|
||||||
|
let Some(on_input) = on_input else { return event::Status::Ignored };
|
||||||
|
|
||||||
if state.is_pasting.is_none()
|
if state.is_pasting.is_none()
|
||||||
&& !state.keyboard_modifiers.command()
|
&& !state.keyboard_modifiers.command()
|
||||||
&& !c.is_control()
|
&& !c.is_control()
|
||||||
|
|
@ -643,7 +668,7 @@ where
|
||||||
|
|
||||||
editor.insert(c);
|
editor.insert(c);
|
||||||
|
|
||||||
let message = (on_change)(editor.contents());
|
let message = (on_input)(editor.contents());
|
||||||
shell.publish(message);
|
shell.publish(message);
|
||||||
|
|
||||||
focus.updated_at = Instant::now();
|
focus.updated_at = Instant::now();
|
||||||
|
|
@ -656,6 +681,8 @@ where
|
||||||
let state = state();
|
let state = state();
|
||||||
|
|
||||||
if let Some(focus) = &mut state.is_focused {
|
if let Some(focus) = &mut state.is_focused {
|
||||||
|
let Some(on_input) = on_input else { return event::Status::Ignored };
|
||||||
|
|
||||||
let modifiers = state.keyboard_modifiers;
|
let modifiers = state.keyboard_modifiers;
|
||||||
focus.updated_at = Instant::now();
|
focus.updated_at = Instant::now();
|
||||||
|
|
||||||
|
|
@ -681,7 +708,7 @@ where
|
||||||
let mut editor = Editor::new(value, &mut state.cursor);
|
let mut editor = Editor::new(value, &mut state.cursor);
|
||||||
editor.backspace();
|
editor.backspace();
|
||||||
|
|
||||||
let message = (on_change)(editor.contents());
|
let message = (on_input)(editor.contents());
|
||||||
shell.publish(message);
|
shell.publish(message);
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::Delete => {
|
keyboard::KeyCode::Delete => {
|
||||||
|
|
@ -701,7 +728,7 @@ where
|
||||||
let mut editor = Editor::new(value, &mut state.cursor);
|
let mut editor = Editor::new(value, &mut state.cursor);
|
||||||
editor.delete();
|
editor.delete();
|
||||||
|
|
||||||
let message = (on_change)(editor.contents());
|
let message = (on_input)(editor.contents());
|
||||||
shell.publish(message);
|
shell.publish(message);
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::Left => {
|
keyboard::KeyCode::Left => {
|
||||||
|
|
@ -776,7 +803,7 @@ where
|
||||||
let mut editor = Editor::new(value, &mut state.cursor);
|
let mut editor = Editor::new(value, &mut state.cursor);
|
||||||
editor.delete();
|
editor.delete();
|
||||||
|
|
||||||
let message = (on_change)(editor.contents());
|
let message = (on_input)(editor.contents());
|
||||||
shell.publish(message);
|
shell.publish(message);
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::V => {
|
keyboard::KeyCode::V => {
|
||||||
|
|
@ -803,7 +830,7 @@ where
|
||||||
let message = if let Some(paste) = &on_paste {
|
let message = if let Some(paste) = &on_paste {
|
||||||
(paste)(editor.contents())
|
(paste)(editor.contents())
|
||||||
} else {
|
} else {
|
||||||
(on_change)(editor.contents())
|
(on_input)(editor.contents())
|
||||||
};
|
};
|
||||||
shell.publish(message);
|
shell.publish(message);
|
||||||
|
|
||||||
|
|
@ -897,6 +924,7 @@ pub fn draw<Renderer>(
|
||||||
placeholder: &str,
|
placeholder: &str,
|
||||||
size: Option<f32>,
|
size: Option<f32>,
|
||||||
font: &Renderer::Font,
|
font: &Renderer::Font,
|
||||||
|
is_disabled: bool,
|
||||||
is_secure: bool,
|
is_secure: bool,
|
||||||
icon: Option<&Icon<Renderer::Font>>,
|
icon: Option<&Icon<Renderer::Font>>,
|
||||||
style: &<Renderer::Theme as StyleSheet>::Style,
|
style: &<Renderer::Theme as StyleSheet>::Style,
|
||||||
|
|
@ -914,7 +942,9 @@ pub fn draw<Renderer>(
|
||||||
|
|
||||||
let is_mouse_over = bounds.contains(cursor_position);
|
let is_mouse_over = bounds.contains(cursor_position);
|
||||||
|
|
||||||
let appearance = if state.is_focused() {
|
let appearance = if is_disabled {
|
||||||
|
theme.disabled(style)
|
||||||
|
} else if state.is_focused() {
|
||||||
theme.focused(style)
|
theme.focused(style)
|
||||||
} else if is_mouse_over {
|
} else if is_mouse_over {
|
||||||
theme.hovered(style)
|
theme.hovered(style)
|
||||||
|
|
@ -1057,6 +1087,8 @@ pub fn draw<Renderer>(
|
||||||
content: if text.is_empty() { placeholder } else { &text },
|
content: if text.is_empty() { placeholder } else { &text },
|
||||||
color: if text.is_empty() {
|
color: if text.is_empty() {
|
||||||
theme.placeholder_color(style)
|
theme.placeholder_color(style)
|
||||||
|
} else if is_disabled {
|
||||||
|
theme.disabled_color(style)
|
||||||
} else {
|
} else {
|
||||||
theme.value_color(style)
|
theme.value_color(style)
|
||||||
},
|
},
|
||||||
|
|
@ -1085,9 +1117,14 @@ pub fn draw<Renderer>(
|
||||||
pub fn mouse_interaction(
|
pub fn mouse_interaction(
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
|
is_disabled: bool,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
if layout.bounds().contains(cursor_position) {
|
if layout.bounds().contains(cursor_position) {
|
||||||
mouse::Interaction::Text
|
if is_disabled {
|
||||||
|
mouse::Interaction::NotAllowed
|
||||||
|
} else {
|
||||||
|
mouse::Interaction::Text
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mouse::Interaction::default()
|
mouse::Interaction::default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@ pub trait StyleSheet {
|
||||||
/// Produces the [`Color`] of the value of a text input.
|
/// Produces the [`Color`] of the value of a text input.
|
||||||
fn value_color(&self, style: &Self::Style) -> Color;
|
fn value_color(&self, style: &Self::Style) -> Color;
|
||||||
|
|
||||||
|
/// Produces the [`Color`] of the value of a disabled text input.
|
||||||
|
fn disabled_color(&self, style: &Self::Style) -> Color;
|
||||||
|
|
||||||
/// Produces the [`Color`] of the selection of a text input.
|
/// Produces the [`Color`] of the selection of a text input.
|
||||||
fn selection_color(&self, style: &Self::Style) -> Color;
|
fn selection_color(&self, style: &Self::Style) -> Color;
|
||||||
|
|
||||||
|
|
@ -40,4 +43,7 @@ pub trait StyleSheet {
|
||||||
fn hovered(&self, style: &Self::Style) -> Appearance {
|
fn hovered(&self, style: &Self::Style) -> Appearance {
|
||||||
self.focused(style)
|
self.focused(style)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Produces the style of a disabled text input.
|
||||||
|
fn disabled(&self, style: &Self::Style) -> Appearance;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1093,4 +1093,28 @@ impl text_input::StyleSheet for Theme {
|
||||||
|
|
||||||
palette.primary.weak.color
|
palette.primary.weak.color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn disabled(&self, style: &Self::Style) -> text_input::Appearance {
|
||||||
|
if let TextInput::Custom(custom) = style {
|
||||||
|
return custom.disabled(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
let palette = self.extended_palette();
|
||||||
|
|
||||||
|
text_input::Appearance {
|
||||||
|
background: palette.background.weak.color.into(),
|
||||||
|
border_radius: 2.0,
|
||||||
|
border_width: 1.0,
|
||||||
|
border_color: palette.background.strong.color,
|
||||||
|
icon_color: palette.background.strong.color,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disabled_color(&self, style: &Self::Style) -> Color {
|
||||||
|
if let TextInput::Custom(custom) = style {
|
||||||
|
return custom.disabled_color(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.placeholder_color(style)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,7 @@ pub fn mouse_interaction(
|
||||||
winit::window::CursorIcon::EwResize
|
winit::window::CursorIcon::EwResize
|
||||||
}
|
}
|
||||||
Interaction::ResizingVertically => winit::window::CursorIcon::NsResize,
|
Interaction::ResizingVertically => winit::window::CursorIcon::NsResize,
|
||||||
|
Interaction::NotAllowed => winit::window::CursorIcon::NotAllowed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue