1 /*
2  * This file is part of the Colobot: Gold Edition source code
3  * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
4  * http://epsitec.ch; http://colobot.info; http://github.com/colobot
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see http://gnu.org/licenses
18  */
19 
20 
21 #include "ui/mainmap.h"
22 
23 #include "app/app.h"
24 
25 #include "level/robotmain.h"
26 
27 #include "ui/controls/interface.h"
28 #include "ui/controls/map.h"
29 #include "ui/controls/scroll.h"
30 #include "ui/controls/slider.h"
31 #include "ui/controls/window.h"
32 
33 
34 namespace Ui
35 {
36 
37 
38 const float ZOOM_MIN = 1.0f;
39 const float ZOOM_MAX = 16.0f;
40 
41 
42 // Constructor of the application card.
43 
CMainMap()44 CMainMap::CMainMap()
45 {
46     m_interface = CRobotMain::GetInstancePointer()->GetInterface();
47     m_event     = CApplication::GetInstancePointer()->GetEventQueue();
48     m_engine    = Gfx::CEngine::GetInstancePointer();
49 
50     m_bFixImage = false;
51 }
52 
53 // Destructor of the application card.
54 
~CMainMap()55 CMainMap::~CMainMap()
56 {
57 }
58 
59 
60 // Created the mini-map and the corresponding buttons.
61 
CreateMap()62 void CMainMap::CreateMap()
63 {
64     CWindow*    pw;
65     Math::Point     pos, dim;
66 
67     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
68     if (pw == nullptr)
69     {
70         pos.x = 0.0f;
71         pos.y = 0.0f;
72         dim.x = 0.0f;
73         dim.y = 0.0f;
74         pw = m_interface->CreateWindows(pos, dim, 10, EVENT_WINDOW1);
75     }
76 
77     dim.x = 10.0f / 640.0f;
78     dim.y = 10.0f / 480.0f;
79     pos.x = 10.0f / 640.0f;
80     pos.y = 10.0f / 480.0f;
81     pw->CreateMap   (pos, dim, 2, EVENT_OBJECT_MAP);
82     pw->CreateSlider(pos, dim, 0, EVENT_OBJECT_MAPZOOM);
83 
84     DimMap();
85 }
86 
87 // Indicates whether the mini-map should display a still image.
88 
SetFixImage(const char * filename)89 void CMainMap::SetFixImage(const char *filename)
90 {
91     CWindow*    pw;
92     CMap*       pm;
93 
94     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
95     if (pw == nullptr)
96         return;
97 
98     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
99     if (pm == nullptr)
100         return;
101 
102     pw->DeleteControl(EVENT_OBJECT_MAPZOOM);
103     m_bFixImage = true;
104 
105     pm->SetFixImage(filename);
106 }
107 
108 // Choosing colors of soil and water for the mini-map.
109 
FloorColorMap(Gfx::Color floor,Gfx::Color water)110 void CMainMap::FloorColorMap(Gfx::Color floor, Gfx::Color water)
111 {
112     CWindow*    pw;
113     CMap*       pm;
114 
115     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
116     if (pw == nullptr)
117         return;
118 
119     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
120     if (pm != nullptr)
121     {
122         pm->SetFloorColor(floor);
123         pm->SetWaterColor(water);
124     }
125 }
126 
127 // Shows or hides the minimap.
128 
ShowMap(bool bShow)129 void CMainMap::ShowMap(bool bShow)
130 {
131     CWindow*    pw;
132     CMap*       pm;
133     CSlider*    ps;
134 
135     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
136     if (pw == nullptr)
137         return;
138 
139 
140     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
141     if (pm != nullptr)
142         pm->SetState(STATE_VISIBLE, bShow);
143 
144     ps = static_cast<CSlider*>(pw->SearchControl(EVENT_OBJECT_MAPZOOM));
145     if (ps != nullptr)
146         ps->SetState(STATE_VISIBLE, bShow);
147 
148     if (bShow)
149     {
150         DimMap();
151     }
152 }
153 
154 // Dimensions of the mini-map.
155 
DimMap()156 void CMainMap::DimMap()
157 {
158     CWindow*    pw;
159     CMap*       pm;
160     CSlider*    ps;
161     Math::Point     pos, dim;
162     float       value;
163 
164     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
165     if (pw == nullptr)
166         return;
167     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
168     if (pm == nullptr)
169         return;
170 
171     dim.x = 100.0f/640.0f;
172     dim.y = 100.0f/480.0f;
173     pos.x = 540.0f/640.0f;
174     pos.y =   0.0f/480.0f;
175     pm->SetPos(pos);
176     pm->SetDim(dim);
177 
178     ps = static_cast<CSlider*>(pw->SearchControl(EVENT_OBJECT_MAPZOOM));
179     if (ps != nullptr)
180     {
181         dim.x = SCROLL_WIDTH;
182         dim.y =  66.0f / 480.0f;
183         pos.x = 523.0f / 640.0f;
184         pos.y =   3.0f / 480.0f;
185         ps->SetPos(pos);
186         ps->SetDim(dim);
187 
188         value = pm->GetZoom();
189         value = (value-ZOOM_MIN) / (ZOOM_MAX-ZOOM_MIN);
190         value = powf(value, 0.5f);
191         ps->SetVisibleValue(value);
192         ps->SetArrowStep(0.2f);
193     }
194 }
195 
196 // Returns the current zoom of the minimap.
197 
GetZoomMap()198 float CMainMap::GetZoomMap()
199 {
200     CWindow*    pw;
201     CMap*       pm;
202     CSlider*    ps;
203 
204     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
205     if (pw == nullptr)
206         return ZOOM_MIN;
207 
208     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
209     if (pm == nullptr)
210         return ZOOM_MIN;
211 
212     ps = static_cast<CSlider*>(pw->SearchControl(EVENT_OBJECT_MAPZOOM));
213     if (ps == nullptr)
214         return ZOOM_MIN;
215 
216     return pm->GetZoom();
217 }
218 
219 // Zoom the mini-map of any factor.
220 
ZoomMap(float zoom)221 void CMainMap::ZoomMap(float zoom)
222 {
223     CWindow*    pw;
224     CMap*       pm;
225     CSlider*    ps;
226 
227     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
228     if (pw == nullptr)
229         return;
230     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
231     if (pm == nullptr)
232         return;
233 
234     ps = static_cast<CSlider*>(pw->SearchControl(EVENT_OBJECT_MAPZOOM));
235     if (ps == nullptr)
236         return;
237 
238     if (zoom < ZOOM_MIN)
239         zoom = ZOOM_MIN;
240     if (zoom > ZOOM_MAX)
241         zoom = ZOOM_MAX;
242     pm->SetZoom(zoom);
243 
244     DimMap();
245 }
246 
247 // The mini-map zoom depending on the slider.
248 
ZoomMap()249 void CMainMap::ZoomMap()
250 {
251     CWindow*    pw;
252     CMap*       pm;
253     CSlider*    ps;
254     float       zoom;
255 
256     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
257     if (pw == nullptr)
258         return;
259     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
260     if (pm == nullptr)
261         return;
262 
263     ps = static_cast<CSlider*>(pw->SearchControl(EVENT_OBJECT_MAPZOOM));
264     if (ps == nullptr)
265         return;
266 
267 
268     zoom = ps->GetVisibleValue();
269     zoom = powf(zoom, 2.0f);
270     zoom = ZOOM_MIN+zoom*(ZOOM_MAX - ZOOM_MIN);
271     pm->SetZoom(zoom);
272 
273     DimMap();
274 }
275 
276 // Enables or disables the card.
277 
MapEnable(bool bEnable)278 void CMainMap::MapEnable(bool bEnable)
279 {
280     CWindow*    pw;
281     CMap*       pm;
282     CSlider*    ps;
283 
284     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
285     if (pw == nullptr)
286         return;
287 
288     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
289     if (pm != nullptr)
290         pm->SetEnable(bEnable);
291 
292     ps = static_cast<CSlider*>(pw->SearchControl(EVENT_OBJECT_MAPZOOM));
293     if (ps != nullptr)
294         ps->SetState(STATE_ENABLE, bEnable);
295 }
296 
297 // Specifies the type of icon for the selected object.
298 
SetToy(bool bToy)299 void CMainMap::SetToy(bool bToy)
300 {
301     CWindow*    pw;
302     CMap*       pm;
303 
304     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
305     if (pw == nullptr)
306         return;
307 
308     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
309     if (pm == nullptr)
310         return;
311 
312     pm->SetToy(bToy);
313 }
314 
315 // Specifies the parameters when using a still image.
316 
SetFixParam(float zoom,float ox,float oy,float angle,int mode,bool bDebug)317 void CMainMap::SetFixParam(float zoom, float ox, float oy, float angle,
318                            int mode, bool bDebug)
319 {
320     CWindow*    pw;
321     CMap*       pm;
322 
323     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
324     if (pw == nullptr)
325         return;
326 
327     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
328     if (pm == nullptr)
329         return;
330 
331     pm->SetZoom(zoom);
332     pm->SetOffset(ox, oy);
333     pm->SetAngle(angle);
334     pm->SetMode(mode);
335     pm->SetDebug(bDebug);
336 }
337 
338 // Updates the mini-map following to a change of terrain.
339 
UpdateMap()340 void CMainMap::UpdateMap()
341 {
342     CWindow*    pw;
343     CMap*       pm;
344 
345     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
346     if (pw == nullptr)
347         return;
348 
349     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
350     if (pm != nullptr)
351         pm->UpdateTerrain();
352 }
353 
354 // Indicates whether the mini-map displays a still image.
355 
GetFixImage()356 bool CMainMap::GetFixImage()
357 {
358     return m_bFixImage;
359 }
360 
361 
362 // The object is detected in the mini-map.
363 
DetectMap(Math::Point pos,bool & bInMap)364 CObject* CMainMap::DetectMap(Math::Point pos, bool &bInMap)
365 {
366     CWindow*    pw;
367     CMap*       pm;
368 
369     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
370     if (pw == nullptr)
371         return nullptr;
372 
373     bInMap = false;
374     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
375     if (pm == nullptr)
376         return nullptr;
377     return pm->DetectObject(pos, bInMap);
378 }
379 
380 
381 // Indicates the object with the mouse hovers over.
382 
SetHighlight(CObject * pObj)383 void CMainMap::SetHighlight(CObject* pObj)
384 {
385     CWindow* pw;
386     CMap*   pm;
387 
388     pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW1));
389     if (pw == nullptr)
390         return;
391 
392     pm = static_cast<CMap*>(pw->SearchControl(EVENT_OBJECT_MAP));
393     if (pm != nullptr)
394         pm->SetHighlight(pObj);
395 }
396 
397 
398 }
399