diff --git a/crates/compositor/src/compositor_linux.rs b/crates/compositor/src/compositor_linux.rs index 3b2632b19..0ea5afd6e 100644 --- a/crates/compositor/src/compositor_linux.rs +++ b/crates/compositor/src/compositor_linux.rs @@ -5075,11 +5075,11 @@ mod tests { /// Les états que le rendu passe en revue (hotspots de `DEFAULT_CURSOR_SPRITES`), et s'ils /// sont centrés : ni tangage ni lacet. const MODEL_STATES: [(&str, [f32; 2], bool); 6] = [ - ("arrow", [0.119, 0.0874], false), - ("pointer", [0.3893, 0.0032], false), - ("text", [0.4375, 0.5333], true), - ("open-hand", [0.4375, 0.1781], false), - ("resize-ew", [0.4881, 0.4706], true), + ("arrow", [0.1205, 0.0881], false), + ("pointer", [0.3874, 0.0032], false), + ("text", [0.4355, 0.5369], true), + ("open-hand", [0.4375, 0.1724], false), + ("resize-ew", [0.485, 0.4706], true), ("not-allowed", [0.5, 0.5], true), ]; diff --git a/crates/compositor/src/compositor_macos.rs b/crates/compositor/src/compositor_macos.rs index c422c4bb2..01e809026 100644 --- a/crates/compositor/src/compositor_macos.rs +++ b/crates/compositor/src/compositor_macos.rs @@ -3709,11 +3709,11 @@ mod tests { /// Les états que le rendu passe en revue (hotspots de `DEFAULT_CURSOR_SPRITES`), et s'ils /// sont centrés : ni tangage ni lacet. const MODEL_STATES: [(&str, [f32; 2], bool); 6] = [ - ("arrow", [0.119, 0.0874], false), - ("pointer", [0.3893, 0.0032], false), - ("text", [0.4375, 0.5333], true), - ("open-hand", [0.4375, 0.1781], false), - ("resize-ew", [0.4881, 0.4706], true), + ("arrow", [0.1205, 0.0881], false), + ("pointer", [0.3874, 0.0032], false), + ("text", [0.4355, 0.5369], true), + ("open-hand", [0.4375, 0.1724], false), + ("resize-ew", [0.485, 0.4706], true), ("not-allowed", [0.5, 0.5], true), ]; diff --git a/crates/compositor/src/cursor_sdf.rs b/crates/compositor/src/cursor_sdf.rs index 987d22429..1dbce9c7e 100644 --- a/crates/compositor/src/cursor_sdf.rs +++ b/crates/compositor/src/cursor_sdf.rs @@ -458,11 +458,11 @@ mod tests { fn the_shipped_arrow_loads() { let path = concat!(env!("CARGO_MANIFEST_DIR"), "/../../public/cursors/default/arrow.png"); let sdf = CursorSdf::load(path).expect("arrow.png"); - assert_eq!((sdf.width, sdf.height), (42 * 4, 70 * 4)); - assert_eq!(sdf.shape.size, [0.6, 1.0]); + assert_eq!((sdf.width, sdf.height), (83 * 4, 139 * 4)); + assert_eq!(sdf.shape.size, [83.0 / 139.0, 1.0]); assert!(sdf.shape.top < 0.02, "haut de la silhouette : {}", sdf.shape.top); - // Le hotspot (0.119, 0.0874) est la pointe de l'incrustation, dans la silhouette. - assert!(sdf.sample([0.119, 0.0874]) < 0.0); + // Le hotspot (0.1205, 0.0881) est la pointe de l'incrustation, dans la silhouette. + assert!(sdf.sample([0.1205, 0.0881]) < 0.0); assert!(sdf.sample([0.9, 0.1]) > 0.0); assert_eq!(sdf.f16_bytes().len(), sdf.texels.len() * 2); } diff --git a/crates/compositor/src/frame_geometry.rs b/crates/compositor/src/frame_geometry.rs index 18e1f9246..1e99d413c 100644 --- a/crates/compositor/src/frame_geometry.rs +++ b/crates/compositor/src/frame_geometry.rs @@ -6476,7 +6476,7 @@ mod tests { #[test] fn sprite_hotspot_stays_on_target_at_any_size() { let center = [0.4, 0.6]; - let hotspot = [0.119, 0.0874]; // flèche intégrée : la pointe, près du coin haut-gauche + let hotspot = [0.1205, 0.0881]; // flèche intégrée : la pointe, près du coin haut-gauche for (w, h) in [(0.02, 0.04), (0.08, 0.16)] { let dst = cursor_sprite_dst(center, w, h, hotspot); @@ -7091,17 +7091,17 @@ mod tests { /// Les seize états du thème par défaut et leurs hotspots (`DEFAULT_CURSOR_SPRITES`, /// `src/lib/cursor/cursorThemes.ts`). const DEFAULT_SPRITES: [(&str, [f32; 2]); 16] = [ - ("arrow", [0.119, 0.0874]), - ("text", [0.4375, 0.5333]), - ("pointer", [0.3893, 0.0032]), + ("arrow", [0.1205, 0.0881]), + ("text", [0.4355, 0.5369]), + ("pointer", [0.3874, 0.0032]), ("crosshair", [0.4667, 0.4667]), - ("open-hand", [0.4375, 0.1781]), - ("closed-hand", [0.3889, 0.451]), - ("resize-ew", [0.4881, 0.4706]), + ("open-hand", [0.4375, 0.1724]), + ("closed-hand", [0.3889, 0.4455]), + ("resize-ew", [0.485, 0.4706]), ("resize-ns", [0.5, 0.5]), ("resize-nesw", [0.5, 0.5]), ("resize-nwse", [0.5, 0.5]), - ("move", [0.4444, 0.4444]), + ("move", [0.4437, 0.4437]), ("not-allowed", [0.5, 0.5]), ("wait", [0.5, 0.5]), ("app-starting", [0.05, 0.0537]), diff --git a/crates/compositor/tests/cursor_model_render.rs b/crates/compositor/tests/cursor_model_render.rs index 7c6e52eb8..9b473ec8f 100644 --- a/crates/compositor/tests/cursor_model_render.rs +++ b/crates/compositor/tests/cursor_model_render.rs @@ -41,17 +41,17 @@ const CONTACT_S: f32 = 0.0495; /// Les seize états du thème par défaut et leurs hotspots (`DEFAULT_CURSOR_SPRITES`, /// `src/lib/cursor/cursorThemes.ts`). const STATES: [(&str, [f32; 2]); 16] = [ - ("arrow", [0.119, 0.0874]), - ("text", [0.4375, 0.5333]), - ("pointer", [0.3893, 0.0032]), + ("arrow", [0.1205, 0.0881]), + ("text", [0.4355, 0.5369]), + ("pointer", [0.3874, 0.0032]), ("crosshair", [0.4667, 0.4667]), - ("open-hand", [0.4375, 0.1781]), - ("closed-hand", [0.3889, 0.451]), - ("resize-ew", [0.4881, 0.4706]), + ("open-hand", [0.4375, 0.1724]), + ("closed-hand", [0.3889, 0.4455]), + ("resize-ew", [0.485, 0.4706]), ("resize-ns", [0.5, 0.5]), ("resize-nesw", [0.5, 0.5]), ("resize-nwse", [0.5, 0.5]), - ("move", [0.4444, 0.4444]), + ("move", [0.4437, 0.4437]), ("not-allowed", [0.5, 0.5]), ("wait", [0.5, 0.5]), ("app-starting", [0.05, 0.0537]), diff --git a/crates/compositor/tests/cursor_tap_render.rs b/crates/compositor/tests/cursor_tap_render.rs index b29116c7a..8b908f922 100644 --- a/crates/compositor/tests/cursor_tap_render.rs +++ b/crates/compositor/tests/cursor_tap_render.rs @@ -167,8 +167,8 @@ fn scene_json(rotation: &str, hide: bool, click_bounce: f32) -> String { "zoomRegions":[{{"clipIndex":0,"startSec":0,"endSec":10,"scale":1,"focusX":0.5,"focusY":0.5,"focusMode":"manual","rotation":{rotation},"hideCursor":{hide}}}], "annotations":[], "cursor":{{"show":true,"size":4,"smoothing":0.5,"motionBlur":0.5,"clickBounce":{click_bounce},"model3d":true,"clipToBounds":false,"theme":"default", - "cursorSprites":{{"arrow":{{"path":"{dir}/arrow.png","hotspotX":0.119,"hotspotY":0.0874}}, - "pointer":{{"path":"{dir}/pointer.png","hotspotX":0.3893,"hotspotY":0.0032}}}}}}, + "cursorSprites":{{"arrow":{{"path":"{dir}/arrow.png","hotspotX":0.1205,"hotspotY":0.0881}}, + "pointer":{{"path":"{dir}/pointer.png","hotspotX":0.3874,"hotspotY":0.0032}}}}}}, "cropByClip":[null], "output":{{"width":1280,"height":720,"fps":30}}}}"## ) diff --git a/crates/compositor/tests/device_frame_render.rs b/crates/compositor/tests/device_frame_render.rs index ad9e62aab..6b649a005 100644 --- a/crates/compositor/tests/device_frame_render.rs +++ b/crates/compositor/tests/device_frame_render.rs @@ -1041,7 +1041,7 @@ fn orbit_clip_frames() { std::fs::write(&path, format!(r#"{{"samples":[{}]}}"#, samples.join(","))).expect("sidecar"); let track = CursorTrack::load(path.to_str().unwrap(), 0.0, 10.0).expect("piste curseur"); let cursor = format!( - r#"{{"show":true,"size":4,"smoothing":0.2,"motionBlur":0,"clickBounce":2.5,"model3d":true,"clipToBounds":false,"theme":"default","cursorSprites":{{"arrow":{{"path":"{}/arrow.png","hotspotX":0.119,"hotspotY":0.0874}}}}}}"#, + r#"{{"show":true,"size":4,"smoothing":0.2,"motionBlur":0,"clickBounce":2.5,"model3d":true,"clipToBounds":false,"theme":"default","cursorSprites":{{"arrow":{{"path":"{}/arrow.png","hotspotX":0.1205,"hotspotY":0.0881}}}}}}"#, std::path::Path::new(env!("CARGO_MANIFEST_DIR")) .join("../../public/cursors/default") .to_string_lossy() diff --git a/crates/compositor/tests/follow_camera_render.rs b/crates/compositor/tests/follow_camera_render.rs index e1aaa9b06..8678a8f87 100644 --- a/crates/compositor/tests/follow_camera_render.rs +++ b/crates/compositor/tests/follow_camera_render.rs @@ -381,7 +381,7 @@ fn orbit_scene(source: &str, regions: &str, (w, h): (u32, u32)) -> Scene { "zoomRegions":[{regions}], "annotations":[], "cursor":{{"show":true,"size":2.2,"smoothing":0,"motionBlur":0,"clickBounce":2.5,"model3d":true,"clipToBounds":false,"theme":"default", - "cursorSprites":{{"arrow":{{"path":"{arrow}","hotspotX":0.119,"hotspotY":0.0874}}}}}}, + "cursorSprites":{{"arrow":{{"path":"{arrow}","hotspotX":0.1205,"hotspotY":0.0881}}}}}}, "cropByClip":[null], "output":{{"width":{w},"height":{h},"fps":30}}}}"## )) diff --git a/public/cursors/default/app-starting.png b/public/cursors/default/app-starting.png index 9a1649eea..b36bdf895 100644 Binary files a/public/cursors/default/app-starting.png and b/public/cursors/default/app-starting.png differ diff --git a/public/cursors/default/arrow.png b/public/cursors/default/arrow.png index 85998081e..2dd2686e5 100644 Binary files a/public/cursors/default/arrow.png and b/public/cursors/default/arrow.png differ diff --git a/public/cursors/default/closed-hand.png b/public/cursors/default/closed-hand.png index 621fba8a2..41852125a 100644 Binary files a/public/cursors/default/closed-hand.png and b/public/cursors/default/closed-hand.png differ diff --git a/public/cursors/default/crosshair.png b/public/cursors/default/crosshair.png index 09d40cd95..edb851773 100644 Binary files a/public/cursors/default/crosshair.png and b/public/cursors/default/crosshair.png differ diff --git a/public/cursors/default/help.png b/public/cursors/default/help.png index 6746db84d..79d347999 100644 Binary files a/public/cursors/default/help.png and b/public/cursors/default/help.png differ diff --git a/public/cursors/default/move.png b/public/cursors/default/move.png index 69a819fcf..25694ef97 100644 Binary files a/public/cursors/default/move.png and b/public/cursors/default/move.png differ diff --git a/public/cursors/default/not-allowed.png b/public/cursors/default/not-allowed.png index f7f35d12e..cc7fad557 100644 Binary files a/public/cursors/default/not-allowed.png and b/public/cursors/default/not-allowed.png differ diff --git a/public/cursors/default/open-hand.png b/public/cursors/default/open-hand.png index 147ebdabf..f3271c042 100644 Binary files a/public/cursors/default/open-hand.png and b/public/cursors/default/open-hand.png differ diff --git a/public/cursors/default/pointer.png b/public/cursors/default/pointer.png index a89d388bf..60b12be56 100644 Binary files a/public/cursors/default/pointer.png and b/public/cursors/default/pointer.png differ diff --git a/public/cursors/default/resize-ew.png b/public/cursors/default/resize-ew.png index b15a4fe5f..a3a6f1f37 100644 Binary files a/public/cursors/default/resize-ew.png and b/public/cursors/default/resize-ew.png differ diff --git a/public/cursors/default/resize-nesw.png b/public/cursors/default/resize-nesw.png index 0f9746865..d17c21a78 100644 Binary files a/public/cursors/default/resize-nesw.png and b/public/cursors/default/resize-nesw.png differ diff --git a/public/cursors/default/resize-ns.png b/public/cursors/default/resize-ns.png index 229ddfaab..4607b9176 100644 Binary files a/public/cursors/default/resize-ns.png and b/public/cursors/default/resize-ns.png differ diff --git a/public/cursors/default/resize-nwse.png b/public/cursors/default/resize-nwse.png index eac720eb6..6c27c919c 100644 Binary files a/public/cursors/default/resize-nwse.png and b/public/cursors/default/resize-nwse.png differ diff --git a/public/cursors/default/text.png b/public/cursors/default/text.png index 27a5e5ef9..1d4acdb82 100644 Binary files a/public/cursors/default/text.png and b/public/cursors/default/text.png differ diff --git a/public/cursors/default/up-arrow.png b/public/cursors/default/up-arrow.png index a32665e50..830a3a46a 100644 Binary files a/public/cursors/default/up-arrow.png and b/public/cursors/default/up-arrow.png differ diff --git a/public/cursors/default/wait.png b/public/cursors/default/wait.png index e8ba48724..512855887 100644 Binary files a/public/cursors/default/wait.png and b/public/cursors/default/wait.png differ diff --git a/scripts/generate-default-cursor-sprites.mjs b/scripts/generate-default-cursor-sprites.mjs index 2fb957680..9f98665c0 100644 --- a/scripts/generate-default-cursor-sprites.mjs +++ b/scripts/generate-default-cursor-sprites.mjs @@ -25,7 +25,10 @@ import { chromium } from "playwright"; const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const SRC_DIR = path.join(ROOT, "src", "assets", "cursors"); const OUT_DIR = path.join(ROOT, "public", "cursors", "default"); -const OUT_SIZE = 128; +// The arrow comes out 139 px tall: sharp up to the top of the size slider (164 px in a 1080p +// export), where a 128 box (70 px) was stretched 2.3x and blurred. No mipmaps, so not more: +// at the default size a bigger master would alias. +const OUT_SIZE = 256; /** * cursorType -> { file, hotspotX, hotspotY } in the 32-logical reference. diff --git a/src/components/ai-edition/CursorPane.levels.test.tsx b/src/components/ai-edition/CursorPane.levels.test.tsx index 5b62a22c0..73fa1ffe4 100644 --- a/src/components/ai-edition/CursorPane.levels.test.tsx +++ b/src/components/ai-edition/CursorPane.levels.test.tsx @@ -43,15 +43,22 @@ const pressed = (group: string) => screen.getByRole("group", { name: group }).querySelectorAll('button[aria-pressed="true"]'); describe("CursorPane named levels", () => { - it("names the size and the click bounce instead of showing a number", () => { - renderWithCursor({ cursorSize: 2, cursorClickBounce: 0 }); - expect([...pressed("Size")].map((b) => b.textContent)).toEqual(["Large"]); + it("names the click bounce instead of showing a number", () => { + renderWithCursor({ cursorClickBounce: 0 }); expect([...pressed("Click bounce")].map((b) => b.textContent)).toEqual(["None"]); - expect(screen.queryByRole("slider", { name: "Size" })).toBeNull(); }); it("presses nothing for a stored value between two levels", () => { - renderWithCursor({ cursorSize: 2.4 }); - expect(pressed("Size")).toHaveLength(0); + renderWithCursor({ cursorClickBounce: 1.5 }); + expect(pressed("Click bounce")).toHaveLength(0); + }); +}); + +describe("CursorPane size", () => { + // Named steps stopped at 2.75; people asked for at least twice that. + it("is a slider from the default up to four times it", () => { + renderWithCursor({ cursorSize: 4.5 }); + const slider = screen.getByRole("slider", { name: "Size" }) as HTMLInputElement; + expect([slider.min, slider.max, slider.value]).toEqual(["1.5", "6", "4.5"]); }); }); diff --git a/src/components/ai-edition/RightPanes.tsx b/src/components/ai-edition/RightPanes.tsx index 0128e813c..dd73092e0 100644 --- a/src/components/ai-edition/RightPanes.tsx +++ b/src/components/ai-edition/RightPanes.tsx @@ -112,6 +112,7 @@ import { type FrameTheme, RECORDING_FRAMES, type RecordingFrame, + SETTING_BOUNDS, WEBCAM_ANCHOR_GRID, WEBCAM_SIZE_MAX, WEBCAM_SIZE_MIN, @@ -3889,17 +3890,23 @@ export function CursorPane() { ) : null} - {namedLevelRow( - ts("cursor.size"), - CURSOR_SIZE_LEVELS.map((level) => ({ value: level.value, label: ts(level.labelKey) })), - settings.cursor.size, - !hasDocument, - (size) => { - void set({ cursor: { size } }); - if (isNativeCompositorActive()) setNativeParam("cursorSize", size); - }, - )}
+ {/* A slider, not named steps: "a bit bigger" is a size between two of them. + `SETTING_BOUNDS` keeps both ends sane. */} + { + setLive({ cursor: { size: v } }); + if (isNativeCompositorActive()) setNativeParam("cursorSize", v); + }} + onCommit={() => void commit()} + /> ({ * Screen Studio's rule: a style is chosen by what it looks like, never by "30.0". Each list * holds the default (`DEFAULT_PROJECT_APPEARANCE`) and stays inside `SETTING_BOUNDS`. */ -const CURSOR_SIZE_LEVELS = [ - { value: 1.5, labelKey: "cursor.sizeNormal" }, - { value: 2, labelKey: "cursor.sizeLarge" }, - { value: 2.75, labelKey: "cursor.sizeExtraLarge" }, -] as const; const CLICK_BOUNCE_LEVELS = [ { value: 0, labelKey: "cursor.bounceNone" }, { value: 1, labelKey: "cursor.bounceLight" }, diff --git a/src/i18n/locales/ar/settings.json b/src/i18n/locales/ar/settings.json index c04b950d3..4f0df992e 100644 --- a/src/i18n/locales/ar/settings.json +++ b/src/i18n/locales/ar/settings.json @@ -450,9 +450,6 @@ "motionBlur": "ضبابية الحركة", "theme": "نمط المؤشر", "autoHide": "إخفاء عند عدم النشاط", - "sizeNormal": "عادي", - "sizeLarge": "كبير", - "sizeExtraLarge": "كبير جدًا", "bounceNone": "بلا", "bounceLight": "خفيف", "bounceStrong": "قوي" diff --git a/src/i18n/locales/cs/settings.json b/src/i18n/locales/cs/settings.json index 63421ec57..3b71f9c04 100644 --- a/src/i18n/locales/cs/settings.json +++ b/src/i18n/locales/cs/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Pohybové rozmazání", "theme": "Styl kurzoru", "autoHide": "Automaticky skrýt, když je neaktivní", - "sizeNormal": "Normální", - "sizeLarge": "Velký", - "sizeExtraLarge": "Velmi velký", "bounceNone": "Žádný", "bounceLight": "Lehký", "bounceStrong": "Výrazný" diff --git a/src/i18n/locales/de/settings.json b/src/i18n/locales/de/settings.json index 41b6f402c..e0a3417ef 100644 --- a/src/i18n/locales/de/settings.json +++ b/src/i18n/locales/de/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Bewegungsunschärfe", "theme": "Cursor-Stil", "autoHide": "Bei Inaktivität ausblenden", - "sizeNormal": "Normal", - "sizeLarge": "Groß", - "sizeExtraLarge": "Sehr groß", "bounceNone": "Keiner", "bounceLight": "Leicht", "bounceStrong": "Stark" diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json index 108ba025b..78971d199 100644 --- a/src/i18n/locales/en/settings.json +++ b/src/i18n/locales/en/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Motion blur", "theme": "Cursor style", "autoHide": "Auto-hide when inactive", - "sizeNormal": "Normal", - "sizeLarge": "Large", - "sizeExtraLarge": "Extra large", "bounceNone": "None", "bounceLight": "Light", "bounceStrong": "Strong" diff --git a/src/i18n/locales/es/settings.json b/src/i18n/locales/es/settings.json index f139d1aa4..de51014fb 100644 --- a/src/i18n/locales/es/settings.json +++ b/src/i18n/locales/es/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Desenfoque de movimiento", "theme": "Estilo del cursor", "autoHide": "Ocultar si está inactivo", - "sizeNormal": "Normal", - "sizeLarge": "Grande", - "sizeExtraLarge": "Muy grande", "bounceNone": "Ninguno", "bounceLight": "Suave", "bounceStrong": "Marcado" diff --git a/src/i18n/locales/fr/settings.json b/src/i18n/locales/fr/settings.json index 527c77073..28d4957ff 100644 --- a/src/i18n/locales/fr/settings.json +++ b/src/i18n/locales/fr/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Flou de mouvement", "theme": "Style du curseur", "autoHide": "Masquer si inactif", - "sizeNormal": "Normale", - "sizeLarge": "Grande", - "sizeExtraLarge": "Très grande", "bounceNone": "Aucun", "bounceLight": "Léger", "bounceStrong": "Marqué" diff --git a/src/i18n/locales/it/settings.json b/src/i18n/locales/it/settings.json index a987c6079..5829e550e 100644 --- a/src/i18n/locales/it/settings.json +++ b/src/i18n/locales/it/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Sfocatura movimento", "theme": "Stile del cursore", "autoHide": "Nascondi se inattivo", - "sizeNormal": "Normale", - "sizeLarge": "Grande", - "sizeExtraLarge": "Molto grande", "bounceNone": "Nessuno", "bounceLight": "Leggero", "bounceStrong": "Marcato" diff --git a/src/i18n/locales/ja-JP/settings.json b/src/i18n/locales/ja-JP/settings.json index 09a2e9624..09806a252 100644 --- a/src/i18n/locales/ja-JP/settings.json +++ b/src/i18n/locales/ja-JP/settings.json @@ -450,9 +450,6 @@ "motionBlur": "モーションブラー", "theme": "カーソルのスタイル", "autoHide": "非アクティブ時に非表示", - "sizeNormal": "標準", - "sizeLarge": "大", - "sizeExtraLarge": "特大", "bounceNone": "なし", "bounceLight": "弱", "bounceStrong": "強" diff --git a/src/i18n/locales/ko-KR/settings.json b/src/i18n/locales/ko-KR/settings.json index f23459804..70d8c351a 100644 --- a/src/i18n/locales/ko-KR/settings.json +++ b/src/i18n/locales/ko-KR/settings.json @@ -450,9 +450,6 @@ "motionBlur": "모션 블러", "theme": "커서 스타일", "autoHide": "비활성 시 자동 숨김", - "sizeNormal": "보통", - "sizeLarge": "크게", - "sizeExtraLarge": "아주 크게", "bounceNone": "없음", "bounceLight": "약하게", "bounceStrong": "강하게" diff --git a/src/i18n/locales/pt-BR/settings.json b/src/i18n/locales/pt-BR/settings.json index d003a943b..a5b08da5e 100644 --- a/src/i18n/locales/pt-BR/settings.json +++ b/src/i18n/locales/pt-BR/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Desfoque de movimento", "theme": "Estilo do cursor", "autoHide": "Ocultar quando inativo", - "sizeNormal": "Normal", - "sizeLarge": "Grande", - "sizeExtraLarge": "Muito grande", "bounceNone": "Nenhum", "bounceLight": "Leve", "bounceStrong": "Forte" diff --git a/src/i18n/locales/ru/settings.json b/src/i18n/locales/ru/settings.json index 284622846..e69757b57 100644 --- a/src/i18n/locales/ru/settings.json +++ b/src/i18n/locales/ru/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Размытие движения", "theme": "Стиль курсора", "autoHide": "Скрывать при неактивности", - "sizeNormal": "Обычный", - "sizeLarge": "Крупный", - "sizeExtraLarge": "Очень крупный", "bounceNone": "Нет", "bounceLight": "Лёгкий", "bounceStrong": "Сильный" diff --git a/src/i18n/locales/tr/settings.json b/src/i18n/locales/tr/settings.json index af4dd0e7c..bd7a93b3f 100644 --- a/src/i18n/locales/tr/settings.json +++ b/src/i18n/locales/tr/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Hareket Bulanıklığı", "theme": "İmleç Stili", "autoHide": "Hareketsizken gizle", - "sizeNormal": "Normal", - "sizeLarge": "Büyük", - "sizeExtraLarge": "Çok büyük", "bounceNone": "Yok", "bounceLight": "Hafif", "bounceStrong": "Belirgin" diff --git a/src/i18n/locales/vi/settings.json b/src/i18n/locales/vi/settings.json index 8f8f9e71d..77337f42c 100644 --- a/src/i18n/locales/vi/settings.json +++ b/src/i18n/locales/vi/settings.json @@ -450,9 +450,6 @@ "motionBlur": "Làm mờ chuyển động", "theme": "Kiểu con trỏ", "autoHide": "Ẩn khi không hoạt động", - "sizeNormal": "Thường", - "sizeLarge": "Lớn", - "sizeExtraLarge": "Rất lớn", "bounceNone": "Không", "bounceLight": "Nhẹ", "bounceStrong": "Mạnh" diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json index 0c80edd76..16f18d0c1 100644 --- a/src/i18n/locales/zh-CN/settings.json +++ b/src/i18n/locales/zh-CN/settings.json @@ -450,9 +450,6 @@ "motionBlur": "运动模糊", "theme": "光标样式", "autoHide": "闲置时隐藏", - "sizeNormal": "标准", - "sizeLarge": "大", - "sizeExtraLarge": "特大", "bounceNone": "无", "bounceLight": "轻", "bounceStrong": "强" diff --git a/src/i18n/locales/zh-TW/settings.json b/src/i18n/locales/zh-TW/settings.json index a8284ffaa..b141c7795 100644 --- a/src/i18n/locales/zh-TW/settings.json +++ b/src/i18n/locales/zh-TW/settings.json @@ -450,9 +450,6 @@ "motionBlur": "動態模糊", "theme": "游標樣式", "autoHide": "閒置時隱藏", - "sizeNormal": "標準", - "sizeLarge": "大", - "sizeExtraLarge": "特大", "bounceNone": "無", "bounceLight": "輕", "bounceStrong": "強" diff --git a/src/lib/ai-edition/store/editorSettings.test.ts b/src/lib/ai-edition/store/editorSettings.test.ts index f2fae5ed5..effa44e44 100644 --- a/src/lib/ai-edition/store/editorSettings.test.ts +++ b/src/lib/ai-edition/store/editorSettings.test.ts @@ -64,7 +64,7 @@ describe("getEditorSettings", () => { motionBlurAmount: "a lot", }, }); - expect([snap.cursor.size, snap.cursor.clickBounce, snap.cursor.smoothing]).toEqual([3, 2, 0]); + expect([snap.cursor.size, snap.cursor.clickBounce, snap.cursor.smoothing]).toEqual([6, 2, 0]); expect([snap.shadowIntensity, snap.padding, snap.borderRadius]).toEqual([1, 0, 64]); expect(snap.motionBlurAmount).toBe(DEFAULT_EDITOR_SETTINGS.motionBlurAmount); }); diff --git a/src/lib/ai-edition/stylePresets.test.ts b/src/lib/ai-edition/stylePresets.test.ts index 9a5d1e5db..adc3a5938 100644 --- a/src/lib/ai-edition/stylePresets.test.ts +++ b/src/lib/ai-edition/stylePresets.test.ts @@ -104,7 +104,7 @@ describe("parseStylePresetAppearance", () => { expect(read({ webcamSizePreset: 50 }).webcamSizePreset).toBe(35); // Every preset saved with the old defaults carries a 2.5 bounce: it still applies. const cursor = read({ cursor: { ...appearance().cursor, size: 10, clickBounce: 2.5 } }).cursor; - expect([cursor.size, cursor.clickBounce]).toEqual([3, 2]); + expect([cursor.size, cursor.clickBounce]).toEqual([6, 2]); }); it("rejects non-numbers, wrong types and unknown enum values", () => { diff --git a/src/lib/cursor/cursorThemes.ts b/src/lib/cursor/cursorThemes.ts index 5cb373a85..2b13b463b 100644 --- a/src/lib/cursor/cursorThemes.ts +++ b/src/lib/cursor/cursorThemes.ts @@ -69,21 +69,21 @@ export interface CursorSprite { * hand-editing, so the PNGs and these hotspots can't drift apart. */ export const DEFAULT_CURSOR_SPRITES: Record = { - arrow: { assetPath: "cursors/default/arrow.png", hotspotX: 0.119, hotspotY: 0.0874 }, - text: { assetPath: "cursors/default/text.png", hotspotX: 0.4375, hotspotY: 0.5333 }, - pointer: { assetPath: "cursors/default/pointer.png", hotspotX: 0.3893, hotspotY: 0.0032 }, + arrow: { assetPath: "cursors/default/arrow.png", hotspotX: 0.1205, hotspotY: 0.0881 }, + text: { assetPath: "cursors/default/text.png", hotspotX: 0.4355, hotspotY: 0.5369 }, + pointer: { assetPath: "cursors/default/pointer.png", hotspotX: 0.3874, hotspotY: 0.0032 }, crosshair: { assetPath: "cursors/default/crosshair.png", hotspotX: 0.4667, hotspotY: 0.4667 }, - "open-hand": { assetPath: "cursors/default/open-hand.png", hotspotX: 0.4375, hotspotY: 0.1781 }, + "open-hand": { assetPath: "cursors/default/open-hand.png", hotspotX: 0.4375, hotspotY: 0.1724 }, "closed-hand": { assetPath: "cursors/default/closed-hand.png", hotspotX: 0.3889, - hotspotY: 0.451, + hotspotY: 0.4455, }, - "resize-ew": { assetPath: "cursors/default/resize-ew.png", hotspotX: 0.4881, hotspotY: 0.4706 }, + "resize-ew": { assetPath: "cursors/default/resize-ew.png", hotspotX: 0.485, hotspotY: 0.4706 }, "resize-ns": { assetPath: "cursors/default/resize-ns.png", hotspotX: 0.5, hotspotY: 0.5 }, "resize-nesw": { assetPath: "cursors/default/resize-nesw.png", hotspotX: 0.5, hotspotY: 0.5 }, "resize-nwse": { assetPath: "cursors/default/resize-nwse.png", hotspotX: 0.5, hotspotY: 0.5 }, - move: { assetPath: "cursors/default/move.png", hotspotX: 0.4444, hotspotY: 0.4444 }, + move: { assetPath: "cursors/default/move.png", hotspotX: 0.4437, hotspotY: 0.4437 }, "not-allowed": { assetPath: "cursors/default/not-allowed.png", hotspotX: 0.5, hotspotY: 0.5 }, wait: { assetPath: "cursors/default/wait.png", hotspotX: 0.5, hotspotY: 0.5 }, "app-starting": { diff --git a/src/lib/projectDefaults.ts b/src/lib/projectDefaults.ts index 4108852f9..f1f6bf0d7 100644 --- a/src/lib/projectDefaults.ts +++ b/src/lib/projectDefaults.ts @@ -267,8 +267,9 @@ export const SETTING_BOUNDS = { webcamSizePreset: [WEBCAM_SIZE_MIN, WEBCAM_SIZE_MAX], webcamRoundness: [0, 1], webcamBlurIntensity: [0, 1], - // At 3 the arrow is 82 px tall in a 1080p export, four times the system one. - cursorSize: [1, 3], + // 1.5 is the default: nothing smaller reads in a demo. At 6 the arrow is 164 px tall in a + // 1080p export, eight times the system one. + cursorSize: [1.5, 6], cursorSmoothing: [0, 1], cursorMotionBlur: [0, 1], // Past about 4.2 the arrow shrank to nothing on every click. diff --git a/src/native/nativeCompositorStore.test.ts b/src/native/nativeCompositorStore.test.ts index 23052e2c9..01a23dfb1 100644 --- a/src/native/nativeCompositorStore.test.ts +++ b/src/native/nativeCompositorStore.test.ts @@ -76,10 +76,10 @@ describe("pushAllNativeParams", () => { }); it("sends cursor values RAW, not in slider space", async () => { - // SliderCell displays cursor.size * 10 and divides by 10 on the way out; - // smoothing and motionBlur use * 100. Pushing a slider-space value from - // here would scale the preview by 10 or 100 on load — a regression that - // would look like "the cursor is enormous when I open a project". + // The smoothing and motion blur sliders display their value * 100 and divide + // on the way out. Pushing a slider-space value from here would scale the + // preview by 100 on load — a regression that would look like "the cursor + // trails forever when I open a project". const pushed = await pushWith({ cursor: { size: 3,