From 21d02153af2df7cc424fcd3b11e780c90eb27399 Mon Sep 17 00:00:00 2001 From: Niklas Korz Date: Tue, 7 May 2024 23:04:10 +0200 Subject: [PATCH] Fix camera controls --- src/main_view.rs | 63 +++++++++++++++++++++++-------------------- src/reference_view.rs | 44 +++++++++++++++++------------- 2 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/main_view.rs b/src/main_view.rs index ecd9d55..da1904a 100644 --- a/src/main_view.rs +++ b/src/main_view.rs @@ -4,7 +4,7 @@ use crate::{ texture::Texture, }; use cgmath::{Matrix4, SquareMatrix, Vector2, Vector3}; -use egui::ImageSource; +use egui::{Image, ImageSource, Sense, Widget}; use egui_wgpu as egui_wgpu_backend; use std::{borrow::Cow, sync::mpsc::channel}; use wgpu::util::DeviceExt; @@ -702,43 +702,48 @@ impl MainView { { self.resize_texture(rpass, device, queue, size.x as u32, size.y as u32); } - let resp = ui.image(ImageSource::Texture((self.texture_id, size).into())); - let input = ui.input(|i| i.clone()); - if input.pointer.any_released() && !input.pointer.any_down() { - self.enable_adaptive_sampling(device); - } - let mut mouse_pos = None; - if let Some(pos) = resp.hover_pos() { - if input.key_pressed(egui::Key::Space) { + let resp = Image::new(ImageSource::Texture((self.texture_id, size).into())) + .sense(Sense::click_and_drag()) + .ui(ui); + if resp.contains_pointer() { + if ui.input(|i| i.key_pressed(egui::Key::Space)) { self.reset_camera(queue); } - if input.pointer.any_pressed() { - mouse_pos = Some([ - (pos.x - resp.rect.left()) / resp.rect.width(), - 1.0 - (pos.y - resp.rect.top()) / resp.rect.height(), - ]); + let scroll_delta = ui.input(|i| i.smooth_scroll_delta); + if scroll_delta.y != 0.0 { + self.on_zoom(queue, scroll_delta.y); } - let camera_op = if input.pointer.button_down(egui::PointerButton::Primary) { + } + if resp.dragged() && resp.interact_pointer_pos().is_some() { + self.enable_adaptive_sampling(device); + let pos = resp.interact_pointer_pos().unwrap(); + let camera_op = if resp.dragged_by(egui::PointerButton::Primary) { CameraOperation::Rotate - } else if input.pointer.button_down(egui::PointerButton::Secondary) { + } else if resp.dragged_by(egui::PointerButton::Secondary) { CameraOperation::Pan } else { CameraOperation::None }; - if input.pointer.is_moving() { - self.on_pointer_moved( - device, - queue, - camera_op, - (pos.x - resp.rect.left(), pos.y - resp.rect.top()), - ); - } - let scroll_delta = ui.input(|i| i.smooth_scroll_delta); - if scroll_delta.y != 0.0 { - self.on_zoom(queue, scroll_delta.y); - } + self.on_pointer_moved( + device, + queue, + camera_op, + (pos.x - resp.rect.left(), pos.y - resp.rect.top()), + ); + } else { + self.prev_pointer_pos = None; + } + // Return click position relative to render view if any + if resp.clicked() { + resp.interact_pointer_pos().map(|pos| { + [ + (pos.x - resp.rect.left()) / resp.rect.width(), + 1.0 - (pos.y - resp.rect.top()) / resp.rect.height(), + ] + }) + } else { + None } - mouse_pos } fn enable_adaptive_sampling(&mut self, device: &wgpu::Device) { diff --git a/src/reference_view.rs b/src/reference_view.rs index ec1e05e..9e586f3 100644 --- a/src/reference_view.rs +++ b/src/reference_view.rs @@ -1,5 +1,5 @@ use cgmath::{Vector2, Vector3}; -use egui::{load::SizedTexture, ImageSource}; +use egui::{load::SizedTexture, Image, ImageSource, Sense, Widget}; use egui_wgpu as egui_wgpu_backend; use wgpu::util::DeviceExt; @@ -303,33 +303,39 @@ impl ReferenceView { } pub fn show(&mut self, ui: &mut egui::Ui, _device: &wgpu::Device, queue: &wgpu::Queue) { - let resp = ui.image(ImageSource::Texture(SizedTexture::new( + let resp = Image::new(ImageSource::Texture(SizedTexture::new( self.texture_id, (INITIAL_SIDEBAR_WIDTH, INITIAL_SIDEBAR_WIDTH), - ))); - let input = ui.input(|i| i.clone()); - if let Some(pos) = resp.hover_pos() { - if input.key_pressed(egui::Key::Space) { + ))) + .sense(Sense::drag()) + .ui(ui); + if resp.contains_pointer() { + if ui.input(|i| i.key_pressed(egui::Key::Space)) { self.reset_camera(queue); } - let camera_op = if input.pointer.button_down(egui::PointerButton::Primary) { + let scroll_delta = ui.input(|i| i.smooth_scroll_delta); + if scroll_delta.y != 0.0 { + self.on_zoom(queue, scroll_delta.y); + } + } + if resp.dragged() { + let Some(pos) = resp.interact_pointer_pos() else { + return; + }; + let camera_op = if resp.dragged_by(egui::PointerButton::Primary) { CameraOperation::Rotate - } else if input.pointer.button_down(egui::PointerButton::Secondary) { + } else if resp.dragged_by(egui::PointerButton::Secondary) { CameraOperation::Pan } else { CameraOperation::None }; - if input.pointer.is_moving() { - self.on_pointer_moved( - queue, - camera_op, - (pos.x - resp.rect.left(), pos.y - resp.rect.top()), - ); - } - let scroll_delta = ui.input(|i| i.smooth_scroll_delta); - if scroll_delta.y != 0.0 { - self.on_zoom(queue, scroll_delta.y); - } + self.on_pointer_moved( + queue, + camera_op, + (pos.x - resp.rect.left(), pos.y - resp.rect.top()), + ); + } else { + self.prev_pointer_pos = None; } }