Skip to content

Commit 6c817f8

Browse files
authored
fix: name, layout and scale issues (#56)
1 parent 0c2b0d5 commit 6c817f8

File tree

9 files changed

+131
-26
lines changed

9 files changed

+131
-26
lines changed

src/ui/UIContext.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import DrawLayerType from './DrawLayerType';
55
import FactoryRegistry from './components/FactoryRegistry';
66
import FontString from './components/simple/FontString';
77
import Frame from './components/simple/Frame';
8+
import LayoutFrame from './components/abstract/LayoutFrame';
89
import Renderer from './rendering/Renderer';
910
import UIRoot from './components/UIRoot';
1011
import ScriptingContext from './scripting/ScriptingContext';
@@ -44,7 +45,7 @@ class UIContext {
4445
for (const { template } of templates) {
4546
// TODO: Does this bit require lock/release of templates?
4647
if (template && !template.locked) {
47-
parentName = node.attributes.get('parent');
48+
parentName = template.node.attributes.get('parent');
4849
}
4950
}
5051
}
@@ -187,7 +188,7 @@ class UIContext {
187188
}
188189
} else {
189190
this.createFrame(child, null, status);
190-
// TODO: Re-layout
191+
LayoutFrame.resizePending();
191192
}
192193
}
193194
}

src/ui/components/UIRoot.ts

+11
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,17 @@ class UIRoot extends LayoutFrame {
109109
strata.batchDirty = 1;
110110
}
111111

