ui.horizontal(...) etc returns Response

This is much more ergonomic than just returning a Rect (like previously).
The Response only contains `hover` checks.
This commit is contained in:
Emil Ernerfeldt 2020-10-14 14:42:40 +02:00
parent 7db71eb875
commit 7561ccc189
6 changed files with 36 additions and 29 deletions

View file

@ -62,7 +62,7 @@ impl State {
ui: &mut Ui, ui: &mut Ui,
id: Id, id: Id,
add_contents: impl FnOnce(&mut Ui) -> R, add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<(R, Rect)> { ) -> Option<(R, Response)> {
let openness = self.openness(ui.ctx(), id); let openness = self.openness(ui.ctx(), id);
let animate = 0.0 < openness && openness < 1.0; let animate = 0.0 < openness && openness < 1.0;
if animate { if animate {
@ -96,10 +96,10 @@ impl State {
r r
})) }))
} else if self.open || ui.memory().all_collpasing_are_open { } else if self.open || ui.memory().all_collpasing_are_open {
let ret_rect = ui.add_custom(add_contents); let (ret, response) = ui.add_custom(add_contents);
let full_size = ret_rect.1.size(); let full_size = response.rect.size();
self.open_height = Some(full_size.y); self.open_height = Some(full_size.y);
Some(ret_rect) Some((ret, response))
} else { } else {
None None
} }

View file

