diff --git a/Cargo.toml b/Cargo.toml index a43ed883..581ea0fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ default = [ "modal", "tab_bar", "tabs", - #"time_picker", + "time_picker", #"wrap", #"selection_list", #"split", @@ -95,7 +95,7 @@ members = [ #"examples/multiple_modals", "examples/tab_bar", "examples/tabs", - #"examples/time_picker", + "examples/time_picker", #"examples/wrap", "examples/number_input", #"examples/selection_list", diff --git a/src/native/overlay/time_picker.rs b/src/native/overlay/time_picker.rs index b3dde92e..46f44a91 100644 --- a/src/native/overlay/time_picker.rs +++ b/src/native/overlay/time_picker.rs @@ -503,7 +503,7 @@ where Message: 'static + Clone, Theme: 'a + StyleSheet + button::StyleSheet + text::StyleSheet + container::StyleSheet, { - fn layout(&self, renderer: &Renderer, bounds: Size, position: Point) -> Node { + fn layout(&mut self, renderer: &Renderer, bounds: Size, position: Point) -> Node { let limits = Limits::new(Size::ZERO, bounds) .pad(Padding::from(PADDING)) .width(Length::Fill) @@ -517,7 +517,9 @@ where // Pre-Buttons TODO: get rid of it let cancel_limits = limits; - let cancel_button = self.cancel_button.layout(renderer, &cancel_limits); + let cancel_button = + self.cancel_button + .layout(&mut self.tree.children[0], renderer, &cancel_limits); let limits = limits.shrink(Size::new( 0.0, @@ -528,7 +530,7 @@ where let mut clock = Row::<(), Renderer>::new() .width(Length::Fill) .height(Length::Fill) - .layout(renderer, &limits); + .layout(&mut self.tree, renderer, &limits); clock.move_to(Point::new( clock.bounds().x + PADDING, @@ -544,12 +546,16 @@ where let cancel_limits = limits.max_width(((clock.bounds().width / 2.0) - BUTTON_SPACING).max(0.0)); - let mut cancel_button = self.cancel_button.layout(renderer, &cancel_limits); + let mut cancel_button = + self.cancel_button + .layout(&mut self.tree.children[0], renderer, &cancel_limits); let submit_limits = limits.max_width(((clock.bounds().width / 2.0) - BUTTON_SPACING).max(0.0)); - let mut submit_button = self.submit_button.layout(renderer, &submit_limits); + let mut submit_button = + self.submit_button + .layout(&mut self.tree.children[1], renderer, &submit_limits); cancel_button.move_to(Point { x: cancel_button.bounds().x + PADDING, @@ -919,7 +925,7 @@ where /// Defines the layout of the digital clock of the time picker. fn digital_clock( - time_picker: &TimePickerOverlay<'_, Message, Theme>, + time_picker: &mut TimePickerOverlay<'_, Message, Theme>, renderer: &Renderer, limits: Limits, ) -> Node @@ -927,10 +933,10 @@ where Message: 'static + Clone, Theme: StyleSheet + button::StyleSheet + text::StyleSheet + container::StyleSheet, { - let arrow_size = renderer.default_size(); - let font_size = 1.2 * renderer.default_size(); + let arrow_size = renderer.default_size().0; + let font_size = 1.2 * renderer.default_size().0; - let mut digital_clock_row = Row::<(), Renderer>::new() + let mut digital_clock_row = Row::>::new() .align_items(Alignment::Center) .height(Length::Shrink) .width(Length::Shrink) @@ -1032,12 +1038,25 @@ where ); } - Container::new(digital_clock_row) + let container = Container::new(digital_clock_row) .width(Length::Fill) .height(Length::Shrink) .center_x() - .center_y() - .layout(renderer, &limits) + .center_y(); + + let element: Element> = Element::new(container); + let container_tree = if let Some(child_tree) = time_picker.tree.children.get_mut(2) { + child_tree.diff(element.as_widget()); + child_tree + } else { + let child_tree = Tree::new(element.as_widget()); + time_picker.tree.children.insert(2, child_tree); + &mut time_picker.tree.children[2] + }; + + element + .as_widget() + .layout(container_tree, renderer, &limits) } /// Draws the analog clock. @@ -1189,7 +1208,7 @@ fn draw_clock( .get(&clock_style_state) .expect("Style Sheet not found.") .clock_number_color, - size: period_size, + size: core::Pixels(period_size), font: renderer.default_font(), horizontal_alignment: Horizontal::Center, vertical_alignment: Vertical::Center, @@ -1234,7 +1253,7 @@ fn draw_clock( .get(&style_state) .expect("Style Sheet not found.") .clock_number_color, - size: number_size, + size: core::Pixels(number_size), font: renderer.default_font(), horizontal_alignment: Horizontal::Center, vertical_alignment: Vertical::Center, @@ -1269,7 +1288,7 @@ fn draw_clock( .get(&style_state) .expect("Style Sheet not found.") .clock_number_color, - size: number_size, + size: core::Pixels(number_size), font: renderer.default_font(), horizontal_alignment: Horizontal::Center, vertical_alignment: Vertical::Center, @@ -1315,7 +1334,7 @@ fn draw_clock( .get(&style_state) .expect("Style Sheet not found.") .clock_number_color, - size: number_size, + size: core::Pixels(number_size), font: renderer.default_font(), horizontal_alignment: Horizontal::Center, vertical_alignment: Vertical::Center, @@ -1417,64 +1436,65 @@ fn draw_digital_clock( let mut buffer = [0; 4]; // Caret up - renderer.fill_text(core::Text { - content: char::from(Icon::CaretUpFill).encode_utf8(&mut buffer), - bounds: Rectangle { - x: up_bounds.center_x(), - y: up_bounds.center_y(), - ..up_bounds + renderer.fill_text( + core::Text { + content: char::from(Icon::CaretUpFill).encode_utf8(&mut buffer), + bounds: Size::new(up_bounds.width, up_bounds.height), + size: core::Pixels( + renderer.default_size().0 + if up_arrow_hovered { 1.0 } else { 0.0 }, + ), + font: crate::graphics::icons::ICON_FONT, + horizontal_alignment: Horizontal::Center, + vertical_alignment: Vertical::Center, + line_height: text::LineHeight::Relative(1.3), + shaping: text::Shaping::Basic, }, - size: renderer.default_size() + if up_arrow_hovered { 1.0 } else { 0.0 }, - color: style + Point::new(up_bounds.center_x(), up_bounds.center_y()), + style .get(&StyleState::Active) .expect("Style Sheet not found.") .text_color, - font: crate::graphics::icons::ICON_FONT, - horizontal_alignment: Horizontal::Center, - vertical_alignment: Vertical::Center, - line_height: text::LineHeight::Relative(1.3), - shaping: text::Shaping::Basic, - }); + ); // Text - renderer.fill_text(core::Text { - content: &text, - bounds: Rectangle { - x: center_bounds.center_x(), - y: center_bounds.center_y(), - ..center_bounds + renderer.fill_text( + core::Text { + content: &text, + bounds: Size::new(center_bounds.width, center_bounds.height), + size: renderer.default_size(), + font: renderer.default_font(), + horizontal_alignment: Horizontal::Center, + vertical_alignment: Vertical::Center, + line_height: text::LineHeight::Relative(1.3), + shaping: text::Shaping::Basic, }, - size: renderer.default_size(), - color: style + Point::new(center_bounds.center_x(), center_bounds.center_y()), + style .get(&StyleState::Active) .expect("Style Sheet not found.") .text_color, - font: renderer.default_font(), - horizontal_alignment: Horizontal::Center, - vertical_alignment: Vertical::Center, - line_height: text::LineHeight::Relative(1.3), - shaping: text::Shaping::Basic, - }); + ); // Down caret - renderer.fill_text(core::Text { - content: char::from(Icon::CaretDownFill).encode_utf8(&mut buffer), - bounds: Rectangle { - x: down_bounds.center_x(), - y: down_bounds.center_y(), - ..down_bounds + renderer.fill_text( + core::Text { + content: char::from(Icon::CaretDownFill).encode_utf8(&mut buffer), + bounds: Size::new(down_bounds.width, down_bounds.height), + size: core::Pixels( + renderer.default_size().0 + if down_arrow_hovered { 1.0 } else { 0.0 }, + ), + font: crate::graphics::icons::ICON_FONT, + horizontal_alignment: Horizontal::Center, + vertical_alignment: Vertical::Center, + line_height: text::LineHeight::Relative(1.3), + shaping: text::Shaping::Basic, }, - size: renderer.default_size() + if down_arrow_hovered { 1.0 } else { 0.0 }, - color: style + Point::new(down_bounds.center_x(), down_bounds.center_y()), + style .get(&StyleState::Active) .expect("Style Sheet not found.") .text_color, - font: crate::graphics::icons::ICON_FONT, - horizontal_alignment: Horizontal::Center, - vertical_alignment: Vertical::Center, - line_height: text::LineHeight::Relative(1.3), - shaping: text::Shaping::Basic, - }); + ); }; if !time_picker.state.use_24h { @@ -1504,21 +1524,27 @@ fn draw_digital_clock( let hour_minute_separator = children .next() .expect("Graphics: Layout should have a hour/minute separator layout"); - renderer.fill_text(core::Text { - content: ":", - bounds: Rectangle { - x: hour_minute_separator.bounds().center_x(), - y: hour_minute_separator.bounds().center_y(), - ..hour_minute_separator.bounds() + + renderer.fill_text( + core::Text { + content: ":", + bounds: Size::new( + hour_minute_separator.bounds().width, + hour_minute_separator.bounds().height, + ), + size: renderer.default_size(), + font: renderer.default_font(), + horizontal_alignment: Horizontal::Center, + vertical_alignment: Vertical::Center, + line_height: text::LineHeight::Relative(1.3), + shaping: text::Shaping::Basic, }, - size: renderer.default_size(), - color: style[&StyleState::Active].text_color, - font: renderer.default_font(), - horizontal_alignment: Horizontal::Center, - vertical_alignment: Vertical::Center, - line_height: text::LineHeight::Relative(1.3), - shaping: text::Shaping::Basic, - }); + Point::new( + hour_minute_separator.bounds().center_x(), + hour_minute_separator.bounds().center_y(), + ), + style[&StyleState::Active].text_color, + ); // Draw minutes let minute_layout = children @@ -1536,24 +1562,26 @@ fn draw_digital_clock( let minute_second_separator = children .next() .expect("Graphics: Layout should have a minute/second separator layout"); - renderer.fill_text(core::Text { - content: ":", - bounds: Rectangle { - x: minute_second_separator.bounds().center_x(), - y: minute_second_separator.bounds().center_y(), - ..minute_second_separator.bounds() + renderer.fill_text( + core::Text { + content: ":", + bounds: Size::new( + minute_second_separator.bounds().width, + minute_second_separator.bounds().height, + ), + size: renderer.default_size(), + font: renderer.default_font(), + horizontal_alignment: Horizontal::Center, + vertical_alignment: Vertical::Center, + line_height: text::LineHeight::Relative(1.3), + shaping: text::Shaping::Basic, }, - size: renderer.default_size(), - color: style - .get(&StyleState::Active) - .expect("Style Sheet not found.") - .text_color, - font: renderer.default_font(), - horizontal_alignment: Horizontal::Center, - vertical_alignment: Vertical::Center, - line_height: text::LineHeight::Relative(1.3), - shaping: text::Shaping::Basic, - }); + Point::new( + minute_second_separator.bounds().center_x(), + minute_second_separator.bounds().center_y(), + ), + style[&StyleState::Active].text_color, + ); // Draw seconds let second_layout = children @@ -1572,28 +1600,24 @@ fn draw_digital_clock( let period = children .next() .expect("Graphics: Layout should have a period layout"); - renderer.fill_text(core::Text { - content: if time_picker.state.time.hour12().0 { - "PM" - } else { - "AM" - }, - bounds: Rectangle { - x: period.bounds().center_x(), - y: period.bounds().center_y(), - ..period.bounds() + renderer.fill_text( + core::Text { + content: if time_picker.state.time.hour12().0 { + "PM" + } else { + "AM" + }, + bounds: Size::new(period.bounds().width, period.bounds().height), + size: renderer.default_size(), + font: renderer.default_font(), + horizontal_alignment: Horizontal::Center, + vertical_alignment: Vertical::Center, + line_height: text::LineHeight::Relative(1.3), + shaping: text::Shaping::Basic, }, - size: renderer.default_size(), - color: style - .get(&StyleState::Active) - .expect("Style Sheet not found.") - .text_color, - font: renderer.default_font(), - horizontal_alignment: Horizontal::Center, - vertical_alignment: Vertical::Center, - line_height: text::LineHeight::Relative(1.3), - shaping: text::Shaping::Basic, - }); + Point::new(period.bounds().center_x(), period.bounds().center_y()), + style[&StyleState::Active].text_color, + ); } } @@ -1708,7 +1732,7 @@ where unimplemented!("This should never be reached!") } - fn layout(&self, _renderer: &Renderer, _limits: &Limits) -> Node { + fn layout(&self, _tree: &mut Tree, _renderer: &Renderer, _limits: &Limits) -> Node { unimplemented!("This should never be reached!") } diff --git a/src/native/time_picker.rs b/src/native/time_picker.rs index a0dfe3df..533d3a41 100644 --- a/src/native/time_picker.rs +++ b/src/native/time_picker.rs @@ -197,8 +197,10 @@ where self.underlay.as_widget().height() } - fn layout(&self, renderer: &Renderer, limits: &Limits) -> Node { - self.underlay.as_widget().layout(renderer, limits) + fn layout(&self, tree: &mut Tree, renderer: &Renderer, limits: &Limits) -> Node { + self.underlay + .as_widget() + .layout(&mut tree.children[0], renderer, limits) } fn on_event(