restty 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/app/index.d.ts +1 -1
- package/dist/app/pane-app-manager.d.ts +4 -1
- package/dist/app/panes.d.ts +14 -0
- package/dist/app/restty.d.ts +3 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +262 -3
- package/dist/renderer/shaders.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -109,6 +109,7 @@ await restty.setFontSources([
|
|
|
109
109
|
|
|
110
110
|
`restty` ships a pane manager and a default terminal context menu so you can add split panes quickly.
|
|
111
111
|
It auto-creates pane DOM, canvas, and hidden IME inputs for you.
|
|
112
|
+
Pane/split/divider styles are injected by the library (no separate CSS file required).
|
|
112
113
|
|
|
113
114
|
```ts
|
|
114
115
|
import {
|
|
@@ -131,6 +132,10 @@ const restty = new Restty({
|
|
|
131
132
|
defaultContextMenu: {
|
|
132
133
|
getPtyUrl: () => "ws://localhost:8787/pty",
|
|
133
134
|
},
|
|
135
|
+
paneStyles: {
|
|
136
|
+
inactivePaneOpacity: 0.82,
|
|
137
|
+
dividerThicknessPx: 1,
|
|
138
|
+
},
|
|
134
139
|
shortcuts: true,
|
|
135
140
|
});
|
|
136
141
|
|
|
@@ -150,6 +155,7 @@ Main methods:
|
|
|
150
155
|
- `destroy()`
|
|
151
156
|
- `getPanes()` / `getActivePane()` / `getFocusedPane()`
|
|
152
157
|
- `splitActivePane("vertical" | "horizontal")` / `splitPane(id, direction)` / `closePane(id)`
|
|
158
|
+
- `getPaneStyleOptions()` / `setPaneStyleOptions({...})`
|
|
153
159
|
- `connectPty(url)` / `disconnectPty()` / `isPtyConnected()`
|
|
154
160
|
- `setRenderer("auto" | "webgpu" | "webgl2")`
|
|
155
161
|
- `setFontSize(number)`
|
package/dist/app/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export { createResttyAppSession, getDefaultResttyAppSession } from "./session";
|
|
|
3
3
|
export { createResttyPaneManager, createDefaultResttyPaneContextMenuItems, getResttyShortcutModifierLabel, } from "./panes";
|
|
4
4
|
export { Restty } from "./restty";
|
|
5
5
|
export type { ResttyAppElements, ResttyAppCallbacks, FontSource, ResttyFontSource, ResttyUrlFontSource, ResttyBufferFontSource, ResttyLocalFontSource, ResttyWasmLogListener, ResttyAppSession, ResttyAppOptions, ResttyApp, } from "./types";
|
|
6
|
-
export type { ResttyPaneSplitDirection, ResttyPaneContextMenuItem, ResttyPaneDefinition, ResttyPaneShortcutsOptions, ResttyPaneContextMenuOptions, CreateResttyPaneManagerOptions, ResttyPaneManager, ResttyPaneWithApp, CreateDefaultResttyPaneContextMenuItemsOptions, } from "./panes";
|
|
6
|
+
export type { ResttyPaneSplitDirection, ResttyPaneContextMenuItem, ResttyPaneDefinition, ResttyPaneStyleOptions, ResttyPaneStylesOptions, ResttyPaneShortcutsOptions, ResttyPaneContextMenuOptions, CreateResttyPaneManagerOptions, ResttyPaneManager, ResttyPaneWithApp, CreateDefaultResttyPaneContextMenuItemsOptions, } from "./panes";
|
|
7
7
|
export type { ResttyOptions } from "./restty";
|
|
8
8
|
export declare function createResttyApp(options: ResttyAppOptions): ResttyApp;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ResttyPaneContextMenuOptions, type ResttyPaneManager, type ResttyPaneShortcutsOptions, type ResttyPaneWithApp } from "./panes";
|
|
1
|
+
import { type ResttyPaneStyleOptions, type ResttyPaneStylesOptions, type ResttyPaneContextMenuOptions, type ResttyPaneManager, type ResttyPaneShortcutsOptions, type ResttyPaneWithApp } from "./panes";
|
|
2
2
|
import type { ResttyAppOptions, ResttyAppSession } from "./types";
|
|
3
3
|
export type ResttyManagedAppPane = ResttyPaneWithApp & {
|
|
4
4
|
canvas: HTMLCanvasElement;
|
|
@@ -11,6 +11,8 @@ export type ResttyPaneDomDefaults = {
|
|
|
11
11
|
imeInputClassName?: string;
|
|
12
12
|
termDebugClassName?: string;
|
|
13
13
|
};
|
|
14
|
+
export type ResttyManagedPaneStyleOptions = ResttyPaneStyleOptions;
|
|
15
|
+
export type ResttyManagedPaneStylesOptions = ResttyPaneStylesOptions;
|
|
14
16
|
export type ResttyPaneAppOptionsInput = Omit<ResttyAppOptions, "canvas" | "imeInput" | "session">;
|
|
15
17
|
export type ResttyDefaultPaneContextMenuOptions = {
|
|
16
18
|
enabled?: boolean;
|
|
@@ -31,6 +33,7 @@ export type CreateResttyAppPaneManagerOptions = {
|
|
|
31
33
|
paneDom?: ResttyPaneDomDefaults;
|
|
32
34
|
autoInit?: boolean;
|
|
33
35
|
minPaneSize?: number;
|
|
36
|
+
paneStyles?: boolean | ResttyManagedPaneStylesOptions;
|
|
34
37
|
shortcuts?: boolean | ResttyPaneShortcutsOptions;
|
|
35
38
|
contextMenu?: ResttyPaneContextMenuOptions<ResttyManagedAppPane> | null;
|
|
36
39
|
defaultContextMenu?: boolean | ResttyDefaultPaneContextMenuOptions;
|
package/dist/app/panes.d.ts
CHANGED
|
@@ -21,6 +21,17 @@ export type ResttyPaneContextMenuOptions<TPane extends ResttyPaneDefinition> = {
|
|
|
21
21
|
canOpen?: (event: MouseEvent, pane: TPane) => boolean;
|
|
22
22
|
getItems: (pane: TPane, manager: ResttyPaneManager<TPane>) => Array<ResttyPaneContextMenuItem | "separator">;
|
|
23
23
|
};
|
|
24
|
+
export type ResttyPaneStyleOptions = {
|
|
25
|
+
splitBackground?: string;
|
|
26
|
+
paneBackground?: string;
|
|
27
|
+
inactivePaneOpacity?: number;
|
|
28
|
+
activePaneOpacity?: number;
|
|
29
|
+
opacityTransitionMs?: number;
|
|
30
|
+
dividerThicknessPx?: number;
|
|
31
|
+
};
|
|
32
|
+
export type ResttyPaneStylesOptions = ResttyPaneStyleOptions & {
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
};
|
|
24
35
|
export type CreateResttyPaneManagerOptions<TPane extends ResttyPaneDefinition> = {
|
|
25
36
|
root: HTMLElement;
|
|
26
37
|
createPane: (context: {
|
|
@@ -37,6 +48,7 @@ export type CreateResttyPaneManagerOptions<TPane extends ResttyPaneDefinition> =
|
|
|
37
48
|
minPaneSize?: number;
|
|
38
49
|
contextMenu?: ResttyPaneContextMenuOptions<TPane> | null;
|
|
39
50
|
shortcuts?: boolean | ResttyPaneShortcutsOptions;
|
|
51
|
+
styles?: boolean | ResttyPaneStylesOptions;
|
|
40
52
|
};
|
|
41
53
|
export type ResttyPaneManager<TPane extends ResttyPaneDefinition> = {
|
|
42
54
|
getPanes: () => TPane[];
|
|
@@ -55,6 +67,8 @@ export type ResttyPaneManager<TPane extends ResttyPaneDefinition> = {
|
|
|
55
67
|
splitPane: (id: number, direction: ResttyPaneSplitDirection) => TPane | null;
|
|
56
68
|
splitActivePane: (direction: ResttyPaneSplitDirection) => TPane | null;
|
|
57
69
|
closePane: (id: number) => boolean;
|
|
70
|
+
getStyleOptions: () => Readonly<Required<ResttyPaneStyleOptions>>;
|
|
71
|
+
setStyleOptions: (options: ResttyPaneStyleOptions) => void;
|
|
58
72
|
requestLayoutSync: () => void;
|
|
59
73
|
hideContextMenu: () => void;
|
|
60
74
|
destroy: () => void;
|
package/dist/app/restty.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { GhosttyTheme } from "../theme";
|
|
2
2
|
import type { InputHandler } from "../input";
|
|
3
|
-
import { type CreateResttyAppPaneManagerOptions, type ResttyPaneAppOptionsInput, type ResttyManagedAppPane } from "./pane-app-manager";
|
|
3
|
+
import { type CreateResttyAppPaneManagerOptions, type ResttyManagedPaneStyleOptions, type ResttyPaneAppOptionsInput, type ResttyManagedAppPane } from "./pane-app-manager";
|
|
4
4
|
import type { ResttyPaneManager, ResttyPaneSplitDirection } from "./panes";
|
|
5
5
|
import type { ResttyFontSource } from "./types";
|
|
6
6
|
export type ResttyOptions = Omit<CreateResttyAppPaneManagerOptions, "appOptions"> & {
|
|
@@ -24,6 +24,8 @@ export declare class Restty {
|
|
|
24
24
|
splitActivePane(direction: ResttyPaneSplitDirection): ResttyManagedAppPane | null;
|
|
25
25
|
splitPane(id: number, direction: ResttyPaneSplitDirection): ResttyManagedAppPane | null;
|
|
26
26
|
closePane(id: number): boolean;
|
|
27
|
+
getPaneStyleOptions(): Readonly<Required<ResttyManagedPaneStyleOptions>>;
|
|
28
|
+
setPaneStyleOptions(options: ResttyManagedPaneStyleOptions): void;
|
|
27
29
|
setActivePane(id: number, options?: {
|
|
28
30
|
focus?: boolean;
|
|
29
31
|
}): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,5 +14,5 @@ export { parseGhosttyTheme, parseGhosttyColor, colorToFloats, colorToRgbU32, lis
|
|
|
14
14
|
export type { GhosttyTheme, ThemeColor, ResttyBuiltinThemeName } from "./theme";
|
|
15
15
|
export { Restty } from "./app/restty";
|
|
16
16
|
export type { ResttyOptions } from "./app/restty";
|
|
17
|
-
export type { ResttyManagedAppPane, ResttyPaneDomDefaults, ResttyPaneAppOptionsInput, } from "./app/pane-app-manager";
|
|
17
|
+
export type { ResttyManagedAppPane, ResttyPaneDomDefaults, ResttyManagedPaneStyleOptions, ResttyManagedPaneStylesOptions, ResttyPaneAppOptionsInput, } from "./app/pane-app-manager";
|
|
18
18
|
export type { ResttyFontSource, ResttyUrlFontSource, ResttyBufferFontSource, ResttyLocalFontSource, } from "./app/types";
|
package/dist/index.js
CHANGED
|
@@ -875,12 +875,12 @@ float luminance(vec3 color) {
|
|
|
875
875
|
}
|
|
876
876
|
|
|
877
877
|
void main() {
|
|
878
|
-
vec4
|
|
878
|
+
vec4 atlasSample = texture(u_atlas, v_uv);
|
|
879
879
|
bool useLinear = u_blend.x > 0.5;
|
|
880
880
|
bool useCorrection = u_blend.y > 0.5;
|
|
881
881
|
|
|
882
882
|
if (v_mode > 0.5) {
|
|
883
|
-
vec4 color =
|
|
883
|
+
vec4 color = atlasSample;
|
|
884
884
|
if (useLinear) {
|
|
885
885
|
color.rgb = srgbToLinear(color.rgb);
|
|
886
886
|
}
|
|
@@ -898,7 +898,7 @@ void main() {
|
|
|
898
898
|
fg.rgb *= fg.a;
|
|
899
899
|
bg.rgb *= bg.a;
|
|
900
900
|
|
|
901
|
-
float alpha =
|
|
901
|
+
float alpha = atlasSample.a;
|
|
902
902
|
if (useCorrection && useLinear) {
|
|
903
903
|
float fg_l = luminance(fg.rgb);
|
|
904
904
|
float bg_l = luminance(bg.rgb);
|
|
@@ -25464,6 +25464,230 @@ function getBuiltinTheme(name) {
|
|
|
25464
25464
|
return parsed;
|
|
25465
25465
|
}
|
|
25466
25466
|
// src/app/panes.ts
|
|
25467
|
+
var RESTTY_PANE_ROOT_CLASS = "restty-pane-root";
|
|
25468
|
+
var RESTTY_PANE_STYLE_MARKER = "data-restty-pane-styles";
|
|
25469
|
+
var RESTTY_PANE_STYLE_TEXT = `
|
|
25470
|
+
.${RESTTY_PANE_ROOT_CLASS} {
|
|
25471
|
+
display: flex;
|
|
25472
|
+
width: 100%;
|
|
25473
|
+
height: 100%;
|
|
25474
|
+
min-width: 0;
|
|
25475
|
+
min-height: 0;
|
|
25476
|
+
}
|
|
25477
|
+
|
|
25478
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-split {
|
|
25479
|
+
display: flex;
|
|
25480
|
+
flex: 1 1 auto;
|
|
25481
|
+
min-width: 0;
|
|
25482
|
+
min-height: 0;
|
|
25483
|
+
gap: 0;
|
|
25484
|
+
padding: 0;
|
|
25485
|
+
background: var(--restty-pane-split-background, #111);
|
|
25486
|
+
}
|
|
25487
|
+
|
|
25488
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-split.is-vertical {
|
|
25489
|
+
flex-direction: row;
|
|
25490
|
+
}
|
|
25491
|
+
|
|
25492
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-split.is-horizontal {
|
|
25493
|
+
flex-direction: column;
|
|
25494
|
+
}
|
|
25495
|
+
|
|
25496
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane {
|
|
25497
|
+
position: relative;
|
|
25498
|
+
flex: 1 1 0;
|
|
25499
|
+
min-width: 0;
|
|
25500
|
+
min-height: 0;
|
|
25501
|
+
background: var(--restty-pane-background, #000);
|
|
25502
|
+
border: 0;
|
|
25503
|
+
overflow: hidden;
|
|
25504
|
+
opacity: var(--restty-pane-inactive-opacity, 0.82);
|
|
25505
|
+
transition: opacity var(--restty-pane-opacity-transition, 140ms) ease-out;
|
|
25506
|
+
}
|
|
25507
|
+
|
|
25508
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane.is-active {
|
|
25509
|
+
opacity: var(--restty-pane-active-opacity, 1);
|
|
25510
|
+
}
|
|
25511
|
+
|
|
25512
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-divider {
|
|
25513
|
+
position: relative;
|
|
25514
|
+
z-index: 2;
|
|
25515
|
+
flex: 0 0 var(--restty-pane-divider-thickness, 1px);
|
|
25516
|
+
touch-action: none;
|
|
25517
|
+
}
|
|
25518
|
+
|
|
25519
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-divider.is-vertical {
|
|
25520
|
+
cursor: col-resize;
|
|
25521
|
+
background: transparent;
|
|
25522
|
+
}
|
|
25523
|
+
|
|
25524
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-divider.is-horizontal {
|
|
25525
|
+
cursor: row-resize;
|
|
25526
|
+
background: transparent;
|
|
25527
|
+
}
|
|
25528
|
+
|
|
25529
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-divider.is-vertical:hover,
|
|
25530
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-divider.is-vertical.is-dragging {
|
|
25531
|
+
background:
|
|
25532
|
+
radial-gradient(
|
|
25533
|
+
100px 46% at 50% 50%,
|
|
25534
|
+
rgba(235, 235, 235, 0.92) 0%,
|
|
25535
|
+
rgba(200, 200, 200, 0.48) 46%,
|
|
25536
|
+
rgba(155, 155, 155, 0.12) 68%,
|
|
25537
|
+
rgba(120, 120, 120, 0) 100%
|
|
25538
|
+
),
|
|
25539
|
+
rgba(185, 185, 185, 0.24);
|
|
25540
|
+
}
|
|
25541
|
+
|
|
25542
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-divider.is-horizontal:hover,
|
|
25543
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-divider.is-horizontal.is-dragging {
|
|
25544
|
+
background:
|
|
25545
|
+
radial-gradient(
|
|
25546
|
+
46% 100px at 50% 50%,
|
|
25547
|
+
rgba(235, 235, 235, 0.92) 0%,
|
|
25548
|
+
rgba(200, 200, 200, 0.48) 46%,
|
|
25549
|
+
rgba(155, 155, 155, 0.12) 68%,
|
|
25550
|
+
rgba(120, 120, 120, 0) 100%
|
|
25551
|
+
),
|
|
25552
|
+
rgba(185, 185, 185, 0.24);
|
|
25553
|
+
}
|
|
25554
|
+
|
|
25555
|
+
body.is-resizing-split {
|
|
25556
|
+
user-select: none;
|
|
25557
|
+
}
|
|
25558
|
+
|
|
25559
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-canvas {
|
|
25560
|
+
width: 100%;
|
|
25561
|
+
height: 100%;
|
|
25562
|
+
display: block;
|
|
25563
|
+
outline: none;
|
|
25564
|
+
}
|
|
25565
|
+
|
|
25566
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-ime-input {
|
|
25567
|
+
position: fixed;
|
|
25568
|
+
left: 0;
|
|
25569
|
+
top: 0;
|
|
25570
|
+
width: 1px;
|
|
25571
|
+
height: 1px;
|
|
25572
|
+
opacity: 0;
|
|
25573
|
+
pointer-events: none;
|
|
25574
|
+
}
|
|
25575
|
+
|
|
25576
|
+
.${RESTTY_PANE_ROOT_CLASS} .pane-term-debug {
|
|
25577
|
+
display: none;
|
|
25578
|
+
}
|
|
25579
|
+
|
|
25580
|
+
.pane-context-menu {
|
|
25581
|
+
position: fixed;
|
|
25582
|
+
z-index: 9999;
|
|
25583
|
+
min-width: 200px;
|
|
25584
|
+
padding: 6px;
|
|
25585
|
+
border: 1px solid #2a2a2a;
|
|
25586
|
+
border-radius: 8px;
|
|
25587
|
+
background: #161616;
|
|
25588
|
+
box-shadow: 0 14px 40px rgba(0, 0, 0, 0.45);
|
|
25589
|
+
}
|
|
25590
|
+
|
|
25591
|
+
.pane-context-menu-item {
|
|
25592
|
+
width: 100%;
|
|
25593
|
+
display: flex;
|
|
25594
|
+
align-items: center;
|
|
25595
|
+
justify-content: space-between;
|
|
25596
|
+
gap: 12px;
|
|
25597
|
+
padding: 7px 9px;
|
|
25598
|
+
border: 0;
|
|
25599
|
+
border-radius: 6px;
|
|
25600
|
+
background: transparent;
|
|
25601
|
+
color: #d6d6d6;
|
|
25602
|
+
text-align: left;
|
|
25603
|
+
cursor: pointer;
|
|
25604
|
+
}
|
|
25605
|
+
|
|
25606
|
+
.pane-context-menu-item:hover {
|
|
25607
|
+
background: #252525;
|
|
25608
|
+
}
|
|
25609
|
+
|
|
25610
|
+
.pane-context-menu-item:disabled {
|
|
25611
|
+
opacity: 0.4;
|
|
25612
|
+
cursor: default;
|
|
25613
|
+
}
|
|
25614
|
+
|
|
25615
|
+
.pane-context-menu-item.is-danger {
|
|
25616
|
+
color: #f1a1a1;
|
|
25617
|
+
}
|
|
25618
|
+
|
|
25619
|
+
.pane-context-menu-label {
|
|
25620
|
+
font-size: 12px;
|
|
25621
|
+
}
|
|
25622
|
+
|
|
25623
|
+
.pane-context-menu-shortcut {
|
|
25624
|
+
font-size: 10px;
|
|
25625
|
+
color: #868686;
|
|
25626
|
+
}
|
|
25627
|
+
|
|
25628
|
+
.pane-context-menu-separator {
|
|
25629
|
+
height: 1px;
|
|
25630
|
+
margin: 6px 4px;
|
|
25631
|
+
background: #2a2a2a;
|
|
25632
|
+
}
|
|
25633
|
+
`;
|
|
25634
|
+
var DEFAULT_RESTTY_PANE_STYLE_OPTIONS = {
|
|
25635
|
+
splitBackground: "#111",
|
|
25636
|
+
paneBackground: "#000",
|
|
25637
|
+
inactivePaneOpacity: 0.82,
|
|
25638
|
+
activePaneOpacity: 1,
|
|
25639
|
+
opacityTransitionMs: 140,
|
|
25640
|
+
dividerThicknessPx: 1
|
|
25641
|
+
};
|
|
25642
|
+
function clampNumber(value, min, max) {
|
|
25643
|
+
return Math.min(max, Math.max(min, value));
|
|
25644
|
+
}
|
|
25645
|
+
function normalizeColor(value, fallback) {
|
|
25646
|
+
if (typeof value !== "string")
|
|
25647
|
+
return fallback;
|
|
25648
|
+
const trimmed = value.trim();
|
|
25649
|
+
return trimmed ? trimmed : fallback;
|
|
25650
|
+
}
|
|
25651
|
+
function normalizePaneStyleOptions(options) {
|
|
25652
|
+
const inactivePaneOpacity = Number.isFinite(options.inactivePaneOpacity) ? clampNumber(Number(options.inactivePaneOpacity), 0, 1) : DEFAULT_RESTTY_PANE_STYLE_OPTIONS.inactivePaneOpacity;
|
|
25653
|
+
const activePaneOpacity = Number.isFinite(options.activePaneOpacity) ? clampNumber(Number(options.activePaneOpacity), 0, 1) : DEFAULT_RESTTY_PANE_STYLE_OPTIONS.activePaneOpacity;
|
|
25654
|
+
const opacityTransitionMs = Number.isFinite(options.opacityTransitionMs) ? clampNumber(Number(options.opacityTransitionMs), 0, 5000) : DEFAULT_RESTTY_PANE_STYLE_OPTIONS.opacityTransitionMs;
|
|
25655
|
+
const dividerThicknessPx = Number.isFinite(options.dividerThicknessPx) ? clampNumber(Number(options.dividerThicknessPx), 1, 32) : DEFAULT_RESTTY_PANE_STYLE_OPTIONS.dividerThicknessPx;
|
|
25656
|
+
return {
|
|
25657
|
+
splitBackground: normalizeColor(options.splitBackground, DEFAULT_RESTTY_PANE_STYLE_OPTIONS.splitBackground),
|
|
25658
|
+
paneBackground: normalizeColor(options.paneBackground, DEFAULT_RESTTY_PANE_STYLE_OPTIONS.paneBackground),
|
|
25659
|
+
inactivePaneOpacity,
|
|
25660
|
+
activePaneOpacity,
|
|
25661
|
+
opacityTransitionMs,
|
|
25662
|
+
dividerThicknessPx
|
|
25663
|
+
};
|
|
25664
|
+
}
|
|
25665
|
+
function ensureResttyPaneStylesDocument(doc) {
|
|
25666
|
+
if (doc.querySelector(`style[${RESTTY_PANE_STYLE_MARKER}="1"]`))
|
|
25667
|
+
return;
|
|
25668
|
+
const style = doc.createElement("style");
|
|
25669
|
+
style.setAttribute(RESTTY_PANE_STYLE_MARKER, "1");
|
|
25670
|
+
style.textContent = RESTTY_PANE_STYLE_TEXT;
|
|
25671
|
+
doc.head.appendChild(style);
|
|
25672
|
+
}
|
|
25673
|
+
function applyPaneStyleOptionsToRoot(root, options) {
|
|
25674
|
+
root.classList.add(RESTTY_PANE_ROOT_CLASS);
|
|
25675
|
+
root.style.setProperty("--restty-pane-split-background", options.splitBackground);
|
|
25676
|
+
root.style.setProperty("--restty-pane-background", options.paneBackground);
|
|
25677
|
+
root.style.setProperty("--restty-pane-inactive-opacity", options.inactivePaneOpacity.toFixed(3));
|
|
25678
|
+
root.style.setProperty("--restty-pane-active-opacity", options.activePaneOpacity.toFixed(3));
|
|
25679
|
+
root.style.setProperty("--restty-pane-opacity-transition", `${options.opacityTransitionMs}ms`);
|
|
25680
|
+
root.style.setProperty("--restty-pane-divider-thickness", `${options.dividerThicknessPx}px`);
|
|
25681
|
+
}
|
|
25682
|
+
function clearPaneStyleOptionsFromRoot(root) {
|
|
25683
|
+
root.classList.remove(RESTTY_PANE_ROOT_CLASS);
|
|
25684
|
+
root.style.removeProperty("--restty-pane-split-background");
|
|
25685
|
+
root.style.removeProperty("--restty-pane-background");
|
|
25686
|
+
root.style.removeProperty("--restty-pane-inactive-opacity");
|
|
25687
|
+
root.style.removeProperty("--restty-pane-active-opacity");
|
|
25688
|
+
root.style.removeProperty("--restty-pane-opacity-transition");
|
|
25689
|
+
root.style.removeProperty("--restty-pane-divider-thickness");
|
|
25690
|
+
}
|
|
25467
25691
|
function getResttyShortcutModifierLabel() {
|
|
25468
25692
|
const isMac = typeof navigator !== "undefined" && /mac/i.test(navigator.platform);
|
|
25469
25693
|
return isMac ? "Cmd" : "Ctrl";
|
|
@@ -25550,6 +25774,17 @@ function createResttyPaneManager(options) {
|
|
|
25550
25774
|
const paneCleanupFns = new Map;
|
|
25551
25775
|
const minPaneSize = Number.isFinite(options.minPaneSize) ? Math.max(24, Number(options.minPaneSize)) : 96;
|
|
25552
25776
|
const shortcutOptions = typeof options.shortcuts === "object" ? options.shortcuts : { enabled: options.shortcuts !== false };
|
|
25777
|
+
const stylesInput = typeof options.styles === "object" && options.styles ? options.styles : undefined;
|
|
25778
|
+
const stylesEnabled = options.styles === false ? false : stylesInput?.enabled ?? true;
|
|
25779
|
+
let styleOptions = normalizePaneStyleOptions({
|
|
25780
|
+
...DEFAULT_RESTTY_PANE_STYLE_OPTIONS,
|
|
25781
|
+
...stylesInput
|
|
25782
|
+
});
|
|
25783
|
+
if (stylesEnabled) {
|
|
25784
|
+
const doc = root.ownerDocument ?? document;
|
|
25785
|
+
ensureResttyPaneStylesDocument(doc);
|
|
25786
|
+
applyPaneStyleOptionsToRoot(root, styleOptions);
|
|
25787
|
+
}
|
|
25553
25788
|
let nextPaneId = 1;
|
|
25554
25789
|
let activePaneId = null;
|
|
25555
25790
|
let focusedPaneId = null;
|
|
@@ -25569,6 +25804,18 @@ function createResttyPaneManager(options) {
|
|
|
25569
25804
|
options.onLayoutChanged?.();
|
|
25570
25805
|
});
|
|
25571
25806
|
};
|
|
25807
|
+
const getStyleOptions = () => ({
|
|
25808
|
+
...styleOptions
|
|
25809
|
+
});
|
|
25810
|
+
const setStyleOptions = (next) => {
|
|
25811
|
+
styleOptions = normalizePaneStyleOptions({
|
|
25812
|
+
...styleOptions,
|
|
25813
|
+
...next
|
|
25814
|
+
});
|
|
25815
|
+
if (!stylesEnabled)
|
|
25816
|
+
return;
|
|
25817
|
+
applyPaneStyleOptionsToRoot(root, styleOptions);
|
|
25818
|
+
};
|
|
25572
25819
|
const getPanes = () => Array.from(panes.values());
|
|
25573
25820
|
const getPaneById = (id) => {
|
|
25574
25821
|
return panes.get(id) ?? null;
|
|
@@ -26004,6 +26251,9 @@ function createResttyPaneManager(options) {
|
|
|
26004
26251
|
root.replaceChildren();
|
|
26005
26252
|
hideContextMenu();
|
|
26006
26253
|
contextMenuEl?.remove();
|
|
26254
|
+
if (stylesEnabled) {
|
|
26255
|
+
clearPaneStyleOptionsFromRoot(root);
|
|
26256
|
+
}
|
|
26007
26257
|
};
|
|
26008
26258
|
const api = {
|
|
26009
26259
|
getPanes,
|
|
@@ -26016,6 +26266,8 @@ function createResttyPaneManager(options) {
|
|
|
26016
26266
|
splitPane,
|
|
26017
26267
|
splitActivePane,
|
|
26018
26268
|
closePane,
|
|
26269
|
+
getStyleOptions,
|
|
26270
|
+
setStyleOptions,
|
|
26019
26271
|
requestLayoutSync,
|
|
26020
26272
|
hideContextMenu,
|
|
26021
26273
|
destroy
|
|
@@ -55127,6 +55379,7 @@ function createResttyAppPaneManager(options) {
|
|
|
55127
55379
|
const manager2 = createResttyPaneManager({
|
|
55128
55380
|
root: options.root,
|
|
55129
55381
|
minPaneSize: options.minPaneSize,
|
|
55382
|
+
styles: options.paneStyles,
|
|
55130
55383
|
shortcuts,
|
|
55131
55384
|
contextMenu,
|
|
55132
55385
|
createPane: ({ id, sourcePane }) => {
|
|
@@ -55228,6 +55481,12 @@ class Restty {
|
|
|
55228
55481
|
closePane(id) {
|
|
55229
55482
|
return this.paneManager.closePane(id);
|
|
55230
55483
|
}
|
|
55484
|
+
getPaneStyleOptions() {
|
|
55485
|
+
return this.paneManager.getStyleOptions();
|
|
55486
|
+
}
|
|
55487
|
+
setPaneStyleOptions(options) {
|
|
55488
|
+
this.paneManager.setStyleOptions(options);
|
|
55489
|
+
}
|
|
55231
55490
|
setActivePane(id, options) {
|
|
55232
55491
|
this.paneManager.setActivePane(id, options);
|
|
55233
55492
|
}
|
|
@@ -2,6 +2,6 @@ export declare const RECT_SHADER = "\nstruct Uniforms {\n res: vec2f,\n _pad:
|
|
|
2
2
|
export declare const RECT_SHADER_GL_VERT = "#version 300 es\nprecision highp float;\n\nuniform vec2 u_resolution;\n\nlayout(location = 0) in vec2 a_quad;\nlayout(location = 1) in vec2 a_pos;\nlayout(location = 2) in vec2 a_size;\nlayout(location = 3) in vec4 a_color;\n\nout vec4 v_color;\n\nvoid main() {\n vec2 pixel = a_pos + a_quad * a_size;\n vec2 clip = vec2(\n (pixel.x / u_resolution.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / u_resolution.y) * 2.0\n );\n gl_Position = vec4(clip, 0.0, 1.0);\n v_color = a_color;\n}\n";
|
|
3
3
|
export declare const RECT_SHADER_GL_FRAG = "#version 300 es\nprecision highp float;\n\nuniform vec2 u_blend;\n\nin vec4 v_color;\nout vec4 fragColor;\n\n// sRGB to linear conversion for proper blending\nfloat srgbToLinear(float c) {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\nvec3 srgbToLinear(vec3 c) {\n return vec3(srgbToLinear(c.r), srgbToLinear(c.g), srgbToLinear(c.b));\n}\n\nvoid main() {\n bool useLinear = u_blend.x > 0.5;\n vec4 color = v_color;\n if (useLinear) {\n color.rgb = srgbToLinear(color.rgb);\n }\n color.rgb *= color.a;\n fragColor = color;\n}\n";
|
|
4
4
|
export declare const GLYPH_SHADER_GL_VERT = "#version 300 es\nprecision highp float;\n\nuniform vec2 u_resolution;\n\nlayout(location = 0) in vec2 a_quad;\nlayout(location = 1) in vec2 a_pos;\nlayout(location = 2) in vec2 a_size;\nlayout(location = 3) in vec2 a_uv0;\nlayout(location = 4) in vec2 a_uv1;\nlayout(location = 5) in vec4 a_color;\nlayout(location = 6) in vec4 a_bg;\nlayout(location = 7) in float a_slant;\nlayout(location = 8) in float a_mode;\n\nout vec2 v_uv;\nout vec4 v_color;\nout vec4 v_bg;\nout float v_mode;\n\nvoid main() {\n vec2 pixel = a_pos + vec2(a_quad.x * a_size.x + a_slant * (1.0 - a_quad.y), a_quad.y * a_size.y);\n vec2 clip = vec2(\n (pixel.x / u_resolution.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / u_resolution.y) * 2.0\n );\n v_uv = a_uv0 + (a_uv1 - a_uv0) * a_quad;\n gl_Position = vec4(clip, 0.0, 1.0);\n v_color = a_color;\n v_bg = a_bg;\n v_mode = a_mode;\n}\n";
|
|
5
|
-
export declare const GLYPH_SHADER_GL_FRAG = "#version 300 es\nprecision highp float;\n\nuniform sampler2D u_atlas;\nuniform vec2 u_blend;\n\nin vec2 v_uv;\nin vec4 v_color;\nin vec4 v_bg;\nin float v_mode;\nout vec4 fragColor;\n\n// sRGB to linear conversion for proper blending\nfloat srgbToLinear(float c) {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\n// Linear to sRGB conversion\nfloat linearToSrgb(float c) {\n if (c <= 0.0031308) {\n return c * 12.92;\n }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\n\nvec3 srgbToLinear(vec3 c) {\n return vec3(srgbToLinear(c.r), srgbToLinear(c.g), srgbToLinear(c.b));\n}\n\nvec3 linearToSrgb(vec3 c) {\n return vec3(linearToSrgb(c.r), linearToSrgb(c.g), linearToSrgb(c.b));\n}\n\nfloat luminance(vec3 color) {\n return dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\n\nvoid main() {\n vec4
|
|
5
|
+
export declare const GLYPH_SHADER_GL_FRAG = "#version 300 es\nprecision highp float;\n\nuniform sampler2D u_atlas;\nuniform vec2 u_blend;\n\nin vec2 v_uv;\nin vec4 v_color;\nin vec4 v_bg;\nin float v_mode;\nout vec4 fragColor;\n\n// sRGB to linear conversion for proper blending\nfloat srgbToLinear(float c) {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\n// Linear to sRGB conversion\nfloat linearToSrgb(float c) {\n if (c <= 0.0031308) {\n return c * 12.92;\n }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\n\nvec3 srgbToLinear(vec3 c) {\n return vec3(srgbToLinear(c.r), srgbToLinear(c.g), srgbToLinear(c.b));\n}\n\nvec3 linearToSrgb(vec3 c) {\n return vec3(linearToSrgb(c.r), linearToSrgb(c.g), linearToSrgb(c.b));\n}\n\nfloat luminance(vec3 color) {\n return dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\n\nvoid main() {\n vec4 atlasSample = texture(u_atlas, v_uv);\n bool useLinear = u_blend.x > 0.5;\n bool useCorrection = u_blend.y > 0.5;\n\n if (v_mode > 0.5) {\n vec4 color = atlasSample;\n if (useLinear) {\n color.rgb = srgbToLinear(color.rgb);\n }\n color.rgb *= color.a;\n fragColor = color;\n return;\n }\n\n vec4 fg = v_color;\n vec4 bg = v_bg;\n if (useLinear) {\n fg.rgb = srgbToLinear(fg.rgb);\n bg.rgb = srgbToLinear(bg.rgb);\n }\n fg.rgb *= fg.a;\n bg.rgb *= bg.a;\n\n float alpha = atlasSample.a;\n if (useCorrection && useLinear) {\n float fg_l = luminance(fg.rgb);\n float bg_l = luminance(bg.rgb);\n if (abs(fg_l - bg_l) > 0.001) {\n float blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));\n alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);\n }\n }\n\n vec4 color = fg * alpha;\n fragColor = color;\n}\n";
|
|
6
6
|
export declare const GLYPH_SHADER = "\nstruct Uniforms {\n res: vec2f,\n _pad: vec2f,\n blend: vec2f,\n _pad2: vec2f,\n};\n\n@group(0) @binding(0) var<uniform> uniforms: Uniforms;\n@group(0) @binding(1) var atlasSampler: sampler;\n@group(0) @binding(2) var atlasTex: texture_2d<f32>;\n\nstruct VSIn {\n @location(0) quad: vec2f,\n @location(1) pos: vec2f,\n @location(2) size: vec2f,\n @location(3) uv0: vec2f,\n @location(4) uv1: vec2f,\n @location(5) color: vec4f,\n @location(6) bg: vec4f,\n @location(7) slant: f32,\n @location(8) mode: f32,\n};\n\nstruct VSOut {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n @location(1) color: vec4f,\n @location(2) bg: vec4f,\n @location(3) mode: f32,\n};\n\n@vertex\nfn vsMain(input: VSIn) -> VSOut {\n let pixel = input.pos +\n vec2f(input.quad.x * input.size.x + input.slant * (1.0 - input.quad.y), input.quad.y * input.size.y);\n let clip = vec2f(\n (pixel.x / uniforms.res.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / uniforms.res.y) * 2.0\n );\n let uv = input.uv0 + (input.uv1 - input.uv0) * input.quad;\n\n var out: VSOut;\n out.position = vec4f(clip.x, clip.y, 0.0, 1.0);\n out.uv = uv;\n out.color = input.color;\n out.bg = input.bg;\n out.mode = input.mode;\n return out;\n}\n\n// sRGB to linear conversion for proper blending\nfn srgbToLinear(c: f32) -> f32 {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(c: f32) -> f32 {\n if (c <= 0.0031308) {\n return c * 12.92;\n }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\n\nfn srgbToLinear3(c: vec3f) -> vec3f {\n return vec3f(srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z));\n}\n\nfn linearToSrgb3(c: vec3f) -> vec3f {\n return vec3f(linearToSrgb(c.x), linearToSrgb(c.y), linearToSrgb(c.z));\n}\n\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n@fragment\nfn fsMain(input: VSOut) -> @location(0) vec4f {\n let sample = textureSample(atlasTex, atlasSampler, input.uv);\n let useLinear = uniforms.blend.x > 0.5;\n let useCorrection = uniforms.blend.y > 0.5;\n\n if (input.mode > 0.5) {\n var color = sample;\n if (useLinear) {\n color = vec4f(srgbToLinear3(color.rgb), color.a);\n }\n return vec4f(color.rgb * color.a, color.a);\n }\n\n var alpha = sample.a;\n\n var fg = input.color;\n var bg = input.bg;\n if (useLinear) {\n fg = vec4f(srgbToLinear3(fg.rgb), fg.a);\n bg = vec4f(srgbToLinear3(bg.rgb), bg.a);\n }\n fg = vec4f(fg.rgb * fg.a, fg.a);\n bg = vec4f(bg.rgb * bg.a, bg.a);\n\n if (useCorrection && useLinear) {\n let fg_l = luminance(fg.rgb);\n let bg_l = luminance(bg.rgb);\n if (abs(fg_l - bg_l) > 0.001) {\n let blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));\n alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);\n }\n }\n\n var color = fg * alpha;\n return color;\n}\n";
|
|
7
7
|
export declare const GLYPH_SHADER_NEAREST = "\nstruct Uniforms {\n res: vec2f,\n _pad: vec2f,\n blend: vec2f,\n _pad2: vec2f,\n};\n\n@group(0) @binding(0) var<uniform> uniforms: Uniforms;\n@group(0) @binding(1) var atlasSampler: sampler;\n@group(0) @binding(2) var atlasTex: texture_2d<f32>;\n\nstruct VSIn {\n @location(0) quad: vec2f,\n @location(1) pos: vec2f,\n @location(2) size: vec2f,\n @location(3) uv0: vec2f,\n @location(4) uv1: vec2f,\n @location(5) color: vec4f,\n @location(6) bg: vec4f,\n @location(7) slant: f32,\n @location(8) mode: f32,\n};\n\nstruct VSOut {\n @builtin(position) position: vec4f,\n @location(0) uv: vec2f,\n @location(1) color: vec4f,\n @location(2) bg: vec4f,\n @location(3) mode: f32,\n};\n\n@vertex\nfn vsMain(input: VSIn) -> VSOut {\n let pixel = input.pos +\n vec2f(input.quad.x * input.size.x + input.slant * (1.0 - input.quad.y), input.quad.y * input.size.y);\n let clip = vec2f(\n (pixel.x / uniforms.res.x) * 2.0 - 1.0,\n 1.0 - (pixel.y / uniforms.res.y) * 2.0\n );\n let uv = input.uv0 + (input.uv1 - input.uv0) * input.quad;\n\n var out: VSOut;\n out.position = vec4f(clip.x, clip.y, 0.0, 1.0);\n out.uv = uv;\n out.color = input.color;\n out.bg = input.bg;\n out.mode = input.mode;\n return out;\n}\n\n// sRGB to linear conversion for proper blending\nfn srgbToLinear(c: f32) -> f32 {\n if (c <= 0.04045) {\n return c / 12.92;\n }\n return pow((c + 0.055) / 1.055, 2.4);\n}\n\n// Linear to sRGB conversion\nfn linearToSrgb(c: f32) -> f32 {\n if (c <= 0.0031308) {\n return c * 12.92;\n }\n return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n}\n\nfn srgbToLinear3(c: vec3f) -> vec3f {\n return vec3f(srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z));\n}\n\nfn linearToSrgb3(c: vec3f) -> vec3f {\n return vec3f(linearToSrgb(c.x), linearToSrgb(c.y), linearToSrgb(c.z));\n}\n\nfn luminance(color: vec3f) -> f32 {\n return dot(color, vec3f(0.2126, 0.7152, 0.0722));\n}\n\n@fragment\nfn fsMain(input: VSOut) -> @location(0) vec4f {\n let sample = textureSample(atlasTex, atlasSampler, input.uv);\n let useLinear = uniforms.blend.x > 0.5;\n let useCorrection = uniforms.blend.y > 0.5;\n\n if (input.mode > 0.5) {\n var color = sample;\n if (useLinear) {\n color = vec4f(srgbToLinear3(color.rgb), color.a);\n }\n return vec4f(color.rgb * color.a, color.a);\n }\n\n var alpha = sample.a;\n\n var fg = input.color;\n var bg = input.bg;\n if (useLinear) {\n fg = vec4f(srgbToLinear3(fg.rgb), fg.a);\n bg = vec4f(srgbToLinear3(bg.rgb), bg.a);\n }\n fg = vec4f(fg.rgb * fg.a, fg.a);\n bg = vec4f(bg.rgb * bg.a, bg.a);\n\n if (useCorrection && useLinear) {\n let fg_l = luminance(fg.rgb);\n let bg_l = luminance(bg.rgb);\n if (abs(fg_l - bg_l) > 0.001) {\n let blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));\n alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);\n }\n }\n\n var color = fg * alpha;\n return color;\n}\n";
|