aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp630
1 files changed, 630 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp
new file mode 100644
index 0000000..ea934d3
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CGUIStaticText.cpp
@@ -0,0 +1,630 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CGUIStaticText.h"
6#ifdef _IRR_COMPILE_WITH_GUI_
7
8#include "IGUISkin.h"
9#include "IGUIEnvironment.h"
10#include "IGUIFont.h"
11#include "IVideoDriver.h"
12#include "rect.h"
13
14namespace irr
15{
16namespace gui
17{
18
19//! constructor
20CGUIStaticText::CGUIStaticText(const wchar_t* text, bool border,
21 IGUIEnvironment* environment, IGUIElement* parent,
22 s32 id, const core::rect<s32>& rectangle,
23 bool background)
24: IGUIStaticText(environment, parent, id, rectangle),
25 HAlign(EGUIA_UPPERLEFT), VAlign(EGUIA_UPPERLEFT),
26 Border(border), OverrideColorEnabled(false), OverrideBGColorEnabled(false), WordWrap(false), Background(background),
27 RestrainTextInside(true), RightToLeft(false),
28 OverrideColor(video::SColor(101,255,255,255)), BGColor(video::SColor(101,210,210,210)),
29 OverrideFont(0), LastBreakFont(0)
30{
31 #ifdef _DEBUG
32 setDebugName("CGUIStaticText");
33 #endif
34
35 Text = text;
36 if (environment && environment->getSkin())
37 {
38 BGColor = environment->getSkin()->getColor(gui::EGDC_3D_FACE);
39 }
40}
41
42
43//! destructor
44CGUIStaticText::~CGUIStaticText()
45{
46 if (OverrideFont)
47 OverrideFont->drop();
48}
49
50
51//! draws the element and its children
52void CGUIStaticText::draw()
53{
54 if (!IsVisible)
55 return;
56
57 IGUISkin* skin = Environment->getSkin();
58 if (!skin)
59 return;
60 video::IVideoDriver* driver = Environment->getVideoDriver();
61
62 core::rect<s32> frameRect(AbsoluteRect);
63
64 // draw background
65
66 if (Background)
67 {
68 if ( !OverrideBGColorEnabled ) // skin-colors can change
69 BGColor = skin->getColor(gui::EGDC_3D_FACE);
70
71 driver->draw2DRectangle(BGColor, frameRect, &AbsoluteClippingRect);
72 }
73
74 // draw the border
75
76 if (Border)
77 {
78 skin->draw3DSunkenPane(this, 0, true, false, frameRect, &AbsoluteClippingRect);
79 frameRect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X);
80 }
81
82 // draw the text
83 if (Text.size())
84 {
85 IGUIFont* font = getActiveFont();
86
87 if (font)
88 {
89 if (!WordWrap)
90 {
91 if (VAlign == EGUIA_LOWERRIGHT)
92 {
93 frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y -
94 font->getDimension(L"A").Height - font->getKerningHeight();
95 }
96 if (HAlign == EGUIA_LOWERRIGHT)
97 {
98 frameRect.UpperLeftCorner.X = frameRect.LowerRightCorner.X -
99 font->getDimension(Text.c_str()).Width;
100 }
101
102 font->draw(Text.c_str(), frameRect,
103 OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT),
104 HAlign == EGUIA_CENTER, VAlign == EGUIA_CENTER, (RestrainTextInside ? &AbsoluteClippingRect : NULL));
105 }
106 else
107 {
108 if (font != LastBreakFont)
109 breakText();
110
111 core::rect<s32> r = frameRect;
112 s32 height = font->getDimension(L"A").Height + font->getKerningHeight();
113 s32 totalHeight = height * BrokenText.size();
114 if (VAlign == EGUIA_CENTER)
115 {
116 r.UpperLeftCorner.Y = r.getCenter().Y - (totalHeight / 2);
117 }
118 else if (VAlign == EGUIA_LOWERRIGHT)
119 {
120 r.UpperLeftCorner.Y = r.LowerRightCorner.Y - totalHeight;
121 }
122
123 for (u32 i=0; i<BrokenText.size(); ++i)
124 {
125 if (HAlign == EGUIA_LOWERRIGHT)
126 {
127 r.UpperLeftCorner.X = frameRect.LowerRightCorner.X -
128 font->getDimension(BrokenText[i].c_str()).Width;
129 }
130
131 font->draw(BrokenText[i].c_str(), r,
132 OverrideColorEnabled ? OverrideColor : skin->getColor(isEnabled() ? EGDC_BUTTON_TEXT : EGDC_GRAY_TEXT),
133 HAlign == EGUIA_CENTER, false, (RestrainTextInside ? &AbsoluteClippingRect : NULL));
134
135 r.LowerRightCorner.Y += height;
136 r.UpperLeftCorner.Y += height;
137 }
138 }
139 }
140 }
141
142 IGUIElement::draw();
143}
144
145
146//! Sets another skin independent font.
147void CGUIStaticText::setOverrideFont(IGUIFont* font)
148{
149 if (OverrideFont == font)
150 return;
151
152 if (OverrideFont)
153 OverrideFont->drop();
154
155 OverrideFont = font;
156
157 if (OverrideFont)
158 OverrideFont->grab();
159
160 breakText();
161}
162
163//! Gets the override font (if any)
164IGUIFont * CGUIStaticText::getOverrideFont() const
165{
166 return OverrideFont;
167}
168
169//! Get the font which is used right now for drawing
170IGUIFont* CGUIStaticText::getActiveFont() const
171{
172 if ( OverrideFont )
173 return OverrideFont;
174 IGUISkin* skin = Environment->getSkin();
175 if (skin)
176 return skin->getFont();
177 return 0;
178}
179
180//! Sets another color for the text.
181void CGUIStaticText::setOverrideColor(video::SColor color)
182{
183 OverrideColor = color;
184 OverrideColorEnabled = true;
185}
186
187
188//! Sets another color for the text.
189void CGUIStaticText::setBackgroundColor(video::SColor color)
190{
191 BGColor = color;
192 OverrideBGColorEnabled = true;
193 Background = true;
194}
195
196
197//! Sets whether to draw the background
198void CGUIStaticText::setDrawBackground(bool draw)
199{
200 Background = draw;
201}
202
203
204//! Gets the background color
205video::SColor CGUIStaticText::getBackgroundColor() const
206{
207 return BGColor;
208}
209
210
211//! Checks if background drawing is enabled
212bool CGUIStaticText::isDrawBackgroundEnabled() const
213{
214 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
215 return Background;
216}
217
218
219//! Sets whether to draw the border
220void CGUIStaticText::setDrawBorder(bool draw)
221{
222 Border = draw;
223}
224
225
226//! Checks if border drawing is enabled
227bool CGUIStaticText::isDrawBorderEnabled() const
228{
229 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
230 return Border;
231}
232
233
234void CGUIStaticText::setTextRestrainedInside(bool restrainTextInside)
235{
236 RestrainTextInside = restrainTextInside;
237}
238
239
240bool CGUIStaticText::isTextRestrainedInside() const
241{
242 return RestrainTextInside;
243}
244
245
246void CGUIStaticText::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical)
247{
248 HAlign = horizontal;
249 VAlign = vertical;
250}
251
252
253video::SColor CGUIStaticText::getOverrideColor() const
254{
255 return OverrideColor;
256}
257
258
259//! Sets if the static text should use the overide color or the
260//! color in the gui skin.
261void CGUIStaticText::enableOverrideColor(bool enable)
262{
263 OverrideColorEnabled = enable;
264}
265
266
267bool CGUIStaticText::isOverrideColorEnabled() const
268{
269 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
270 return OverrideColorEnabled;
271}
272
273
274//! Enables or disables word wrap for using the static text as
275//! multiline text control.
276void CGUIStaticText::setWordWrap(bool enable)
277{
278 WordWrap = enable;
279 breakText();
280}
281
282
283bool CGUIStaticText::isWordWrapEnabled() const
284{
285 _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
286 return WordWrap;
287}
288
289
290void CGUIStaticText::setRightToLeft(bool rtl)
291{
292 if (RightToLeft != rtl)
293 {
294 RightToLeft = rtl;
295 breakText();
296 }
297}
298
299
300bool CGUIStaticText::isRightToLeft() const
301{
302 return RightToLeft;
303}
304
305
306//! Breaks the single text line.
307void CGUIStaticText::breakText()
308{
309 if (!WordWrap)
310 return;
311
312 BrokenText.clear();
313
314 IGUISkin* skin = Environment->getSkin();
315 IGUIFont* font = getActiveFont();
316 if (!font)
317 return;
318
319 LastBreakFont = font;
320
321 core::stringw line;
322 core::stringw word;
323 core::stringw whitespace;
324 s32 size = Text.size();
325 s32 length = 0;
326 s32 elWidth = RelativeRect.getWidth();
327 if (Border)
328 elWidth -= 2*skin->getSize(EGDS_TEXT_DISTANCE_X);
329 wchar_t c;
330
331 // We have to deal with right-to-left and left-to-right differently
332 // However, most parts of the following code is the same, it's just
333 // some order and boundaries which change.
334 if (!RightToLeft)
335 {
336 // regular (left-to-right)
337 for (s32 i=0; i<size; ++i)
338 {
339 c = Text[i];
340 bool lineBreak = false;
341
342 if (c == L'\r') // Mac or Windows breaks
343 {
344 lineBreak = true;
345 if (Text[i+1] == L'\n') // Windows breaks
346 {
347 Text.erase(i+1);
348 --size;
349 }
350 c = '\0';
351 }
352 else if (c == L'\n') // Unix breaks
353 {
354 lineBreak = true;
355 c = '\0';
356 }
357
358 bool isWhitespace = (c == L' ' || c == 0);
359 if ( !isWhitespace )
360 {
361 // part of a word
362 word += c;
363 }
364
365 if ( isWhitespace || i == (size-1))
366 {
367 if (word.size())
368 {
369 // here comes the next whitespace, look if
370 // we must break the last word to the next line.
371 const s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
372 const s32 wordlgth = font->getDimension(word.c_str()).Width;
373
374 if (wordlgth > elWidth)
375 {
376 // This word is too long to fit in the available space, look for
377 // the Unicode Soft HYphen (SHY / 00AD) character for a place to
378 // break the word at
379 int where = word.findFirst( wchar_t(0x00AD) );
380 if (where != -1)
381 {
382 core::stringw first = word.subString(0, where);
383 core::stringw second = word.subString(where, word.size() - where);
384 BrokenText.push_back(line + first + L"-");
385 const s32 secondLength = font->getDimension(second.c_str()).Width;
386
387 length = secondLength;
388 line = second;
389 }
390 else
391 {
392 // No soft hyphen found, so there's nothing more we can do
393 // break to next line
394 if (length)
395 BrokenText.push_back(line);
396 length = wordlgth;
397 line = word;
398 }
399 }
400 else if (length && (length + wordlgth + whitelgth > elWidth))
401 {
402 // break to next line
403 BrokenText.push_back(line);
404 length = wordlgth;
405 line = word;
406 }
407 else
408 {
409 // add word to line
410 line += whitespace;
411 line += word;
412 length += whitelgth + wordlgth;
413 }
414
415 word = L"";
416 whitespace = L"";
417 }
418
419 if ( isWhitespace )
420 {
421 whitespace += c;
422 }
423
424 // compute line break
425 if (lineBreak)
426 {
427 line += whitespace;
428 line += word;
429 BrokenText.push_back(line);
430 line = L"";
431 word = L"";
432 whitespace = L"";
433 length = 0;
434 }
435 }
436 }
437
438 line += whitespace;
439 line += word;
440 BrokenText.push_back(line);
441 }
442 else
443 {
444 // right-to-left
445 for (s32 i=size; i>=0; --i)
446 {
447 c = Text[i];
448 bool lineBreak = false;
449
450 if (c == L'\r') // Mac or Windows breaks
451 {
452 lineBreak = true;
453 if ((i>0) && Text[i-1] == L'\n') // Windows breaks
454 {
455 Text.erase(i-1);
456 --size;
457 }
458 c = '\0';
459 }
460 else if (c == L'\n') // Unix breaks
461 {
462 lineBreak = true;
463 c = '\0';
464 }
465
466 if (c==L' ' || c==0 || i==0)
467 {
468 if (word.size())
469 {
470 // here comes the next whitespace, look if
471 // we must break the last word to the next line.
472 const s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
473 const s32 wordlgth = font->getDimension(word.c_str()).Width;
474
475 if (length && (length + wordlgth + whitelgth > elWidth))
476 {
477 // break to next line
478 BrokenText.push_back(line);
479 length = wordlgth;
480 line = word;
481 }
482 else
483 {
484 // add word to line
485 line = whitespace + line;
486 line = word + line;
487 length += whitelgth + wordlgth;
488 }
489
490 word = L"";
491 whitespace = L"";
492 }
493
494 if (c != 0)
495 whitespace = core::stringw(&c, 1) + whitespace;
496
497 // compute line break
498 if (lineBreak)
499 {
500 line = whitespace + line;
501 line = word + line;
502 BrokenText.push_back(line);
503 line = L"";
504 word = L"";
505 whitespace = L"";
506 length = 0;
507 }
508 }
509 else
510 {
511 // yippee this is a word..
512 word = core::stringw(&c, 1) + word;
513 }
514 }
515
516 line = whitespace + line;
517 line = word + line;
518 BrokenText.push_back(line);
519 }
520}
521
522
523//! Sets the new caption of this element.
524void CGUIStaticText::setText(const wchar_t* text)
525{
526 IGUIElement::setText(text);
527 breakText();
528}
529
530
531void CGUIStaticText::updateAbsolutePosition()
532{
533 IGUIElement::updateAbsolutePosition();
534 breakText();
535}
536
537
538//! Returns the height of the text in pixels when it is drawn.
539s32 CGUIStaticText::getTextHeight() const
540{
541 IGUIFont* font = getActiveFont();
542 if (!font)
543 return 0;
544
545 s32 height = font->getDimension(L"A").Height + font->getKerningHeight();
546
547 if (WordWrap)
548 height *= BrokenText.size();
549
550 return height;
551}
552
553
554s32 CGUIStaticText::getTextWidth() const
555{
556 IGUIFont * font = getActiveFont();
557 if(!font)
558 return 0;
559
560 if(WordWrap)
561 {
562 s32 widest = 0;
563
564 for(u32 line = 0; line < BrokenText.size(); ++line)
565 {
566 s32 width = font->getDimension(BrokenText[line].c_str()).Width;
567
568 if(width > widest)
569 widest = width;
570 }
571
572 return widest;
573 }
574 else
575 {
576 return font->getDimension(Text.c_str()).Width;
577 }
578}
579
580
581//! Writes attributes of the element.
582//! Implement this to expose the attributes of your element for
583//! scripting languages, editors, debuggers or xml serialization purposes.
584void CGUIStaticText::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
585{
586 IGUIStaticText::serializeAttributes(out,options);
587
588 out->addBool ("Border", Border);
589 out->addBool ("OverrideColorEnabled",OverrideColorEnabled);
590 out->addBool ("OverrideBGColorEnabled",OverrideBGColorEnabled);
591 out->addBool ("WordWrap", WordWrap);
592 out->addBool ("Background", Background);
593 out->addBool ("RightToLeft", RightToLeft);
594 out->addBool ("RestrainTextInside", RestrainTextInside);
595 out->addColor ("OverrideColor", OverrideColor);
596 out->addColor ("BGColor", BGColor);
597 out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames);
598 out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames);
599
600 // out->addFont ("OverrideFont", OverrideFont);
601}
602
603
604//! Reads attributes of the element
605void CGUIStaticText::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
606{
607 IGUIStaticText::deserializeAttributes(in,options);
608
609 Border = in->getAttributeAsBool("Border");
610 enableOverrideColor(in->getAttributeAsBool("OverrideColorEnabled"));
611 OverrideBGColorEnabled = in->getAttributeAsBool("OverrideBGColorEnabled");
612 setWordWrap(in->getAttributeAsBool("WordWrap"));
613 Background = in->getAttributeAsBool("Background");
614 RightToLeft = in->getAttributeAsBool("RightToLeft");
615 RestrainTextInside = in->getAttributeAsBool("RestrainTextInside");
616 OverrideColor = in->getAttributeAsColor("OverrideColor");
617 BGColor = in->getAttributeAsColor("BGColor");
618
619 setTextAlignment( (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("HTextAlign", GUIAlignmentNames),
620 (EGUI_ALIGNMENT) in->getAttributeAsEnumeration("VTextAlign", GUIAlignmentNames));
621
622 // OverrideFont = in->getAttributeAsFont("OverrideFont");
623}
624
625
626} // end namespace gui
627} // end namespace irr
628
629#endif // _IRR_COMPILE_WITH_GUI_
630