1 /***************************************************************************
2  *      Mechanized Assault and Exploration Reloaded Projectfile            *
3  *                                                                         *
4  *   This program 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  *   This program 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 this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18  ***************************************************************************/
19 
20 #include "ui/graphical/window.h"
21 #include "ui/graphical/application.h"
22 
23 #include "input/mouse/mouse.h"
24 #include "input/mouse/cursor/mousecursorsimple.h"
25 #include "settings.h"
26 #include "video.h"
27 
28 //------------------------------------------------------------------------------
cWindow(AutoSurface surface_,eWindowBackgrounds backgroundType_)29 cWindow::cWindow (AutoSurface surface_, eWindowBackgrounds backgroundType_) :
30 	surface (nullptr),
31 	backgroundType (backgroundType_),
32 	activeApplication (nullptr),
33 	closing (false),
34 	hasBeenDrawnOnce (false)
35 {
36 	setSurface (std::move (surface_));
37 }
38 
39 //------------------------------------------------------------------------------
isClosing() const40 bool cWindow::isClosing() const
41 {
42 	return closing;
43 }
44 
45 //------------------------------------------------------------------------------
close()46 void cWindow::close()
47 {
48 	closing = true;
49 }
50 
51 //------------------------------------------------------------------------------
draw(SDL_Surface & destination,const cBox<cPosition> & clipRect)52 void cWindow::draw (SDL_Surface& destination, const cBox<cPosition>& clipRect)
53 {
54 	if (!hasBeenDrawnOnce)
55 	{
56 		switch (backgroundType)
57 		{
58 			case eWindowBackgrounds::Black:
59 				SDL_FillRect (cVideo::buffer, nullptr, 0xFF000000);
60 				break;
61 			case eWindowBackgrounds::Alpha:
62 				// NOTE: this is not fully robust yet! It will not work if an
63 				// alpha-background-window will call another alpha-background-window.
64 				// Returning to an alpha-background-window from any other window
65 				// will not work as expected as well.
66 				if (cSettings::getInstance().isAlphaEffects())
67 				{
68 					Video.applyShadow (nullptr, destination);
69 				}
70 				break;
71 			case eWindowBackgrounds::Transparent:
72 				// do nothing here
73 				break;
74 		}
75 	}
76 
77 	SDL_Rect position = getArea().toSdlRect();
78 	if (surface != nullptr) SDL_BlitSurface (surface.get(), nullptr, &destination, &position);
79 
80 	hasBeenDrawnOnce = true;
81 
82 	cWidget::draw (destination, clipRect); // draws all children
83 }
84 
85 //------------------------------------------------------------------------------
handleActivated(cApplication & application,bool firstTime)86 void cWindow::handleActivated (cApplication& application, bool firstTime)
87 {
88 	// one window should not be displayed in multiple applications at once
89 	// (we have only one application anyway...)
90 	assert (activeApplication == nullptr);
91 
92 	hasBeenDrawnOnce = false;
93 	activeApplication = &application;
94 
95 	auto mouse = activeApplication->getActiveMouse();
96 	if (mouse)
97 	{
98 		auto defaultCursor = getDefaultCursor();
99 		if (defaultCursor)
100 		{
101 			mouse->setCursor (std::move (defaultCursor));
102 		}
103 	}
104 }
105 
106 //------------------------------------------------------------------------------
handleDeactivated(cApplication & application,bool removed)107 void cWindow::handleDeactivated (cApplication& application, bool removed)
108 {
109 	if (activeApplication == &application)
110 	{
111 		activeApplication = nullptr;
112 	}
113 
114 	if (removed)
115 	{
116 		assert (isClosing());
117 
118 		terminated();
119 	}
120 }
121 
122 //------------------------------------------------------------------------------
wantsCentered() const123 bool cWindow::wantsCentered() const
124 {
125 	return true;
126 }
127 
128 //------------------------------------------------------------------------------
getActiveApplication() const129 cApplication* cWindow::getActiveApplication() const
130 {
131 	return activeApplication;
132 }
133 
134 //------------------------------------------------------------------------------
getDefaultCursor() const135 std::unique_ptr<cMouseCursor> cWindow::getDefaultCursor() const
136 {
137 	return std::make_unique<cMouseCursorSimple> (eMouseCursorSimpleType::Hand);
138 }
139 
140 //------------------------------------------------------------------------------
getActiveMouse() const141 cMouse* cWindow::getActiveMouse() const
142 {
143 	return activeApplication ? activeApplication->getActiveMouse() : nullptr;
144 }
145 
146 //------------------------------------------------------------------------------
getActiveKeyboard() const147 cKeyboard* cWindow::getActiveKeyboard() const
148 {
149 	return activeApplication ? activeApplication->getActiveKeyboard() : nullptr;
150 }
151 
152 //------------------------------------------------------------------------------
getSurface()153 SDL_Surface* cWindow::getSurface()
154 {
155 	return surface.get();
156 }
157 
158 //------------------------------------------------------------------------------
setSurface(AutoSurface surface_)159 void cWindow::setSurface (AutoSurface surface_)
160 {
161 	surface = std::move (surface_);
162 	if (surface != nullptr)
163 	{
164 		resize (cPosition (surface->w, surface->h));
165 	}
166 }
167