From 4e0881f68953803ff2699ffb0b996304d12544db Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 20 Dec 2012 13:57:29 +0000 Subject: [PATCH] - fixed #1167 - CLabel will print text in "{}" using title color --- README.linux | 13 ++- client/CCastleInterface.cpp | 2 +- client/CPreGame.cpp | 4 +- client/GUIClasses.cpp | 132 +++++++++++++++++------ client/GUIClasses.h | 16 +-- client/UIFramework/CIntObjectClasses.cpp | 55 +++++----- client/UIFramework/CIntObjectClasses.h | 22 ++-- client/UIFramework/Fonts.h | 3 - 8 files changed, 162 insertions(+), 85 deletions(-) diff --git a/README.linux b/README.linux index 68c8ada6e..749503700 100644 --- a/README.linux +++ b/README.linux @@ -4,6 +4,7 @@ To run the game you will need: 1) Heroes 3 data files (SoD or Complete editions); 2) Unofficial WoG addon 2) VCMI data pack (http://download.vcmi.eu/core.zip) +All of them can be installed manually or using vcmibuilder script For complete installation instructions see VCMI wiki: http://wiki.vcmi.eu/index.php?title=Installation_on_Linux#Preparing_data @@ -59,15 +60,11 @@ That will generate vcmiclient, vcmiserver as well as 3 .so libraries. III. Installing binaries -Since VCMI is still in development, there's no install procedure, although this will work: +To install VCMI type (as root): make install -You also need to update configuration files: - cp /PATH_TO_SOURCE/config /DATA_PATH/vcmi -In this case you'll have to manually update these files after any changes. -For more permament solution you should use links as described below. -For development puposes, it's better to use links. Go -to /BIN_PATH/, and type: +For development puposes, it's better to use links instead. +Go to /BIN_PATH/, and type: ln -s .../trunk/build/client/vcmiclient ln -s .../trunk/build/server/vcmiserver @@ -83,4 +80,6 @@ Go to /LIB_PATH/vcmi/AI, and type: Go to /DATA_PATH/vcmi, and type: ln -s .../trunk/source/config + ln -s .../trunk/source/Mods + diff --git a/client/CCastleInterface.cpp b/client/CCastleInterface.cpp index 3ce62fe8f..30ab33182 100644 --- a/client/CCastleInterface.cpp +++ b/client/CCastleInterface.cpp @@ -851,7 +851,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst garr = new CGarrisonInt(305, 387, 4, Point(0,96), panel->bg, Point(62,374), town->getUpperArmy(), town->visitingHero); heroes = new HeroSlots(town, Point(241, 387), Point(241, 483), garr, true); - title = new CLabel(85, 387, FONT_MEDIUM, TOPLEFT, Colors::WHITE, town->name); + title = new CLabel(60, 382, FONT_MEDIUM, TOPLEFT, Colors::WHITE, town->name); income = new CLabel(195, 443, FONT_SMALL, CENTER); icon = new CAnimImage("ITPT", 0, 0, 15, 387); diff --git a/client/CPreGame.cpp b/client/CPreGame.cpp index ddb57956b..44b1c865d 100644 --- a/client/CPreGame.cpp +++ b/client/CPreGame.cpp @@ -2861,7 +2861,7 @@ void OptionsTab::CPregameTooltipBox::genTownWindow() for (size_t i=0; i< town.creatures.size(); i++) components.push_back(new CComponent(CComponent::creature, town.creatures[i].front(), 0, CComponent::tiny)); - new CComponentBox(components, Rect(0, 140, pos.w, 140)); + new CComponentBox(components, Rect(10, 140, pos.w - 20, 140)); } void OptionsTab::CPregameTooltipBox::genHeroWindow() @@ -2881,7 +2881,7 @@ void OptionsTab::CPregameTooltipBox::genBonusWindow() pos = Rect(0, 0, 228, 162); genHeader(); - new CTextBox(getDescription(), Rect(10, 88, pos.w - 20, 70), 0, FONT_SMALL, CENTER, Colors::WHITE ); + new CTextBox(getDescription(), Rect(10, 100, pos.w - 20, 70), 0, FONT_SMALL, CENTER, Colors::WHITE ); } OptionsTab::SelectedBox::SelectedBox(Point position, PlayerSettings & settings, SelType type) diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index fcd5adfa1..a74a6e136 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -1146,7 +1146,8 @@ void CComponentBox::placeComponents(bool selectable) const int distance = prevComp ? getDistance(prevComp, comp) : 0; //start next row - if (pos.w != 0 && rows.back().width + comp->pos.w + distance > pos.w) + if ((pos.w != 0 && rows.back().width + comp->pos.w + distance > pos.w) // row is full + || rows.back().comps >= 4) // no more than 4 comps per row { prevComp = nullptr; rows.push_back (RowData (0,0,0)); @@ -1182,11 +1183,14 @@ void CComponentBox::placeComponents(bool selectable) //move components to their positions for (size_t row = 0; row < rows.size(); row++) { + // amount of free space we may add on each side of every component + int freeSpace = (pos.w - rows[row].width) / (rows[row].comps * 2); prevComp = nullptr; - int currentX = (pos.w - rows[row].width) / 2; + int currentX = 0; for (size_t col = 0; col < rows[row].comps; col++) { + currentX += freeSpace; if (prevComp) { if (selectable) @@ -1200,6 +1204,7 @@ void CComponentBox::placeComponents(bool selectable) (*iter)->moveBy(Point(currentX, currentY)); currentX += (*iter)->pos.w; + currentX += freeSpace; prevComp = *(iter++); } @@ -1933,15 +1938,90 @@ void CObjectListWindow::keyPressed (const SDL_KeyboardEvent & key) changeSelection(sel); } -CTradeWindow::CTradeableItem::CTradeableItem( EType Type, int ID, bool Left, int Serial) +CTradeWindow::CTradeableItem::CTradeableItem( EType Type, int ID, bool Left, int Serial): + type(Type), + id(ID), + serial(Serial), + left(Left) { - serial = Serial; - left = Left; - type = Type; - id = ID; addUsedEvents(LCLICK | HOVER | RCLICK); downSelection = false; hlp = NULL; + image = nullptr; +} + +void CTradeWindow::CTradeableItem::setType(EType newType) +{ + if (type != newType) + { + OBJ_CONSTRUCTION_CAPTURING_ALL; + type = newType; + delete image; + + if (getIndex() < 0) + { + image = new CAnimImage(getFilename(), 0); + image->disable(); + } + else + image = new CAnimImage(getFilename(), getIndex()); + } +} + +void CTradeWindow::CTradeableItem::setID(int newID) +{ + if (id != newID) + { + id = newID; + if (image) + { + int index = getIndex(); + if (index < 0) + image->disable(); + else + { + image->enable(); + image->setFrame(index); + } + } + } +} + +std::string CTradeWindow::CTradeableItem::getFilename() +{ + switch(type) + { + case RESOURCE: + return "resource 32"; + case PLAYER: + return "flags"; + case ARTIFACT_TYPE: + case ARTIFACT_PLACEHOLDER: + case ARTIFACT_INSTANCE: + return "artdefs"; + case CREATURE: + return "crtport"; + default: + return ""; + } +} + +int CTradeWindow::CTradeableItem::getIndex() +{ + switch(type) + { + case RESOURCE: + case PLAYER: + return id; + case ARTIFACT_TYPE: + case ARTIFACT_PLACEHOLDER: + case ARTIFACT_INSTANCE: + return id; + case CREATURE: + return id; + default: + return -1; + } } void CTradeWindow::CTradeableItem::showAll(SDL_Surface * to) @@ -1975,8 +2055,11 @@ void CTradeWindow::CTradeableItem::showAll(SDL_Surface * to) break; } - if(SDL_Surface *hlp = getSurface()) - blitAt(hlp, pos + posToBitmap, to); + if (image) + { + image->moveTo(posToBitmap); + image->showAll(to); + } printAtMiddleLoc(subtitle, posToSubCenter, FONT_SMALL, Colors::WHITE, to); } @@ -2006,7 +2089,7 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState) CCS->curh->dragAndDropCursor(new CAnimImage("artifact", art->artType->iconIndex)); aw->arts->artifactsOnAltar.erase(art); - id = -1; + setID(-1); subtitle = ""; aw->deal->block(!aw->arts->artifactsOnAltar.size()); } @@ -2032,25 +2115,6 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState) } } -SDL_Surface * CTradeWindow::CTradeableItem::getSurface() -{ - switch(type) - { - case RESOURCE: - return graphics->resources32->ourImages[id].bitmap; - case PLAYER: - return graphics->flags->ourImages[id].bitmap; - case ARTIFACT_TYPE: - case ARTIFACT_PLACEHOLDER: - case ARTIFACT_INSTANCE: - return id >= 0 ? graphics->artDefs->ourImages[id].bitmap : NULL; - case CREATURE: - return graphics->bigImgs[id]; - default: - return NULL; - } -} - void CTradeWindow::CTradeableItem::showAllAt(const Point &dstPos, const std::string &customSub, SDL_Surface * to) { Rect oldPos = pos; @@ -2146,9 +2210,9 @@ void CTradeWindow::CTradeableItem::setArtInstance(const CArtifactInstance *art) assert(type == ARTIFACT_PLACEHOLDER || type == ARTIFACT_INSTANCE); hlp = art; if(art) - id = art->artType->id; + setID(art->artType->id); else - id = -1; + setID(-1); } CTradeWindow::CTradeWindow(std::string bgName, const IMarket *Market, const CGHeroInstance *Hero, EMarketMode::EMarketMode Mode): @@ -3045,7 +3109,7 @@ void CAltarWindow::makeDeal() BOOST_FOREACH(CTradeableItem *t, items[0]) { - t->type = CREATURE_PLACEHOLDER; + t->setType(CREATURE_PLACEHOLDER); t->subtitle = ""; } } @@ -3059,7 +3123,7 @@ void CAltarWindow::makeDeal() BOOST_FOREACH(CTradeableItem *t, items[0]) { - t->id = -1; + t->setID(-1); t->subtitle = ""; } @@ -3232,7 +3296,7 @@ void CAltarWindow::blockTrade() void CAltarWindow::updateRight(CTradeableItem *toUpdate) { int val = sacrificedUnits[toUpdate->serial]; - toUpdate->type = val ? CREATURE : CREATURE_PLACEHOLDER; + toUpdate->setType(val ? CREATURE : CREATURE_PLACEHOLDER); toUpdate->subtitle = val ? boost::str(boost::format(CGI->generaltexth->allTexts[122]) % boost::lexical_cast(val * expPerUnit[toUpdate->serial])) : ""; //%s exp } diff --git a/client/GUIClasses.h b/client/GUIClasses.h index ee0168819..a24dd9c0c 100644 --- a/client/GUIClasses.h +++ b/client/GUIClasses.h @@ -587,18 +587,23 @@ public: }; class CTradeableItem : public CIntObject { - const CArtifactInstance *hlp; //holds ptr to artifact instance id type artifact + CAnimImage * image; + + std::string getFilename(); + int getIndex(); public: + const CArtifactInstance *hlp; //holds ptr to artifact instance id type artifact EType type; int id; - int serial; - bool left; + const int serial; + const bool left; std::string subtitle; //empty if default + void setType(EType newType); + void setID(int newID); + const CArtifactInstance *getArtInstance() const; void setArtInstance(const CArtifactInstance *art); -// const CArtifact *getArt() const; -// void setArt(const CArtifact *artT) const; CFunctionList callback; bool downSelection; @@ -609,7 +614,6 @@ public: void hover (bool on); void showAll(SDL_Surface * to); void clickLeft(tribool down, bool previousState); - SDL_Surface *getSurface(); std::string getName(int number = -1) const; CTradeableItem(EType Type, int ID, bool Left, int Serial); }; diff --git a/client/UIFramework/CIntObjectClasses.cpp b/client/UIFramework/CIntObjectClasses.cpp index d45fead4a..8ade163ee 100644 --- a/client/UIFramework/CIntObjectClasses.cpp +++ b/client/UIFramework/CIntObjectClasses.cpp @@ -1215,22 +1215,12 @@ void CLabel::showAll(SDL_Surface * to) if(!toPrint.length()) return; - switch (alignment) - { - break; case TOPLEFT : - CIntObject::printAtLoc(toPrint, textOffset.x, textOffset.y, font, color, to); - break; case CENTER : - CIntObject::printAtMiddleLoc(toPrint, textOffset.x, textOffset.y, font, color, to); - break; case BOTTOMRIGHT : - CIntObject::printToLoc(toPrint, textOffset.x, textOffset.y, font, color, to); - break; default : - assert(0); - } + blitLine(to, pos.topLeft()/2 + pos.bottomRight()/2, toPrint); } CLabel::CLabel(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, const SDL_Color &Color /*= Colors::WHITE*/, const std::string &Text /*= ""*/) -:alignment(Align), font(Font), color(Color), text(Text) +:CTextContainer(Align, Font, Color), text(Text) { autoRedraw = true; pos.x += x; @@ -1239,8 +1229,11 @@ CLabel::CLabel(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, con bg = NULL; ignoreLeadingWhitespace = false; - pos.w = graphics->fonts[font]->getStringWidth(text.c_str()); - pos.h = graphics->fonts[font]->getLineHeight(); + if (alignment == TOPLEFT) // causes issues for MIDDLE + { + pos.w = graphics->fonts[font]->getStringWidth(text.c_str()); + pos.h = graphics->fonts[font]->getLineHeight(); + } } std::string CLabel::visibleText() @@ -1276,10 +1269,20 @@ void CBoundedLabel::setTxt(const std::string &Txt) CLabel::setTxt(Txt); } -void CBoundedLabel::blitLine(SDL_Surface *to, Point where, std::string what) +void CTextContainer::blitLine(SDL_Surface *to, Point where, std::string what) { const IFont * f = graphics->fonts[font]; + auto renderer = &IFont::renderTextLeft; + + switch (alignment) + { + break; case TOPLEFT: renderer = &IFont::renderTextLeft; + break; case CENTER: renderer = &IFont::renderTextCenter; + break; case BOTTOMRIGHT: renderer = &IFont::renderTextRight; + break; default: assert(0); + } + size_t begin = 0; size_t end; std::string delimeters = "{}"; @@ -1292,9 +1295,9 @@ void CBoundedLabel::blitLine(SDL_Surface *to, Point where, std::string what) { std::string toPrint = what.substr(begin, end-1); if (currDelimeter % 2) // Enclosed in {} text - set to yellow - graphics->fonts[font]->renderTextLeft(to, toPrint, Colors::YELLOW, where); + (graphics->fonts[font]->*renderer)(to, toPrint, Colors::YELLOW, where); else // Non-enclosed text - graphics->fonts[font]->renderTextLeft(to, toPrint, color, where); + (graphics->fonts[font]->*renderer)(to, toPrint, color, where); begin = end; where.x += f->getStringWidth(toPrint.c_str()); } @@ -1303,6 +1306,12 @@ void CBoundedLabel::blitLine(SDL_Surface *to, Point where, std::string what) while (begin++ != std::string::npos); } +CTextContainer::CTextContainer(EAlignment alignment, EFonts font, SDL_Color color): + alignment(alignment), + font(font), + color(color) +{} + void CBoundedLabel::showAll(SDL_Surface * to) { CIntObject::showAll(to); @@ -1402,7 +1411,8 @@ void CTextBox::showAll(SDL_Surface * to) const IFont * f = graphics->fonts[font]; int dy = f->getLineHeight(); //line height int base_y = pos.y; - if(alignment == CENTER) + + if (alignment == CENTER) base_y += std::max((pos.h - maxH)/2,0); int howManyLinesToPrint = slider ? slider->capacity : lines.size(); @@ -1413,13 +1423,8 @@ void CTextBox::showAll(SDL_Surface * to) const std::string &line = lines[i + firstLineToPrint]; if(!line.size()) continue; - int x = pos.x; - if(alignment == CENTER) - { - x += (pos.w - f->getStringWidth(line.c_str())) / 2; - if(slider) - x -= slider->pos.w / 2 + 5; - } + int width = pos.w + (slider ? (slider->pos.w) : 0); + int x = pos.x + int(alignment) * width / 2; blitLine(to, Point(x, base_y + i * dy), line); } diff --git a/client/UIFramework/CIntObjectClasses.h b/client/UIFramework/CIntObjectClasses.h index fd5580abb..cf23b14d0 100644 --- a/client/UIFramework/CIntObjectClasses.h +++ b/client/UIFramework/CIntObjectClasses.h @@ -329,16 +329,27 @@ public: std::string getCurrent(); //getter for current }; -/// Label which shows text -class CLabel : public virtual CIntObject +class CTextContainer : public virtual CIntObject { protected: - virtual std::string visibleText(); + void blitLine(SDL_Surface * to, Point where, std::string what); + + CTextContainer(EAlignment alignment, EFonts font, SDL_Color color); + //CTextContainer() {}; public: EAlignment alignment; EFonts font; SDL_Color color; +}; + +/// Label which shows text +class CLabel : public CTextContainer +{ +protected: + virtual std::string visibleText(); + +public: std::string text; CPicture *bg; bool autoRedraw; //whether control will redraw itself on setTxt @@ -352,8 +363,6 @@ public: class CBoundedLabel : public CLabel { -protected: - void blitLine(SDL_Surface * to, Point where, std::string what); public: int maxW; //longest line of text in px @@ -421,8 +430,7 @@ public: }; /// UIElement which can get input focus -class CFocusable - : public virtual CIntObject +class CFocusable : public virtual CIntObject { public: bool focus; //only one focusable control can have focus at one moment diff --git a/client/UIFramework/Fonts.h b/client/UIFramework/Fonts.h index cdf3dbe2c..6c53e06b5 100644 --- a/client/UIFramework/Fonts.h +++ b/client/UIFramework/Fonts.h @@ -48,9 +48,6 @@ public: /// pos = bottomright corner of the text void renderTextCenter(SDL_Surface * surface, const std::string & data, const SDL_Color & color, const Point & pos) const; - /** - * @param maxWidth - max width in pixels of one line - */ /// pos = topleft corner of the text void renderTextLinesLeft(SDL_Surface * surface, const std::vector & data, const SDL_Color & color, const Point & pos) const; /// pos = center of the text