debugger: Improve drag-and-scroll in memory views (#34526)

Closes #34508

Release Notes:

- N/A
This commit is contained in:
Piotr Osiewicz 2025-07-16 12:00:36 +02:00 committed by GitHub
parent 42b2b65241
commit 312369c84f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -8,10 +8,10 @@ use std::{
use editor::{Editor, EditorElement, EditorStyle};
use gpui::{
Action, AppContext, DismissEvent, Empty, Entity, FocusHandle, Focusable, MouseButton,
MouseMoveEvent, Point, ScrollStrategy, ScrollWheelEvent, Stateful, Subscription, Task,
TextStyle, UniformList, UniformListScrollHandle, WeakEntity, actions, anchored, bounds,
deferred, point, size, uniform_list,
Action, AppContext, DismissEvent, DragMoveEvent, Empty, Entity, FocusHandle, Focusable,
MouseButton, Point, ScrollStrategy, ScrollWheelEvent, Stateful, Subscription, Task, TextStyle,
UniformList, UniformListScrollHandle, WeakEntity, actions, anchored, deferred, point,
uniform_list,
};
use notifications::status_toast::{StatusToast, ToastIcon};
use project::debugger::{MemoryCell, dap_command::DataBreakpointContext, session::Session};
@ -126,6 +126,8 @@ impl ViewState {
}
}
struct ScrollbarDragging;
static HEX_BYTES_MEMOIZED: LazyLock<[SharedString; 256]> =
LazyLock::new(|| std::array::from_fn(|byte| SharedString::from(format!("{byte:02X}"))));
static UNKNOWN_BYTE: SharedString = SharedString::new_static("??");
@ -189,11 +191,14 @@ impl MemoryView {
div()
.occlude()
.id("memory-view-vertical-scrollbar")
.on_mouse_move(cx.listener(|this, evt, _, cx| {
this.handle_drag(evt);
.on_drag_move(cx.listener(|this, evt, _, cx| {
let did_handle = this.handle_scroll_drag(evt);
cx.notify();
cx.stop_propagation()
if did_handle {
cx.stop_propagation()
}
}))
.on_drag(ScrollbarDragging, |_, _, _, cx| cx.new(|_| Empty))
.on_hover(|_, _, cx| {
cx.stop_propagation();
})
@ -307,16 +312,12 @@ impl MemoryView {
.detach();
}
fn handle_drag(&mut self, evt: &MouseMoveEvent) {
if !evt.dragging() {
return;
}
if !self.scroll_state.is_dragging()
&& !self
.view_state
.selection
.as_ref()
.is_some_and(|selection| selection.is_dragging())
fn handle_memory_drag(&mut self, evt: &DragMoveEvent<Drag>) {
if !self
.view_state
.selection
.as_ref()
.is_some_and(|selection| selection.is_dragging())
{
return;
}
@ -324,25 +325,34 @@ impl MemoryView {
debug_assert!(row_count > 1);
let scroll_handle = self.scroll_state.scroll_handle();
let viewport = scroll_handle.viewport();
let (top_area, bottom_area) = {
let size = size(viewport.size.width, viewport.size.height / 10.);
(
bounds(viewport.origin, size),
bounds(
point(viewport.origin.x, viewport.origin.y + size.height * 2.),
size,
),
)
};
if bottom_area.contains(&evt.position) {
//ix == row_count - 1 {
if viewport.bottom() < evt.event.position.y {
self.view_state.schedule_scroll_down();
} else if top_area.contains(&evt.position) {
} else if viewport.top() > evt.event.position.y {
self.view_state.schedule_scroll_up();
}
}
fn handle_scroll_drag(&mut self, evt: &DragMoveEvent<ScrollbarDragging>) -> bool {
if !self.scroll_state.is_dragging() {
return false;
}
let row_count = self.view_state.row_count();
debug_assert!(row_count > 1);
let scroll_handle = self.scroll_state.scroll_handle();
let viewport = scroll_handle.viewport();
if viewport.bottom() < evt.event.position.y {
self.view_state.schedule_scroll_down();
true
} else if viewport.top() > evt.event.position.y {
self.view_state.schedule_scroll_up();
true
} else {
false
}
}
fn editor_style(editor: &Entity<Editor>, cx: &Context<Self>) -> EditorStyle {
let is_read_only = editor.read(cx).read_only(cx);
let settings = ThemeSettings::get_global(cx);
@ -955,8 +965,8 @@ impl Render for MemoryView {
.child(
v_flex()
.size_full()
.on_mouse_move(cx.listener(|this, evt: &MouseMoveEvent, _, _| {
this.handle_drag(evt);
.on_drag_move(cx.listener(|this, evt, _, _| {
this.handle_memory_drag(&evt);
}))
.child(self.render_memory(cx).size_full())
.children(self.open_context_menu.as_ref().map(|(menu, position, _)| {