mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 11:08:11 +08:00
Desktop: Add the transparent viewport hole punch and hook up window button plumbing (#2949)
This commit is contained in:
@@ -1,18 +1,17 @@
|
||||
<script lang="ts" context="module">
|
||||
export type ApplicationPlatform = "Windows" | "Mac" | "Linux" | "Web";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { AppWindowPlatform } from "@graphite/messages";
|
||||
|
||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||
import StatusBar from "@graphite/components/window/status-bar/StatusBar.svelte";
|
||||
import TitleBar from "@graphite/components/window/title-bar/TitleBar.svelte";
|
||||
import Workspace from "@graphite/components/window/workspace/Workspace.svelte";
|
||||
|
||||
let platform: ApplicationPlatform = "Web";
|
||||
let maximized: true;
|
||||
export let platform: AppWindowPlatform;
|
||||
export let maximized: boolean;
|
||||
export let viewportHolePunch: boolean;
|
||||
</script>
|
||||
|
||||
<LayoutCol class="main-window">
|
||||
<LayoutCol class="main-window" classes={{ "viewport-hole-punch": viewportHolePunch }}>
|
||||
<TitleBar {platform} {maximized} />
|
||||
|
||||
<Workspace />
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
<script lang="ts" context="module">
|
||||
export type Platform = "Windows" | "Mac" | "Linux" | "Web";
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { getContext, onMount } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import { type KeyRaw, type LayoutKeysGroup, type MenuBarEntry, type MenuListEntry, UpdateMenuBarLayout } from "@graphite/messages";
|
||||
import { type KeyRaw, type LayoutKeysGroup, type MenuBarEntry, type MenuListEntry, type AppWindowPlatform, UpdateMenuBarLayout } from "@graphite/messages";
|
||||
import type { PortfolioState } from "@graphite/state-providers/portfolio";
|
||||
import { platformIsMac } from "@graphite/utility-functions/platform";
|
||||
|
||||
@@ -17,7 +13,7 @@
|
||||
import WindowButtonsWindows from "@graphite/components/window/title-bar/WindowButtonsWindows.svelte";
|
||||
import WindowTitle from "@graphite/components/window/title-bar/WindowTitle.svelte";
|
||||
|
||||
export let platform: Platform;
|
||||
export let platform: AppWindowPlatform;
|
||||
export let maximized: boolean;
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
@@ -73,7 +69,7 @@
|
||||
<!-- Menu bar (or on Mac: window buttons) -->
|
||||
<LayoutRow class="left">
|
||||
{#if platform === "Mac"}
|
||||
<WindowButtonsMac {maximized} />
|
||||
<WindowButtonsMac />
|
||||
{:else}
|
||||
{#each entries as entry}
|
||||
<TextButton label={entry.label} icon={entry.icon} menuListChildren={entry.children} action={entry.action} flush={true} />
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
|
||||
export let maximized = false;
|
||||
const editor = getContext<Editor>("editor");
|
||||
</script>
|
||||
|
||||
<LayoutRow class="window-buttons-mac">
|
||||
<div class="close" title="Close" />
|
||||
<div class="minimize" title={maximized ? "Minimize" : "Maximize"} />
|
||||
<div class="zoom" title="Zoom" />
|
||||
<div class="close" on:click={() => editor.handle.appWindowClose()} />
|
||||
<div class="minimize" on:click={() => editor.handle.appWindowMinimize()} />
|
||||
<div class="zoom" on:click={() => editor.handle.appWindowMaximize()} />
|
||||
</LayoutRow>
|
||||
|
||||
<style lang="scss" global>
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
import type { FullscreenState } from "@graphite/state-providers/fullscreen";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
|
||||
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
const fullscreen = getContext<FullscreenState>("fullscreen");
|
||||
|
||||
$: requestFullscreenHotkeys = fullscreen.keyboardLockApiSupported && !$fullscreen.keyboardLocked;
|
||||
|
||||
async function handleClick() {
|
||||
async function handleClick(e: MouseEvent) {
|
||||
// TODO: Remove this debugging option to switch from web to desktop window buttons
|
||||
if (e.ctrlKey && e.shiftKey && e.altKey) {
|
||||
editor.handle.appWindowMinimize();
|
||||
editor.handle.appWindowMinimize();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($fullscreen.windowFullscreen) fullscreen.exitFullscreen();
|
||||
else fullscreen.enterFullscreen();
|
||||
}
|
||||
</script>
|
||||
|
||||
<LayoutRow class="window-buttons-web" on:click={() => handleClick()} tooltip={($fullscreen.windowFullscreen ? "Exit" : "Enter") + " Fullscreen (F11)"}>
|
||||
<LayoutRow class="window-buttons-web" on:click={handleClick} tooltip={$fullscreen.windowFullscreen ? "Exit Fullscreen (F11)" : "Enter Fullscreen (F11)"}>
|
||||
{#if requestFullscreenHotkeys}
|
||||
<TextLabel italic={true}>Go fullscreen to access all hotkeys</TextLabel>
|
||||
{/if}
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from "svelte";
|
||||
|
||||
import type { Editor } from "@graphite/editor";
|
||||
|
||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
|
||||
|
||||
export let maximized = false;
|
||||
export let maximized;
|
||||
|
||||
const editor = getContext<Editor>("editor");
|
||||
</script>
|
||||
|
||||
<LayoutRow class="window-button windows minimize" tooltip="Minimize">
|
||||
<LayoutRow class="window-button windows" tooltip="Minimize" on:click={() => editor.handle.appWindowMinimize()}>
|
||||
<IconLabel icon={"WindowButtonWinMinimize"} />
|
||||
</LayoutRow>
|
||||
{#if !maximized}
|
||||
<LayoutRow class="window-button windows maximize" tooltip="Maximize">
|
||||
<IconLabel icon={"WindowButtonWinMaximize"} />
|
||||
</LayoutRow>
|
||||
{:else}
|
||||
<LayoutRow class="window-button windows restore-down" tooltip="Restore Down">
|
||||
<IconLabel icon={"WindowButtonWinRestoreDown"} />
|
||||
</LayoutRow>
|
||||
{/if}
|
||||
<LayoutRow class="window-button windows close" tooltip="Close">
|
||||
<LayoutRow class="window-button windows" tooltip={maximized ? "Restore Down" : "Maximize"} on:click={() => editor.handle.appWindowMaximize()}>
|
||||
<IconLabel icon={maximized ? "WindowButtonWinRestoreDown" : "WindowButtonWinMaximize"} />
|
||||
</LayoutRow>
|
||||
<LayoutRow class="window-button windows" tooltip="Close" on:click={() => editor.handle.appWindowClose()}>
|
||||
<IconLabel icon={"WindowButtonWinClose"} />
|
||||
</LayoutRow>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.close:hover {
|
||||
&:last-of-type:hover {
|
||||
background: #e81123;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,13 @@
|
||||
export let clickAction: ((index: number) => void) | undefined = undefined;
|
||||
export let closeAction: ((index: number) => void) | undefined = undefined;
|
||||
|
||||
let className = "";
|
||||
export { className as class };
|
||||
export let classes: Record<string, boolean> = {};
|
||||
let styleName = "";
|
||||
export { styleName as style };
|
||||
export let styles: Record<string, string | number | undefined> = {};
|
||||
|
||||
let tabElements: (LayoutRow | undefined)[] = [];
|
||||
|
||||
function platformModifiers(reservedKey: boolean): LayoutKeysGroup {
|
||||
@@ -90,7 +97,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<LayoutCol class="panel" on:pointerdown={() => panelType && editor.handle.setActivePanel(panelType)}>
|
||||
<LayoutCol on:pointerdown={() => panelType && editor.handle.setActivePanel(panelType)} class={`panel ${className}`.trim()} {classes} style={styleName} {styles}>
|
||||
<LayoutRow class="tab-bar" classes={{ "min-widths": tabMinWidths }}>
|
||||
<LayoutRow class="tab-group" scrollableX={true}>
|
||||
{#each tabLabels as tabLabel, tabIndex}
|
||||
@@ -194,6 +201,7 @@
|
||||
.tab-bar {
|
||||
height: 28px;
|
||||
min-height: auto;
|
||||
background: var(--color-1-nearblack); // Needed for the viewport hole punch on desktop
|
||||
|
||||
&.min-widths .tab-group .tab {
|
||||
min-width: 120px;
|
||||
@@ -336,5 +344,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Needed for the viewport hole punch on desktop
|
||||
.viewport-hole-punch &.document-panel,
|
||||
.viewport-hole-punch &.document-panel .panel-body:not(:has(.empty-panel)) {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -137,6 +137,7 @@
|
||||
<LayoutCol class="workspace-grid-subdivision" styles={{ "flex-grow": panelSizes["content"] }} data-subdivision-name="content">
|
||||
<LayoutRow class="workspace-grid-subdivision" styles={{ "flex-grow": panelSizes["document"] }} data-subdivision-name="document">
|
||||
<Panel
|
||||
class="document-panel"
|
||||
panelType={$portfolio.documents.length > 0 ? "Document" : undefined}
|
||||
tabCloseButtons={true}
|
||||
tabMinWidths={true}
|
||||
@@ -176,8 +177,9 @@
|
||||
flex: 1 1 100%;
|
||||
|
||||
.workspace-grid-subdivision {
|
||||
min-height: 28px;
|
||||
position: relative;
|
||||
flex: 1 1 0;
|
||||
min-height: 28px;
|
||||
|
||||
&.folded {
|
||||
flex-grow: 0;
|
||||
@@ -196,5 +198,15 @@
|
||||
cursor: ew-resize;
|
||||
}
|
||||
}
|
||||
|
||||
// Needed for the viewport hole punch on desktop
|
||||
.viewport-hole-punch & .workspace-grid-subdivision:has(.panel.document-panel)::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 6px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 0 calc(100vw + 100vh) var(--color-2-mildblack);
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user