@gtkx/react 1.5.0 → 1.6.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/adw/element-behaviors.js +34 -31
- package/dist/adw/element-behaviors.js.map +1 -1
- package/dist/components/element.d.ts +6 -1
- package/dist/components/element.d.ts.map +1 -1
- package/dist/components/element.js +6 -3
- package/dist/components/element.js.map +1 -1
- package/dist/element-behaviors.js +18 -18
- package/dist/element-behaviors.js.map +1 -1
- package/dist/reconciler/behaviors.d.ts +10 -7
- package/dist/reconciler/behaviors.d.ts.map +1 -1
- package/dist/reconciler/behaviors.js +21 -17
- package/dist/reconciler/behaviors.js.map +1 -1
- package/dist/reconciler/instance.d.ts.map +1 -1
- package/dist/reconciler/instance.js +5 -4
- package/dist/reconciler/instance.js.map +1 -1
- package/dist/reconciler/metadata.d.ts.map +1 -1
- package/dist/reconciler/metadata.js +17 -3
- package/dist/reconciler/metadata.js.map +1 -1
- package/package.json +5 -5
- package/src/adw/element-behaviors.ts +37 -34
- package/src/components/element.tsx +11 -3
- package/src/element-behaviors.ts +18 -18
- package/src/reconciler/behaviors.ts +36 -27
- package/src/reconciler/instance.ts +5 -4
- package/src/reconciler/metadata.ts +25 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type * as Gtk from "@gtkx/gi/gtk";
|
|
2
1
|
import * as Adw from "@gtkx/gi/adw";
|
|
2
|
+
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
3
|
import type { AlertDialogResponse } from "./prop-types.js";
|
|
4
4
|
import {
|
|
5
5
|
applicationCreator,
|
|
@@ -35,22 +35,27 @@ type PrefixSuffixRow = Adw.ActionRow | Adw.EntryRow | Adw.ExpanderRow;
|
|
|
35
35
|
|
|
36
36
|
const SLOT_SUFFIX = "Slot";
|
|
37
37
|
const childSetter = childSetterSlot<AdwChildSetter>();
|
|
38
|
-
const contentSetter = contentSetterSlot<AdwContentSetter>();
|
|
39
|
-
const breakpoints = methodSlot<BreakpointHost, Adw.Breakpoint>("breakpoints",
|
|
38
|
+
const contentSetter = contentSetterSlot<AdwContentSetter>(Gtk.Widget);
|
|
39
|
+
const breakpoints = methodSlot<BreakpointHost, Adw.Breakpoint>("breakpoints", Adw.Breakpoint, "addBreakpoint");
|
|
40
40
|
|
|
41
41
|
const prefixSuffix = [
|
|
42
|
-
methodSlot<PrefixSuffixRow, Gtk.Widget>("prefix",
|
|
43
|
-
methodSlot<PrefixSuffixRow, Gtk.Widget>("suffix",
|
|
42
|
+
methodSlot<PrefixSuffixRow, Gtk.Widget>("prefix", Gtk.Widget, "addPrefix", "remove"),
|
|
43
|
+
methodSlot<PrefixSuffixRow, Gtk.Widget>("suffix", Gtk.Widget, "addSuffix", "remove"),
|
|
44
44
|
];
|
|
45
45
|
|
|
46
46
|
const preferencesDialogChildren = methodSlot<Adw.PreferencesDialog, Adw.PreferencesPage>(
|
|
47
|
-
"children",
|
|
47
|
+
"children", Adw.PreferencesPage, "add", "remove",
|
|
48
48
|
);
|
|
49
49
|
|
|
50
|
-
const alertDialogExtraChild = setterSlot<Adw.AlertDialog, Gtk.Widget>("children",
|
|
51
|
-
const sidebarSections = indexedSlot<Adw.Sidebar, Adw.SidebarSection>("children",
|
|
52
|
-
const sidebarItems = indexedSlot<Adw.SidebarSection, Adw.SidebarItem>("children",
|
|
53
|
-
const isWidget = childMatcher(
|
|
50
|
+
const alertDialogExtraChild = setterSlot<Adw.AlertDialog, Gtk.Widget>("children", Gtk.Widget, "setExtraChild");
|
|
51
|
+
const sidebarSections = indexedSlot<Adw.Sidebar, Adw.SidebarSection>("children", Adw.SidebarSection);
|
|
52
|
+
const sidebarItems = indexedSlot<Adw.SidebarSection, Adw.SidebarItem>("children", Adw.SidebarItem);
|
|
53
|
+
const isWidget = childMatcher(Gtk.Widget);
|
|
54
|
+
|
|
55
|
+
const scrollableWidget = {
|
|
56
|
+
[Symbol.hasInstance]: (value: unknown): value is Gtk.Scrollable & Gtk.Widget =>
|
|
57
|
+
value instanceof Gtk.Scrollable && value instanceof Gtk.Widget,
|
|
58
|
+
};
|
|
54
59
|
|
|
55
60
|
const multiLayoutSlots: ElementBehavior<Adw.MultiLayoutView> = {
|
|
56
61
|
attach: (view, child, info) => {
|
|
@@ -60,7 +65,7 @@ const multiLayoutSlots: ElementBehavior<Adw.MultiLayoutView> = {
|
|
|
60
65
|
return;
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
view.setChild(id, child
|
|
68
|
+
view.setChild(id, child);
|
|
64
69
|
|
|
65
70
|
return true;
|
|
66
71
|
},
|
|
@@ -71,15 +76,13 @@ const multiLayoutSlots: ElementBehavior<Adw.MultiLayoutView> = {
|
|
|
71
76
|
return;
|
|
72
77
|
}
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (view.getChild(id) === widget) {
|
|
77
|
-
widget.unparent();
|
|
79
|
+
if (view.getChild(id) === child) {
|
|
80
|
+
child.unparent();
|
|
78
81
|
}
|
|
79
82
|
},
|
|
80
83
|
};
|
|
81
84
|
|
|
82
|
-
const multiLayoutLayouts = slot<Adw.MultiLayoutView, Gtk.Widget>("layouts",
|
|
85
|
+
const multiLayoutLayouts = slot<Adw.MultiLayoutView, Gtk.Widget>("layouts", Gtk.Widget, {
|
|
83
86
|
attach: (view, content) => {
|
|
84
87
|
const layout = new Adw.Layout({ content });
|
|
85
88
|
view.addLayout(layout);
|
|
@@ -113,7 +116,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
113
116
|
},
|
|
114
117
|
AdwClampScrollable: {
|
|
115
118
|
behaviors: [
|
|
116
|
-
setterSlot<Adw.ClampScrollable, Gtk.Scrollable & Gtk.Widget>("children",
|
|
119
|
+
setterSlot<Adw.ClampScrollable, Gtk.Scrollable & Gtk.Widget>("children", scrollableWidget, "setChild"),
|
|
117
120
|
],
|
|
118
121
|
},
|
|
119
122
|
...forTypes(CHILD_SETTER_TYPES, {
|
|
@@ -135,7 +138,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
135
138
|
behaviors: [
|
|
136
139
|
childSetter,
|
|
137
140
|
methodSlot<Adw.BreakpointBin, Adw.Breakpoint>(
|
|
138
|
-
"breakpoints",
|
|
141
|
+
"breakpoints", Adw.Breakpoint, "addBreakpoint", "removeBreakpoint",
|
|
139
142
|
),
|
|
140
143
|
],
|
|
141
144
|
},
|
|
@@ -148,18 +151,18 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
148
151
|
AdwExpanderRow: {
|
|
149
152
|
behaviors: [
|
|
150
153
|
...prefixSuffix,
|
|
151
|
-
methodSlot<Adw.ExpanderRow, Gtk.Widget>("rows",
|
|
154
|
+
methodSlot<Adw.ExpanderRow, Gtk.Widget>("rows", Gtk.Widget, "addRow", "remove"),
|
|
152
155
|
],
|
|
153
156
|
},
|
|
154
157
|
AdwNavigationSplitView: {
|
|
155
|
-
behaviors: [contentSetterSlot<Adw.NavigationSplitView, Adw.NavigationPage>(
|
|
158
|
+
behaviors: [contentSetterSlot<Adw.NavigationSplitView, Adw.NavigationPage>(Adw.NavigationPage)],
|
|
156
159
|
},
|
|
157
160
|
AdwWrapBox: {
|
|
158
161
|
behaviors: [boxSlot<Adw.WrapBox>()],
|
|
159
162
|
},
|
|
160
163
|
AdwCarousel: {
|
|
161
164
|
behaviors: [
|
|
162
|
-
slot<Adw.Carousel, Gtk.Widget>("children",
|
|
165
|
+
slot<Adw.Carousel, Gtk.Widget>("children", Gtk.Widget, {
|
|
163
166
|
attach: (carousel, child, info) => {
|
|
164
167
|
carousel.insert(child, info.index);
|
|
165
168
|
},
|
|
@@ -174,7 +177,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
174
177
|
},
|
|
175
178
|
AdwPreferencesPage: {
|
|
176
179
|
behaviors: [
|
|
177
|
-
slot<Adw.PreferencesPage, Adw.PreferencesGroup>("children",
|
|
180
|
+
slot<Adw.PreferencesPage, Adw.PreferencesGroup>("children", Adw.PreferencesGroup, {
|
|
178
181
|
attach: (page, group, info) => {
|
|
179
182
|
page.insert(group, info.index);
|
|
180
183
|
},
|
|
@@ -188,11 +191,11 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
188
191
|
behaviors: [preferencesDialogChildren],
|
|
189
192
|
},
|
|
190
193
|
AdwPreferencesGroup: {
|
|
191
|
-
behaviors: [methodSlot<Adw.PreferencesGroup, Gtk.Widget>("children",
|
|
194
|
+
behaviors: [methodSlot<Adw.PreferencesGroup, Gtk.Widget>("children", Gtk.Widget, "add", "remove")],
|
|
192
195
|
},
|
|
193
196
|
AdwTabView: {
|
|
194
197
|
behaviors: [
|
|
195
|
-
slot<Adw.TabView, Gtk.Widget>("children",
|
|
198
|
+
slot<Adw.TabView, Gtk.Widget>("children", Gtk.Widget, {
|
|
196
199
|
attach: (view, child, info) => view.insert(child, info.index),
|
|
197
200
|
reorder: (view, _child, info) => {
|
|
198
201
|
if (info.adopted instanceof Adw.TabPage) {
|
|
@@ -210,37 +213,37 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
210
213
|
},
|
|
211
214
|
AdwNavigationView: {
|
|
212
215
|
behaviors: [
|
|
213
|
-
methodSlot<Adw.NavigationView, Adw.NavigationPage>("children",
|
|
216
|
+
methodSlot<Adw.NavigationView, Adw.NavigationPage>("children", Adw.NavigationPage, "add", "remove"),
|
|
214
217
|
],
|
|
215
218
|
},
|
|
216
219
|
AdwViewStack: {
|
|
217
220
|
behaviors: [
|
|
218
|
-
methodSlot<Adw.ViewStack, Gtk.Widget>("children",
|
|
221
|
+
methodSlot<Adw.ViewStack, Gtk.Widget>("children", Gtk.Widget, "add", "remove"),
|
|
219
222
|
deferred<Adw.ViewStack, string>("visibleChildName", (stack, name) => stack.getChildByName(name) !== null),
|
|
220
223
|
],
|
|
221
224
|
},
|
|
222
225
|
AdwToolbarView: {
|
|
223
226
|
behaviors: [
|
|
224
|
-
contentSetterSlot<Adw.ToolbarView>(),
|
|
225
|
-
methodSlot<Adw.ToolbarView, Gtk.Widget>("topBar",
|
|
226
|
-
methodSlot<Adw.ToolbarView, Gtk.Widget>("bottomBar",
|
|
227
|
+
contentSetterSlot<Adw.ToolbarView>(Gtk.Widget),
|
|
228
|
+
methodSlot<Adw.ToolbarView, Gtk.Widget>("topBar", Gtk.Widget, "addTopBar", "remove"),
|
|
229
|
+
methodSlot<Adw.ToolbarView, Gtk.Widget>("bottomBar", Gtk.Widget, "addBottomBar", "remove"),
|
|
227
230
|
],
|
|
228
231
|
},
|
|
229
232
|
AdwHeaderBar: {
|
|
230
233
|
behaviors: [
|
|
231
|
-
methodSlot<Adw.HeaderBar, Gtk.Widget>("start",
|
|
232
|
-
methodSlot<Adw.HeaderBar, Gtk.Widget>("end",
|
|
234
|
+
methodSlot<Adw.HeaderBar, Gtk.Widget>("start", Gtk.Widget, "packStart", "remove"),
|
|
235
|
+
methodSlot<Adw.HeaderBar, Gtk.Widget>("end", Gtk.Widget, "packEnd", "remove"),
|
|
233
236
|
],
|
|
234
237
|
},
|
|
235
238
|
AdwShortcutsDialog: {
|
|
236
|
-
behaviors: [methodSlot<Adw.ShortcutsDialog, Adw.ShortcutsSection>("children",
|
|
239
|
+
behaviors: [methodSlot<Adw.ShortcutsDialog, Adw.ShortcutsSection>("children", Adw.ShortcutsSection, "add")],
|
|
237
240
|
},
|
|
238
241
|
AdwShortcutsSection: {
|
|
239
|
-
behaviors: [methodSlot<Adw.ShortcutsSection, Adw.ShortcutsItem>("children",
|
|
242
|
+
behaviors: [methodSlot<Adw.ShortcutsSection, Adw.ShortcutsItem>("children", Adw.ShortcutsItem, "add")],
|
|
240
243
|
},
|
|
241
244
|
AdwToggleGroup: {
|
|
242
245
|
behaviors: [
|
|
243
|
-
methodSlot<Adw.ToggleGroup, Adw.Toggle>("children",
|
|
246
|
+
methodSlot<Adw.ToggleGroup, Adw.Toggle>("children", Adw.Toggle, "add", "remove"),
|
|
244
247
|
deferred<Adw.ToggleGroup, string>("activeName", (group, name) => group.getToggleByName(name) !== null),
|
|
245
248
|
deferred("active"),
|
|
246
249
|
],
|
|
@@ -72,11 +72,19 @@ const buildElement = (typeName: string, record: Props): ReactElement => {
|
|
|
72
72
|
* Left out, the component takes `unknown`, which accepts no attributes at all.
|
|
73
73
|
*
|
|
74
74
|
* @param typeName GType name to render, such as `GtkButton` or the `typeName` given to `registerClass`.
|
|
75
|
+
* @param cls Wrapper class the name resolves to. Referencing it keeps the class, and with it the
|
|
76
|
+
* registration the reconciler's name lookup depends on, in a tree-shaken bundle; the component
|
|
77
|
+
* itself renders through the name.
|
|
78
|
+
* @param metadata Registered metadata entry for the type. Referencing it keeps the type's property
|
|
79
|
+
* and signal tables, which register themselves when evaluated, in a tree-shaken bundle.
|
|
75
80
|
* @returns A component taking that type's props.
|
|
76
81
|
*/
|
|
77
82
|
/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- callers name the props */
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
const createElementComponent: <P = unknown>(
|
|
84
|
+
typeName: string,
|
|
85
|
+
cls?: unknown,
|
|
86
|
+
metadata?: unknown,
|
|
87
|
+
) => (props: P) => ReactNode =
|
|
88
|
+
(typeName) => (props): ReactNode => buildElement(typeName, isRecord(props) ? props : {});
|
|
81
89
|
|
|
82
90
|
export { Prop, createElementComponent };
|
package/src/element-behaviors.ts
CHANGED
|
@@ -47,8 +47,8 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
47
47
|
}),
|
|
48
48
|
...forTypes(["GtkHeaderBar", "GtkActionBar"], {
|
|
49
49
|
behaviors: [
|
|
50
|
-
methodSlot<Gtk.HeaderBar | Gtk.ActionBar, Gtk.Widget>("start",
|
|
51
|
-
methodSlot<Gtk.HeaderBar | Gtk.ActionBar, Gtk.Widget>("end",
|
|
50
|
+
methodSlot<Gtk.HeaderBar | Gtk.ActionBar, Gtk.Widget>("start", Gtk.Widget, "packStart", "remove"),
|
|
51
|
+
methodSlot<Gtk.HeaderBar | Gtk.ActionBar, Gtk.Widget>("end", Gtk.Widget, "packEnd", "remove"),
|
|
52
52
|
],
|
|
53
53
|
}),
|
|
54
54
|
GtkWindow: {
|
|
@@ -56,7 +56,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
56
56
|
},
|
|
57
57
|
GtkWidget: {
|
|
58
58
|
behaviors: [
|
|
59
|
-
slot<Gtk.Widget, Gtk.Popover>("children",
|
|
59
|
+
slot<Gtk.Widget, Gtk.Popover>("children", Gtk.Popover, {
|
|
60
60
|
attach: (parent, popover) => {
|
|
61
61
|
popover.setParent(parent);
|
|
62
62
|
},
|
|
@@ -65,10 +65,10 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
65
65
|
},
|
|
66
66
|
}),
|
|
67
67
|
methodSlot<Gtk.Widget, Gtk.EventController>(
|
|
68
|
-
"controllers",
|
|
68
|
+
"controllers", Gtk.EventController, "addController", "removeController",
|
|
69
69
|
),
|
|
70
|
-
setterSlot<Gtk.Widget, Gtk.LayoutManager>("layoutManager",
|
|
71
|
-
slot<Gtk.Widget, Gio.ActionGroup>("actionGroups",
|
|
70
|
+
setterSlot<Gtk.Widget, Gtk.LayoutManager>("layoutManager", Gtk.LayoutManager, "setLayoutManager"),
|
|
71
|
+
slot<Gtk.Widget, Gio.ActionGroup>("actionGroups", Gio.ActionGroup, {
|
|
72
72
|
attach: (widget, group, info) => {
|
|
73
73
|
widget.insertActionGroup((info.props.prefix as string | null) ?? "", group);
|
|
74
74
|
},
|
|
@@ -100,7 +100,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
100
100
|
GtkOverlay: {
|
|
101
101
|
behaviors: [
|
|
102
102
|
childSetterSlot<Gtk.Overlay>(),
|
|
103
|
-
slot<Gtk.Overlay, Gtk.Widget>("overlays",
|
|
103
|
+
slot<Gtk.Overlay, Gtk.Widget>("overlays", Gtk.Widget, {
|
|
104
104
|
attach: (overlay, child) => {
|
|
105
105
|
overlay.addOverlay(child);
|
|
106
106
|
},
|
|
@@ -114,7 +114,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
114
114
|
GtkShortcutController: {
|
|
115
115
|
behaviors: [
|
|
116
116
|
methodSlot<Gtk.ShortcutController, Gtk.Shortcut>(
|
|
117
|
-
"shortcuts",
|
|
117
|
+
"shortcuts", Gtk.Shortcut, "addShortcut", "removeShortcut",
|
|
118
118
|
),
|
|
119
119
|
],
|
|
120
120
|
},
|
|
@@ -122,11 +122,11 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
122
122
|
behaviors: [{ create: () => Gtk.TextChildAnchor.new() }],
|
|
123
123
|
},
|
|
124
124
|
GtkTextView: {
|
|
125
|
-
behaviors: [setterSlot<Gtk.TextView, Gtk.TextBuffer>("children",
|
|
125
|
+
behaviors: [setterSlot<Gtk.TextView, Gtk.TextBuffer>("children", Gtk.TextBuffer, "setBuffer")],
|
|
126
126
|
},
|
|
127
127
|
GActionMap: {
|
|
128
128
|
behaviors: [
|
|
129
|
-
slot<Gio.ActionMap, Gio.Action>("actions",
|
|
129
|
+
slot<Gio.ActionMap, Gio.Action>("actions", Gio.Action, {
|
|
130
130
|
attach: (map, action) => {
|
|
131
131
|
map.addAction(action);
|
|
132
132
|
},
|
|
@@ -150,7 +150,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
150
150
|
},
|
|
151
151
|
GtkColumnView: {
|
|
152
152
|
behaviors: [
|
|
153
|
-
slot<Gtk.ColumnView, Gtk.ColumnViewColumn>("children",
|
|
153
|
+
slot<Gtk.ColumnView, Gtk.ColumnViewColumn>("children", Gtk.ColumnViewColumn, {
|
|
154
154
|
attach: (view, column, info) => {
|
|
155
155
|
view.insertColumn(info.index, column);
|
|
156
156
|
},
|
|
@@ -162,7 +162,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
162
162
|
},
|
|
163
163
|
GtkGrid: {
|
|
164
164
|
behaviors: [
|
|
165
|
-
slot<Gtk.Grid, Gtk.Widget>("children",
|
|
165
|
+
slot<Gtk.Grid, Gtk.Widget>("children", Gtk.Widget, {
|
|
166
166
|
attach: (grid, child) => {
|
|
167
167
|
grid.attach(child, 0, 0, 1, 1);
|
|
168
168
|
},
|
|
@@ -175,7 +175,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
175
175
|
},
|
|
176
176
|
GtkFixed: {
|
|
177
177
|
behaviors: [
|
|
178
|
-
slot<Gtk.Fixed, Gtk.Widget>("children",
|
|
178
|
+
slot<Gtk.Fixed, Gtk.Widget>("children", Gtk.Widget, {
|
|
179
179
|
attach: (fixed, child) => {
|
|
180
180
|
fixed.put(child, 0, 0);
|
|
181
181
|
},
|
|
@@ -201,10 +201,10 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
201
201
|
GtkConstraintLayout: {
|
|
202
202
|
behaviors: [
|
|
203
203
|
methodSlot<Gtk.ConstraintLayout, Gtk.Constraint>(
|
|
204
|
-
"constraints",
|
|
204
|
+
"constraints", Gtk.Constraint, "addConstraint", "removeConstraint",
|
|
205
205
|
),
|
|
206
206
|
methodSlot<Gtk.ConstraintLayout, Gtk.ConstraintGuide>(
|
|
207
|
-
"guides",
|
|
207
|
+
"guides", Gtk.ConstraintGuide, "addGuide", "removeGuide",
|
|
208
208
|
),
|
|
209
209
|
list<Gtk.ConstraintLayout, VflConstraints, Gtk.Constraint[]>("vfl", {
|
|
210
210
|
add: (layout, item) => [
|
|
@@ -225,13 +225,13 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
225
225
|
},
|
|
226
226
|
GtkStack: {
|
|
227
227
|
behaviors: [
|
|
228
|
-
methodSlot<Gtk.Stack, Gtk.Widget>("children",
|
|
228
|
+
methodSlot<Gtk.Stack, Gtk.Widget>("children", Gtk.Widget, "addChild", "remove"),
|
|
229
229
|
deferred<Gtk.Stack, string>("visibleChildName", (stack, name) => stack.getChildByName(name) !== null),
|
|
230
230
|
],
|
|
231
231
|
},
|
|
232
232
|
GtkNotebook: {
|
|
233
233
|
behaviors: [
|
|
234
|
-
slot<Gtk.Notebook, Gtk.Widget>("children",
|
|
234
|
+
slot<Gtk.Notebook, Gtk.Widget>("children", Gtk.Widget, {
|
|
235
235
|
attach: (notebook, child, info) => notebook.insertPage(child, null, info.index),
|
|
236
236
|
reorder: (notebook, child, info) => {
|
|
237
237
|
notebook.reorderChild(child, info.index);
|
|
@@ -246,7 +246,7 @@ const BUILTIN_BEHAVIORS: Record<string, ElementConfig<never>> = {
|
|
|
246
246
|
GtkApplication: {
|
|
247
247
|
behaviors: [
|
|
248
248
|
applicationCreator(Gtk.Application),
|
|
249
|
-
methodSlot<Gtk.Application, Gtk.Window>("children",
|
|
249
|
+
methodSlot<Gtk.Application, Gtk.Window>("children", Gtk.Window, "addWindow", "removeWindow"),
|
|
250
250
|
list<Gtk.Application, ActionAccel>("actionAccels", {
|
|
251
251
|
add: (application, item) => {
|
|
252
252
|
application.setAccelsForAction(item.detailedActionName, item.accels);
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type * as GObject from "@gtkx/gi/gobject";
|
|
2
|
-
import
|
|
2
|
+
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
3
|
import {
|
|
4
|
-
type AnyClass,
|
|
5
4
|
type ApplicationClass,
|
|
6
5
|
type CommandLineApplication,
|
|
7
6
|
createApplication,
|
|
8
7
|
getClassType,
|
|
8
|
+
getInstanceType,
|
|
9
9
|
TYPE_INVALID,
|
|
10
|
-
typeFromName,
|
|
11
10
|
typeIsA,
|
|
12
11
|
} from "@gtkx/runtime";
|
|
13
|
-
import {
|
|
12
|
+
import { isDeepEqual, kebabCase, structuredClone, unsanitizeIdentifier } from "@gtkx/utils";
|
|
14
13
|
import type { DetachInfo, ElementBehavior, PlaceInfo, Props } from "./registry.js";
|
|
15
14
|
import { getPropertyName } from "./metadata.js";
|
|
16
15
|
import { applyWrite } from "./signals.js";
|
|
@@ -67,22 +66,32 @@ type IndexedChildHost<C extends GObject.Object> = GObject.Object & {
|
|
|
67
66
|
insert: (child: C, position: number) => unknown;
|
|
68
67
|
};
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
type ChildClass<C extends GObject.Object> =
|
|
70
|
+
(abstract new (...args: never[]) => C) |
|
|
71
|
+
{ [Symbol.hasInstance]: (value: unknown) => value is C };
|
|
71
72
|
|
|
72
|
-
const
|
|
73
|
+
const childClassType = (cls: ChildClass<GObject.Object>): bigint =>
|
|
74
|
+
typeof cls === "function" ? getClassType(cls) : TYPE_INVALID;
|
|
73
75
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
const isChildInstance = <C extends GObject.Object>(child: GObject.Object, cls: ChildClass<C>): child is C => {
|
|
77
|
+
if (child instanceof cls) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
const type = childClassType(cls);
|
|
82
|
+
|
|
83
|
+
return type !== TYPE_INVALID && typeIsA(getInstanceType(child), type);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const childMatcher =
|
|
87
|
+
<C extends GObject.Object>(cls: ChildClass<C> | undefined): ((child: GObject.Object) => child is C) =>
|
|
88
|
+
(child): child is C =>
|
|
89
|
+
cls !== undefined && isChildInstance(child, cls);
|
|
81
90
|
|
|
82
91
|
const slotAttach =
|
|
83
92
|
<P extends GObject.Object, C extends GObject.Object>(
|
|
84
93
|
slotName: string,
|
|
85
|
-
isMatch: (child: GObject.Object) =>
|
|
94
|
+
isMatch: (child: GObject.Object) => child is C,
|
|
86
95
|
attach: SlotHooks<P, C>["attach"],
|
|
87
96
|
): NonNullable<ElementBehavior["attach"]> =>
|
|
88
97
|
(object, child, info) => {
|
|
@@ -90,15 +99,15 @@ const slotAttach =
|
|
|
90
99
|
return;
|
|
91
100
|
}
|
|
92
101
|
|
|
93
|
-
return attach(object as P, child
|
|
102
|
+
return attach(object as P, child, info) ?? true;
|
|
94
103
|
};
|
|
95
104
|
|
|
96
105
|
const slot = <P extends GObject.Object, C extends GObject.Object>(
|
|
97
106
|
slotName: string,
|
|
98
|
-
|
|
107
|
+
childClass: ChildClass<C> | undefined,
|
|
99
108
|
hooks: SlotHooks<P, C>,
|
|
100
109
|
): ElementBehavior => {
|
|
101
|
-
const matches = childMatcher(
|
|
110
|
+
const matches = childMatcher(childClass);
|
|
102
111
|
const { attach, detach, reorder, resolve } = hooks;
|
|
103
112
|
const behavior: ElementBehavior = { attach: slotAttach(slotName, matches, attach) };
|
|
104
113
|
|
|
@@ -296,7 +305,7 @@ const controlledText = (prop: string): ElementBehavior =>
|
|
|
296
305
|
});
|
|
297
306
|
|
|
298
307
|
const childSetterSlot = <P extends ChildSetter>(): ElementBehavior<P> =>
|
|
299
|
-
slot<P, Gtk.Widget>("children",
|
|
308
|
+
slot<P, Gtk.Widget>("children", Gtk.Widget, {
|
|
300
309
|
attach: (parent, child) => {
|
|
301
310
|
parent.setChild(child);
|
|
302
311
|
},
|
|
@@ -306,9 +315,9 @@ const childSetterSlot = <P extends ChildSetter>(): ElementBehavior<P> =>
|
|
|
306
315
|
});
|
|
307
316
|
|
|
308
317
|
const contentSetterSlot = <P extends ContentSetter<C>, C extends Gtk.Widget = Gtk.Widget>(
|
|
309
|
-
|
|
318
|
+
childClass: ChildClass<C>,
|
|
310
319
|
): ElementBehavior<P> =>
|
|
311
|
-
slot<P, C>("children",
|
|
320
|
+
slot<P, C>("children", childClass, {
|
|
312
321
|
attach: (parent, child) => {
|
|
313
322
|
parent.setContent(child);
|
|
314
323
|
},
|
|
@@ -318,7 +327,7 @@ const contentSetterSlot = <P extends ContentSetter<C>, C extends Gtk.Widget = Gt
|
|
|
318
327
|
});
|
|
319
328
|
|
|
320
329
|
const boxSlot = <P extends BoxLike>(): ElementBehavior<P> =>
|
|
321
|
-
slot<P, Gtk.Widget>("children",
|
|
330
|
+
slot<P, Gtk.Widget>("children", Gtk.Widget, {
|
|
322
331
|
attach: (box, child, info) => box.insertChildAfter(child, info.sibling as Gtk.Widget | null),
|
|
323
332
|
detach: (box, child) => {
|
|
324
333
|
box.remove(child);
|
|
@@ -333,7 +342,7 @@ const callMethod = <P extends GObject.Object, A>(parent: P, method: MethodKey<P,
|
|
|
333
342
|
|
|
334
343
|
const methodSlot = <P extends GObject.Object, C extends GObject.Object>(
|
|
335
344
|
slotName: string,
|
|
336
|
-
|
|
345
|
+
childClass: ChildClass<C> | undefined,
|
|
337
346
|
add: MethodKey<P, C>,
|
|
338
347
|
remove?: MethodKey<P, C>,
|
|
339
348
|
): ElementBehavior => {
|
|
@@ -345,15 +354,15 @@ const methodSlot = <P extends GObject.Object, C extends GObject.Object>(
|
|
|
345
354
|
};
|
|
346
355
|
}
|
|
347
356
|
|
|
348
|
-
return slot<P, C>(slotName,
|
|
357
|
+
return slot<P, C>(slotName, childClass, hooks);
|
|
349
358
|
};
|
|
350
359
|
|
|
351
360
|
const setterSlot = <P extends GObject.Object, C extends GObject.Object>(
|
|
352
361
|
slotName: string,
|
|
353
|
-
|
|
362
|
+
childClass: ChildClass<C> | undefined,
|
|
354
363
|
setter: MethodKey<P, C | null>,
|
|
355
364
|
): ElementBehavior =>
|
|
356
|
-
slot<P, C>(slotName,
|
|
365
|
+
slot<P, C>(slotName, childClass, {
|
|
357
366
|
attach: (parent, child) => {
|
|
358
367
|
callMethod<P, C | null>(parent, setter, child);
|
|
359
368
|
},
|
|
@@ -364,9 +373,9 @@ const setterSlot = <P extends GObject.Object, C extends GObject.Object>(
|
|
|
364
373
|
|
|
365
374
|
const indexedSlot = <P extends IndexedChildHost<C>, C extends GObject.Object>(
|
|
366
375
|
slotName: string,
|
|
367
|
-
|
|
376
|
+
childClass: ChildClass<C> | undefined,
|
|
368
377
|
): ElementBehavior<P> =>
|
|
369
|
-
slot<P, C>(slotName,
|
|
378
|
+
slot<P, C>(slotName, childClass, {
|
|
370
379
|
attach: (parent, child, info) => {
|
|
371
380
|
parent.insert(child, info.index);
|
|
372
381
|
},
|
|
@@ -419,7 +428,7 @@ const wrappingIndexedSlot = <W extends Gtk.Widget, P extends IndexedChildHost<Gt
|
|
|
419
428
|
Wrapper: new (props: Props) => W,
|
|
420
429
|
setChild: (wrapper: W, inner: Gtk.Widget) => void,
|
|
421
430
|
): ElementBehavior<P> => ({
|
|
422
|
-
...slot<P, Gtk.Widget>("children",
|
|
431
|
+
...slot<P, Gtk.Widget>("children", Gtk.Widget, {
|
|
423
432
|
attach: (parent, child, info) =>
|
|
424
433
|
parent.insert(wrappedRow(Wrapper, setChild, info.context as RowCache, child), info.index),
|
|
425
434
|
detach: (parent, child, info) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type * as GObject from "@gtkx/gi/gobject";
|
|
2
|
-
import {
|
|
2
|
+
import { TYPE_INVALID, typeFromName, typeIsA } from "@gtkx/runtime";
|
|
3
|
+
import { getExactWrapperClass } from "@gtkx/runtime/internal";
|
|
3
4
|
import { getOrInsert, pickBy } from "@gtkx/utils";
|
|
4
5
|
import type { Props } from "./registry.js";
|
|
5
6
|
import { type TypeInfo, typeInfoFor } from "./metadata.js";
|
|
@@ -57,8 +58,8 @@ const constructInput = (info: TypeInfo, props: Props): Props =>
|
|
|
57
58
|
(info.constructOnly.has(name) || info.construct.has(name)),
|
|
58
59
|
);
|
|
59
60
|
|
|
60
|
-
const instantiate = (type: bigint, input: Props): GObject.Object => {
|
|
61
|
-
const cls =
|
|
61
|
+
const instantiate = (typeName: string, type: bigint, input: Props): GObject.Object => {
|
|
62
|
+
const cls = getExactWrapperClass(type, typeName) as WidgetConstructor;
|
|
62
63
|
|
|
63
64
|
return new cls(input);
|
|
64
65
|
};
|
|
@@ -66,7 +67,7 @@ const instantiate = (type: bigint, input: Props): GObject.Object => {
|
|
|
66
67
|
const createObject = (typeName: string, type: bigint, input: Props): GObject.Object => {
|
|
67
68
|
const create = ELEMENTS[typeName]?.behaviors?.find((behavior) => behavior.create !== undefined)?.create;
|
|
68
69
|
|
|
69
|
-
return create === undefined ? instantiate(type, input) : create(input);
|
|
70
|
+
return create === undefined ? instantiate(typeName, type, input) : create(input);
|
|
70
71
|
};
|
|
71
72
|
|
|
72
73
|
const resolveElementNode = (typeName: string, props: Props, dispatch: Dispatch): ElementNode | LazyNode => {
|
|
@@ -9,6 +9,11 @@ import {
|
|
|
9
9
|
typeName,
|
|
10
10
|
typeParent,
|
|
11
11
|
} from "@gtkx/runtime";
|
|
12
|
+
import {
|
|
13
|
+
elementMetadataVersion,
|
|
14
|
+
registeredElementProperties,
|
|
15
|
+
registeredElementSignals,
|
|
16
|
+
} from "@gtkx/runtime/internal";
|
|
12
17
|
import { getOrInsert } from "@gtkx/utils";
|
|
13
18
|
import { properties, type PropertyEntry, signals, userEventSignals } from "virtual:gtkx-config";
|
|
14
19
|
import { deferredProps, type ElementBehavior, ELEMENTS } from "./registry.js";
|
|
@@ -36,6 +41,19 @@ const FLAGS = 1;
|
|
|
36
41
|
const DEFAULT_VALUE = 2;
|
|
37
42
|
const ancestryCache: Map<string, string[]> = new Map();
|
|
38
43
|
const typeInfoCache: Map<string, TypeInfo> = new Map();
|
|
44
|
+
const metadataCacheState = { seenVersion: elementMetadataVersion() };
|
|
45
|
+
|
|
46
|
+
const dropStaleCaches = (): void => {
|
|
47
|
+
const current = elementMetadataVersion();
|
|
48
|
+
|
|
49
|
+
if (metadataCacheState.seenVersion === current) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
metadataCacheState.seenVersion = current;
|
|
54
|
+
ancestryCache.clear();
|
|
55
|
+
typeInfoCache.clear();
|
|
56
|
+
};
|
|
39
57
|
|
|
40
58
|
const addAncestor = (names: string[], seen: Set<string>, name: string | null): void => {
|
|
41
59
|
if (name === null || seen.has(name)) {
|
|
@@ -75,7 +93,7 @@ const addAll = <T>(target: Set<T>, source: Iterable<T> | undefined): void => {
|
|
|
75
93
|
};
|
|
76
94
|
|
|
77
95
|
const accumulateAncestor = (info: TypeInfo, ancestor: string): void => {
|
|
78
|
-
Object.assign(info.signals, signals[ancestor] ?? {});
|
|
96
|
+
Object.assign(info.signals, registeredElementSignals[ancestor] ?? signals[ancestor] ?? {});
|
|
79
97
|
addAll(info.userEventSignals, userEventSignals[ancestor]);
|
|
80
98
|
info.behaviors.push(...(ELEMENTS[ancestor]?.behaviors ?? []));
|
|
81
99
|
};
|
|
@@ -141,7 +159,7 @@ const buildTypeInfo = (name: string): TypeInfo => {
|
|
|
141
159
|
info.isLazy = chain.some((ancestor) => ELEMENTS[ancestor]?.isLazy === true);
|
|
142
160
|
|
|
143
161
|
for (const ancestor of chain.toReversed()) {
|
|
144
|
-
Object.assign(info.properties, properties[ancestor] ?? {});
|
|
162
|
+
Object.assign(info.properties, registeredElementProperties[ancestor] ?? properties[ancestor] ?? {});
|
|
145
163
|
}
|
|
146
164
|
|
|
147
165
|
resolveProperties(info);
|
|
@@ -149,7 +167,11 @@ const buildTypeInfo = (name: string): TypeInfo => {
|
|
|
149
167
|
return info;
|
|
150
168
|
};
|
|
151
169
|
|
|
152
|
-
const typeInfoFor = (name: string): TypeInfo =>
|
|
170
|
+
const typeInfoFor = (name: string): TypeInfo => {
|
|
171
|
+
dropStaleCaches();
|
|
172
|
+
|
|
173
|
+
return getOrInsert(typeInfoCache, name, buildTypeInfo);
|
|
174
|
+
};
|
|
153
175
|
|
|
154
176
|
const getTypeInfo = (object: GObject.Object): TypeInfo | undefined => {
|
|
155
177
|
const name = typeName(getClassType(object.constructor as AnyClass));
|