@gtkx/react 0.13.3 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -31
- package/dist/generated/internal.js +98 -0
- package/dist/generated/jsx.d.ts +1110 -1781
- package/dist/jsx.d.ts +66 -35
- package/dist/jsx.js +17 -5
- package/dist/nodes/application.js +6 -6
- package/dist/nodes/index.d.ts +1 -0
- package/dist/nodes/index.js +1 -0
- package/dist/nodes/internal/constants.js +11 -0
- package/dist/nodes/internal/list-item-renderer.js +1 -1
- package/dist/nodes/internal/tree-list-item-renderer.js +1 -1
- package/dist/nodes/list-view.js +5 -0
- package/dist/nodes/models/list.d.ts +6 -1
- package/dist/nodes/models/list.js +21 -6
- package/dist/nodes/models/tree-list.d.ts +6 -1
- package/dist/nodes/models/tree-list.js +21 -7
- package/dist/nodes/scrolled-window.d.ts +1 -0
- package/dist/nodes/scrolled-window.js +21 -0
- package/dist/nodes/slot.js +11 -2
- package/dist/nodes/tree-list-view.js +5 -0
- package/dist/nodes/widget.d.ts +5 -0
- package/dist/nodes/widget.js +82 -4
- package/dist/render.d.ts +14 -14
- package/dist/render.js +14 -14
- package/dist/types.d.ts +84 -1
- package/package.json +3 -3
package/dist/jsx.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type * as Gtk from "@gtkx/ffi/gtk";
|
|
|
2
2
|
import type { ReactElement, ReactNode } from "react";
|
|
3
3
|
import type { RenderItemFn } from "./nodes/internal/list-item-renderer.js";
|
|
4
4
|
import type { TreeRenderItemFn } from "./nodes/internal/tree-list-item-renderer.js";
|
|
5
|
-
export type { EventControllerProps } from "./types.js";
|
|
5
|
+
export type { DragSourceProps, DropTargetProps, EventControllerProps } from "./types.js";
|
|
6
6
|
/**
|
|
7
7
|
* Props for slot-based child positioning.
|
|
8
8
|
*
|
|
@@ -14,6 +14,13 @@ export type SlotProps = {
|
|
|
14
14
|
/** Content to place in the slot */
|
|
15
15
|
children?: ReactNode;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Props for virtual child containers that don't expose slot id.
|
|
19
|
+
*/
|
|
20
|
+
export type VirtualSlotProps = {
|
|
21
|
+
/** Content to place in the slot */
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
};
|
|
17
24
|
/**
|
|
18
25
|
* Props for items in a {@link ListView} or {@link GridView}.
|
|
19
26
|
*
|
|
@@ -60,7 +67,7 @@ export type StringListItemProps = {
|
|
|
60
67
|
*
|
|
61
68
|
* @see {@link GridChild} for usage
|
|
62
69
|
*/
|
|
63
|
-
export type GridChildProps =
|
|
70
|
+
export type GridChildProps = VirtualSlotProps & {
|
|
64
71
|
/** Column index (0-based) */
|
|
65
72
|
column?: number;
|
|
66
73
|
/** Row index (0-based) */
|
|
@@ -75,7 +82,7 @@ export type GridChildProps = Omit<SlotProps, "id"> & {
|
|
|
75
82
|
*
|
|
76
83
|
* @see {@link FixedChild} for usage
|
|
77
84
|
*/
|
|
78
|
-
export type FixedChildProps =
|
|
85
|
+
export type FixedChildProps = VirtualSlotProps & {
|
|
79
86
|
/** X coordinate in pixels */
|
|
80
87
|
x?: number;
|
|
81
88
|
/** Y coordinate in pixels */
|
|
@@ -131,18 +138,18 @@ export type ColumnViewRootProps<C extends string = string> = {
|
|
|
131
138
|
/**
|
|
132
139
|
* Props for notebook (tabbed) pages.
|
|
133
140
|
*/
|
|
134
|
-
export type NotebookPageProps =
|
|
141
|
+
export type NotebookPageProps = VirtualSlotProps & {
|
|
135
142
|
/** Tab label text (optional when using Notebook.PageTab) */
|
|
136
143
|
label?: string;
|
|
137
144
|
};
|
|
138
145
|
/**
|
|
139
146
|
* Props for custom notebook page tab widgets.
|
|
140
147
|
*/
|
|
141
|
-
export type NotebookPageTabProps =
|
|
148
|
+
export type NotebookPageTabProps = VirtualSlotProps;
|
|
142
149
|
/**
|
|
143
150
|
* Props for the root Stack component.
|
|
144
151
|
*/
|
|
145
|
-
export type StackRootProps =
|
|
152
|
+
export type StackRootProps = VirtualSlotProps & {
|
|
146
153
|
/** ID of the currently visible page */
|
|
147
154
|
page?: string;
|
|
148
155
|
};
|
|
@@ -151,7 +158,7 @@ export type StackRootProps = Omit<SlotProps, "id"> & {
|
|
|
151
158
|
*
|
|
152
159
|
* @see {@link StackPage} for usage
|
|
153
160
|
*/
|
|
154
|
-
export type StackPageProps =
|
|
161
|
+
export type StackPageProps = VirtualSlotProps & {
|
|
155
162
|
/** Unique identifier for this page (used with page prop) */
|
|
156
163
|
id?: string;
|
|
157
164
|
/** Display title shown in stack switchers */
|
|
@@ -205,7 +212,7 @@ export type MenuSubmenuProps = {
|
|
|
205
212
|
/**
|
|
206
213
|
* Props for children within an Overlay container.
|
|
207
214
|
*/
|
|
208
|
-
export type OverlayChildProps =
|
|
215
|
+
export type OverlayChildProps = VirtualSlotProps & {
|
|
209
216
|
/** Whether to include this child in size measurement */
|
|
210
217
|
measure?: boolean;
|
|
211
218
|
/** Whether to clip this overlay child to the main child bounds */
|
|
@@ -307,33 +314,45 @@ export type ExpanderRowChildProps = {
|
|
|
307
314
|
/** Children to add to this slot */
|
|
308
315
|
children?: ReactNode;
|
|
309
316
|
};
|
|
317
|
+
type NavigationPageBaseProps = {
|
|
318
|
+
title?: string;
|
|
319
|
+
canPop?: boolean;
|
|
320
|
+
children?: ReactNode;
|
|
321
|
+
};
|
|
310
322
|
/**
|
|
311
|
-
* Props for the NavigationPage virtual element.
|
|
323
|
+
* Props for the NavigationPage virtual element with type-safe targeting.
|
|
312
324
|
*
|
|
313
|
-
*
|
|
325
|
+
* The `for` prop is required and determines valid `id` values:
|
|
326
|
+
* - `AdwNavigationView`: `id` can be any string (page tags for navigation history)
|
|
327
|
+
* - `AdwNavigationSplitView`: `id` is narrowed to `"content" | "sidebar"` (slot positions)
|
|
314
328
|
*
|
|
315
329
|
* @example
|
|
316
330
|
* ```tsx
|
|
331
|
+
* // In NavigationView - id can be any string
|
|
317
332
|
* <AdwNavigationView history={["home", "details"]}>
|
|
318
|
-
* <x.NavigationPage id="home" title="Home">
|
|
333
|
+
* <x.NavigationPage for={AdwNavigationView} id="home" title="Home">
|
|
319
334
|
* <HomeContent />
|
|
320
335
|
* </x.NavigationPage>
|
|
321
|
-
* <x.NavigationPage id="details" title="Details">
|
|
322
|
-
* <DetailsContent />
|
|
323
|
-
* </x.NavigationPage>
|
|
324
336
|
* </AdwNavigationView>
|
|
337
|
+
*
|
|
338
|
+
* // In NavigationSplitView - id is narrowed to "content" | "sidebar"
|
|
339
|
+
* <AdwNavigationSplitView>
|
|
340
|
+
* <x.NavigationPage for={AdwNavigationSplitView} id="sidebar" title="Sidebar">
|
|
341
|
+
* <SidebarContent />
|
|
342
|
+
* </x.NavigationPage>
|
|
343
|
+
* <x.NavigationPage for={AdwNavigationSplitView} id="content" title="Content">
|
|
344
|
+
* <MainContent />
|
|
345
|
+
* </x.NavigationPage>
|
|
346
|
+
* </AdwNavigationSplitView>
|
|
325
347
|
* ```
|
|
326
348
|
*/
|
|
327
|
-
export type NavigationPageProps = {
|
|
328
|
-
|
|
349
|
+
export type NavigationPageProps = (NavigationPageBaseProps & {
|
|
350
|
+
for: "AdwNavigationView";
|
|
329
351
|
id: string;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
/** Page content */
|
|
335
|
-
children?: ReactNode;
|
|
336
|
-
};
|
|
352
|
+
}) | (NavigationPageBaseProps & {
|
|
353
|
+
for: "AdwNavigationSplitView";
|
|
354
|
+
id: import("./generated/jsx.js").WidgetSlotNames["AdwNavigationSplitView"];
|
|
355
|
+
});
|
|
337
356
|
/**
|
|
338
357
|
* Type mapping widget names to their available slot IDs.
|
|
339
358
|
*/
|
|
@@ -772,18 +791,30 @@ export declare const x: {
|
|
|
772
791
|
*/
|
|
773
792
|
ExpanderRowAction: "ExpanderRowAction";
|
|
774
793
|
/**
|
|
775
|
-
*
|
|
794
|
+
* Type-safe page component for AdwNavigationView or AdwNavigationSplitView.
|
|
795
|
+
*
|
|
796
|
+
* The `for` prop is required and determines valid `id` values:
|
|
797
|
+
* - `AdwNavigationView`: any string (page tags for navigation history)
|
|
798
|
+
* - `AdwNavigationSplitView`: `"content"` or `"sidebar"` (slot positions)
|
|
776
799
|
*
|
|
777
800
|
* @example
|
|
778
801
|
* ```tsx
|
|
802
|
+
* // In NavigationView - id can be any string
|
|
779
803
|
* <AdwNavigationView history={["home"]}>
|
|
780
|
-
* <x.NavigationPage id="home" title="Home">
|
|
804
|
+
* <x.NavigationPage for={AdwNavigationView} id="home" title="Home">
|
|
781
805
|
* <GtkLabel label="Welcome!" />
|
|
782
806
|
* </x.NavigationPage>
|
|
783
|
-
* <x.NavigationPage id="settings" title="Settings">
|
|
784
|
-
* <GtkLabel label="Settings page" />
|
|
785
|
-
* </x.NavigationPage>
|
|
786
807
|
* </AdwNavigationView>
|
|
808
|
+
*
|
|
809
|
+
* // In NavigationSplitView - id is narrowed to "content" | "sidebar"
|
|
810
|
+
* <AdwNavigationSplitView>
|
|
811
|
+
* <x.NavigationPage for={AdwNavigationSplitView} id="sidebar" title="Sidebar">
|
|
812
|
+
* <GtkLabel label="Sidebar" />
|
|
813
|
+
* </x.NavigationPage>
|
|
814
|
+
* <x.NavigationPage for={AdwNavigationSplitView} id="content" title="Content">
|
|
815
|
+
* <GtkLabel label="Content" />
|
|
816
|
+
* </x.NavigationPage>
|
|
817
|
+
* </AdwNavigationSplitView>
|
|
787
818
|
* ```
|
|
788
819
|
*/
|
|
789
820
|
NavigationPage: "NavigationPage";
|
|
@@ -792,8 +823,8 @@ declare global {
|
|
|
792
823
|
namespace React {
|
|
793
824
|
namespace JSX {
|
|
794
825
|
interface IntrinsicElements {
|
|
795
|
-
ActionRowPrefix:
|
|
796
|
-
ActionRowSuffix:
|
|
826
|
+
ActionRowPrefix: VirtualSlotProps;
|
|
827
|
+
ActionRowSuffix: VirtualSlotProps;
|
|
797
828
|
CalendarMark: CalendarMarkProps;
|
|
798
829
|
ColumnViewColumn: ColumnViewColumnProps<any>;
|
|
799
830
|
ExpanderRowAction: ExpanderRowChildProps;
|
|
@@ -806,16 +837,16 @@ declare global {
|
|
|
806
837
|
MenuSection: MenuSectionProps;
|
|
807
838
|
MenuSubmenu: MenuSubmenuProps;
|
|
808
839
|
NotebookPage: NotebookPageProps;
|
|
809
|
-
NotebookPageTab:
|
|
840
|
+
NotebookPageTab: VirtualSlotProps;
|
|
810
841
|
OverlayChild: OverlayChildProps;
|
|
811
|
-
PackEnd:
|
|
812
|
-
PackStart:
|
|
842
|
+
PackEnd: VirtualSlotProps;
|
|
843
|
+
PackStart: VirtualSlotProps;
|
|
813
844
|
ScaleMark: ScaleMarkProps;
|
|
814
845
|
SimpleListItem: StringListItemProps;
|
|
815
846
|
StackPage: StackPageProps;
|
|
816
847
|
Toggle: ToggleProps;
|
|
817
|
-
ToolbarBottom:
|
|
818
|
-
ToolbarTop:
|
|
848
|
+
ToolbarBottom: VirtualSlotProps;
|
|
849
|
+
ToolbarTop: VirtualSlotProps;
|
|
819
850
|
TreeListItem: TreeListItemProps<any>;
|
|
820
851
|
NavigationPage: NavigationPageProps;
|
|
821
852
|
}
|
package/dist/jsx.js
CHANGED
|
@@ -398,18 +398,30 @@ export const x = {
|
|
|
398
398
|
*/
|
|
399
399
|
ExpanderRowAction: "ExpanderRowAction",
|
|
400
400
|
/**
|
|
401
|
-
*
|
|
401
|
+
* Type-safe page component for AdwNavigationView or AdwNavigationSplitView.
|
|
402
|
+
*
|
|
403
|
+
* The `for` prop is required and determines valid `id` values:
|
|
404
|
+
* - `AdwNavigationView`: any string (page tags for navigation history)
|
|
405
|
+
* - `AdwNavigationSplitView`: `"content"` or `"sidebar"` (slot positions)
|
|
402
406
|
*
|
|
403
407
|
* @example
|
|
404
408
|
* ```tsx
|
|
409
|
+
* // In NavigationView - id can be any string
|
|
405
410
|
* <AdwNavigationView history={["home"]}>
|
|
406
|
-
* <x.NavigationPage id="home" title="Home">
|
|
411
|
+
* <x.NavigationPage for={AdwNavigationView} id="home" title="Home">
|
|
407
412
|
* <GtkLabel label="Welcome!" />
|
|
408
413
|
* </x.NavigationPage>
|
|
409
|
-
* <x.NavigationPage id="settings" title="Settings">
|
|
410
|
-
* <GtkLabel label="Settings page" />
|
|
411
|
-
* </x.NavigationPage>
|
|
412
414
|
* </AdwNavigationView>
|
|
415
|
+
*
|
|
416
|
+
* // In NavigationSplitView - id is narrowed to "content" | "sidebar"
|
|
417
|
+
* <AdwNavigationSplitView>
|
|
418
|
+
* <x.NavigationPage for={AdwNavigationSplitView} id="sidebar" title="Sidebar">
|
|
419
|
+
* <GtkLabel label="Sidebar" />
|
|
420
|
+
* </x.NavigationPage>
|
|
421
|
+
* <x.NavigationPage for={AdwNavigationSplitView} id="content" title="Content">
|
|
422
|
+
* <GtkLabel label="Content" />
|
|
423
|
+
* </x.NavigationPage>
|
|
424
|
+
* </AdwNavigationSplitView>
|
|
413
425
|
* ```
|
|
414
426
|
*/
|
|
415
427
|
NavigationPage: "NavigationPage",
|
|
@@ -23,20 +23,20 @@ class ApplicationNode extends Node {
|
|
|
23
23
|
this.container.setMenubar(this.menu.getMenu());
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
-
if (child instanceof WindowNode) {
|
|
26
|
+
if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
|
-
throw new Error(`Cannot append '${child.typeName}' to 'Application': expected
|
|
29
|
+
throw new Error(`Cannot append '${child.typeName}' to 'Application': expected ApplicationWindow or MenuItem`);
|
|
30
30
|
}
|
|
31
31
|
insertBefore(child, before) {
|
|
32
32
|
if (child instanceof MenuNode) {
|
|
33
33
|
this.menu.insertBefore(child, before);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
if (child instanceof WindowNode) {
|
|
36
|
+
if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
|
-
throw new Error(`Cannot insert '${child.typeName}' into 'Application': expected
|
|
39
|
+
throw new Error(`Cannot insert '${child.typeName}' into 'Application': expected ApplicationWindow or MenuItem`);
|
|
40
40
|
}
|
|
41
41
|
removeChild(child) {
|
|
42
42
|
if (child instanceof MenuNode) {
|
|
@@ -48,10 +48,10 @@ class ApplicationNode extends Node {
|
|
|
48
48
|
}, CommitPriority.LOW);
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
if (child instanceof WindowNode) {
|
|
51
|
+
if (child instanceof WindowNode && child.container instanceof Gtk.ApplicationWindow) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
throw new Error(`Cannot remove '${child.typeName}' from 'Application': expected
|
|
54
|
+
throw new Error(`Cannot remove '${child.typeName}' from 'Application': expected ApplicationWindow or MenuItem`);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
registerNodeClass(ApplicationNode);
|
package/dist/nodes/index.d.ts
CHANGED
package/dist/nodes/index.js
CHANGED
|
@@ -7,4 +7,15 @@ export const EVENT_CONTROLLER_PROPS = new Set([
|
|
|
7
7
|
"onKeyPressed",
|
|
8
8
|
"onKeyReleased",
|
|
9
9
|
"onScroll",
|
|
10
|
+
"onDragPrepare",
|
|
11
|
+
"onDragBegin",
|
|
12
|
+
"onDragEnd",
|
|
13
|
+
"onDragCancel",
|
|
14
|
+
"dragActions",
|
|
15
|
+
"onDrop",
|
|
16
|
+
"onDropEnter",
|
|
17
|
+
"onDropLeave",
|
|
18
|
+
"onDropMotion",
|
|
19
|
+
"dropActions",
|
|
20
|
+
"dropTypes",
|
|
10
21
|
]);
|
|
@@ -35,7 +35,7 @@ export class ListItemRenderer {
|
|
|
35
35
|
initialize() {
|
|
36
36
|
signalStore.set(this, this.factory, "setup", (_self, listItem) => {
|
|
37
37
|
const ptr = getNativeId(listItem.handle);
|
|
38
|
-
const box = new Gtk.Box(Gtk.Orientation.VERTICAL
|
|
38
|
+
const box = new Gtk.Box(Gtk.Orientation.VERTICAL);
|
|
39
39
|
if (this.estimatedItemHeight !== undefined) {
|
|
40
40
|
box.setSizeRequest(-1, this.estimatedItemHeight);
|
|
41
41
|
}
|
|
@@ -39,7 +39,7 @@ export class TreeListItemRenderer {
|
|
|
39
39
|
signalStore.set(this, this.factory, "setup", (_self, listItem) => {
|
|
40
40
|
const ptr = getNativeId(listItem.handle);
|
|
41
41
|
const expander = new Gtk.TreeExpander();
|
|
42
|
-
const box = new Gtk.Box(Gtk.Orientation.VERTICAL
|
|
42
|
+
const box = new Gtk.Box(Gtk.Orientation.VERTICAL);
|
|
43
43
|
if (this.estimatedItemHeight !== undefined) {
|
|
44
44
|
box.setSizeRequest(-1, this.estimatedItemHeight);
|
|
45
45
|
}
|
package/dist/nodes/list-view.js
CHANGED
|
@@ -53,7 +53,12 @@ class ListViewNode extends WidgetNode {
|
|
|
53
53
|
if (!oldProps || oldProps.estimatedItemHeight !== newProps.estimatedItemHeight) {
|
|
54
54
|
this.itemRenderer.setEstimatedItemHeight(newProps.estimatedItemHeight);
|
|
55
55
|
}
|
|
56
|
+
const previousModel = this.list.getSelectionModel();
|
|
56
57
|
this.list.updateProps(oldProps ? filterProps(oldProps, PROP_NAMES) : null, filterProps(newProps, PROP_NAMES));
|
|
58
|
+
const currentModel = this.list.getSelectionModel();
|
|
59
|
+
if (previousModel !== currentModel) {
|
|
60
|
+
this.container.setModel(currentModel);
|
|
61
|
+
}
|
|
57
62
|
super.updateProps(oldProps ? filterProps(oldProps, PROP_NAMES) : null, filterProps(newProps, PROP_NAMES));
|
|
58
63
|
}
|
|
59
64
|
}
|
|
@@ -7,14 +7,17 @@ export type ListProps = {
|
|
|
7
7
|
selected?: string[];
|
|
8
8
|
onSelectionChanged?: (ids: string[]) => void;
|
|
9
9
|
};
|
|
10
|
+
type SelectionModel = Gtk.NoSelection | Gtk.SingleSelection | Gtk.MultiSelection;
|
|
10
11
|
export declare class List extends VirtualNode<ListProps> {
|
|
11
12
|
private store;
|
|
12
13
|
private selectionModel;
|
|
13
14
|
private handleSelectionChange?;
|
|
15
|
+
private pendingSelection?;
|
|
16
|
+
private selectionScheduled;
|
|
14
17
|
constructor(props?: ListProps);
|
|
15
18
|
private initSelectionHandler;
|
|
16
19
|
getStore(): ListStore;
|
|
17
|
-
getSelectionModel():
|
|
20
|
+
getSelectionModel(): SelectionModel;
|
|
18
21
|
appendChild(child: Node): void;
|
|
19
22
|
insertBefore(child: Node, before: Node): void;
|
|
20
23
|
removeChild(child: Node): void;
|
|
@@ -22,4 +25,6 @@ export declare class List extends VirtualNode<ListProps> {
|
|
|
22
25
|
private createSelectionModel;
|
|
23
26
|
private getSelection;
|
|
24
27
|
private setSelection;
|
|
28
|
+
private applySelection;
|
|
25
29
|
}
|
|
30
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import { CommitPriority, scheduleAfterCommit } from "../../scheduler.js";
|
|
2
3
|
import { ListStore } from "../internal/list-store.js";
|
|
3
4
|
import { signalStore } from "../internal/signal-store.js";
|
|
4
5
|
import { ListItemNode } from "../list-item.js";
|
|
@@ -7,6 +8,8 @@ export class List extends VirtualNode {
|
|
|
7
8
|
store;
|
|
8
9
|
selectionModel;
|
|
9
10
|
handleSelectionChange;
|
|
11
|
+
pendingSelection;
|
|
12
|
+
selectionScheduled = false;
|
|
10
13
|
constructor(props = {}) {
|
|
11
14
|
super("", {}, undefined);
|
|
12
15
|
this.store = new ListStore();
|
|
@@ -71,13 +74,15 @@ export class List extends VirtualNode {
|
|
|
71
74
|
createSelectionModel(mode) {
|
|
72
75
|
const model = this.store.getModel();
|
|
73
76
|
const selectionMode = mode ?? Gtk.SelectionMode.SINGLE;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
: new Gtk.SingleSelection(model);
|
|
77
|
-
if (selectionModel instanceof Gtk.SingleSelection) {
|
|
78
|
-
selectionModel.setAutoselect(false);
|
|
79
|
-
selectionModel.setCanUnselect(true);
|
|
77
|
+
if (selectionMode === Gtk.SelectionMode.NONE) {
|
|
78
|
+
return new Gtk.NoSelection(model);
|
|
80
79
|
}
|
|
80
|
+
if (selectionMode === Gtk.SelectionMode.MULTIPLE) {
|
|
81
|
+
return new Gtk.MultiSelection(model);
|
|
82
|
+
}
|
|
83
|
+
const selectionModel = new Gtk.SingleSelection(model);
|
|
84
|
+
selectionModel.setAutoselect(selectionMode === Gtk.SelectionMode.BROWSE);
|
|
85
|
+
selectionModel.setCanUnselect(selectionMode !== Gtk.SelectionMode.BROWSE);
|
|
81
86
|
return selectionModel;
|
|
82
87
|
}
|
|
83
88
|
getSelection() {
|
|
@@ -95,6 +100,16 @@ export class List extends VirtualNode {
|
|
|
95
100
|
return ids;
|
|
96
101
|
}
|
|
97
102
|
setSelection(ids) {
|
|
103
|
+
this.pendingSelection = ids;
|
|
104
|
+
if (!this.selectionScheduled) {
|
|
105
|
+
this.selectionScheduled = true;
|
|
106
|
+
scheduleAfterCommit(() => this.applySelection(), CommitPriority.LOW);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
applySelection() {
|
|
110
|
+
this.selectionScheduled = false;
|
|
111
|
+
const ids = this.pendingSelection;
|
|
112
|
+
this.pendingSelection = undefined;
|
|
98
113
|
const model = this.store.getModel();
|
|
99
114
|
const nItems = model.getNItems();
|
|
100
115
|
const selected = new Gtk.Bitset();
|
|
@@ -8,17 +8,20 @@ export type TreeListProps = {
|
|
|
8
8
|
selected?: string[];
|
|
9
9
|
onSelectionChanged?: (ids: string[]) => void;
|
|
10
10
|
};
|
|
11
|
+
type SelectionModel = Gtk.NoSelection | Gtk.SingleSelection | Gtk.MultiSelection;
|
|
11
12
|
export declare class TreeList extends VirtualNode<TreeListProps> {
|
|
12
13
|
private store;
|
|
13
14
|
private treeListModel;
|
|
14
15
|
private selectionModel;
|
|
15
16
|
private handleSelectionChange?;
|
|
17
|
+
private pendingSelection?;
|
|
18
|
+
private selectionScheduled;
|
|
16
19
|
constructor(props?: TreeListProps);
|
|
17
20
|
private initSelectionHandler;
|
|
18
21
|
private createChildModel;
|
|
19
22
|
getStore(): TreeStore;
|
|
20
23
|
getTreeListModel(): Gtk.TreeListModel;
|
|
21
|
-
getSelectionModel():
|
|
24
|
+
getSelectionModel(): SelectionModel;
|
|
22
25
|
appendChild(child: Node): void;
|
|
23
26
|
insertBefore(child: Node, before: Node): void;
|
|
24
27
|
removeChild(child: Node): void;
|
|
@@ -26,4 +29,6 @@ export declare class TreeList extends VirtualNode<TreeListProps> {
|
|
|
26
29
|
private createSelectionModel;
|
|
27
30
|
private getSelection;
|
|
28
31
|
private setSelection;
|
|
32
|
+
private applySelection;
|
|
29
33
|
}
|
|
34
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
-
import { scheduleAfterCommit } from "../../scheduler.js";
|
|
2
|
+
import { CommitPriority, scheduleAfterCommit } from "../../scheduler.js";
|
|
3
3
|
import { signalStore } from "../internal/signal-store.js";
|
|
4
4
|
import { TreeStore } from "../internal/tree-store.js";
|
|
5
5
|
import { TreeListItemNode } from "../tree-list-item.js";
|
|
@@ -9,6 +9,8 @@ export class TreeList extends VirtualNode {
|
|
|
9
9
|
treeListModel;
|
|
10
10
|
selectionModel;
|
|
11
11
|
handleSelectionChange;
|
|
12
|
+
pendingSelection;
|
|
13
|
+
selectionScheduled = false;
|
|
12
14
|
constructor(props = {}) {
|
|
13
15
|
super("", {}, undefined);
|
|
14
16
|
this.store = new TreeStore();
|
|
@@ -117,13 +119,15 @@ export class TreeList extends VirtualNode {
|
|
|
117
119
|
}
|
|
118
120
|
createSelectionModel(mode) {
|
|
119
121
|
const selectionMode = mode ?? Gtk.SelectionMode.SINGLE;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
: new Gtk.SingleSelection(this.treeListModel);
|
|
123
|
-
if (selectionModel instanceof Gtk.SingleSelection) {
|
|
124
|
-
selectionModel.setAutoselect(false);
|
|
125
|
-
selectionModel.setCanUnselect(true);
|
|
122
|
+
if (selectionMode === Gtk.SelectionMode.NONE) {
|
|
123
|
+
return new Gtk.NoSelection(this.treeListModel);
|
|
126
124
|
}
|
|
125
|
+
if (selectionMode === Gtk.SelectionMode.MULTIPLE) {
|
|
126
|
+
return new Gtk.MultiSelection(this.treeListModel);
|
|
127
|
+
}
|
|
128
|
+
const selectionModel = new Gtk.SingleSelection(this.treeListModel);
|
|
129
|
+
selectionModel.setAutoselect(selectionMode === Gtk.SelectionMode.BROWSE);
|
|
130
|
+
selectionModel.setCanUnselect(selectionMode !== Gtk.SelectionMode.BROWSE);
|
|
127
131
|
return selectionModel;
|
|
128
132
|
}
|
|
129
133
|
getSelection() {
|
|
@@ -143,6 +147,16 @@ export class TreeList extends VirtualNode {
|
|
|
143
147
|
return ids;
|
|
144
148
|
}
|
|
145
149
|
setSelection(ids) {
|
|
150
|
+
this.pendingSelection = ids;
|
|
151
|
+
if (!this.selectionScheduled) {
|
|
152
|
+
this.selectionScheduled = true;
|
|
153
|
+
scheduleAfterCommit(() => this.applySelection(), CommitPriority.LOW);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
applySelection() {
|
|
157
|
+
this.selectionScheduled = false;
|
|
158
|
+
const ids = this.pendingSelection;
|
|
159
|
+
this.pendingSelection = undefined;
|
|
146
160
|
const nItems = this.treeListModel.getNItems();
|
|
147
161
|
const selected = new Gtk.Bitset();
|
|
148
162
|
const mask = Gtk.Bitset.newRange(0, nItems);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as Gtk from "@gtkx/ffi/gtk";
|
|
2
|
+
import { registerNodeClass } from "../registry.js";
|
|
3
|
+
import { filterProps, isContainerType } from "./internal/utils.js";
|
|
4
|
+
import { WidgetNode } from "./widget.js";
|
|
5
|
+
const PROPS = ["hscrollbarPolicy", "vscrollbarPolicy"];
|
|
6
|
+
class ScrolledWindowNode extends WidgetNode {
|
|
7
|
+
static priority = 2;
|
|
8
|
+
static matches(_type, containerOrClass) {
|
|
9
|
+
return isContainerType(Gtk.ScrolledWindow, containerOrClass);
|
|
10
|
+
}
|
|
11
|
+
updateProps(oldProps, newProps) {
|
|
12
|
+
if (oldProps?.hscrollbarPolicy !== newProps.hscrollbarPolicy ||
|
|
13
|
+
oldProps?.vscrollbarPolicy !== newProps.vscrollbarPolicy) {
|
|
14
|
+
const hPolicy = newProps.hscrollbarPolicy ?? Gtk.PolicyType.AUTOMATIC;
|
|
15
|
+
const vPolicy = newProps.vscrollbarPolicy ?? Gtk.PolicyType.AUTOMATIC;
|
|
16
|
+
this.container.setPolicy(hPolicy, vPolicy);
|
|
17
|
+
}
|
|
18
|
+
super.updateProps(filterProps(oldProps ?? {}, PROPS), filterProps(newProps, PROPS));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
registerNodeClass(ScrolledWindowNode);
|
package/dist/nodes/slot.js
CHANGED
|
@@ -17,11 +17,20 @@ export class SlotNode extends VirtualNode {
|
|
|
17
17
|
}
|
|
18
18
|
unmount() {
|
|
19
19
|
if (this.parent && this.child) {
|
|
20
|
+
const parent = this.parent;
|
|
20
21
|
const oldChild = this.child;
|
|
21
22
|
this.child = undefined;
|
|
22
|
-
|
|
23
|
+
queueMicrotask(() => {
|
|
24
|
+
if (parent.getRoot() !== null) {
|
|
25
|
+
this.parent = parent;
|
|
26
|
+
this.onChildChange(oldChild);
|
|
27
|
+
}
|
|
28
|
+
this.parent = undefined;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.parent = undefined;
|
|
23
33
|
}
|
|
24
|
-
this.parent = undefined;
|
|
25
34
|
super.unmount();
|
|
26
35
|
}
|
|
27
36
|
getId() {
|
|
@@ -59,7 +59,12 @@ class TreeListViewNode extends WidgetNode {
|
|
|
59
59
|
if (!oldProps || oldProps.estimatedItemHeight !== newProps.estimatedItemHeight) {
|
|
60
60
|
this.itemRenderer.setEstimatedItemHeight(newProps.estimatedItemHeight);
|
|
61
61
|
}
|
|
62
|
+
const previousModel = this.treeList.getSelectionModel();
|
|
62
63
|
this.treeList.updateProps(oldProps ? filterProps(oldProps, RENDERER_PROP_NAMES) : null, filterProps(newProps, RENDERER_PROP_NAMES));
|
|
64
|
+
const currentModel = this.treeList.getSelectionModel();
|
|
65
|
+
if (previousModel !== currentModel) {
|
|
66
|
+
this.container.setModel(currentModel);
|
|
67
|
+
}
|
|
63
68
|
super.updateProps(oldProps ? filterProps(oldProps, PROP_NAMES) : null, filterProps(newProps, PROP_NAMES));
|
|
64
69
|
}
|
|
65
70
|
}
|
package/dist/nodes/widget.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export declare class WidgetNode<T extends Gtk.Widget = Gtk.Widget, P extends Pro
|
|
|
7
7
|
private clickController?;
|
|
8
8
|
private keyController?;
|
|
9
9
|
private scrollController?;
|
|
10
|
+
private dragSourceController?;
|
|
11
|
+
private dropTargetController?;
|
|
10
12
|
static matches(_type: string, containerOrClass?: Container | ContainerClass | null): boolean;
|
|
11
13
|
static createContainer(props: Props, containerClass: typeof Gtk.Widget): Container | null;
|
|
12
14
|
appendChild(child: Node): void;
|
|
@@ -15,7 +17,10 @@ export declare class WidgetNode<T extends Gtk.Widget = Gtk.Widget, P extends Pro
|
|
|
15
17
|
private insertBeforeReorderable;
|
|
16
18
|
private insertBeforeInsertable;
|
|
17
19
|
updateProps(oldProps: P | null, newProps: P): void;
|
|
20
|
+
private updateSizeRequest;
|
|
18
21
|
private updateEventControllerProp;
|
|
22
|
+
private ensureDragSource;
|
|
23
|
+
private ensureDropTarget;
|
|
19
24
|
private updateNotifyHandler;
|
|
20
25
|
private propNameToSignalName;
|
|
21
26
|
private getProperty;
|