112+
notifyFrameMovedOrResized(frame: Frame) {
113+
const strata = this.strata[frame.strataType];
114+
strata.levelsDirty = 1;
115+
116+
if (this.layout.frame) {
117+
this.raiseFrame(this.layout.frame, false);
118+
}
119+
120+
// TODO: Focus check
121+
}
122+
112123
onLayerUpdate(elapsedSecs: number) {
113124
// TODO: Clean-up destroyed frames
114125

src/ui/components/abstract/FramePoint.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,18 @@ class FramePoint {
7272
return rect;
7373
}
7474

75-
setRelative(_relative: LayoutFrame, _relativePoint: Type, _offsetX: number, _offsetY: number) {
76-
// TODO: Implement
75+
markUnused() {
76+
this.type = Type.TOPLEFT - 1;
77+
this.offset.setElements(0.0, 0.0);
78+
// this.relative = null;
79+
this.flags = this.flags & 0x2 ? 0x2 | 0x4 | 0x8 : 0x8;
80+
}
81+
82+
setRelative(relative: LayoutFrame, relativePoint: Type, offsetX: number, offsetY: number) {
83+
this.type = relativePoint;
84+
this.offset.setElements(offsetX, offsetY);
85+
this.relative = relative;
86+
this.flags = this.flags & 0x2 ? 0x2 | 0x4 : 0x0;
7787
}
7888

7989
x(scale: number) {

src/ui/components/abstract/LayoutFrame.ts

+28-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import ScriptRegion from './ScriptRegion';
21
import XMLNode from '../../XMLNode';
32
import { stringToFramePointType } from '../../utils';
43
import {
@@ -81,7 +80,7 @@ class LayoutFrame {
8180
};
8281

8382
this.resizeList = LinkedList.using('link');
84-
this.resizeCounter = NaN;
83+
this.resizeCounter = 0;
8584

8685
this.points = [
8786
null, null, null,
@@ -329,10 +328,21 @@ class LayoutFrame {
329328
return true;
330329
}
331330

331+
clearAllPoints() {
332+
this.freePoints();
333+
}
334+
332335
freePoints() {
336+
let i = 0;
333337
for (const point of this.points) {
334-
// TODO: Implementation
335-
console.error('freeing point', point);
338+
if (point && !(point.flags & 0x8)) {
339+
if (point.relative) {
340+
point.relative.unregisterResize(this, 1 << i);
341+
}
342+
343+
point.markUnused();
344+
}
345+
++i;
336346
}
337347
}
338348

@@ -357,6 +367,10 @@ class LayoutFrame {
357367
return FramePoint.UNDEFINED;
358368
}
359369

370+
getLayoutFrameByName(_name: string): LayoutFrame | null {
371+
return null;
372+
}
373+
360374
getRect() {
361375
if (!(this.layoutFlags & 0x1)) {
362376
return undefined;
@@ -367,6 +381,11 @@ class LayoutFrame {
367381
return rect;
368382
}
369383

384+
isResizeDependency(_dependentFrame: LayoutFrame) {
385+
// TODO: Implementation
386+
return false;
387+
}
388+
370389
loadXML(node: XMLNode, status: Status) {
371390
const size = node.getChildByName('Size');
372391
if (size) {
@@ -413,8 +432,7 @@ class LayoutFrame {
413432

414433
let relative = layoutParent;
415434
if (relativeValue) {
416-
const fqname = this.fullyQualifyName(relativeValue)!;
417-
relative = ScriptRegion.getObjectByName(fqname);
435+
relative = this.getLayoutFrameByName(relativeValue);
418436
if (!relative) {
419437
status.warning(`could not find relative frame: ${relativeValue}`);
420438
continue;
@@ -554,6 +572,10 @@ class LayoutFrame {
554572
}
555573
}
556574

575+
setLayoutScale(_scale: number, _force: boolean) {
576+
// TODO: Implementation
577+
}
578+
557579
setPoint(pointType: FramePointType, relative: LayoutFrame | null, relativePointType: FramePointType, offsetX = 0, offsetY = 0, resize = false) {
558580
if (!relative || !relative.canBeAnchorFor(this)) {
559581
return;

src/ui/components/abstract/ScriptObject.ts

-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ class ScriptObject extends FrameScriptObject {
1717
this._name = null;
1818
}
1919

20-
get displayName() {
21-
return this.name || '<unnamed>';
22-
}
23-
2420
get name() {
2521
return this._name;
2622
}

src/ui/components/abstract/ScriptRegion.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,15 @@ class ScriptRegion extends multipleClasses(ScriptObject, LayoutFrame) {
3434
}
3535

3636
get layoutParent(): LayoutFrame {
37-
if (this.width === 0.0 || !this.parent) {
37+
if (!this._parent || this._parent.layoutScale === 0.0) {
3838
return UIRoot.instance;
3939
}
40-
return this.parent;
40+
return this._parent;
41+
}
42+
43+
getLayoutFrameByName(name: string): LayoutFrame | null {
44+
const fqname = this.fullyQualifyName(name);
45+
return ScriptRegion.getObjectByName(fqname);
4146
}
4247

4348
loadXML(node: XMLNode, status: Status) {

src/ui/components/simple/Frame.ts

+45-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
Status,
1717
stringToBoolean,
1818
} from '../../../utils';
19-
import { Rect } from '../../../math';
19+
import { EPSILON1, Rect, areClose } from '../../../math';
2020
import {
2121
stringToDrawLayerType,
2222
stringToFrameStrataType,
@@ -53,6 +53,7 @@ class Frame extends ScriptRegion {
5353
visible: boolean;
5454
strataType: FrameStrataType;
5555
level: number;
56+
frameScale: number;
5657

5758
layersEnabled: EnumRecord<DrawLayerType, boolean>;
5859
backdrop: Backdrop | null;
@@ -77,6 +78,7 @@ class Frame extends ScriptRegion {
7778
this.visible = false;
7879
this.strataType = FrameStrataType.MEDIUM;
7980
this.level = 0;
81+
this.frameScale = 1.0;
8082

8183
this.layersEnabled = [
8284
true,
@@ -210,19 +212,21 @@ class Frame extends ScriptRegion {
210212
if (parent) {
211213
this.setFrameStrataType(parent.strataType);
212214
this.setFrameLevel(parent.level + 1, true);
215+
this.updateScale(false);
213216

214217
// TODO: Alpha and scrolling adjustments
215218
} else {
216219
this.setFrameStrataType(FrameStrataType.MEDIUM);
217220
this.setFrameLevel(0, true);
221+
this.updateScale(false);
218222

219223
// TODO: Alpha and scrolling adjustments
220224
}
221225

222226
if (parent) {
223227
// TODO: Parent attachment protection
224228
const node = new FrameNode(this);
225-
parent.children.linkToHead(node);
229+
parent.children.linkToTail(node);
226230
}
227231

228232
if (this.shown) {
@@ -482,7 +486,7 @@ class Frame extends ScriptRegion {
482486
return false;
483487
}
484488

485-
if (this.parent && !this.parent.visible) {
489+
if (this._parent && !this._parent.visible) {
486490
return false;
487491
}
488492

@@ -604,11 +608,23 @@ class Frame extends ScriptRegion {
604608

605609
// TODO: Set hit rect
606610

607-
if (this.backdrop) {
608-
this.backdrop.update(this.rect);
611+
if (!areClose(rect.minX, this.rect.maxX) || !areClose(rect.minY, this.rect.maxY)) {
612+
if (this.backdrop) {
613+
this.backdrop.update(this.rect);
614+
}
615+
616+
const ratio = 1.0 / this.layoutScale;
617+
const width = ratio * (this.rect.maxX - this.rect.minX);
618+
const height = ratio * (this.rect.maxY - this.rect.minY);
619+
620+
this.onFrameSizeChangedRange(width, height);
609621
}
610622

611-
// TODO: Remaining implementation
623+
UIRoot.instance.notifyFrameMovedOrResized(this);
624+
}
625+
626+
onFrameSizeChangedRange(_width: number, _height: number) {
627+
// TODO
612628
}
613629

614630
onLayerShow() {
@@ -648,6 +664,29 @@ class Frame extends ScriptRegion {
648664
this.runScript('OnShow');
649665
}
650666
}
667+
668+
updateScale(force: boolean) {
669+
let scale = this.frameScale;
670+
if (this.parent) {
671+
scale *= this.parent.layoutScale;
672+
}
673+
674+
if ((!force && areClose(scale, this.layoutScale, EPSILON1)) || scale === 0.0) {
675+
return false;
676+
}
677+
678+
this.setLayoutScale(scale, force);
679+
680+
for (const region of this.regions) {
681+
region.setLayoutScale(scale, force);
682+
}
683+
684+
for (const child of this.children) {
685+
child.frame.updateScale(false);
686+
}
687+
688+
return true;
689+
}
651690
}
652691

653692
export default Frame;

src/ui/components/simple/Texture.ts

+17-4
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ class Texture extends Region {
7373
}
7474

7575
get width() {
76-
const layoutwidth = super.width;
77-
if (layoutwidth !== 0.0) {
78-
return layoutwidth;
76+
const layoutWidth = super.width;
77+
if (layoutWidth !== 0.0) {
78+
return layoutWidth;
7979
}
8080

8181
if (this.texture && this.texture.isLoaded) {
@@ -253,7 +253,20 @@ class Texture extends Region {
253253
}
254254

255255
postLoadXML(_node: XMLNode) {
256-
// TODO
256+
if (this._parent) {
257+
let i = 0;
258+
for (const point of this.points) {
259+
if (point && !(point.flags & 0x8)) {
260+
break;
261+
}
262+
263+
if (i + 1 === this.points.length) {
264+
this.setAllPoints(this._parent, true);
265+
break;
266+
}
267+
++i;
268+
}
269+
}
257270
}
258271

259272
onFrameSizeChanged(rect: Rect) {

src/ui/scripting/FrameScriptObject.ts

+8
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,18 @@ class FrameScriptObject {
4141
);
4242
}
4343

44+
get displayName() {
45+
return this.name || '<unnamed>';
46+
}
47+
4448
get isLuaRegistered() {
4549
return this.luaRef !== null;
4650
}
4751

52+
get name(): string | null {
53+
return null;
54+
}
55+
4856
register(name: string | null = null) {
4957
const L = ScriptingContext.instance.state;
5058

0 commit comments

Comments
 (0)