Skip to content

Commit

Permalink
Merge branch 'camera-controllers'
Browse files Browse the repository at this point in the history
  • Loading branch information
hyazinthh committed Feb 13, 2025
2 parents 2aedc31 + 5450a84 commit ad6975f
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 28 deletions.
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
- Fixed multisampled raw download
- Added pointer event variants with keyboard modifiers
- [ArcBallController] Use captured pointer events
- [FreeFlyController] Fix pointer capture for middle mouse button when using iframes
- [Animation] Improved adaptive sampling scheme for splines to avoid infinite recursion when control points are coinciding
- [Animation] Fixed issue with ticks not being processed when all animations are paused
- [Animation] Adjust action processing to resolve an issue with events when restarting an animation
Expand Down
13 changes: 7 additions & 6 deletions src/Aardvark.UI.Primitives/Controllers/ArcBallController.fs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ module ArcBallController =

{ model with view = cam; dragStart = pos; orbitCenter = center }


[<Obsolete>]
let onMouseDown (cb : MouseButtons -> V2i -> 'msg) =
onEvent
"onmousedown"
Expand Down Expand Up @@ -288,14 +288,15 @@ module ArcBallController =
let attributes (state : AdaptiveCameraControllerState) (f : Message -> 'msg) =
AttributeMap.ofListCond [
always (onBlur (fun _ -> f Blur))
always (onMouseDown (fun b p -> f (Down(b,p))))
//always (onCapturedPointerDown (Some 2) (fun t b p -> match t with Mouse -> f (Down(b,p)) | _ -> f (Down(b,p))))
//always (onCapturedPointerUp (Some 2) (fun t b p -> match t with Mouse -> f (Up(b)) | _ -> f (Down(b,p))))
always (onMouseUp (fun b p -> f (Up b)))
always (onCapturedPointerDownModifiers None (fun t m b p ->
let b = if b = MouseButtons.Left && m.ctrl then MouseButtons.Right else b // Workaround for ctrl click on Mac, not sure if still required
f <| match t with Mouse -> Down(b, p) | _ -> Nop
))
always (onCapturedPointerUp None (fun t b p -> match t with Mouse -> f (Up(b)) | _ -> f Nop))
always (onKeyDown (KeyDown >> f))
always (onKeyUp (KeyUp >> f))
always (onWheelPrevent true (fun x -> f (Wheel x)))
onlyWhen (state.look %|| state.pan %|| state.zoom) (onMouseMove (Move >> f))
onlyWhen (state.look %|| state.pan %|| state.zoom) (onCapturedPointerMove None (fun t p -> match t with Mouse -> f (Move p) | _ -> f Nop ))
]

let extractAttributes (state : AdaptiveCameraControllerState) (f : Message -> 'msg) =
Expand Down
6 changes: 3 additions & 3 deletions src/Aardvark.UI.Primitives/Controllers/FreeFlyController.fs
Original file line number Diff line number Diff line change
Expand Up @@ -610,11 +610,11 @@ module FreeFlyController =
let attributes (state : AdaptiveCameraControllerState) (f : Message -> 'msg) =
AttributeMap.ofListCond [
always (onBlur (fun _ -> f Blur))
always (onCapturedPointerDown (Some 2) (fun t b p -> match t with Mouse -> f (Down(b,p)) | _ -> f Nop))
always (onCapturedPointerUp (Some 2) (fun t b p -> match t with Mouse -> f (Up(b)) | _ -> f Nop))
always (onCapturedPointerDown None (fun t b p -> match t with Mouse -> f (Down(b,p)) | _ -> f Nop))
always (onCapturedPointerUp None (fun t b p -> match t with Mouse -> f (Up(b)) | _ -> f Nop))
onlyWhen
(state.look %|| state.pan %|| state.dolly %|| state.zoom)
(onCapturedPointerMove (Some 2) (fun t p -> match t with Mouse -> f (Move p) | _ -> f Nop ))
(onCapturedPointerMove None (fun t p -> match t with Mouse -> f (Move p) | _ -> f Nop ))
always (onKeyDownModifiers (fun m k -> KeyDown(m,k) |> f))
always (onKeyUpModifiers (fun m k -> KeyUp(m,k) |> f))
always (onWheelPrevent true (fun x -> f (Wheel x)))
Expand Down
69 changes: 50 additions & 19 deletions src/Aardvark.UI/Attributes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@ module Events =
ctrl : bool
}

module internal KeyModifiers =

let ofString (shift: string) (alt: string) (ctrl: string) =
{
shift = shift = "true"
alt = alt = "true"
ctrl = ctrl = "true"
}

let onKeyDownModifiers (cb : KeyModifiers -> Keys -> 'msg) =
"onkeydown" ,
AttributeValue.Event(
Expand All @@ -179,12 +188,7 @@ module Events =
if rep <> "true" then
let keyCode = int (float keyCode)
let key = KeyConverter.keyFromVirtualKey keyCode
let m =
{
shift = shift = "true";
alt = alt = "true"
ctrl = ctrl = "true"
}
let m = KeyModifiers.ofString shift alt ctrl
Seq.delay (fun () -> Seq.singleton (cb m key))
else
Seq.empty
Expand Down Expand Up @@ -330,13 +334,23 @@ module Events =
| _ ->
Seq.empty
}

type PointerType =
| Mouse
| Touch
| Pen

let onPointerEvent name (needButton : bool) (preventDefault : Option<int>) (useCapture : Option<bool>) (f : PointerType -> MouseButtons -> V2i -> 'msg) =
module internal PointerType =

let ofString (str: string) =
match str.Trim('\"', '\\') with // Is this really needed?
| "mouse" -> Mouse
| "touch" -> Touch
| "pen" -> Pen
| _ -> failwith $"PointerType '{str}' not supported"

let onPointerEventModifiers (name: string) (needButton : bool) (preventDefault : Option<int>) (useCapture : Option<bool>)
(cb : PointerType -> KeyModifiers -> MouseButtons -> V2i -> 'msg) =
name, AttributeValue.Event {
clientSide = fun send src ->
String.concat ";" [
Expand All @@ -345,24 +359,41 @@ module Events =
yield "var y = (event.clientY - rect.top)"
match preventDefault with | None -> () | Some i -> yield (sprintf "if(event.which==%d){event.preventDefault();};" i)
match useCapture with | None -> () | Some b -> if b then yield "this.setPointerCapture(event.pointerId)" else yield "this.releasePointerCapture(event.pointerId)"
yield send src ["event.pointerType";"event.which"; "x|0"; "y|0"]
yield send src ["event.pointerType";"event.which"; "x|0"; "y|0"; "event.shiftKey"; "event.altKey"; "event.ctrlKey"]

]
serverSide = fun client src args ->
match args with
| pointertypestr :: which :: x :: y :: _ ->
| pointertypestr :: which :: x :: y :: shift :: alt :: ctrl :: _ ->
let v : V2i = V2i(int x, int y)
let button = if needButton then button which else MouseButtons.None
let pointertypestrp = pointertypestr.Trim('\"').Trim('\\')
let pointertype = match pointertypestrp with | "mouse" -> Mouse | "pen" -> Pen | "touch" -> Touch | _ -> failwith "PointerType not supported"
Seq.singleton (f pointertype button v)
let modifiers = KeyModifiers.ofString shift alt ctrl
let pointertype = PointerType.ofString pointertypestr
Seq.singleton (cb pointertype modifiers button v)
| _ ->
Seq.empty
Seq.empty
}

let onCapturedPointerDown (preventDefault : Option<int>) cb = onPointerEvent "onpointerdown" true preventDefault (Some true) cb
let onCapturedPointerUp (preventDefault : Option<int>) cb = onPointerEvent "onpointerup" true preventDefault (Some false) cb
let onCapturedPointerMove (preventDefault : Option<int>) cb = onPointerEvent "onpointermove" false preventDefault None (fun t _ v -> cb t v)

let onPointerEvent name (needButton : bool) (preventDefault : Option<int>) (useCapture : Option<bool>) (f : PointerType -> MouseButtons -> V2i -> 'msg) =
onPointerEventModifiers name needButton preventDefault useCapture (fun t _ b p -> f t b p)

let onCapturedPointerDown preventDefault cb =
onPointerEvent "onpointerdown" true preventDefault (Some true) cb

let onCapturedPointerDownModifiers preventDefault cb =
onPointerEventModifiers "onpointerdown" true preventDefault (Some true) cb

let onCapturedPointerUp preventDefault cb =
onPointerEvent "onpointerup" true preventDefault (Some false) cb

let onCapturedPointerUpModifiers preventDefault cb =
onPointerEventModifiers "onpointerup" true preventDefault (Some false) cb

let onCapturedPointerMove preventDefault cb =
onPointerEvent "onpointermove" false preventDefault None (fun t _ v -> cb t v)

let onCapturedPointerMoveModifiers preventDefault cb =
onPointerEventModifiers "onpointermove" false preventDefault None (fun t _ v -> cb t v)

module Gamepad =

Expand Down

0 comments on commit ad6975f

Please sign in to comment.