|
@@ -1,4 +1,5 @@
|
|
|
<script>
|
|
|
+ import { onDestroy } from 'svelte'
|
|
|
import {
|
|
|
LogicalSize,
|
|
|
UserAttentionType,
|
|
@@ -10,6 +11,8 @@
|
|
|
} from '@tauri-apps/api/window'
|
|
|
import { WebviewWindow } from '@tauri-apps/api/webviewWindow'
|
|
|
|
|
|
+ export let onMessage
|
|
|
+
|
|
|
const webview = WebviewWindow.getCurrent()
|
|
|
|
|
|
let selectedWebview = webview.label
|
|
@@ -82,7 +85,6 @@
|
|
|
(s) => ProgressBarStatus[s]
|
|
|
)
|
|
|
|
|
|
- export let onMessage
|
|
|
const mainEl = document.querySelector('main')
|
|
|
|
|
|
let newWebviewLabel
|
|
@@ -95,7 +97,7 @@
|
|
|
let decorations = true
|
|
|
let alwaysOnTop = false
|
|
|
let alwaysOnBottom = false
|
|
|
- let contentProtected = true
|
|
|
+ let contentProtected = false
|
|
|
let fullscreen = false
|
|
|
let width = null
|
|
|
let height = null
|
|
@@ -116,6 +118,7 @@
|
|
|
let cursorVisible = true
|
|
|
let cursorX = null
|
|
|
let cursorY = null
|
|
|
+ /** @type {import('@tauri-apps/api/window').CursorIcon} */
|
|
|
let cursorIcon = 'default'
|
|
|
let cursorIgnoreEvents = false
|
|
|
let windowTitle = 'Awesome Tauri Example!'
|
|
@@ -126,7 +129,8 @@
|
|
|
let effectRadius
|
|
|
let effectR, effectG, effectB, effectA
|
|
|
|
|
|
- let selectedProgressBarStatus = 'none'
|
|
|
+ /** @type {ProgressBarStatus} */
|
|
|
+ let selectedProgressBarStatus = ProgressBarStatus.None
|
|
|
let progress = 0
|
|
|
|
|
|
let windowIconPath
|
|
@@ -146,7 +150,7 @@
|
|
|
}
|
|
|
|
|
|
function changeIcon() {
|
|
|
- webviewMap[selectedWebview].setIcon(path)
|
|
|
+ webviewMap[selectedWebview].setIcon(windowIconPath)
|
|
|
}
|
|
|
|
|
|
function createWebviewWindow() {
|
|
@@ -187,12 +191,8 @@
|
|
|
|
|
|
async function addWindowEventListeners(window) {
|
|
|
if (!window) return
|
|
|
- if (resizeEventUnlisten) {
|
|
|
- resizeEventUnlisten()
|
|
|
- }
|
|
|
- if (moveEventUnlisten) {
|
|
|
- moveEventUnlisten()
|
|
|
- }
|
|
|
+ resizeEventUnlisten?.()
|
|
|
+ moveEventUnlisten?.()
|
|
|
moveEventUnlisten = await window.listen('tauri://move', loadWindowPosition)
|
|
|
resizeEventUnlisten = await window.listen('tauri://resize', loadWindowSize)
|
|
|
}
|
|
@@ -206,6 +206,13 @@
|
|
|
await webviewMap[selectedWebview].requestUserAttention(null)
|
|
|
}
|
|
|
|
|
|
+ async function updateProgressBar() {
|
|
|
+ webviewMap[selectedWebview]?.setProgressBar({
|
|
|
+ status: selectedProgressBarStatus,
|
|
|
+ progress
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
async function addEffect() {
|
|
|
if (!effects.includes(selectedEffect)) {
|
|
|
effects = [...effects, selectedEffect]
|
|
@@ -288,46 +295,56 @@
|
|
|
new PhysicalPosition(cursorX, cursorY)
|
|
|
)
|
|
|
$: webviewMap[selectedWebview]?.setIgnoreCursorEvents(cursorIgnoreEvents)
|
|
|
- $: webviewMap[selectedWebview]?.setProgressBar({
|
|
|
- status: selectedProgressBarStatus,
|
|
|
- progress
|
|
|
+
|
|
|
+ onDestroy(() => {
|
|
|
+ resizeEventUnlisten?.()
|
|
|
+ moveEventUnlisten?.()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
-<div class="flex flex-col children:grow gap-2">
|
|
|
- <div class="flex gap-1">
|
|
|
- <input
|
|
|
- class="input grow"
|
|
|
- type="text"
|
|
|
- placeholder="New Window label.."
|
|
|
- bind:value={newWebviewLabel}
|
|
|
- />
|
|
|
- <button class="btn" on:click={createWebviewWindow}>New window</button>
|
|
|
- </div>
|
|
|
- <br />
|
|
|
- {#if Object.keys(webviewMap).length >= 1}
|
|
|
- <span class="font-700 text-sm">Selected window:</span>
|
|
|
- <select class="input" bind:value={selectedWebview}>
|
|
|
- <option value="" disabled selected>Choose a window...</option>
|
|
|
- {#each Object.keys(webviewMap) as label}
|
|
|
- <option value={label}>{label}</option>
|
|
|
- {/each}
|
|
|
- </select>
|
|
|
- {/if}
|
|
|
- {#if webviewMap[selectedWebview]}
|
|
|
- <br />
|
|
|
- <div class="flex gap-1 items-center">
|
|
|
- <label for="windowIconPath"> Icon path </label>
|
|
|
- <form class="flex gap-1 grow" on:submit|preventDefault={setTitle_}>
|
|
|
+<div class="flex flex-col children:grow gap-8 mb-4">
|
|
|
+ <div class="flex flex-wrap items-center gap-4 pb-6 border-b-solid border-b-1 border-code">
|
|
|
+ {#if Object.keys(webviewMap).length >= 1}
|
|
|
+ <div class="grid gap-1">
|
|
|
+ <h4 class="my-2">Selected Window</h4>
|
|
|
+ <select class="input" bind:value={selectedWebview}>
|
|
|
+ <option value="" disabled selected>Choose a window...</option>
|
|
|
+ {#each Object.keys(webviewMap) as label}
|
|
|
+ <option value={label}>{label}</option>
|
|
|
+ {/each}
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ {/if}
|
|
|
+ <div class="grid gap-1">
|
|
|
+ <h4 class="my-2">Create New Window</h4>
|
|
|
+ <div class="flex gap-2">
|
|
|
<input
|
|
|
- id="windowIconPath"
|
|
|
- class="input grow"
|
|
|
- bind:value={windowIconPath}
|
|
|
+ class="input"
|
|
|
+ type="text"
|
|
|
+ placeholder="New window label.."
|
|
|
+ bind:value={newWebviewLabel}
|
|
|
/>
|
|
|
- <button class="btn" type="submit"> Change window icon </button>
|
|
|
- </form>
|
|
|
+ <button class="btn" on:click={createWebviewWindow}>Create</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {#if webviewMap[selectedWebview]}
|
|
|
+ <div class="flex flex-wrap items-center gap-4">
|
|
|
+ <div class="grid gap-1 grow">
|
|
|
+ <h4 class="my-2">Change Window Icon</h4>
|
|
|
+ <div class="flex gap-2">
|
|
|
+ <input class="input flex-1 min-w-10" placeholder="Window icon path" bind:value={windowIconPath} />
|
|
|
+ <button class="btn" on:click={changeIcon}>Change</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="grid gap-1 grow">
|
|
|
+ <h4 class="my-2">Set Window Title</h4>
|
|
|
+ <div class="flex gap-2">
|
|
|
+ <input class="input flex-1 min-w-10" bind:value={windowTitle}/>
|
|
|
+ <button class="btn" on:click={setTitle_}>Set</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <br />
|
|
|
<div class="flex flex-wrap gap-2">
|
|
|
<button
|
|
|
class="btn"
|
|
@@ -357,53 +374,51 @@
|
|
|
>Request attention</button
|
|
|
>
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="flex flex-wrap gap-2">
|
|
|
- <label>
|
|
|
- Maximized
|
|
|
- <input type="checkbox" bind:checked={maximized} />
|
|
|
- </label>
|
|
|
+ <div class="grid cols-[repeat(auto-fill,minmax(180px,1fr))]">
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={resizable} />
|
|
|
Resizable
|
|
|
- <input type="checkbox" bind:checked={resizable} />
|
|
|
</label>
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={maximizable} />
|
|
|
Maximizable
|
|
|
- <input type="checkbox" bind:checked={maximizable} />
|
|
|
</label>
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={minimizable} />
|
|
|
Minimizable
|
|
|
- <input type="checkbox" bind:checked={minimizable} />
|
|
|
</label>
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={closable} />
|
|
|
Closable
|
|
|
- <input type="checkbox" bind:checked={closable} />
|
|
|
</label>
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={decorations} />
|
|
|
Has decorations
|
|
|
- <input type="checkbox" bind:checked={decorations} />
|
|
|
</label>
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={alwaysOnTop} />
|
|
|
Always on top
|
|
|
- <input type="checkbox" bind:checked={alwaysOnTop} />
|
|
|
</label>
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={alwaysOnBottom} />
|
|
|
Always on bottom
|
|
|
- <input type="checkbox" bind:checked={alwaysOnBottom} />
|
|
|
</label>
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={contentProtected} />
|
|
|
Content protected
|
|
|
- <input type="checkbox" bind:checked={contentProtected} />
|
|
|
</label>
|
|
|
<label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={maximized} />
|
|
|
+ Maximized
|
|
|
+ </label>
|
|
|
+ <label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={fullscreen} />
|
|
|
Fullscreen
|
|
|
- <input type="checkbox" bind:checked={fullscreen} />
|
|
|
</label>
|
|
|
</div>
|
|
|
- <br />
|
|
|
- <div class="flex flex-row gap-2 flex-wrap">
|
|
|
- <div class="flex children:grow flex-col">
|
|
|
- <div>
|
|
|
+ <div class="flex flex-wrap children:flex-basis-30 gap-2">
|
|
|
+ <div class="grid gap-1 children:grid">
|
|
|
+ <label>
|
|
|
X
|
|
|
<input
|
|
|
class="input"
|
|
@@ -412,8 +427,8 @@
|
|
|
on:change={updatePosition}
|
|
|
min="0"
|
|
|
/>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
+ </label>
|
|
|
+ <label>
|
|
|
Y
|
|
|
<input
|
|
|
class="input"
|
|
@@ -422,11 +437,10 @@
|
|
|
on:change={updatePosition}
|
|
|
min="0"
|
|
|
/>
|
|
|
- </div>
|
|
|
+ </label>
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="flex children:grow flex-col">
|
|
|
- <div>
|
|
|
+ <div class="grid gap-1 children:grid">
|
|
|
+ <label>
|
|
|
Width
|
|
|
<input
|
|
|
class="input"
|
|
@@ -435,7 +449,7 @@
|
|
|
on:change={updateSize}
|
|
|
min="400"
|
|
|
/>
|
|
|
- </div>
|
|
|
+ </label>
|
|
|
<div>
|
|
|
Height
|
|
|
<input
|
|
@@ -447,133 +461,130 @@
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="flex children:grow flex-col">
|
|
|
- <div>
|
|
|
+ <div class="grid gap-1 children:grid">
|
|
|
+ <label>
|
|
|
Min width
|
|
|
<input class="input" type="number" bind:value={minWidth} />
|
|
|
- </div>
|
|
|
- <div>
|
|
|
+ </label>
|
|
|
+ <label>
|
|
|
Min height
|
|
|
<input class="input" type="number" bind:value={minHeight} />
|
|
|
- </div>
|
|
|
+ </label>
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="flex children:grow flex-col">
|
|
|
- <div>
|
|
|
+ <div class="grid gap-1 children:grid">
|
|
|
+ <label>
|
|
|
Max width
|
|
|
<input class="input" type="number" bind:value={maxWidth} min="800" />
|
|
|
- </div>
|
|
|
- <div>
|
|
|
+ </label>
|
|
|
+ <label>
|
|
|
Max height
|
|
|
<input class="input" type="number" bind:value={maxHeight} min="400" />
|
|
|
- </div>
|
|
|
+ </label>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <br />
|
|
|
<div class="grid grid-cols-2 gap-2 max-inline-2xl">
|
|
|
- <div >
|
|
|
- <div class="text-accent dark:text-darkAccent font-700 m-block-2">Inner Size</div>
|
|
|
+ <div>
|
|
|
+ <div class="text-accent dark:text-darkAccent font-700 m-block-1">
|
|
|
+ Inner Size
|
|
|
+ </div>
|
|
|
<span>Width: {innerSize.width}</span>
|
|
|
<span>Height: {innerSize.height}</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <div class="text-accent dark:text-darkAccent font-700 m-block-2">Outer Size</div>
|
|
|
+ <div class="text-accent dark:text-darkAccent font-700 m-block-1">
|
|
|
+ Outer Size
|
|
|
+ </div>
|
|
|
<span>Width: {outerSize.width}</span>
|
|
|
<span>Height: {outerSize.height}</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <div class="text-accent dark:text-darkAccent font-700 m-block-2">
|
|
|
+ <div class="text-accent dark:text-darkAccent font-700 m-block-1">
|
|
|
Inner Logical Size
|
|
|
</div>
|
|
|
<span>Width: {innerSize.toLogical(scaleFactor).width.toFixed(3)}</span>
|
|
|
<span>Height: {innerSize.toLogical(scaleFactor).height.toFixed(3)}</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <div class="text-accent dark:text-darkAccent font-700 m-block-2">
|
|
|
+ <div class="text-accent dark:text-darkAccent font-700 m-block-1">
|
|
|
Outer Logical Size
|
|
|
</div>
|
|
|
<span>Width: {outerSize.toLogical(scaleFactor).width.toFixed(3)}</span>
|
|
|
<span>Height: {outerSize.toLogical(scaleFactor).height.toFixed(3)}</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <div class="text-accent dark:text-darkAccent font-700 m-block-2">
|
|
|
+ <div class="text-accent dark:text-darkAccent font-700 m-block-1">
|
|
|
Inner Position
|
|
|
</div>
|
|
|
<span>x: {innerPosition.x}</span>
|
|
|
<span>y: {innerPosition.y}</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <div class="text-accent dark:text-darkAccent font-700 m-block-2">
|
|
|
+ <div class="text-accent dark:text-darkAccent font-700 m-block-1">
|
|
|
Outer Position
|
|
|
</div>
|
|
|
<span>x: {outerPosition.x}</span>
|
|
|
<span>y: {outerPosition.y}</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <div class="text-accent dark:text-darkAccent font-700 m-block-2">
|
|
|
+ <div class="text-accent dark:text-darkAccent font-700 m-block-1">
|
|
|
Inner Logical Position
|
|
|
</div>
|
|
|
<span>x: {innerPosition.toLogical(scaleFactor).x.toFixed(3)}</span>
|
|
|
<span>y: {innerPosition.toLogical(scaleFactor).y.toFixed(3)}</span>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <div class="text-accent dark:text-darkAccent font-700 m-block-2">
|
|
|
+ <div class="text-accent dark:text-darkAccent font-700 m-block-1">
|
|
|
Outer Logical Position
|
|
|
</div>
|
|
|
<span>x: {outerPosition.toLogical(scaleFactor).x.toFixed(3)}</span>
|
|
|
<span>y: {outerPosition.toLogical(scaleFactor).y.toFixed(3)}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <br />
|
|
|
- <h4 class="mb-2">Cursor</h4>
|
|
|
- <div class="flex gap-2">
|
|
|
- <label>
|
|
|
- <input type="checkbox" bind:checked={cursorGrab} />
|
|
|
- Grab
|
|
|
- </label>
|
|
|
- <label>
|
|
|
- <input type="checkbox" bind:checked={cursorVisible} />
|
|
|
- Visible
|
|
|
- </label>
|
|
|
- <label>
|
|
|
- <input type="checkbox" bind:checked={cursorIgnoreEvents} />
|
|
|
- Ignore events
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <div class="flex gap-2">
|
|
|
- <label>
|
|
|
- Icon
|
|
|
- <select class="input" bind:value={cursorIcon}>
|
|
|
- {#each cursorIconOptions as kind}
|
|
|
- <option value={kind}>{kind}</option>
|
|
|
- {/each}
|
|
|
- </select>
|
|
|
- </label>
|
|
|
- <label>
|
|
|
- X position
|
|
|
- <input class="input" type="number" bind:value={cursorX} />
|
|
|
- </label>
|
|
|
- <label>
|
|
|
- Y position
|
|
|
- <input class="input" type="number" bind:value={cursorY} />
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <br />
|
|
|
- <div class="flex flex-col gap-1">
|
|
|
- <form class="flex gap-1" on:submit|preventDefault={setTitle_}>
|
|
|
- <input class="input grow" id="title" bind:value={windowTitle} />
|
|
|
- <button class="btn" type="submit">Set title</button>
|
|
|
- </form>
|
|
|
+ <div class="grid gap-2">
|
|
|
+ <h4 class="my-2">Cursor</h4>
|
|
|
+ <div class="flex gap-2">
|
|
|
+ <label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={cursorGrab} />
|
|
|
+ Grab
|
|
|
+ </label>
|
|
|
+ <label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={cursorVisible} />
|
|
|
+ Visible
|
|
|
+ </label>
|
|
|
+ <label>
|
|
|
+ <input type="checkbox" class="checkbox" bind:checked={cursorIgnoreEvents} />
|
|
|
+ Ignore events
|
|
|
+ </label>
|
|
|
+ </div>
|
|
|
+ <div class="flex gap-2">
|
|
|
+ <label>
|
|
|
+ Icon
|
|
|
+ <select class="input" bind:value={cursorIcon}>
|
|
|
+ {#each cursorIconOptions as kind}
|
|
|
+ <option value={kind}>{kind}</option>
|
|
|
+ {/each}
|
|
|
+ </select>
|
|
|
+ </label>
|
|
|
+ <label>
|
|
|
+ X position
|
|
|
+ <input class="input" type="number" bind:value={cursorX} />
|
|
|
+ </label>
|
|
|
+ <label>
|
|
|
+ Y position
|
|
|
+ <input class="input" type="number" bind:value={cursorY} />
|
|
|
+ </label>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
- <br />
|
|
|
-
|
|
|
<div class="flex flex-col gap-1">
|
|
|
<div class="flex gap-2">
|
|
|
<label>
|
|
|
Progress Status
|
|
|
- <select class="input" bind:value={selectedProgressBarStatus}>
|
|
|
+ <select
|
|
|
+ class="input"
|
|
|
+ bind:value={selectedProgressBarStatus}
|
|
|
+ on:change={updateProgressBar}
|
|
|
+ >
|
|
|
{#each progressBarStatusOptions as status}
|
|
|
<option value={status}>{status}</option>
|
|
|
{/each}
|
|
@@ -588,14 +599,25 @@
|
|
|
min="0"
|
|
|
max="100"
|
|
|
bind:value={progress}
|
|
|
+ on:change={updateProgressBar}
|
|
|
/>
|
|
|
</label>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
{#if isWindows || isMacOS}
|
|
|
- <div class="flex flex-col gap-1">
|
|
|
- <div class="flex">
|
|
|
+ <div class="flex flex-col gap-2">
|
|
|
+ <div class="flex items-center gap-2">
|
|
|
+ <div>
|
|
|
+ Applied effects: {effects.length ? effects.join(', ') : 'None'}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <button class="btn" on:click={clearEffects}
|
|
|
+ >Clear</button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="flex gap-2">
|
|
|
<label>
|
|
|
Effect
|
|
|
<select class="input" bind:value={selectedEffect}>
|
|
@@ -623,30 +645,26 @@
|
|
|
<div class="flex">
|
|
|
<label>
|
|
|
Color
|
|
|
- <div class="flex">
|
|
|
+ <div class="flex gap-2 children:flex-basis-30">
|
|
|
<input
|
|
|
- style="max-width: 120px;"
|
|
|
class="input"
|
|
|
type="number"
|
|
|
placeholder="R"
|
|
|
bind:value={effectR}
|
|
|
/>
|
|
|
<input
|
|
|
- style="max-width: 120px;"
|
|
|
class="input"
|
|
|
type="number"
|
|
|
placeholder="G"
|
|
|
bind:value={effectG}
|
|
|
/>
|
|
|
<input
|
|
|
- style="max-width: 120px;"
|
|
|
class="input"
|
|
|
type="number"
|
|
|
placeholder="B"
|
|
|
bind:value={effectB}
|
|
|
/>
|
|
|
<input
|
|
|
- style="max-width: 120px;"
|
|
|
class="input"
|
|
|
type="number"
|
|
|
placeholder="A"
|
|
@@ -657,20 +675,10 @@
|
|
|
</div>
|
|
|
|
|
|
<div class="flex">
|
|
|
- <button class="btn" style="width: 80px;" on:click={addEffect}
|
|
|
+ <button class="btn" on:click={addEffect}
|
|
|
>Add</button
|
|
|
>
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="flex">
|
|
|
- <div>
|
|
|
- Applied effects: {effects.length ? effects.join(',') : 'None'}
|
|
|
- </div>
|
|
|
-
|
|
|
- <button class="btn" style="width: 80px;" on:click={clearEffects}
|
|
|
- >Clear</button
|
|
|
- >
|
|
|
- </div>
|
|
|
</div>
|
|
|
{/if}
|
|
|
{/if}
|