Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 57 additions & 25 deletions packages/rsnap-overlay/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,12 @@ use self::rendering::{
#[cfg(all(target_os = "macos", test))]
use self::session_state::InflightScrollCaptureObservation;
use self::session_state::{
ActiveFrozenBrushStroke, CursorMoveTrace, FrozenBrushModelState, FrozenBrushState,
FrozenBrushStroke, FrozenMosaicDragState, FrozenSelectionDragCursorMoveTiming,
FrozenSelectionDragState, FrozenTextAnnotation, FrozenTextColor, FrozenTextEditState,
FrozenTextStyle, FrozenToolbarPointerState, FrozenToolbarState, HudDrawConfig,
LiveSampleApplyResult, ScrollCaptureState, SlowOperationLogger, WindowFreezeCaptureTarget,
ActiveFrozenBrushStroke, CursorMoveTrace, FrozenAnnotationColor, FrozenBrushModelState,
FrozenBrushState, FrozenBrushStroke, FrozenMosaicDragState,
FrozenSelectionDragCursorMoveTiming, FrozenSelectionDragState, FrozenTextAnnotation,
FrozenTextEditState, FrozenTextStyle, FrozenToolbarPointerState, FrozenToolbarState,
HudDrawConfig, LiveSampleApplyResult, ScrollCaptureState, SlowOperationLogger,
WindowFreezeCaptureTarget,
};
#[cfg(target_os = "macos")]
use self::session_state::{
Expand Down Expand Up @@ -258,6 +259,7 @@ const MACOS_HUD_WINDOW_LEVEL: isize = 26;
const MACOS_OVERLAY_WINDOW_LEVEL: isize = 25;
const FROZEN_TOOLBAR_BUTTON_SIZE_POINTS: f32 = 24.0;
const FROZEN_TOOLBAR_ITEM_SPACING_POINTS: f32 = 4.0;
const TOOLBAR_PILL_INNER_MARGIN_Y_POINTS: f32 = 6.0;
const LIVE_EVENT_CURSOR_CACHE_TTL: Duration = Duration::from_millis(120);
const CURSOR_EVENT_TICK_TTL: Duration = Duration::from_millis(24);
const LIVE_HOVER_HIT_TEST_INTERVAL: Duration = Duration::from_millis(60);
Expand Down Expand Up @@ -297,17 +299,17 @@ const SCROLL_CAPTURE_DUPLICATE_STREAM_STALL_THRESHOLD: u8 = 3;
#[cfg(target_os = "macos")]
const SCROLL_CAPTURE_DUPLICATE_STREAM_REFRESH_INTERVAL: Duration = Duration::from_millis(80);
const HUD_PILL_INNER_MARGIN_X_POINTS: f32 = 12.0;
const HUD_PILL_INNER_MARGIN_Y_POINTS: f32 = 8.0;
const HUD_PILL_STROKE_WIDTH_POINTS: f32 = 1.0;
const TOOLBAR_EXPANDED_HEIGHT_PX: f32 = FROZEN_TOOLBAR_BUTTON_SIZE_POINTS
+ 2.0 * HUD_PILL_INNER_MARGIN_Y_POINTS
+ 2.0 * TOOLBAR_PILL_INNER_MARGIN_Y_POINTS
+ 2.0 * HUD_PILL_STROKE_WIDTH_POINTS;
const TOOLBAR_CAPTURE_GAP_PX: f32 = 10.0;
const TOOLBAR_SCREEN_MARGIN_PX: f32 = 10.0;
const TOOLBAR_DEFAULT_SLOT_POSITION_EPSILON_POINTS: f32 = 1.0;
const HUD_PILL_CORNER_RADIUS_POINTS: u8 = 18;
const FROZEN_TEXT_FONT_SIZE_POINTS: f32 = 16.0;
const FROZEN_TEXT_FONT_SIZE_PRESETS: [f32; 4] = [16.0, 22.0, 30.0, 40.0];
const FROZEN_TEXT_FONT_SIZE_MIN_POINTS: f32 = 12.0;
const FROZEN_TEXT_FONT_SIZE_MAX_POINTS: f32 = 72.0;
const FROZEN_TEXT_PREVIEW_PLACEHOLDER: &str = "Type";
const FROZEN_TEXT_CARET_BLINK_PERIOD_SECS: f64 = 1.0;
const FROZEN_TEXT_CARET_REPAINT_INTERVAL: Duration = Duration::from_millis(250);
Expand Down Expand Up @@ -356,6 +358,8 @@ const FROZEN_SELECTION_RESIZE_HANDLE_STROKE_WIDTH_POINTS: f32 = 1.3;
const FROZEN_MOSAIC_BLOCK_SIZE_PX: u32 = 12;
const FROZEN_EDIT_HISTORY_LIMIT: usize = 24;
const FROZEN_BRUSH_STROKE_WIDTH_POINTS: f32 = 3.5;
const FROZEN_BRUSH_STROKE_WIDTH_MIN_POINTS: f32 = 1.0;
const FROZEN_BRUSH_STROKE_WIDTH_MAX_POINTS: f32 = 24.0;
const FROZEN_BRUSH_POINT_SPACING_MIN_POINTS: f32 = 0.25;
const FROZEN_BRUSH_PREVIEW_POINT_SPACING_MIN_POINTS: f32 = 0.1;
const FROZEN_BRUSH_MODELED_POINT_SPACING_MIN_POINTS: f32 = 0.25;
Expand All @@ -381,7 +385,6 @@ const FROZEN_BRUSH_STREAMLINE_DISTANCE_CEILING_POINTS: f32 = 6.0;
const FROZEN_BRUSH_PREVIEW_ROUNDING_PASSES: usize = 1;
const FROZEN_BRUSH_COMMIT_ROUNDING_PASSES: usize = 2;
const FROZEN_BRUSH_RENDER_SAMPLE_STEP_POINTS: f32 = 0.25;
const FROZEN_BRUSH_COLOR_RGBA: [u8; 4] = [255, 69, 58, 255];
const WINDOW_CAPTURE_MATTE_LIGHT_RGBA: image::Rgba<u8> = image::Rgba([246, 246, 246, 255]);
const WINDOW_CAPTURE_MATTE_DARK_RGBA: image::Rgba<u8> = image::Rgba([24, 24, 24, 255]);
const SCROLL_PREVIEW_WINDOW_WIDTH_POINTS: f64 = 260.0;
Expand Down Expand Up @@ -1600,6 +1603,14 @@ impl OverlaySession {
}
}

fn inline_toolbar_size_wheel_active(&self, toolbar_window_id: bool) -> bool {
!toolbar_window_id
&& !cfg!(target_os = "macos")
&& matches!(self.state.mode, OverlayMode::Frozen)
&& self.toolbar_state.visible
&& self.toolbar_state.annotation_size_control_hovered
}

/// Handles a winit window event for one of the overlay-owned windows.
pub fn handle_window_event(
&mut self,
Expand Down Expand Up @@ -1635,6 +1646,8 @@ impl OverlaySession {
.toolbar_window
.as_ref()
.is_some_and(|toolbar_window| toolbar_window.window.id() == window_id);
let inline_toolbar_size_wheel_active =
self.inline_toolbar_size_wheel_active(toolbar_window_id);
let control = match event {
WindowEvent::CloseRequested => self.cancel_overlay("window_close_requested"),
WindowEvent::MouseInput {
Expand All @@ -1645,27 +1658,17 @@ impl OverlaySession {
WindowEvent::Resized(size) if toolbar_window_id => {
self.handle_toolbar_window_resized(*size)
},
WindowEvent::Moved(position) if toolbar_window_id => {
self.handle_toolbar_window_moved(window_id, *position)
},
WindowEvent::Resized(size) => self.handle_resized(window_id, *size),
WindowEvent::ScaleFactorChanged { .. } if toolbar_window_id => {
self.handle_toolbar_window_scale_factor_changed(window_id)
},
WindowEvent::ScaleFactorChanged { .. } => self.handle_scale_factor_changed(window_id),
WindowEvent::CursorEntered { .. } if toolbar_window_id => OverlayControl::Continue,
WindowEvent::CursorLeft { .. } if toolbar_window_id => {
self.toolbar_pointer_local = None;
self.toolbar_left_button_down = false;
self.toolbar_left_button_went_down = false;
self.toolbar_left_button_went_up = false;
self.toolbar_state.dragging = false;
self.toolbar_state.drag_offset = Vec2::ZERO;
self.toolbar_state.drag_anchor = None;

#[cfg(target_os = "macos")]
{
self.request_redraw_toolbar_window();
}

OverlayControl::Continue
self.handle_toolbar_cursor_left()
},
WindowEvent::CursorMoved { position, .. } => {
if toolbar_window_id {
Expand All @@ -1675,7 +1678,12 @@ impl OverlaySession {
}
},
WindowEvent::Ime(event) => self.handle_ime_event(window_id, event),
WindowEvent::MouseWheel { delta, .. } if toolbar_window_id => OverlayControl::Continue,
WindowEvent::MouseWheel { delta, .. } if toolbar_window_id => {
self.handle_toolbar_mouse_wheel(delta)
},
WindowEvent::MouseWheel { delta, .. } if inline_toolbar_size_wheel_active => {
self.handle_toolbar_mouse_wheel(delta)
},
WindowEvent::MouseWheel { delta, .. } => {
self.handle_scroll_mouse_wheel(window_id, delta)
Comment thread
yvette-carlisle marked this conversation as resolved.
},
Expand Down Expand Up @@ -1843,16 +1851,18 @@ impl OverlaySession {

let left_button_went_down = self.toolbar_left_button_went_down;
let left_button_went_up = self.toolbar_left_button_went_up;
#[cfg(not(target_os = "macos"))]
let left_button_down = self.toolbar_left_button_down;

self.toolbar_left_button_went_down = false;
self.toolbar_left_button_went_up = false;

let cursor_local = toolbar_cursor_local_override
.or_else(|| self.state.cursor.and_then(|cursor| global_to_local(cursor, monitor)))?;
let left_button_down = self.toolbar_left_button_down;

Some(FrozenToolbarPointerState {
cursor_local,
#[cfg(not(target_os = "macos"))]
left_button_down,
left_button_went_down,
left_button_went_up,
Expand Down Expand Up @@ -3087,9 +3097,25 @@ enum FrozenCommittedOverlay<'a> {
Text(&'a FrozenTextAnnotation),
}

pub(super) fn frozen_toolbar_corner_radius_u8(toolbar_height_points: f32) -> u8 {
if toolbar_height_points <= TOOLBAR_EXPANDED_HEIGHT_PX + 0.5 {
(toolbar_height_points * 0.5).round().clamp(1.0, f32::from(u8::MAX)) as u8
} else {
HUD_PILL_CORNER_RADIUS_POINTS
}
}

pub(super) fn frozen_toolbar_corner_radius_points(toolbar_height_points: f32) -> f64 {
f64::from(frozen_toolbar_corner_radius_u8(toolbar_height_points))
}

fn frozen_toolbar_window_startup_size_points() -> Vec2 {
[
FrozenToolbarState::default(),
FrozenToolbarState {
selected_tool: FrozenToolbarTool::Pen,
..FrozenToolbarState::default()
},
FrozenToolbarState {
selected_tool: FrozenToolbarTool::Text,
..FrozenToolbarState::default()
Expand All @@ -3101,6 +3127,12 @@ fn frozen_toolbar_window_startup_size_points() -> Vec2 {
scroll_capture_available: true,
..FrozenToolbarState::default()
},
FrozenToolbarState {
selected_tool: FrozenToolbarTool::Pen,
auto_center_available: true,
scroll_capture_available: true,
..FrozenToolbarState::default()
},
FrozenToolbarState {
selected_tool: FrozenToolbarTool::Text,
auto_center_available: true,
Expand Down
11 changes: 7 additions & 4 deletions packages/rsnap-overlay/src/overlay/config_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ use winit::window::WindowId;

#[cfg(target_os = "macos")]
use crate::backend;
use crate::overlay;
#[cfg(target_os = "macos")]
use crate::overlay::{self, OverlayWorker};
use crate::overlay::OverlayWorker;
use crate::overlay::{
Arc, HUD_PILL_CORNER_RADIUS_POINTS, Instant, LOUPE_TILE_CORNER_RADIUS_POINTS, OverlayConfig,
OverlayMode, OverlaySession,
Arc, Instant, LOUPE_TILE_CORNER_RADIUS_POINTS, OverlayConfig, OverlayMode, OverlaySession,
WindowRenderer,
};
#[cfg(target_os = "macos")]
use crate::overlay::{MacLiveFrameStream, MacOSHudWindowConfigState, SLOW_OP_WARN_HUD_CONFIG};
Expand Down Expand Up @@ -178,7 +179,9 @@ impl OverlaySession {

self.configure_hud_window_common(
window.as_ref(),
Some(f64::from(HUD_PILL_CORNER_RADIUS_POINTS)),
Some(overlay::frozen_toolbar_corner_radius_points(
WindowRenderer::frozen_toolbar_size(&self.toolbar_state).y,
)),
);
}
}
Expand Down
23 changes: 17 additions & 6 deletions packages/rsnap-overlay/src/overlay/frozen_brush_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::time::Instant;

#[cfg(test)]
use crate::overlay::FROZEN_BRUSH_MODEL_SYNTHETIC_SAMPLE_INTERVAL_SECONDS;
use crate::overlay::session_state::FrozenBrushStyle;
use crate::overlay::{
ActiveFrozenBrushStroke, FROZEN_BRUSH_COMMIT_ROUNDING_PASSES,
FROZEN_BRUSH_MODEL_CURVE_AMPLITUDE_POINTS, FROZEN_BRUSH_MODEL_CURVE_RESPONSE_BOOST,
Expand Down Expand Up @@ -64,8 +65,11 @@ impl OverlaySession {
let point = Pos2::new(cursor_x as f32, cursor_y as f32);
let sampled_at = Instant::now();

self.frozen_brush.active_stroke =
Some(Self::new_active_frozen_brush_stroke(point, sampled_at));
self.frozen_brush.active_stroke = Some(Self::new_active_frozen_brush_stroke(
point,
sampled_at,
self.toolbar_state.brush_style,
));

self.request_redraw_for_monitor(monitor);

Expand Down Expand Up @@ -105,9 +109,10 @@ impl OverlaySession {
return false;
}

self.frozen_brush
.committed_strokes
.push(FrozenBrushStroke { points: Self::finished_frozen_brush_points(&stroke) });
self.frozen_brush.committed_strokes.push(FrozenBrushStroke {
points: Self::finished_frozen_brush_points(&stroke),
style: stroke.style,
});
self.push_frozen_edit_to_undo_history(FrozenEditKind::BrushStroke);
self.sync_frozen_toolbar_state();

Expand Down Expand Up @@ -173,10 +178,12 @@ impl OverlaySession {
pub(super) fn new_active_frozen_brush_stroke(
point: Pos2,
sampled_at: Instant,
style: FrozenBrushStyle,
) -> ActiveFrozenBrushStroke {
ActiveFrozenBrushStroke {
raw_points: vec![point],
points: vec![point],
style,
model_state: FrozenBrushModelState {
filtered_input_point: point,
modeled_point: point,
Expand Down Expand Up @@ -753,7 +760,11 @@ impl OverlaySession {
}

let started_at = Instant::now();
let mut stroke = Self::new_active_frozen_brush_stroke(points[0], started_at);
let mut stroke = Self::new_active_frozen_brush_stroke(
points[0],
started_at,
FrozenBrushStyle::default(),
);

for (index, point) in points.iter().copied().enumerate().skip(1) {
let sampled_at = started_at
Expand Down
12 changes: 7 additions & 5 deletions packages/rsnap-overlay/src/overlay/frozen_export_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use image::{
imageops::{self, FilterType},
};

use crate::overlay::session_state::FrozenBrushStyle;
use crate::overlay::{
FROZEN_BRUSH_COLOR_RGBA, FROZEN_BRUSH_RENDER_SAMPLE_STEP_POINTS,
FROZEN_BRUSH_STROKE_WIDTH_POINTS, FrozenBrushStroke, FrozenCaptureSource,
FROZEN_BRUSH_RENDER_SAMPLE_STEP_POINTS, FrozenBrushStroke, FrozenCaptureSource,
FrozenCommittedOverlay, FrozenEditKind, FrozenExportTransform, FrozenTextAnnotation,
MonitorRect, OverlaySession, Pos2, RectPoints, WINDOW_CAPTURE_MATTE_DARK_RGBA,
WINDOW_CAPTURE_MATTE_LIGHT_RGBA, WindowCaptureAlphaMode,
Expand Down Expand Up @@ -72,6 +72,7 @@ impl OverlaySession {
coverage_mask,
export_transform,
&stroke.points,
stroke.style,
);
},
FrozenCommittedOverlay::Text(annotation) => {
Expand All @@ -95,6 +96,7 @@ impl OverlaySession {
coverage_mask,
export_transform,
&display_points,
active_stroke.style,
);
}
}
Expand All @@ -104,6 +106,7 @@ impl OverlaySession {
coverage_mask: &mut [u8],
export_transform: FrozenExportTransform,
points: &[Pos2],
style: FrozenBrushStyle,
) {
if export_image.width() == 0 || export_image.height() == 0 {
return;
Expand All @@ -112,9 +115,8 @@ impl OverlaySession {
return;
}

let radius =
(FROZEN_BRUSH_STROKE_WIDTH_POINTS * export_transform.scalar_scale() * 0.5).max(1.0);
let color = Rgba(FROZEN_BRUSH_COLOR_RGBA);
let radius = (style.stroke_width_points * export_transform.scalar_scale() * 0.5).max(1.0);
let color = Rgba(style.color.export_rgba());

coverage_mask.fill(0);

Expand Down
41 changes: 39 additions & 2 deletions packages/rsnap-overlay/src/overlay/input_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::overlay::{
AltActivationMode, CURSOR_EVENT_TICK_TTL, CursorMoveTrace, DeviceCursorPointSource,
ElementState, FrozenSelectionDragCursorMoveTiming, FrozenTextEditState, FrozenTextInputSource,
FrozenToolbarTool, GlobalPoint, Ime, Key, KeyEvent, LIVE_DRAG_START_THRESHOLD_PX, Modifiers,
MonitorRect, NamedKey, OverlayControl, OverlayMode, OverlaySession, PhysicalPosition,
PhysicalSize, PngAction, Vec2, WindowId,
MonitorRect, MouseScrollDelta, NamedKey, OverlayControl, OverlayMode, OverlaySession,
PhysicalPosition, PhysicalSize, PngAction, Vec2, WindowId,
};

impl OverlaySession {
Expand Down Expand Up @@ -43,6 +43,16 @@ impl OverlaySession {
self.toolbar_left_button_down = toolbar_left_button_down;

if !toolbar_left_button_down {
if self.toolbar_state.dragging
&& let Some(monitor) = self.state.monitor.or_else(|| self.active_cursor_monitor())
&& let Some(toolbar_window) = self.toolbar_window.as_ref()
&& let Some(outer_position) = Self::toolbar_window_outer_position(toolbar_window)
{
let _ = self.sync_toolbar_outer_position_from_window(monitor, outer_position);

self.force_apply_pending_toolbar_window_move();
}

self.stop_frozen_selection_drag();
self.stop_frozen_mosaic_drag();

Expand All @@ -69,11 +79,38 @@ impl OverlaySession {
OverlayControl::Continue
}

pub(super) fn handle_toolbar_mouse_wheel(
&mut self,
delta: &MouseScrollDelta,
) -> OverlayControl {
if !matches!(self.state.mode, OverlayMode::Frozen) || !self.toolbar_state.visible {
return OverlayControl::Continue;
}
if !self.toolbar_state.apply_annotation_size_wheel_delta(delta) {
return OverlayControl::Continue;
}

self.toolbar_state.needs_redraw = true;

if let Some(monitor) = self.state.monitor {
self.request_redraw_for_monitor(monitor);
}

#[cfg(target_os = "macos")]
{
self.request_redraw_toolbar_window();
}

OverlayControl::Continue
}

pub(super) fn reset_toolbar_pointer_state(&mut self) {
self.toolbar_left_button_down = false;
self.toolbar_left_button_went_down = false;
self.toolbar_left_button_went_up = false;
self.toolbar_pointer_local = None;
self.toolbar_state.annotation_size_control_hovered = false;
self.toolbar_state.annotation_size_wheel_accumulator = 0.0;
self.toolbar_state.drag_anchor = None;
}

Expand Down
Loading
Loading