1 /*
2  *  This file is part of Dune Legacy.
3  *
4  *  Dune Legacy is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Dune Legacy is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Dune Legacy.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <GUI/TextView.h>
19 
20 #include <misc/string_util.h>
21 
22 #include <algorithm>
23 
TextView()24 TextView::TextView() : Widget() {
25     enableResizing(true,true);
26 
27     resize(getMinimumSize().x,getMinimumSize().y);
28 }
29 
~TextView()30 TextView::~TextView() {
31     invalidateTextures();
32 }
33 
handleMouseMovement(Sint32 x,Sint32 y,bool insideOverlay)34 void TextView::handleMouseMovement(Sint32 x, Sint32 y, bool insideOverlay) {
35     scrollbar.handleMouseMovement(x - getSize().x + scrollbar.getSize().x,y,insideOverlay);
36 }
37 
handleMouseLeft(Sint32 x,Sint32 y,bool pressed)38 bool TextView::handleMouseLeft(Sint32 x, Sint32 y, bool pressed) {
39     return scrollbar.handleMouseLeft(x - getSize().x + scrollbar.getSize().x,y,pressed);
40 }
41 
handleMouseWheel(Sint32 x,Sint32 y,bool up)42 bool TextView::handleMouseWheel(Sint32 x, Sint32 y, bool up)  {
43     // forward mouse wheel event to scrollbar
44     return scrollbar.handleMouseWheel(0,0,up);
45 }
46 
handleKeyPress(SDL_KeyboardEvent & key)47 bool TextView::handleKeyPress(SDL_KeyboardEvent& key) {
48     Widget::handleKeyPress(key);
49 
50     scrollbar.handleKeyPress(key);
51     return true;
52 }
53 
draw(Point position)54 void TextView::draw(Point position) {
55     if(isVisible() == false) {
56         return;
57     }
58 
59     updateTextures();
60 
61     if(pBackground != nullptr) {
62         SDL_Rect dest = calcDrawingRect(pBackground, position.x, position.y);
63         SDL_RenderCopy(renderer, pBackground, nullptr, &dest);
64     }
65 
66     if(pForeground != nullptr) {
67         int lineHeight = GUIStyle::getInstance().getTextHeight(fontID) + 2;
68 
69         SDL_Rect src = {    0,
70                             scrollbar.getCurrentValue() * lineHeight,
71                             getWidth(pForeground),
72                             std::min(getHeight(pForeground), getSize().y - 2) };
73 
74         SDL_Rect dest = {   position.x + 2,
75                             position.y + 1,
76                             getWidth(pForeground),
77                             std::min(getHeight(pForeground), getSize().y - 2) };
78         SDL_RenderCopy(renderer, pForeground, &src, &dest);
79     }
80 
81     Point scrollBarPos = position;
82     scrollBarPos.x += getSize().x - scrollbar.getSize().x;
83 
84     if(!bAutohideScrollbar || (scrollbar.getRangeMin() != scrollbar.getRangeMax())) {
85         scrollbar.draw(scrollBarPos);
86     }
87 }
88 
resize(Uint32 width,Uint32 height)89 void TextView::resize(Uint32 width, Uint32 height) {
90     invalidateTextures();
91 
92     scrollbar.resize(scrollbar.getMinimumSize().x,height);
93 
94     int fontID = this->fontID;
95     std::vector<std::string> textLines = greedyWordWrap(text,
96                                                         getSize().x - scrollbar.getSize().x - 4,
97                                                         [fontID](const std::string& tmp) {
98                                                             return GUIStyle::getInstance().getMinimumLabelSize(tmp, fontID).x - 4;
99                                                         });
100 
101     int lineHeight = GUIStyle::getInstance().getTextHeight(fontID) + 2;
102 
103     int numVisibleLines = height/lineHeight;
104     scrollbar.setRange(0,std::max(0, ((int) textLines.size()) - numVisibleLines));
105     scrollbar.setBigStepSize(std::max(1, numVisibleLines-1));
106 
107     Widget::resize(width,height);
108 }
109 
updateTextures()110 void TextView::updateTextures() {
111     if(pBackground == nullptr) {
112         pBackground = convertSurfaceToTexture(GUIStyle::getInstance().createWidgetBackground(getSize().x, getSize().y), true);
113     }
114 
115     if(pForeground == nullptr) {
116         int fontID = this->fontID;
117         std::vector<std::string> textLines = greedyWordWrap(text,
118                                                             getSize().x - scrollbar.getSize().x - 4,
119                                                             [fontID](const std::string& tmp) {
120                                                                 return GUIStyle::getInstance().getMinimumLabelSize(tmp, fontID).x - 4;
121                                                             });
122 
123         int lineHeight = GUIStyle::getInstance().getTextHeight(fontID) + 2;
124         int labelHeight = lineHeight * textLines.size() + 2;
125         pForeground = convertSurfaceToTexture(GUIStyle::getInstance().createLabelSurface(getSize().x-4,labelHeight,textLines,fontID,alignment,textcolor,textshadowcolor,backgroundcolor), true);
126     }
127 }
128