@gtkx/react 0.19.0 → 0.20.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/dist/components/list.d.ts +35 -0
- package/dist/components/list.d.ts.map +1 -0
- package/dist/components/list.js +40 -0
- package/dist/components/list.js.map +1 -0
- package/dist/generated/internal.d.ts +5 -6
- package/dist/generated/internal.d.ts.map +1 -1
- package/dist/generated/internal.js +3473 -260
- package/dist/generated/internal.js.map +1 -1
- package/dist/generated/jsx.d.ts +0 -324
- package/dist/generated/jsx.d.ts.map +1 -1
- package/dist/generated/jsx.js +0 -324
- package/dist/generated/jsx.js.map +1 -1
- package/dist/host-config.d.ts.map +1 -1
- package/dist/host-config.js +2 -0
- package/dist/host-config.js.map +1 -1
- package/dist/jsx.d.ts +42 -105
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +2 -66
- package/dist/jsx.js.map +1 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +7 -3
- package/dist/metadata.js.map +1 -1
- package/dist/node.d.ts +0 -4
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +19 -41
- package/dist/node.js.map +1 -1
- package/dist/nodes/application.d.ts.map +1 -1
- package/dist/nodes/application.js +4 -0
- package/dist/nodes/application.js.map +1 -1
- package/dist/nodes/column-view-column.d.ts +19 -19
- package/dist/nodes/column-view-column.d.ts.map +1 -1
- package/dist/nodes/column-view-column.js +130 -119
- package/dist/nodes/column-view-column.js.map +1 -1
- package/dist/nodes/event-controller.d.ts.map +1 -1
- package/dist/nodes/event-controller.js +3 -9
- package/dist/nodes/event-controller.js.map +1 -1
- package/dist/nodes/internal/accessible.d.ts.map +1 -1
- package/dist/nodes/internal/accessible.js.map +1 -1
- package/dist/nodes/internal/bound-item.d.ts +4 -0
- package/dist/nodes/internal/bound-item.d.ts.map +1 -0
- package/dist/nodes/internal/bound-item.js +2 -0
- package/dist/nodes/internal/bound-item.js.map +1 -0
- package/dist/nodes/internal/construct.d.ts +1 -8
- package/dist/nodes/internal/construct.d.ts.map +1 -1
- package/dist/nodes/internal/construct.js +30 -54
- package/dist/nodes/internal/construct.js.map +1 -1
- package/dist/nodes/internal/widget.d.ts.map +1 -1
- package/dist/nodes/internal/widget.js +4 -1
- package/dist/nodes/internal/widget.js.map +1 -1
- package/dist/nodes/list-item-node.d.ts +12 -0
- package/dist/nodes/list-item-node.d.ts.map +1 -0
- package/dist/nodes/list-item-node.js +23 -0
- package/dist/nodes/list-item-node.js.map +1 -0
- package/dist/nodes/list.d.ts +100 -0
- package/dist/nodes/list.d.ts.map +1 -0
- package/dist/nodes/list.js +950 -0
- package/dist/nodes/list.js.map +1 -0
- package/dist/nodes/notebook-page.d.ts.map +1 -1
- package/dist/nodes/notebook-page.js +4 -0
- package/dist/nodes/notebook-page.js.map +1 -1
- package/dist/nodes/widget.d.ts.map +1 -1
- package/dist/nodes/widget.js +9 -8
- package/dist/nodes/widget.js.map +1 -1
- package/dist/nodes/window.d.ts.map +1 -1
- package/dist/nodes/window.js +2 -2
- package/dist/nodes/window.js.map +1 -1
- package/dist/registry.d.ts +0 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -13
- package/dist/registry.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/components/list.tsx +83 -0
- package/src/generated/internal.ts +3479 -258
- package/src/generated/jsx.ts +0 -324
- package/src/host-config.ts +2 -0
- package/src/jsx.ts +49 -141
- package/src/metadata.ts +6 -3
- package/src/node.ts +23 -39
- package/src/nodes/application.ts +5 -0
- package/src/nodes/column-view-column.ts +125 -128
- package/src/nodes/event-controller.ts +3 -11
- package/src/nodes/internal/accessible.ts +0 -1
- package/src/nodes/internal/bound-item.ts +4 -0
- package/src/nodes/internal/construct.ts +38 -68
- package/src/nodes/internal/widget.ts +3 -1
- package/src/nodes/list-item-node.ts +29 -0
- package/src/nodes/list.ts +1082 -0
- package/src/nodes/notebook-page.ts +4 -0
- package/src/nodes/widget.ts +8 -13
- package/src/nodes/window.ts +2 -2
- package/src/registry.ts +11 -19
- package/src/types.ts +7 -2
- package/dist/fiber-root.d.ts +0 -4
- package/dist/fiber-root.d.ts.map +0 -1
- package/dist/fiber-root.js +0 -6
- package/dist/fiber-root.js.map +0 -1
- package/dist/nodes/column-view.d.ts +0 -37
- package/dist/nodes/column-view.d.ts.map +0 -1
- package/dist/nodes/column-view.js +0 -205
- package/dist/nodes/column-view.js.map +0 -1
- package/dist/nodes/drop-down.d.ts +0 -37
- package/dist/nodes/drop-down.d.ts.map +0 -1
- package/dist/nodes/drop-down.js +0 -231
- package/dist/nodes/drop-down.js.map +0 -1
- package/dist/nodes/grid-view.d.ts +0 -30
- package/dist/nodes/grid-view.d.ts.map +0 -1
- package/dist/nodes/grid-view.js +0 -90
- package/dist/nodes/grid-view.js.map +0 -1
- package/dist/nodes/internal/base-item-renderer.d.ts +0 -28
- package/dist/nodes/internal/base-item-renderer.d.ts.map +0 -1
- package/dist/nodes/internal/base-item-renderer.js +0 -85
- package/dist/nodes/internal/base-item-renderer.js.map +0 -1
- package/dist/nodes/internal/grid-item-renderer.d.ts +0 -20
- package/dist/nodes/internal/grid-item-renderer.d.ts.map +0 -1
- package/dist/nodes/internal/grid-item-renderer.js +0 -66
- package/dist/nodes/internal/grid-item-renderer.js.map +0 -1
- package/dist/nodes/internal/header-item-renderer.d.ts +0 -23
- package/dist/nodes/internal/header-item-renderer.d.ts.map +0 -1
- package/dist/nodes/internal/header-item-renderer.js +0 -87
- package/dist/nodes/internal/header-item-renderer.js.map +0 -1
- package/dist/nodes/internal/header-renderer-manager.d.ts +0 -13
- package/dist/nodes/internal/header-renderer-manager.d.ts.map +0 -1
- package/dist/nodes/internal/header-renderer-manager.js +0 -20
- package/dist/nodes/internal/header-renderer-manager.js.map +0 -1
- package/dist/nodes/internal/list-item-renderer.d.ts +0 -27
- package/dist/nodes/internal/list-item-renderer.d.ts.map +0 -1
- package/dist/nodes/internal/list-item-renderer.js +0 -131
- package/dist/nodes/internal/list-item-renderer.js.map +0 -1
- package/dist/nodes/internal/list-store.d.ts +0 -21
- package/dist/nodes/internal/list-store.d.ts.map +0 -1
- package/dist/nodes/internal/list-store.js +0 -90
- package/dist/nodes/internal/list-store.js.map +0 -1
- package/dist/nodes/internal/sectioned-list-store.d.ts +0 -50
- package/dist/nodes/internal/sectioned-list-store.d.ts.map +0 -1
- package/dist/nodes/internal/sectioned-list-store.js +0 -250
- package/dist/nodes/internal/sectioned-list-store.js.map +0 -1
- package/dist/nodes/internal/selection-helpers.d.ts +0 -12
- package/dist/nodes/internal/selection-helpers.d.ts.map +0 -1
- package/dist/nodes/internal/selection-helpers.js +0 -25
- package/dist/nodes/internal/selection-helpers.js.map +0 -1
- package/dist/nodes/internal/selection-model-controller.d.ts +0 -26
- package/dist/nodes/internal/selection-model-controller.d.ts.map +0 -1
- package/dist/nodes/internal/selection-model-controller.js +0 -82
- package/dist/nodes/internal/selection-model-controller.js.map +0 -1
- package/dist/nodes/internal/simple-list-store.d.ts +0 -15
- package/dist/nodes/internal/simple-list-store.d.ts.map +0 -1
- package/dist/nodes/internal/simple-list-store.js +0 -110
- package/dist/nodes/internal/simple-list-store.js.map +0 -1
- package/dist/nodes/internal/tree-store.d.ts +0 -37
- package/dist/nodes/internal/tree-store.d.ts.map +0 -1
- package/dist/nodes/internal/tree-store.js +0 -253
- package/dist/nodes/internal/tree-store.js.map +0 -1
- package/dist/nodes/list-item.d.ts +0 -24
- package/dist/nodes/list-item.d.ts.map +0 -1
- package/dist/nodes/list-item.js +0 -83
- package/dist/nodes/list-item.js.map +0 -1
- package/dist/nodes/list-section.d.ts +0 -27
- package/dist/nodes/list-section.d.ts.map +0 -1
- package/dist/nodes/list-section.js +0 -43
- package/dist/nodes/list-section.js.map +0 -1
- package/dist/nodes/list-view.d.ts +0 -32
- package/dist/nodes/list-view.d.ts.map +0 -1
- package/dist/nodes/list-view.js +0 -123
- package/dist/nodes/list-view.js.map +0 -1
- package/dist/nodes/models/list.d.ts +0 -39
- package/dist/nodes/models/list.d.ts.map +0 -1
- package/dist/nodes/models/list.js +0 -207
- package/dist/nodes/models/list.js.map +0 -1
- package/src/fiber-root.ts +0 -20
- package/src/nodes/column-view.ts +0 -262
- package/src/nodes/drop-down.ts +0 -284
- package/src/nodes/grid-view.ts +0 -119
- package/src/nodes/internal/base-item-renderer.ts +0 -107
- package/src/nodes/internal/grid-item-renderer.ts +0 -78
- package/src/nodes/internal/header-item-renderer.ts +0 -105
- package/src/nodes/internal/header-renderer-manager.ts +0 -33
- package/src/nodes/internal/list-item-renderer.ts +0 -162
- package/src/nodes/internal/list-store.ts +0 -107
- package/src/nodes/internal/sectioned-list-store.ts +0 -287
- package/src/nodes/internal/selection-helpers.ts +0 -35
- package/src/nodes/internal/selection-model-controller.ts +0 -119
- package/src/nodes/internal/simple-list-store.ts +0 -116
- package/src/nodes/internal/tree-store.ts +0 -289
- package/src/nodes/list-item.ts +0 -107
- package/src/nodes/list-section.ts +0 -64
- package/src/nodes/list-view.ts +0 -164
- package/src/nodes/models/list.ts +0 -250
package/src/node.ts
CHANGED
|
@@ -14,8 +14,6 @@ export class Node<TContainer = any, TProps = any, TParent extends Node = any, TC
|
|
|
14
14
|
rootContainer: Container;
|
|
15
15
|
parent: TParent | null = null;
|
|
16
16
|
children: TChild[] = [];
|
|
17
|
-
private childIndices = new Map<TChild, number>();
|
|
18
|
-
private childrenDirty = false;
|
|
19
17
|
|
|
20
18
|
constructor(typeName: string, props: TProps, container: TContainer, rootContainer: Container) {
|
|
21
19
|
this.typeName = typeName;
|
|
@@ -37,6 +35,7 @@ export class Node<TContainer = any, TProps = any, TParent extends Node = any, TC
|
|
|
37
35
|
if (parent !== null && !this.isValidParent(parent)) {
|
|
38
36
|
throw new Error(`Cannot add '${this.typeName}' to '${parent.typeName}'`);
|
|
39
37
|
}
|
|
38
|
+
|
|
40
39
|
this.parent = parent;
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -45,64 +44,49 @@ export class Node<TContainer = any, TProps = any, TParent extends Node = any, TC
|
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
public appendChild(child: TChild): void {
|
|
48
|
-
if (this.childrenDirty) this.flushChildRemovals();
|
|
49
47
|
if (!this.isValidChild(child)) {
|
|
50
48
|
throw new Error(`Cannot append '${child.typeName}' to '${this.typeName}'`);
|
|
51
49
|
}
|
|
52
|
-
|
|
50
|
+
|
|
51
|
+
const existingIndex = this.children.indexOf(child);
|
|
52
|
+
if (existingIndex !== -1) {
|
|
53
|
+
this.children.splice(existingIndex, 1);
|
|
54
|
+
}
|
|
53
55
|
this.children.push(child);
|
|
54
|
-
|
|
56
|
+
|
|
57
|
+
if (child.parent !== this) {
|
|
58
|
+
child.setParent(this);
|
|
59
|
+
}
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
public removeChild(child: TChild): void {
|
|
58
|
-
if (!this.childIndices.has(child)) return;
|
|
59
63
|
child.setParent(null);
|
|
60
|
-
this.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
const index = this.children.indexOf(child);
|
|
65
|
+
|
|
66
|
+
if (index !== -1) {
|
|
67
|
+
this.children.splice(index, 1);
|
|
64
68
|
}
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
public insertBefore(child: TChild, before: TChild): void {
|
|
68
|
-
if (this.
|
|
69
|
-
|
|
70
|
-
const beforeIndex = this.childIndices.get(before);
|
|
71
|
-
if (beforeIndex === undefined) {
|
|
72
|
-
throw new Error(`Cannot find 'before' child '${before.typeName}' in '${this.typeName}'`);
|
|
72
|
+
if (!this.isValidChild(child)) {
|
|
73
|
+
throw new Error(`Cannot insert '${child.typeName}' into '${this.typeName}'`);
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
const existingIndex = this.
|
|
76
|
-
if (existingIndex !==
|
|
76
|
+
const existingIndex = this.children.indexOf(child);
|
|
77
|
+
if (existingIndex !== -1) {
|
|
77
78
|
this.children.splice(existingIndex, 1);
|
|
78
|
-
const adjustedIndex = existingIndex < beforeIndex ? beforeIndex - 1 : beforeIndex;
|
|
79
|
-
this.children.splice(adjustedIndex, 0, child);
|
|
80
|
-
this.rebuildChildIndices(Math.min(existingIndex, adjustedIndex));
|
|
81
|
-
return;
|
|
82
79
|
}
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
const beforeIndex = this.children.indexOf(before);
|
|
82
|
+
if (beforeIndex === -1) {
|
|
83
|
+
throw new Error(`Cannot find 'before' child '${before.typeName}' in '${this.typeName}'`);
|
|
86
84
|
}
|
|
87
85
|
|
|
88
86
|
this.children.splice(beforeIndex, 0, child);
|
|
89
|
-
this.rebuildChildIndices(beforeIndex);
|
|
90
|
-
child.setParent(this);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
private flushChildRemovals(): void {
|
|
94
|
-
if (!this.childrenDirty) return;
|
|
95
|
-
this.childrenDirty = false;
|
|
96
|
-
this.children = this.children.filter((c) => this.childIndices.has(c));
|
|
97
|
-
this.childIndices.clear();
|
|
98
|
-
for (let i = 0; i < this.children.length; i++) {
|
|
99
|
-
this.childIndices.set(this.children[i] as TChild, i);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
87
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.childIndices.set(this.children[i] as TChild, i);
|
|
88
|
+
if (child.parent !== this) {
|
|
89
|
+
child.setParent(this);
|
|
106
90
|
}
|
|
107
91
|
}
|
|
108
92
|
|
package/src/nodes/application.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Node } from "../node.js";
|
|
|
3
3
|
import type { Container, Props } from "../types.js";
|
|
4
4
|
import { MenuNode } from "./menu.js";
|
|
5
5
|
import { MenuModel } from "./models/menu.js";
|
|
6
|
+
import { WindowNode } from "./window.js";
|
|
6
7
|
|
|
7
8
|
export class ApplicationNode extends Node<Gtk.Application, Props, Node, Node> {
|
|
8
9
|
private menu: MenuModel;
|
|
@@ -51,6 +52,10 @@ export class ApplicationNode extends Node<Gtk.Application, Props, Node, Node> {
|
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
if (child instanceof WindowNode) {
|
|
56
|
+
child.container.setVisible(false);
|
|
57
|
+
}
|
|
58
|
+
|
|
54
59
|
super.removeChild(child);
|
|
55
60
|
}
|
|
56
61
|
}
|
|
@@ -1,19 +1,34 @@
|
|
|
1
|
+
import { getNativeId } from "@gtkx/ffi";
|
|
1
2
|
import * as Gio from "@gtkx/ffi/gio";
|
|
3
|
+
import type * as GObject from "@gtkx/ffi/gobject";
|
|
2
4
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
3
|
-
import type { ColumnViewColumnProps } from "../jsx.js";
|
|
5
|
+
import type { ColumnViewColumnProps, ListItem } from "../jsx.js";
|
|
4
6
|
import type { Node } from "../node.js";
|
|
5
7
|
import type { Container } from "../types.js";
|
|
6
|
-
import {
|
|
7
|
-
import { ListItemRenderer } from "./internal/list-item-renderer.js";
|
|
8
|
-
import type { ListStore } from "./internal/list-store.js";
|
|
8
|
+
import type { BoundItem } from "./internal/bound-item.js";
|
|
9
9
|
import { hasChanged } from "./internal/props.js";
|
|
10
|
-
import type { TreeStore } from "./internal/tree-store.js";
|
|
11
10
|
import { MenuNode } from "./menu.js";
|
|
12
11
|
import { MenuModel } from "./models/menu.js";
|
|
13
12
|
import { VirtualNode } from "./virtual.js";
|
|
14
13
|
import { WidgetNode } from "./widget.js";
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
const UNBOUND_POSITION = -1;
|
|
16
|
+
|
|
17
|
+
export class ColumnViewColumnNode extends VirtualNode<ColumnViewColumnProps, WidgetNode, MenuNode> {
|
|
18
|
+
private column: Gtk.ColumnViewColumn | null = null;
|
|
19
|
+
private columnFactory: Gtk.SignalListItemFactory | null = null;
|
|
20
|
+
private containers = new Map<Gtk.ListItem, number>();
|
|
21
|
+
private containerKeys = new Map<Gtk.ListItem, string>();
|
|
22
|
+
private menu: MenuModel;
|
|
23
|
+
private actionGroup: Gio.SimpleActionGroup;
|
|
24
|
+
|
|
25
|
+
constructor(typeName: string, props: ColumnViewColumnProps, container: undefined, rootContainer: Container) {
|
|
26
|
+
super(typeName, props, container, rootContainer);
|
|
27
|
+
this.actionGroup = new Gio.SimpleActionGroup();
|
|
28
|
+
this.menu = new MenuModel("root", {}, rootContainer, this.actionGroup);
|
|
29
|
+
this.menu.setActionMap(this.actionGroup, props.id);
|
|
30
|
+
}
|
|
31
|
+
|
|
17
32
|
public override isValidChild(child: Node): boolean {
|
|
18
33
|
return child instanceof MenuNode;
|
|
19
34
|
}
|
|
@@ -21,172 +36,154 @@ export class ColumnViewColumnNode extends VirtualNode<ColumnViewColumnProps, Wid
|
|
|
21
36
|
public override isValidParent(parent: Node): boolean {
|
|
22
37
|
return parent instanceof WidgetNode && parent.container instanceof Gtk.ColumnView;
|
|
23
38
|
}
|
|
24
|
-
private column: Gtk.ColumnViewColumn;
|
|
25
|
-
private treeRenderer: ListItemRenderer | null;
|
|
26
|
-
private flatRenderer: GridItemRenderer | null = null;
|
|
27
|
-
private menu: MenuModel | null = null;
|
|
28
|
-
private actionGroup: Gio.SimpleActionGroup | null = null;
|
|
29
|
-
private columnView: Gtk.ColumnView | null = null;
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
|
|
40
|
+
public override finalizeInitialChildren(props: ColumnViewColumnProps): boolean {
|
|
41
|
+
this.setupFactory();
|
|
42
|
+
this.setupColumn(props);
|
|
43
|
+
this.updateHeaderMenu();
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public override commitUpdate(oldProps: ColumnViewColumnProps | null, newProps: ColumnViewColumnProps): void {
|
|
48
|
+
super.commitUpdate(oldProps, newProps);
|
|
49
|
+
if (oldProps === null) return;
|
|
50
|
+
this.applyColumnProps(oldProps, newProps);
|
|
36
51
|
}
|
|
37
52
|
|
|
38
53
|
public override appendChild(child: MenuNode): void {
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
54
|
+
this.menu.appendChild(child);
|
|
55
|
+
this.updateHeaderMenu();
|
|
41
56
|
}
|
|
42
57
|
|
|
43
58
|
public override insertBefore(child: MenuNode, before: MenuNode): void {
|
|
44
|
-
this.
|
|
45
|
-
|
|
46
|
-
this.menu?.insertBefore(child, before);
|
|
47
|
-
} else {
|
|
48
|
-
this.menu?.appendChild(child);
|
|
49
|
-
}
|
|
59
|
+
this.menu.insertBefore(child, before);
|
|
60
|
+
this.updateHeaderMenu();
|
|
50
61
|
}
|
|
51
62
|
|
|
52
63
|
public override removeChild(child: MenuNode): void {
|
|
53
|
-
this.menu
|
|
54
|
-
|
|
55
|
-
if (this.menu && this.menu.getMenu().getNItems() === 0) {
|
|
56
|
-
this.cleanupMenu();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
public override commitUpdate(oldProps: ColumnViewColumnProps | null, newProps: ColumnViewColumnProps): void {
|
|
61
|
-
super.commitUpdate(oldProps, newProps);
|
|
62
|
-
this.applyOwnProps(oldProps, newProps);
|
|
64
|
+
this.menu.removeChild(child);
|
|
65
|
+
this.updateHeaderMenu();
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
public override detachDeletedInstance(): void {
|
|
66
|
-
this.cleanupMenu();
|
|
67
|
-
this.treeRenderer?.dispose();
|
|
68
|
-
this.flatRenderer?.dispose();
|
|
69
69
|
super.detachDeletedInstance();
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
public getColumn(): Gtk.ColumnViewColumn {
|
|
73
|
+
if (!this.column) throw new Error("ColumnViewColumn not initialized");
|
|
73
74
|
return this.column;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
public
|
|
77
|
-
this.
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
public setStore(model: TreeStore | null): void {
|
|
82
|
-
this.treeRenderer?.setStore(model);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
public setFlatStore(store: ListStore): void {
|
|
86
|
-
if (this.treeRenderer) {
|
|
87
|
-
this.treeRenderer.dispose();
|
|
88
|
-
this.treeRenderer = null;
|
|
89
|
-
}
|
|
90
|
-
if (!this.flatRenderer) {
|
|
91
|
-
this.flatRenderer = new GridItemRenderer(this.signalStore);
|
|
92
|
-
this.flatRenderer.setRenderFn(this.props.renderCell);
|
|
93
|
-
this.column.setFactory(this.flatRenderer.getFactory());
|
|
94
|
-
}
|
|
95
|
-
this.flatRenderer.setStore(store);
|
|
96
|
-
}
|
|
77
|
+
public collectBoundItems(flatItems: ListItem[]): BoundItem[] {
|
|
78
|
+
const { renderCell } = this.props;
|
|
79
|
+
if (!renderCell) return [];
|
|
97
80
|
|
|
98
|
-
|
|
99
|
-
this.treeRenderer?.setEstimatedItemHeight(height);
|
|
100
|
-
this.flatRenderer?.setEstimatedItemHeight(height);
|
|
101
|
-
}
|
|
81
|
+
const items: BoundItem[] = [];
|
|
102
82
|
|
|
103
|
-
|
|
104
|
-
|
|
83
|
+
for (const [container, position] of this.containers) {
|
|
84
|
+
if (position === UNBOUND_POSITION) continue;
|
|
105
85
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
}
|
|
86
|
+
const key = this.containerKeys.get(container);
|
|
87
|
+
if (!key) continue;
|
|
110
88
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
89
|
+
const item = flatItems[position];
|
|
90
|
+
if (!item) continue;
|
|
91
|
+
const content = renderCell(item.value);
|
|
92
|
+
items.push([content, container, key]);
|
|
114
93
|
}
|
|
115
94
|
|
|
116
|
-
|
|
95
|
+
return items;
|
|
117
96
|
}
|
|
118
97
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
this.actionGroup = new Gio.SimpleActionGroup();
|
|
123
|
-
this.menu = new MenuModel("root", {}, this.rootContainer);
|
|
124
|
-
this.menu.setActionMap(this.actionGroup, this.props.id);
|
|
125
|
-
this.column.setHeaderMenu(this.menu.getMenu());
|
|
98
|
+
public installActionGroup(widget: Gtk.Widget): void {
|
|
99
|
+
widget.insertActionGroup(this.props.id, this.actionGroup);
|
|
100
|
+
}
|
|
126
101
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
102
|
+
public uninstallActionGroup(widget: Gtk.Widget): void {
|
|
103
|
+
widget.insertActionGroup(this.props.id, null);
|
|
130
104
|
}
|
|
131
105
|
|
|
132
|
-
private
|
|
133
|
-
|
|
106
|
+
private setupFactory(): void {
|
|
107
|
+
this.columnFactory = new Gtk.SignalListItemFactory();
|
|
134
108
|
|
|
135
|
-
this.
|
|
109
|
+
this.columnFactory.connect("setup", (_self: GObject.Object, obj: GObject.Object) => {
|
|
110
|
+
const listItem = obj as unknown as Gtk.ListItem;
|
|
111
|
+
const key = String(getNativeId(listItem.handle));
|
|
112
|
+
const placeholder = new Gtk.Box();
|
|
113
|
+
const { width, height } = this.getParentEstimatedItemSize();
|
|
114
|
+
placeholder.setSizeRequest(width, height);
|
|
115
|
+
listItem.setChild(placeholder);
|
|
116
|
+
this.containers.set(listItem, UNBOUND_POSITION);
|
|
117
|
+
this.containerKeys.set(listItem, key);
|
|
118
|
+
});
|
|
136
119
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
120
|
+
this.columnFactory.connect("bind", (_self: GObject.Object, obj: GObject.Object) => {
|
|
121
|
+
const listItem = obj as unknown as Gtk.ListItem;
|
|
122
|
+
this.containers.set(listItem, listItem.getPosition());
|
|
123
|
+
this.scheduleParentUpdate();
|
|
124
|
+
});
|
|
140
125
|
|
|
141
|
-
this.
|
|
142
|
-
|
|
126
|
+
this.columnFactory.connect("unbind", (_self: GObject.Object, obj: GObject.Object) => {
|
|
127
|
+
const listItem = obj as unknown as Gtk.ListItem;
|
|
128
|
+
this.containers.set(listItem, UNBOUND_POSITION);
|
|
129
|
+
this.scheduleParentUpdate();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
this.columnFactory.connect("teardown", (_self: GObject.Object, obj: GObject.Object) => {
|
|
133
|
+
const listItem = obj as unknown as Gtk.ListItem;
|
|
134
|
+
this.containers.delete(listItem);
|
|
135
|
+
this.containerKeys.delete(listItem);
|
|
136
|
+
listItem.setChild(null);
|
|
137
|
+
});
|
|
143
138
|
}
|
|
144
139
|
|
|
145
|
-
private
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
this.flatRenderer?.setRenderFn(newProps.renderCell);
|
|
149
|
-
}
|
|
140
|
+
private setupColumn(props: ColumnViewColumnProps): void {
|
|
141
|
+
this.column = new Gtk.ColumnViewColumn(props.title, this.columnFactory);
|
|
142
|
+
this.column.setId(props.id);
|
|
150
143
|
|
|
151
|
-
if (
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
-
}
|
|
144
|
+
if (props.expand !== undefined) this.column.setExpand(props.expand);
|
|
145
|
+
if (props.resizable !== undefined) this.column.setResizable(props.resizable);
|
|
146
|
+
if (props.fixedWidth !== undefined) this.column.setFixedWidth(props.fixedWidth);
|
|
147
|
+
if (props.visible !== undefined) this.column.setVisible(props.visible);
|
|
148
|
+
if (props.sortable) this.column.setSorter(new Gtk.Sorter());
|
|
149
|
+
}
|
|
158
150
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
151
|
+
private applyColumnProps(oldProps: ColumnViewColumnProps, newProps: ColumnViewColumnProps): void {
|
|
152
|
+
if (!this.column) return;
|
|
162
153
|
|
|
163
|
-
if (hasChanged(oldProps, newProps, "
|
|
164
|
-
|
|
154
|
+
if (hasChanged(oldProps, newProps, "title")) this.column.setTitle(newProps.title);
|
|
155
|
+
if (hasChanged(oldProps, newProps, "expand")) this.column.setExpand(newProps.expand ?? false);
|
|
156
|
+
if (hasChanged(oldProps, newProps, "resizable")) this.column.setResizable(newProps.resizable ?? false);
|
|
157
|
+
if (hasChanged(oldProps, newProps, "fixedWidth")) this.column.setFixedWidth(newProps.fixedWidth ?? -1);
|
|
158
|
+
if (hasChanged(oldProps, newProps, "visible")) this.column.setVisible(newProps.visible ?? true);
|
|
159
|
+
if (hasChanged(oldProps, newProps, "sortable")) {
|
|
160
|
+
this.column.setSorter(newProps.sortable ? new Gtk.Sorter() : null);
|
|
165
161
|
}
|
|
162
|
+
if (hasChanged(oldProps, newProps, "renderCell")) this.scheduleParentUpdate();
|
|
163
|
+
}
|
|
166
164
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.column.setId(newProps.id);
|
|
174
|
-
|
|
175
|
-
if (oldProps && this.menu && this.actionGroup) {
|
|
176
|
-
this.menu.setActionMap(this.actionGroup, newProps.id);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
165
|
+
private updateHeaderMenu(): void {
|
|
166
|
+
if (!this.column) return;
|
|
167
|
+
const menu = this.menu.getMenu();
|
|
168
|
+
this.column.setHeaderMenu(menu.getNItems() > 0 ? menu : null);
|
|
169
|
+
}
|
|
179
170
|
|
|
180
|
-
|
|
181
|
-
|
|
171
|
+
private getParentEstimatedItemSize(): { width: number; height: number } {
|
|
172
|
+
if (this.parent && "getEstimatedItemSize" in this.parent) {
|
|
173
|
+
return (
|
|
174
|
+
this.parent as { getEstimatedItemSize(): { width: number; height: number } }
|
|
175
|
+
).getEstimatedItemSize();
|
|
182
176
|
}
|
|
177
|
+
return { width: -1, height: -1 };
|
|
178
|
+
}
|
|
183
179
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
180
|
+
private scheduleParentUpdate(): void {
|
|
181
|
+
if (
|
|
182
|
+
this.parent &&
|
|
183
|
+
"scheduleBoundItemsUpdate" in this.parent &&
|
|
184
|
+
typeof this.parent.scheduleBoundItemsUpdate === "function"
|
|
185
|
+
) {
|
|
186
|
+
(this.parent as { scheduleBoundItemsUpdate(): void }).scheduleBoundItemsUpdate();
|
|
190
187
|
}
|
|
191
188
|
}
|
|
192
189
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
-
import { CONSTRUCTOR_PROPS } from "../generated/internal.js";
|
|
3
2
|
import { isConstructOnlyProp, resolvePropMeta, resolveSignal } from "../metadata.js";
|
|
4
3
|
import { Node } from "../node.js";
|
|
5
4
|
import type { Props } from "../types.js";
|
|
6
|
-
import {
|
|
5
|
+
import { createContainerWithProperties } from "./internal/construct.js";
|
|
7
6
|
import type { SignalHandler } from "./internal/signal-store.js";
|
|
8
7
|
import { WidgetNode } from "./widget.js";
|
|
9
8
|
|
|
@@ -18,19 +17,12 @@ export class EventControllerNode<
|
|
|
18
17
|
props: Props,
|
|
19
18
|
containerClass: typeof Gtk.EventController,
|
|
20
19
|
): Gtk.EventController {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (typeName === "GtkDropTarget") {
|
|
20
|
+
if (containerClass.glibTypeName === "GtkDropTarget") {
|
|
24
21
|
const actions = (props.actions as number | undefined) ?? 0;
|
|
25
22
|
return new Gtk.DropTarget(G_TYPE_INVALID, actions);
|
|
26
23
|
}
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return createContainerWithConstructOnly(containerClass, props, () => {
|
|
31
|
-
// biome-ignore lint/suspicious/noExplicitAny: Dynamic constructor invocation
|
|
32
|
-
return new (containerClass as any)(...args);
|
|
33
|
-
}) as Gtk.EventController;
|
|
25
|
+
return createContainerWithProperties(containerClass, props) as Gtk.EventController;
|
|
34
26
|
}
|
|
35
27
|
|
|
36
28
|
public override isValidChild(child: Node): boolean {
|
|
@@ -29,7 +29,6 @@ const fromString: CreateValue = (val) => Value.newFromString(val as string);
|
|
|
29
29
|
const fromBoolean: CreateValue = (val) => Value.newFromBoolean(val as boolean);
|
|
30
30
|
const fromInt: CreateValue = (val) => Value.newFromInt(val as number);
|
|
31
31
|
const fromDouble: CreateValue = (val) => Value.newFromDouble(val as number);
|
|
32
|
-
|
|
33
32
|
const fromObject: CreateValue = (val) => Value.newFromObject((val as GObject.Object) ?? null);
|
|
34
33
|
|
|
35
34
|
const fromRefList: CreateValue = (val) => {
|
|
@@ -1,90 +1,60 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { NativeClass, Type } from "@gtkx/ffi";
|
|
2
|
+
import { Object as GObject, toValue, type Value } from "@gtkx/ffi/gobject";
|
|
3
|
+
import { CONSTRUCTION_META } from "../../generated/internal.js";
|
|
4
4
|
import type { Container, ContainerClass, Props } from "../../types.js";
|
|
5
5
|
|
|
6
|
-
type
|
|
6
|
+
type ConstructionPropMeta = {
|
|
7
|
+
girName: string;
|
|
8
|
+
ffiType: Type;
|
|
9
|
+
constructOnly?: true;
|
|
10
|
+
};
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
* Collects construct-only property metadata by walking the class hierarchy.
|
|
10
|
-
* Returns all active construct-only props (those with values set in the initial props)
|
|
11
|
-
* that are NOT already handled by the designated constructor parameters.
|
|
12
|
-
*/
|
|
13
|
-
function collectActiveConstructOnlyProps(
|
|
12
|
+
function collectConstructionProps(
|
|
14
13
|
containerClass: ContainerClass,
|
|
15
14
|
props: Props,
|
|
16
15
|
): Array<{ girName: string; ffiType: Type; value: unknown }> {
|
|
17
16
|
const result: Array<{ girName: string; ffiType: Type; value: unknown }> = [];
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
// biome-ignore lint/
|
|
21
|
-
let current:
|
|
22
|
-
while (current
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
const seen = new Set<string>();
|
|
18
|
+
|
|
19
|
+
// biome-ignore lint/complexity/noBannedTypes: Walking prototype chain requires Function type
|
|
20
|
+
let current: Function | null = containerClass;
|
|
21
|
+
while (current) {
|
|
22
|
+
const typeName = (current as NativeClass).glibTypeName;
|
|
23
|
+
if (!typeName) break;
|
|
24
|
+
|
|
25
|
+
const meta: Record<string, ConstructionPropMeta> | undefined = CONSTRUCTION_META[typeName];
|
|
26
|
+
if (meta) {
|
|
27
|
+
for (const [camelName, propMeta] of Object.entries(meta)) {
|
|
28
|
+
if (seen.has(camelName)) continue;
|
|
29
|
+
seen.add(camelName);
|
|
28
30
|
if (props[camelName] !== undefined) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"handle" in rawValue
|
|
35
|
-
? (rawValue as { handle: NativeHandle }).handle
|
|
36
|
-
: rawValue;
|
|
37
|
-
result.push({ girName: meta.girName, ffiType: meta.ffiType, value });
|
|
31
|
+
result.push({
|
|
32
|
+
girName: propMeta.girName,
|
|
33
|
+
ffiType: propMeta.ffiType,
|
|
34
|
+
value: props[camelName],
|
|
35
|
+
});
|
|
38
36
|
}
|
|
39
37
|
}
|
|
40
38
|
}
|
|
39
|
+
|
|
41
40
|
current = Object.getPrototypeOf(current);
|
|
41
|
+
if (current === Object || current === Function) break;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
return result;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
* When construct-only props are present that aren't handled by the designated
|
|
51
|
-
* constructor, uses `g_object_new` to set them during object construction.
|
|
52
|
-
* Otherwise falls back to the normal constructor.
|
|
53
|
-
*/
|
|
54
|
-
export function createContainerWithConstructOnly(
|
|
55
|
-
containerClass: ContainerClass,
|
|
56
|
-
props: Props,
|
|
57
|
-
normalConstructor: () => Container,
|
|
58
|
-
): Container {
|
|
59
|
-
const constructOnlyArgs = collectActiveConstructOnlyProps(containerClass, props);
|
|
60
|
-
|
|
61
|
-
if (constructOnlyArgs.length === 0) {
|
|
62
|
-
return normalConstructor();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const typeName = containerClass.glibTypeName;
|
|
66
|
-
const gtype = typeFromName(typeName);
|
|
47
|
+
export function createContainerWithProperties(containerClass: ContainerClass, props: Props): Container {
|
|
48
|
+
const gtype = containerClass.getGType();
|
|
49
|
+
const constructionProps = collectConstructionProps(containerClass, props);
|
|
67
50
|
|
|
68
|
-
const
|
|
51
|
+
const names: string[] = [];
|
|
52
|
+
const values: Value[] = [];
|
|
69
53
|
|
|
70
|
-
for (const { girName, ffiType, value } of
|
|
71
|
-
|
|
72
|
-
|
|
54
|
+
for (const { girName, ffiType, value } of constructionProps) {
|
|
55
|
+
names.push(girName);
|
|
56
|
+
values.push(toValue(ffiType, value));
|
|
73
57
|
}
|
|
74
58
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const handle = call("libgobject-2.0.so.0", "g_object_new", args, {
|
|
78
|
-
type: "gobject",
|
|
79
|
-
ownership: "full",
|
|
80
|
-
}) as NativeHandle;
|
|
81
|
-
|
|
82
|
-
setInstantiating(true);
|
|
83
|
-
// biome-ignore lint/suspicious/noExplicitAny: Dynamic instantiation with isInstantiating flag
|
|
84
|
-
const instance = new (containerClass as any)() as Container & { handle: NativeHandle };
|
|
85
|
-
setInstantiating(false);
|
|
86
|
-
instance.handle = handle;
|
|
87
|
-
registerNativeObject(instance);
|
|
88
|
-
|
|
89
|
-
return instance;
|
|
59
|
+
return GObject.newWithProperties(gtype, names, values) as unknown as Container;
|
|
90
60
|
}
|
|
@@ -14,6 +14,8 @@ export function detachChild(child: Gtk.Widget, container: Gtk.Widget): void {
|
|
|
14
14
|
container.setChild(null);
|
|
15
15
|
} else if (isRemovable(container)) {
|
|
16
16
|
container.remove(child);
|
|
17
|
+
} else {
|
|
18
|
+
child.unparent();
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
|
|
@@ -27,7 +29,7 @@ export function attachChild(child: Gtk.Widget, container: Gtk.Widget): void {
|
|
|
27
29
|
} else if (isSingleChild(container)) {
|
|
28
30
|
container.setChild(child);
|
|
29
31
|
} else {
|
|
30
|
-
|
|
32
|
+
child.setParent(container);
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
|