@ -269,7 +269,7 @@ impl<'open> Window<'open> {
); );
resize.min_size.x = resize.min_size.x.at_least(title_bar.rect.width()); // Prevent making window smaller than title bar width resize.min_size.x = resize.min_size.x.at_least(title_bar.rect.width()); // Prevent making window smaller than title bar width
let content_rect = collapsing let content_response = collapsing
.add_contents(&mut frame.content_ui, collapsing_id, |ui| { .add_contents(&mut frame.content_ui, collapsing_id, |ui| {
resize.show(ui, |ui| { resize.show(ui, |ui| {
// Add some spacing between title and content: // Add some spacing between title and content:
@ -295,7 +295,7 @@ impl<'open> Window<'open> {
title_bar.ui( title_bar.ui(
&mut area_content_ui, &mut area_content_ui,
outer_rect, outer_rect,
content_rect, content_response,
open, open,
&mut collapsing, &mut collapsing,
collapsible, collapsible,
@ -612,7 +612,7 @@ fn show_title_bar(
collapsing: &mut collapsing_header::State, collapsing: &mut collapsing_header::State,
collapsible: bool, collapsible: bool,
) -> TitleBar { ) -> TitleBar {
let title_bar_and_rect = ui.horizontal(|ui| { let (title_bar, response) = ui.horizontal(|ui| {
ui.set_min_height(title_label.font_height(ui.fonts(), ui.style())); ui.set_min_height(title_label.font_height(ui.fonts(), ui.style()));
let item_spacing = ui.style().spacing.item_spacing; let item_spacing = ui.style().spacing.item_spacing;
@ -656,8 +656,8 @@ fn show_title_bar(
}); });
TitleBar { TitleBar {
rect: title_bar_and_rect.1, rect: response.rect,
..title_bar_and_rect.0 ..title_bar
} }
} }
@ -666,14 +666,14 @@ impl TitleBar {
mut self, mut self,
ui: &mut Ui, ui: &mut Ui,
outer_rect: Rect, outer_rect: Rect,
content_rect: Option<Rect>, content_response: Option<Response>,
open: Option<&mut bool>, open: Option<&mut bool>,
collapsing: &mut collapsing_header::State, collapsing: &mut collapsing_header::State,
collapsible: bool, collapsible: bool,
) { ) {
if let Some(content_rect) = content_rect { if let Some(content_response) = &content_response {
// Now we know how large we got to be: // Now we know how large we got to be:
self.rect.max.x = self.rect.max.x.max(content_rect.max.x); self.rect.max.x = self.rect.max.x.max(content_response.rect.max.x);
} }
if let Some(open) = open { if let Some(open) = open {
@ -687,11 +687,11 @@ impl TitleBar {
self.title_label self.title_label
.paint_galley(ui, self.title_rect.min, self.title_galley); .paint_galley(ui, self.title_rect.min, self.title_galley);
if let Some(content_rect) = content_rect { if let Some(content_response) = &content_response {
// paint separator between title and content: // paint separator between title and content:
let left = outer_rect.left(); let left = outer_rect.left();
let right = outer_rect.right(); let right = outer_rect.right();
let y = content_rect.top() + ui.style().spacing.item_spacing.y * 0.5; let y = content_response.rect.top() + ui.style().spacing.item_spacing.y * 0.5;
ui.painter().line_segment( ui.painter().line_segment(
[pos2(left, y), pos2(right, y)], [pos2(left, y), pos2(right, y)],
ui.style().visuals.widgets.inactive.bg_stroke, ui.style().visuals.widgets.inactive.bg_stroke,

View file

@ -37,7 +37,7 @@ impl BarState {
} }
} }
pub fn bar<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Rect) { pub fn bar<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Response) {
ui.horizontal(|ui| { ui.horizontal(|ui| {
Frame::menu_bar(ui.style()).show(ui, |ui| { Frame::menu_bar(ui.style()).show(ui, |ui| {
let mut style = ui.style().clone(); let mut style = ui.style().clone();

View file

@ -458,7 +458,7 @@ fn ui_slider_vec2(
range: std::ops::RangeInclusive<f32>, range: std::ops::RangeInclusive<f32>,
text: &str, text: &str,
) -> Response { ) -> Response {
let (_, rect) = ui.horizontal(|ui| { ui.horizontal(|ui| {
/* /*
let fsw = full slider_width let fsw = full slider_width
let ssw = small slider_width let ssw = small slider_width
@ -481,8 +481,8 @@ fn ui_slider_vec2(
ui.add(Slider::f32(&mut value.x, range.clone()).text("w")); ui.add(Slider::f32(&mut value.x, range.clone()).text("w"));
ui.add(Slider::f32(&mut value.y, range.clone()).text("h")); ui.add(Slider::f32(&mut value.y, range.clone()).text("h"));
ui.label(text); ui.label(text);
}); })
ui.interact_hover(rect) .1
} }
fn ui_color(ui: &mut Ui, srgba: &mut Srgba, text: &str) { fn ui_color(ui: &mut Ui, srgba: &mut Srgba, text: &str) {

View file

@ -179,6 +179,7 @@ pub struct Sense {
} }
impl Sense { impl Sense {
/// Senses no clicks or drags (but everything senses mouse hover).
pub fn nothing() -> Self { pub fn nothing() -> Self {
Self { Self {
click: false, click: false,

View file

@ -657,12 +657,13 @@ impl Ui {
} }
/// Create a child ui. You can use this to temporarily change the Style of a sub-region, for instance. /// Create a child ui. You can use this to temporarily change the Style of a sub-region, for instance.
pub fn add_custom<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Rect) { pub fn add_custom<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Response) {
let child_rect = self.available(); let child_rect = self.available();
let mut child_ui = self.child_ui(child_rect, self.layout); let mut child_ui = self.child_ui(child_rect, self.layout);
let r = add_contents(&mut child_ui); let ret = add_contents(&mut child_ui);
let size = child_ui.min_size(); let size = child_ui.min_size();
(r, self.allocate_space(size)) let rect = self.allocate_space(size);
(ret, self.interact_hover(rect))
} }
/// Create a child ui which is indented to the right /// Create a child ui which is indented to the right
@ -670,7 +671,7 @@ impl Ui {
&mut self, &mut self,
id_source: impl Hash, id_source: impl Hash,
add_contents: impl FnOnce(&mut Ui) -> R, add_contents: impl FnOnce(&mut Ui) -> R,
) -> (R, Rect) { ) -> (R, Response) {
assert!( assert!(
self.layout().dir() == Direction::Vertical, self.layout().dir() == Direction::Vertical,
"You can only indent vertical layouts" "You can only indent vertical layouts"
@ -693,7 +694,8 @@ impl Ui {
self.style().visuals.widgets.noninteractive.bg_stroke, self.style().visuals.widgets.noninteractive.bg_stroke,
); );
(ret, self.allocate_space(indent + size)) let rect = self.allocate_space(indent + size);
(ret, self.interact_hover(rect))
} }
pub fn left_column(&mut self, width: f32) -> Ui { pub fn left_column(&mut self, width: f32) -> Ui {
@ -732,7 +734,11 @@ impl Ui {
/// The initial height is `style.spacing.interact_size.y`. /// The initial height is `style.spacing.interact_size.y`.
/// Centering is almost always what you want if you are /// Centering is almost always what you want if you are
/// planning to to mix widgets or just different types of text. /// planning to to mix widgets or just different types of text.
pub fn horizontal<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Rect) { ///
/// The returned `Response` will only have checked for mouse hover
/// but can be used for tooltips (`on_hover_text`).
/// It also contains the `Rect` used by the horizontal layout.
pub fn horizontal<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Response) {
let initial_size = vec2( let initial_size = vec2(
self.available().width(), self.available().width(),
self.style().spacing.interact_size.y, // Assume there will be something interactive on the horizontal layout self.style().spacing.interact_size.y, // Assume there will be something interactive on the horizontal layout
@ -750,7 +756,7 @@ impl Ui {
/// Start a ui with vertical layout. /// Start a ui with vertical layout.
/// Widgets will be left-justified. /// Widgets will be left-justified.
pub fn vertical<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Rect) { pub fn vertical<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> (R, Response) {
self.with_layout(Layout::vertical(Align::Min), add_contents) self.with_layout(Layout::vertical(Align::Min), add_contents)
} }
@ -759,25 +765,25 @@ impl Ui {
layout: Layout, layout: Layout,
initial_size: Vec2, initial_size: Vec2,
add_contents: impl FnOnce(&mut Self) -> R, add_contents: impl FnOnce(&mut Self) -> R,
) -> (R, Rect) { ) -> (R, Response) {
let child_rect = self.layout.rect_from_cursor_size(self.cursor, initial_size); let child_rect = self.layout.rect_from_cursor_size(self.cursor, initial_size);
let mut child_ui = self.child_ui(child_rect, layout); let mut child_ui = self.child_ui(child_rect, layout);
let ret = add_contents(&mut child_ui); let ret = add_contents(&mut child_ui);
let size = child_ui.min_size(); let size = child_ui.min_size();
let rect = self.allocate_space(size); let rect = self.allocate_space(size);
(ret, rect) (ret, self.interact_hover(rect))
} }
pub fn with_layout<R>( pub fn with_layout<R>(
&mut self, &mut self,
layout: Layout, layout: Layout,
add_contents: impl FnOnce(&mut Self) -> R, add_contents: impl FnOnce(&mut Self) -> R,
) -> (R, Rect) { ) -> (R, Response) {
let mut child_ui = self.child_ui(self.available(), layout); let mut child_ui = self.child_ui(self.available(), layout);
let ret = add_contents(&mut child_ui); let ret = add_contents(&mut child_ui);
let size = child_ui.min_size(); let size = child_ui.min_size();
let rect = self.allocate_space(size); let rect = self.allocate_space(size);
(ret, rect) (ret, self.interact_hover(rect))
} }
/// Temporarily split split an Ui into several columns. /// Temporarily split split an Ui into several columns.