source: xplra/src/plugin/src/xplra/MessageWindow.cc@ 49:2f52c296803c

Last change on this file since 49:2f52c296803c was 49:2f52c296803c, checked in by István Váradi <ivaradi@…>, 11 years ago

Made the moving and resizing better looking

File size: 8.7 KB
Line 
1// Copyright (c) 2013 by István Váradi
2
3// This file is part of XPLRA, a remote-access plugin for X-Plane
4
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7
8// 1. Redistributions of source code must retain the above copyright notice, this
9// list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25// The views and conclusions contained in the software and documentation are those
26// of the authors and should not be interpreted as representing official policies,
27// either expressed or implied, of the FreeBSD Project.
28
29//------------------------------------------------------------------------------
30
31#include "MessageWindow.h"
32
33#include <hu/varadiistvan/xplcommon/Util.h>
34
35#include <XPLMProcessing.h>
36#include <XPLMGraphics.h>
37
38//------------------------------------------------------------------------------
39
40using xplra::MessageWindow;
41
42using hu::varadiistvan::xplcommon::Util;
43
44using std::min;
45using std::max;
46
47//------------------------------------------------------------------------------
48
49void MessageWindow::drawWindowCallback(XPLMWindowID /*windowID*/, void* refCon)
50{
51 MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
52 messageWindow->drawWindow();
53}
54
55//------------------------------------------------------------------------------
56
57void MessageWindow::handleKeyCallback(XPLMWindowID /*windowID*/, char key,
58 XPLMKeyFlags flags, char virtualKey,
59 void* refCon, int losingFocus)
60{
61 MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
62 messageWindow->handleKey(key, flags, virtualKey, losingFocus!=0);
63}
64
65//------------------------------------------------------------------------------
66
67int MessageWindow::handleMouseClickCallback(XPLMWindowID /*windowID*/,
68 int x, int y,
69 XPLMMouseStatus mouse, void* refCon)
70{
71 MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
72 return messageWindow->handleMouseClick(x, y, mouse) ? 1 : 0;
73}
74
75//------------------------------------------------------------------------------
76
77MessageWindow::MessageWindow() :
78 showForced(false),
79 hideTime(0.0),
80 clickedX(-1),
81 clickedY(-1),
82 clickedLeft(-1),
83 clickedTop(-1),
84 clickedRight(-1),
85 clickedBottom(-1),
86 duration(0.0)
87{
88 widthDataRef = XPLMFindDataRef("sim/graphics/view/window_width");
89 heightDataRef = XPLMFindDataRef("sim/graphics/view/window_height");
90
91 resetLocation();
92
93 windowID = XPLMCreateWindow(left, top, right, bottom, 0,
94 &drawWindowCallback,
95 &handleKeyCallback,
96 &handleMouseClickCallback, this);
97}
98
99//------------------------------------------------------------------------------
100
101MessageWindow::~MessageWindow()
102{
103 XPLMSetWindowIsVisible(windowID, 0);
104 XPLMDestroyWindow(windowID);
105}
106
107//------------------------------------------------------------------------------
108
109void MessageWindow::show()
110{
111 showForced = true;
112 XPLMSetWindowIsVisible(windowID, 1);
113}
114
115//------------------------------------------------------------------------------
116
117void MessageWindow::hide()
118{
119 showForced = false;
120}
121
122//------------------------------------------------------------------------------
123
124void MessageWindow::reset()
125{
126 resetLocation();
127 XPLMSetWindowGeometry(windowID, left, top, right, bottom);
128}
129
130//------------------------------------------------------------------------------
131
132void MessageWindow::drawWindow()
133{
134 static float colour[3] = { 0.2, 1.0, 0.65 };
135
136 float now = XPLMGetElapsedTime();
137
138 float d = getNewMessage(displayedMessage);
139 if (d>0.0) {
140 hideTime = now + d;
141 }
142
143 if (now>=hideTime) hideTime = 0.0;
144
145 if (hideTime==0.0 && !showForced) {
146 XPLMSetWindowIsVisible(windowID, 0);
147 } else {
148 XPLMDrawTranslucentDarkBox(left, top, right, bottom);
149 if (hideTime!=0.0) {
150 XPLMDrawString(colour, left + 25, top - 15,
151 const_cast<char*>(displayedMessage.c_str()), 0,
152 xplmFont_Basic);
153 }
154 }
155}
156
157//------------------------------------------------------------------------------
158
159void MessageWindow::handleKey(char key, XPLMKeyFlags flags, char virtualKey,
160 bool losingFocus)
161{
162 Util::debug("hu.varadiistvan.xplra.MessageWindow.handleKey: key=0x%02d (%c), flags=0x%04x, virtualKey=0x%02d (%c), losingFocus=%d\n",
163 key, key, flags, virtualKey, virtualKey, losingFocus);
164}
165
166//------------------------------------------------------------------------------
167
168bool MessageWindow::handleMouseClick(int x, int y, XPLMMouseStatus mouse)
169{
170 if (mouse==xplm_MouseDown) {
171 if (x <= (left + resizeArea) ) {
172 mouseMode = MOUSE_RESIZE_LEFT;
173 } else if (x > (right-resizeArea) ) {
174 mouseMode = MOUSE_RESIZE_RIGHT;
175 } else {
176 mouseMode = MOUSE_MOVE;
177 }
178 clickedX = x;
179 clickedY = y;
180 clickedLeft = left;
181 clickedTop = top;
182 clickedRight = right;
183 clickedBottom = bottom;
184 } else if (mouse==xplm_MouseDrag) {
185 int xDiff = x - clickedX;
186
187 if (mouseMode==MOUSE_MOVE) {
188 int newLeft = clickedLeft + xDiff;
189 int newRight = clickedRight + xDiff;
190
191 int screenWidth = XPLMGetDatai(widthDataRef);
192 if (newLeft>=0 && newRight<screenWidth) {
193 left = newLeft;
194 right = newRight;
195 }
196
197 int yDiff = y - clickedY;
198 int newTop = clickedTop + yDiff;
199 int newBottom = clickedBottom + yDiff;
200
201 int screenHeight = XPLMGetDatai(heightDataRef);
202 if (newTop<screenHeight && newBottom>=0) {
203 top = newTop;
204 bottom = newBottom;
205 }
206 } else if (mouseMode==MOUSE_RESIZE_LEFT) {
207 int newLeft = clickedLeft + xDiff;
208 if (newLeft>=0 && (right-newLeft)>=minimalWidth) {
209 left = newLeft;
210 }
211 } else if (mouseMode==MOUSE_RESIZE_RIGHT) {
212 int newRight = clickedRight + xDiff;
213 int screenWidth = XPLMGetDatai(widthDataRef);
214 if (newRight<screenWidth && (newRight-left)>=minimalWidth) {
215 right = newRight;
216 }
217 }
218
219 XPLMSetWindowGeometry(windowID, left, top, right, bottom);
220
221 // clickedX = x;
222 // clickedY = y;
223 }
224
225 return true;
226}
227
228//------------------------------------------------------------------------------
229
230float MessageWindow::getNewMessage(std::string& dest)
231{
232 mutex.lock();
233
234 float d = duration;
235 if (d>0.0) {
236 dest = message;
237
238 message.clear();
239 duration = 0.0;
240 }
241
242 mutex.unlock();
243
244 return d;
245}
246
247//------------------------------------------------------------------------------
248
249void MessageWindow::setNewMessage(const std::string& msg, float d)
250{
251 mutex.lock();
252 message = msg;
253 duration = d;
254 mutex.unlock();
255
256 XPLMSetWindowIsVisible(windowID, 1);
257}
258
259//------------------------------------------------------------------------------
260
261void MessageWindow::resetLocation()
262{
263 int screenWidth = XPLMGetDatai(widthDataRef);
264 int screenHeight = XPLMGetDatai(heightDataRef);
265
266 // Util::debug("hu.varadiistvan.xplra.MessageWindow: screenWidth=%d, screenHeight=%d\n",
267 // screenWidth, screenHeight);
268
269 left = 50; right = screenWidth - left;
270 top = screenHeight * 9 / 10; bottom = top - 25;
271}
272
273//------------------------------------------------------------------------------
274
275// Local Variables:
276// mode: C++
277// c-basic-offset: 4
278// indent-tabs-mode: nil
279// End:
Note: See TracBrowser for help on using the repository browser.