[button] add ability to disable Button

This commit is contained in:
Emil Ernerfeldt 2020-06-22 10:36:27 +02:00
parent 10a9d48091
commit 67bafad8f9
7 changed files with 68 additions and 15 deletions

View File

@ -154,7 +154,7 @@ impl CollapsingHeader {
.text_style(TextStyle::Button) .text_style(TextStyle::Button)
.multiline(false), .multiline(false),
default_open: false, default_open: false,
id_source : None, id_source: None,
} }
} }

View File

@ -321,6 +321,7 @@ impl Context {
if interaction_id.is_none() || sense == Sense::nothing() { if interaction_id.is_none() || sense == Sense::nothing() {
// Not interested in input: // Not interested in input:
return InteractInfo { return InteractInfo {
sense,
rect, rect,
hovered, hovered,
clicked: false, clicked: false,
@ -341,6 +342,7 @@ impl Context {
if self.input.mouse.pressed { if self.input.mouse.pressed {
if hovered { if hovered {
let mut info = InteractInfo { let mut info = InteractInfo {
sense,
rect, rect,
hovered: true, hovered: true,
clicked: false, clicked: false,
@ -368,6 +370,7 @@ impl Context {
} else { } else {
// miss // miss
InteractInfo { InteractInfo {
sense,
rect, rect,
hovered, hovered,
clicked: false, clicked: false,
@ -378,6 +381,7 @@ impl Context {
} else if self.input.mouse.released { } else if self.input.mouse.released {
let clicked = hovered && active; let clicked = hovered && active;
InteractInfo { InteractInfo {
sense,
rect, rect,
hovered, hovered,
clicked, clicked,
@ -386,6 +390,7 @@ impl Context {
} }
} else if self.input.mouse.down { } else if self.input.mouse.down {
InteractInfo { InteractInfo {
sense,
rect, rect,
hovered: hovered && active, hovered: hovered && active,
clicked: false, clicked: false,
@ -394,6 +399,7 @@ impl Context {
} }
} else { } else {
InteractInfo { InteractInfo {
sense,
rect, rect,
hovered, hovered,
clicked: false, clicked: false,

View File

@ -274,7 +274,7 @@ impl ExampleWindow {
#[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "with_serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "with_serde", serde(default))] #[cfg_attr(feature = "with_serde", serde(default))]
struct Widgets { struct Widgets {
checked: bool, button_enabled: bool,
count: usize, count: usize,
radio: usize, radio: usize,
slider_value: f32, slider_value: f32,
@ -285,7 +285,7 @@ struct Widgets {
impl Default for Widgets { impl Default for Widgets {
fn default() -> Self { fn default() -> Self {
Self { Self {
checked: true, button_enabled: true,
radio: 0, radio: 0,
count: 0, count: 0,
slider_value: 3.14, slider_value: 3.14,
@ -305,8 +305,6 @@ impl Widgets {
); );
}); });
ui.add(Checkbox::new(&mut self.checked, "checkbox"));
ui.horizontal(|ui| { ui.horizontal(|ui| {
if ui.add(radio(self.radio == 0, "First")).clicked { if ui.add(radio(self.radio == 0, "First")).clicked {
self.radio = 0; self.radio = 0;
@ -319,9 +317,11 @@ impl Widgets {
} }
}); });
ui.add(Checkbox::new(&mut self.button_enabled, "Button enabled"));
ui.inner_layout(Layout::horizontal(Align::Center), |ui| { ui.inner_layout(Layout::horizontal(Align::Center), |ui| {
if ui if ui
.add(Button::new("Click me")) .add(Button::new("Click me").enabled(self.button_enabled))
.tooltip_text("This will just increase a counter.") .tooltip_text("This will just increase a counter.")
.clicked .clicked
{ {

View File

@ -104,6 +104,7 @@ pub struct Interact {
pub active: WidgetStyle, pub active: WidgetStyle,
pub hovered: WidgetStyle, pub hovered: WidgetStyle,
pub inactive: WidgetStyle, pub inactive: WidgetStyle,
pub disabled: WidgetStyle,
} }
impl Default for Interact { impl Default for Interact {
@ -133,13 +134,23 @@ impl Default for Interact {
rect_outline: Some(LineStyle::new(1.0, white(128))), rect_outline: Some(LineStyle::new(1.0, white(128))),
corner_radius: 4.0, corner_radius: 4.0,
}, },
disabled: WidgetStyle {
bg_fill: None,
fill: srgba(50, 50, 50, 255),
stroke_color: gray(128, 255), // Should look grayed out
stroke_width: 0.5,
rect_outline: Some(LineStyle::new(0.5, white(128))),
corner_radius: 4.0,
},
} }
} }
} }
impl Interact { impl Interact {
pub fn style(&self, interact: &InteractInfo) -> &WidgetStyle { pub fn style(&self, interact: &InteractInfo) -> &WidgetStyle {
if interact.active { if interact.sense == Sense::nothing() {
&self.disabled
} else if interact.active {
&self.active &self.active
} else if interact.hovered { } else if interact.hovered {
&self.hovered &self.hovered

View File

@ -41,6 +41,9 @@ impl Default for CursorIcon {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "with_serde", derive(serde::Serialize))] #[cfg_attr(feature = "with_serde", derive(serde::Serialize))]
pub struct InteractInfo { pub struct InteractInfo {
/// The senses (click or drag) that the widget is interested in (if any).
pub sense: Sense,
/// The mouse is hovering above this thing /// The mouse is hovering above this thing
pub hovered: bool, pub hovered: bool,
@ -59,6 +62,7 @@ pub struct InteractInfo {
impl InteractInfo { impl InteractInfo {
pub fn nothing() -> Self { pub fn nothing() -> Self {
Self { Self {
sense: Sense::nothing(),
hovered: false, hovered: false,
clicked: false, clicked: false,
double_clicked: false, double_clicked: false,
@ -69,6 +73,7 @@ impl InteractInfo {
pub fn union(self, other: Self) -> Self { pub fn union(self, other: Self) -> Self {
Self { Self {
sense: self.sense.union(other.sense),
hovered: self.hovered || other.hovered, hovered: self.hovered || other.hovered,
clicked: self.clicked || other.clicked, clicked: self.clicked || other.clicked,
double_clicked: self.double_clicked || other.double_clicked, double_clicked: self.double_clicked || other.double_clicked,
@ -82,6 +87,9 @@ impl InteractInfo {
// TODO: rename GuiResponse // TODO: rename GuiResponse
pub struct GuiResponse { pub struct GuiResponse {
/// The senses (click or drag) that the widget is interested in (if any).
pub sense: Sense,
/// The mouse is hovering above this /// The mouse is hovering above this
pub hovered: bool, pub hovered: bool,
@ -120,6 +128,7 @@ impl GuiResponse {
impl Into<InteractInfo> for GuiResponse { impl Into<InteractInfo> for GuiResponse {
fn into(self) -> InteractInfo { fn into(self) -> InteractInfo {
InteractInfo { InteractInfo {
sense: self.sense,
hovered: self.hovered, hovered: self.hovered,
clicked: self.clicked, clicked: self.clicked,
double_clicked: self.double_clicked, double_clicked: self.double_clicked,
@ -133,6 +142,7 @@ impl Into<InteractInfo> for GuiResponse {
/// What sort of interaction is a widget sensitive to? /// What sort of interaction is a widget sensitive to?
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "with_serde", derive(serde::Serialize))]
pub struct Sense { pub struct Sense {
/// buttons, sliders, windows ... /// buttons, sliders, windows ...
pub click: bool, pub click: bool,
@ -170,4 +180,12 @@ impl Sense {
drag: true, drag: true,
} }
} }
#[must_use]
pub fn union(self, other: Self) -> Self {
Self {
click: self.click | other.click,
drag: self.drag | other.drag,
}
}
} }

View File

@ -303,8 +303,7 @@ impl Ui {
&mut self, &mut self,
explicit_id_source: Option<Id>, explicit_id_source: Option<Id>,
default_id_source: Option<&str>, default_id_source: Option<&str>,
) -> Id ) -> Id {
{
let id = if let Some(explicit_id_source) = explicit_id_source { let id = if let Some(explicit_id_source) = explicit_id_source {
self.id.with(&explicit_id_source) self.id.with(&explicit_id_source)
} else { } else {
@ -315,7 +314,8 @@ impl Ui {
self.make_position_id() self.make_position_id()
} }
}; };
self.ctx.register_unique_id(id, default_id_source.unwrap_or_default(), self.cursor) self.ctx
.register_unique_id(id, default_id_source.unwrap_or_default(), self.cursor)
} }
/// Make an Id that is unique to this positon. /// Make an Id that is unique to this positon.
@ -349,12 +349,21 @@ impl Ui {
#[must_use] #[must_use]
pub fn response(&mut self, interact: InteractInfo) -> GuiResponse { pub fn response(&mut self, interact: InteractInfo) -> GuiResponse {
// TODO: unify GuiResponse and InteractInfo. They are the same thing! // TODO: unify GuiResponse and InteractInfo. They are the same thing!
let InteractInfo {
sense,
hovered,
clicked,
double_clicked,
active,
rect,
} = interact;
GuiResponse { GuiResponse {
hovered: interact.hovered, sense,
clicked: interact.clicked, hovered,
double_clicked: interact.double_clicked, clicked,
active: interact.active, double_clicked,
rect: interact.rect, active,
rect,
ctx: self.ctx.clone(), ctx: self.ctx.clone(),
} }
} }

View File

@ -232,6 +232,15 @@ impl Button {
self.sense = sense; self.sense = sense;
self self
} }
/// If you set this to `false`, the button will be grayed out and un-clickable.
/// `enabled(false)` has the same effect as calling `sense(Sense::nothing())`.
pub fn enabled(mut self, enabled: bool) -> Self {
if !enabled {
self.sense = Sense::nothing();
}
self
}
} }
impl Widget for Button { impl Widget for Button {