@gtkx/react 0.18.0 → 0.18.2
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/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +1 -0
- package/dist/errors.js.map +1 -0
- package/dist/factory.d.ts +1 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +1 -0
- package/dist/factory.js.map +1 -0
- package/dist/fiber-root.d.ts +1 -0
- package/dist/fiber-root.d.ts.map +1 -0
- package/dist/fiber-root.js +1 -0
- package/dist/fiber-root.js.map +1 -0
- package/dist/generated/internal.d.ts +1 -0
- package/dist/generated/internal.d.ts.map +1 -0
- package/dist/generated/internal.js +1 -0
- package/dist/generated/internal.js.map +1 -0
- package/dist/generated/jsx.d.ts +1 -0
- package/dist/generated/jsx.d.ts.map +1 -0
- package/dist/generated/jsx.js +1 -0
- package/dist/generated/jsx.js.map +1 -0
- package/dist/generated/registry.d.ts +1 -0
- package/dist/generated/registry.d.ts.map +1 -0
- package/dist/generated/registry.js +1 -0
- package/dist/generated/registry.js.map +1 -0
- package/dist/host-config.d.ts +1 -0
- package/dist/host-config.d.ts.map +1 -0
- package/dist/host-config.js +1 -0
- package/dist/host-config.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx.d.ts +1 -0
- package/dist/jsx.d.ts.map +1 -0
- package/dist/jsx.js +1 -0
- package/dist/jsx.js.map +1 -0
- package/dist/metadata.d.ts +1 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +1 -0
- package/dist/metadata.js.map +1 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +1 -0
- package/dist/node.js.map +1 -0
- package/dist/nodes/adjustable.d.ts +1 -0
- package/dist/nodes/adjustable.d.ts.map +1 -0
- package/dist/nodes/adjustable.js +1 -0
- package/dist/nodes/adjustable.js.map +1 -0
- package/dist/nodes/alert-dialog-response.d.ts +1 -0
- package/dist/nodes/alert-dialog-response.d.ts.map +1 -0
- package/dist/nodes/alert-dialog-response.js +1 -0
- package/dist/nodes/alert-dialog-response.js.map +1 -0
- package/dist/nodes/animation.d.ts +1 -0
- package/dist/nodes/animation.d.ts.map +1 -0
- package/dist/nodes/animation.js +1 -0
- package/dist/nodes/animation.js.map +1 -0
- package/dist/nodes/application.d.ts +1 -0
- package/dist/nodes/application.d.ts.map +1 -0
- package/dist/nodes/application.js +1 -0
- package/dist/nodes/application.js.map +1 -0
- package/dist/nodes/calendar.d.ts +1 -0
- package/dist/nodes/calendar.d.ts.map +1 -0
- package/dist/nodes/calendar.js +1 -0
- package/dist/nodes/calendar.js.map +1 -0
- package/dist/nodes/color-dialog-button.d.ts +1 -0
- package/dist/nodes/color-dialog-button.d.ts.map +1 -0
- package/dist/nodes/color-dialog-button.js +1 -0
- package/dist/nodes/color-dialog-button.js.map +1 -0
- package/dist/nodes/column-view-column.d.ts +1 -0
- package/dist/nodes/column-view-column.d.ts.map +1 -0
- package/dist/nodes/column-view-column.js +1 -0
- package/dist/nodes/column-view-column.js.map +1 -0
- package/dist/nodes/column-view.d.ts +1 -0
- package/dist/nodes/column-view.d.ts.map +1 -0
- package/dist/nodes/column-view.js +1 -0
- package/dist/nodes/column-view.js.map +1 -0
- package/dist/nodes/container-slot.d.ts +1 -0
- package/dist/nodes/container-slot.d.ts.map +1 -0
- package/dist/nodes/container-slot.js +1 -0
- package/dist/nodes/container-slot.js.map +1 -0
- package/dist/nodes/dialog.d.ts +1 -0
- package/dist/nodes/dialog.d.ts.map +1 -0
- package/dist/nodes/dialog.js +1 -0
- package/dist/nodes/dialog.js.map +1 -0
- package/dist/nodes/drawing-area.d.ts +1 -0
- package/dist/nodes/drawing-area.d.ts.map +1 -0
- package/dist/nodes/drawing-area.js +1 -0
- package/dist/nodes/drawing-area.js.map +1 -0
- package/dist/nodes/drop-down.d.ts +1 -0
- package/dist/nodes/drop-down.d.ts.map +1 -0
- package/dist/nodes/drop-down.js +1 -0
- package/dist/nodes/drop-down.js.map +1 -0
- package/dist/nodes/event-controller.d.ts +1 -0
- package/dist/nodes/event-controller.d.ts.map +1 -0
- package/dist/nodes/event-controller.js +1 -0
- package/dist/nodes/event-controller.js.map +1 -0
- package/dist/nodes/fixed-child.d.ts +1 -0
- package/dist/nodes/fixed-child.d.ts.map +1 -0
- package/dist/nodes/fixed-child.js +1 -0
- package/dist/nodes/fixed-child.js.map +1 -0
- package/dist/nodes/font-dialog-button.d.ts +1 -0
- package/dist/nodes/font-dialog-button.d.ts.map +1 -0
- package/dist/nodes/font-dialog-button.js +1 -0
- package/dist/nodes/font-dialog-button.js.map +1 -0
- package/dist/nodes/grid-child.d.ts +1 -0
- package/dist/nodes/grid-child.d.ts.map +1 -0
- package/dist/nodes/grid-child.js +1 -0
- package/dist/nodes/grid-child.js.map +1 -0
- package/dist/nodes/grid-view.d.ts +1 -0
- package/dist/nodes/grid-view.d.ts.map +1 -0
- package/dist/nodes/grid-view.js +1 -0
- package/dist/nodes/grid-view.js.map +1 -0
- package/dist/nodes/internal/base-item-renderer.d.ts +1 -0
- package/dist/nodes/internal/base-item-renderer.d.ts.map +1 -0
- package/dist/nodes/internal/base-item-renderer.js +1 -0
- package/dist/nodes/internal/base-item-renderer.js.map +1 -0
- package/dist/nodes/internal/grid-item-renderer.d.ts +1 -0
- package/dist/nodes/internal/grid-item-renderer.d.ts.map +1 -0
- package/dist/nodes/internal/grid-item-renderer.js +1 -0
- package/dist/nodes/internal/grid-item-renderer.js.map +1 -0
- package/dist/nodes/internal/list-item-renderer.d.ts +1 -0
- package/dist/nodes/internal/list-item-renderer.d.ts.map +1 -0
- package/dist/nodes/internal/list-item-renderer.js +1 -0
- package/dist/nodes/internal/list-item-renderer.js.map +1 -0
- package/dist/nodes/internal/list-store.d.ts +1 -0
- package/dist/nodes/internal/list-store.d.ts.map +1 -0
- package/dist/nodes/internal/list-store.js +1 -0
- package/dist/nodes/internal/list-store.js.map +1 -0
- package/dist/nodes/internal/predicates.d.ts +1 -0
- package/dist/nodes/internal/predicates.d.ts.map +1 -0
- package/dist/nodes/internal/predicates.js +1 -0
- package/dist/nodes/internal/predicates.js.map +1 -0
- package/dist/nodes/internal/props.d.ts +1 -0
- package/dist/nodes/internal/props.d.ts.map +1 -0
- package/dist/nodes/internal/props.js +1 -0
- package/dist/nodes/internal/props.js.map +1 -0
- package/dist/nodes/internal/selection-model-controller.d.ts +1 -0
- package/dist/nodes/internal/selection-model-controller.d.ts.map +1 -0
- package/dist/nodes/internal/selection-model-controller.js +1 -0
- package/dist/nodes/internal/selection-model-controller.js.map +1 -0
- package/dist/nodes/internal/signal-store.d.ts +1 -0
- package/dist/nodes/internal/signal-store.d.ts.map +1 -0
- package/dist/nodes/internal/signal-store.js +1 -0
- package/dist/nodes/internal/signal-store.js.map +1 -0
- package/dist/nodes/internal/simple-list-store.d.ts +1 -0
- package/dist/nodes/internal/simple-list-store.d.ts.map +1 -0
- package/dist/nodes/internal/simple-list-store.js +1 -0
- package/dist/nodes/internal/simple-list-store.js.map +1 -0
- package/dist/nodes/internal/text-buffer-controller.d.ts +1 -0
- package/dist/nodes/internal/text-buffer-controller.d.ts.map +1 -0
- package/dist/nodes/internal/text-buffer-controller.js +1 -0
- package/dist/nodes/internal/text-buffer-controller.js.map +1 -0
- package/dist/nodes/internal/tree-store.d.ts +1 -0
- package/dist/nodes/internal/tree-store.d.ts.map +1 -0
- package/dist/nodes/internal/tree-store.js +1 -0
- package/dist/nodes/internal/tree-store.js.map +1 -0
- package/dist/nodes/internal/widget.d.ts +1 -0
- package/dist/nodes/internal/widget.d.ts.map +1 -0
- package/dist/nodes/internal/widget.js +1 -0
- package/dist/nodes/internal/widget.js.map +1 -0
- package/dist/nodes/level-bar.d.ts +1 -0
- package/dist/nodes/level-bar.d.ts.map +1 -0
- package/dist/nodes/level-bar.js +1 -0
- package/dist/nodes/level-bar.js.map +1 -0
- package/dist/nodes/list-item.d.ts +1 -0
- package/dist/nodes/list-item.d.ts.map +1 -0
- package/dist/nodes/list-item.js +1 -0
- package/dist/nodes/list-item.js.map +1 -0
- package/dist/nodes/list-view.d.ts +1 -0
- package/dist/nodes/list-view.d.ts.map +1 -0
- package/dist/nodes/list-view.js +1 -0
- package/dist/nodes/list-view.js.map +1 -0
- package/dist/nodes/menu.d.ts +1 -0
- package/dist/nodes/menu.d.ts.map +1 -0
- package/dist/nodes/menu.js +1 -0
- package/dist/nodes/menu.js.map +1 -0
- package/dist/nodes/models/grid.d.ts +1 -0
- package/dist/nodes/models/grid.d.ts.map +1 -0
- package/dist/nodes/models/grid.js +1 -0
- package/dist/nodes/models/grid.js.map +1 -0
- package/dist/nodes/models/list.d.ts +1 -0
- package/dist/nodes/models/list.d.ts.map +1 -0
- package/dist/nodes/models/list.js +1 -0
- package/dist/nodes/models/list.js.map +1 -0
- package/dist/nodes/models/menu.d.ts +1 -0
- package/dist/nodes/models/menu.d.ts.map +1 -0
- package/dist/nodes/models/menu.js +1 -0
- package/dist/nodes/models/menu.js.map +1 -0
- package/dist/nodes/navigation-page.d.ts +1 -0
- package/dist/nodes/navigation-page.d.ts.map +1 -0
- package/dist/nodes/navigation-page.js +1 -0
- package/dist/nodes/navigation-page.js.map +1 -0
- package/dist/nodes/navigation-view.d.ts +1 -0
- package/dist/nodes/navigation-view.d.ts.map +1 -0
- package/dist/nodes/navigation-view.js +1 -0
- package/dist/nodes/navigation-view.js.map +1 -0
- package/dist/nodes/notebook-page-tab.d.ts +1 -0
- package/dist/nodes/notebook-page-tab.d.ts.map +1 -0
- package/dist/nodes/notebook-page-tab.js +1 -0
- package/dist/nodes/notebook-page-tab.js.map +1 -0
- package/dist/nodes/notebook-page.d.ts +1 -0
- package/dist/nodes/notebook-page.d.ts.map +1 -0
- package/dist/nodes/notebook-page.js +1 -0
- package/dist/nodes/notebook-page.js.map +1 -0
- package/dist/nodes/notebook.d.ts +1 -0
- package/dist/nodes/notebook.d.ts.map +1 -0
- package/dist/nodes/notebook.js +1 -0
- package/dist/nodes/notebook.js.map +1 -0
- package/dist/nodes/overlay-child.d.ts +1 -0
- package/dist/nodes/overlay-child.d.ts.map +1 -0
- package/dist/nodes/overlay-child.js +1 -0
- package/dist/nodes/overlay-child.js.map +1 -0
- package/dist/nodes/popover-menu.d.ts +1 -0
- package/dist/nodes/popover-menu.d.ts.map +1 -0
- package/dist/nodes/popover-menu.js +1 -0
- package/dist/nodes/popover-menu.js.map +1 -0
- package/dist/nodes/scale.d.ts +1 -0
- package/dist/nodes/scale.d.ts.map +1 -0
- package/dist/nodes/scale.js +1 -0
- package/dist/nodes/scale.js.map +1 -0
- package/dist/nodes/scrolled-window.d.ts +1 -0
- package/dist/nodes/scrolled-window.d.ts.map +1 -0
- package/dist/nodes/scrolled-window.js +1 -0
- package/dist/nodes/scrolled-window.js.map +1 -0
- package/dist/nodes/search-bar.d.ts +1 -0
- package/dist/nodes/search-bar.d.ts.map +1 -0
- package/dist/nodes/search-bar.js +1 -0
- package/dist/nodes/search-bar.js.map +1 -0
- package/dist/nodes/shortcut-controller.d.ts +1 -0
- package/dist/nodes/shortcut-controller.d.ts.map +1 -0
- package/dist/nodes/shortcut-controller.js +1 -0
- package/dist/nodes/shortcut-controller.js.map +1 -0
- package/dist/nodes/shortcut.d.ts +1 -0
- package/dist/nodes/shortcut.d.ts.map +1 -0
- package/dist/nodes/shortcut.js +1 -0
- package/dist/nodes/shortcut.js.map +1 -0
- package/dist/nodes/slot.d.ts +1 -0
- package/dist/nodes/slot.d.ts.map +1 -0
- package/dist/nodes/slot.js +1 -0
- package/dist/nodes/slot.js.map +1 -0
- package/dist/nodes/source-view.d.ts +1 -0
- package/dist/nodes/source-view.d.ts.map +1 -0
- package/dist/nodes/source-view.js +1 -0
- package/dist/nodes/source-view.js.map +1 -0
- package/dist/nodes/stack-page.d.ts +1 -0
- package/dist/nodes/stack-page.d.ts.map +1 -0
- package/dist/nodes/stack-page.js +1 -0
- package/dist/nodes/stack-page.js.map +1 -0
- package/dist/nodes/stack.d.ts +1 -0
- package/dist/nodes/stack.d.ts.map +1 -0
- package/dist/nodes/stack.js +1 -0
- package/dist/nodes/stack.js.map +1 -0
- package/dist/nodes/text-anchor.d.ts +1 -0
- package/dist/nodes/text-anchor.d.ts.map +1 -0
- package/dist/nodes/text-anchor.js +1 -0
- package/dist/nodes/text-anchor.js.map +1 -0
- package/dist/nodes/text-content.d.ts +1 -0
- package/dist/nodes/text-content.d.ts.map +1 -0
- package/dist/nodes/text-content.js +1 -0
- package/dist/nodes/text-content.js.map +1 -0
- package/dist/nodes/text-paintable.d.ts +1 -0
- package/dist/nodes/text-paintable.d.ts.map +1 -0
- package/dist/nodes/text-paintable.js +1 -0
- package/dist/nodes/text-paintable.js.map +1 -0
- package/dist/nodes/text-segment.d.ts +1 -0
- package/dist/nodes/text-segment.d.ts.map +1 -0
- package/dist/nodes/text-segment.js +1 -0
- package/dist/nodes/text-segment.js.map +1 -0
- package/dist/nodes/text-tag.d.ts +1 -0
- package/dist/nodes/text-tag.d.ts.map +1 -0
- package/dist/nodes/text-tag.js +1 -0
- package/dist/nodes/text-tag.js.map +1 -0
- package/dist/nodes/text-view.d.ts +1 -0
- package/dist/nodes/text-view.d.ts.map +1 -0
- package/dist/nodes/text-view.js +1 -0
- package/dist/nodes/text-view.js.map +1 -0
- package/dist/nodes/toggle-group.d.ts +1 -0
- package/dist/nodes/toggle-group.d.ts.map +1 -0
- package/dist/nodes/toggle-group.js +1 -0
- package/dist/nodes/toggle-group.js.map +1 -0
- package/dist/nodes/toggle.d.ts +1 -0
- package/dist/nodes/toggle.d.ts.map +1 -0
- package/dist/nodes/toggle.js +1 -0
- package/dist/nodes/toggle.js.map +1 -0
- package/dist/nodes/virtual.d.ts +1 -0
- package/dist/nodes/virtual.d.ts.map +1 -0
- package/dist/nodes/virtual.js +1 -0
- package/dist/nodes/virtual.js.map +1 -0
- package/dist/nodes/web-view.d.ts +1 -0
- package/dist/nodes/web-view.d.ts.map +1 -0
- package/dist/nodes/web-view.js +1 -0
- package/dist/nodes/web-view.js.map +1 -0
- package/dist/nodes/widget.d.ts +1 -0
- package/dist/nodes/widget.d.ts.map +1 -0
- package/dist/nodes/widget.js +1 -0
- package/dist/nodes/widget.js.map +1 -0
- package/dist/nodes/window.d.ts +1 -0
- package/dist/nodes/window.d.ts.map +1 -0
- package/dist/nodes/window.js +1 -0
- package/dist/nodes/window.js.map +1 -0
- package/dist/portal.d.ts +1 -0
- package/dist/portal.d.ts.map +1 -0
- package/dist/portal.js +1 -0
- package/dist/portal.js.map +1 -0
- package/dist/reconciler.d.ts +1 -0
- package/dist/reconciler.d.ts.map +1 -0
- package/dist/reconciler.js +1 -0
- package/dist/reconciler.js.map +1 -0
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +1 -0
- package/dist/registry.js.map +1 -0
- package/dist/render.d.ts +1 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +1 -0
- package/dist/render.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +6 -4
- package/src/errors.ts +52 -0
- package/src/factory.ts +62 -0
- package/src/fiber-root.ts +20 -0
- package/src/generated/internal.ts +2134 -0
- package/src/generated/jsx.ts +20068 -0
- package/src/generated/registry.ts +16 -0
- package/src/host-config.ts +186 -0
- package/src/index.ts +11 -0
- package/src/jsx.ts +1294 -0
- package/src/metadata.ts +36 -0
- package/src/node.ts +109 -0
- package/src/nodes/adjustable.ts +68 -0
- package/src/nodes/alert-dialog-response.ts +78 -0
- package/src/nodes/animation.ts +402 -0
- package/src/nodes/application.ts +56 -0
- package/src/nodes/calendar.ts +38 -0
- package/src/nodes/color-dialog-button.ts +69 -0
- package/src/nodes/column-view-column.ts +84 -0
- package/src/nodes/column-view.ts +192 -0
- package/src/nodes/container-slot.ts +87 -0
- package/src/nodes/dialog.ts +25 -0
- package/src/nodes/drawing-area.ts +51 -0
- package/src/nodes/drop-down.ts +92 -0
- package/src/nodes/event-controller.ts +100 -0
- package/src/nodes/fixed-child.ts +108 -0
- package/src/nodes/font-dialog-button.ts +97 -0
- package/src/nodes/grid-child.ts +103 -0
- package/src/nodes/grid-view.ts +96 -0
- package/src/nodes/internal/base-item-renderer.ts +108 -0
- package/src/nodes/internal/grid-item-renderer.ts +71 -0
- package/src/nodes/internal/list-item-renderer.ts +155 -0
- package/src/nodes/internal/list-store.ts +105 -0
- package/src/nodes/internal/predicates.ts +80 -0
- package/src/nodes/internal/props.ts +51 -0
- package/src/nodes/internal/selection-model-controller.ts +115 -0
- package/src/nodes/internal/signal-store.ts +141 -0
- package/src/nodes/internal/simple-list-store.ts +99 -0
- package/src/nodes/internal/text-buffer-controller.ts +374 -0
- package/src/nodes/internal/tree-store.ts +237 -0
- package/src/nodes/internal/widget.ts +78 -0
- package/src/nodes/level-bar.ts +36 -0
- package/src/nodes/list-item.ts +107 -0
- package/src/nodes/list-view.ts +97 -0
- package/src/nodes/menu.ts +27 -0
- package/src/nodes/models/grid.ts +105 -0
- package/src/nodes/models/list.ts +140 -0
- package/src/nodes/models/menu.ts +310 -0
- package/src/nodes/navigation-page.ts +154 -0
- package/src/nodes/navigation-view.ts +58 -0
- package/src/nodes/notebook-page-tab.ts +55 -0
- package/src/nodes/notebook-page.ts +185 -0
- package/src/nodes/notebook.ts +28 -0
- package/src/nodes/overlay-child.ts +109 -0
- package/src/nodes/popover-menu.ts +59 -0
- package/src/nodes/scale.ts +28 -0
- package/src/nodes/scrolled-window.ts +23 -0
- package/src/nodes/search-bar.ts +27 -0
- package/src/nodes/shortcut-controller.ts +27 -0
- package/src/nodes/shortcut.ts +69 -0
- package/src/nodes/slot.ts +138 -0
- package/src/nodes/source-view.ts +130 -0
- package/src/nodes/stack-page.ts +170 -0
- package/src/nodes/stack.ts +35 -0
- package/src/nodes/text-anchor.ts +74 -0
- package/src/nodes/text-content.ts +14 -0
- package/src/nodes/text-paintable.ts +51 -0
- package/src/nodes/text-segment.ts +55 -0
- package/src/nodes/text-tag.ts +287 -0
- package/src/nodes/text-view.ts +93 -0
- package/src/nodes/toggle-group.ts +27 -0
- package/src/nodes/toggle.ts +72 -0
- package/src/nodes/virtual.ts +16 -0
- package/src/nodes/web-view.ts +22 -0
- package/src/nodes/widget.ts +398 -0
- package/src/nodes/window.ts +159 -0
- package/src/portal.ts +37 -0
- package/src/reconciler.ts +52 -0
- package/src/registry.ts +123 -0
- package/src/render.tsx +192 -0
- package/src/types.ts +7 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import { toCamelCase } from "@gtkx/gir";
|
|
3
|
+
import type { SlotProps } from "../jsx.js";
|
|
4
|
+
import type { Node } from "../node.js";
|
|
5
|
+
import type { ContainerClass, Props } from "../types.js";
|
|
6
|
+
import { getFocusWidget, isDescendantOf, resolvePropertySetter } from "./internal/widget.js";
|
|
7
|
+
import { VirtualNode } from "./virtual.js";
|
|
8
|
+
import { WidgetNode } from "./widget.js";
|
|
9
|
+
|
|
10
|
+
export class SlotNode<P extends Props = SlotProps, TChild extends Node = WidgetNode> extends VirtualNode<
|
|
11
|
+
P,
|
|
12
|
+
WidgetNode,
|
|
13
|
+
TChild
|
|
14
|
+
> {
|
|
15
|
+
private cachedSetter: ((child: Gtk.Widget | null) => void) | null = null;
|
|
16
|
+
private detachedParentWidget: Gtk.Widget | null = null;
|
|
17
|
+
|
|
18
|
+
public override isValidChild(child: Node): boolean {
|
|
19
|
+
return child instanceof WidgetNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public override isValidParent(parent: Node): boolean {
|
|
23
|
+
return parent instanceof WidgetNode;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public override setParent(parent: WidgetNode | null): void {
|
|
27
|
+
const previousParent = this.parent;
|
|
28
|
+
if (previousParent !== parent) {
|
|
29
|
+
this.cachedSetter = null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!parent && previousParent) {
|
|
33
|
+
this.detachedParentWidget = previousParent.container;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
super.setParent(parent);
|
|
37
|
+
|
|
38
|
+
if (parent && this.children[0]) {
|
|
39
|
+
this.onChildChange(null);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public override appendChild(child: TChild): void {
|
|
44
|
+
const firstChild = this.children[0];
|
|
45
|
+
const oldChildWidget = firstChild instanceof WidgetNode ? firstChild.container : null;
|
|
46
|
+
|
|
47
|
+
super.appendChild(child);
|
|
48
|
+
|
|
49
|
+
if (this.parent) {
|
|
50
|
+
this.onChildChange(oldChildWidget);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public override removeChild(child: TChild): void {
|
|
55
|
+
const oldChildWidget = child instanceof WidgetNode ? child.container : null;
|
|
56
|
+
|
|
57
|
+
super.removeChild(child);
|
|
58
|
+
|
|
59
|
+
if (this.parent && oldChildWidget) {
|
|
60
|
+
this.onChildChange(oldChildWidget);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public override detachDeletedInstance(): void {
|
|
65
|
+
const parentWidget = this.detachedParentWidget;
|
|
66
|
+
|
|
67
|
+
if (parentWidget && this.children[0]) {
|
|
68
|
+
if (parentWidget.getRoot() !== null) {
|
|
69
|
+
this.cachedSetter = null;
|
|
70
|
+
const setter = this.resolveChildSetter(parentWidget);
|
|
71
|
+
if (setter) {
|
|
72
|
+
const oldChild = this.children[0].container;
|
|
73
|
+
const focus = getFocusWidget(oldChild);
|
|
74
|
+
if (focus && isDescendantOf(focus, oldChild)) {
|
|
75
|
+
parentWidget.grabFocus();
|
|
76
|
+
}
|
|
77
|
+
setter(null);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
this.detachedParentWidget = null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
super.detachDeletedInstance();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private getId(): string {
|
|
87
|
+
const id = (this.props as SlotProps).id;
|
|
88
|
+
|
|
89
|
+
if (!id) {
|
|
90
|
+
throw new Error("Expected 'id' prop to be present on Slot");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return toCamelCase(id);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private getParentWidget(): Gtk.Widget {
|
|
97
|
+
if (!this.parent) {
|
|
98
|
+
throw new Error(`Expected parent widget to be set on '${this.getId()}' SlotNode`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return this.parent.container;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private ensureChildSetter(): (child: Gtk.Widget | null) => void {
|
|
105
|
+
if (this.cachedSetter) return this.cachedSetter;
|
|
106
|
+
|
|
107
|
+
const parent = this.getParentWidget();
|
|
108
|
+
const setter = this.resolveChildSetter(parent);
|
|
109
|
+
|
|
110
|
+
if (!setter) {
|
|
111
|
+
const parentType = (parent.constructor as ContainerClass).glibTypeName;
|
|
112
|
+
throw new Error(`Unable to find property for Slot '${this.getId()}' on type '${parentType}'`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
this.cachedSetter = setter;
|
|
116
|
+
return this.cachedSetter;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private onChildChange(oldChild: Gtk.Widget | null): void {
|
|
120
|
+
const setter = this.ensureChildSetter();
|
|
121
|
+
const childWidget = this.children[0]?.container ?? null;
|
|
122
|
+
|
|
123
|
+
if (oldChild && !childWidget) {
|
|
124
|
+
const parent = this.getParentWidget();
|
|
125
|
+
const focus = getFocusWidget(oldChild);
|
|
126
|
+
|
|
127
|
+
if (focus && isDescendantOf(focus, oldChild)) {
|
|
128
|
+
parent.grabFocus();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
setter(childWidget);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private resolveChildSetter(parent: Gtk.Widget): ((child: Gtk.Widget | null) => void) | null {
|
|
136
|
+
return resolvePropertySetter(parent, this.getId());
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import * as GtkSource from "@gtkx/ffi/gtksource";
|
|
3
|
+
import type { GtkSourceViewProps } from "../jsx.js";
|
|
4
|
+
import { filterProps, hasChanged } from "./internal/props.js";
|
|
5
|
+
import { TextBufferController } from "./internal/text-buffer-controller.js";
|
|
6
|
+
import { TextViewNode } from "./text-view.js";
|
|
7
|
+
|
|
8
|
+
const OWN_PROPS = [
|
|
9
|
+
"language",
|
|
10
|
+
"styleScheme",
|
|
11
|
+
"highlightSyntax",
|
|
12
|
+
"highlightMatchingBrackets",
|
|
13
|
+
"implicitTrailingNewline",
|
|
14
|
+
"onCursorMoved",
|
|
15
|
+
"onHighlightUpdated",
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
type SourceViewProps = Pick<
|
|
19
|
+
GtkSourceViewProps,
|
|
20
|
+
| "enableUndo"
|
|
21
|
+
| "onBufferChanged"
|
|
22
|
+
| "onTextInserted"
|
|
23
|
+
| "onTextDeleted"
|
|
24
|
+
| "onCanUndoChanged"
|
|
25
|
+
| "onCanRedoChanged"
|
|
26
|
+
| (typeof OWN_PROPS)[number]
|
|
27
|
+
>;
|
|
28
|
+
|
|
29
|
+
export class SourceViewNode extends TextViewNode {
|
|
30
|
+
protected override createBufferController(): TextBufferController<GtkSource.Buffer> {
|
|
31
|
+
return new TextBufferController<GtkSource.Buffer>(this, this.container, () => new GtkSource.Buffer());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected override ensureBufferController(): TextBufferController<GtkSource.Buffer> {
|
|
35
|
+
return super.ensureBufferController() as TextBufferController<GtkSource.Buffer>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public override commitUpdate(oldProps: SourceViewProps | null, newProps: SourceViewProps): void {
|
|
39
|
+
super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
40
|
+
this.applyOwnProps(oldProps, newProps);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private resolveLanguage(language: string | GtkSource.Language): GtkSource.Language | null {
|
|
44
|
+
if (typeof language === "string") {
|
|
45
|
+
const langManager = GtkSource.LanguageManager.getDefault();
|
|
46
|
+
return langManager.getLanguage(language);
|
|
47
|
+
}
|
|
48
|
+
return language;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private resolveStyleScheme(scheme: string | GtkSource.StyleScheme): GtkSource.StyleScheme | null {
|
|
52
|
+
if (typeof scheme === "string") {
|
|
53
|
+
const schemeManager = GtkSource.StyleSchemeManager.getDefault();
|
|
54
|
+
return schemeManager.getScheme(scheme);
|
|
55
|
+
}
|
|
56
|
+
return scheme;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private applyOwnProps(oldProps: SourceViewProps | null, newProps: SourceViewProps): void {
|
|
60
|
+
if (hasChanged(oldProps, newProps, "onCursorMoved") || hasChanged(oldProps, newProps, "onHighlightUpdated")) {
|
|
61
|
+
this.applySignalProps(newProps);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.applyBufferProps(oldProps, newProps);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private applyBufferProps(oldProps: SourceViewProps | null, newProps: SourceViewProps): void {
|
|
68
|
+
const languageChanged = hasChanged(oldProps, newProps, "language");
|
|
69
|
+
const styleSchemeChanged = hasChanged(oldProps, newProps, "styleScheme");
|
|
70
|
+
const highlightSyntaxChanged = hasChanged(oldProps, newProps, "highlightSyntax");
|
|
71
|
+
const highlightBracketsChanged = hasChanged(oldProps, newProps, "highlightMatchingBrackets");
|
|
72
|
+
const trailingNewlineChanged = hasChanged(oldProps, newProps, "implicitTrailingNewline");
|
|
73
|
+
|
|
74
|
+
if (
|
|
75
|
+
!languageChanged &&
|
|
76
|
+
!styleSchemeChanged &&
|
|
77
|
+
!highlightSyntaxChanged &&
|
|
78
|
+
!highlightBracketsChanged &&
|
|
79
|
+
!trailingNewlineChanged
|
|
80
|
+
) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const buffer = this.ensureBufferController().ensureBuffer();
|
|
85
|
+
|
|
86
|
+
if (languageChanged) {
|
|
87
|
+
if (newProps.language !== undefined) {
|
|
88
|
+
buffer.setLanguage(this.resolveLanguage(newProps.language));
|
|
89
|
+
} else if (oldProps?.language !== undefined) {
|
|
90
|
+
buffer.setLanguage(null);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (styleSchemeChanged) {
|
|
95
|
+
if (newProps.styleScheme !== undefined) {
|
|
96
|
+
buffer.setStyleScheme(this.resolveStyleScheme(newProps.styleScheme));
|
|
97
|
+
} else if (oldProps?.styleScheme !== undefined) {
|
|
98
|
+
buffer.setStyleScheme(null);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (highlightSyntaxChanged || languageChanged) {
|
|
103
|
+
buffer.setHighlightSyntax(newProps.highlightSyntax ?? newProps.language !== undefined);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (highlightBracketsChanged) {
|
|
107
|
+
buffer.setHighlightMatchingBrackets(newProps.highlightMatchingBrackets ?? true);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (trailingNewlineChanged && newProps.implicitTrailingNewline !== undefined) {
|
|
111
|
+
buffer.setImplicitTrailingNewline(newProps.implicitTrailingNewline);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private applySignalProps(props: SourceViewProps): void {
|
|
116
|
+
const buffer = this.ensureBufferController().getBuffer();
|
|
117
|
+
if (!buffer) return;
|
|
118
|
+
|
|
119
|
+
const { onCursorMoved, onHighlightUpdated } = props;
|
|
120
|
+
|
|
121
|
+
this.signalStore.set(this, buffer, "cursor-moved", onCursorMoved);
|
|
122
|
+
|
|
123
|
+
this.signalStore.set(
|
|
124
|
+
this,
|
|
125
|
+
buffer,
|
|
126
|
+
"highlight-updated",
|
|
127
|
+
onHighlightUpdated ? (start: Gtk.TextIter, end: Gtk.TextIter) => onHighlightUpdated(start, end) : undefined,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import * as Adw from "@gtkx/ffi/adw";
|
|
2
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
+
import type { StackPageProps } from "../jsx.js";
|
|
4
|
+
import type { Node } from "../node.js";
|
|
5
|
+
import type { StackWidget } from "../registry.js";
|
|
6
|
+
import { hasChanged } from "./internal/props.js";
|
|
7
|
+
import { VirtualNode } from "./virtual.js";
|
|
8
|
+
import { WidgetNode } from "./widget.js";
|
|
9
|
+
|
|
10
|
+
export class StackPageNode extends VirtualNode<StackPageProps, WidgetNode<StackWidget>, WidgetNode> {
|
|
11
|
+
private page: Gtk.StackPage | Adw.ViewStackPage | null = null;
|
|
12
|
+
|
|
13
|
+
public override isValidChild(child: Node): boolean {
|
|
14
|
+
return child instanceof WidgetNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public override isValidParent(parent: Node): boolean {
|
|
18
|
+
return (
|
|
19
|
+
parent instanceof WidgetNode &&
|
|
20
|
+
(parent.container instanceof Gtk.Stack || parent.container instanceof Adw.ViewStack)
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public override setParent(parent: WidgetNode<StackWidget> | null): void {
|
|
25
|
+
const previousParent = this.parent;
|
|
26
|
+
|
|
27
|
+
if (previousParent && !parent) {
|
|
28
|
+
const childWidget = this.children[0]?.container ?? null;
|
|
29
|
+
if (childWidget) {
|
|
30
|
+
this.removePage(childWidget);
|
|
31
|
+
}
|
|
32
|
+
this.page = null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
super.setParent(parent);
|
|
36
|
+
|
|
37
|
+
if (parent && this.children[0]) {
|
|
38
|
+
this.onChildChange(null);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public override appendChild(child: WidgetNode): void {
|
|
43
|
+
const oldChildWidget = this.children[0]?.container ?? null;
|
|
44
|
+
super.appendChild(child);
|
|
45
|
+
|
|
46
|
+
if (this.parent) {
|
|
47
|
+
this.onChildChange(oldChildWidget);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public override removeChild(child: WidgetNode): void {
|
|
52
|
+
const oldChildWidget = child.container;
|
|
53
|
+
super.removeChild(child);
|
|
54
|
+
|
|
55
|
+
if (this.parent && oldChildWidget) {
|
|
56
|
+
this.onChildChange(oldChildWidget);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public override commitUpdate(oldProps: StackPageProps | null, newProps: StackPageProps): void {
|
|
61
|
+
super.commitUpdate(oldProps, newProps);
|
|
62
|
+
this.applyOwnProps(oldProps, newProps);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public override detachDeletedInstance(): void {
|
|
66
|
+
const childWidget = this.children[0]?.container ?? null;
|
|
67
|
+
if (childWidget && this.parent) {
|
|
68
|
+
this.removePage(childWidget);
|
|
69
|
+
}
|
|
70
|
+
this.page = null;
|
|
71
|
+
super.detachDeletedInstance();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private getChildWidget(): Gtk.Widget {
|
|
75
|
+
const child = this.children[0];
|
|
76
|
+
if (!child) {
|
|
77
|
+
throw new Error("Expected child widget to be set on StackPageNode");
|
|
78
|
+
}
|
|
79
|
+
return child.container;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private getParentWidget(): StackWidget {
|
|
83
|
+
if (!this.parent) {
|
|
84
|
+
throw new Error("Expected parent widget to be set on StackPageNode");
|
|
85
|
+
}
|
|
86
|
+
return this.parent.container;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private applyOwnProps(oldProps: StackPageProps | null, newProps: StackPageProps): void {
|
|
90
|
+
if (!this.page) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (hasChanged(oldProps, newProps, "title") && newProps.title !== undefined) {
|
|
95
|
+
this.page.setTitle(newProps.title);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (hasChanged(oldProps, newProps, "iconName") && newProps.iconName !== undefined) {
|
|
99
|
+
this.page.setIconName(newProps.iconName);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (hasChanged(oldProps, newProps, "needsAttention")) {
|
|
103
|
+
this.page.setNeedsAttention(newProps.needsAttention ?? false);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (hasChanged(oldProps, newProps, "visible")) {
|
|
107
|
+
this.page.setVisible(newProps.visible ?? true);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (hasChanged(oldProps, newProps, "useUnderline")) {
|
|
111
|
+
this.page.setUseUnderline(newProps.useUnderline ?? false);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if ("setBadgeNumber" in this.page && hasChanged(oldProps, newProps, "badgeNumber")) {
|
|
115
|
+
this.page.setBadgeNumber?.(newProps.badgeNumber ?? 0);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private onChildChange(oldChild: Gtk.Widget | null): void {
|
|
120
|
+
this.removePage(oldChild);
|
|
121
|
+
|
|
122
|
+
if (this.children[0]) {
|
|
123
|
+
this.addPage();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private addPage(): void {
|
|
128
|
+
const child = this.getChildWidget();
|
|
129
|
+
const parent = this.getParentWidget();
|
|
130
|
+
|
|
131
|
+
let page: Gtk.StackPage | Adw.ViewStackPage;
|
|
132
|
+
|
|
133
|
+
if (parent instanceof Adw.ViewStack) {
|
|
134
|
+
if (this.props.title && this.props.iconName) {
|
|
135
|
+
page = parent.addTitledWithIcon(child, this.props.title, this.props.iconName, this.props.id);
|
|
136
|
+
} else if (this.props.title) {
|
|
137
|
+
page = parent.addTitled(child, this.props.title, this.props.id);
|
|
138
|
+
} else if (this.props.id) {
|
|
139
|
+
page = parent.addNamed(child, this.props.id);
|
|
140
|
+
} else {
|
|
141
|
+
page = parent.add(child);
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
if (this.props.title) {
|
|
145
|
+
page = parent.addTitled(child, this.props.title, this.props.id);
|
|
146
|
+
} else if (this.props.id) {
|
|
147
|
+
page = parent.addNamed(child, this.props.id);
|
|
148
|
+
} else {
|
|
149
|
+
page = parent.addChild(child);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
this.page = page;
|
|
154
|
+
this.commitUpdate(null, this.props);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private removePage(oldChild: Gtk.Widget | null): void {
|
|
158
|
+
const parent = this.getParentWidget();
|
|
159
|
+
|
|
160
|
+
if (!oldChild) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const currentParent = oldChild.getParent();
|
|
165
|
+
|
|
166
|
+
if (currentParent && currentParent === parent) {
|
|
167
|
+
parent.remove(oldChild);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AdwViewStackProps, GtkStackProps } from "../jsx.js";
|
|
2
|
+
import type { StackWidget } from "../registry.js";
|
|
3
|
+
import { filterProps, hasChanged } from "./internal/props.js";
|
|
4
|
+
import { WidgetNode } from "./widget.js";
|
|
5
|
+
|
|
6
|
+
const OWN_PROPS = ["page", "onPageChanged"] as const;
|
|
7
|
+
|
|
8
|
+
type StackProps = Omit<Pick<GtkStackProps | AdwViewStackProps, (typeof OWN_PROPS)[number]>, "onPageChanged"> & {
|
|
9
|
+
onPageChanged?: ((page: string | null, self: StackWidget) => void) | null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export class StackNode extends WidgetNode<StackWidget, StackProps> {
|
|
13
|
+
public override commitUpdate(oldProps: StackProps | null, newProps: StackProps): void {
|
|
14
|
+
super.commitUpdate(oldProps ? filterProps(oldProps, OWN_PROPS) : null, filterProps(newProps, OWN_PROPS));
|
|
15
|
+
this.applyOwnProps(oldProps, newProps);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private applyOwnProps(oldProps: StackProps | null, newProps: StackProps): void {
|
|
19
|
+
if (newProps.page && this.container.getVisibleChildName() !== newProps.page) {
|
|
20
|
+
if (this.container.getChildByName(newProps.page)) {
|
|
21
|
+
this.container.setVisibleChildName(newProps.page);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (hasChanged(oldProps, newProps, "onPageChanged")) {
|
|
26
|
+
const { onPageChanged } = newProps;
|
|
27
|
+
this.signalStore.set(
|
|
28
|
+
this,
|
|
29
|
+
this.container,
|
|
30
|
+
"notify::visible-child-name",
|
|
31
|
+
onPageChanged ? (self: StackWidget) => onPageChanged(self.getVisibleChildName(), self) : undefined,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import type { TextAnchorProps } from "../jsx.js";
|
|
3
|
+
import type { Node } from "../node.js";
|
|
4
|
+
import { TEXT_OBJECT_REPLACEMENT, type TextContentParent } from "./text-content.js";
|
|
5
|
+
import { isTextContentParent } from "./text-segment.js";
|
|
6
|
+
import { VirtualNode } from "./virtual.js";
|
|
7
|
+
import { WidgetNode } from "./widget.js";
|
|
8
|
+
|
|
9
|
+
export class TextAnchorNode extends VirtualNode<TextAnchorProps, Node & TextContentParent, WidgetNode> {
|
|
10
|
+
private textView: Gtk.TextView | null = null;
|
|
11
|
+
private buffer: Gtk.TextBuffer | null = null;
|
|
12
|
+
private anchor: Gtk.TextChildAnchor | null = null;
|
|
13
|
+
|
|
14
|
+
private bufferOffset = 0;
|
|
15
|
+
|
|
16
|
+
public getBufferOffset(): number {
|
|
17
|
+
return this.bufferOffset;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public setBufferOffset(offset: number): void {
|
|
21
|
+
this.bufferOffset = offset;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public override isValidChild(child: Node): boolean {
|
|
25
|
+
return child instanceof WidgetNode;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public override isValidParent(parent: Node): boolean {
|
|
29
|
+
return isTextContentParent(parent);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public getLength(): number {
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public getText(): string {
|
|
37
|
+
return TEXT_OBJECT_REPLACEMENT;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public setTextViewAndBuffer(textView: Gtk.TextView, buffer: Gtk.TextBuffer): void {
|
|
41
|
+
this.textView = textView;
|
|
42
|
+
this.buffer = buffer;
|
|
43
|
+
this.setupAnchor();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private setupAnchor(): void {
|
|
47
|
+
if (!this.textView || !this.buffer) return;
|
|
48
|
+
|
|
49
|
+
const iter = new Gtk.TextIter();
|
|
50
|
+
this.buffer.getIterAtOffset(iter, this.bufferOffset);
|
|
51
|
+
|
|
52
|
+
this.anchor = this.buffer.createChildAnchor(iter);
|
|
53
|
+
|
|
54
|
+
const widgetChild = this.children[0];
|
|
55
|
+
if (widgetChild?.container && this.anchor) {
|
|
56
|
+
this.textView.addChildAtAnchor(widgetChild.container, this.anchor);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public override appendChild(child: WidgetNode): void {
|
|
61
|
+
super.appendChild(child);
|
|
62
|
+
|
|
63
|
+
if (this.textView && this.anchor && child.container) {
|
|
64
|
+
this.textView.addChildAtAnchor(child.container, this.anchor);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public override detachDeletedInstance(): void {
|
|
69
|
+
this.anchor = null;
|
|
70
|
+
this.buffer = null;
|
|
71
|
+
this.textView = null;
|
|
72
|
+
super.detachDeletedInstance();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
|
|
6
|
+
export const TEXT_OBJECT_REPLACEMENT = "\uFFFC";
|
|
7
|
+
|
|
8
|
+
export type TextContentChild = TextSegmentNode | TextTagNode | TextAnchorNode | TextPaintableNode;
|
|
9
|
+
|
|
10
|
+
export type TextContentParent = {
|
|
11
|
+
onChildInserted(child: TextContentChild): void;
|
|
12
|
+
onChildRemoved(child: TextContentChild): void;
|
|
13
|
+
onChildTextChanged(child: TextSegmentNode, oldLength: number, newLength: number): void;
|
|
14
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import type { TextPaintableProps } from "../jsx.js";
|
|
3
|
+
import type { Node } from "../node.js";
|
|
4
|
+
import { TEXT_OBJECT_REPLACEMENT, type TextContentParent } from "./text-content.js";
|
|
5
|
+
import { isTextContentParent } from "./text-segment.js";
|
|
6
|
+
import { VirtualNode } from "./virtual.js";
|
|
7
|
+
|
|
8
|
+
export class TextPaintableNode extends VirtualNode<TextPaintableProps, Node & TextContentParent, never> {
|
|
9
|
+
public override isValidChild(_child: Node): boolean {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public override isValidParent(parent: Node): boolean {
|
|
14
|
+
return isTextContentParent(parent);
|
|
15
|
+
}
|
|
16
|
+
private buffer: Gtk.TextBuffer | null = null;
|
|
17
|
+
private bufferOffset = 0;
|
|
18
|
+
|
|
19
|
+
public getBufferOffset(): number {
|
|
20
|
+
return this.bufferOffset;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public setBufferOffset(offset: number): void {
|
|
24
|
+
this.bufferOffset = offset;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public getLength(): number {
|
|
28
|
+
return 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public getText(): string {
|
|
32
|
+
return TEXT_OBJECT_REPLACEMENT;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public setTextViewAndBuffer(_textView: Gtk.TextView, buffer: Gtk.TextBuffer): void {
|
|
36
|
+
this.buffer = buffer;
|
|
37
|
+
this.insertPaintable();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private insertPaintable(): void {
|
|
41
|
+
if (!this.buffer || !this.props.paintable) return;
|
|
42
|
+
const iter = new Gtk.TextIter();
|
|
43
|
+
this.buffer.getIterAtOffset(iter, this.bufferOffset);
|
|
44
|
+
this.buffer.insertPaintable(iter, this.props.paintable);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public override detachDeletedInstance(): void {
|
|
48
|
+
this.buffer = null;
|
|
49
|
+
super.detachDeletedInstance();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { TextSegmentProps } from "../jsx.js";
|
|
2
|
+
import type { Node } from "../node.js";
|
|
3
|
+
import { hasChanged } from "./internal/props.js";
|
|
4
|
+
import type { TextContentParent } from "./text-content.js";
|
|
5
|
+
import { VirtualNode } from "./virtual.js";
|
|
6
|
+
|
|
7
|
+
type TextSegmentParent = Node & TextContentParent;
|
|
8
|
+
|
|
9
|
+
export class TextSegmentNode extends VirtualNode<TextSegmentProps, TextSegmentParent, never> {
|
|
10
|
+
private bufferOffset = 0;
|
|
11
|
+
|
|
12
|
+
public getBufferOffset(): number {
|
|
13
|
+
return this.bufferOffset;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public setBufferOffset(offset: number): void {
|
|
17
|
+
this.bufferOffset = offset;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public override isValidChild(_child: Node): boolean {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public override isValidParent(parent: Node): boolean {
|
|
25
|
+
return isTextContentParent(parent);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public getText(): string {
|
|
29
|
+
return this.props.text;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public getLength(): number {
|
|
33
|
+
return this.props.text.length;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public override commitUpdate(oldProps: TextSegmentProps | null, newProps: TextSegmentProps): void {
|
|
37
|
+
const oldText = oldProps?.text ?? "";
|
|
38
|
+
const newText = newProps.text;
|
|
39
|
+
|
|
40
|
+
super.commitUpdate(oldProps, newProps);
|
|
41
|
+
|
|
42
|
+
if (hasChanged(oldProps, newProps, "text") && this.parent) {
|
|
43
|
+
this.parent.onChildTextChanged(this, oldText.length, newText.length);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function isTextContentParent(node: Node): node is TextSegmentParent {
|
|
49
|
+
const candidate = node as unknown as TextContentParent;
|
|
50
|
+
return (
|
|
51
|
+
typeof candidate.onChildInserted === "function" &&
|
|
52
|
+
typeof candidate.onChildRemoved === "function" &&
|
|
53
|
+
typeof candidate.onChildTextChanged === "function"
|
|
54
|
+
);
|
|
55
|
+
}
|