Line data Source code
1 : /* Copyright (C) 2021 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. 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 : * 0 A.D. 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 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 :
20 : #include "CText.h"
21 :
22 : #include "gui/CGUI.h"
23 : #include "gui/CGUIScrollBarVertical.h"
24 : #include "gui/CGUIText.h"
25 :
26 0 : CText::CText(CGUI& pGUI)
27 : : IGUIObject(pGUI),
28 : IGUIScrollBarOwner(*static_cast<IGUIObject*>(this)),
29 : IGUITextOwner(*static_cast<IGUIObject*>(this)),
30 : m_BufferZone(this, "buffer_zone"),
31 : m_Caption(this, "caption"),
32 : m_Clip(this, "clip", true),
33 : m_Font(this, "font"),
34 : m_ScrollBar(this, "scrollbar", false),
35 : m_ScrollBarStyle(this, "scrollbar_style"),
36 : m_ScrollBottom(this, "scroll_bottom"),
37 : m_ScrollTop(this, "scroll_top"),
38 : m_Sprite(this, "sprite"),
39 : m_SpriteOverlay(this, "sprite_overlay"),
40 : m_TextColor(this, "textcolor"),
41 0 : m_TextColorDisabled(this, "textcolor_disabled")
42 : {
43 : // Add scroll-bar
44 0 : auto bar = std::make_unique<CGUIScrollBarVertical>(pGUI);
45 0 : bar->SetRightAligned(true);
46 0 : AddScrollBar(std::move(bar));
47 :
48 : // Add text
49 0 : AddText();
50 0 : }
51 :
52 0 : CText::~CText()
53 : {
54 0 : }
55 :
56 0 : void CText::SetupText()
57 : {
58 0 : if (m_GeneratedTexts.empty())
59 0 : return;
60 :
61 0 : float width = m_CachedActualSize.GetWidth();
62 : // remove scrollbar if applicable
63 0 : if (m_ScrollBar && GetScrollBar(0).GetStyle())
64 0 : width -= GetScrollBar(0).GetStyle()->m_Width;
65 :
66 0 : m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, width, m_BufferZone, m_TextAlign, this);
67 :
68 0 : if (!m_ScrollBar)
69 0 : CalculateTextPosition(m_CachedActualSize, m_TextPos, m_GeneratedTexts[0]);
70 :
71 : // Setup scrollbar
72 0 : if (m_ScrollBar)
73 : {
74 : // If we are currently scrolled to the bottom of the text,
75 : // then add more lines of text, update the scrollbar so we
76 : // stick to the bottom.
77 : // (Use 1.5px delta so this triggers the first time caption is set)
78 0 : bool bottom = false;
79 0 : if (m_ScrollBottom && GetScrollBar(0).GetPos() > GetScrollBar(0).GetMaxPos() - 1.5f)
80 0 : bottom = true;
81 :
82 0 : GetScrollBar(0).SetScrollRange(m_GeneratedTexts[0].GetSize().Height);
83 0 : GetScrollBar(0).SetScrollSpace(m_CachedActualSize.GetHeight());
84 :
85 0 : GetScrollBar(0).SetX(m_CachedActualSize.right);
86 0 : GetScrollBar(0).SetY(m_CachedActualSize.top);
87 0 : GetScrollBar(0).SetZ(GetBufferedZ());
88 0 : GetScrollBar(0).SetLength(m_CachedActualSize.bottom - m_CachedActualSize.top);
89 :
90 0 : if (bottom)
91 0 : GetScrollBar(0).SetPos(GetScrollBar(0).GetMaxPos());
92 :
93 0 : if (m_ScrollTop)
94 0 : GetScrollBar(0).SetPos(0.0f);
95 : }
96 : }
97 :
98 0 : void CText::ResetStates()
99 : {
100 0 : IGUIObject::ResetStates();
101 0 : IGUIScrollBarOwner::ResetStates();
102 0 : }
103 :
104 0 : void CText::UpdateCachedSize()
105 : {
106 0 : IGUIObject::UpdateCachedSize();
107 0 : IGUITextOwner::UpdateCachedSize();
108 0 : }
109 :
110 0 : CSize2D CText::GetTextSize()
111 : {
112 0 : UpdateText();
113 0 : return m_GeneratedTexts[0].GetSize();
114 : }
115 :
116 0 : const CStrW& CText::GetTooltipText() const
117 : {
118 0 : for (const CGUIText& text : m_GeneratedTexts)
119 0 : for (const CGUIText::STextCall& textChunk : text.GetTextCalls())
120 : {
121 0 : if (textChunk.m_Tooltip.empty())
122 0 : continue;
123 0 : CRect area(textChunk.m_Pos - CVector2D(0.f, textChunk.m_Size.Height), textChunk.m_Size);
124 0 : if (area.PointInside(m_pGUI.GetMousePos() - m_CachedActualSize.TopLeft()))
125 0 : return textChunk.m_Tooltip;
126 : }
127 0 : return m_Tooltip;
128 : }
129 :
130 0 : void CText::HandleMessage(SGUIMessage& Message)
131 : {
132 0 : IGUIObject::HandleMessage(Message);
133 0 : IGUIScrollBarOwner::HandleMessage(Message);
134 : //IGUITextOwner::HandleMessage(Message); <== placed it after the switch instead!
135 :
136 0 : switch (Message.type)
137 : {
138 0 : case GUIM_SETTINGS_UPDATED:
139 0 : if (Message.value == "scrollbar")
140 0 : SetupText();
141 :
142 : // Update scrollbar
143 0 : if (Message.value == "scrollbar_style")
144 : {
145 0 : GetScrollBar(0).SetScrollBarStyle(m_ScrollBarStyle);
146 0 : SetupText();
147 : }
148 :
149 0 : break;
150 :
151 0 : case GUIM_MOUSE_WHEEL_DOWN:
152 : {
153 0 : GetScrollBar(0).ScrollPlus();
154 : // Since the scroll was changed, let's simulate a mouse movement
155 : // to check if scrollbar now is hovered
156 0 : SGUIMessage msg(GUIM_MOUSE_MOTION);
157 0 : HandleMessage(msg);
158 0 : break;
159 : }
160 0 : case GUIM_MOUSE_WHEEL_UP:
161 : {
162 0 : GetScrollBar(0).ScrollMinus();
163 : // Since the scroll was changed, let's simulate a mouse movement
164 : // to check if scrollbar now is hovered
165 0 : SGUIMessage msg(GUIM_MOUSE_MOTION);
166 0 : HandleMessage(msg);
167 0 : break;
168 : }
169 0 : case GUIM_LOAD:
170 : {
171 0 : GetScrollBar(0).SetX(m_CachedActualSize.right);
172 0 : GetScrollBar(0).SetY(m_CachedActualSize.top);
173 0 : GetScrollBar(0).SetZ(GetBufferedZ());
174 0 : GetScrollBar(0).SetLength(m_CachedActualSize.bottom - m_CachedActualSize.top);
175 0 : GetScrollBar(0).SetScrollBarStyle(m_ScrollBarStyle);
176 0 : break;
177 : }
178 :
179 0 : default:
180 0 : break;
181 : }
182 :
183 0 : IGUITextOwner::HandleMessage(Message);
184 0 : }
185 :
186 0 : void CText::Draw(CCanvas2D& canvas)
187 : {
188 0 : m_pGUI.DrawSprite(m_Sprite, canvas, m_CachedActualSize);
189 :
190 0 : float scroll = 0.f;
191 0 : if (m_ScrollBar)
192 0 : scroll = GetScrollBar(0).GetPos();
193 :
194 : // Clipping area (we'll have to subtract the scrollbar)
195 0 : CRect cliparea;
196 0 : if (m_Clip)
197 : {
198 0 : cliparea = m_CachedActualSize;
199 :
200 0 : if (m_ScrollBar)
201 : {
202 : // subtract scrollbar from cliparea
203 0 : if (cliparea.right > GetScrollBar(0).GetOuterRect().left &&
204 0 : cliparea.right <= GetScrollBar(0).GetOuterRect().right)
205 0 : cliparea.right = GetScrollBar(0).GetOuterRect().left;
206 :
207 0 : if (cliparea.left >= GetScrollBar(0).GetOuterRect().left &&
208 0 : cliparea.left < GetScrollBar(0).GetOuterRect().right)
209 0 : cliparea.left = GetScrollBar(0).GetOuterRect().right;
210 : }
211 : }
212 :
213 0 : const CGUIColor& color = m_Enabled ? m_TextColor : m_TextColorDisabled;
214 :
215 0 : if (m_ScrollBar)
216 0 : DrawText(canvas, 0, color, m_CachedActualSize.TopLeft() - CVector2D(0.f, scroll), cliparea);
217 : else
218 0 : DrawText(canvas, 0, color, m_TextPos, cliparea);
219 :
220 : // Draw scrollbars on top of the content
221 0 : if (m_ScrollBar)
222 0 : IGUIScrollBarOwner::Draw(canvas);
223 :
224 : // Draw the overlays last
225 0 : m_pGUI.DrawSprite(m_SpriteOverlay, canvas, m_CachedActualSize);
226 0 : }
|