-
-
Notifications
You must be signed in to change notification settings - Fork 68
/
Label.hx
195 lines (168 loc) · 7.19 KB
/
Label.hx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package haxe.ui.components;
import haxe.ui.behaviours.DataBehaviour;
import haxe.ui.core.Component;
import haxe.ui.core.CompositeBuilder;
import haxe.ui.events.UIEvent;
import haxe.ui.geom.Size;
import haxe.ui.layouts.DefaultLayout;
import haxe.ui.styles.Style;
/**
* A way to display static (uneditable) text.
*/
@:composite(Builder, LabelLayout)
class Label extends Component {
//***********************************************************************************************************
// Styles
//***********************************************************************************************************
/**
* The alignment of the text inside the label. can be one of:
*
* - "left"
* - "right"
* - "center"
* - "justify"
*/
@:style(layout) public var textAlign:Null<String>;
/**
* Whether or not the label should automatically transfer text for which
* there isn't enough space from the end of the current line of text to the beginning of the next.
*/
@:style(layout) public var wordWrap:Null<Bool>;
//***********************************************************************************************************
// Public API
//***********************************************************************************************************
/**
* The actual text displayed inside the label.
*/
@:clonable @:behaviour(TextBehaviour) public var text:String;
/**
* A string containing HTML markup to be displayed inside the label.
*/
@:clonable @:behaviour(HtmlTextBehaviour) public var htmlText:String;
/**
* The text displayed inside the label.
*
* `value` is used as a universal way to access the "core" value a component is based on.
* in this case, its the text inside of the label.
*/
@:clonable @:value(text) public var value:Dynamic;
/**
* Wheter the label text can be selected by the user or not
*/
@:clonable @:behaviour(SelectableBehaviour) public var selectable:Bool;
@:style public var fontSize:Null<Float>;
}
//***********************************************************************************************************
// Composite Layout
//***********************************************************************************************************
@:dox(hide) @:noCompletion
private class LabelLayout extends DefaultLayout {
private override function resizeChildren() {
if (component.autoWidth == false) {
component.getTextDisplay().width = component.componentWidth - paddingLeft - paddingRight;
var wordWrap = true;
if (_component.style != null && _component.style.wordWrap != null) {
wordWrap = _component.style.wordWrap;
}
// TODO: make not specific - need to check all backends first - update: can move to backends!
#if (haxeui_flixel)
component.getTextDisplay().wordWrap = wordWrap;
component.getTextDisplay().tf.autoSize = false;
#elseif (haxeui_openfl)
component.getTextDisplay().textField.autoSize = openfl.text.TextFieldAutoSize.NONE;
component.getTextDisplay().multiline = wordWrap;
component.getTextDisplay().wordWrap = wordWrap;
#elseif (haxeui_pixijs)
component.getTextDisplay().textField.style.wordWrapWidth = component.getTextDisplay().width;
component.getTextDisplay().wordWrap = wordWrap;
#else
component.getTextDisplay().wordWrap = wordWrap;
#end
} else {
component.getTextDisplay().width = component.getTextDisplay().textWidth;
}
if (component.autoHeight == true) {
component.getTextDisplay().height = component.getTextDisplay().textHeight;
} else {
component.getTextDisplay().height = component.height;
}
}
private override function repositionChildren() {
if (component.hasTextDisplay() == true) {
component.getTextDisplay().left = paddingLeft;
component.getTextDisplay().top = paddingTop;
}
}
public override function calcAutoSize(exclusions:Array<Component> = null):Size {
var size:Size = super.calcAutoSize(exclusions);
if (component.hasTextDisplay() == true) {
size.width += component.getTextDisplay().textWidth;
size.height += component.getTextDisplay().textHeight;
}
return size;
}
private function textAlign(child:Component):String {
if (child == null || child.style == null || child.style.textAlign == null) {
return "left";
}
return child.style.textAlign;
}
}
//***********************************************************************************************************
// Behaviours
//***********************************************************************************************************
@:dox(hide) @:noCompletion
private class TextBehaviour extends DataBehaviour {
public override function validateData() {
if (_component.getTextDisplay().textStyle != _component.style) {
_component.invalidateComponentStyle(true);
}
_component.getTextDisplay().text = '${_value}';
_component.dispatch(new UIEvent(UIEvent.CHANGE));
}
}
@:dox(hide) @:noCompletion
private class HtmlTextBehaviour extends DataBehaviour {
public override function validateData() {
if (_component.getTextDisplay().textStyle != _component.style) {
_component.invalidateComponentStyle(true);
}
_component.getTextDisplay().htmlText = '${_value}';
_component.dispatch(new UIEvent(UIEvent.CHANGE));
}
}
@:dox(hide) @:noCompletion
private class SelectableBehaviour extends DataBehaviour {
public override function validateData() {
_component.getTextDisplay().selectable = _value;
}
}
//***********************************************************************************************************
// Composite Builder
//***********************************************************************************************************
@:dox(hide) @:noCompletion
private class Builder extends CompositeBuilder {
private var _label:Label;
public function new(label:Label) {
super(label);
_label = label;
}
public override function applyStyle(style:Style) {
if (_label.hasTextDisplay() == true) {
_label.getTextDisplay().textStyle = style;
if ((style.contentType == "auto" || style.contentType == "html") && _label.getTextDisplay().supportsHtml && isHtml(Std.string(_component.text))) {
_label.htmlText = _label.text;
}
}
}
public static inline function isHtml(v:String):Bool {
return v == null ? false : v.indexOf("<font ") != -1;
}
public override function get_isComponentClipped():Bool {
var componentClipRect = _component.componentClipRect;
if (componentClipRect == null) {
return false;
}
return _label.getTextDisplay().measureTextWidth() > componentClipRect.width;
}
}