Ticket #723: Multiline_centered_text.diff

File Multiline_centered_text.diff, 16.6 KB (added by fcxSanya, 13 years ago)
  • source/gui/CButton.cpp

     
    7676    GUI<float>::GetSetting(this, "buffer_zone", buffer_zone);
    7777    *m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, m_CachedActualSize.GetWidth(), buffer_zone, this);
    7878
    79     CalculateTextPosition(m_CachedActualSize, m_TextPos, *m_GeneratedTexts[0]);
     79    CalculateTextPosition(m_CachedActualSize, m_TextPositions, m_SpritePositions, *m_GeneratedTexts[0], buffer_zone);
    8080}
    8181
    8282void CButton::HandleMessage(const SGUIMessage &Message)
     
    127127               cell_id);
    128128
    129129    CColor color = ChooseColor();
    130     IGUITextOwner::Draw(0, color, m_TextPos, bz+0.1f);
     130    IGUITextOwner::Draw(0, color, m_TextPositions, m_SpritePositions, 0, bz+0.1f);
    131131}
  • source/gui/CButton.h

     
    8484    void SetupText();
    8585
    8686    /**
    87      * Placement of text.
     87     * Placements of text.
    8888     */
    89     CPos m_TextPos;
     89    std::vector<CPos> m_TextPositions;
     90
     91    /**
     92     * Placements of sprites.
     93     */
     94    std::vector<CPos> m_SpritePositions;
    9095};
    9196
    9297#endif
  • source/gui/CCheckBox.cpp

     
    175175    if (square_side > line_height)
    176176        text_pos.y += square_side/2.f - line_height/2.f;
    177177
    178     IGUITextOwner::Draw(0, color, text_pos, bz+0.1f, m_CachedActualSize);
     178    std::vector<CPos> TextPositions, SpritePositions;
     179    TextPositions.push_back(text_pos);
     180    IGUITextOwner::Draw(0, color, TextPositions, SpritePositions, 0, bz+0.1f, m_CachedActualSize);
    179181}
  • source/gui/CDropDown.cpp

     
    337337                       m_CachedActualSize.right-button_width, m_CachedActualSize.bottom);
    338338
    339339        CPos pos(m_CachedActualSize.left, m_CachedActualSize.top);
    340         IGUITextOwner::Draw(selected, color, pos, bz+0.1f, cliparea);
     340        std::vector<CPos> TextPositions, SpritePositions;
     341        TextPositions.push_back(pos);
     342        IGUITextOwner::Draw(selected, color, TextPositions, SpritePositions, 0, bz+0.1f, cliparea);
    341343    }
    342344
    343345    bool *scrollbar=NULL, old;
  • source/gui/CGUI.cpp

     
    932932    return Text;
    933933}
    934934
    935 void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor,
    936                     const CPos &pos, const float &z, const CRect &clipping)
     935void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor,
     936                    const std::vector<CPos> &TextCallPositions,
     937                    const std::vector<CPos> &SpritePositions,
     938                    const float &scroll, const float &z, const CRect &clipping)
    937939{
    938940    // TODO Gee: All these really necessary? Some
    939941    //  are defaults and if you changed them
     
    968970    CFont* font = NULL;
    969971    CStrW LastFontName;
    970972
    971     for (std::vector<SGUIText::STextCall>::const_iterator it = Text.m_TextCalls.begin();
    972          it != Text.m_TextCalls.end();
    973          ++it)
     973    int textPosIndex;
     974    for (unsigned int i = 0; i < Text.m_TextCalls.size(); ++i)
    974975    {
     976        SGUIText::STextCall *TextCall = &(Text.m_TextCalls[i]);
     977        textPosIndex = std::min(i, TextCallPositions.size() - 1);
     978        const CPos *TextPos = &(TextCallPositions[textPosIndex]);
    975979        // If this is just a placeholder for a sprite call, continue
    976         if (it->m_pSpriteCall)
     980        if (TextCall->m_pSpriteCall)
    977981            continue;
    978982
    979983        // Switch fonts when necessary, but remember the last one used
    980         if (it->m_Font != LastFontName)
     984        if (TextCall->m_Font != LastFontName)
    981985        {
    982986            delete font;
    983             font = new CFont(it->m_Font);
     987            font = new CFont(TextCall->m_Font);
    984988            font->Bind();
    985             LastFontName = it->m_Font;
     989            LastFontName = TextCall->m_Font;
    986990        }
    987991
    988         CColor color = it->m_UseCustomColor ? it->m_Color : DefaultColor;
     992        CColor color = TextCall->m_UseCustomColor ? TextCall->m_Color : DefaultColor;
    989993
    990994        glPushMatrix();
    991995
    992996        // TODO Gee: (2004-09-04) Why are font corrupted if inputted float value?
    993         glTranslatef((GLfloat)int(pos.x+it->m_Pos.x), (GLfloat)int(pos.y+it->m_Pos.y), z);
     997        glTranslatef((GLfloat)int(TextPos->x + TextCall->m_Pos.x), (GLfloat)int(TextPos->y + TextCall->m_Pos.y - scroll), z);
    994998        glColor4fv(color.FloatArray());
    995         glwprintf(L"%ls", it->m_String.c_str()); // "%ls" is necessary in case m_String contains % symbols
     999        glwprintf(L"%ls", TextCall->m_String.c_str()); // "%ls" is necessary in case m_String contains % symbols
    9961000
    9971001        glPopMatrix();
    9981002
     
    10011005    if (font)
    10021006        delete font;
    10031007
    1004     for (std::list<SGUIText::SSpriteCall>::iterator it=Text.m_SpriteCalls.begin();
    1005          it!=Text.m_SpriteCalls.end();
     1008    std::list<SGUIText::SSpriteCall>::const_iterator it;
     1009    unsigned int spriteIndex = 0;
     1010    for (it = Text.m_SpriteCalls.begin();
     1011         it != Text.m_SpriteCalls.end();
    10061012         ++it)
    10071013    {
    1008         DrawSprite(it->m_Sprite, it->m_CellID, z, it->m_Area + pos);
     1014        DrawSprite(it->m_Sprite, it->m_CellID, z,
     1015            it->m_Area + SpritePositions[spriteIndex] - CPos(0, scroll));
     1016        if (spriteIndex < SpritePositions.size() - 1) spriteIndex++;
    10091017    }
    10101018
    10111019    // TODO To whom it may concern: Thing were not reset, so
  • source/gui/CGUI.h

     
    158158     * @param clipping
    159159     */
    160160    void DrawText(SGUIText &Text, const CColor &DefaultColor,
    161                   const CPos &pos, const float &z, const CRect &clipping);
     161                  const std::vector<CPos> &TextPositions, const std::vector<CPos> &SpritePositions,
     162                  const float &scroll, const float &z, const CRect &clipping);
    162163
    163164    /**
    164165     * Clean up, call this to clean up all memory allocated
  • source/gui/CList.cpp

     
    380380        CColor color;
    381381        GUI<CColor>::GetSetting(this, _textcolor, color);
    382382
     383        std::vector<CPos> TextPositions;
     384   
    383385        for (int i=0; i<(int)pList->m_Items.size(); ++i)
    384386        {
    385387            if (m_ItemsYPositions[i+1] - scroll < 0 ||
     
    400402                    cliparea.left = GetScrollBar(0).GetOuterRect().right;
    401403            }
    402404
    403             IGUITextOwner::Draw(i, color, rect.TopLeft() - CPos(0.f, scroll - m_ItemsYPositions[i]),
    404                                 bz+0.1f, cliparea);
     405            CPos text_pos(rect.TopLeft() + CPos(0.f, m_ItemsYPositions[i]));
     406            std::vector<CPos> TextPositions, SpritePositions;
     407            TextPositions.push_back(text_pos);
     408            IGUITextOwner::Draw(i, color, TextPositions, SpritePositions, scroll, bz+0.1f, cliparea);
    405409        }
    406410    }
    407411}
  • source/gui/CText.cpp

     
    9797    GUI<float>::GetSetting(this, "buffer_zone", buffer_zone);
    9898    *m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, width, buffer_zone, this);
    9999
    100     if (! scrollbar)
    101         CalculateTextPosition(m_CachedActualSize, m_TextPos, *m_GeneratedTexts[0]);
     100    CalculateTextPosition(m_CachedActualSize, m_TextPositions, m_SpritePositions, *m_GeneratedTexts[0], buffer_zone);
    102101
    103102    // Setup scrollbar
    104103    if (scrollbar)
     
    240239        CColor color;
    241240        GUI<CColor>::GetSetting(this, "textcolor", color);
    242241
    243         // Draw text
    244         if (scrollbar)
    245             IGUITextOwner::Draw(0, color, m_CachedActualSize.TopLeft() - CPos(0.f, scroll), bz+0.1f, cliparea);
    246         else
    247             IGUITextOwner::Draw(0, color, m_TextPos, bz+0.1f, cliparea);
     242        IGUITextOwner::Draw(0, color, m_TextPositions, m_SpritePositions, scroll, bz+0.1f, cliparea);
    248243    }
    249244}
    250245
  • source/gui/CText.h

     
    9191    virtual void Draw();
    9292
    9393    /**
    94      * Placement of text. Ignored when scrollbars are active.
     94     * Placements of text.
    9595     */
    96     CPos m_TextPos;
     96    std::vector<CPos> m_TextPositions;
     97
     98    /**
     99     * Placements of sprites.
     100     */
     101    std::vector<CPos> m_SpritePositions;
    97102};
    98103
    99104#endif
  • source/gui/CTooltip.cpp

     
    160160        GUI<CColor>::GetSetting(this, "textcolor", color);
    161161
    162162        // Draw text
    163         IGUITextOwner::Draw(0, color, m_CachedActualSize.TopLeft(), z+0.1f);
     163        std::vector<CPos> TextPositions, SpritePositions;
     164        TextPositions.push_back(m_CachedActualSize.TopLeft());
     165        IGUITextOwner::Draw(0, color, TextPositions, SpritePositions, 0, z+0.1f);
    164166    }
    165167}
  • source/gui/IGUITextOwner.cpp

     
    7878    m_GeneratedTextsValid = false;
    7979}
    8080
    81 void IGUITextOwner::Draw(const int &index, const CColor &color, const CPos &pos,
    82                          const float &z, const CRect &clipping)
     81void IGUITextOwner::Draw(const int &index, const CColor &color,
     82                         const std::vector<CPos> &TextPositions, const std::vector<CPos> &SpritePositions,
     83                         const float &scroll, const float &z, const CRect &clipping)
    8384{
    8485    if (!m_GeneratedTextsValid)
    8586    {
     
    9596
    9697    if (GetGUI())
    9798    {
    98         GetGUI()->DrawText(*m_GeneratedTexts[index], color, pos, z, clipping);
     99        GetGUI()->DrawText(*m_GeneratedTexts[index], color, TextPositions, SpritePositions, scroll, z, clipping);
    99100    }
    100101}
    101102
    102 void IGUITextOwner::CalculateTextPosition(CRect &ObjSize, CPos &TextPos, SGUIText &Text)
     103void IGUITextOwner::CalculateTextPosition(CRect &ObjSize, std::vector<CPos> &TextPositions,
     104                                          std::vector<CPos> &SpritePositions, SGUIText &Text, float &buffer_zone)
    103105{
    104106    EAlign align;
    105107    EVAlign valign;
    106108    GUI<EAlign>::GetSetting(this, "text_align", align);
    107109    GUI<EVAlign>::GetSetting(this, "text_valign", valign);
    108110
    109     switch (align)
     111    if (Text.m_TextCalls.size() == 0 && Text.m_SpriteCalls.size() == 0)
    110112    {
    111     case EAlign_Left:
    112         TextPos.x = ObjSize.left;
    113         break;
    114     case EAlign_Center:
    115         // Round to integer pixel values, else the fonts look awful
    116         TextPos.x = floorf(ObjSize.CenterPoint().x - Text.m_Size.cx/2.f);
    117         break;
    118     case EAlign_Right:
    119         TextPos.x = ObjSize.right - Text.m_Size.cx;
    120         break;
    121     default:
    122         debug_warn(L"Broken EAlign in CButton::SetupText()");
    123         break;
     113        TextPositions.clear();
     114        SpritePositions.clear();
     115        return;
    124116    }
    125117
    126     switch (valign)
     118    // In case of align == EAlign_Center or align == EAlign_Center
     119    // we need additional preparations
     120    // XBounds - map of bounds of x coordinate for each line of text
     121    // key - y value of TextCall position
     122    // value - pair of min and max x values for this line
     123    std::map<float, std::pair<float, float>> xBounds;
     124    if (align == EAlign_Center || align == EAlign_Right)
    127125    {
    128     case EVAlign_Top:
    129         TextPos.y = ObjSize.top;
    130         break;
    131     case EVAlign_Center:
    132         // Round to integer pixel values, else the fonts look awful
    133         TextPos.y = floorf(ObjSize.CenterPoint().y - Text.m_Size.cy/2.f);
    134         break;
    135     case EVAlign_Bottom:
    136         TextPos.y = ObjSize.bottom - Text.m_Size.cy;
    137         break;
    138     default:
    139         debug_warn(L"Broken EVAlign in CButton::SetupText()");
    140         break;
     126        for (std::vector<SGUIText::STextCall>::const_iterator it = Text.m_TextCalls.begin();
     127            it != Text.m_TextCalls.end();
     128            ++it)
     129        {
     130            float xLeft = it->m_Pos.x;
     131            float xRight = it->m_Pos.x + it->m_Size.cx;
     132            if (xBounds.find(it->m_Pos.y) != xBounds.end())
     133            {
     134                float *xMin = &(xBounds[it->m_Pos.y].first);
     135                float *xMax = &(xBounds[it->m_Pos.y].second);
     136               
     137                if (xLeft < *xMin) *xMin = xLeft;
     138                if (xRight > *xMax) *xMax = xRight;
     139            }
     140            else
     141            {
     142                xBounds[it->m_Pos.y] = std::make_pair<float, float>(xLeft, xRight);
     143            }
     144        }
     145
     146        for (std::list<SGUIText::SSpriteCall>::const_iterator it = Text.m_SpriteCalls.begin();
     147            it != Text.m_SpriteCalls.end();
     148            ++it)
     149        {
     150            float xLeft = it->m_Area.left;
     151            float xRight = it->m_Area.right;
     152            if (xBounds.find(it->m_Area.top) != xBounds.end())
     153            {
     154                float *xMin = &(xBounds[it->m_Area.top].first);
     155                float *xMax = &(xBounds[it->m_Area.top].second);
     156               
     157                if (xLeft < *xMin) *xMin = xLeft;
     158                if (xRight > *xMax) *xMax = xRight;
     159            }
     160            else
     161            {
     162                xBounds[it->m_Area.top] = std::make_pair<float, float>(xLeft, xRight);
     163            }
     164        }
    141165    }
     166
     167    if (Text.m_TextCalls.size() == 0)
     168    {
     169        TextPositions.clear();
     170    }
     171    else
     172    {
     173        TextPositions.resize(Text.m_TextCalls.size());
     174        CPos *TextPos;
     175        std::pair<float, float> bounds;
     176        float lineWidth;
     177        for (unsigned int i = 0; i < Text.m_TextCalls.size(); ++i)
     178        {
     179            TextPos = &(TextPositions[i]);
     180            switch (align)
     181            {
     182            case EAlign_Left:
     183                TextPos->x = ObjSize.left;
     184                break;
     185            case EAlign_Center:
     186                bounds = xBounds[Text.m_TextCalls[i].m_Pos.y];
     187                lineWidth = bounds.second - bounds.first;
     188                TextPos->x = ObjSize.CenterPoint().x - buffer_zone - lineWidth / 2.f;
     189                break;
     190            case EAlign_Right:
     191                bounds = xBounds[Text.m_TextCalls[i].m_Pos.y];
     192                TextPos->x = ObjSize.right - bounds.second - buffer_zone;
     193                break;
     194            default:
     195                debug_warn(L"Broken EAlign in IGUITextOwner::CalculateTextPosition()");
     196                break;
     197            }
     198
     199            switch (valign)
     200            {
     201            case EVAlign_Top:
     202                TextPos->y = ObjSize.top;
     203                break;
     204            case EVAlign_Center:
     205                // if text height is less than object height
     206                // then center it, else stick text to object's top
     207                if (ObjSize.GetHeight() > Text.m_Size.cy)
     208                {
     209                    // Round to integer pixel values, else the fonts look awful
     210                    TextPos->y = floorf(ObjSize.CenterPoint().y - Text.m_Size.cy/2.f);
     211                }
     212                else
     213                {
     214                    TextPos->y = ObjSize.top;
     215                }
     216                break;
     217            case EVAlign_Bottom:
     218                // if text height is less than object height
     219                // then stick text to oblects bottom, else stick it top
     220                if (ObjSize.GetHeight() > Text.m_Size.cy)
     221                {
     222                    TextPos->y = ObjSize.bottom - Text.m_Size.cy;
     223                }
     224                else
     225                {
     226                    TextPos->y = ObjSize.top;
     227                }
     228                break;
     229            default:
     230                debug_warn(L"Broken EVAlign in IGUITextOwner::CalculateTextPosition()");
     231                break;
     232            }
     233        }
     234    }
     235
     236    if (Text.m_SpriteCalls.size() == 0)
     237    {
     238        SpritePositions.clear();
     239    }
     240    else
     241    {
     242        CPos *SpritePos;
     243
     244        SpritePositions.resize(Text.m_SpriteCalls.size());
     245
     246        std::list<SGUIText::SSpriteCall>::const_iterator it;
     247        unsigned int i = 0;
     248        for (it = Text.m_SpriteCalls.begin();
     249             it != Text.m_SpriteCalls.end();
     250             ++it)
     251        {
     252            SpritePos = &(SpritePositions[i]);
     253            switch (align)
     254            {
     255            case EAlign_Left:
     256                SpritePos->x = ObjSize.left;
     257                break;
     258            case EAlign_Center:
     259                {
     260                std::pair<float, float> bounds = xBounds[it->m_Area.top];
     261                float lineWidth = bounds.second - bounds.first;
     262                float lineLeft = ObjSize.CenterPoint().x - lineWidth / 2.f;
     263                SpritePos->x = lineLeft;
     264                break;
     265                }
     266            case EAlign_Right:
     267                SpritePos->x = ObjSize.right - Text.m_Size.cx;
     268                break;
     269            default:
     270                debug_warn(L"Broken EAlign in CButton::SetupText()");
     271                break;
     272            }
     273
     274            switch (valign)
     275            {
     276            case EVAlign_Top:
     277                SpritePos->y = ObjSize.top;
     278                break;
     279            case EVAlign_Center:
     280                // Round to integer pixel values, else the fonts look awful
     281                SpritePos->y = floorf(ObjSize.CenterPoint().y - Text.m_Size.cy/2.f);
     282                break;
     283            case EVAlign_Bottom:
     284                SpritePos->y = ObjSize.bottom - Text.m_Size.cy;
     285                break;
     286            default:
     287                debug_warn(L"Broken EVAlign in CButton::SetupText()");
     288                break;
     289            }
     290            ++i;
     291        }
     292    }
    142293}
    143294
    144295bool IGUITextOwner::MouseOverIcon()
  • source/gui/IGUITextOwner.h

     
    8888     * @param clipping Clipping rectangle, don't even add a parameter
    8989     *        to get no clipping.
    9090     */
    91     virtual void Draw(const int &index, const CColor &color, const CPos &pos,
    92                       const float &z, const CRect &clipping = CRect());
     91    virtual void Draw(const int &index, const CColor &color,
     92                      const std::vector<CPos> &TextPositions, const std::vector<CPos> &SpritePositions,
     93                      const float &scroll, const float &z, const CRect &clipping = CRect());
    9394
    9495    /**
    9596     * Test if mouse position is over an icon
     
    116117    /**
    117118     * Calculate the position for the text, based on the alignment.
    118119     */
    119     void CalculateTextPosition(CRect &ObjSize, CPos &TextPos, SGUIText &Text);
     120    void CalculateTextPosition(CRect &ObjSize, std::vector<CPos> &TextPositions, std::vector<CPos> &SpritePositions, SGUIText &Text, float &buffer_zone);
    120121};
    121122
    122123#endif