@gjsify/adwaita-nativescript 0.64.13-next.283 → 0.64.14
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/lib/esm/builder/index.js +1 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/namespace/gio.js +1 -1
- package/lib/esm/namespace/gtk.js +1 -1
- package/lib/esm/widgets/adw-about-dialog.js +3 -3
- package/lib/esm/widgets/adw-action-row.js +1 -1
- package/lib/esm/widgets/adw-avatar.js +1 -1
- package/lib/esm/widgets/adw-banner.js +1 -1
- package/lib/esm/widgets/adw-bottom-sheet.js +1 -1
- package/lib/esm/widgets/adw-button-row.js +1 -1
- package/lib/esm/widgets/adw-carousel.js +1 -1
- package/lib/esm/widgets/adw-combo-row.js +1 -1
- package/lib/esm/widgets/adw-data-grid.js +1 -1
- package/lib/esm/widgets/adw-dialog.js +1 -1
- package/lib/esm/widgets/adw-entry-row.js +1 -1
- package/lib/esm/widgets/adw-image-button.js +1 -1
- package/lib/esm/widgets/adw-navigation-page.js +1 -1
- package/lib/esm/widgets/adw-navigation-split-view.js +1 -1
- package/lib/esm/widgets/adw-navigation-view.js +1 -1
- package/lib/esm/widgets/adw-overlay-split-view.js +1 -1
- package/lib/esm/widgets/adw-password-entry-row.js +1 -1
- package/lib/esm/widgets/adw-preferences-dialog.js +1 -1
- package/lib/esm/widgets/adw-preferences-group.js +1 -1
- package/lib/esm/widgets/adw-preferences-page.js +1 -1
- package/lib/esm/widgets/adw-sidebar.js +1 -1
- package/lib/esm/widgets/adw-slider-row.js +1 -1
- package/lib/esm/widgets/adw-spin-row.js +1 -1
- package/lib/esm/widgets/adw-split-button.js +1 -1
- package/lib/esm/widgets/adw-tab-view.js +1 -1
- package/lib/esm/widgets/adw-toggle-group.js +1 -1
- package/lib/esm/widgets/adw-toolbar-view.js +1 -1
- package/lib/esm/widgets/adw-view-switcher-bar.js +1 -1
- package/lib/esm/widgets/adw-wrap-box.js +1 -1
- package/lib/esm/widgets/box-layout.js +1 -1
- package/lib/esm/widgets/construct-props.js +1 -1
- package/lib/esm/widgets/gtk-action-bar.js +1 -1
- package/lib/esm/widgets/gtk-box.js +1 -1
- package/lib/esm/widgets/gtk-button.js +1 -1
- package/lib/esm/widgets/gtk-check-button.js +1 -1
- package/lib/esm/widgets/gtk-drawing-area.js +1 -1
- package/lib/esm/widgets/gtk-drop-down.js +1 -1
- package/lib/esm/widgets/gtk-entry.js +1 -1
- package/lib/esm/widgets/gtk-grid.js +1 -1
- package/lib/esm/widgets/gtk-icon-size.js +1 -1
- package/lib/esm/widgets/gtk-image.js +1 -1
- package/lib/esm/widgets/gtk-label.js +2 -2
- package/lib/esm/widgets/gtk-list-box.js +1 -1
- package/lib/esm/widgets/gtk-menu-button.js +1 -1
- package/lib/esm/widgets/gtk-popover-menu.js +1 -1
- package/lib/esm/widgets/gtk-revealer.js +1 -1
- package/lib/esm/widgets/gtk-scrolled-window.js +1 -1
- package/lib/esm/widgets/gtk-stack.js +1 -1
- package/lib/esm/widgets/gtk-text-view.js +1 -1
- package/lib/esm/widgets/gtk-toggle-button.js +1 -1
- package/lib/esm/widgets/gtk-window.js +1 -1
- package/lib/esm/widgets/index.js +1 -1
- package/lib/esm/widgets/label-markup-native.android.js +1 -0
- package/lib/esm/widgets/label-markup-native.ios.js +1 -0
- package/lib/esm/widgets/label-markup-native.js +1 -0
- package/lib/esm/widgets/label-markup.js +1 -1
- package/lib/esm/widgets/menu-slot.js +1 -0
- package/lib/esm/widgets/popup-menu-view.js +1 -1
- package/lib/esm/widgets/popup-menu.js +1 -1
- package/lib/esm/widgets/scrolled-window-policy.js +1 -1
- package/lib/esm/widgets/signals.js +1 -1
- package/lib/esm/widgets/single-child-base.js +1 -1
- package/lib/esm/widgets/single-child-cell.js +1 -0
- package/lib/esm/widgets/stack-page.js +1 -1
- package/lib/esm/widgets/transition-type.js +1 -1
- package/lib/esm/widgets/view-stack-page.js +1 -1
- package/lib/esm/widgets/widget-layout.js +1 -1
- package/lib/esm/widgets/xml-values.js +1 -1
- package/lib/types/clamped-bin.spec.d.ts +2 -0
- package/lib/types/combo-row-properties.spec.d.ts +2 -0
- package/lib/types/drop-down-properties.spec.d.ts +2 -0
- package/lib/types/entry-properties.spec.d.ts +1 -0
- package/lib/types/index.d.ts +4 -2
- package/lib/types/menu-model-door.spec.d.ts +1 -0
- package/lib/types/namespace/gio.d.ts +1 -1
- package/lib/types/single-child-cell.spec.d.ts +2 -0
- package/lib/types/template-xalign.spec.d.ts +2 -0
- package/lib/types/testing/ns-core.d.mts +35 -2
- package/lib/types/widgets/actions.d.ts +3 -3
- package/lib/types/widgets/adw-combo-row.d.ts +42 -26
- package/lib/types/widgets/adw-split-button.d.ts +17 -7
- package/lib/types/widgets/box-layout.d.ts +37 -0
- package/lib/types/widgets/gtk-box.d.ts +11 -5
- package/lib/types/widgets/gtk-drop-down.d.ts +41 -33
- package/lib/types/widgets/gtk-entry.d.ts +62 -34
- package/lib/types/widgets/gtk-label.d.ts +24 -0
- package/lib/types/widgets/gtk-menu-button.d.ts +22 -13
- package/lib/types/widgets/gtk-popover-menu.d.ts +7 -7
- package/lib/types/widgets/index.d.ts +2 -4
- package/lib/types/widgets/label-markup-native.android.d.ts +5 -0
- package/lib/types/widgets/label-markup-native.d.ts +19 -0
- package/lib/types/widgets/label-markup-native.ios.d.ts +5 -0
- package/lib/types/widgets/label-markup.d.ts +62 -1
- package/lib/types/widgets/menu-slot.d.ts +40 -0
- package/lib/types/widgets/popup-menu-view.d.ts +3 -2
- package/lib/types/widgets/popup-menu.d.ts +8 -6
- package/lib/types/widgets/signals.d.ts +33 -8
- package/lib/types/widgets/single-child-base.d.ts +5 -0
- package/lib/types/widgets/single-child-cell.d.ts +13 -0
- package/lib/types/widgets/xml-values.d.ts +12 -0
- package/package.json +13 -14
- package/src/testing/ns-core.mts +74 -2
- package/src/theme/adwaita.css +24 -11
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { LabelMarkupNativeText } from './label-markup.js';
|
|
2
|
+
/**
|
|
3
|
+
* Record the markup `label` must draw natively, or clear it with `null` — answers whether
|
|
4
|
+
* this host draws its own styled text at all, so a caller can take the `FormattedString`
|
|
5
|
+
* path on the same condition it would take it on.
|
|
6
|
+
*
|
|
7
|
+
* A host that answers `true` here MUST answer `true` from {@link labelMarkupDrawNative}
|
|
8
|
+
* for as long as something is held, and the caller may rely on that: nothing re-reads the
|
|
9
|
+
* markup between the hold and the write.
|
|
10
|
+
*/
|
|
11
|
+
export declare function labelMarkupHoldNative(_label: object, _text: LabelMarkupNativeText | null): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Draw the held markup into `label`'s native text view — `false` when there is nothing held
|
|
14
|
+
* or this host has no such text, and then the caller lets `TextBase._setNativeText` run.
|
|
15
|
+
*
|
|
16
|
+
* `reset` is the platform's own "clear the text" call, which no styled text can answer:
|
|
17
|
+
* it is always refused so the base implementation clears the view.
|
|
18
|
+
*/
|
|
19
|
+
export declare function labelMarkupDrawNative(_label: object, _reset: boolean): boolean;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LabelMarkupNativeText } from './label-markup.js';
|
|
2
|
+
/** Record what `label` must draw natively — iOS draws none. See {@link labelMarkupHoldNative}. */
|
|
3
|
+
export declare function labelMarkupHoldNative(_label: object, _text: LabelMarkupNativeText | null): boolean;
|
|
4
|
+
/** Draw the held markup — iOS holds none. See {@link labelMarkupDrawNative}. */
|
|
5
|
+
export declare function labelMarkupDrawNative(_label: object, _reset: boolean): boolean;
|
|
@@ -1,5 +1,66 @@
|
|
|
1
1
|
import { FormattedString, Span } from '@nativescript/core';
|
|
2
|
-
import { type LabelMarkupRender, type LabelMarkupRun } from '@gjsify/adwaita-core';
|
|
2
|
+
import { type LabelMarkupRender, type LabelMarkupRun, type LabelMarkupStyle } from '@gjsify/adwaita-core';
|
|
3
|
+
/**
|
|
4
|
+
* The native FACE one run asks for: the typeface, the two lines, the baseline and the font
|
|
5
|
+
* factor, with pango's tags and `<span>` attributes already resolved against each other.
|
|
6
|
+
*
|
|
7
|
+
* WHY A SECOND SHAPE BESIDE {@link labelMarkupSpan}. A `Span` IS the shape on the surfaces
|
|
8
|
+
* that go through a `FormattedString`, so there the resolution and the write are one
|
|
9
|
+
* function. Android's spans are not a shape at all — `TypefaceSpan`, `StyleSpan`,
|
|
10
|
+
* `UnderlineSpan`, `RelativeSizeSpan` are independent objects over a RANGE of one
|
|
11
|
+
* builder — so the decisions have to be readable before anything native exists, which is
|
|
12
|
+
* also what makes them assertable off a device. `label-markup-native.android.ts` turns one
|
|
13
|
+
* face into those spans and decides nothing else.
|
|
14
|
+
*
|
|
15
|
+
* THE SCALE IS RELATIVE, which is what pango's is. `<big>` is a FACTOR
|
|
16
|
+
* (`PANGO_SCALE_LARGE`), so a platform with a relative span needs no base size and drops
|
|
17
|
+
* nothing — where the `Span` path's `fontSize` is an absolute number of DIPs and has to
|
|
18
|
+
* resolve the factor against a size something has written, which is why it SKIPS the scale
|
|
19
|
+
* when nothing has (see the header). The same markup is therefore more faithful on the
|
|
20
|
+
* native path, not differently faithful; the measured corpus has no `<big>`/`<small>` at
|
|
21
|
+
* all, so no label in it renders differently either way.
|
|
22
|
+
*
|
|
23
|
+
* THE WEIGHT LADDER COLLAPSES TO BOLD, declared rather than approximated: Android picks a
|
|
24
|
+
* weight with `Typeface.create(family, weight, italic)` from API 28 and has nothing but
|
|
25
|
+
* `Typeface.BOLD` below it, and this port supports API 24. So pango's named and numeric
|
|
26
|
+
* weights are read and answered as bold from {@link BOLD_FROM} up. `semilight`, `book` and
|
|
27
|
+
* `ultraheavy` are dropped, which is the same answer {@link SPAN_WEIGHTS} gives them.
|
|
28
|
+
*/
|
|
29
|
+
export interface LabelMarkupFace {
|
|
30
|
+
/** The typeface family, or `undefined` for the view's own. `<tt>` is `monospace`. */
|
|
31
|
+
readonly family: string | undefined;
|
|
32
|
+
readonly bold: boolean;
|
|
33
|
+
readonly italic: boolean;
|
|
34
|
+
readonly underline: boolean;
|
|
35
|
+
readonly strikethrough: boolean;
|
|
36
|
+
/** `<sub>` / `<sup>` — a baseline shift, not a size. */
|
|
37
|
+
readonly script: 'sub' | 'sup' | null;
|
|
38
|
+
/** The font factor `<big>`, `<small>`, `<sub>` and `<sup>` multiply up to. 1 means none. */
|
|
39
|
+
readonly scale: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* One run's style as the face a native span-setter writes.
|
|
43
|
+
*
|
|
44
|
+
* The `<span>` attributes are read OUTERMOST FIRST and the pango tags after, so a tag wins
|
|
45
|
+
* a collision — the same declared order {@link labelMarkupSpan} applies, for the same
|
|
46
|
+
* reason: the runs record the tags as booleans and the `<span>`s as a separate stack, so
|
|
47
|
+
* neither renderer can know which element was inner.
|
|
48
|
+
*/
|
|
49
|
+
export declare function labelMarkupFace(style: LabelMarkupStyle, link: boolean): LabelMarkupFace;
|
|
50
|
+
/**
|
|
51
|
+
* A label's markup as the platform half of this package has to DRAW it — everything
|
|
52
|
+
* `label-markup-native.ts` needs and nothing a `FormattedString` would add.
|
|
53
|
+
*
|
|
54
|
+
* `onLinkTap` rather than the links themselves: following a link is the widget's decision
|
|
55
|
+
* (`GtkLabel._activateLink` runs `::activate-link` under GTK's handled accumulator), and a
|
|
56
|
+
* span-setter that reached for `render.links[i].href` would be making it a second time.
|
|
57
|
+
*/
|
|
58
|
+
export interface LabelMarkupNativeText {
|
|
59
|
+
readonly render: LabelMarkupRender;
|
|
60
|
+
/** `use-underline` — whether the mnemonic marker is stripped out of each run's text. */
|
|
61
|
+
readonly mnemonics: boolean;
|
|
62
|
+
onLinkTap(index: number): void;
|
|
63
|
+
}
|
|
3
64
|
/**
|
|
4
65
|
* One run as one `Span`.
|
|
5
66
|
*
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AdwMenuTree, GioMenuModel } from '@gjsify/adwaita-core';
|
|
2
|
+
export declare class MenuSlot {
|
|
3
|
+
private readonly widget;
|
|
4
|
+
private readonly onItemsChanged;
|
|
5
|
+
private readonly _authored;
|
|
6
|
+
private _model;
|
|
7
|
+
private _tree;
|
|
8
|
+
private _unwatch;
|
|
9
|
+
/**
|
|
10
|
+
* @param widget the class name {@link refuseMenuString} names in its refusal.
|
|
11
|
+
* @param onItemsChanged what to do when the HELD menu mutates under the widget.
|
|
12
|
+
*/
|
|
13
|
+
constructor(widget: string, onItemsChanged: () => void);
|
|
14
|
+
/** The model itself, by identity — what `menuModel` answers. */
|
|
15
|
+
get model(): GioMenuModel | null;
|
|
16
|
+
/** The snapshot `planPopupMenu` reads. Re-taken on each `items-changed`, never aliased. */
|
|
17
|
+
get tree(): AdwMenuTree;
|
|
18
|
+
/**
|
|
19
|
+
* Whether there is anything to show — NOT whether there is a menu.
|
|
20
|
+
*
|
|
21
|
+
* `null` and an empty `Gio.Menu` are different menus, and on GTK they behave
|
|
22
|
+
* differently: an empty non-null model still builds a `GtkPopoverMenu` (measured,
|
|
23
|
+
* `MENU_MODEL_DOOR_VECTORS`). A `PopupMenu` with no items draws no window at all, so
|
|
24
|
+
* this is the question the TAP asks, and the widgets ask `model === null` where GTK asks
|
|
25
|
+
* about the model.
|
|
26
|
+
*/
|
|
27
|
+
get isEmpty(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* A property write: a real model by identity, `null` for no menu — and a `TypeError` for
|
|
30
|
+
* a string, an array or anything else, which this door does not take (`buildMenu` is how
|
|
31
|
+
* an array becomes a model now).
|
|
32
|
+
*
|
|
33
|
+
* The refusal is a THROW because a property assignment is a call: whoever wrote the
|
|
34
|
+
* menu is on the stack and can hear it. There is no second, quieter door here the way
|
|
35
|
+
* the browser has one for markup.
|
|
36
|
+
*/
|
|
37
|
+
write(value: unknown): void;
|
|
38
|
+
/** Hold `next`, snapshot it, and listen to it — the three that always happen together. */
|
|
39
|
+
private _adopt;
|
|
40
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { AdwMenuActions, AdwMenuItem,
|
|
1
|
+
import type { AdwMenuActions, AdwMenuItem, AdwMenuPath, AdwMenuTree } from '@gjsify/adwaita-core';
|
|
2
2
|
import { type ActionHost } from './actions.js';
|
|
3
3
|
import { type PopupMenuSurface } from './popup-menu.js';
|
|
4
4
|
export interface MenuPopupOptions {
|
|
5
|
-
|
|
5
|
+
/** The SNAPSHOT of the menu model, as `MenuSlot.tree` holds it (ADR 0128 § 3). */
|
|
6
|
+
readonly tree: AdwMenuTree;
|
|
6
7
|
/** What the application wrote itself; absent, the registry above `anchor` answers. */
|
|
7
8
|
readonly actions?: AdwMenuActions | null;
|
|
8
9
|
/** A leaf item was chosen, after its action fired. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AdwMenuActions,
|
|
1
|
+
import type { AdwMenuActions, AdwMenuPath, AdwMenuTree, PopupMenuLevelPlan, PopupMenuPlan } from '@gjsify/adwaita-core';
|
|
2
2
|
/** The `MenuItem` calls the driver makes. */
|
|
3
3
|
export interface PopupMenuItemLike {
|
|
4
4
|
setEnabled(enabled: boolean): unknown;
|
|
@@ -33,7 +33,8 @@ export declare const GROUP_DIVIDER_API = 28;
|
|
|
33
33
|
export declare function fillPopupMenu(menu: PopupMenuLike, level: PopupMenuLevelPlan, apiLevel: number): Map<number, AdwMenuPath>;
|
|
34
34
|
export interface OpenPopupMenuOptions {
|
|
35
35
|
readonly surface: PopupMenuSurface;
|
|
36
|
-
|
|
36
|
+
/** The SNAPSHOT of the menu model, as `MenuSlot.tree` holds it (ADR 0128 § 3). */
|
|
37
|
+
readonly tree: AdwMenuTree;
|
|
37
38
|
/** What {@link resolveMenuItemState} reads; from `menuActionsFor` it is the registry's. */
|
|
38
39
|
readonly actions?: AdwMenuActions;
|
|
39
40
|
/** A tap on a leaf item, with its model path. Fire the action here (`activateMenuItem`). */
|
|
@@ -46,14 +47,15 @@ export interface OpenPopupMenuOptions {
|
|
|
46
47
|
*/
|
|
47
48
|
export declare function openPopupMenu(options: OpenPopupMenuOptions): PopupMenuPlan;
|
|
48
49
|
/**
|
|
49
|
-
* Throw if `
|
|
50
|
+
* Throw if `tree` holds what `PopupMenu` can never draw, at the ASSIGNMENT: a `custom` item or a
|
|
50
51
|
* section label. A radio run that shares a group needs the actions to be known, so it throws when
|
|
51
52
|
* the menu is opened.
|
|
52
53
|
*/
|
|
53
|
-
export declare function assertPopupMenuAssignable(
|
|
54
|
+
export declare function assertPopupMenuAssignable(tree: AdwMenuTree): void;
|
|
54
55
|
/**
|
|
55
56
|
* A JSON string is not a menu model here: NativeScript's XML Builder writes an attribute straight
|
|
56
|
-
* onto the property, so accepting one would open an XML door nothing can prove
|
|
57
|
-
*
|
|
57
|
+
* onto the property, so accepting one would open an XML door nothing can prove. Since ADR 0128
|
|
58
|
+
* the core's door DOES parse one — that is how the browser's `menu-model` attribute works — so
|
|
59
|
+
* this stays in front of it rather than relying on a refusal the shared door no longer makes.
|
|
58
60
|
*/
|
|
59
61
|
export declare function refuseMenuString(value: unknown, widget: string): void;
|
|
@@ -22,9 +22,9 @@ type Declared<P> = P & {
|
|
|
22
22
|
*/
|
|
23
23
|
readonly normalize?: (value: unknown, self: object) => unknown;
|
|
24
24
|
/**
|
|
25
|
-
* Replaces the equal-write check for this property
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* Replaces the equal-write check for this property: `written` is the value as the caller
|
|
26
|
+
* spelled it, `next` what {@link Declared.normalize} made of it, `held` what the store holds
|
|
27
|
+
* — and the answer decides whether the write notifies at all.
|
|
28
28
|
*
|
|
29
29
|
* WHY. A C setter guards on `g_strcmp0 (value, adw_…_get_…(self))`, against the GETTER
|
|
30
30
|
* READBACK rather than the stored field. Where storage normalises, the two differ and the
|
|
@@ -33,12 +33,19 @@ type Declared<P> = P & {
|
|
|
33
33
|
* libadwaita 1.9.4). Comparing the held value says the opposite, and only the property whose
|
|
34
34
|
* `normalize` collapses distinct writes onto one held value can tell the difference.
|
|
35
35
|
*
|
|
36
|
-
*
|
|
36
|
+
* RUNS ON BOTH LEGS. It used to run on the pure one alone, on the reasoning that "there the
|
|
37
|
+
* guard IS the C one" — which holds for a widget wrapping a real C object and not for a
|
|
38
|
+
* foreign-parent class, which has no C setter at all. On route D node-gi's generated setter
|
|
39
|
+
* is an identity guard and nothing more (`installForeignPropertyAccessors` in `gi.js`), so a
|
|
40
|
+
* property that left this to the real leg got the identity answer there and the measured one
|
|
41
|
+
* off-device — the per-leg difference this seam exists to close.
|
|
37
42
|
*/
|
|
38
43
|
readonly changed?: (next: unknown, held: unknown, written: unknown, self: object) => boolean;
|
|
39
44
|
/**
|
|
40
|
-
* The rest of the C setter
|
|
41
|
-
*
|
|
45
|
+
* The rest of the C setter: runs once this property's own `notify::<name>` is out, so a
|
|
46
|
+
* setter that also drives OTHER properties emits in the order C does. For a property with
|
|
47
|
+
* {@link ForeignScalarProperty.explicitNotify} it runs INSTEAD of that notify, and owes every
|
|
48
|
+
* emission the write makes, its own included.
|
|
42
49
|
*
|
|
43
50
|
* WHY IT IS NOT `normalize`. A normalizer runs AHEAD of the store, so a cross-write made
|
|
44
51
|
* there notifies before the property that caused it. `Adw.SplitButton` measures the other way
|
|
@@ -46,8 +53,9 @@ type Declared<P> = P & {
|
|
|
46
53
|
* after — and the two cannot both be one hook. The SHAPE of a value still belongs to
|
|
47
54
|
* `normalize`; what the write does to its siblings belongs here.
|
|
48
55
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
56
|
+
* RUNS ON BOTH LEGS, for the reason {@link Declared.changed} states: the foreign-parent class
|
|
57
|
+
* route D registers has no C setter to do this instead. `adw-split-button`'s label/icon-name
|
|
58
|
+
* mutual clear is the one that was silently missing on Android because of it.
|
|
51
59
|
*/
|
|
52
60
|
readonly afterNotify?: (self: object) => void;
|
|
53
61
|
};
|
|
@@ -223,4 +231,21 @@ export declare function withProperties<TBase extends ObservableConstructor>(Base
|
|
|
223
231
|
/** Only what this class ADDS; `emittedSignalsOf` merges it with the base's. */
|
|
224
232
|
readonly emittedSignals: readonly string[];
|
|
225
233
|
}) & TBase;
|
|
234
|
+
/**
|
|
235
|
+
* Write a declared property's held value WITHOUT notifying, and without running `normalize`,
|
|
236
|
+
* `changed` or `afterNotify` — the PUSH half of a property whose widget owns the emission.
|
|
237
|
+
*
|
|
238
|
+
* WHY A WIDGET NEEDS IT. A property whose value also moves from UNDERNEATH — the selection of an
|
|
239
|
+
* `Adw.ComboRow` when its model is replaced, or when the held model splices — cannot be kept in
|
|
240
|
+
* sync by writing it, because the write is the thing that emits and the emission order is
|
|
241
|
+
* measured and is not the order a write would produce. `model = null` is the sharpest case:
|
|
242
|
+
* `selected` goes to the sentinel and `selected-item` to null with NO notify at all, and `model`
|
|
243
|
+
* alone notifies. So the widget pushes the new value in here and emits what it owes with
|
|
244
|
+
* `notify('<name>')`, in the order it measured.
|
|
245
|
+
*
|
|
246
|
+
* Only a {@link isSeamOwned} property may be pushed, and a name that is not one THROWS rather
|
|
247
|
+
* than writing a store route D would never read back: there the value lives in the GObject, and
|
|
248
|
+
* a silent push would be correct off-device and invisible on the device.
|
|
249
|
+
*/
|
|
250
|
+
export declare function pushDeclared(self: object, name: string, value: unknown): void;
|
|
226
251
|
export {};
|
|
@@ -4,8 +4,13 @@ export declare abstract class AdwSingleChildBase extends AdwStyledLayoutBase {
|
|
|
4
4
|
private _child;
|
|
5
5
|
constructor();
|
|
6
6
|
private _columnIsStar;
|
|
7
|
+
private _rowIsStar;
|
|
7
8
|
onLoaded(): void;
|
|
9
|
+
onUnloaded(): void;
|
|
10
|
+
private _onWidthChangeSyncColumn;
|
|
11
|
+
private _onHeightChangeSyncRow;
|
|
8
12
|
private _syncColumnToAlignment;
|
|
13
|
+
private _syncRowToAlignment;
|
|
9
14
|
/** The child, or `null`. */
|
|
10
15
|
get child(): View | null;
|
|
11
16
|
set child(view: View | null);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the single cell of a one-child container is `star` rather than `auto`, on ONE axis.
|
|
3
|
+
*
|
|
4
|
+
* `star` when the container's extent along that axis is settled — either because it stretches
|
|
5
|
+
* to its parent, or because a definite `width` / `height` was written on it. `auto` otherwise,
|
|
6
|
+
* so the container can still report its child's natural size and be placed by its alignment.
|
|
7
|
+
*
|
|
8
|
+
* TAKES NO AXIS, because there is nothing axis-specific left once the question is phrased that
|
|
9
|
+
* way: `'stretch'` is the stretching value of BOTH `horizontalAlignment` and
|
|
10
|
+
* `verticalAlignment`, and a settled `width` reads exactly like a settled `height`. The column
|
|
11
|
+
* passes `horizontalAlignment` + `width`, the row `verticalAlignment` + `height`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function singleChildCellIsStar(alignment: unknown, length: unknown): boolean;
|
|
@@ -6,6 +6,18 @@
|
|
|
6
6
|
* caller can keep validating a RANGE without also having to re-check the type.
|
|
7
7
|
*/
|
|
8
8
|
export declare function xmlNumber(value: unknown, fallback: number): number;
|
|
9
|
+
/**
|
|
10
|
+
* The integer GtkBuilder reads out of an enum property's value, or `undefined` when the
|
|
11
|
+
* value is a nick or name.
|
|
12
|
+
*
|
|
13
|
+
* `_gtk_builder_enum_from_string` (gtk/gtkbuilder.c) tries the number FIRST
|
|
14
|
+
* (`g_ascii_strtoull (string, &endptr, 0)`, so base 0: decimal, `0x` hex, leading-`0` octal)
|
|
15
|
+
* and only then the nick and the name — which is why `halign="1"` and `halign="start"` are
|
|
16
|
+
* the same attribute in a `.ui` file. A JS number is the same reading, already parsed.
|
|
17
|
+
* GTK also accepts a numeric PREFIX (`"2abc"` is 2); the whole string must be a number here,
|
|
18
|
+
* so a nick that merely starts with a digit stays a nick.
|
|
19
|
+
*/
|
|
20
|
+
export declare function gtkBuilderInteger(value: unknown): number | undefined;
|
|
9
21
|
/**
|
|
10
22
|
* An attribute as a boolean.
|
|
11
23
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/adwaita-nativescript",
|
|
3
|
-
"version": "0.64.
|
|
3
|
+
"version": "0.64.14",
|
|
4
4
|
"description": "Native Adwaita widgets for the NativeScript runtime — real NativeScript components (StackLayout/GridLayout/Switch/Label) styled like Libadwaita, not a webview",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -73,15 +73,15 @@
|
|
|
73
73
|
"design-system"
|
|
74
74
|
],
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@gjsify/adwaita-core": "0.64.
|
|
77
|
-
"@gjsify/adwaita-fonts": "0.64.
|
|
78
|
-
"@gjsify/adwaita-icons": "0.64.
|
|
79
|
-
"@gjsify/canvas2d-core": "0.64.
|
|
80
|
-
"@gjsify/native-platform": "0.64.
|
|
76
|
+
"@gjsify/adwaita-core": "^0.64.14",
|
|
77
|
+
"@gjsify/adwaita-fonts": "^0.64.14",
|
|
78
|
+
"@gjsify/adwaita-icons": "^0.64.14",
|
|
79
|
+
"@gjsify/canvas2d-core": "^0.64.14",
|
|
80
|
+
"@gjsify/native-platform": "^0.64.14"
|
|
81
81
|
},
|
|
82
82
|
"peerDependencies": {
|
|
83
83
|
"@nativescript/core": "*",
|
|
84
|
-
"@gjsify/app-settings": "0.64.
|
|
84
|
+
"@gjsify/app-settings": "^0.64.14"
|
|
85
85
|
},
|
|
86
86
|
"peerDependenciesMeta": {
|
|
87
87
|
"@nativescript/core": {
|
|
@@ -92,11 +92,11 @@
|
|
|
92
92
|
}
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@gjsify/app-settings": "0.64.
|
|
96
|
-
"@gjsify/blueprint": "0.64.
|
|
97
|
-
"@gjsify/cli": "0.64.
|
|
98
|
-
"@gjsify/unit": "0.64.
|
|
99
|
-
"@gjsify/vite-plugin-blueprint": "0.64.
|
|
95
|
+
"@gjsify/app-settings": "^0.64.14",
|
|
96
|
+
"@gjsify/blueprint": "^0.64.14",
|
|
97
|
+
"@gjsify/cli": "^0.64.14",
|
|
98
|
+
"@gjsify/unit": "^0.64.14",
|
|
99
|
+
"@gjsify/vite-plugin-blueprint": "^0.64.14",
|
|
100
100
|
"@types/node": "^25.9.2",
|
|
101
101
|
"typescript": "^6.0.3"
|
|
102
102
|
},
|
|
@@ -125,6 +125,5 @@
|
|
|
125
125
|
"bugs": {
|
|
126
126
|
"url": "https://github.com/gjsify/gjsify/issues"
|
|
127
127
|
},
|
|
128
|
-
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/nativescript-bridge/adwaita#readme"
|
|
129
|
-
"gitHead": "05fae97125a374e84bf57c2d2d086fb53523f205"
|
|
128
|
+
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/nativescript-bridge/adwaita#readme"
|
|
130
129
|
}
|
package/src/testing/ns-core.mts
CHANGED
|
@@ -177,6 +177,8 @@ export class Style extends Observable {
|
|
|
177
177
|
fontSize?: number;
|
|
178
178
|
readonly viewRef: WeakRef<View>;
|
|
179
179
|
#visibility = 'visible';
|
|
180
|
+
#width: number | string = 'auto';
|
|
181
|
+
#height: number | string = 'auto';
|
|
180
182
|
|
|
181
183
|
constructor(view: View) {
|
|
182
184
|
super();
|
|
@@ -193,6 +195,33 @@ export class Style extends Observable {
|
|
|
193
195
|
this.#visibility = value;
|
|
194
196
|
this.notify({ eventName: 'visibilityChange', object: this, propertyName: 'visibility', value, oldValue });
|
|
195
197
|
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* The inline width, in DIPs or as a percentage string, `'auto'` until written — and the
|
|
201
|
+
* `widthChange` a one-child container listens for. A CSS property notifies on the style
|
|
202
|
+
* and not on the view, which is the whole reason this pair lives here.
|
|
203
|
+
*/
|
|
204
|
+
get width(): number | string {
|
|
205
|
+
return this.#width;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
set width(value: number | string) {
|
|
209
|
+
const oldValue = this.#width;
|
|
210
|
+
if (value === oldValue) return;
|
|
211
|
+
this.#width = value;
|
|
212
|
+
this.notify({ eventName: 'widthChange', object: this, propertyName: 'width', value, oldValue });
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
get height(): number | string {
|
|
216
|
+
return this.#height;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
set height(value: number | string) {
|
|
220
|
+
const oldValue = this.#height;
|
|
221
|
+
if (value === oldValue) return;
|
|
222
|
+
this.#height = value;
|
|
223
|
+
this.notify({ eventName: 'heightChange', object: this, propertyName: 'height', value, oldValue });
|
|
224
|
+
}
|
|
196
225
|
}
|
|
197
226
|
|
|
198
227
|
export class View extends Observable {
|
|
@@ -234,8 +263,32 @@ export class View extends Observable {
|
|
|
234
263
|
* missing so the first `className` write died inside a constructor.
|
|
235
264
|
*/
|
|
236
265
|
readonly cssClasses: Set<string> = new Set();
|
|
237
|
-
|
|
238
|
-
|
|
266
|
+
/**
|
|
267
|
+
* `'auto'` until written, and HELD ON THE {@link Style} as `widthProperty` /
|
|
268
|
+
* `heightProperty` are (`ui/styling/style-properties.ts` registers both on `Style`;
|
|
269
|
+
* `view-common.ts`'s `get width()` is a one-line forward to `this.style.width`).
|
|
270
|
+
*
|
|
271
|
+
* This double held them as plain fields on the view, which made it STRUCTURALLY BLIND to
|
|
272
|
+
* the one thing a reader needs from them: the notification. `AdwSingleChildBase` learns
|
|
273
|
+
* that a parent settled its width from `widthChange` on the style — on a device the only
|
|
274
|
+
* place it is emitted — and against a field there is no event at all, so a spec would
|
|
275
|
+
* have passed while the widget sat waiting for a message that never came.
|
|
276
|
+
*/
|
|
277
|
+
get width(): number | string {
|
|
278
|
+
return this._style.width;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
set width(value: number | string) {
|
|
282
|
+
this._style.width = value;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
get height(): number | string {
|
|
286
|
+
return this._style.height;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
set height(value: number | string) {
|
|
290
|
+
this._style.height = value;
|
|
291
|
+
}
|
|
239
292
|
horizontalAlignment = 'stretch';
|
|
240
293
|
verticalAlignment = 'stretch';
|
|
241
294
|
/**
|
|
@@ -614,11 +667,22 @@ export class GridLayout extends LayoutBase {
|
|
|
614
667
|
if (at !== -1) this._rows.splice(at, 1);
|
|
615
668
|
}
|
|
616
669
|
|
|
670
|
+
/** `GridLayoutBase.removeColumn` — BY SPEC, like `removeRow`, not by index. */
|
|
671
|
+
removeColumn(itemSpec: ItemSpec): void {
|
|
672
|
+
const at = this._cols.indexOf(itemSpec);
|
|
673
|
+
if (at !== -1) this._cols.splice(at, 1);
|
|
674
|
+
}
|
|
675
|
+
|
|
617
676
|
/** `GridLayoutBase.getColumns` — a copy, as on a device. */
|
|
618
677
|
getColumns(): ItemSpec[] {
|
|
619
678
|
return [...this._cols];
|
|
620
679
|
}
|
|
621
680
|
|
|
681
|
+
/** `GridLayoutBase.getRows` — the same read on the other axis. */
|
|
682
|
+
getRows(): ItemSpec[] {
|
|
683
|
+
return [...this._rows];
|
|
684
|
+
}
|
|
685
|
+
|
|
622
686
|
removeColumns(): void {
|
|
623
687
|
this._cols.length = 0;
|
|
624
688
|
}
|
|
@@ -840,6 +904,14 @@ export class Label extends View {
|
|
|
840
904
|
this._text = value?.toString() ?? '';
|
|
841
905
|
}
|
|
842
906
|
|
|
907
|
+
/**
|
|
908
|
+
* `TextBase._setNativeText` — the framework's sink for every text write, and the seam
|
|
909
|
+
* the native markup path draws at (`widgets/label-markup-native.ts`). There is no
|
|
910
|
+
* native text view off a device, so this records nothing: it exists because the port
|
|
911
|
+
* overrides it and `super._setNativeText()` has to be callable.
|
|
912
|
+
*/
|
|
913
|
+
_setNativeText(_reset = false): void {}
|
|
914
|
+
|
|
843
915
|
textWrap = false;
|
|
844
916
|
textAlignment = 'initial';
|
|
845
917
|
textOverflow = 'initial';
|
package/src/theme/adwaita.css
CHANGED
|
@@ -506,13 +506,22 @@ Page.adw-window {
|
|
|
506
506
|
|
|
507
507
|
/* ===== Button (variants) ===== */
|
|
508
508
|
|
|
509
|
+
/* A FLOOR AND NOT A BOX. 38 is libadwaita's `min-height: 24px` plus its 5px of vertical
|
|
510
|
+
* padding twice (_buttons.scss, pin 42f647ff) — a MINIMUM there, and GTK has no CSS
|
|
511
|
+
* `height` at all. Writing it as NativeScript's `height`, which is exact, made every
|
|
512
|
+
* button in the port exactly 38 tall and silently swallowed `height-request`, which the
|
|
513
|
+
* bridge maps to `minHeight` and which GTK treats as a second floor: Learn6502's d-pad
|
|
514
|
+
* asks each of its five cells for 50×50 and got 50×38, so the cross came out as a row of
|
|
515
|
+
* flattened buttons. `min-height` is the property that means what the SCSS means, it
|
|
516
|
+
* composes with `height-request` the way GTK composes its two floors — the larger wins —
|
|
517
|
+
* and a caller that really wants an exact box can still write `height` itself. */
|
|
509
518
|
.adw-button {
|
|
510
519
|
background-color: rgba(0, 0, 0, 0.08);
|
|
511
520
|
color: rgba(0, 0, 0, 0.8);
|
|
512
521
|
border-radius: 9;
|
|
513
522
|
font-weight: 700;
|
|
514
523
|
padding: 5 16 5 16;
|
|
515
|
-
height: 38;
|
|
524
|
+
min-height: 38;
|
|
516
525
|
}
|
|
517
526
|
|
|
518
527
|
.adw-button.suggested-action {
|
|
@@ -534,10 +543,10 @@ Page.adw-window {
|
|
|
534
543
|
* pin 42f647ff). The padding is the whole variant, and it is why this rule HAS to
|
|
535
544
|
* restate the height.
|
|
536
545
|
*
|
|
537
|
-
* `.adw-button` above pins
|
|
538
|
-
*
|
|
539
|
-
* `adw-spinner.size
|
|
540
|
-
* box it
|
|
546
|
+
* `.adw-button` above pins a 38 floor, and this variant doubles the vertical padding
|
|
547
|
+
* inside it. While that floor was written as an EXACT NativeScript `height` — the
|
|
548
|
+
* non-equivalence ADR 0034 measured for `adw-spinner.size` — the variant could not grow
|
|
549
|
+
* the box it sat in: the base budgets 38 − (5 + 5) = 28 for the label, and this one left
|
|
541
550
|
* 38 − (10 + 10) = 18 for a `.adw-button-label` at `font-size: 15`, whose line box does
|
|
542
551
|
* not fit in 18. The pill was clipped, and every consumer that wanted one had to
|
|
543
552
|
* override the height itself — which is how the defect surfaced, in Learn6502.
|
|
@@ -547,13 +556,17 @@ Page.adw-window {
|
|
|
547
556
|
* 34, + 10px twice is 44 — so the pill is taller than the plain button there too.
|
|
548
557
|
*
|
|
549
558
|
* THE RULE THIS VARIANT BROKE, stated because the next variant will meet it: in this
|
|
550
|
-
* stylesheet a class that changes vertical padding on a widget whose base
|
|
551
|
-
* `height` must restate that
|
|
552
|
-
* button halves do (38) beside their own padding. This one did not,
|
|
559
|
+
* stylesheet a class that changes vertical padding on a widget whose base states a
|
|
560
|
+
* `min-height` must restate that floor at its own padding. `.adw-button.circular` does
|
|
561
|
+
* (34), and both split button halves do (38) beside their own padding. This one did not,
|
|
562
|
+
* and nothing said so. The floors are `min-*` rather than `height` / `width` since the
|
|
563
|
+
* d-pad incident above, so a `height-request` larger than the floor now wins as it does
|
|
564
|
+
* in GTK — but a floor that is too SMALL for its own padding still clips, which is the
|
|
565
|
+
* half this comment is about and the reason the number is restated here. */
|
|
553
566
|
.adw-button.pill {
|
|
554
567
|
border-radius: 9999;
|
|
555
568
|
padding: 10 32 10 32;
|
|
556
|
-
height: 48;
|
|
569
|
+
min-height: 48;
|
|
557
570
|
}
|
|
558
571
|
|
|
559
572
|
/* `%circular_button` — the explicit exception to the 9px rounded square: a full
|
|
@@ -563,8 +576,8 @@ Page.adw-window {
|
|
|
563
576
|
* at all", and a class with no rule would have drawn a rounded rectangle instead. The
|
|
564
577
|
* 34 is the same number `.adw-image-button` above carries, from the same line. */
|
|
565
578
|
.adw-button.circular {
|
|
566
|
-
width: 34;
|
|
567
|
-
height: 34;
|
|
579
|
+
min-width: 34;
|
|
580
|
+
min-height: 34;
|
|
568
581
|
border-radius: 9999;
|
|
569
582
|
padding: 0;
|
|
570
583
|
}
|