mirror of
https://codeberg.org/PLG-Development/PLG-MuDiCS
synced 2026-07-06 00:47:09 +00:00
add svelte splitpanes for pinned display view
This commit is contained in:
Generated
+23
-1
@@ -9,7 +9,8 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@thisux/sveltednd": "^0.0.20",
|
"@thisux/sveltednd": "^0.0.20",
|
||||||
"lucide-svelte": "^0.545.0"
|
"lucide-svelte": "^0.545.0",
|
||||||
|
"svelte-splitpanes": "^8.0.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/compat": "^1.2.5",
|
"@eslint/compat": "^1.2.5",
|
||||||
@@ -2352,6 +2353,15 @@
|
|||||||
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
|
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/esm-env-robust": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/esm-env-robust/-/esm-env-robust-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-90Gnuw2DALOqlL1581VxP3GHPUNHX9U+fQ+8FNcTTFClhY5gEggAAnJ3q1b2Oq23knRsjv8YpNeMRPaMLUymOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"esm-env": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/espree": {
|
"node_modules/espree": {
|
||||||
"version": "10.4.0",
|
"version": "10.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
|
||||||
@@ -3848,6 +3858,18 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/svelte-splitpanes": {
|
||||||
|
"version": "8.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte-splitpanes/-/svelte-splitpanes-8.0.9.tgz",
|
||||||
|
"integrity": "sha512-L3oLXTC99M191FInTXJ/f/2i0welRql1QuVbPaU8iy6nvCR6X9VyjHCsCpLqKGWHwqkWo/AM9CQ1c0nzlb+MkA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"esm-env-robust": "0.0.3"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"svelte": "^4.2.19 || ^5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tailwindcss": {
|
"node_modules/tailwindcss": {
|
||||||
"version": "4.1.14",
|
"version": "4.1.14",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@thisux/sveltednd": "^0.0.20",
|
"@thisux/sveltednd": "^0.0.20",
|
||||||
"lucide-svelte": "^0.545.0"
|
"lucide-svelte": "^0.545.0",
|
||||||
|
"svelte-splitpanes": "^8.0.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,3 +13,81 @@
|
|||||||
--color-stone-750: oklch(0.321 0.0085 50.928);
|
--color-stone-750: oklch(0.321 0.0085 50.928);
|
||||||
--color-stone-850: oklch(0.242 0.0065 45.171);
|
--color-stone-850: oklch(0.242 0.0065 45.171);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Splitpanes */
|
||||||
|
.splitpanes.mudics-stone-theme {
|
||||||
|
.splitpanes__pane {
|
||||||
|
@apply bg-stone-900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splitpanes__splitter {
|
||||||
|
@apply bg-transparent hover:bg-stone-600 transition-colors duration-200 shrink-0 relative box-border rounded mx-5;
|
||||||
|
/* box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0; */
|
||||||
|
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
@apply bg-stone-750 transition-colors duration-200 absolute top-[50%] left-[50%] content-[''] rounded;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover:before,
|
||||||
|
&:hover:after {
|
||||||
|
@apply bg-stone-300;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
/* cursor: auto; */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mudics-stone-theme {
|
||||||
|
&.splitpanes .splitpanes .splitpanes__splitter {
|
||||||
|
@apply z-10;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.splitpanes--vertical>.splitpanes__splitter,
|
||||||
|
.splitpanes--vertical>.splitpanes__splitter {
|
||||||
|
@apply w-2.5 cursor-col-resize;
|
||||||
|
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
@apply w-0.5 h-10 translate-y-[-50%];
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
@apply ml-[calc(-0.75*var(--spacing))];
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
@apply ml-[calc(0.25*var(--spacing))];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.splitpanes--horizontal>.splitpanes__splitter,
|
||||||
|
.splitpanes--horizontal>.splitpanes__splitter {
|
||||||
|
@apply h-2 cursor-row-resize;
|
||||||
|
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
@apply h-0.5 w-10 translate-x-[-50%];
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
@apply mt-[calc(-0.7*var(--spacing))];
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
@apply mt-[calc(0.1*var(--spacing))];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { dragHandleZone, TRIGGERS } from 'svelte-dnd-action';
|
import { dragHandleZone, TRIGGERS } from 'svelte-dnd-action';
|
||||||
import { dnd_flip_duration_ms, get_selectable_color_classes, is_display_drag, is_group_drag } from '../ts/stores/ui_behavior';
|
import {
|
||||||
|
dnd_flip_duration_ms,
|
||||||
|
get_selectable_color_classes,
|
||||||
|
is_display_drag,
|
||||||
|
is_group_drag
|
||||||
|
} from '../ts/stores/ui_behavior';
|
||||||
import { cubicOut } from 'svelte/easing';
|
import { cubicOut } from 'svelte/easing';
|
||||||
import { flip } from 'svelte/animate';
|
import { flip } from 'svelte/animate';
|
||||||
import DisplayObject from './DisplayObject.svelte';
|
import DisplayObject from './DisplayObject.svelte';
|
||||||
@@ -16,9 +21,10 @@
|
|||||||
import type { DisplayGroup, MenuOption } from '../ts/types';
|
import type { DisplayGroup, MenuOption } from '../ts/types';
|
||||||
import { selected_display_ids } from '../ts/stores/select';
|
import { selected_display_ids } from '../ts/stores/select';
|
||||||
|
|
||||||
let { display_group, get_display_menu_options } = $props<{
|
let { display_group, get_display_menu_options, close_pinned_display } = $props<{
|
||||||
display_group: DisplayGroup;
|
display_group: DisplayGroup;
|
||||||
get_display_menu_options: (display_id: string) => MenuOption[]
|
get_display_menu_options: (display_id: string) => MenuOption[];
|
||||||
|
close_pinned_display: () => void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
let hovering_selectable = $state(false);
|
let hovering_selectable = $state(false);
|
||||||
@@ -65,7 +71,7 @@
|
|||||||
items: display_group.data,
|
items: display_group.data,
|
||||||
type: 'item',
|
type: 'item',
|
||||||
flipDurationMs: dnd_flip_duration_ms,
|
flipDurationMs: dnd_flip_duration_ms,
|
||||||
dropTargetStyle: { outline: 'none' },
|
dropTargetStyle: { outline: 'none' }
|
||||||
}}
|
}}
|
||||||
onconsider={handle_consider}
|
onconsider={handle_consider}
|
||||||
onfinalize={handle_finalize}
|
onfinalize={handle_finalize}
|
||||||
@@ -77,7 +83,7 @@
|
|||||||
class="outline-none"
|
class="outline-none"
|
||||||
role="figure"
|
role="figure"
|
||||||
>
|
>
|
||||||
<DisplayObject {display} {get_display_menu_options} />
|
<DisplayObject {display} {get_display_menu_options} {close_pinned_display} />
|
||||||
</section>
|
</section>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,10 @@
|
|||||||
import { is_selected, select, selected_display_ids } from '../ts/stores/select';
|
import { is_selected, select, selected_display_ids } from '../ts/stores/select';
|
||||||
import { update_screenshot } from '../ts/stores/displays';
|
import { update_screenshot } from '../ts/stores/displays';
|
||||||
|
|
||||||
let { display, get_display_menu_options } = $props<{
|
let { display, get_display_menu_options, close_pinned_display } = $props<{
|
||||||
display: Display;
|
display: Display;
|
||||||
get_display_menu_options: (display_id: string) => MenuOption[];
|
get_display_menu_options: (display_id: string) => MenuOption[];
|
||||||
|
close_pinned_display: () => void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
let hovering_unselectable = $state(false);
|
let hovering_unselectable = $state(false);
|
||||||
@@ -26,11 +27,11 @@
|
|||||||
|
|
||||||
function on_preview_click(e: MouseEvent) {
|
function on_preview_click(e: MouseEvent) {
|
||||||
if ($pinned_display_id === display.id) {
|
if ($pinned_display_id === display.id) {
|
||||||
$pinned_display_id = null;
|
close_pinned_display();
|
||||||
} else {
|
} else {
|
||||||
$pinned_display_id = display.id;
|
$pinned_display_id = display.id;
|
||||||
}
|
}
|
||||||
update_screenshot(display.id);
|
// update_screenshot(display.id); DEBUG
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fade, scale, slide } from 'svelte/transition';
|
import { fade, scale } from 'svelte/transition';
|
||||||
import {
|
import {
|
||||||
all_displays_of_group_selected,
|
all_displays_of_group_selected,
|
||||||
displays,
|
displays,
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
import { dragHandleZone } from 'svelte-dnd-action';
|
import { dragHandleZone } from 'svelte-dnd-action';
|
||||||
import { flip } from 'svelte/animate';
|
import { flip } from 'svelte/animate';
|
||||||
import DisplayGroupObject from './DisplayGroupObject.svelte';
|
import DisplayGroupObject from './DisplayGroupObject.svelte';
|
||||||
|
import { Pane, Splitpanes } from 'svelte-splitpanes';
|
||||||
|
|
||||||
let { handle_display_deletion, handle_display_editing } = $props<{
|
let { handle_display_deletion, handle_display_editing } = $props<{
|
||||||
handle_display_deletion: (display_id: string) => void;
|
handle_display_deletion: (display_id: string) => void;
|
||||||
@@ -36,6 +37,14 @@
|
|||||||
get_display_by_id($pinned_display_id || '', $displays)
|
get_display_by_id($pinned_display_id || '', $displays)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let last_pinned_pane_size: number = 45;
|
||||||
|
let pinned_pane_size: number = $state(last_pinned_pane_size);
|
||||||
|
|
||||||
|
function close_pinned_display() {
|
||||||
|
last_pinned_pane_size = pinned_pane_size;
|
||||||
|
pinned_pane_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
function get_display_menu_options(display_id: string): MenuOption[] {
|
function get_display_menu_options(display_id: string): MenuOption[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -72,6 +81,13 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handle_splitpane_resize(e: any) {
|
||||||
|
if (e.detail[0].size === 0) {
|
||||||
|
$pinned_display_id = null;
|
||||||
|
pinned_pane_size = last_pinned_pane_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function on_wheel(e: WheelEvent) {
|
function on_wheel(e: WheelEvent) {
|
||||||
if (!$is_group_drag && !$is_display_drag) return;
|
if (!$is_group_drag && !$is_display_drag) return;
|
||||||
if (!displays_scroll_box) return;
|
if (!displays_scroll_box) return;
|
||||||
@@ -88,14 +104,15 @@
|
|||||||
<svelte:window on:wheel={on_wheel} />
|
<svelte:window on:wheel={on_wheel} />
|
||||||
|
|
||||||
<div class="h-[calc(100dvh-3rem-(6*var(--spacing)))] flex flex-col gap-2">
|
<div class="h-[calc(100dvh-3rem-(6*var(--spacing)))] flex flex-col gap-2">
|
||||||
|
<Splitpanes horizontal theme="mudics-stone-theme" on:resized={handle_splitpane_resize}>
|
||||||
{#if $pinned_display_id}
|
{#if $pinned_display_id}
|
||||||
<!-- Pinned Item -->
|
<!-- Pinned Item -->
|
||||||
<div in:fade={{ duration: 140 }} out:fade={{ duration: 120 }}>
|
<Pane maxSize={60} snapSize={20} bind:size={pinned_pane_size}>
|
||||||
|
<div class="h-full" transition:fade>
|
||||||
|
<div class="grid grid-rows-[2.5rem_auto] will-change-[height,opacity] h-full">
|
||||||
<div
|
<div
|
||||||
class="grid grid-rows-[2.5rem_auto] will-change-[height,opacity] overflow-hidden rounded-2xl"
|
class="bg-stone-700 rounded-t-2xl flex justify-between w-full p-1 min-w-0 basis-0 flex-1"
|
||||||
transition:slide={{ duration: 260, easing: cubicOut }}
|
|
||||||
>
|
>
|
||||||
<div class="bg-stone-700 flex justify-between w-full p-1 min-w-0 basis-0 flex-1">
|
|
||||||
<span
|
<span
|
||||||
class="text-xl font-bold pl-2 content-center truncate min-w-0"
|
class="text-xl font-bold pl-2 content-center truncate min-w-0"
|
||||||
title={pinned_display?.name}
|
title={pinned_display?.name}
|
||||||
@@ -126,16 +143,16 @@
|
|||||||
title="Bildschirm nicht mehr anpinnen"
|
title="Bildschirm nicht mehr anpinnen"
|
||||||
className="aspect-square !p-1"
|
className="aspect-square !p-1"
|
||||||
bg="bg-stone-600"
|
bg="bg-stone-600"
|
||||||
click_function={() => {
|
click_function={close_pinned_display}
|
||||||
$pinned_display_id = null;
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<PinOff />
|
<PinOff />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full h-[30dvh] bg-stone-800 flex justify-center items-center">
|
<div
|
||||||
|
class="h-full bg-stone-800 rounded-b-2xl overflow-hidden flex justify-center items-center"
|
||||||
|
>
|
||||||
{#if pinned_display?.preview_url}
|
{#if pinned_display?.preview_url}
|
||||||
<img
|
<img
|
||||||
src={pinned_display.preview_url}
|
src={pinned_display.preview_url}
|
||||||
@@ -150,9 +167,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</Pane>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="min-h-0 h-full grid grid-rows-[2.5rem_auto] bg-stone-800 rounded-2xl overflow-hidden">
|
<Pane>
|
||||||
|
<div
|
||||||
|
class="min-h-0 h-full grid grid-rows-[2.5rem_auto] bg-stone-800 rounded-2xl overflow-hidden"
|
||||||
|
>
|
||||||
<!-- Normal Heading Left -->
|
<!-- Normal Heading Left -->
|
||||||
<div class="bg-stone-700 flex justify-between w-full p-1 gap-2 min-w-0">
|
<div class="bg-stone-700 flex justify-between w-full p-1 gap-2 min-w-0">
|
||||||
<span class="text-xl font-bold pl-2 content-center truncate min-w-0">
|
<span class="text-xl font-bold pl-2 content-center truncate min-w-0">
|
||||||
@@ -236,11 +257,13 @@
|
|||||||
animate:flip={{ duration: dnd_flip_duration_ms, easing: cubicOut }}
|
animate:flip={{ duration: dnd_flip_duration_ms, easing: cubicOut }}
|
||||||
class="outline-none"
|
class="outline-none"
|
||||||
>
|
>
|
||||||
<DisplayGroupObject {display_group} {get_display_menu_options} />
|
<DisplayGroupObject {display_group} {get_display_menu_options} {close_pinned_display} />
|
||||||
</section>
|
</section>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</Pane>
|
||||||
|
</Splitpanes>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user