00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "mmsgui/mmstextboxwidget.h"
00033 #include "mmsgui/mmstextbase.h"
00034 #include <cstdlib>
00035 #include <vector>
00036
00037 MMSTextBoxWidget::MMSTextBoxWidget(MMSWindow *root, string className, MMSTheme *theme) : MMSWidget() {
00038 create(root, className, theme);
00039 }
00040
00041 MMSTextBoxWidget::~MMSTextBoxWidget() {
00042 for(vector<TEXTBOX_WORDGEOM *>::iterator it(wordgeom.begin()); it != wordgeom.end(); ++it) {
00043 delete(*it);
00044 }
00045 if (this->file) {
00046 delete this->file;
00047 }
00048 }
00049
00050 bool MMSTextBoxWidget::create(MMSWindow *root, string className, MMSTheme *theme) {
00051 this->type = MMSWIDGETTYPE_TEXTBOX;
00052 this->className = className;
00053
00054
00055 this->da = new MMSWIDGET_DRAWABLE_ATTRIBUTES;
00056 if (theme) this->da->theme = theme; else this->da->theme = globalTheme;
00057 this->textBoxWidgetClass = this->da->theme->getTextBoxWidgetClass(className);
00058 this->da->baseWidgetClass = &(this->da->theme->textBoxWidgetClass.widgetClass);
00059 if (this->textBoxWidgetClass) this->da->widgetClass = &(this->textBoxWidgetClass->widgetClass); else this->da->widgetClass = NULL;
00060
00061
00062 initLanguage();
00063 this->fontpath = "";
00064 this->fontname = "";
00065 this->fontsize = 0;
00066 this->font = NULL;
00067 this->load_font = true;
00068 this->lasttext = "";
00069 this->surfaceChanged = true;
00070 this->translated = false;
00071 this->swap_left_right = false;
00072 this->file = NULL;
00073 this->current_fgset = false;
00074
00075 return MMSWidget::create(root, true, false, true, true, false, false, true);
00076 }
00077
00078 MMSWidget *MMSTextBoxWidget::copyWidget() {
00079
00080 MMSTextBoxWidget *newWidget = new MMSTextBoxWidget(this->rootwindow, className);
00081
00082 newWidget->className = this->className;
00083 newWidget->textBoxWidgetClass = this->textBoxWidgetClass;
00084 newWidget->myTextBoxWidgetClass = this->myTextBoxWidgetClass;
00085
00086 newWidget->lang = this->lang;
00087 newWidget->wordgeom = this->wordgeom;
00088 newWidget->lasttext = this->lasttext;
00089 newWidget->surfaceChanged = this->surfaceChanged;
00090 newWidget->translated_text = this->translated_text;
00091 newWidget->current_fgset = this->current_fgset;
00092 newWidget->current_fgcolor = this->current_fgcolor;
00093
00094
00095 MMSWidget::copyWidget((MMSWidget*)newWidget);
00096
00097
00098 initLanguage(newWidget);
00099 newWidget->fontpath = "";
00100 newWidget->fontname = "";
00101 newWidget->fontsize = 0;
00102 newWidget->font = NULL;
00103 newWidget->load_font = true;
00104 if (this->rootwindow) {
00105
00106 loadFont(newWidget);
00107 }
00108
00109 newWidget->translated = false;
00110 newWidget->swap_left_right = false;
00111
00112
00113 newWidget->file = NULL;
00114 newWidget->loadFile(false);
00115
00116 return newWidget;
00117 }
00118
00119
00120 void MMSTextBoxWidget::initLanguage(MMSTextBoxWidget *widget) {
00121 if (!widget) widget = this;
00122
00123 widget->lang = (!this->rootwindow)?MMSLANG_NONE:this->rootwindow->windowmanager->getTranslator()->getTargetLang();
00124 }
00125
00126 void MMSTextBoxWidget::loadFont(MMSTextBoxWidget *widget) {
00127 if (!this->load_font) return;
00128 if (!widget) widget = this;
00129
00130 if (this->rootwindow) {
00131
00132 widget->lang = this->rootwindow->windowmanager->getTranslator()->getTargetLang();
00133 string fontpath = widget->getFontPath();
00134 string fontname = widget->getFontName(widget->lang);
00135 unsigned int fontsize = widget->getFontSize();
00136
00137 if (fontpath != widget->fontpath || fontname != widget->fontname || fontsize != widget->fontsize || !widget->font) {
00138
00139 if (widget->font)
00140 this->rootwindow->fm->releaseFont(widget->font);
00141 widget->fontpath = fontpath;
00142 widget->fontname = fontname;
00143 widget->fontsize = fontsize;
00144 widget->font = this->rootwindow->fm->getFont(widget->fontpath, widget->fontname, widget->fontsize);
00145 if (widget->font) widget->load_font = false;
00146
00147
00148 widget->lasttext = "";
00149 }
00150 else {
00151
00152 widget->load_font = false;
00153 }
00154 }
00155 }
00156
00157
00158 bool MMSTextBoxWidget::setSurfaceGeometry(unsigned int width, unsigned int height) {
00159 if (MMSWidget::setSurfaceGeometry(width, height)) {
00160 this->surfaceChanged = true;
00161
00162 this->surface->lock();
00163
00164 this->surface->setFont(this->font);
00165 this->surface->unlock();
00166
00167 return true;
00168 }
00169 return false;
00170 }
00171
00172
00173 bool MMSTextBoxWidget::calcWordGeom(string &text, unsigned int startWidth, unsigned int startHeight,
00174 unsigned int *realWidth, unsigned int *realHeight,
00175 unsigned int *scrollDX, unsigned int *scrollDY, unsigned int *lines, unsigned int *paragraphs,
00176 bool wrap, bool splitwords, MMSALIGNMENT alignment,
00177 unsigned int *minWidth, unsigned int *minHeight, bool force_recalc) {
00178 int fontHeight, blankWidth;
00179 unsigned int x = 0, y = 0;
00180
00181
00182 *realWidth = startWidth;
00183 *realHeight = startHeight;
00184 *lines = 0;
00185 *paragraphs = 0;
00186
00187
00188 this->font->getHeight(&fontHeight);
00189 *scrollDX = fontHeight;
00190 *scrollDY = fontHeight;
00191
00192 if (minWidth) *minWidth = 0;
00193 if (minHeight) *minHeight = 0;
00194
00195
00196 if ((!force_recalc) && (text == this->lasttext) && (!this->surfaceChanged)) return false;
00197 this->lasttext = text;
00198 this->surfaceChanged = false;
00199
00200
00201 for (int i = (int)(this->wordgeom.size())-1; i >= 0; i--) {
00202 delete this->wordgeom.at(i);
00203 this->wordgeom.erase(this->wordgeom.end()-1);
00204 }
00205
00206
00207 if (text=="")
00208
00209 return true;
00210
00211
00212 this->font->getStringWidth(" ", -1, &blankWidth);
00213
00214
00215 int text_pos = 0;
00216 do {
00217
00218 size_t lfindex;
00219
00220
00221 size_t index;
00222
00223
00224 if ((lfindex = text.find('\n', text_pos)) != string::npos) lfindex-= text_pos;
00225
00226 if (wrap) {
00227
00228 if ((index = text.find(' ', text_pos)) != string::npos) index-= text_pos;
00229 }
00230 else {
00231
00232 index = string::npos;
00233 }
00234
00235 if (lfindex == string::npos) {
00236
00237 if (index == string::npos) {
00238
00239 index = text.size() - text_pos;
00240 }
00241 else
00242 if (index == 0) {
00243
00244
00245 if ((index = text.find_first_not_of(' ', text_pos)) != string::npos) index-= text_pos;
00246 index--;
00247 if (index == string::npos) {
00248
00249 index = text.size() - text_pos;
00250 }
00251 }
00252 }
00253 else {
00254
00255 if ((index == string::npos)||(index > lfindex)) {
00256
00257
00258 index = lfindex;
00259 }
00260 else {
00261
00262 if (index == 0) {
00263
00264
00265 if ((index = text.find_first_not_of(' ', text_pos)) != string::npos) index-= text_pos;
00266 index--;
00267 }
00268 lfindex = string::npos;
00269 }
00270 }
00271
00272 if (*lines == 0) {
00273
00274 *lines = 1;
00275 x = 0;
00276 y = 0;
00277 }
00278
00279
00280 TEXTBOX_WORDGEOM *mywordgeom = new TEXTBOX_WORDGEOM;
00281 mywordgeom->geom.h = fontHeight;
00282 mywordgeom->word = text.substr(text_pos, index);
00283
00284
00285 this->font->getStringWidth(mywordgeom->word, -1, &mywordgeom->geom.w);
00286
00287 if (x > 0)
00288 x += blankWidth;
00289
00290 unsigned int endpos = x + mywordgeom->geom.w;
00291
00292 bool gotonext = true;
00293
00294 if ((wrap)&&(splitwords)) {
00295
00296 if ((index != string::npos)&&(mywordgeom->geom.w > (int)*realWidth)) {
00297
00298 while ((index > 1)&&(mywordgeom->geom.w > (int)*realWidth)) {
00299 index--;
00300 mywordgeom->word = text.substr(text_pos, index);
00301 this->font->getStringWidth(mywordgeom->word, -1, &mywordgeom->geom.w);
00302 endpos = x + mywordgeom->geom.w;
00303 }
00304
00305
00306 text_pos+= index;
00307 gotonext = false;
00308 }
00309 }
00310
00311 if ((x==0)||(endpos <= *realWidth)||(wrap==false)) {
00312 if (endpos > *realWidth) {
00313 if (wrap==false)
00314 *realWidth = endpos;
00315 else {
00316 mywordgeom->geom.w-= endpos - *realWidth;
00317 endpos = *realWidth;
00318 }
00319 }
00320
00321 mywordgeom->geom.x = x;
00322 mywordgeom->geom.y = y;
00323
00324 x = endpos;
00325
00326 mywordgeom->line = *lines;
00327 mywordgeom->paragraph = *paragraphs;
00328 }
00329 else
00330 {
00331 x = 0;
00332 y+= fontHeight;
00333 (*lines)++;
00334
00335 mywordgeom->geom.x = x;
00336 mywordgeom->geom.y = y;
00337
00338 x += mywordgeom->geom.w;
00339
00340 mywordgeom->line = *lines;
00341 mywordgeom->paragraph = *paragraphs;
00342 }
00343
00344 if ((lfindex != string::npos)||(gotonext==false)) {
00345 x = 0;
00346 y+= fontHeight;
00347 (*lines)++;
00348 if (lfindex != string::npos) (*paragraphs)++;
00349 }
00350
00351 if (minWidth) {
00352 if (*minWidth < mywordgeom->geom.x + mywordgeom->geom.w)
00353 *minWidth = mywordgeom->geom.x + mywordgeom->geom.w;
00354 }
00355
00356 if (minHeight) {
00357 if (*minHeight < mywordgeom->geom.y + mywordgeom->geom.h)
00358 *minHeight = mywordgeom->geom.y + mywordgeom->geom.h;
00359 }
00360
00361
00362 wordgeom.push_back(mywordgeom);
00363
00364 if (gotonext) {
00365 if (index + 1 < text.size() - text_pos) {
00366
00367 text_pos+= index + 1;
00368 }
00369 else {
00370
00371 text_pos = (int)text.size();
00372 }
00373 }
00374 } while ((int)text.size() - text_pos > 0);
00375
00376
00377 unsigned int oldline = 1;
00378 unsigned int oldpos = 0;
00379 for (unsigned int i = 0; i < wordgeom.size(); i++) {
00380 if (wordgeom.at(i)->line != oldline) {
00381 if ((alignment == MMSALIGNMENT_CENTER)||(alignment == MMSALIGNMENT_TOP_CENTER)||(alignment == MMSALIGNMENT_BOTTOM_CENTER)) {
00382
00383 unsigned int diff = (*realWidth - wordgeom.at(i-1)->geom.x - wordgeom.at(i-1)->geom.w) / 2;
00384 for (unsigned int j = oldpos; j < i; j++)
00385 wordgeom.at(j)->geom.x += diff;
00386 }
00387 else
00388 if ((alignment == MMSALIGNMENT_RIGHT)||(alignment == MMSALIGNMENT_TOP_RIGHT)
00389 ||(alignment == MMSALIGNMENT_BOTTOM_RIGHT)) {
00390
00391 unsigned int diff = *realWidth - wordgeom.at(i-1)->geom.x - wordgeom.at(i-1)->geom.w;
00392 for (unsigned int j = oldpos; j < i; j++)
00393 wordgeom.at(j)->geom.x += diff;
00394 }
00395 else
00396 if (((alignment == MMSALIGNMENT_JUSTIFY)||(alignment == MMSALIGNMENT_TOP_JUSTIFY)
00397 ||(alignment == MMSALIGNMENT_BOTTOM_JUSTIFY))&&(wordgeom.at(i)->paragraph == wordgeom.at(i-1)->paragraph)) {
00398
00399 if (oldpos < i-1) {
00400 unsigned int diff = ((*realWidth - wordgeom.at(i-1)->geom.x - wordgeom.at(i-1)->geom.w)*10) / (i-1-oldpos);
00401 for (unsigned int j = oldpos + 1; j < i-1; j++) {
00402 wordgeom.at(j)->geom.x += ((j - oldpos) * diff) / 10;
00403 }
00404 if (oldpos < i-1) {
00405
00406 wordgeom.at(i-1)->geom.x = *realWidth - wordgeom.at(i-1)->geom.w;
00407 }
00408 }
00409 }
00410 oldpos = i;
00411 oldline = wordgeom.at(i)->line;
00412 }
00413 }
00414 if ((alignment == MMSALIGNMENT_CENTER)||(alignment == MMSALIGNMENT_TOP_CENTER)||(alignment == MMSALIGNMENT_BOTTOM_CENTER)) {
00415
00416 unsigned int diff = (*realWidth - wordgeom.at(wordgeom.size()-1)->geom.x - wordgeom.at(wordgeom.size()-1)->geom.w) / 2;
00417 for (unsigned int j = oldpos; j < wordgeom.size(); j++)
00418 wordgeom.at(j)->geom.x += diff;
00419 }
00420 else
00421 if ((alignment == MMSALIGNMENT_RIGHT)||(alignment == MMSALIGNMENT_TOP_RIGHT)
00422 ||(alignment == MMSALIGNMENT_BOTTOM_RIGHT)) {
00423
00424 unsigned int diff = *realWidth - wordgeom.at(wordgeom.size()-1)->geom.x - wordgeom.at(wordgeom.size()-1)->geom.w;
00425 for (unsigned int j = oldpos; j < wordgeom.size(); j++)
00426 wordgeom.at(j)->geom.x += diff;
00427 }
00428
00429
00430 if (fontHeight * (*lines) > *realHeight) {
00431 *realHeight = fontHeight * (*lines);
00432 } else if (fontHeight * (*lines) < *realHeight) {
00433 if ((alignment == MMSALIGNMENT_CENTER)||(alignment == MMSALIGNMENT_LEFT)
00434 ||(alignment == MMSALIGNMENT_RIGHT)||(alignment == MMSALIGNMENT_JUSTIFY)) {
00435
00436 unsigned int diff = (*realHeight - fontHeight * (*lines)) / 2;
00437 if (diff > 0) {
00438 for (unsigned int i = 0; i < wordgeom.size(); i++)
00439 wordgeom.at(i)->geom.y += diff;
00440 }
00441 }
00442 else
00443 if ((alignment == MMSALIGNMENT_BOTTOM_CENTER)||(alignment == MMSALIGNMENT_BOTTOM_LEFT)
00444 ||(alignment == MMSALIGNMENT_BOTTOM_RIGHT)||(alignment == MMSALIGNMENT_BOTTOM_JUSTIFY)) {
00445
00446 unsigned int diff = (*realHeight - fontHeight * (*lines));
00447 if (diff > 0)
00448 for (unsigned int i = 0; i < wordgeom.size(); i++)
00449 wordgeom.at(i)->geom.y += diff;
00450 }
00451 }
00452 if(this->swap_left_right) {
00453
00454 std::vector<int> mylines;
00455 int linepos = (*wordgeom.begin())->geom.y;
00456 mylines.push_back(linepos);
00457 for (unsigned int i = 0; i < wordgeom.size(); i++) {
00458 if(linepos != wordgeom.at(i)->geom.y) {
00459 linepos = wordgeom.at(i)->geom.y;
00460 mylines.push_back(linepos);
00461 }
00462 }
00463 for(vector<int>::iterator it = mylines.begin(); it != mylines.end(); it++) {
00464 printf("%d\n", *it);
00465 }
00466
00467 linepos = (*wordgeom.begin())->geom.y;
00468 vector<int>::reverse_iterator it = mylines.rbegin();
00469 for (unsigned int i = 0; i < wordgeom.size(); i++) {
00470 if(linepos != wordgeom.at(i)->geom.y) {
00471 linepos = wordgeom.at(i)->geom.y;
00472 it++;
00473 }
00474 wordgeom.at(i)->geom.y = *it;
00475 }
00476
00477 }
00478
00479
00480
00481 return true;
00482 }
00483
00484
00485 bool MMSTextBoxWidget::init() {
00486
00487 if (!MMSWidget::init())
00488 return false;
00489
00490
00491 initLanguage();
00492
00493
00494 loadFont();
00495
00496
00497 this->loadFile(false);
00498
00499 return true;
00500 }
00501
00502 bool MMSTextBoxWidget::release() {
00503
00504 if (!MMSWidget::release())
00505 return false;
00506
00507
00508 this->rootwindow->fm->releaseFont(this->font);
00509 this->fontpath = "";
00510 this->fontname = "";
00511 this->fontsize = 0;
00512 this->font = NULL;
00513 this->load_font = true;
00514
00515 return true;
00516 }
00517
00518
00519 bool MMSTextBoxWidget::prepareText(int *width, int *height, bool recalc) {
00520
00521 this->surface->lock();
00522 loadFont();
00523
00524 if (!this->font) {
00525 this->surface->unlock();
00526 return false;
00527 }
00528
00529
00530 this->surface->setFont(this->font);
00531 this->surface->unlock();
00532
00533 if (!this->translated) {
00534
00535 if ((this->rootwindow)&&(this->rootwindow->windowmanager)&&(getTranslate())) {
00536
00537 string source;
00538 getText(source);
00539 this->rootwindow->windowmanager->getTranslator()->translate(source, this->translated_text);
00540 }
00541 else {
00542
00543 getText(this->translated_text);
00544 }
00545
00546
00547 this->swap_left_right = false;
00548
00549
00550 MMSLanguage targetlang = this->rootwindow->windowmanager->getTranslator()->getTargetLang();
00551 if (((targetlang == MMSLANG_IL) || (targetlang == MMSLANG_AR)) && getTranslate()) {
00552 if (convBidiString(this->translated_text, this->translated_text, (targetlang == MMSLANG_AR) ? true : false)) {
00553
00554 this->swap_left_right = true;
00555 }
00556 }
00557
00558
00559 this->translated = true;
00560 }
00561
00562 if (!this->minmax_set) {
00563
00564 unsigned int realWidth, realHeight, scrollDX, scrollDY, lines, paragraphs;
00565 if (calcWordGeom(this->translated_text, getInnerGeometry().w, getInnerGeometry().h, &realWidth, &realHeight, &scrollDX, &scrollDY,
00566 &lines, ¶graphs, getWrap(), getSplitWords(),
00567 (!this->swap_left_right) ? getAlignment() : swapAlignmentHorizontal(getAlignment()))) {
00568
00569 setScrollSize(scrollDX, scrollDY);
00570 setSurfaceGeometry(realWidth, realHeight);
00571 }
00572 }
00573 else {
00574
00575 int maxWidth = getMaxWidthPix();
00576 if (maxWidth <= 0) maxWidth = getInnerGeometry().w;
00577 int maxHeight = getMaxHeightPix();
00578 if (maxHeight <= 0) maxHeight = getInnerGeometry().h;
00579
00580
00581 if (recalc) {
00582 unsigned int realWidth, realHeight, scrollDX, scrollDY, lines, paragraphs, minWidth, minHeight;
00583 if (calcWordGeom(this->translated_text,
00584 maxWidth, maxHeight,
00585 &realWidth, &realHeight, &scrollDX, &scrollDY,
00586 &lines, ¶graphs, getWrap(), getSplitWords(),
00587 (!this->swap_left_right) ? getAlignment() : swapAlignmentHorizontal(getAlignment()),
00588 &minWidth, &minHeight, true)) {
00589
00590
00591
00592
00593
00594 if (minWidth < getMinWidthPix())
00595 minWidth = getMinWidthPix();
00596 if (minHeight < getMinHeightPix())
00597 minHeight = getMinHeightPix();
00598
00599 if (minWidth < maxWidth || minHeight < maxHeight) {
00600 calcWordGeom(this->translated_text,
00601 (minWidth < maxWidth) ? minWidth : maxWidth,
00602 (minHeight < maxHeight) ? minHeight : maxHeight,
00603 &realWidth, &realHeight, &scrollDX, &scrollDY,
00604 &lines, ¶graphs, getWrap(), getSplitWords(),
00605 (!this->swap_left_right) ? getAlignment() : swapAlignmentHorizontal(getAlignment()),
00606 &minWidth, &minHeight, true);
00607 }
00608
00609
00610 if (width) {
00611 if (realWidth < minWidth)
00612 *width = minWidth;
00613 else
00614 if (realWidth > maxWidth)
00615 *width = maxWidth;
00616 else
00617 *width = realWidth;
00618
00619 if (*width <= 0) *width = 1;
00620 }
00621
00622 if (height) {
00623 if (realHeight < minHeight)
00624 *height = minHeight;
00625 else
00626 if (realHeight > maxHeight)
00627 *height = maxHeight;
00628 else
00629 *height = realHeight;
00630
00631 if (*height <= 0) *height = 1;
00632 }
00633 }
00634 }
00635 else {
00636 unsigned int realWidth, realHeight, scrollDX, scrollDY, lines, paragraphs;
00637 if (calcWordGeom(this->translated_text, getInnerGeometry().w, getInnerGeometry().h, &realWidth, &realHeight, &scrollDX, &scrollDY,
00638 &lines, ¶graphs, getWrap(), getSplitWords(),
00639 (!this->swap_left_right) ? getAlignment() : swapAlignmentHorizontal(getAlignment()))) {
00640
00641 setScrollSize(scrollDX, scrollDY);
00642 setSurfaceGeometry(realWidth, realHeight);
00643 }
00644 }
00645
00646
00647 }
00648
00649 return true;
00650 }
00651
00652
00653 void MMSTextBoxWidget::calcContentSize() {
00654 int width, height;
00655
00656 if (prepareText(&width, &height, true)) {
00657
00658 setContentSize(width, height);
00659 }
00660 }
00661
00662
00663 void MMSTextBoxWidget::getForeground(MMSFBColor *color) {
00664 color->a = 0;
00665
00666 if (isActivated()) {
00667 if (isSelected()) {
00668 *color = getSelColor();
00669 }
00670 else {
00671 *color = getColor();
00672 }
00673 if (isPressed()) {
00674 MMSFBColor mycol;
00675 if (isSelected()) {
00676 mycol = getSelColor_p();
00677 if (mycol.a>0) *color=mycol;
00678 }
00679 else {
00680 mycol = getColor_p();
00681 if (mycol.a>0) *color=mycol;
00682 }
00683 }
00684 }
00685 else {
00686 if (isSelected()) {
00687 *color = getSelColor_i();
00688 }
00689 else {
00690 *color = getColor_i();
00691 }
00692 }
00693 }
00694
00695 bool MMSTextBoxWidget::enableRefresh(bool enable) {
00696 if (!MMSWidget::enableRefresh(enable)) return false;
00697
00698
00699 this->current_fgset = false;
00700
00701 return true;
00702 }
00703
00704 bool MMSTextBoxWidget::checkRefreshStatus() {
00705 if (MMSWidget::checkRefreshStatus()) return true;
00706
00707 if (this->current_fgset) {
00708
00709 MMSFBColor color;
00710 getForeground(&color);
00711
00712 if (color == this->current_fgcolor) {
00713
00714 return false;
00715 }
00716 }
00717
00718
00719 enableRefresh();
00720
00721 return true;
00722 }
00723
00724
00725 bool MMSTextBoxWidget::draw(bool *backgroundFilled) {
00726 bool myBackgroundFilled = false;
00727
00728 if (!this->initialized) {
00729
00730 init();
00731 this->initialized = true;
00732 }
00733
00734 if(!surface)
00735 return false;
00736
00737 if (backgroundFilled) {
00738 if (this->has_own_surface)
00739 *backgroundFilled = false;
00740 }
00741 else
00742 backgroundFilled = &myBackgroundFilled;
00743
00744
00745 this->surface->lock();
00746
00747
00748 if (MMSWidget::draw(backgroundFilled)) {
00749
00750
00751 if (prepareText(NULL, NULL)) {
00752
00753 MMSFBRectangle surfaceGeom = getSurfaceGeometry();
00754
00755
00756 MMSFBColor color;
00757 getForeground(&color);
00758 this->current_fgcolor = color;
00759 this->current_fgset = true;
00760
00761 if (color.a) {
00762
00763 this->surface->setDrawingColorAndFlagsByBrightnessAndOpacity(
00764 color,
00765 (isSelected())?getSelShadowColor(MMSPOSITION_TOP):getShadowColor(MMSPOSITION_TOP),
00766 (isSelected())?getSelShadowColor(MMSPOSITION_BOTTOM):getShadowColor(MMSPOSITION_BOTTOM),
00767 (isSelected())?getSelShadowColor(MMSPOSITION_LEFT):getShadowColor(MMSPOSITION_LEFT),
00768 (isSelected())?getSelShadowColor(MMSPOSITION_RIGHT):getShadowColor(MMSPOSITION_RIGHT),
00769 (isSelected())?getSelShadowColor(MMSPOSITION_TOP_LEFT):getShadowColor(MMSPOSITION_TOP_LEFT),
00770 (isSelected())?getSelShadowColor(MMSPOSITION_TOP_RIGHT):getShadowColor(MMSPOSITION_TOP_RIGHT),
00771 (isSelected())?getSelShadowColor(MMSPOSITION_BOTTOM_LEFT):getShadowColor(MMSPOSITION_BOTTOM_LEFT),
00772 (isSelected())?getSelShadowColor(MMSPOSITION_BOTTOM_RIGHT):getShadowColor(MMSPOSITION_BOTTOM_RIGHT),
00773 getBrightness(), getOpacity());
00774
00775
00776 for (unsigned int i = 0; i < this->wordgeom.size(); i++) {
00777 if (this->has_own_surface) {
00778 this->surface->drawString(this->wordgeom.at(i)->word, -1,
00779 surfaceGeom.x + this->wordgeom.at(i)->geom.x,
00780 surfaceGeom.y + this->wordgeom.at(i)->geom.y);
00781 }
00782 else {
00783 this->surface->drawString(this->wordgeom.at(i)->word, -1,
00784 surfaceGeom.x + this->wordgeom.at(i)->geom.x - this->da->scrollPosX,
00785 surfaceGeom.y + this->wordgeom.at(i)->geom.y - this->da->scrollPosY);
00786 }
00787 }
00788 }
00789 }
00790
00791
00792 updateWindowSurfaceWithSurface(!*backgroundFilled);
00793 }
00794
00795
00796 this->surface->unlock();
00797
00798
00799 return MMSWidget::drawDebug();
00800 }
00801
00802 void MMSTextBoxWidget::targetLangChanged(MMSLanguage lang) {
00803 this->translated = false;
00804 this->load_font = true;
00805
00806
00807
00808 recalcContentSize(false);
00809 }
00810
00811 bool MMSTextBoxWidget::loadFile(bool refresh) {
00812 if (this->file) {
00813
00814 delete this->file;
00815 this->file = NULL;
00816 }
00817
00818
00819 this->file = new MMSFile(getFilePath() + "/" + getFileName());
00820 if (!this->file)
00821 return false;
00822 if (this->file->getLastError())
00823 return false;
00824
00825
00826 void *ptr;
00827 size_t ritems;
00828 if (!this->file->readBufferEx(&ptr, &ritems)) {
00829 delete this->file;
00830 this->file = NULL;
00831 return false;
00832 }
00833
00834
00835 setText("", false);
00836
00837
00838 string text;
00839 text.insert(0, (const char *)ptr, ritems);
00840 setText(&text, refresh);
00841
00842
00843 free(ptr);
00844
00845 return true;
00846 }
00847
00848 bool MMSTextBoxWidget::reloadFile() {
00849 return loadFile(true);
00850 }
00851
00852
00853
00854
00855
00856
00857 #define GETTEXTBOX(x) \
00858 if (this->myTextBoxWidgetClass.is##x()) return myTextBoxWidgetClass.get##x(); \
00859 else if ((textBoxWidgetClass)&&(textBoxWidgetClass->is##x())) return textBoxWidgetClass->get##x(); \
00860 else return this->da->theme->textBoxWidgetClass.get##x();
00861
00862 #define GETTEXTBOX2(x, y) \
00863 if (this->myTextBoxWidgetClass.is##x()) y=myTextBoxWidgetClass.get##x(); \
00864 else if ((textBoxWidgetClass)&&(textBoxWidgetClass->is##x())) y=textBoxWidgetClass->get##x(); \
00865 else y=this->da->theme->textBoxWidgetClass.get##x();
00866
00867 #define GETTEXTBOXFONT(lang) \
00868 if (this->myTextBoxWidgetClass.isFontName(lang)) return myTextBoxWidgetClass.getFontName(lang); \
00869 else if (this->myTextBoxWidgetClass.isFontName(MMSLANG_NONE)) return myTextBoxWidgetClass.getFontName(MMSLANG_NONE); \
00870 else if ((textBoxWidgetClass)&&(textBoxWidgetClass->isFontName(lang))) return textBoxWidgetClass->getFontName(lang); \
00871 else if ((textBoxWidgetClass)&&(textBoxWidgetClass->isFontName(MMSLANG_NONE))) return textBoxWidgetClass->getFontName(MMSLANG_NONE); \
00872 else return this->da->theme->textBoxWidgetClass.getFontName();
00873
00874 #define GETTEXTBOXSHADOW(x) \
00875 if (this->myTextBoxWidgetClass.isShadowColor(x)) return myTextBoxWidgetClass.getShadowColor(x); \
00876 else if ((textBoxWidgetClass)&&(textBoxWidgetClass->isShadowColor(x))) return textBoxWidgetClass->getShadowColor(x); \
00877 else return this->da->theme->textBoxWidgetClass.getShadowColor(x);
00878
00879 #define GETTEXTBOXSHADOWSEL(x) \
00880 if (this->myTextBoxWidgetClass.isSelShadowColor(x)) return myTextBoxWidgetClass.getSelShadowColor(x); \
00881 else if ((textBoxWidgetClass)&&(textBoxWidgetClass->isSelShadowColor(x))) return textBoxWidgetClass->getSelShadowColor(x); \
00882 else return this->da->theme->textBoxWidgetClass.getSelShadowColor(x);
00883
00884 string MMSTextBoxWidget::getFontPath() {
00885 GETTEXTBOX(FontPath);
00886 }
00887
00888 string MMSTextBoxWidget::getFontName(MMSLanguage lang) {
00889 GETTEXTBOXFONT(lang);
00890 }
00891
00892 unsigned int MMSTextBoxWidget::getFontSize() {
00893 GETTEXTBOX(FontSize);
00894 }
00895
00896 MMSALIGNMENT MMSTextBoxWidget::getAlignment() {
00897 GETTEXTBOX(Alignment);
00898 }
00899
00900 bool MMSTextBoxWidget::getWrap() {
00901 GETTEXTBOX(Wrap);
00902 }
00903
00904 bool MMSTextBoxWidget::getSplitWords() {
00905 GETTEXTBOX(SplitWords);
00906 }
00907
00908 MMSFBColor MMSTextBoxWidget::getColor() {
00909 GETTEXTBOX(Color);
00910 }
00911
00912 MMSFBColor MMSTextBoxWidget::getSelColor() {
00913 GETTEXTBOX(SelColor);
00914 }
00915
00916 MMSFBColor MMSTextBoxWidget::getColor_p() {
00917 GETTEXTBOX(Color_p);
00918 }
00919
00920 MMSFBColor MMSTextBoxWidget::getSelColor_p() {
00921 GETTEXTBOX(SelColor_p);
00922 }
00923
00924 MMSFBColor MMSTextBoxWidget::getColor_i() {
00925 GETTEXTBOX(Color_i);
00926 }
00927
00928 MMSFBColor MMSTextBoxWidget::getSelColor_i() {
00929 GETTEXTBOX(SelColor_i);
00930 }
00931
00932 string MMSTextBoxWidget::getText() {
00933 GETTEXTBOX(Text);
00934 }
00935
00936 void MMSTextBoxWidget::getText(string &text) {
00937 GETTEXTBOX2(Text, text);
00938 }
00939
00940 bool MMSTextBoxWidget::getTranslate() {
00941 GETTEXTBOX(Translate);
00942 }
00943
00944 string MMSTextBoxWidget::getFilePath() {
00945 GETTEXTBOX(FilePath);
00946 }
00947
00948 string MMSTextBoxWidget::getFileName() {
00949 GETTEXTBOX(FileName);
00950 }
00951
00952 MMSFBColor MMSTextBoxWidget::getShadowColor(MMSPOSITION position) {
00953 GETTEXTBOXSHADOW(position);
00954 }
00955
00956 MMSFBColor MMSTextBoxWidget::getSelShadowColor(MMSPOSITION position) {
00957 GETTEXTBOXSHADOWSEL(position);
00958 }
00959
00960
00961
00962
00963
00964 void MMSTextBoxWidget::setFontPath(string fontpath, bool load, bool refresh) {
00965 myTextBoxWidgetClass.setFontPath(fontpath);
00966 if (load) {
00967 this->load_font = true;
00968 loadFont();
00969 }
00970
00971
00972 enableRefresh();
00973
00974 this->refresh(refresh);
00975 }
00976
00977 void MMSTextBoxWidget::setFontName(MMSLanguage lang, string fontname, bool load, bool refresh) {
00978 myTextBoxWidgetClass.setFontName(fontname, lang);
00979 if (load) {
00980 this->load_font = true;
00981 loadFont();
00982 }
00983
00984
00985 enableRefresh();
00986
00987 this->refresh(refresh);
00988 }
00989
00990 void MMSTextBoxWidget::setFontName(string fontname, bool load, bool refresh) {
00991 setFontName(MMSLANG_NONE, fontname, load, refresh);
00992 }
00993
00994 void MMSTextBoxWidget::setFontSize(unsigned int fontsize, bool load, bool refresh) {
00995 myTextBoxWidgetClass.setFontSize(fontsize);
00996 if (load) {
00997 this->load_font = true;
00998 loadFont();
00999 }
01000
01001
01002 enableRefresh();
01003
01004 this->refresh(refresh);
01005 }
01006
01007 void MMSTextBoxWidget::setFont(MMSLanguage lang, string fontpath, string fontname, unsigned int fontsize, bool load, bool refresh) {
01008 myTextBoxWidgetClass.setFontPath(fontpath);
01009 myTextBoxWidgetClass.setFontName(fontname, lang);
01010 myTextBoxWidgetClass.setFontSize(fontsize);
01011 if (load) {
01012 this->load_font = true;
01013 loadFont();
01014 }
01015
01016
01017 enableRefresh();
01018
01019 this->refresh(refresh);
01020 }
01021
01022 void MMSTextBoxWidget::setFont(string fontpath, string fontname, unsigned int fontsize, bool load, bool refresh) {
01023 setFont(MMSLANG_NONE, fontpath, fontname, fontsize, load, refresh);
01024 }
01025
01026 void MMSTextBoxWidget::setAlignment(MMSALIGNMENT alignment, bool refresh) {
01027 myTextBoxWidgetClass.setAlignment(alignment);
01028
01029
01030 enableRefresh();
01031
01032 this->refresh(refresh);
01033 }
01034
01035 void MMSTextBoxWidget::setWrap(bool wrap, bool refresh) {
01036 myTextBoxWidgetClass.setWrap(wrap);
01037
01038
01039 enableRefresh();
01040
01041 this->refresh(refresh);
01042 }
01043
01044 void MMSTextBoxWidget::setSplitWords(bool splitwords, bool refresh) {
01045 myTextBoxWidgetClass.setSplitWords(splitwords);
01046
01047
01048 enableRefresh();
01049
01050 this->refresh(refresh);
01051 }
01052
01053 void MMSTextBoxWidget::setColor(MMSFBColor color, bool refresh) {
01054 myTextBoxWidgetClass.setColor(color);
01055
01056
01057 enableRefresh((color != this->current_fgcolor));
01058
01059 this->refresh(refresh);
01060 }
01061
01062 void MMSTextBoxWidget::setSelColor(MMSFBColor selcolor, bool refresh) {
01063 myTextBoxWidgetClass.setSelColor(selcolor);
01064
01065
01066 enableRefresh((selcolor != this->current_fgcolor));
01067
01068 this->refresh(refresh);
01069 }
01070
01071 void MMSTextBoxWidget::setColor_p(MMSFBColor color_p, bool refresh) {
01072 myTextBoxWidgetClass.setColor_p(color_p);
01073
01074
01075 enableRefresh((color_p != this->current_fgcolor));
01076
01077 this->refresh(refresh);
01078 }
01079
01080 void MMSTextBoxWidget::setSelColor_p(MMSFBColor selcolor_p, bool refresh) {
01081 myTextBoxWidgetClass.setSelColor_p(selcolor_p);
01082
01083
01084 enableRefresh((selcolor_p != this->current_fgcolor));
01085
01086 this->refresh(refresh);
01087 }
01088
01089 void MMSTextBoxWidget::setColor_i(MMSFBColor color_i, bool refresh) {
01090 myTextBoxWidgetClass.setColor_i(color_i);
01091
01092
01093 enableRefresh((color_i != this->current_fgcolor));
01094
01095 this->refresh(refresh);
01096 }
01097
01098 void MMSTextBoxWidget::setSelColor_i(MMSFBColor selcolor_i, bool refresh) {
01099 myTextBoxWidgetClass.setSelColor_i(selcolor_i);
01100
01101
01102 enableRefresh((selcolor_i != this->current_fgcolor));
01103
01104 this->refresh(refresh);
01105 }
01106
01107
01108 void MMSTextBoxWidget::setText(string *text, bool refresh) {
01109 myTextBoxWidgetClass.setText(text);
01110 this->translated = false;
01111 this->da->scrollPosX=0;
01112 this->da->scrollPosY=0;
01113
01114
01115 enableRefresh();
01116
01117 this->refresh(refresh);
01118 }
01119
01120 void MMSTextBoxWidget::setText(string text, bool refresh) {
01121 setText(&text, refresh);
01122 }
01123
01124 void MMSTextBoxWidget::setTranslate(bool translate, bool refresh) {
01125 myTextBoxWidgetClass.setTranslate(translate);
01126 this->translated = false;
01127
01128
01129 enableRefresh();
01130
01131 this->refresh(refresh);
01132 }
01133
01134 void MMSTextBoxWidget::setFilePath(string filepath, bool load, bool refresh) {
01135 myTextBoxWidgetClass.setFilePath(filepath);
01136 if (load)
01137 loadFile(false);
01138
01139
01140 enableRefresh();
01141
01142 this->refresh(refresh);
01143 }
01144
01145 void MMSTextBoxWidget::setFileName(string filename, bool load, bool refresh) {
01146 myTextBoxWidgetClass.setFileName(filename);
01147 if (load)
01148 loadFile(false);
01149
01150
01151 enableRefresh();
01152
01153 this->refresh(refresh);
01154 }
01155
01156 void MMSTextBoxWidget::setShadowColor(MMSPOSITION position, MMSFBColor color, bool refresh) {
01157 myTextBoxWidgetClass.setShadowColor(position, color);
01158
01159
01160 enableRefresh();
01161
01162 this->refresh(refresh);
01163 }
01164
01165 void MMSTextBoxWidget::setSelShadowColor(MMSPOSITION position, MMSFBColor selcolor, bool refresh) {
01166 myTextBoxWidgetClass.setSelShadowColor(position, selcolor);
01167
01168
01169 enableRefresh();
01170
01171 this->refresh(refresh);
01172 }
01173
01174
01175 void MMSTextBoxWidget::updateFromThemeClass(MMSTextBoxWidgetClass *themeClass) {
01176
01177
01178 if (themeClass->isWrap())
01179 setWrap(themeClass->getWrap());
01180 if (themeClass->isSplitWords())
01181 setSplitWords(themeClass->getSplitWords());
01182 if (themeClass->isTranslate())
01183 setTranslate(themeClass->getTranslate());
01184 if (themeClass->isFilePath())
01185 setFilePath(themeClass->getFilePath());
01186 if (themeClass->isFileName())
01187 setFileName(themeClass->getFileName());
01188
01189
01190 MMSTEXTBASE_UPDATE_FROM_THEME_CLASS(this, themeClass);
01191
01192
01193 MMSWidget::updateFromThemeClass(&(themeClass->widgetClass));
01194 }
01195
01196
01197
01198