Skip to content

Commit

Permalink
Fix anchored text objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
D8H committed Oct 1, 2024
1 parent 3d8aee7 commit b50b933
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 55 deletions.
58 changes: 48 additions & 10 deletions Extensions/AnchorBehavior/anchorruntimebehavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ namespace gdjs {
owner: gdjs.RuntimeObject
) {
super(instanceContainer, behaviorData, owner);
this._relativeToOriginalWindowSize = !!behaviorData.relativeToOriginalWindowSize;
this._relativeToOriginalWindowSize =
!!behaviorData.relativeToOriginalWindowSize;
this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;
this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;
this._topEdgeAnchor = behaviorData.topEdgeAnchor;
Expand Down Expand Up @@ -88,7 +89,6 @@ namespace gdjs {
const workingPoint: FloatPoint = gdjs.staticArray(
gdjs.AnchorRuntimeBehavior.prototype.doStepPreEvents
) as FloatPoint;
// TODO EBO Make it work with event based objects or hide this behavior for them.
let parentMinX = instanceContainer.getUnrotatedViewportMinX();
let parentMinY = instanceContainer.getUnrotatedViewportMinY();
let parentMaxX = instanceContainer.getUnrotatedViewportMaxX();
Expand All @@ -111,10 +111,11 @@ namespace gdjs {
}

//Calculate the distances from the window's bounds.
const topLeftPixel = layer.convertCoords(
const topLeftPixel = this._convertCoords(
instanceContainer,
layer,
this.owner.getDrawableX(),
this.owner.getDrawableY(),
0,
workingPoint
);

Expand All @@ -141,10 +142,11 @@ namespace gdjs {
}

// It's fine to reuse workingPoint as topLeftPixel is no longer used.
const bottomRightPixel = layer.convertCoords(
const bottomRightPixel = this._convertCoords(
instanceContainer,
layer,
this.owner.getDrawableX() + this.owner.getWidth(),
this.owner.getDrawableY() + this.owner.getHeight(),
0,
workingPoint
);

Expand Down Expand Up @@ -225,19 +227,21 @@ namespace gdjs {
}

// It's fine to reuse workingPoint as topLeftPixel is no longer used.
const topLeftCoord = layer.convertInverseCoords(
const topLeftCoord = this._convertInverseCoords(
instanceContainer,
layer,
leftPixel,
topPixel,
0,
workingPoint
);
const left = topLeftCoord[0];
const top = topLeftCoord[1];

const bottomRightCoord = layer.convertInverseCoords(
const bottomRightCoord = this._convertInverseCoords(
instanceContainer,
layer,
rightPixel,
bottomPixel,
0,
workingPoint
);
const right = bottomRightCoord[0];
Expand Down Expand Up @@ -328,6 +332,40 @@ namespace gdjs {
}

doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {}

private _convertCoords(
instanceContainer: gdjs.RuntimeInstanceContainer,
layer: gdjs.RuntimeLayer,
x: float,
y: float,
result: FloatPoint
) {
const isParentACustomObject =
instanceContainer !== instanceContainer.getScene();
if (isParentACustomObject) {
result[0] = x;
result[1] = y;
return result;
}
return layer.convertCoords(x, y, 0, result);
}

private _convertInverseCoords(
instanceContainer: gdjs.RuntimeInstanceContainer,
layer: gdjs.RuntimeLayer,
x: float,
y: float,
result: FloatPoint
) {
const isParentACustomObject =
instanceContainer !== instanceContainer.getScene();
if (isParentACustomObject) {
result[0] = x;
result[1] = y;
return result;
}
return layer.convertInverseCoords(x, y, 0, result);
}
}
gdjs.registerBehavior(
'AnchorBehavior::AnchorBehavior',
Expand Down
21 changes: 21 additions & 0 deletions Extensions/AnchorBehavior/tests/anchorruntimebehavior.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,5 +265,26 @@ describe('gdjs.AnchorRuntimeBehavior', function () {
expect(object.getWidth()).to.equal(2000);
expect(object.getHeight()).to.equal(3000);
});

it('can fill the screen with an object using proportional anchors (with custom origin)', () => {
setGameResolutionSizeAndStep(1000, 500);

const object = createSpriteWithOriginAtCenter({
leftEdgeAnchor: 3,
topEdgeAnchor: 3,
rightEdgeAnchor: 3,
bottomEdgeAnchor: 3,
});
object.setCustomWidthAndHeight(1000, 500);
object.setPosition(500, 250);
runtimeScene.renderAndStep(1000 / 60);

setGameResolutionSizeAndStep(2000, 3000);

expect(object.getX()).to.equal(1000);
expect(object.getY()).to.equal(1500);
expect(object.getWidth()).to.equal(2000);
expect(object.getHeight()).to.equal(3000);
});
});
});
18 changes: 17 additions & 1 deletion Extensions/TextObject/textruntimeobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ namespace gdjs {
*/
export class TextRuntimeObject
extends gdjs.RuntimeObject
implements gdjs.TextContainer, gdjs.OpacityHandler {
implements gdjs.TextContainer, gdjs.OpacityHandler
{
_characterSize: number;
_fontName: string;
_bold: boolean;
Expand Down Expand Up @@ -684,6 +685,21 @@ namespace gdjs {
}
}

setWidth(width: float): void {
this.setWrappingWidth(width);
}

getDrawableY(): float {
return (
this.getY() -
(this._verticalTextAlignment === 'center'
? this.getHeight() / 2
: this._verticalTextAlignment === 'bottom'
? this.getHeight()
: 0)
);
}

/**
* Set the outline for the text object.
* @param str color as a "R;G;B" string, for example: "255;0;0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ export class LayoutedInstance {
constructor(instance: gdInitialInstance) {
this.instance = instance;
this.ptr = instance.ptr;
this._hasCustomSize = instance.hasCustomSize();
this._hasCustomDepth = instance.hasCustomDepth();
this._customWidth = instance.getCustomWidth();
this._customHeight = instance.getCustomHeight();
this._customDepth = instance.getCustomWidth();
}

getX() {
Expand Down Expand Up @@ -365,7 +370,7 @@ export const getLayoutedRenderedInstance = <T: ChildRenderedInstance>(

const initialInstanceOriginX =
(renderedInstance.getOriginX() * initialInstanceWidth) /
renderedInstance.getDefaultWidth();
Math.max(1, renderedInstance.getWidth());
const initialInstanceMinX = initialInstanceX - initialInstanceOriginX;
const initialInstanceMaxX = initialInstanceMinX + initialInstanceWidth;

Expand Down Expand Up @@ -397,28 +402,23 @@ export const getLayoutedRenderedInstance = <T: ChildRenderedInstance>(
right = parentCenterX + initialInstanceMaxX - parentInitialCenterX;
}

let x, width;
if (rightEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor) {
width = initialInstanceWidth;
const originX =
(renderedInstance.getOriginX() * width) /
renderedInstance.getDefaultWidth();
x = left + originX;
} else if (leftEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor) {
width = initialInstanceWidth;
const originX =
(renderedInstance.getOriginX() * width) /
renderedInstance.getDefaultWidth();
x = right - width + originX;
} else {
width = right - left;
const originX =
(renderedInstance.getOriginX() * width) /
renderedInstance.getDefaultWidth();
x = left + originX;
}
layoutedInstance.x = x;
const width =
rightEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor
? initialInstanceWidth
: leftEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor
? initialInstanceWidth
: right - left;
layoutedInstance.setCustomWidth(width);

// The originX according to the new width.
const originX = renderedInstance.getOriginX();
const x =
rightEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor
? left + originX
: leftEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor
? right - width + originX
: left + originX;
layoutedInstance.x = x;
}

const initialInstanceY = initialInstance.getY();
Expand All @@ -438,7 +438,7 @@ export const getLayoutedRenderedInstance = <T: ChildRenderedInstance>(

const initialInstanceOriginY =
(renderedInstance.getOriginY() * initialInstanceHeight) /
renderedInstance.getDefaultHeight();
Math.max(1, renderedInstance.getHeight());
const initialInstanceMinY = initialInstanceY - initialInstanceOriginY;
const initialInstanceMaxY = initialInstanceMinY + initialInstanceHeight;

Expand Down Expand Up @@ -470,28 +470,23 @@ export const getLayoutedRenderedInstance = <T: ChildRenderedInstance>(
top = parentCenterY + initialInstanceMinY - parentInitialCenterY;
}

let y, height;
if (bottomEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor) {
height = initialInstanceHeight;
const originY =
(renderedInstance.getOriginY() * height) /
renderedInstance.getDefaultHeight();
y = top + originY;
} else if (topEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor) {
height = initialInstanceHeight;
const originY =
(renderedInstance.getOriginY() * height) /
renderedInstance.getDefaultHeight();
y = bottom - height + originY;
} else {
height = bottom - top;
const originY =
(renderedInstance.getOriginY() * height) /
renderedInstance.getDefaultHeight();
y = top + originY;
}
layoutedInstance.y = y;
const height =
bottomEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor
? initialInstanceHeight
: topEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor
? initialInstanceHeight
: bottom - top;
layoutedInstance.setCustomHeight(height);

// The originY according to the new height.
const originY = renderedInstance.getOriginY();
const y =
bottomEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor
? top + originY
: topEdgeAnchor === gd.CustomObjectConfiguration.NoAnchor
? bottom - height + originY
: top + originY;
layoutedInstance.y = y;
}
return renderedInstance;
};

0 comments on commit b50b933

Please sign in to comment.