1 /*! 2 @file 3 @author Albert Semenov 4 @date 03/2011 5 */ 6 7 #include "MyGUI_Precompiled.h" 8 #include <MyGUI_ResourceImageSet.h> 9 #include <MyGUI_ImageBox.h> 10 #include <MyGUI_TextBox.h> 11 #include <MyGUI_WidgetManager.h> 12 #include <MyGUI_FontManager.h> 13 #include <MyGUI_IFont.h> 14 #include "HyperTextBox.h" 15 16 namespace MyGUI 17 { 18 HyperTextBox()19 HyperTextBox::HyperTextBox() : 20 mBold(false), 21 mItalic(false), 22 mStrike(false), 23 mUnder(false), 24 mImage(false), 25 mHeader1(false), 26 mHeader2(false), 27 mHeader3(false), 28 mColour(false), 29 mUrl(false), 30 mStackPanel(nullptr), 31 mScrollViewPanel(nullptr), 32 mTextSkin("TextBox"), 33 mImageSkin("ImageBox"), 34 mParagraphSkin("Default"), 35 mLineSkin("WhiteSkin"), 36 mLinkPoiner("link"), 37 mHeader1Font("Default"), 38 mHeader2Font("Default"), 39 mHeader3Font("Default"), 40 mDefaultFont("Default"), 41 mBoldFont("Default"), 42 mItalicFont("Default"), 43 mBoldItalicFont("Default"), 44 mCurrentWrapPanel(nullptr), 45 mBreakHeight(0) 46 { 47 } 48 initialiseOverride()49 void HyperTextBox::initialiseOverride() 50 { 51 Base::initialiseOverride(); 52 53 assignWidget(mScrollViewPanel, "ScrollViewPanel"); 54 assignWidget(mStackPanel, "StackPanel"); 55 56 if (isUserString("TextSkin")) 57 mTextSkin = getUserString("TextSkin"); 58 if (isUserString("ImageSkin")) 59 mImageSkin = getUserString("ImageSkin"); 60 if (isUserString("ParagraphSkin")) 61 mParagraphSkin = getUserString("ParagraphSkin"); 62 if (isUserString("LineSkin")) 63 mLineSkin = getUserString("LineSkin"); 64 if (isUserString("LinkPointer")) 65 mLinkPoiner = getUserString("LinkPointer"); 66 67 updateBreakHeight(); 68 } 69 shutdownOverride()70 void HyperTextBox::shutdownOverride() 71 { 72 Base::shutdownOverride(); 73 } 74 addItem(const std::string & _value)75 void HyperTextBox::addItem(const std::string& _value) 76 { 77 parseParagraph(mStackPanel, _value); 78 mCurrentWrapPanel = nullptr; 79 } 80 parseParagraph(Widget * _parent,const std::string & _value)81 void HyperTextBox::parseParagraph(Widget* _parent, const std::string& _value) 82 { 83 std::string::const_iterator textItem = _value.end(); 84 for (std::string::const_iterator item = _value.begin(); item != _value.end(); ++ item) 85 { 86 if ((*item) == '<') 87 { 88 // отрезаем текст 89 if (textItem < item) 90 { 91 if (mCurrentWrapPanel != nullptr) 92 parseText(mCurrentWrapPanel, _value.substr(textItem - _value.begin(), item - textItem)); 93 } 94 95 // ищем конец тега 96 for (std::string::const_iterator tagItem = item; tagItem != _value.end(); ++ tagItem) 97 { 98 if ((*tagItem) == '>') 99 { 100 parseTag(_value.substr(item - _value.begin(), tagItem - item + 1)); 101 102 item = tagItem; 103 textItem = tagItem + 1; 104 break; 105 } 106 } 107 } 108 } 109 } 110 parseText(Widget * _parent,const std::string & _value)111 void HyperTextBox::parseText(Widget* _parent, const std::string& _value) 112 { 113 const int defaultSize = 16; 114 115 if (mImage) 116 { 117 if (mImageSize.width == 0 || mImageSize.height == 0) 118 { 119 IResource* resource = ResourceManager::getInstance().getByName(_value, false); 120 if (resource != nullptr) 121 { 122 ResourceImageSet* imageSet = resource->castType<ResourceImageSet>(false); 123 if (imageSet != nullptr) 124 { 125 ImageIndexInfo info = imageSet->getIndexInfo(0, 0); 126 mImageSize = info.size; 127 } 128 } 129 } 130 131 ImageBox* image = _parent->createWidget<ImageBox>(mImageSkin, IntCoord(0, 0, mImageSize.width, mImageSize.height), Align::Default); 132 image->setItemResource(_value); 133 // картинка как урл 134 if (mUrl) 135 { 136 image->setPointer(mLinkPoiner); 137 image->eventMouseButtonClick += newDelegate(this, &HyperTextBox::OnTextClick); 138 image->setUserString("URL", mUrlValue); 139 } 140 } 141 else if (mUrl) 142 { 143 TextBox* text = _parent->createWidget<TextBox>(mTextSkin, IntCoord(0, 0, defaultSize, defaultSize), Align::Default); 144 text->setCaption(_value); 145 text->setPointer(mLinkPoiner); 146 if (mBold) 147 { 148 if (mItalic) 149 text->setFontName(mBoldItalicFont); 150 else 151 text->setFontName(mBoldFont); 152 } 153 else if (mItalic) 154 { 155 text->setFontName(mItalicFont); 156 } 157 158 Widget* line = text->createWidget<Widget>(mLineSkin, IntCoord(0, defaultSize - 1, defaultSize, 1), Align::HStretch | Align::Bottom); 159 line->setColour(Colour::Black); 160 line->setVisible(false); 161 line->setNeedMouseFocus(false); 162 163 text->eventMouseLostFocus += newDelegate(this, &HyperTextBox::OnTextLostFocus); 164 text->eventMouseSetFocus += newDelegate(this, &HyperTextBox::OnTextSetFocus); 165 text->eventMouseButtonClick += newDelegate(this, &HyperTextBox::OnTextClick); 166 text->setUserString("URL", mUrlValue); 167 } 168 else 169 { 170 VectorString result = utility::split(_value); 171 for (VectorString::const_iterator item = result.begin(); item != result.end(); ++ item) 172 { 173 TextBox* text = _parent->createWidget<TextBox>(mTextSkin, IntCoord(0, 0, defaultSize, defaultSize), Align::Default); 174 text->setCaption(*item); 175 if (mBold) 176 { 177 if (mItalic) 178 text->setFontName(mBoldItalicFont); 179 else 180 text->setFontName(mBoldFont); 181 } 182 else if (mItalic) 183 { 184 text->setFontName(mItalicFont); 185 } 186 else if (mHeader1) 187 { 188 text->setFontName(mHeader1Font); 189 } 190 else if (mHeader2) 191 { 192 text->setFontName(mHeader2Font); 193 } 194 else if (mHeader3) 195 { 196 text->setFontName(mHeader3Font); 197 } 198 199 if (mColour) 200 { 201 text->setTextColour(mColourValue); 202 } 203 204 if (mStrike) 205 { 206 Widget* line = text->createWidget<Widget>(mLineSkin, IntCoord(0, 0, defaultSize, 1), Align::HStretch | Align::VCenter); 207 line->setColour(Colour::Black); 208 line->setNeedMouseFocus(false); 209 if (mColour) 210 line->setColour(mColourValue); 211 } 212 213 if (mUnder) 214 { 215 Widget* line = text->createWidget<Widget>(mLineSkin, IntCoord(0, defaultSize - 1, defaultSize, 1), Align::HStretch | Align::Bottom); 216 line->setColour(Colour::Black); 217 line->setNeedMouseFocus(false); 218 if (mColour) 219 line->setColour(mColourValue); 220 } 221 } 222 } 223 } 224 parseTag(const std::string & _value)225 void HyperTextBox::parseTag(const std::string& _value) 226 { 227 const std::string imageStartTagName = "<img"; 228 const std::string imageEndTagName = ">"; 229 230 const std::string paragraphStartTagName = "<p"; 231 const std::string paragraphEndTagName = ">"; 232 233 const std::string colourStartTagName = "<color"; 234 const std::string colourEndTagName = ">"; 235 236 const std::string urlStartTagName = "<url"; 237 const std::string urlEndTagName = ">"; 238 239 if (_value == "<h1>") 240 { 241 mHeader1 = true; 242 } 243 else if (_value == "</h1>") 244 { 245 mHeader1 = false; 246 } 247 else if (_value == "<h2>") 248 { 249 mHeader2 = true; 250 } 251 else if (_value == "</h2>") 252 { 253 mHeader2 = false; 254 } 255 else if (_value == "<h3>") 256 { 257 mHeader3 = true; 258 } 259 else if (_value == "</h3>") 260 { 261 mHeader3 = false; 262 } 263 else if (_value == "<b>") 264 { 265 mBold = true; 266 } 267 else if (_value == "</b>") 268 { 269 mBold = false; 270 } 271 else if (_value == "<i>") 272 { 273 mItalic = true; 274 } 275 else if (_value == "</i>") 276 { 277 mItalic = false; 278 } 279 else if (_value == "<s>") 280 { 281 mStrike = true; 282 } 283 else if (_value == "</s>") 284 { 285 mStrike = false; 286 } 287 else if (_value == "<u>") 288 { 289 mUnder = true; 290 } 291 else if (_value == "</u>") 292 { 293 mUnder = false; 294 } 295 else if (utility::startWith(_value, colourStartTagName)) 296 { 297 mColour = true; 298 mColourValue = Colour::Black; 299 300 const std::string colourTagName = "value="; 301 302 std::string valueColour = _value.substr(colourStartTagName.size(), _value.size() - (colourStartTagName.size() + colourEndTagName.size())); 303 VectorString result = utility::split(valueColour); 304 for (VectorString::const_iterator item = result.begin(); item != result.end(); ++ item) 305 { 306 if (utility::startWith(*item, colourTagName)) 307 { 308 if ((colourTagName.size() + 2) < ((*item).size())) 309 { 310 std::string value = (*item).substr(colourTagName.size() + 1, (*item).size() - (colourTagName.size() + 2)); 311 mColourValue = Colour::parse(value); 312 } 313 } 314 } 315 } 316 else if (_value == "</color>") 317 { 318 mColour = false; 319 } 320 else if (utility::startWith(_value, urlStartTagName)) 321 { 322 mUrl = true; 323 mUrlValue.clear(); 324 325 const std::string urlTagName = "value="; 326 327 std::string valueUrl = _value.substr(urlStartTagName.size(), _value.size() - (urlStartTagName.size() + urlEndTagName.size())); 328 VectorString result = utility::split(valueUrl); 329 for (VectorString::const_iterator item = result.begin(); item != result.end(); ++ item) 330 { 331 if (utility::startWith(*item, urlTagName)) 332 { 333 if ((urlTagName.size() + 2) < ((*item).size())) 334 { 335 mUrlValue = (*item).substr(urlTagName.size() + 1, (*item).size() - (urlTagName.size() + 2)); 336 } 337 } 338 } 339 } 340 else if (_value == "</url>") 341 { 342 mUrl = false; 343 } 344 else if (utility::startWith(_value, paragraphStartTagName)) 345 { 346 mCurrentWrapPanel = mStackPanel->createWidget<WrapPanel>(mParagraphSkin, IntCoord(), Align::Default); 347 mCurrentWrapPanel->setContentAlign(Align::Left | Align::Bottom); 348 mCurrentWrapPanel->setSpacer(mSpacer); 349 350 Align alignResult = Align::Default; 351 bool needAlign = false; 352 353 Align floatResult = Align::Default; 354 bool needFloat = false; 355 356 const std::string alightTagName = "align="; 357 const std::string floatTagName = "float="; 358 359 std::string valueParagraph = _value.substr(paragraphStartTagName.size(), _value.size() - (paragraphStartTagName.size() + paragraphEndTagName.size())); 360 VectorString result = utility::split(valueParagraph); 361 for (VectorString::const_iterator item = result.begin(); item != result.end(); ++ item) 362 { 363 if (utility::startWith(*item, alightTagName)) 364 { 365 if ((alightTagName.size() + 2) < ((*item).size())) 366 { 367 needAlign = true; 368 std::string value = (*item).substr(alightTagName.size() + 1, (*item).size() - (alightTagName.size() + 2)); 369 if (value == "left") 370 alignResult = Align::Default; 371 else if (value == "center") 372 alignResult = Align::HCenter | Align::Top; 373 else if (value == "right") 374 alignResult = Align::Right | Align::Top; 375 else 376 alignResult = Align::Default; 377 } 378 } 379 else if (utility::startWith(*item, floatTagName)) 380 { 381 if ((floatTagName.size() + 2) < ((*item).size())) 382 { 383 needFloat = true; 384 std::string value = (*item).substr(floatTagName.size() + 1, (*item).size() - (floatTagName.size() + 2)); 385 if (value == "left") 386 floatResult = Align::Default; 387 else if (value == "center") 388 floatResult = Align::HCenter | Align::Top; 389 else if (value == "right") 390 floatResult = Align::Right | Align::Top; 391 else 392 floatResult = Align::Default; 393 } 394 } 395 } 396 397 if (needAlign) 398 { 399 mCurrentWrapPanel->setContentAlign(alignResult); 400 } 401 if (needFloat) 402 { 403 mCurrentWrapPanel->setContentFloat(true); 404 mCurrentWrapPanel->setSnapFloat(floatResult); 405 } 406 } 407 else if (_value == "</p>") 408 { 409 mCurrentWrapPanel = nullptr; 410 } 411 else if (utility::startWith(_value, imageStartTagName)) 412 { 413 mImageSize.clear(); 414 mImage = true; 415 416 const std::string widthTagName = "width="; 417 const std::string heightTagName = "height="; 418 419 std::string valueImage = _value.substr(imageStartTagName.size(), _value.size() - (imageStartTagName.size() + imageEndTagName.size())); 420 VectorString result = utility::split(valueImage); 421 for (VectorString::const_iterator item = result.begin(); item != result.end(); ++ item) 422 { 423 if (utility::startWith(*item, widthTagName)) 424 { 425 if ((widthTagName.size() + 2) < ((*item).size())) 426 { 427 std::string value = (*item).substr(widthTagName.size() + 1, (*item).size() - (widthTagName.size() + 2)); 428 mImageSize.width = utility::parseValue<int>(value); 429 } 430 } 431 else if (utility::startWith(*item, heightTagName)) 432 { 433 if ((heightTagName.size() + 2) < ((*item).size())) 434 { 435 std::string value = (*item).substr(heightTagName.size() + 1, (*item).size() - (heightTagName.size() + 2)); 436 mImageSize.height = utility::parseValue<int>(value); 437 } 438 } 439 } 440 } 441 else if (_value == "</img>") 442 { 443 mImage = false; 444 } 445 else if (_value == "<br/>") 446 { 447 if (mCurrentWrapPanel == nullptr) 448 { 449 WrapPanel* panel = mStackPanel->createWidget<WrapPanel>(mParagraphSkin, IntCoord(), Align::Default); 450 panel->setContentAlign(Align::Left | Align::Bottom); 451 panel->setSpacer(mSpacer); 452 panel->createWidget<Widget>("Default", IntCoord(0, 0, 0, mBreakHeight), Align::Default); 453 } 454 } 455 else if (_value == "<t/>") 456 { 457 if (mCurrentWrapPanel != nullptr) 458 { 459 const int countInTab = 4; 460 mCurrentWrapPanel->createWidget<Widget>("Default", IntCoord(0, 0, countInTab * mSpacer.width, 0), Align::Default); 461 } 462 } 463 } 464 OnTextLostFocus(Widget * _sender,Widget * _new)465 void HyperTextBox::OnTextLostFocus(Widget* _sender, Widget* _new) 466 { 467 size_t count = _sender->getChildCount(); 468 if (count > 0) 469 _sender->getChildAt(0)->setVisible(false); 470 } 471 OnTextSetFocus(Widget * _sender,Widget * _old)472 void HyperTextBox::OnTextSetFocus(Widget* _sender, Widget* _old) 473 { 474 size_t count = _sender->getChildCount(); 475 if (count > 0) 476 _sender->getChildAt(0)->setVisible(true); 477 } 478 OnTextClick(Widget * _sender)479 void HyperTextBox::OnTextClick(Widget* _sender) 480 { 481 std::string url = _sender->getUserString("URL"); 482 eventUrlClick(this, url); 483 } 484 updateContent()485 void HyperTextBox::updateContent() 486 { 487 mStackPanel->setSpacer(IntSize(0, mSpacer.height)); 488 mScrollViewPanel->updateContent(); 489 } 490 getSpacer() const491 const IntSize& HyperTextBox::getSpacer() const 492 { 493 return mSpacer; 494 } 495 setSpacer(const IntSize & _value)496 void HyperTextBox::setSpacer(const IntSize& _value) 497 { 498 mSpacer = _value; 499 } 500 getHeader1Font() const501 const std::string& HyperTextBox::getHeader1Font() const 502 { 503 return mHeader1Font; 504 } 505 setHeader1Font(const std::string & _value)506 void HyperTextBox::setHeader1Font(const std::string& _value) 507 { 508 mHeader1Font = _value; 509 } 510 getHeader2Font() const511 const std::string& HyperTextBox::getHeader2Font() const 512 { 513 return mHeader2Font; 514 } 515 setHeader2Font(const std::string & _value)516 void HyperTextBox::setHeader2Font(const std::string& _value) 517 { 518 mHeader2Font = _value; 519 } 520 getHeader3Font() const521 const std::string& HyperTextBox::getHeader3Font() const 522 { 523 return mHeader3Font; 524 } 525 setHeader3Font(const std::string & _value)526 void HyperTextBox::setHeader3Font(const std::string& _value) 527 { 528 mHeader3Font = _value; 529 } 530 getDefaultFont() const531 const std::string& HyperTextBox::getDefaultFont() const 532 { 533 return mDefaultFont; 534 } 535 setDefaultFont(const std::string & _value)536 void HyperTextBox::setDefaultFont(const std::string& _value) 537 { 538 mDefaultFont = _value; 539 updateBreakHeight(); 540 } 541 getBoldFont() const542 const std::string& HyperTextBox::getBoldFont() const 543 { 544 return mBoldFont; 545 } 546 setBoldFont(const std::string & _value)547 void HyperTextBox::setBoldFont(const std::string& _value) 548 { 549 mBoldFont = _value; 550 } 551 getItalicFont() const552 const std::string& HyperTextBox::getItalicFont() const 553 { 554 return mItalicFont; 555 } 556 setItalicFont(const std::string & _value)557 void HyperTextBox::setItalicFont(const std::string& _value) 558 { 559 mItalicFont = _value; 560 } 561 getBoldItalicFont() const562 const std::string& HyperTextBox::getBoldItalicFont() const 563 { 564 return mBoldItalicFont; 565 } 566 setBoldItalicFont(const std::string & _value)567 void HyperTextBox::setBoldItalicFont(const std::string& _value) 568 { 569 mBoldItalicFont =_value; 570 } 571 setPropertyOverride(const std::string & _key,const std::string & _value)572 void HyperTextBox::setPropertyOverride(const std::string& _key, const std::string& _value) 573 { 574 if (_key == "Spacer") 575 setSpacer(utility::parseValue<IntSize>(_value)); 576 else if (_key == "DefaultFont") 577 setDefaultFont(_value); 578 else if (_key == "BoldFont") 579 setBoldFont(_value); 580 else if (_key == "ItalicFont") 581 setItalicFont(_value); 582 else if (_key == "BoldItalicFont") 583 setBoldItalicFont(_value); 584 else if (_key == "Header1Font") 585 setHeader1Font(_value); 586 else if (_key == "Header2Font") 587 setHeader2Font(_value); 588 else if (_key == "Header3Font") 589 setHeader3Font(_value); 590 else 591 { 592 Base::setPropertyOverride(_key, _value); 593 return; 594 } 595 eventChangeProperty(this, _key, _value); 596 } 597 setCaption(const UString & _value)598 void HyperTextBox::setCaption(const UString& _value) 599 { 600 removeAllItems(); 601 602 addItem(_value); 603 604 updateContent(); 605 } 606 removeAllItems()607 void HyperTextBox::removeAllItems() 608 { 609 while (mStackPanel->getChildCount() != 0) 610 WidgetManager::getInstancePtr()->destroyWidget(mStackPanel->getChildAt(0)); 611 } 612 getItemsCount() const613 size_t HyperTextBox::getItemsCount() const 614 { 615 return mStackPanel->getChildCount(); 616 } 617 removeItemAt(size_t _index)618 void HyperTextBox::removeItemAt(size_t _index) 619 { 620 MYGUI_ASSERT_RANGE(_index, mStackPanel->getChildCount(), "HyperTextBox::removeItemAt"); 621 WidgetManager::getInstancePtr()->destroyWidget(mStackPanel->getChildAt(_index)); 622 } 623 updateBreakHeight()624 void HyperTextBox::updateBreakHeight() 625 { 626 mBreakHeight = 0; 627 628 IFont* font = FontManager::getInstancePtr()->getByName(getDefaultFont()); 629 if (font != nullptr) 630 mBreakHeight = font->getDefaultHeight(); 631 } 632 633 } // namespace MyGUI 634