Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vertical alignment property for text object #6975

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Extensions/TextObject/TextObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ TextObject::TextObject()
underlined(false),
color("0;0;0"),
textAlignment("left"),
verticalTextAlignment("top"),
isOutlineEnabled(false),
outlineThickness(2),
outlineColor("255;255;255"),
Expand Down Expand Up @@ -69,6 +70,10 @@ bool TextObject::UpdateProperty(const gd::String& propertyName,
textAlignment = newValue;
return true;
}
if (propertyName == "verticalTextAlignment") {
verticalTextAlignment = newValue;
return true;
}
if (propertyName == "isOutlineEnabled") {
isOutlineEnabled = newValue == "1";
return true;
Expand Down Expand Up @@ -158,6 +163,15 @@ std::map<gd::String, gd::PropertyDescriptor> TextObject::GetProperties() const {
.SetLabel(_("Alignment, when multiple lines are displayed"))
.SetGroup(_("Font"));

objectProperties["verticalTextAlignment"]
.SetValue(verticalTextAlignment)
.SetType("choice")
.AddExtraInfo("top")
.AddExtraInfo("center")
.AddExtraInfo("bottom")
.SetLabel(_("Vertical alignment, when multiple lines are displayed"))
.SetGroup(_("Font"));

objectProperties["isOutlineEnabled"]
.SetValue(isOutlineEnabled ? "true" : "false")
.SetType("boolean")
Expand Down Expand Up @@ -229,6 +243,7 @@ void TextObject::DoUnserializeFrom(gd::Project& project,

SetFontName(content.GetChild("font", 0, "Font").GetValue().GetString());
SetTextAlignment(content.GetChild("textAlignment").GetValue().GetString());
SetVerticalTextAlignment(content.GetStringAttribute("verticalTextAlignment", "top"));
SetCharacterSize(content.GetChild("characterSize", 0, "CharacterSize")
.GetValue()
.GetInt());
Expand Down Expand Up @@ -298,6 +313,7 @@ void TextObject::DoSerializeTo(gd::SerializerElement& element) const {
content.AddChild("text").SetValue(GetText());
content.AddChild("font").SetValue(GetFontName());
content.AddChild("textAlignment").SetValue(GetTextAlignment());
content.AddChild("verticalTextAlignment").SetValue(GetVerticalTextAlignment());
content.AddChild("characterSize").SetValue(GetCharacterSize());
content.AddChild("color").SetValue(GetColor());

Expand Down
6 changes: 6 additions & 0 deletions Extensions/TextObject/TextObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
textAlignment = textAlignment_;
};

inline const gd::String& GetVerticalTextAlignment() const { return verticalTextAlignment; };
void SetVerticalTextAlignment(const gd::String& verticalTextAlignment_) {
verticalTextAlignment = verticalTextAlignment_;
};

bool IsBold() const { return bold; };
void SetBold(bool enable) { bold = enable; };
bool IsItalic() const { return italic; };
Expand Down Expand Up @@ -120,6 +125,7 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
bool bold, italic, underlined;
gd::String color;
gd::String textAlignment;
gd::String verticalTextAlignment;

bool isOutlineEnabled;
double outlineThickness;
Expand Down
10 changes: 10 additions & 0 deletions Extensions/TextObject/textruntimeobject-pixi-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ namespace gdjs {
this._text.anchor.x = 0.5;
}
this._text.position.y = this._object.y + this._text.height / 2;

const alignmentY =
this._object._verticalTextAlignment === 'bottom'
? 1
: this._object._verticalTextAlignment === 'center'
? 0.5
: 0;
this._text.position.y =
this._object.y + this._text.height * (0.5 - alignmentY);
this._text.anchor.y = 0.5;
}

updateAngle(): void {
Expand Down
28 changes: 28 additions & 0 deletions Extensions/TextObject/textruntimeobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace gdjs {
/** The text of the object */
text: string;
textAlignment: string;
verticalTextAlignment: string;

isOutlineEnabled: boolean;
outlineThickness: float;
Expand Down Expand Up @@ -83,6 +84,7 @@ namespace gdjs {
_gradientType: string = '';
opacity: float = 255;
_textAlign: string = 'left';
_verticalTextAlignment: string = 'top';
_wrapping: boolean = false;
// A wrapping of 1 makes games crash on Firefox
_wrappingWidth: float = 100;
Expand Down Expand Up @@ -124,6 +126,7 @@ namespace gdjs {
this._color = gdjs.rgbOrHexToRGBColor(content.color);
this._str = content.text;
this._textAlign = content.textAlignment;
this._verticalTextAlignment = content.verticalTextAlignment;

this._isOutlineEnabled = content.isOutlineEnabled;
this._outlineThickness = content.outlineThickness;
Expand Down Expand Up @@ -175,6 +178,11 @@ namespace gdjs {
if (oldContent.textAlignment !== newContent.textAlignment) {
this.setTextAlignment(newContent.textAlignment);
}
if (
oldContent.verticalTextAlignment !== newContent.verticalTextAlignment
) {
this.setVerticalTextAlignment(newContent.verticalTextAlignment);
}
if (oldContent.isOutlineEnabled !== newContent.isOutlineEnabled) {
this.setOutlineEnabled(newContent.isOutlineEnabled);
}
Expand Down Expand Up @@ -267,6 +275,9 @@ namespace gdjs {
if (networkSyncData.ta !== undefined) {
this.setTextAlignment(networkSyncData.ta);
}
if (networkSyncData.ta !== undefined) {
this.setVerticalTextAlignment(networkSyncData.ta);
}
if (networkSyncData.wrap !== undefined) {
this.setWrapping(networkSyncData.wrap);
}
Expand Down Expand Up @@ -594,6 +605,23 @@ namespace gdjs {
return this._color[0] + ';' + this._color[1] + ';' + this._color[2];
}

/**
* Set the text alignment on Y axis for multiline text objects.
* @param alignment The text alignment.
*/
setVerticalTextAlignment(alignment: string): void {
this._verticalTextAlignment = alignment;
this._renderer.updateStyle();
}

/**
* Get the text alignment on Y axis of text object.
* @return The text alignment.
*/
getVerticalTextAlignment(): string {
return this._verticalTextAlignment;
}

/**
* Set the text alignment for multiline text objects.
* @param alignment The text alignment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ describe('gdjs.TweenRuntimeBehavior', () => {
color: '0;0;0',
text: '',
textAlignment: 'left',
verticalTextAlignment: 'top',
isOutlineEnabled: false,
outlineThickness: 2,
outlineColor: '255;255;255',
Expand Down
1 change: 1 addition & 0 deletions Extensions/TweenBehavior/tests/TweenBehavior.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ describe('gdjs.TweenRuntimeBehavior', () => {
color: '0;0;0',
text: '',
textAlignment: 'left',
verticalTextAlignment: 'top',
isOutlineEnabled: false,
outlineThickness: 2,
outlineColor: '255;255;255',
Expand Down
2 changes: 2 additions & 0 deletions GDevelop.js/Bindings/Bindings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -3492,6 +3492,8 @@ interface TextObject {
[Const, Ref] DOMString GetColor();
void SetTextAlignment([Const] DOMString textAlignment);
[Const, Ref] DOMString GetTextAlignment();
void SetVerticalTextAlignment([Const] DOMString value);
[Const, Ref] DOMString GetVerticalTextAlignment();

void SetOutlineEnabled(boolean enable);
boolean IsOutlineEnabled();
Expand Down
2 changes: 1 addition & 1 deletion GDevelop.js/__tests__/Serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('libGD.js object serialization', function() {
obj.delete();

expect(jsonObject).toBe(
'{"bold":false,"italic":false,"smoothed":true,"underlined":false,"string":"Text of the object, with 官话 characters","font":"","textAlignment":"left","characterSize":20.0,"color":{"b":0,"g":0,"r":0},"content":{"bold":false,"isOutlineEnabled":false,"isShadowEnabled":false,"italic":false,"outlineColor":"255;255;255","outlineThickness":2.0,"shadowAngle":90.0,"shadowBlurRadius":2.0,"shadowColor":"0;0;0","shadowDistance":4.0,"shadowOpacity":127.0,"smoothed":true,"underlined":false,"text":"Text of the object, with 官话 characters","font":"","textAlignment":"left","characterSize":20.0,"color":"0;0;0"}}'
'{"bold":false,"italic":false,"smoothed":true,"underlined":false,"string":"Text of the object, with 官话 characters","font":"","textAlignment":"left","characterSize":20.0,"color":{"b":0,"g":0,"r":0},"content":{"bold":false,"isOutlineEnabled":false,"isShadowEnabled":false,"italic":false,"outlineColor":"255;255;255","outlineThickness":2.0,"shadowAngle":90.0,"shadowBlurRadius":2.0,"shadowColor":"0;0;0","shadowDistance":4.0,"shadowOpacity":127.0,"smoothed":true,"underlined":false,"text":"Text of the object, with 官话 characters","font":"","textAlignment":"left","verticalTextAlignment":"top","characterSize":20.0,"color":"0;0;0"}}'
);
});
});
Expand Down
2 changes: 2 additions & 0 deletions GDevelop.js/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2597,6 +2597,8 @@ export class TextObject extends ObjectConfiguration {
getColor(): string;
setTextAlignment(textAlignment: string): void;
getTextAlignment(): string;
setVerticalTextAlignment(value: string): void;
getVerticalTextAlignment(): string;
setOutlineEnabled(enable: boolean): void;
isOutlineEnabled(): boolean;
setOutlineThickness(value: number): void;
Expand Down
2 changes: 2 additions & 0 deletions GDevelop.js/types/gdtextobject.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ declare class gdTextObject extends gdObjectConfiguration {
getColor(): string;
setTextAlignment(textAlignment: string): void;
getTextAlignment(): string;
setVerticalTextAlignment(value: string): void;
getVerticalTextAlignment(): string;
setOutlineEnabled(enable: boolean): void;
isOutlineEnabled(): boolean;
setOutlineThickness(value: number): void;
Expand Down
70 changes: 66 additions & 4 deletions newIDE/app/src/ObjectEditor/Editors/TextEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import Checkbox from '../../UI/Checkbox';
import { Line, Column } from '../../UI/Grid';
import ColorPicker from '../../UI/ColorField/ColorPicker';
import { MiniToolbarText } from '../../UI/MiniToolbar';
import { ColumnStackLayout, ResponsiveLineStackLayout } from '../../UI/Layout';
import {
ColumnStackLayout,
LineStackLayout,
ResponsiveLineStackLayout,
} from '../../UI/Layout';
import ResourceSelector from '../../ResourcesList/ResourceSelector';
import ResourcesLoader from '../../ResourcesLoader';
import { type EditorProps } from './EditorProps.flow';
Expand All @@ -18,6 +22,9 @@ import Tooltip from '@material-ui/core/Tooltip';
import LeftTextAlignment from '../../UI/CustomSvgIcons/LeftTextAlignment';
import CenterTextAlignment from '../../UI/CustomSvgIcons/CenterTextAlignment';
import RightTextAlignment from '../../UI/CustomSvgIcons/RightTextAlignment';
import TopTextAlignment from '../../UI/CustomSvgIcons/TopTextAlignment';
import CenterVerticalTextAlignment from '../../UI/CustomSvgIcons/CenterVerticalTextAlignment';
import BottomTextAlignment from '../../UI/CustomSvgIcons/BottomTextAlignment';
import Text from '../../UI/Text';
import {
rgbColorToRGBString,
Expand Down Expand Up @@ -55,6 +62,7 @@ export default class TextEditor extends React.Component<EditorProps, void> {
);

const textAlignment = textObjectConfiguration.getTextAlignment();
const verticalTextAlignment = textObjectConfiguration.getVerticalTextAlignment();

return (
<ColumnStackLayout noMargin>
Expand Down Expand Up @@ -94,8 +102,6 @@ export default class TextEditor extends React.Component<EditorProps, void> {
this.forceUpdate();
}}
/>
</Line>
<Line noMargin alignItems="center">
<Checkbox
label={<Trans>Bold</Trans>}
checked={textObjectConfiguration.isBold()}
Expand All @@ -114,6 +120,8 @@ export default class TextEditor extends React.Component<EditorProps, void> {
}}
style={styles.checkbox}
/>
</Line>
<LineStackLayout noMargin alignItems="center">
<ButtonGroup size="small">
<Tooltip title={<Trans>Align text on the left</Trans>}>
<Button
Expand Down Expand Up @@ -154,7 +162,61 @@ export default class TextEditor extends React.Component<EditorProps, void> {
</Button>
</Tooltip>
</ButtonGroup>
</Line>
<ButtonGroup size="small">
<Tooltip title={<Trans>Align text on the top</Trans>}>
<Button
variant={
verticalTextAlignment === 'top' ? 'contained' : 'outlined'
}
color={
verticalTextAlignment === 'top' ? 'secondary' : 'default'
}
onClick={() => {
textObjectConfiguration.setVerticalTextAlignment('top');
this.forceUpdate();
}}
>
<TopTextAlignment />
</Button>
</Tooltip>
<Tooltip title={<Trans>Align text on the center</Trans>}>
<Button
variant={
verticalTextAlignment === 'center'
? 'contained'
: 'outlined'
}
color={
verticalTextAlignment === 'center' ? 'secondary' : 'default'
}
onClick={() => {
textObjectConfiguration.setVerticalTextAlignment('center');
this.forceUpdate();
}}
>
<CenterVerticalTextAlignment />
</Button>
</Tooltip>
<Tooltip title={<Trans>Align text on the bottom</Trans>}>
<Button
variant={
verticalTextAlignment === 'bottom'
? 'contained'
: 'outlined'
}
color={
verticalTextAlignment === 'bottom' ? 'secondary' : 'default'
}
onClick={() => {
textObjectConfiguration.setVerticalTextAlignment('bottom');
this.forceUpdate();
}}
>
<BottomTextAlignment />
</Button>
</Tooltip>
</ButtonGroup>
</LineStackLayout>
</ResponsiveLineStackLayout>
<ResourceSelector
project={project}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default class RenderedTextInstance extends RenderedInstance {
_fontFamily: string = '';
_color: string = '0;0;0';
_textAlignment: string = 'left';
_verticalTextAlignment: string = 'top';

_isOutlineEnabled = false;
_outlineColor = '255;255;255';
Expand Down Expand Up @@ -91,6 +92,8 @@ export default class RenderedTextInstance extends RenderedInstance {
textObjectConfiguration.isBold() !== this._isBold ||
textObjectConfiguration.getCharacterSize() !== this._characterSize ||
textObjectConfiguration.getTextAlignment() !== this._textAlignment ||
textObjectConfiguration.getVerticalTextAlignment() !==
this._verticalTextAlignment ||
textObjectConfiguration.getColor() !== this._color ||
textObjectConfiguration.isOutlineEnabled() !== this._isOutlineEnabled ||
textObjectConfiguration.getOutlineColor() !== this._outlineColor ||
Expand All @@ -110,6 +113,7 @@ export default class RenderedTextInstance extends RenderedInstance {
this._isBold = textObjectConfiguration.isBold();
this._characterSize = textObjectConfiguration.getCharacterSize();
this._textAlignment = textObjectConfiguration.getTextAlignment();
this._verticalTextAlignment = textObjectConfiguration.getVerticalTextAlignment();
this._color = textObjectConfiguration.getColor();

this._isOutlineEnabled = textObjectConfiguration.isOutlineEnabled();
Expand Down Expand Up @@ -204,8 +208,16 @@ export default class RenderedTextInstance extends RenderedInstance {
this._instance.getX() + this._pixiObject.width / 2;
this._pixiObject.anchor.x = 0.5;
}
const alignmentY =
this._verticalTextAlignment === 'bottom'
? 1
: this._verticalTextAlignment === 'center'
? 0.5
: 0;
this._pixiObject.position.y =
this._instance.getY() + this._pixiObject.height / 2;
this._instance.getY() + this._pixiObject.height * (0.5 - alignmentY);
this._pixiObject.anchor.y = 0.5;

this._pixiObject.rotation = RenderedInstance.toRad(
this._instance.getAngle()
);
Expand All @@ -222,4 +234,13 @@ export default class RenderedTextInstance extends RenderedInstance {
getDefaultHeight() {
return this._pixiObject.height;
}

getOriginY(): number {
const height = this.getHeight();
return this._verticalTextAlignment === 'bottom'
? height
: this._verticalTextAlignment === 'center'
? height / 2
: 0;
}
}
19 changes: 19 additions & 0 deletions newIDE/app/src/UI/CustomSvgIcons/BottomTextAlignment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import SvgIcon from '@material-ui/core/SvgIcon';

export default React.memo(props => (
<SvgIcon {...props} width="24" height="24" viewBox="0 0 24 24" fill="none">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M14.2303 11.7197C14.5232 12.0126 14.5232 12.4874 14.2303 12.7803L12.4803 14.5303C12.1874 14.8232 11.7126 14.8232 11.4197 14.5303L9.66967 12.7803C9.37677 12.4874 9.37677 12.0126 9.66967 11.7197C9.96256 11.4268 10.4374 11.4268 10.7303 11.7197L11.2 12.1893L11.2 6C11.2 5.58579 11.5358 5.25 11.95 5.25C12.3642 5.25 12.7 5.58579 12.7 6L12.7 12.1893L13.1697 11.7197C13.4626 11.4268 13.9374 11.4268 14.2303 11.7197Z"
fill="currentColor"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M3.25 18C3.25 17.5858 3.58579 17.25 4 17.25H20C20.4142 17.25 20.75 17.5858 20.75 18C20.75 18.4142 20.4142 18.75 20 18.75H4C3.58579 18.75 3.25 18.4142 3.25 18Z"
fill="currentColor"
/>
</SvgIcon>
));
Loading
Loading