@gtkx/react 0.14.0 → 0.16.0
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 +28 -27
- package/dist/errors.js +3 -0
- package/dist/factory.d.ts +3 -2
- package/dist/factory.js +1 -1
- package/dist/generated/internal.d.ts +28 -1
- package/dist/generated/internal.js +93 -18
- package/dist/generated/jsx.d.ts +1712 -1516
- package/dist/generated/jsx.js +475 -0
- package/dist/host-config.d.ts +3 -1
- package/dist/host-config.js +31 -11
- package/dist/jsx.d.ts +147 -97
- package/dist/jsx.js +89 -21
- package/dist/node.d.ts +3 -1
- package/dist/node.js +5 -3
- package/dist/nodes/abstract/positional-child.d.ts +9 -0
- package/dist/nodes/abstract/positional-child.js +29 -0
- package/dist/nodes/abstract/positional-parent.d.ts +18 -0
- package/dist/nodes/abstract/positional-parent.js +48 -0
- package/dist/nodes/abstract/virtual-container.d.ts +17 -0
- package/dist/nodes/abstract/virtual-container.js +59 -0
- package/dist/nodes/abstract/virtual-single-child.d.ts +18 -0
- package/dist/nodes/abstract/virtual-single-child.js +54 -0
- package/dist/nodes/action-row-child.d.ts +0 -13
- package/dist/nodes/action-row-child.js +14 -12
- package/dist/nodes/action-row.d.ts +6 -1
- package/dist/nodes/action-row.js +4 -37
- package/dist/nodes/adjustable.d.ts +23 -0
- package/dist/nodes/adjustable.js +62 -0
- package/dist/nodes/alert-dialog-response.d.ts +1 -0
- package/dist/nodes/alert-dialog-response.js +86 -0
- package/dist/nodes/animation/animation-controller.d.ts +17 -0
- package/dist/nodes/animation/animation-controller.js +107 -0
- package/dist/nodes/animation/animation-factory.d.ts +15 -0
- package/dist/nodes/animation/animation-factory.js +25 -0
- package/dist/nodes/animation/animation-node.d.ts +9 -0
- package/dist/nodes/animation/animation-node.js +126 -0
- package/dist/nodes/animation/animation-style-sheet.d.ts +16 -0
- package/dist/nodes/animation/animation-style-sheet.js +74 -0
- package/dist/nodes/animation/index.d.ts +4 -0
- package/dist/nodes/animation/index.js +1 -0
- package/dist/nodes/animation/property-mapper.d.ts +11 -0
- package/dist/nodes/animation/property-mapper.js +36 -0
- package/dist/nodes/animation/transform-state.d.ts +11 -0
- package/dist/nodes/animation/transform-state.js +57 -0
- package/dist/nodes/animation/widget-registry.d.ts +5 -0
- package/dist/nodes/animation/widget-registry.js +42 -0
- package/dist/nodes/application.js +17 -7
- package/dist/nodes/autowrapped.js +37 -43
- package/dist/nodes/calendar.js +16 -55
- package/dist/nodes/color-dialog-button.d.ts +1 -0
- package/dist/nodes/color-dialog-button.js +70 -0
- package/dist/nodes/column-view-column.d.ts +4 -3
- package/dist/nodes/column-view-column.js +5 -1
- package/dist/nodes/column-view.js +40 -43
- package/dist/nodes/dialog.d.ts +11 -0
- package/dist/nodes/dialog.js +20 -0
- package/dist/nodes/drawing-area.d.ts +1 -0
- package/dist/nodes/drawing-area.js +36 -0
- package/dist/nodes/event-controller.d.ts +1 -0
- package/dist/nodes/event-controller.js +96 -0
- package/dist/nodes/expander-row-child.d.ts +0 -14
- package/dist/nodes/expander-row-child.js +14 -12
- package/dist/nodes/expander-row.d.ts +6 -1
- package/dist/nodes/expander-row.js +11 -47
- package/dist/nodes/fixed-child.js +48 -36
- package/dist/nodes/font-dialog-button.d.ts +1 -0
- package/dist/nodes/font-dialog-button.js +90 -0
- package/dist/nodes/grid-child.js +39 -45
- package/dist/nodes/grid.d.ts +1 -0
- package/dist/nodes/grid.js +41 -0
- package/dist/nodes/index.d.ts +22 -6
- package/dist/nodes/index.js +22 -6
- package/dist/nodes/internal/base-item-renderer.d.ts +29 -0
- package/dist/nodes/internal/base-item-renderer.js +88 -0
- package/dist/nodes/internal/base-store.d.ts +9 -0
- package/dist/nodes/internal/base-store.js +20 -0
- package/dist/nodes/internal/child-attachment.d.ts +26 -0
- package/dist/nodes/internal/child-attachment.js +48 -0
- package/dist/nodes/internal/deferred-action.d.ts +8 -0
- package/dist/nodes/internal/deferred-action.js +19 -0
- package/dist/nodes/internal/list-item-renderer.d.ts +14 -14
- package/dist/nodes/internal/list-item-renderer.js +49 -70
- package/dist/nodes/internal/list-store.d.ts +7 -6
- package/dist/nodes/internal/list-store.js +20 -24
- package/dist/nodes/internal/predicates.d.ts +28 -1
- package/dist/nodes/internal/predicates.js +53 -38
- package/dist/nodes/internal/selection-model.d.ts +30 -0
- package/dist/nodes/internal/selection-model.js +91 -0
- package/dist/nodes/internal/signal-store.d.ts +5 -3
- package/dist/nodes/internal/signal-store.js +30 -21
- package/dist/nodes/internal/simple-list-store.js +6 -9
- package/dist/nodes/internal/text-buffer-controller.d.ts +43 -0
- package/dist/nodes/internal/text-buffer-controller.js +287 -0
- package/dist/nodes/internal/text-tag-styles.d.ts +43 -0
- package/dist/nodes/internal/text-tag-styles.js +52 -0
- package/dist/nodes/internal/tree-list-item-renderer.d.ts +16 -14
- package/dist/nodes/internal/tree-list-item-renderer.js +88 -91
- package/dist/nodes/internal/tree-store.d.ts +10 -9
- package/dist/nodes/internal/tree-store.js +31 -35
- package/dist/nodes/internal/utils.d.ts +7 -4
- package/dist/nodes/internal/utils.js +50 -5
- package/dist/nodes/level-bar.js +18 -66
- package/dist/nodes/list-item.d.ts +6 -3
- package/dist/nodes/list-item.js +7 -4
- package/dist/nodes/list-view.js +19 -11
- package/dist/nodes/menu.d.ts +3 -3
- package/dist/nodes/menu.js +3 -3
- package/dist/nodes/models/list.d.ts +11 -13
- package/dist/nodes/models/list.js +16 -73
- package/dist/nodes/models/menu.d.ts +8 -7
- package/dist/nodes/models/menu.js +43 -50
- package/dist/nodes/models/tree-list.d.ts +6 -12
- package/dist/nodes/models/tree-list.js +30 -93
- package/dist/nodes/navigation-page.d.ts +1 -0
- package/dist/nodes/navigation-page.js +7 -3
- package/dist/nodes/navigation-view.js +17 -28
- package/dist/nodes/notebook-page-tab.d.ts +4 -3
- package/dist/nodes/notebook-page-tab.js +5 -2
- package/dist/nodes/notebook-page.d.ts +7 -5
- package/dist/nodes/notebook-page.js +39 -16
- package/dist/nodes/notebook.js +2 -2
- package/dist/nodes/overlay-child.js +90 -30
- package/dist/nodes/pack-child.d.ts +0 -13
- package/dist/nodes/pack-child.js +14 -12
- package/dist/nodes/pack.d.ts +6 -1
- package/dist/nodes/pack.js +4 -37
- package/dist/nodes/popover-menu.js +2 -2
- package/dist/nodes/scale.js +15 -58
- package/dist/nodes/scrolled-window.js +7 -5
- package/dist/nodes/search-bar.d.ts +1 -0
- package/dist/nodes/search-bar.js +40 -0
- package/dist/nodes/shortcut-controller.d.ts +1 -0
- package/dist/nodes/shortcut-controller.js +90 -0
- package/dist/nodes/shortcut.d.ts +39 -0
- package/dist/nodes/shortcut.js +52 -0
- package/dist/nodes/simple-list-view.js +2 -3
- package/dist/nodes/slot.d.ts +6 -9
- package/dist/nodes/slot.js +27 -42
- package/dist/nodes/source-view.d.ts +1 -0
- package/dist/nodes/source-view.js +93 -0
- package/dist/nodes/stack-page.js +17 -13
- package/dist/nodes/stack.js +19 -5
- package/dist/nodes/text-anchor.d.ts +41 -0
- package/dist/nodes/text-anchor.js +59 -0
- package/dist/nodes/text-content.d.ts +10 -0
- package/dist/nodes/text-content.js +1 -0
- package/dist/nodes/text-paintable.d.ts +17 -0
- package/dist/nodes/text-paintable.js +34 -0
- package/dist/nodes/text-segment.d.ts +15 -0
- package/dist/nodes/text-segment.js +29 -0
- package/dist/nodes/text-tag.d.ts +136 -0
- package/dist/nodes/text-tag.js +202 -0
- package/dist/nodes/text-view.d.ts +31 -0
- package/dist/nodes/text-view.js +73 -0
- package/dist/nodes/toggle-group.js +24 -32
- package/dist/nodes/toggle.d.ts +1 -15
- package/dist/nodes/toggle.js +40 -32
- package/dist/nodes/toolbar-child.js +14 -16
- package/dist/nodes/tree-list-item.d.ts +7 -5
- package/dist/nodes/tree-list-item.js +24 -36
- package/dist/nodes/tree-list-view.js +9 -4
- package/dist/nodes/virtual.d.ts +1 -1
- package/dist/nodes/widget.d.ts +3 -13
- package/dist/nodes/widget.js +117 -231
- package/dist/nodes/window.d.ts +9 -3
- package/dist/nodes/window.js +35 -19
- package/dist/registry.d.ts +1 -1
- package/dist/render.js +8 -6
- package/dist/scheduler.d.ts +11 -1
- package/dist/scheduler.js +16 -4
- package/dist/types.d.ts +2 -110
- package/package.json +3 -3
- package/dist/nodes/calendar-mark.d.ts +0 -15
- package/dist/nodes/calendar-mark.js +0 -29
- package/dist/nodes/internal/constants.d.ts +0 -1
- package/dist/nodes/internal/constants.js +0 -21
- package/dist/nodes/level-bar-offset.d.ts +0 -13
- package/dist/nodes/level-bar-offset.js +0 -35
- package/dist/nodes/scale-mark.d.ts +0 -17
- package/dist/nodes/scale-mark.js +0 -38
- package/dist/nodes/virtual-child.d.ts +0 -18
- package/dist/nodes/virtual-child.js +0 -62
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import type { Props } from "../types.js";
|
|
3
|
+
import { VirtualNode } from "./virtual.js";
|
|
4
|
+
/**
|
|
5
|
+
* Props for the Shortcut virtual element.
|
|
6
|
+
*
|
|
7
|
+
* Defines a keyboard shortcut. Must be a child of `x.ShortcutController`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <x.ShortcutController>
|
|
12
|
+
* <x.Shortcut trigger="<Control>s" onActivate={save} />
|
|
13
|
+
* <x.Shortcut trigger={["F5", "<Control>r"]} onActivate={refresh} />
|
|
14
|
+
* <x.Shortcut trigger="Escape" onActivate={cancel} disabled={!canCancel} />
|
|
15
|
+
* </x.ShortcutController>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export type ShortcutProps = Props & {
|
|
19
|
+
/** The trigger string(s) using GTK accelerator format (e.g., "\<Control\>s", "F1") */
|
|
20
|
+
trigger: string | string[];
|
|
21
|
+
/**
|
|
22
|
+
* Called when the shortcut is activated.
|
|
23
|
+
* Return false to indicate the shortcut was not handled; otherwise it is considered handled.
|
|
24
|
+
*/
|
|
25
|
+
onActivate: () => boolean | void;
|
|
26
|
+
/** Whether the shortcut is disabled */
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
};
|
|
29
|
+
export declare class ShortcutNode extends VirtualNode<ShortcutProps> {
|
|
30
|
+
static priority: number;
|
|
31
|
+
static matches(type: string): boolean;
|
|
32
|
+
shortcut: Gtk.Shortcut | null;
|
|
33
|
+
private action;
|
|
34
|
+
createShortcut(): void;
|
|
35
|
+
updateProps(oldProps: ShortcutProps | null, newProps: ShortcutProps): void;
|
|
36
|
+
protected applyOwnProps(oldProps: ShortcutProps | null, newProps: ShortcutProps): void;
|
|
37
|
+
unmount(): void;
|
|
38
|
+
private createTrigger;
|
|
39
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import { registerNodeClass } from "../registry.js";
|
|
3
|
+
import { hasChanged } from "./internal/utils.js";
|
|
4
|
+
import { VirtualNode } from "./virtual.js";
|
|
5
|
+
export class ShortcutNode extends VirtualNode {
|
|
6
|
+
static priority = 1;
|
|
7
|
+
static matches(type) {
|
|
8
|
+
return type === "Shortcut";
|
|
9
|
+
}
|
|
10
|
+
shortcut = null;
|
|
11
|
+
action = null;
|
|
12
|
+
createShortcut() {
|
|
13
|
+
const trigger = this.createTrigger();
|
|
14
|
+
this.action = new Gtk.CallbackAction(() => {
|
|
15
|
+
const result = this.props.onActivate();
|
|
16
|
+
return result !== false;
|
|
17
|
+
});
|
|
18
|
+
this.shortcut = new Gtk.Shortcut(trigger, this.action);
|
|
19
|
+
}
|
|
20
|
+
updateProps(oldProps, newProps) {
|
|
21
|
+
super.updateProps(oldProps, newProps);
|
|
22
|
+
this.applyOwnProps(oldProps, newProps);
|
|
23
|
+
}
|
|
24
|
+
applyOwnProps(oldProps, newProps) {
|
|
25
|
+
if (!this.shortcut)
|
|
26
|
+
return;
|
|
27
|
+
if (hasChanged(oldProps, newProps, "trigger") || hasChanged(oldProps, newProps, "disabled")) {
|
|
28
|
+
this.shortcut.setTrigger(this.createTrigger());
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
unmount() {
|
|
32
|
+
this.shortcut = null;
|
|
33
|
+
this.action = null;
|
|
34
|
+
super.unmount();
|
|
35
|
+
}
|
|
36
|
+
createTrigger() {
|
|
37
|
+
if (this.props.disabled) {
|
|
38
|
+
return Gtk.NeverTrigger.get();
|
|
39
|
+
}
|
|
40
|
+
const { trigger } = this.props;
|
|
41
|
+
const triggers = Array.isArray(trigger) ? trigger : [trigger];
|
|
42
|
+
if (triggers.length === 0) {
|
|
43
|
+
return Gtk.NeverTrigger.get();
|
|
44
|
+
}
|
|
45
|
+
let result = new Gtk.ShortcutTrigger(triggers[0]);
|
|
46
|
+
for (let i = 1; i < triggers.length; i++) {
|
|
47
|
+
result = new Gtk.AlternativeTrigger(result, new Gtk.ShortcutTrigger(triggers[i]));
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
registerNodeClass(ShortcutNode);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { DROP_DOWN_CLASSES } from "../generated/internal.js";
|
|
2
2
|
import { registerNodeClass } from "../registry.js";
|
|
3
|
-
import { signalStore } from "./internal/signal-store.js";
|
|
4
3
|
import { SimpleListStore } from "./internal/simple-list-store.js";
|
|
5
4
|
import { filterProps, matchesAnyClass } from "./internal/utils.js";
|
|
6
5
|
import { SimpleListItemNode } from "./simple-list-item.js";
|
|
@@ -28,7 +27,7 @@ class SimpleListViewNode extends WidgetNode {
|
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
: undefined;
|
|
31
|
-
signalStore.set(this, this.container, "notify::selected", handleSelectionChange);
|
|
30
|
+
this.signalStore.set(this, this.container, "notify::selected", handleSelectionChange);
|
|
32
31
|
}
|
|
33
32
|
if (!oldProps || oldProps.selectedId !== newProps.selectedId) {
|
|
34
33
|
const index = newProps.selectedId !== undefined ? this.store.getIndexById(newProps.selectedId) : null;
|
|
@@ -36,7 +35,7 @@ class SimpleListViewNode extends WidgetNode {
|
|
|
36
35
|
this.container.setSelected(index);
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
|
-
super.updateProps(filterProps(oldProps
|
|
38
|
+
super.updateProps(oldProps ? filterProps(oldProps, PROP_NAMES) : null, filterProps(newProps, PROP_NAMES));
|
|
40
39
|
}
|
|
41
40
|
appendChild(child) {
|
|
42
41
|
if (!(child instanceof SimpleListItemNode)) {
|
package/dist/nodes/slot.d.ts
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import type * as Gtk from "@gtkx/ffi/gtk";
|
|
2
2
|
import type { SlotProps } from "../jsx.js";
|
|
3
|
-
import type { Node } from "../node.js";
|
|
4
3
|
import type { Props } from "../types.js";
|
|
5
|
-
import {
|
|
4
|
+
import { VirtualSingleChildNode } from "./abstract/virtual-single-child.js";
|
|
6
5
|
type SlotNodeProps = Omit<SlotProps, "children">;
|
|
7
|
-
export declare class SlotNode<P extends Props = SlotNodeProps> extends
|
|
6
|
+
export declare class SlotNode<P extends Props = SlotNodeProps> extends VirtualSingleChildNode<P> {
|
|
8
7
|
static priority: number;
|
|
9
8
|
static matches(type: string): boolean;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
setParent(parent?: Gtk.Widget): void;
|
|
9
|
+
private cachedSetter;
|
|
10
|
+
setParent(parent: Gtk.Widget | null): void;
|
|
13
11
|
unmount(): void;
|
|
12
|
+
getChild(): Gtk.Widget;
|
|
14
13
|
protected getId(): string;
|
|
15
14
|
protected getParent(): Gtk.Widget;
|
|
16
|
-
|
|
17
|
-
appendChild(child: Node): void;
|
|
18
|
-
removeChild(): void;
|
|
15
|
+
protected ensureChildSetter(): (child: Gtk.Widget | null) => void;
|
|
19
16
|
protected onChildChange(oldChild: Gtk.Widget | null): void;
|
|
20
17
|
private isDescendantOf;
|
|
21
18
|
}
|
package/dist/nodes/slot.js
CHANGED
|
@@ -1,38 +1,44 @@
|
|
|
1
1
|
import { isObjectEqual } from "@gtkx/ffi";
|
|
2
2
|
import { toCamelCase } from "@gtkx/gir";
|
|
3
3
|
import { registerNodeClass } from "../registry.js";
|
|
4
|
-
import {
|
|
4
|
+
import { VirtualSingleChildNode } from "./abstract/virtual-single-child.js";
|
|
5
5
|
import { resolvePropMeta } from "./internal/utils.js";
|
|
6
|
-
|
|
7
|
-
import { WidgetNode } from "./widget.js";
|
|
8
|
-
export class SlotNode extends VirtualNode {
|
|
6
|
+
export class SlotNode extends VirtualSingleChildNode {
|
|
9
7
|
static priority = 2;
|
|
10
8
|
static matches(type) {
|
|
11
9
|
return type === "Slot";
|
|
12
10
|
}
|
|
13
|
-
|
|
14
|
-
child;
|
|
11
|
+
cachedSetter = null;
|
|
15
12
|
setParent(parent) {
|
|
16
|
-
this.parent
|
|
13
|
+
if (this.parent !== parent) {
|
|
14
|
+
this.cachedSetter = null;
|
|
15
|
+
}
|
|
16
|
+
super.setParent(parent);
|
|
17
17
|
}
|
|
18
18
|
unmount() {
|
|
19
19
|
if (this.parent && this.child) {
|
|
20
20
|
const parent = this.parent;
|
|
21
21
|
const oldChild = this.child;
|
|
22
|
-
this.child =
|
|
22
|
+
this.child = null;
|
|
23
23
|
queueMicrotask(() => {
|
|
24
24
|
if (parent.getRoot() !== null) {
|
|
25
25
|
this.parent = parent;
|
|
26
26
|
this.onChildChange(oldChild);
|
|
27
27
|
}
|
|
28
|
-
this.parent =
|
|
28
|
+
this.parent = null;
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
else {
|
|
32
|
-
this.parent =
|
|
32
|
+
this.parent = null;
|
|
33
33
|
}
|
|
34
34
|
super.unmount();
|
|
35
35
|
}
|
|
36
|
+
getChild() {
|
|
37
|
+
if (!this.child) {
|
|
38
|
+
throw new Error(`Expected child widget to be set on '${this.getId()}' SlotNode`);
|
|
39
|
+
}
|
|
40
|
+
return this.child;
|
|
41
|
+
}
|
|
36
42
|
getId() {
|
|
37
43
|
const id = this.props.id;
|
|
38
44
|
if (!id) {
|
|
@@ -46,55 +52,34 @@ export class SlotNode extends VirtualNode {
|
|
|
46
52
|
}
|
|
47
53
|
return this.parent;
|
|
48
54
|
}
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
return this.child;
|
|
54
|
-
}
|
|
55
|
-
appendChild(child) {
|
|
56
|
-
if (!(child instanceof WidgetNode)) {
|
|
57
|
-
throw new Error(`Cannot append '${child.typeName}' to 'Slot': expected Widget`);
|
|
58
|
-
}
|
|
59
|
-
const oldChild = this.child;
|
|
60
|
-
this.child = child.container;
|
|
61
|
-
scheduleAfterCommit(() => {
|
|
62
|
-
if (this.parent) {
|
|
63
|
-
this.onChildChange(oldChild ?? null);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
removeChild() {
|
|
68
|
-
const oldChild = this.child;
|
|
69
|
-
scheduleAfterCommit(() => {
|
|
70
|
-
if (oldChild === this.child) {
|
|
71
|
-
this.child = undefined;
|
|
72
|
-
}
|
|
73
|
-
if (this.parent) {
|
|
74
|
-
this.onChildChange(oldChild ?? null);
|
|
75
|
-
}
|
|
76
|
-
}, CommitPriority.HIGH);
|
|
77
|
-
}
|
|
78
|
-
onChildChange(oldChild) {
|
|
55
|
+
ensureChildSetter() {
|
|
56
|
+
if (this.cachedSetter)
|
|
57
|
+
return this.cachedSetter;
|
|
79
58
|
const parent = this.getParent();
|
|
80
59
|
const parentType = parent.constructor.glibTypeName;
|
|
81
60
|
const propMeta = resolvePropMeta(parent, this.getId());
|
|
82
61
|
if (!propMeta) {
|
|
83
62
|
throw new Error(`Unable to find property for Slot '${this.getId()}' on type '${parentType}'`);
|
|
84
63
|
}
|
|
85
|
-
const [
|
|
64
|
+
const [, setterName] = propMeta;
|
|
86
65
|
const setter = parent[setterName];
|
|
87
66
|
if (typeof setter !== "function") {
|
|
88
67
|
throw new Error(`Expected setter function for Slot '${this.getId()}' on type '${parentType}'`);
|
|
89
68
|
}
|
|
69
|
+
this.cachedSetter = setter.bind(parent);
|
|
70
|
+
return this.cachedSetter;
|
|
71
|
+
}
|
|
72
|
+
onChildChange(oldChild) {
|
|
73
|
+
const setter = this.ensureChildSetter();
|
|
90
74
|
if (oldChild && !this.child) {
|
|
75
|
+
const parent = this.getParent();
|
|
91
76
|
const root = oldChild.getRoot();
|
|
92
77
|
const focusWidget = root?.getFocus?.();
|
|
93
78
|
if (focusWidget && this.isDescendantOf(focusWidget, oldChild)) {
|
|
94
79
|
parent.grabFocus();
|
|
95
80
|
}
|
|
96
81
|
}
|
|
97
|
-
setter
|
|
82
|
+
setter(this.child);
|
|
98
83
|
}
|
|
99
84
|
isDescendantOf(widget, ancestor) {
|
|
100
85
|
let current = widget;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as GtkSource from "@gtkx/ffi/gtksource";
|
|
2
|
+
import { registerNodeClass } from "../registry.js";
|
|
3
|
+
import { TextBufferController } from "./internal/text-buffer-controller.js";
|
|
4
|
+
import { hasChanged, matchesAnyClass } from "./internal/utils.js";
|
|
5
|
+
import { TextViewNode } from "./text-view.js";
|
|
6
|
+
class SourceViewNode extends TextViewNode {
|
|
7
|
+
static priority = 1;
|
|
8
|
+
static matches(_type, containerOrClass) {
|
|
9
|
+
return matchesAnyClass([GtkSource.View], containerOrClass);
|
|
10
|
+
}
|
|
11
|
+
createBufferController() {
|
|
12
|
+
return new TextBufferController(this, this.container, () => new GtkSource.Buffer());
|
|
13
|
+
}
|
|
14
|
+
ensureBufferController() {
|
|
15
|
+
return super.ensureBufferController();
|
|
16
|
+
}
|
|
17
|
+
applyOwnProps(oldProps, newProps) {
|
|
18
|
+
super.applyOwnProps(oldProps, newProps);
|
|
19
|
+
this.applySourceViewProps(oldProps, newProps);
|
|
20
|
+
}
|
|
21
|
+
resolveLanguage(language) {
|
|
22
|
+
if (typeof language === "string") {
|
|
23
|
+
const langManager = GtkSource.LanguageManager.getDefault();
|
|
24
|
+
return langManager.getLanguage(language);
|
|
25
|
+
}
|
|
26
|
+
return language;
|
|
27
|
+
}
|
|
28
|
+
resolveStyleScheme(scheme) {
|
|
29
|
+
if (typeof scheme === "string") {
|
|
30
|
+
const schemeManager = GtkSource.StyleSchemeManager.getDefault();
|
|
31
|
+
return schemeManager.getScheme(scheme);
|
|
32
|
+
}
|
|
33
|
+
return scheme;
|
|
34
|
+
}
|
|
35
|
+
applySourceViewProps(oldProps, newProps) {
|
|
36
|
+
const hasSourceViewProps = newProps.language !== undefined ||
|
|
37
|
+
newProps.styleScheme !== undefined ||
|
|
38
|
+
newProps.highlightSyntax !== undefined ||
|
|
39
|
+
newProps.highlightMatchingBrackets !== undefined ||
|
|
40
|
+
newProps.implicitTrailingNewline !== undefined ||
|
|
41
|
+
newProps.onCursorMoved !== undefined ||
|
|
42
|
+
newProps.onHighlightUpdated !== undefined ||
|
|
43
|
+
oldProps?.language !== undefined ||
|
|
44
|
+
oldProps?.styleScheme !== undefined;
|
|
45
|
+
if (!hasSourceViewProps) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const buffer = this.ensureBufferController().ensureBuffer();
|
|
49
|
+
if (hasChanged(oldProps, newProps, "language")) {
|
|
50
|
+
if (newProps.language !== undefined) {
|
|
51
|
+
const language = this.resolveLanguage(newProps.language);
|
|
52
|
+
buffer.setLanguage(language);
|
|
53
|
+
}
|
|
54
|
+
else if (oldProps?.language !== undefined) {
|
|
55
|
+
buffer.setLanguage(null);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (hasChanged(oldProps, newProps, "styleScheme")) {
|
|
59
|
+
if (newProps.styleScheme !== undefined) {
|
|
60
|
+
const scheme = this.resolveStyleScheme(newProps.styleScheme);
|
|
61
|
+
buffer.setStyleScheme(scheme);
|
|
62
|
+
}
|
|
63
|
+
else if (oldProps?.styleScheme !== undefined) {
|
|
64
|
+
buffer.setStyleScheme(null);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (hasChanged(oldProps, newProps, "highlightSyntax") || hasChanged(oldProps, newProps, "language")) {
|
|
68
|
+
const highlightSyntax = newProps.highlightSyntax ?? newProps.language !== undefined;
|
|
69
|
+
buffer.setHighlightSyntax(highlightSyntax);
|
|
70
|
+
}
|
|
71
|
+
if (hasChanged(oldProps, newProps, "highlightMatchingBrackets")) {
|
|
72
|
+
const highlightMatchingBrackets = newProps.highlightMatchingBrackets ?? true;
|
|
73
|
+
buffer.setHighlightMatchingBrackets(highlightMatchingBrackets);
|
|
74
|
+
}
|
|
75
|
+
if (hasChanged(oldProps, newProps, "implicitTrailingNewline")) {
|
|
76
|
+
if (newProps.implicitTrailingNewline !== undefined) {
|
|
77
|
+
buffer.setImplicitTrailingNewline(newProps.implicitTrailingNewline);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (hasChanged(oldProps, newProps, "onCursorMoved") || hasChanged(oldProps, newProps, "onHighlightUpdated")) {
|
|
81
|
+
this.updateSourceViewSignalHandlers(newProps);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
updateSourceViewSignalHandlers(props) {
|
|
85
|
+
const buffer = this.ensureBufferController().getBuffer();
|
|
86
|
+
if (!buffer)
|
|
87
|
+
return;
|
|
88
|
+
const { onCursorMoved, onHighlightUpdated } = props;
|
|
89
|
+
this.signalStore.set(this, buffer, "cursor-moved", onCursorMoved ?? null);
|
|
90
|
+
this.signalStore.set(this, buffer, "highlight-updated", onHighlightUpdated ? (start, end) => onHighlightUpdated(start, end) : null);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
registerNodeClass(SourceViewNode);
|
package/dist/nodes/stack-page.js
CHANGED
|
@@ -1,37 +1,47 @@
|
|
|
1
1
|
import { isObjectEqual } from "@gtkx/ffi";
|
|
2
2
|
import * as Adw from "@gtkx/ffi/adw";
|
|
3
3
|
import { registerNodeClass } from "../registry.js";
|
|
4
|
+
import { hasChanged } from "./internal/utils.js";
|
|
4
5
|
import { SlotNode } from "./slot.js";
|
|
5
6
|
class StackPageNode extends SlotNode {
|
|
6
7
|
static priority = 1;
|
|
7
|
-
page;
|
|
8
|
+
page = null;
|
|
8
9
|
static matches(type) {
|
|
9
10
|
return type === "StackPage";
|
|
10
11
|
}
|
|
11
12
|
updateProps(oldProps, newProps) {
|
|
12
13
|
super.updateProps(oldProps, newProps);
|
|
14
|
+
this.applyOwnProps(oldProps, newProps);
|
|
15
|
+
}
|
|
16
|
+
applyOwnProps(oldProps, newProps) {
|
|
13
17
|
if (!this.page) {
|
|
14
18
|
return;
|
|
15
19
|
}
|
|
16
|
-
if (newProps
|
|
20
|
+
if (hasChanged(oldProps, newProps, "title") && newProps.title !== undefined) {
|
|
17
21
|
this.page.setTitle(newProps.title);
|
|
18
22
|
}
|
|
19
|
-
if (newProps
|
|
23
|
+
if (hasChanged(oldProps, newProps, "iconName") && newProps.iconName !== undefined) {
|
|
20
24
|
this.page.setIconName(newProps.iconName);
|
|
21
25
|
}
|
|
22
|
-
if (
|
|
26
|
+
if (hasChanged(oldProps, newProps, "needsAttention")) {
|
|
23
27
|
this.page.setNeedsAttention(newProps.needsAttention ?? false);
|
|
24
28
|
}
|
|
25
|
-
if (
|
|
29
|
+
if (hasChanged(oldProps, newProps, "visible")) {
|
|
26
30
|
this.page.setVisible(newProps.visible ?? true);
|
|
27
31
|
}
|
|
28
|
-
if (
|
|
32
|
+
if (hasChanged(oldProps, newProps, "useUnderline")) {
|
|
29
33
|
this.page.setUseUnderline(newProps.useUnderline ?? false);
|
|
30
34
|
}
|
|
31
|
-
if ("setBadgeNumber" in this.page && (
|
|
35
|
+
if ("setBadgeNumber" in this.page && hasChanged(oldProps, newProps, "badgeNumber")) {
|
|
32
36
|
this.page.setBadgeNumber?.(newProps.badgeNumber ?? 0);
|
|
33
37
|
}
|
|
34
38
|
}
|
|
39
|
+
onChildChange(oldChild) {
|
|
40
|
+
this.removePage(oldChild);
|
|
41
|
+
if (this.child) {
|
|
42
|
+
this.addPage();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
35
45
|
addPage() {
|
|
36
46
|
const child = this.getChild();
|
|
37
47
|
const parent = this.getParent();
|
|
@@ -74,11 +84,5 @@ class StackPageNode extends SlotNode {
|
|
|
74
84
|
parent.remove(oldChild);
|
|
75
85
|
}
|
|
76
86
|
}
|
|
77
|
-
onChildChange(oldChild) {
|
|
78
|
-
this.removePage(oldChild);
|
|
79
|
-
if (this.child) {
|
|
80
|
-
this.addPage();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
87
|
}
|
|
84
88
|
registerNodeClass(StackPageNode);
|
package/dist/nodes/stack.js
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
import { STACK_CLASSES } from "../generated/internal.js";
|
|
2
2
|
import { registerNodeClass } from "../registry.js";
|
|
3
|
-
import { scheduleAfterCommit } from "../scheduler.js";
|
|
4
|
-
import { filterProps, matchesAnyClass } from "./internal/utils.js";
|
|
3
|
+
import { CommitPriority, scheduleAfterCommit } from "../scheduler.js";
|
|
4
|
+
import { filterProps, hasChanged, matchesAnyClass } from "./internal/utils.js";
|
|
5
5
|
import { WidgetNode } from "./widget.js";
|
|
6
|
-
const
|
|
6
|
+
const OWN_PROPS = ["page", "onPageChanged"];
|
|
7
7
|
class StackNode extends WidgetNode {
|
|
8
8
|
static priority = 1;
|
|
9
9
|
static matches(_type, containerOrClass) {
|
|
10
10
|
return matchesAnyClass(STACK_CLASSES, containerOrClass);
|
|
11
11
|
}
|
|
12
12
|
updateProps(oldProps, newProps) {
|
|
13
|
+
super.updateProps(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
14
|
+
this.applyOwnProps(oldProps, newProps);
|
|
15
|
+
}
|
|
16
|
+
applyOwnProps(oldProps, newProps) {
|
|
13
17
|
if (newProps.page && this.container.getVisibleChildName() !== newProps.page) {
|
|
14
18
|
const page = newProps.page;
|
|
15
19
|
scheduleAfterCommit(() => {
|
|
16
20
|
if (this.container.getChildByName(page)) {
|
|
17
21
|
this.container.setVisibleChildName(page);
|
|
18
22
|
}
|
|
19
|
-
});
|
|
23
|
+
}, CommitPriority.NORMAL);
|
|
24
|
+
}
|
|
25
|
+
if (hasChanged(oldProps, newProps, "onPageChanged")) {
|
|
26
|
+
const { onPageChanged } = newProps;
|
|
27
|
+
if (onPageChanged) {
|
|
28
|
+
this.signalStore.set(this, this.container, "notify::visible-child-name", (self) => {
|
|
29
|
+
onPageChanged(self.getVisibleChildName(), self);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
this.signalStore.set(this, this.container, "notify::visible-child-name", null);
|
|
34
|
+
}
|
|
20
35
|
}
|
|
21
|
-
super.updateProps(filterProps(oldProps ?? {}, PROPS), filterProps(newProps, PROPS));
|
|
22
36
|
}
|
|
23
37
|
}
|
|
24
38
|
registerNodeClass(StackNode);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import type { Node } from "../node.js";
|
|
4
|
+
import { VirtualNode } from "./virtual.js";
|
|
5
|
+
/**
|
|
6
|
+
* Props for the TextAnchor virtual element.
|
|
7
|
+
*
|
|
8
|
+
* Used to declaratively embed widgets within text content in a TextBuffer.
|
|
9
|
+
* The anchor is placed at the current position in the text flow.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <GtkTextView>
|
|
14
|
+
* <x.TextBuffer>
|
|
15
|
+
* Click here: <x.TextAnchor>
|
|
16
|
+
* <GtkButton label="Click me" />
|
|
17
|
+
* </x.TextAnchor> to continue.
|
|
18
|
+
* </x.TextBuffer>
|
|
19
|
+
* </GtkTextView>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export type TextAnchorProps = {
|
|
23
|
+
/** The widget to embed at this anchor position */
|
|
24
|
+
children?: ReactNode;
|
|
25
|
+
};
|
|
26
|
+
export declare class TextAnchorNode extends VirtualNode<TextAnchorProps> {
|
|
27
|
+
static priority: number;
|
|
28
|
+
private textView;
|
|
29
|
+
private buffer;
|
|
30
|
+
private anchor;
|
|
31
|
+
private widgetChild;
|
|
32
|
+
bufferOffset: number;
|
|
33
|
+
static matches(type: string): boolean;
|
|
34
|
+
getLength(): number;
|
|
35
|
+
getText(): string;
|
|
36
|
+
setTextViewAndBuffer(textView: Gtk.TextView, buffer: Gtk.TextBuffer): void;
|
|
37
|
+
private setupAnchor;
|
|
38
|
+
appendChild(child: Node): void;
|
|
39
|
+
removeChild(child: Node): void;
|
|
40
|
+
unmount(): void;
|
|
41
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import { registerNodeClass } from "../registry.js";
|
|
3
|
+
import { VirtualNode } from "./virtual.js";
|
|
4
|
+
import { WidgetNode } from "./widget.js";
|
|
5
|
+
const PLACEHOLDER = "\uFFFC";
|
|
6
|
+
export class TextAnchorNode extends VirtualNode {
|
|
7
|
+
static priority = 1;
|
|
8
|
+
textView = null;
|
|
9
|
+
buffer = null;
|
|
10
|
+
anchor = null;
|
|
11
|
+
widgetChild = null;
|
|
12
|
+
bufferOffset = 0;
|
|
13
|
+
static matches(type) {
|
|
14
|
+
return type === "TextAnchor";
|
|
15
|
+
}
|
|
16
|
+
getLength() {
|
|
17
|
+
return 1;
|
|
18
|
+
}
|
|
19
|
+
getText() {
|
|
20
|
+
return PLACEHOLDER;
|
|
21
|
+
}
|
|
22
|
+
setTextViewAndBuffer(textView, buffer) {
|
|
23
|
+
this.textView = textView;
|
|
24
|
+
this.buffer = buffer;
|
|
25
|
+
this.setupAnchor();
|
|
26
|
+
}
|
|
27
|
+
setupAnchor() {
|
|
28
|
+
if (!this.textView || !this.buffer)
|
|
29
|
+
return;
|
|
30
|
+
const iter = new Gtk.TextIter();
|
|
31
|
+
this.buffer.getIterAtOffset(iter, this.bufferOffset);
|
|
32
|
+
this.anchor = this.buffer.createChildAnchor(iter);
|
|
33
|
+
if (this.widgetChild?.container && this.anchor) {
|
|
34
|
+
this.textView.addChildAtAnchor(this.widgetChild.container, this.anchor);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
appendChild(child) {
|
|
38
|
+
if (!(child instanceof WidgetNode)) {
|
|
39
|
+
throw new Error(`TextAnchor can only contain widget children, got '${child.typeName}'`);
|
|
40
|
+
}
|
|
41
|
+
this.widgetChild = child;
|
|
42
|
+
if (this.textView && this.anchor && child.container) {
|
|
43
|
+
this.textView.addChildAtAnchor(child.container, this.anchor);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
removeChild(child) {
|
|
47
|
+
if (child === this.widgetChild) {
|
|
48
|
+
this.widgetChild = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
unmount() {
|
|
52
|
+
this.anchor = null;
|
|
53
|
+
this.widgetChild = null;
|
|
54
|
+
this.buffer = null;
|
|
55
|
+
this.textView = null;
|
|
56
|
+
super.unmount();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
registerNodeClass(TextAnchorNode);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TextAnchorNode } from "./text-anchor.js";
|
|
2
|
+
import type { TextPaintableNode } from "./text-paintable.js";
|
|
3
|
+
import type { TextSegmentNode } from "./text-segment.js";
|
|
4
|
+
import type { TextTagNode } from "./text-tag.js";
|
|
5
|
+
export type TextContentChild = TextSegmentNode | TextTagNode | TextAnchorNode | TextPaintableNode;
|
|
6
|
+
export type TextContentParent = {
|
|
7
|
+
onChildInserted(child: TextContentChild): void;
|
|
8
|
+
onChildRemoved(child: TextContentChild): void;
|
|
9
|
+
onChildTextChanged(child: TextSegmentNode, oldLength: number, newLength: number): void;
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type * as Gdk from "@gtkx/ffi/gdk";
|
|
2
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
+
import { VirtualNode } from "./virtual.js";
|
|
4
|
+
export type TextPaintableProps = {
|
|
5
|
+
paintable: Gdk.Paintable;
|
|
6
|
+
};
|
|
7
|
+
export declare class TextPaintableNode extends VirtualNode<TextPaintableProps> {
|
|
8
|
+
static priority: number;
|
|
9
|
+
private buffer;
|
|
10
|
+
bufferOffset: number;
|
|
11
|
+
static matches(type: string): boolean;
|
|
12
|
+
getLength(): number;
|
|
13
|
+
getText(): string;
|
|
14
|
+
setTextViewAndBuffer(_textView: Gtk.TextView, buffer: Gtk.TextBuffer): void;
|
|
15
|
+
private insertPaintable;
|
|
16
|
+
unmount(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import { registerNodeClass } from "../registry.js";
|
|
3
|
+
import { VirtualNode } from "./virtual.js";
|
|
4
|
+
const PLACEHOLDER = "\uFFFC";
|
|
5
|
+
export class TextPaintableNode extends VirtualNode {
|
|
6
|
+
static priority = 1;
|
|
7
|
+
buffer = null;
|
|
8
|
+
bufferOffset = 0;
|
|
9
|
+
static matches(type) {
|
|
10
|
+
return type === "TextPaintable";
|
|
11
|
+
}
|
|
12
|
+
getLength() {
|
|
13
|
+
return 1;
|
|
14
|
+
}
|
|
15
|
+
getText() {
|
|
16
|
+
return PLACEHOLDER;
|
|
17
|
+
}
|
|
18
|
+
setTextViewAndBuffer(_textView, buffer) {
|
|
19
|
+
this.buffer = buffer;
|
|
20
|
+
this.insertPaintable();
|
|
21
|
+
}
|
|
22
|
+
insertPaintable() {
|
|
23
|
+
if (!this.buffer || !this.props.paintable)
|
|
24
|
+
return;
|
|
25
|
+
const iter = new Gtk.TextIter();
|
|
26
|
+
this.buffer.getIterAtOffset(iter, this.bufferOffset);
|
|
27
|
+
this.buffer.insertPaintable(iter, this.props.paintable);
|
|
28
|
+
}
|
|
29
|
+
unmount() {
|
|
30
|
+
this.buffer = null;
|
|
31
|
+
super.unmount();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
registerNodeClass(TextPaintableNode);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { TextContentParent } from "./text-content.js";
|
|
2
|
+
import { VirtualNode } from "./virtual.js";
|
|
3
|
+
export type TextSegmentProps = {
|
|
4
|
+
text: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class TextSegmentNode extends VirtualNode<TextSegmentProps> {
|
|
7
|
+
static priority: number;
|
|
8
|
+
private parent;
|
|
9
|
+
bufferOffset: number;
|
|
10
|
+
static matches(type: string): boolean;
|
|
11
|
+
setParent(parent: TextContentParent): void;
|
|
12
|
+
getText(): string;
|
|
13
|
+
getLength(): number;
|
|
14
|
+
updateProps(oldProps: TextSegmentProps | null, newProps: TextSegmentProps): void;
|
|
15
|
+
}
|