1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #include "GUI/BsGUILabel.h" |
4 | #include "GUI/BsGUIElementStyle.h" |
5 | #include "2D/BsTextSprite.h" |
6 | #include "Image/BsSpriteTexture.h" |
7 | #include "GUI/BsGUIDimensions.h" |
8 | #include "GUI/BsGUIHelper.h" |
9 | |
10 | namespace bs |
11 | { |
12 | GUILabel::GUILabel(const String& styleName, const GUIContent& content, const GUIDimensions& dimensions) |
13 | :GUIElement(styleName, dimensions), mContent(content), mImageSprite(nullptr) |
14 | { |
15 | mTextSprite = bs_new<TextSprite>(); |
16 | } |
17 | |
18 | GUILabel::~GUILabel() |
19 | { |
20 | bs_delete(mTextSprite); |
21 | |
22 | if (mImageSprite != nullptr) |
23 | bs_delete(mImageSprite); |
24 | } |
25 | |
26 | UINT32 GUILabel::_getNumRenderElements() const |
27 | { |
28 | UINT32 numElements = mTextSprite->getNumRenderElements(); |
29 | |
30 | if(mImageSprite != nullptr) |
31 | numElements += mImageSprite->getNumRenderElements(); |
32 | |
33 | return numElements; |
34 | } |
35 | |
36 | const SpriteMaterialInfo& GUILabel::_getMaterial(UINT32 renderElementIdx, SpriteMaterial** material) const |
37 | { |
38 | UINT32 imageSpriteIdx = mTextSprite->getNumRenderElements(); |
39 | |
40 | if(renderElementIdx >= imageSpriteIdx) |
41 | { |
42 | *material = mImageSprite->getMaterial(imageSpriteIdx - renderElementIdx); |
43 | return mImageSprite->getMaterialInfo(imageSpriteIdx - renderElementIdx); |
44 | } |
45 | else |
46 | { |
47 | *material = mTextSprite->getMaterial(renderElementIdx); |
48 | return mTextSprite->getMaterialInfo(renderElementIdx); |
49 | } |
50 | } |
51 | |
52 | void GUILabel::_getMeshInfo(UINT32 renderElementIdx, UINT32& numVertices, UINT32& numIndices, GUIMeshType& type) const |
53 | { |
54 | UINT32 imageSpriteIdx = mTextSprite->getNumRenderElements(); |
55 | |
56 | UINT32 numQuads; |
57 | if (renderElementIdx >= imageSpriteIdx) |
58 | numQuads = mImageSprite->getNumQuads(imageSpriteIdx - renderElementIdx); |
59 | else |
60 | numQuads = mTextSprite->getNumQuads(renderElementIdx); |
61 | |
62 | numVertices = numQuads * 4; |
63 | numIndices = numQuads * 6; |
64 | type = GUIMeshType::Triangle; |
65 | } |
66 | |
67 | UINT32 GUILabel::_getRenderElementDepth(UINT32 renderElementIdx) const |
68 | { |
69 | UINT32 imageSpriteIdx = mTextSprite->getNumRenderElements(); |
70 | |
71 | if (renderElementIdx >= imageSpriteIdx) |
72 | return _getDepth() + 1; |
73 | else |
74 | return _getDepth(); |
75 | } |
76 | |
77 | UINT32 GUILabel::_getRenderElementDepthRange() const |
78 | { |
79 | return 2; |
80 | } |
81 | |
82 | void GUILabel::updateRenderElementsInternal() |
83 | { |
84 | const HSpriteTexture& activeTex = _getStyle()->normal.texture; |
85 | if (SpriteTexture::checkIsLoaded(activeTex)) |
86 | { |
87 | mImageDesc.texture = activeTex; |
88 | |
89 | if (mImageSprite == nullptr) |
90 | mImageSprite = bs_new<ImageSprite>(); |
91 | } |
92 | else |
93 | { |
94 | mImageDesc.texture = nullptr; |
95 | |
96 | if (mImageSprite != nullptr) |
97 | { |
98 | bs_delete(mImageSprite); |
99 | mImageSprite = nullptr; |
100 | } |
101 | } |
102 | |
103 | if (mImageSprite != nullptr) |
104 | { |
105 | mImageDesc.width = mLayoutData.area.width; |
106 | mImageDesc.height = mLayoutData.area.height; |
107 | |
108 | mImageDesc.borderLeft = _getStyle()->border.left; |
109 | mImageDesc.borderRight = _getStyle()->border.right; |
110 | mImageDesc.borderTop = _getStyle()->border.top; |
111 | mImageDesc.borderBottom = _getStyle()->border.bottom; |
112 | mImageDesc.color = getTint(); |
113 | |
114 | mImageSprite->update(mImageDesc, (UINT64)_getParentWidget()); |
115 | } |
116 | |
117 | mDesc.font = _getStyle()->font; |
118 | mDesc.fontSize = _getStyle()->fontSize; |
119 | mDesc.wordWrap = _getStyle()->wordWrap; |
120 | mDesc.horzAlign = _getStyle()->textHorzAlign; |
121 | mDesc.vertAlign = _getStyle()->textVertAlign; |
122 | mDesc.width = mLayoutData.area.width; |
123 | mDesc.height = mLayoutData.area.height; |
124 | mDesc.text = mContent.text; |
125 | mDesc.color = getTint() * _getStyle()->normal.textColor;; |
126 | |
127 | mTextSprite->update(mDesc, (UINT64)_getParentWidget()); |
128 | |
129 | GUIElement::updateRenderElementsInternal(); |
130 | } |
131 | |
132 | Vector2I GUILabel::_getOptimalSize() const |
133 | { |
134 | return GUIHelper::calcOptimalContentsSize(mContent, *_getStyle(), _getDimensions()); |
135 | } |
136 | |
137 | void GUILabel::_fillBuffer(UINT8* vertices, UINT32* indices, UINT32 vertexOffset, UINT32 indexOffset, |
138 | UINT32 maxNumVerts, UINT32 maxNumIndices, UINT32 renderElementIdx) const |
139 | { |
140 | UINT8* uvs = vertices + sizeof(Vector2); |
141 | UINT32 vertexStride = sizeof(Vector2) * 2; |
142 | UINT32 indexStride = sizeof(UINT32); |
143 | Vector2I offset(mLayoutData.area.x, mLayoutData.area.y); |
144 | |
145 | UINT32 imageSpriteIdx = mTextSprite->getNumRenderElements(); |
146 | |
147 | if (renderElementIdx < imageSpriteIdx) |
148 | { |
149 | mTextSprite->fillBuffer(vertices, uvs, indices, vertexOffset, indexOffset, maxNumVerts, maxNumIndices, vertexStride, |
150 | indexStride, renderElementIdx, offset, mLayoutData.getLocalClipRect()); |
151 | |
152 | return; |
153 | } |
154 | |
155 | mImageSprite->fillBuffer(vertices, uvs, indices, vertexOffset, indexOffset, maxNumVerts, maxNumIndices, |
156 | vertexStride, indexStride, imageSpriteIdx - renderElementIdx, offset, mLayoutData.getLocalClipRect()); |
157 | } |
158 | |
159 | void GUILabel::setContent(const GUIContent& content) |
160 | { |
161 | Vector2I origSize = mDimensions.calculateSizeRange(_getOptimalSize()).optimal; |
162 | mContent = content; |
163 | Vector2I newSize = mDimensions.calculateSizeRange(_getOptimalSize()).optimal; |
164 | |
165 | if (origSize != newSize) |
166 | _markLayoutAsDirty(); |
167 | else |
168 | _markContentAsDirty(); |
169 | } |
170 | |
171 | GUILabel* GUILabel::create(const HString& text, const String& styleName) |
172 | { |
173 | return create(GUIContent(text), styleName); |
174 | } |
175 | |
176 | GUILabel* GUILabel::create(const HString& text, const GUIOptions& options, const String& styleName) |
177 | { |
178 | return create(GUIContent(text), options, styleName); |
179 | } |
180 | |
181 | GUILabel* GUILabel::create(const GUIContent& content, const String& styleName) |
182 | { |
183 | return new (bs_alloc<GUILabel>()) GUILabel(getStyleName<GUILabel>(styleName), content, GUIDimensions::create()); |
184 | } |
185 | |
186 | GUILabel* GUILabel::create(const GUIContent& content, const GUIOptions& options, const String& styleName) |
187 | { |
188 | return new (bs_alloc<GUILabel>()) GUILabel(getStyleName<GUILabel>(styleName), content, GUIDimensions::create(options)); |
189 | } |
190 | |
191 | const String& GUILabel::getGUITypeName() |
192 | { |
193 | static String typeName = "Label" ; |
194 | return typeName; |
195 | } |
196 | } |