From 8df9575a16d3bc2ad77b6da54e03c833dd41ffdf Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 15 Nov 2022 17:06:49 +0100 Subject: [PATCH] Move X-Y pad tooltip updating to a function --- plugins/diopser/src/editor/xy_pad.rs | 76 +++++++++++++++------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/plugins/diopser/src/editor/xy_pad.rs b/plugins/diopser/src/editor/xy_pad.rs index 7fdc8f9e..64f0eac3 100644 --- a/plugins/diopser/src/editor/xy_pad.rs +++ b/plugins/diopser/src/editor/xy_pad.rs @@ -215,6 +215,44 @@ impl XyPad { self.x_param_base.end_set_parameter(cx); self.y_param_base.end_set_parameter(cx); } + + /// Used to position the tooltip to the top right of the mouse cursor. If there's not enough + /// space there, the tooltip will be pushed to the left or the right of the cursor. + fn update_tooltip_pos(&mut self, cx: &mut EventContext) { + let bounds = cx.cache.get_bounds(cx.current()); + let relative_x = cx.mouse.cursorx - bounds.x; + let relative_y = cx.mouse.cursory - bounds.y; + + // These positions need to take DPI scaling into account + let dpi_scale = cx.style.dpi_factor as f32; + let padding = 2.0 * dpi_scale; + + // If there's not enough space at the top right, we'll move the tooltip to the + // bottom and/or the left + let tooltip_entity = cx + .tree + .get_last_child(cx.current()) + .expect("Missing child view in X-Y pad"); + let tooltip_bounds = cx.cache.get_bounds(tooltip_entity); + // NOTE: The width can vary drastically depending on the frequency value, so we'll + // hardcode a minimum width in this comparison to avoid this from jumping + // around. The parameter value updates are a bit delayed when dragging the + // parameter, so we may be using an old width here. + let tooltip_pos_x = + if (relative_x + tooltip_bounds.w.max(150.0) + (padding * 2.0)) >= bounds.w { + relative_x - padding - tooltip_bounds.w + } else { + relative_x + padding + }; + let tooltip_pos_y = if (relative_y - tooltip_bounds.h - (padding * 2.0)) <= 0.0 { + relative_y + padding + } else { + relative_y - padding - tooltip_bounds.h + }; + + self.tooltip_pos_x = Pixels(tooltip_pos_x / dpi_scale); + self.tooltip_pos_y = Pixels(tooltip_pos_y / dpi_scale); + } } impl XyPadHandle { @@ -290,42 +328,12 @@ impl View for XyPad { } } WindowEvent::MouseMove(x, y) => { - // This is used to position the tooltip to the top right of the mouse cursor - let bounds = cx.cache.get_bounds(cx.current()); - let relative_x = x - bounds.x; - let relative_y = y - bounds.y; - - // These positions need to take DPI scaling into account - let dpi_scale = cx.style.dpi_factor as f32; - let padding = 2.0 * dpi_scale; - - // If there's not enough space at the top right, we'll move the tooltip to the - // bottom and/or the left - let tooltip_entity = cx - .tree - .get_last_child(cx.current()) - .expect("Missing child view in X-Y pad"); - let tooltip_bounds = cx.cache.get_bounds(tooltip_entity); - // NOTE: The width can vary drastically depending on the frequency value, so we'll - // hardcode a minimum width in this comparison to avoid this from jumping - // around. The parameter value updates are a bit delayed when dragging the - // parameter, so we may be using an old width here. - let tooltip_pos_x = - if (relative_x + tooltip_bounds.w.max(150.0) + (padding * 2.0)) >= bounds.w { - relative_x - padding - tooltip_bounds.w - } else { - relative_x + padding - }; - let tooltip_pos_y = if (relative_y - tooltip_bounds.h - (padding * 2.0)) <= 0.0 { - relative_y + padding - } else { - relative_y - padding - tooltip_bounds.h - }; - - self.tooltip_pos_x = Pixels(tooltip_pos_x / dpi_scale); - self.tooltip_pos_y = Pixels(tooltip_pos_y / dpi_scale); + // The tooltip should track the mouse position + self.update_tooltip_pos(cx); if self.drag_active { + let dpi_scale = cx.style.dpi_factor as f32; + // If shift is being held then the drag should be more granular instead of // absolute // TODO: Mouse warping is really needed here, but it's not exposed right now