@react-x11/components 0.4.0 → 0.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/README.md +143 -8
- package/dist/charts/components.d.ts +3 -1
- package/dist/charts/components.d.ts.map +1 -1
- package/dist/charts/components.js +8 -4
- package/dist/charts/components.js.map +1 -1
- package/dist/charts/node.d.ts +13 -6
- package/dist/charts/node.d.ts.map +1 -1
- package/dist/charts/node.js +75 -24
- package/dist/charts/node.js.map +1 -1
- package/dist/charts/render.d.ts +4 -0
- package/dist/charts/render.d.ts.map +1 -1
- package/dist/charts/render.js +11 -6
- package/dist/charts/render.js.map +1 -1
- package/dist/code-editor/node.d.ts +47 -16
- package/dist/code-editor/node.d.ts.map +1 -1
- package/dist/code-editor/node.js +121 -51
- package/dist/code-editor/node.js.map +1 -1
- package/dist/flow/draw.d.ts +19 -1
- package/dist/flow/draw.d.ts.map +1 -1
- package/dist/flow/draw.js +64 -35
- package/dist/flow/draw.js.map +1 -1
- package/dist/flow/index.d.ts.map +1 -1
- package/dist/flow/index.js +24 -8
- package/dist/flow/index.js.map +1 -1
- package/dist/flow/model.d.ts +4 -2
- package/dist/flow/model.d.ts.map +1 -1
- package/dist/flow/model.js +4 -2
- package/dist/flow/model.js.map +1 -1
- package/dist/flow/node.d.ts +40 -9
- package/dist/flow/node.d.ts.map +1 -1
- package/dist/flow/node.js +142 -53
- package/dist/flow/node.js.map +1 -1
- package/dist/flow/types.d.ts +46 -21
- package/dist/flow/types.d.ts.map +1 -1
- package/dist/formula/index.d.ts +4 -2
- package/dist/formula/index.d.ts.map +1 -1
- package/dist/formula/index.js.map +1 -1
- package/dist/formula/node.d.ts +5 -1
- package/dist/formula/node.d.ts.map +1 -1
- package/dist/formula/node.js +19 -3
- package/dist/formula/node.js.map +1 -1
- package/dist/html/controls.d.ts +4 -1
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js.map +1 -1
- package/dist/html/css/cascade.d.ts +11 -5
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +18 -8
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/parse.d.ts +15 -10
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +41 -16
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +3 -0
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +3 -1
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/values.d.ts +14 -1
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js +11 -8
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +1 -0
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +12 -5
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +7 -4
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +22 -1
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/node.d.ts +22 -8
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +97 -15
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +3 -0
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +2 -2
- package/dist/html/paint.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/maps/clip.d.ts +43 -0
- package/dist/maps/clip.d.ts.map +1 -0
- package/dist/maps/clip.js +171 -0
- package/dist/maps/clip.js.map +1 -0
- package/dist/maps/gzip.d.ts +15 -0
- package/dist/maps/gzip.d.ts.map +1 -0
- package/dist/maps/gzip.js +56 -0
- package/dist/maps/gzip.js.map +1 -0
- package/dist/maps/index.d.ts +55 -0
- package/dist/maps/index.d.ts.map +1 -0
- package/dist/maps/index.js +141 -0
- package/dist/maps/index.js.map +1 -0
- package/dist/maps/labels.d.ts +123 -0
- package/dist/maps/labels.d.ts.map +1 -0
- package/dist/maps/labels.js +323 -0
- package/dist/maps/labels.js.map +1 -0
- package/dist/maps/mvt.d.ts +244 -0
- package/dist/maps/mvt.d.ts.map +1 -0
- package/dist/maps/mvt.js +820 -0
- package/dist/maps/mvt.js.map +1 -0
- package/dist/maps/node.d.ts +278 -0
- package/dist/maps/node.d.ts.map +1 -0
- package/dist/maps/node.js +1459 -0
- package/dist/maps/node.js.map +1 -0
- package/dist/maps/overlay.d.ts +157 -0
- package/dist/maps/overlay.d.ts.map +1 -0
- package/dist/maps/overlay.js +472 -0
- package/dist/maps/overlay.js.map +1 -0
- package/dist/maps/paint.d.ts +226 -0
- package/dist/maps/paint.d.ts.map +1 -0
- package/dist/maps/paint.js +705 -0
- package/dist/maps/paint.js.map +1 -0
- package/dist/maps/proj.d.ts +281 -0
- package/dist/maps/proj.d.ts.map +1 -0
- package/dist/maps/proj.js +451 -0
- package/dist/maps/proj.js.map +1 -0
- package/dist/maps/sources.d.ts +256 -0
- package/dist/maps/sources.d.ts.map +1 -0
- package/dist/maps/sources.js +210 -0
- package/dist/maps/sources.js.map +1 -0
- package/dist/maps/style.d.ts +141 -0
- package/dist/maps/style.d.ts.map +1 -0
- package/dist/maps/style.js +147 -0
- package/dist/maps/style.js.map +1 -0
- package/dist/maps/styles.d.ts +82 -0
- package/dist/maps/styles.d.ts.map +1 -0
- package/dist/maps/styles.js +898 -0
- package/dist/maps/styles.js.map +1 -0
- package/dist/maps/tiles.d.ts +283 -0
- package/dist/maps/tiles.d.ts.map +1 -0
- package/dist/maps/tiles.js +469 -0
- package/dist/maps/tiles.js.map +1 -0
- package/dist/maps/types.d.ts +244 -0
- package/dist/maps/types.d.ts.map +1 -0
- package/dist/maps/types.js +2 -0
- package/dist/maps/types.js.map +1 -0
- package/dist/markdown/ast.d.ts +80 -6
- package/dist/markdown/ast.d.ts.map +1 -1
- package/dist/markdown/ast.js +13 -4
- package/dist/markdown/ast.js.map +1 -1
- package/dist/markdown/expressions.d.ts +27 -0
- package/dist/markdown/expressions.d.ts.map +1 -0
- package/dist/markdown/expressions.js +203 -0
- package/dist/markdown/expressions.js.map +1 -0
- package/dist/markdown/index.d.ts +61 -2
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +101 -2
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/parse.d.ts +1 -1
- package/dist/markdown/parse.d.ts.map +1 -1
- package/dist/markdown/parse.js +163 -15
- package/dist/markdown/parse.js.map +1 -1
- package/dist/markdown/spans.d.ts.map +1 -1
- package/dist/markdown/spans.js +4 -0
- package/dist/markdown/spans.js.map +1 -1
- package/dist/markdown/tags.d.ts +35 -0
- package/dist/markdown/tags.d.ts.map +1 -0
- package/dist/markdown/tags.js +213 -0
- package/dist/markdown/tags.js.map +1 -0
- package/dist/reorder/hx.d.ts +18 -0
- package/dist/reorder/hx.d.ts.map +1 -0
- package/dist/reorder/hx.js +10 -0
- package/dist/reorder/hx.js.map +1 -0
- package/dist/reorder/index.d.ts +314 -0
- package/dist/reorder/index.d.ts.map +1 -0
- package/dist/reorder/index.js +1539 -0
- package/dist/reorder/index.js.map +1 -0
- package/dist/reorder/model.d.ts +107 -0
- package/dist/reorder/model.d.ts.map +1 -0
- package/dist/reorder/model.js +162 -0
- package/dist/reorder/model.js.map +1 -0
- package/dist/richtext/node.d.ts +15 -5
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js +40 -11
- package/dist/richtext/node.js.map +1 -1
- package/dist/richtext/runs.d.ts +35 -13
- package/dist/richtext/runs.d.ts.map +1 -1
- package/dist/richtext/runs.js +83 -27
- package/dist/richtext/runs.js.map +1 -1
- package/dist/tabs/index.d.ts +17 -0
- package/dist/tabs/index.d.ts.map +1 -1
- package/dist/tabs/index.js +849 -186
- package/dist/tabs/index.js.map +1 -1
- package/dist/terminal/vt/fonts.d.ts +45 -15
- package/dist/terminal/vt/fonts.d.ts.map +1 -1
- package/dist/terminal/vt/fonts.js +89 -19
- package/dist/terminal/vt/fonts.js.map +1 -1
- package/dist/terminal/vt/node.d.ts +42 -0
- package/dist/terminal/vt/node.d.ts.map +1 -1
- package/dist/terminal/vt/node.js +95 -11
- package/dist/terminal/vt/node.js.map +1 -1
- package/dist/terminal/vt/renderer.d.ts.map +1 -1
- package/dist/terminal/vt/renderer.js +13 -3
- package/dist/terminal/vt/renderer.js.map +1 -1
- package/package.json +14 -3
- package/src/charts/components.ts +14 -7
- package/src/charts/node.ts +81 -26
- package/src/charts/render.ts +16 -6
- package/src/code-editor/node.ts +147 -53
- package/src/flow/draw.ts +104 -35
- package/src/flow/index.ts +33 -13
- package/src/flow/model.ts +4 -2
- package/src/flow/node.ts +158 -59
- package/src/flow/types.ts +46 -21
- package/src/formula/index.ts +4 -2
- package/src/formula/node.ts +24 -5
- package/src/html/controls.ts +4 -1
- package/src/html/css/cascade.ts +18 -7
- package/src/html/css/parse.ts +46 -21
- package/src/html/css/style.ts +6 -1
- package/src/html/css/values.ts +25 -9
- package/src/html/index.ts +1 -0
- package/src/html/layout/boxes.ts +19 -9
- package/src/html/layout/inline.ts +23 -1
- package/src/html/node.ts +110 -17
- package/src/html/paint.ts +17 -2
- package/src/index.ts +102 -0
- package/src/maps/clip.ts +184 -0
- package/src/maps/gzip.ts +66 -0
- package/src/maps/index.ts +316 -0
- package/src/maps/labels.ts +442 -0
- package/src/maps/mvt.ts +857 -0
- package/src/maps/node.ts +1819 -0
- package/src/maps/overlay.ts +639 -0
- package/src/maps/paint.ts +978 -0
- package/src/maps/proj.ts +641 -0
- package/src/maps/sources.ts +425 -0
- package/src/maps/style.ts +309 -0
- package/src/maps/styles.ts +1040 -0
- package/src/maps/tiles.ts +676 -0
- package/src/maps/types.ts +260 -0
- package/src/markdown/ast.ts +85 -9
- package/src/markdown/expressions.ts +223 -0
- package/src/markdown/index.ts +190 -5
- package/src/markdown/parse.ts +230 -15
- package/src/markdown/spans.ts +4 -0
- package/src/markdown/tags.ts +240 -0
- package/src/reorder/hx.ts +31 -0
- package/src/reorder/index.ts +2223 -0
- package/src/reorder/model.ts +232 -0
- package/src/richtext/node.ts +49 -14
- package/src/richtext/runs.ts +115 -30
- package/src/tabs/index.ts +1040 -204
- package/src/terminal/vt/fonts.ts +128 -36
- package/src/terminal/vt/node.ts +105 -12
- package/src/terminal/vt/renderer.ts +13 -3
package/dist/flow/node.d.ts
CHANGED
|
@@ -153,16 +153,44 @@ export declare class FlowGraphNode extends Node implements FlowInstance {
|
|
|
153
153
|
/** who touches whom — what a moved node's damage has to include */
|
|
154
154
|
private _rebuildAdjacency;
|
|
155
155
|
private _viewport;
|
|
156
|
+
/**
|
|
157
|
+
* Device pixels per logical pixel — the display scale this pane's window
|
|
158
|
+
* resolved to (react-x11's docs/scale.md): `1` on an ordinary display,
|
|
159
|
+
* `2` on a retina panel, fractional on a desktop configured to 1.5.
|
|
160
|
+
*
|
|
161
|
+
* The pane thinks in logical pixels throughout. They are the unit its API
|
|
162
|
+
* speaks (a viewport, a node's size, a `NodeBodyRect`), the unit a
|
|
163
|
+
* synthetic event's `x`/`y` arrive in, and the unit the sibling boxes
|
|
164
|
+
* `<Flow>` mounts bodies in are laid out in. What core hands this element
|
|
165
|
+
* is device pixels — `abs`, `contentBox()`, `this.style`, the paint
|
|
166
|
+
* context, `paintDamage()`, a rect given to `invalidate` or
|
|
167
|
+
* `scrollContents`, an a11y scene rect — so each of those crossings
|
|
168
|
+
* converts, once, in the helpers below, and nothing in between knows the
|
|
169
|
+
* factor. At 1x every conversion is the identity, which is how a pane
|
|
170
|
+
* that compared `ev.x` with `contentBox()` passed every test and then
|
|
171
|
+
* hovered at half the distance, panned at half speed and framed the graph
|
|
172
|
+
* at half size the day a native backend reported a retina panel.
|
|
173
|
+
*/
|
|
174
|
+
private get _scale();
|
|
175
|
+
/** A logical rect on the device grid, grown outward to whole pixels —
|
|
176
|
+
* what a damage claim has to cover for an antialiased edge to repaint. */
|
|
177
|
+
private _device;
|
|
178
|
+
/** One of core's device rects in the pane's logical units. */
|
|
179
|
+
private _logical;
|
|
180
|
+
/** Claim a logical rect as damage. Every partial repaint the pane asks
|
|
181
|
+
* for goes through here; the full ones pass `abs`, which is device
|
|
182
|
+
* already. */
|
|
183
|
+
private _claim;
|
|
156
184
|
/**
|
|
157
185
|
* The pane proper: `abs` inset by border and padding, off core's own
|
|
158
186
|
* resolved layout (react-x11#254) — so a `<Flow style={{ borderWidth: 1,
|
|
159
187
|
* padding: 8 }}>` keeps its border, and its padding means what it does on
|
|
160
|
-
* a `<box>`.
|
|
188
|
+
* a `<box>`. In logical pixels, like everything the pane computes.
|
|
161
189
|
*/
|
|
162
190
|
private _pane;
|
|
163
|
-
/** Graph point to window pixels. */
|
|
191
|
+
/** Graph point to logical window pixels. */
|
|
164
192
|
private _toScreen;
|
|
165
|
-
/**
|
|
193
|
+
/** Logical window pixels to graph point. */
|
|
166
194
|
private _toGraph;
|
|
167
195
|
/** Where a node is *now*: mid-drag that is not where its props say. */
|
|
168
196
|
private _positionOf;
|
|
@@ -180,7 +208,7 @@ export declare class FlowGraphNode extends Node implements FlowInstance {
|
|
|
180
208
|
private _grips;
|
|
181
209
|
private _handlesOf;
|
|
182
210
|
/**
|
|
183
|
-
* A node's box on screen, **on whole pixels**.
|
|
211
|
+
* A node's box on screen, **on whole device pixels**.
|
|
184
212
|
*
|
|
185
213
|
* The rounding is not cosmetic. ntk draws a rounded box as cached corner
|
|
186
214
|
* glyphs plus `FillRectangles` when its geometry is integral, and
|
|
@@ -189,8 +217,10 @@ export declare class FlowGraphNode extends Node implements FlowInstance {
|
|
|
189
217
|
* six hundred mask uploads a frame and about four megabytes on the wire;
|
|
190
218
|
* `react-x11/debug`'s trace names it as `fell back … fractional`.
|
|
191
219
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
220
|
+
* The grid is the panel's, not the logical one: at 2x a logical half is
|
|
221
|
+
* a whole pixel, and at 1.5x a logical integer is not always one. Hit
|
|
222
|
+
* testing reads the same rect, so what is drawn and what is clicked still
|
|
223
|
+
* agree to the pixel.
|
|
194
224
|
*/
|
|
195
225
|
private _screenRect;
|
|
196
226
|
private _visible;
|
|
@@ -212,8 +242,8 @@ export declare class FlowGraphNode extends Node implements FlowInstance {
|
|
|
212
242
|
* panels repaint in place.
|
|
213
243
|
*
|
|
214
244
|
* Still a full repaint when:
|
|
215
|
-
* - the zoom moved (scaling is not a blit) or the shift is fractional
|
|
216
|
-
* every real pan gesture is whole pixels;
|
|
245
|
+
* - the zoom moved (scaling is not a blit) or the shift is fractional on
|
|
246
|
+
* the device grid — every real pan gesture is whole device pixels;
|
|
217
247
|
* - mounted node bodies exist: they are core-owned siblings whose
|
|
218
248
|
* gesture-time commits claim *inside* the rect every step, which
|
|
219
249
|
* declines the blit anyway — bailing early skips the churn;
|
|
@@ -386,7 +416,8 @@ export declare class FlowGraphNode extends Node implements FlowInstance {
|
|
|
386
416
|
private _paintGridPattern;
|
|
387
417
|
private _makeGridSurface;
|
|
388
418
|
/** Draw one grid cell with the mark at the phase point, wrapped — a mark
|
|
389
|
-
* near an edge is drawn again a tile over, so the seam never cuts it.
|
|
419
|
+
* near an edge is drawn again a tile over, so the seam never cuts it.
|
|
420
|
+
* Device pixels throughout: `unit` is how many of them a graph unit is. */
|
|
390
421
|
private _renderGridTile;
|
|
391
422
|
private _dropGridTile;
|
|
392
423
|
/** Draws every visible edge; answers whether any of them is animated, so
|
package/dist/flow/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/flow/node.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAkEvE,OAAO,KAAK,EAKV,cAAc,EAEd,QAAQ,EAER,YAAY,EAGZ,QAAQ,EACR,YAAY,EAEZ,UAAU,EAOV,QAAQ,EACR,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB;;;eAGe;AACf,eAAO,MAAM,OAAO,cAAc,CAAC;AAuFnC,KAAK,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;AAEjC,KAAK,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AAErC;;;iCAGiC;AACjC,UAAU,SAAS;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3B;AA8ED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAoB/C,CAAC;AAkJF,qBAAa,aAAc,SAAQ,IAAK,YAAW,YAAY;IAE7D,OAAO,CAAC,GAAG,CAAqC;IAChD,OAAO,CAAC,WAAW,CAAS;IAG5B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,YAAY,CAAgC;IACpD,uEAAuE;IACvE,OAAO,CAAC,SAAS,CAAiB;IAClC;gEAC4D;IAC5D,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAAiB;IAG/B,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,MAAM,CAAwB;IACtC;;;sDAGkD;IAClD,OAAO,CAAC,OAAO,CAAwC;IACvD,iEAAiE;IACjE,OAAO,CAAC,SAAS,CAA+C;IAChE;wCACoC;IACpC,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAAiB;IACnC;gCAC4B;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B;;;4EAGwE;IACxE,OAAO,CAAC,YAAY,CAAS;IAC7B;wEACoE;IACpE,OAAO,CAAC,eAAe,CAAS;IAChC;oDACgD;IAChD,OAAO,CAAC,UAAU,CAAyB;IAC3C;wDACoD;IACpD,OAAO,CAAC,QAAQ,CAAyB;IAEzC,OAAO,CAAC,UAAU,CAAiC;IACnD;yEACqE;IACrE,OAAO,CAAC,SAAS,CAKD;IAEhB,YAAY,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,EAYvD;IAID,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,IAAI;IAKZ,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,YAAY;
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/flow/node.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAkEvE,OAAO,KAAK,EAKV,cAAc,EAEd,QAAQ,EAER,YAAY,EAGZ,QAAQ,EACR,YAAY,EAEZ,UAAU,EAOV,QAAQ,EACR,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB;;;eAGe;AACf,eAAO,MAAM,OAAO,cAAc,CAAC;AAuFnC,KAAK,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;AAEjC,KAAK,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AAErC;;;iCAGiC;AACjC,UAAU,SAAS;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;CAC3B;AA8ED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAoB/C,CAAC;AAkJF,qBAAa,aAAc,SAAQ,IAAK,YAAW,YAAY;IAE7D,OAAO,CAAC,GAAG,CAAqC;IAChD,OAAO,CAAC,WAAW,CAAS;IAG5B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,YAAY,CAAgC;IACpD,uEAAuE;IACvE,OAAO,CAAC,SAAS,CAAiB;IAClC;gEAC4D;IAC5D,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAAiB;IAG/B,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,MAAM,CAAwB;IACtC;;;sDAGkD;IAClD,OAAO,CAAC,OAAO,CAAwC;IACvD,iEAAiE;IACjE,OAAO,CAAC,SAAS,CAA+C;IAChE;wCACoC;IACpC,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAAiB;IACnC;gCAC4B;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B;;;4EAGwE;IACxE,OAAO,CAAC,YAAY,CAAS;IAC7B;wEACoE;IACpE,OAAO,CAAC,eAAe,CAAS;IAChC;oDACgD;IAChD,OAAO,CAAC,UAAU,CAAyB;IAC3C;wDACoD;IACpD,OAAO,CAAC,QAAQ,CAAyB;IAEzC,OAAO,CAAC,UAAU,CAAiC;IACnD;yEACqE;IACrE,OAAO,CAAC,SAAS,CAKD;IAEhB,YAAY,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,EAYvD;IAID,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,KAAK;IAKb,OAAO,CAAC,IAAI;IAKZ,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,QAAQ,CACwC;IAExD,OAAO,CAAC,QAAQ;IAShB;;;;;OAKG;IACH,OAAO,CAAC,KAAK;IAsBb;;;;;;;;;;OAUG;IACH,OAAO,CAAC,WAAW;IAwCnB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,WAAW;IA+EnB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,aAAa;IAkCrB,OAAO,CAAC,aAAa;IAUrB,mEAAmE;IACnE,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,SAAS;IAIjB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,KAAK,MAAM,GAEjB;IAED;8EAC0E;IAC1E,OAAO,CAAC,OAAO;IAYf,8DAA8D;IAC9D,OAAO,CAAC,QAAQ;IAUhB;;kBAEc;IACd,OAAO,CAAC,MAAM;IAId;;;;;OAKG;IACH,OAAO,CAAC,KAAK;IAIb,4CAA4C;IAC5C,OAAO,CAAC,SAAS;IASjB,4CAA4C;IAC5C,OAAO,CAAC,QAAQ;IAShB,uEAAuE;IACvE,OAAO,CAAC,WAAW;IAInB;;2EAEuE;IACvE,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ,CAKjC;IAED;sDACkD;IAClD,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,UAAU;IAMlB;;eAEW;IACX,OAAO,CAAC,MAAM;IAoBd,OAAO,CAAC,UAAU;IAKlB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,cAAc;IAkBtB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,QAAQ;IAuFhB;4CACwC;IACxC,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,IAAI;IAuBZ,WAAW,IAAI,QAAQ,CAEtB;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAO7C;IAED,MAAM,CAAC,IAAI,SAAY,GAAG,IAAI,CAG7B;IAED,OAAO,CAAC,IAAI,SAAY,GAAG,IAAI,CAE9B;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQzB;IAED,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAEtC;IAED,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CASjE;IAED,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAElD;IAED,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAElD;IAED,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAIzC;IAED,cAAc,CAAC,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,GAAG,IAAI,CASvD;IAID,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,UAAU;IAKlB;4CACwC;IACxC,OAAO,CAAC,OAAO;IA0Cf,OAAO,CAAC,gBAAgB;IAUxB;mDAC+C;IAC/C,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,SAAS;IA+BjB;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IA8Bf,OAAO,CAAC,OAAO;IAgBf;;;;;;;;;OASG;IACH,OAAO,CAAC,cAAc;IAyBtB;;8DAE0D;IAC1D,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,UAAU;IAQlB;mEAC+D;IAC/D,OAAO,CAAC,SAAS;IA2BjB;;sDAEkD;IAClD,OAAO,CAAC,aAAa;IAwCrB,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,OAAO;IAsBf,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,eAAe;IAMvB;gDAC4C;IAC5C,OAAO,CAAC,QAAQ;IA6ChB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,aAAa;IAgBZ,gBAAgB,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CA+J9C;IAEQ,gBAAgB,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CAU9C;IAED,OAAO,CAAC,aAAa;IA2CZ,cAAc,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CA+F5C;IAEQ,kBAAkB,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CAoBhD;IAED,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,SAAS;IAyEjB;;+DAE2D;IAC3D,OAAO,CAAC,WAAW;IA+CnB,OAAO,CAAC,YAAY;IA+DpB;iEAC6D;IAC7D,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,UAAU;IA6BlB;;2EAEuE;IAC9D,YAAY,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CAQ1C;IAED,OAAO,CAAC,cAAc;IActB;;qBAEiB;IACR,gBAAgB,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CA+B9C;IAEQ,iBAAiB,IAAI,IAAI,CASjC;IAED;wEACoE;IACpE,OAAO,CAAC,YAAY;IAepB;;;;;;;;;OASG;IACM,SAAS,IAAI,aAAa,EAAE,CAyBpC;IAED;;;;OAIG;IACM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAKrE;IAIQ,cAAc,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CAQ/C;IAED,OAAO,CAAC,YAAY;IAiFpB,OAAO,CAAC,UAAU;IAkBlB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAkBf,UAAU,CACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,IAAI,CAmDN;IAEQ,cAAc,IAAI,IAAI,CAI9B;IAED,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,cAAc;IAQb,KAAK,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAmInC;IAED;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IA4CnB;;yEAEqE;IACrE,OAAO,CAAC,UAAU;IA0ElB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,iBAAiB;IAqDzB,OAAO,CAAC,gBAAgB;IAcxB;;+EAE2E;IAC3E,OAAO,CAAC,eAAe;IAgCvB,OAAO,CAAC,aAAa;IAQrB;yDACqD;IACrD,OAAO,CAAC,WAAW;IA6MnB;gEAC4D;IAC5D,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,UAAU;IA4ClB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,WAAW;IAmBnB;uDACmD;IACnD;;iCAE6B;IAC7B,OAAO,CAAC,eAAe;IA0CvB;iDAC6C;IAC7C,OAAO,CAAC,aAAa;IAqErB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,aAAa;IA8CrB,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,aAAa;IAwErB,OAAO,CAAC,cAAc;CA4EvB"}
|
package/dist/flow/node.js
CHANGED
|
@@ -23,7 +23,7 @@ import * as ntk from 'react-x11/ntk';
|
|
|
23
23
|
import { Node } from 'react-x11/node';
|
|
24
24
|
import { tint } from 'react-x11/style';
|
|
25
25
|
import { ctrlChordLetter, keysymOf, XK_BACKSPACE, XK_DELETE, XK_DOWN, XK_ESCAPE, XK_HOME, XK_LEFT, XK_RIGHT, XK_UP, } from 'react-x11/keysyms';
|
|
26
|
-
import { createPainter, measureText } from './draw.js';
|
|
26
|
+
import { createPainter, measureText, toDevice } from './draw.js';
|
|
27
27
|
import { boundsOf, canConnect, clamp, DEFAULT_MARKER_SIZE, DEFAULT_MAX_ZOOM, DEFAULT_MIN_ZOOM, EDGE_SLOP, EDGE_STEP_OFFSET, fitViewport, handleAnchor, HANDLE_RADIUS, HANDLE_SLOP, gripPoint, inflateRect, intersectRects, measureNode, MIN_NODE_HEIGHT, MIN_NODE_WIDTH, NODE_BODY_INSET, NODE_DESC_SIZE, NODE_HEADER, NODE_LABEL_SIZE, NODE_PAD_X, NODE_PAD_Y, normalizeBackground, normalizeMarker, orientConnection, rectContains, rectsOverlap, RENDER_ZOOM, RESIZE_DIRECTIONS, RESIZE_GRIP, RESIZE_SLOP, resizeRect, resolveHandles, resolvePalette, snapTo, unionRects, ZOOM_STEP, } from './model.js';
|
|
28
28
|
import { distanceToPath, edgePath, endAngle, pathBounds, pointAtFraction, startAngle, trimEnd, } from './paths.js';
|
|
29
29
|
/** Registration key, `kind` and JSX tag, one string — react-x11 rejects a
|
|
@@ -350,6 +350,7 @@ export class FlowGraphNode extends Node {
|
|
|
350
350
|
this._themeString('fontFamily') ??
|
|
351
351
|
'sans-serif',
|
|
352
352
|
color: this._palette().text,
|
|
353
|
+
scale: this._scale,
|
|
353
354
|
cache: this._textCache,
|
|
354
355
|
};
|
|
355
356
|
}
|
|
@@ -624,16 +625,66 @@ export class FlowGraphNode extends Node {
|
|
|
624
625
|
_viewport() {
|
|
625
626
|
return this._prop('viewport') ?? this._vp;
|
|
626
627
|
}
|
|
628
|
+
/**
|
|
629
|
+
* Device pixels per logical pixel — the display scale this pane's window
|
|
630
|
+
* resolved to (react-x11's docs/scale.md): `1` on an ordinary display,
|
|
631
|
+
* `2` on a retina panel, fractional on a desktop configured to 1.5.
|
|
632
|
+
*
|
|
633
|
+
* The pane thinks in logical pixels throughout. They are the unit its API
|
|
634
|
+
* speaks (a viewport, a node's size, a `NodeBodyRect`), the unit a
|
|
635
|
+
* synthetic event's `x`/`y` arrive in, and the unit the sibling boxes
|
|
636
|
+
* `<Flow>` mounts bodies in are laid out in. What core hands this element
|
|
637
|
+
* is device pixels — `abs`, `contentBox()`, `this.style`, the paint
|
|
638
|
+
* context, `paintDamage()`, a rect given to `invalidate` or
|
|
639
|
+
* `scrollContents`, an a11y scene rect — so each of those crossings
|
|
640
|
+
* converts, once, in the helpers below, and nothing in between knows the
|
|
641
|
+
* factor. At 1x every conversion is the identity, which is how a pane
|
|
642
|
+
* that compared `ev.x` with `contentBox()` passed every test and then
|
|
643
|
+
* hovered at half the distance, panned at half speed and framed the graph
|
|
644
|
+
* at half size the day a native backend reported a retina panel.
|
|
645
|
+
*/
|
|
646
|
+
get _scale() {
|
|
647
|
+
return this.scale > 0 ? this.scale : 1;
|
|
648
|
+
}
|
|
649
|
+
/** A logical rect on the device grid, grown outward to whole pixels —
|
|
650
|
+
* what a damage claim has to cover for an antialiased edge to repaint. */
|
|
651
|
+
_device(rect) {
|
|
652
|
+
const s = this._scale;
|
|
653
|
+
const x = Math.floor(toDevice(rect.x, s));
|
|
654
|
+
const y = Math.floor(toDevice(rect.y, s));
|
|
655
|
+
return {
|
|
656
|
+
x,
|
|
657
|
+
y,
|
|
658
|
+
width: Math.ceil(toDevice(rect.x + rect.width, s)) - x,
|
|
659
|
+
height: Math.ceil(toDevice(rect.y + rect.height, s)) - y,
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
/** One of core's device rects in the pane's logical units. */
|
|
663
|
+
_logical(rect) {
|
|
664
|
+
const s = this._scale;
|
|
665
|
+
return {
|
|
666
|
+
x: rect.x / s,
|
|
667
|
+
y: rect.y / s,
|
|
668
|
+
width: rect.width / s,
|
|
669
|
+
height: rect.height / s,
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
/** Claim a logical rect as damage. Every partial repaint the pane asks
|
|
673
|
+
* for goes through here; the full ones pass `abs`, which is device
|
|
674
|
+
* already. */
|
|
675
|
+
_claim(rect, reason) {
|
|
676
|
+
this.invalidate(false, this._device(rect), reason);
|
|
677
|
+
}
|
|
627
678
|
/**
|
|
628
679
|
* The pane proper: `abs` inset by border and padding, off core's own
|
|
629
680
|
* resolved layout (react-x11#254) — so a `<Flow style={{ borderWidth: 1,
|
|
630
681
|
* padding: 8 }}>` keeps its border, and its padding means what it does on
|
|
631
|
-
* a `<box>`.
|
|
682
|
+
* a `<box>`. In logical pixels, like everything the pane computes.
|
|
632
683
|
*/
|
|
633
684
|
_pane() {
|
|
634
|
-
return this.contentBox();
|
|
685
|
+
return this._logical(this.contentBox());
|
|
635
686
|
}
|
|
636
|
-
/** Graph point to window pixels. */
|
|
687
|
+
/** Graph point to logical window pixels. */
|
|
637
688
|
_toScreen(p) {
|
|
638
689
|
const v = this._viewport();
|
|
639
690
|
const pane = this._pane();
|
|
@@ -642,7 +693,7 @@ export class FlowGraphNode extends Node {
|
|
|
642
693
|
y: pane.y + p.y * v.zoom + v.y,
|
|
643
694
|
};
|
|
644
695
|
}
|
|
645
|
-
/**
|
|
696
|
+
/** Logical window pixels to graph point. */
|
|
646
697
|
_toGraph(x, y) {
|
|
647
698
|
const v = this._viewport();
|
|
648
699
|
const pane = this._pane();
|
|
@@ -703,7 +754,7 @@ export class FlowGraphNode extends Node {
|
|
|
703
754
|
return entry.specs.map((spec) => handleAnchor(entry.node.id, rect, spec));
|
|
704
755
|
}
|
|
705
756
|
/**
|
|
706
|
-
* A node's box on screen, **on whole pixels**.
|
|
757
|
+
* A node's box on screen, **on whole device pixels**.
|
|
707
758
|
*
|
|
708
759
|
* The rounding is not cosmetic. ntk draws a rounded box as cached corner
|
|
709
760
|
* glyphs plus `FillRectangles` when its geometry is integral, and
|
|
@@ -712,22 +763,26 @@ export class FlowGraphNode extends Node {
|
|
|
712
763
|
* six hundred mask uploads a frame and about four megabytes on the wire;
|
|
713
764
|
* `react-x11/debug`'s trace names it as `fell back … fractional`.
|
|
714
765
|
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
766
|
+
* The grid is the panel's, not the logical one: at 2x a logical half is
|
|
767
|
+
* a whole pixel, and at 1.5x a logical integer is not always one. Hit
|
|
768
|
+
* testing reads the same rect, so what is drawn and what is clicked still
|
|
769
|
+
* agree to the pixel.
|
|
717
770
|
*/
|
|
718
771
|
_screenRect(entry) {
|
|
719
772
|
const v = this._viewport();
|
|
720
773
|
const rect = this.rectOf(entry);
|
|
721
774
|
const p = this._toScreen(rect);
|
|
722
|
-
const
|
|
723
|
-
const
|
|
775
|
+
const s = this._scale;
|
|
776
|
+
const grid = (value) => Math.round(value * s) / s;
|
|
777
|
+
const x = grid(p.x);
|
|
778
|
+
const y = grid(p.y);
|
|
724
779
|
return {
|
|
725
780
|
x,
|
|
726
781
|
y,
|
|
727
782
|
// rounded as edges rather than as a size, so two nodes that share a
|
|
728
783
|
// column still share it after rounding
|
|
729
|
-
width:
|
|
730
|
-
height:
|
|
784
|
+
width: grid(p.x + rect.width * v.zoom) - x,
|
|
785
|
+
height: grid(p.y + rect.height * v.zoom) - y,
|
|
731
786
|
};
|
|
732
787
|
}
|
|
733
788
|
_visible() {
|
|
@@ -773,8 +828,8 @@ export class FlowGraphNode extends Node {
|
|
|
773
828
|
* panels repaint in place.
|
|
774
829
|
*
|
|
775
830
|
* Still a full repaint when:
|
|
776
|
-
* - the zoom moved (scaling is not a blit) or the shift is fractional
|
|
777
|
-
* every real pan gesture is whole pixels;
|
|
831
|
+
* - the zoom moved (scaling is not a blit) or the shift is fractional on
|
|
832
|
+
* the device grid — every real pan gesture is whole device pixels;
|
|
778
833
|
* - mounted node bodies exist: they are core-owned siblings whose
|
|
779
834
|
* gesture-time commits claim *inside* the rect every step, which
|
|
780
835
|
* declines the blit anyway — bailing early skips the churn;
|
|
@@ -786,11 +841,17 @@ export class FlowGraphNode extends Node {
|
|
|
786
841
|
return false;
|
|
787
842
|
if (this._bodiesKey !== '')
|
|
788
843
|
return false;
|
|
789
|
-
|
|
790
|
-
|
|
844
|
+
// Device pixels: the blit copies the backing store, and its grid is the
|
|
845
|
+
// panel's. A pointer step lands on it whatever the scale — it came off
|
|
846
|
+
// the wire as whole device pixels — so every real pan gesture blits.
|
|
847
|
+
const s = this._scale;
|
|
848
|
+
const shiftX = toDevice(next.x - previous.x, s);
|
|
849
|
+
const shiftY = toDevice(next.y - previous.y, s);
|
|
850
|
+
const dx = Math.round(shiftX);
|
|
851
|
+
const dy = Math.round(shiftY);
|
|
791
852
|
if (dx === 0 && dy === 0)
|
|
792
853
|
return true; // sub-pixel: nothing to show yet
|
|
793
|
-
if (
|
|
854
|
+
if (shiftX !== dx || shiftY !== dy)
|
|
794
855
|
return false;
|
|
795
856
|
const pane = this._pane();
|
|
796
857
|
// The horizontal bands the furniture lives in. Full-width, because the
|
|
@@ -815,27 +876,34 @@ export class FlowGraphNode extends Node {
|
|
|
815
876
|
const last = buttons[buttons.length - 1].rect;
|
|
816
877
|
claim(unionRects(first, last), this._controlsOptions()?.position ?? 'bottom-left');
|
|
817
878
|
}
|
|
879
|
+
// From here on, device pixels: `scrollContents` and the claims speak
|
|
880
|
+
// core's units. The bands round *up* and the blit is what is left, so
|
|
881
|
+
// the three sit edge to edge on whole pixels — a claim overlapping the
|
|
882
|
+
// blit rect by a pixel is a foreign claim, and declines the blit.
|
|
883
|
+
const box = this.contentBox();
|
|
884
|
+
const top = Math.ceil(toDevice(topBand, s));
|
|
885
|
+
const bottom = Math.ceil(toDevice(bottomBand, s));
|
|
818
886
|
const blit = {
|
|
819
|
-
x:
|
|
820
|
-
y:
|
|
821
|
-
width:
|
|
822
|
-
height:
|
|
887
|
+
x: box.x,
|
|
888
|
+
y: box.y + top,
|
|
889
|
+
width: box.width,
|
|
890
|
+
height: box.height - top - bottom,
|
|
823
891
|
};
|
|
824
|
-
if (blit.width < 64 || blit.height < 64)
|
|
892
|
+
if (blit.width < 64 * s || blit.height < 64 * s)
|
|
825
893
|
return false;
|
|
826
894
|
if (Math.abs(dx) >= blit.width || Math.abs(dy) >= blit.height) {
|
|
827
895
|
return false;
|
|
828
896
|
}
|
|
829
897
|
this.scrollContents(blit, dx, dy);
|
|
830
|
-
if (
|
|
831
|
-
this.invalidate(false, { x:
|
|
898
|
+
if (top > 0) {
|
|
899
|
+
this.invalidate(false, { x: box.x, y: box.y, width: box.width, height: top }, 'scroll');
|
|
832
900
|
}
|
|
833
|
-
if (
|
|
901
|
+
if (bottom > 0) {
|
|
834
902
|
this.invalidate(false, {
|
|
835
|
-
x:
|
|
903
|
+
x: box.x,
|
|
836
904
|
y: blit.y + blit.height,
|
|
837
|
-
width:
|
|
838
|
-
height:
|
|
905
|
+
width: box.width,
|
|
906
|
+
height: bottom,
|
|
839
907
|
}, 'scroll');
|
|
840
908
|
}
|
|
841
909
|
return true;
|
|
@@ -1496,7 +1564,7 @@ export class FlowGraphNode extends Node {
|
|
|
1496
1564
|
// The box outline is all that moves this step; a node crossing the
|
|
1497
1565
|
// boundary changes `selected`, and that repaints through the
|
|
1498
1566
|
// controlled round trip like any other selection change.
|
|
1499
|
-
this.
|
|
1567
|
+
this._claim(inflateRect(unionRects(oldBox, selectBoxRect(gesture)), CULL_MARGIN), 'style-state');
|
|
1500
1568
|
return;
|
|
1501
1569
|
}
|
|
1502
1570
|
case 'minimap': {
|
|
@@ -1668,7 +1736,7 @@ export class FlowGraphNode extends Node {
|
|
|
1668
1736
|
}
|
|
1669
1737
|
this._emitNodes(changes);
|
|
1670
1738
|
if (damage) {
|
|
1671
|
-
this.
|
|
1739
|
+
this._claim(inflateRect(damage, CULL_MARGIN), 'content');
|
|
1672
1740
|
}
|
|
1673
1741
|
else {
|
|
1674
1742
|
this._repaint();
|
|
@@ -1717,7 +1785,7 @@ export class FlowGraphNode extends Node {
|
|
|
1717
1785
|
});
|
|
1718
1786
|
}
|
|
1719
1787
|
this._emitNodes(changes);
|
|
1720
|
-
this.
|
|
1788
|
+
this._claim(inflateRect(damage, CULL_MARGIN), 'content');
|
|
1721
1789
|
this._emitBodies();
|
|
1722
1790
|
}
|
|
1723
1791
|
_connectStep(gesture, ev) {
|
|
@@ -1763,7 +1831,7 @@ export class FlowGraphNode extends Node {
|
|
|
1763
1831
|
if (target)
|
|
1764
1832
|
box = unionRects(box, this._screenRect(target));
|
|
1765
1833
|
gesture.box = box;
|
|
1766
|
-
this.
|
|
1834
|
+
this._claim(inflateRect(oldBox ? unionRects(oldBox, box) : box, CULL_MARGIN), 'style-state');
|
|
1767
1835
|
}
|
|
1768
1836
|
/** The pending connection's polyline — one builder for the paint and for
|
|
1769
1837
|
* the damage it has to claim, so the two cannot disagree. */
|
|
@@ -1870,7 +1938,7 @@ export class FlowGraphNode extends Node {
|
|
|
1870
1938
|
const damage = unionMaybe(this._hoverDamage(this._hover), this._hoverDamage(next));
|
|
1871
1939
|
this._hover = next;
|
|
1872
1940
|
if (damage) {
|
|
1873
|
-
this.
|
|
1941
|
+
this._claim(inflateRect(damage, CULL_MARGIN), 'style-state');
|
|
1874
1942
|
}
|
|
1875
1943
|
else {
|
|
1876
1944
|
this._repaint('style-state');
|
|
@@ -1882,7 +1950,7 @@ export class FlowGraphNode extends Node {
|
|
|
1882
1950
|
const damage = this._hoverDamage(this._hover);
|
|
1883
1951
|
this._hover = NO_HOVER;
|
|
1884
1952
|
if (damage) {
|
|
1885
|
-
this.
|
|
1953
|
+
this._claim(inflateRect(damage, CULL_MARGIN), 'style-state');
|
|
1886
1954
|
}
|
|
1887
1955
|
else {
|
|
1888
1956
|
this._repaint('style-state');
|
|
@@ -1928,7 +1996,8 @@ export class FlowGraphNode extends Node {
|
|
|
1928
1996
|
const degree = out.length;
|
|
1929
1997
|
items.push({
|
|
1930
1998
|
id: entry.node.id,
|
|
1931
|
-
|
|
1999
|
+
// the scene's rects are `abs`'s space — device pixels
|
|
2000
|
+
rect: this._device(rect),
|
|
1932
2001
|
role: 'listitem',
|
|
1933
2002
|
name: data?.label ?? entry.node.id,
|
|
1934
2003
|
description: degree === 0
|
|
@@ -2121,7 +2190,7 @@ export class FlowGraphNode extends Node {
|
|
|
2121
2190
|
if (damage === 'full')
|
|
2122
2191
|
this._repaint('props');
|
|
2123
2192
|
else if (damage)
|
|
2124
|
-
this.
|
|
2193
|
+
this._claim(damage, 'props');
|
|
2125
2194
|
// Core re-reads the scene for aria-prop commits; a `nodes`/`edges`
|
|
2126
2195
|
// change is invisible to it, so the re-read is asked for by name.
|
|
2127
2196
|
// Free when no assistive technology is listening.
|
|
@@ -2141,7 +2210,7 @@ export class FlowGraphNode extends Node {
|
|
|
2141
2210
|
this._dashPhase += ANIMATION_SPEED;
|
|
2142
2211
|
// the box the last paint saw animated edges in, not the pane: a
|
|
2143
2212
|
// marching dash should not cost a full grid repaint per tick
|
|
2144
|
-
this.invalidate(false, this._animBox
|
|
2213
|
+
this.invalidate(false, this._animBox ? this._device(this._animBox) : this.abs, 'animation');
|
|
2145
2214
|
}, ANIMATION_MS) ?? null;
|
|
2146
2215
|
}
|
|
2147
2216
|
_stopAnimation() {
|
|
@@ -2195,7 +2264,13 @@ export class FlowGraphNode extends Node {
|
|
|
2195
2264
|
this._fit(this._prop('fitViewOptions'));
|
|
2196
2265
|
}
|
|
2197
2266
|
}
|
|
2198
|
-
|
|
2267
|
+
// `paintDamage()` speaks device pixels, like `abs`; the culling below
|
|
2268
|
+
// speaks logical ones, like everything the pane draws.
|
|
2269
|
+
this._frameClip = this._fitPending
|
|
2270
|
+
? this._pane()
|
|
2271
|
+
: clip
|
|
2272
|
+
? this._logical(clip)
|
|
2273
|
+
: null;
|
|
2199
2274
|
const palette = this._palette();
|
|
2200
2275
|
const { x, y, width, height } = this._pane();
|
|
2201
2276
|
painter.save();
|
|
@@ -2204,8 +2279,10 @@ export class FlowGraphNode extends Node {
|
|
|
2204
2279
|
// clip is the content box rather than `abs` because the border has been
|
|
2205
2280
|
// stroked already, inside the box, and drawing over it would leave a
|
|
2206
2281
|
// `borderWidth: 1` looking like half of one.
|
|
2282
|
+
// `this.style` arrives in device pixels (react-x11's docs/scale.md);
|
|
2283
|
+
// the painter takes logical ones.
|
|
2207
2284
|
const radius = Math.max(0, (this.style.borderRadius ?? 0) -
|
|
2208
|
-
(this.style.borderWidth ?? 0));
|
|
2285
|
+
(this.style.borderWidth ?? 0)) / this._scale;
|
|
2209
2286
|
// The rounded clip only when this pass can actually reach a corner: a
|
|
2210
2287
|
// non-rectangular clip forfeits ntk's rounded-box fast path for every
|
|
2211
2288
|
// fill under it, which multiplies a rounded *pane* into a per-card
|
|
@@ -2287,8 +2364,8 @@ export class FlowGraphNode extends Node {
|
|
|
2287
2364
|
continue;
|
|
2288
2365
|
bodies.push({
|
|
2289
2366
|
id: entry.node.id,
|
|
2290
|
-
// pane-relative, because that is what an absolutely
|
|
2291
|
-
// beside the pane is laid out against
|
|
2367
|
+
// pane-relative and logical, because that is what an absolutely
|
|
2368
|
+
// positioned box beside the pane is laid out against, and in
|
|
2292
2369
|
x: Math.round(rect.x + inset - pane.x),
|
|
2293
2370
|
y: Math.round(rect.y + header - pane.y),
|
|
2294
2371
|
width: Math.round(width),
|
|
@@ -2297,8 +2374,11 @@ export class FlowGraphNode extends Node {
|
|
|
2297
2374
|
selected: entry.node.selected ?? false,
|
|
2298
2375
|
});
|
|
2299
2376
|
}
|
|
2377
|
+
// The zoom is in the key as well as the rect it produced: it is the
|
|
2378
|
+
// body's subtree scale now, and two zooms a rounding apart can leave a
|
|
2379
|
+
// box on the same integers while the text inside it should have moved.
|
|
2300
2380
|
const key = bodies
|
|
2301
|
-
.map((b) => `${b.id}:${b.x},${b.y},${b.width},${b.height},${b.selected}`)
|
|
2381
|
+
.map((b) => `${b.id}:${b.x},${b.y},${b.width},${b.height},${b.zoom},${b.selected}`)
|
|
2302
2382
|
.join('|');
|
|
2303
2383
|
if (key === this._bodiesKey)
|
|
2304
2384
|
return;
|
|
@@ -2394,8 +2474,13 @@ export class FlowGraphNode extends Node {
|
|
|
2394
2474
|
* 24px tile is a handful of requests on any server.
|
|
2395
2475
|
*/
|
|
2396
2476
|
_paintGridPattern(painter, options, step, color, region) {
|
|
2397
|
-
|
|
2398
|
-
|
|
2477
|
+
// The tile is a pixmap on the panel's grid, so the pitch has to be a
|
|
2478
|
+
// whole number of *device* pixels, and the phase is where the viewport
|
|
2479
|
+
// origin lands on that grid.
|
|
2480
|
+
const s = this._scale;
|
|
2481
|
+
const pitch = toDevice(step, s);
|
|
2482
|
+
const tileSize = Math.round(pitch);
|
|
2483
|
+
if (Math.abs(pitch - tileSize) > 0.01 || tileSize < 2)
|
|
2399
2484
|
return false;
|
|
2400
2485
|
const raw = painter.raw;
|
|
2401
2486
|
if (!raw || typeof raw.createPattern !== 'function')
|
|
@@ -2403,9 +2488,11 @@ export class FlowGraphNode extends Node {
|
|
|
2403
2488
|
const v = this._viewport();
|
|
2404
2489
|
const pane = this._pane();
|
|
2405
2490
|
const mod = (a, m) => ((a % m) + m) % m;
|
|
2406
|
-
const px = Math.round(mod(pane.x + v.x, tileSize)) % tileSize;
|
|
2407
|
-
const py = Math.round(mod(pane.y + v.y, tileSize)) % tileSize;
|
|
2408
|
-
|
|
2491
|
+
const px = Math.round(mod(toDevice(pane.x + v.x, s), tileSize)) % tileSize;
|
|
2492
|
+
const py = Math.round(mod(toDevice(pane.y + v.y, s), tileSize)) % tileSize;
|
|
2493
|
+
// device pixels per graph unit — what a mark's size is drawn in
|
|
2494
|
+
const unit = v.zoom * s;
|
|
2495
|
+
const key = `${options.variant}|${Math.round(options.size * unit * 4)}|${color}|${px},${py}`;
|
|
2409
2496
|
let tile = this._gridTile;
|
|
2410
2497
|
if (!tile || tile.size !== tileSize) {
|
|
2411
2498
|
this._dropGridTile();
|
|
@@ -2422,10 +2509,11 @@ export class FlowGraphNode extends Node {
|
|
|
2422
2509
|
}
|
|
2423
2510
|
if (tile.key !== key) {
|
|
2424
2511
|
tile.key = key;
|
|
2425
|
-
this._renderGridTile(tile, options,
|
|
2512
|
+
this._renderGridTile(tile, options, unit, color, px, py);
|
|
2426
2513
|
}
|
|
2427
2514
|
raw.fillStyle = tile.pattern;
|
|
2428
|
-
|
|
2515
|
+
const fill = this._device(region);
|
|
2516
|
+
raw.fillRect?.(fill.x, fill.y, fill.width, fill.height);
|
|
2429
2517
|
return true;
|
|
2430
2518
|
}
|
|
2431
2519
|
_makeGridSurface(tileSize) {
|
|
@@ -2444,8 +2532,9 @@ export class FlowGraphNode extends Node {
|
|
|
2444
2532
|
}
|
|
2445
2533
|
}
|
|
2446
2534
|
/** Draw one grid cell with the mark at the phase point, wrapped — a mark
|
|
2447
|
-
* near an edge is drawn again a tile over, so the seam never cuts it.
|
|
2448
|
-
|
|
2535
|
+
* near an edge is drawn again a tile over, so the seam never cuts it.
|
|
2536
|
+
* Device pixels throughout: `unit` is how many of them a graph unit is. */
|
|
2537
|
+
_renderGridTile(tile, options, unit, color, px, py) {
|
|
2449
2538
|
const t = tile.size;
|
|
2450
2539
|
tile.surface.render((ctx) => {
|
|
2451
2540
|
ctx.clearRect?.(0, 0, t, t);
|
|
@@ -2461,12 +2550,12 @@ export class FlowGraphNode extends Node {
|
|
|
2461
2550
|
ctx.fillRect(0, cy - 0.5, t, 1);
|
|
2462
2551
|
}
|
|
2463
2552
|
else if (options.variant === 'cross') {
|
|
2464
|
-
const arm = Math.max(2, options.size * 3 *
|
|
2553
|
+
const arm = Math.max(2, options.size * 3 * unit);
|
|
2465
2554
|
ctx.fillRect(cx - arm, cy - 0.5, arm * 2, 1);
|
|
2466
2555
|
ctx.fillRect(cx - 0.5, cy - arm, 1, arm * 2);
|
|
2467
2556
|
}
|
|
2468
2557
|
else {
|
|
2469
|
-
const dot = Math.max(1, Math.round(options.size * 2 *
|
|
2558
|
+
const dot = Math.max(1, Math.round(options.size * 2 * unit));
|
|
2470
2559
|
ctx.fillRect(cx - dot / 2, cy - dot / 2, dot, dot);
|
|
2471
2560
|
}
|
|
2472
2561
|
}
|