source: xplra/src/plugin/src/xplra/MessageWindow.cc@ 50:d650ff7422a5

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

The font size is now taken into account and the maximal message length is considered

File size: 9.5 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::string;
45using std::min;
46using std::max;
47
48//------------------------------------------------------------------------------
49
50void MessageWindow::drawWindowCallback(XPLMWindowID /*windowID*/, void* refCon)
51{
52 MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
53 messageWindow->drawWindow();
54}
55
56//------------------------------------------------------------------------------
57
58void MessageWindow::handleKeyCallback(XPLMWindowID /*windowID*/, char key,
59 XPLMKeyFlags flags, char virtualKey,
60 void* refCon, int losingFocus)
61{
62 MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
63 messageWindow->handleKey(key, flags, virtualKey, losingFocus!=0);
64}
65
66//------------------------------------------------------------------------------
67
68int MessageWindow::handleMouseClickCallback(XPLMWindowID /*windowID*/,
69 int x, int y,
70 XPLMMouseStatus mouse, void* refCon)
71{
72 MessageWindow* messageWindow = reinterpret_cast<MessageWindow*>(refCon);
73 return messageWindow->handleMouseClick(x, y, mouse) ? 1 : 0;
74}
75
76//------------------------------------------------------------------------------
77
78MessageWindow::MessageWindow() :
79 maxMessageLength(0),
80 showForced(false),
81 hideTime(0.0),
82 clickedX(-1),
83 clickedY(-1),
84 clickedLeft(-1),
85 clickedTop(-1),
86 clickedRight(-1),
87 clickedBottom(-1),
88 duration(0.0)
89{
90 widthDataRef = XPLMFindDataRef("sim/graphics/view/window_width");
91 heightDataRef = XPLMFindDataRef("sim/graphics/view/window_height");
92
93 int digitsOnly = 0;
94 XPLMGetFontDimensions(xplmFont_Basic, &fontWidth, &fontHeight, &digitsOnly);
95
96 Util::debug("hu.varadiistvan.xplra.MessageWindow: fontWidth=%d, fontHeight=%d\n",
97 fontWidth, fontHeight);
98
99 resetLocation();
100
101 windowID = XPLMCreateWindow(left, top, right, bottom, 0,
102 &drawWindowCallback,
103 &handleKeyCallback,
104 &handleMouseClickCallback, this);
105}
106
107//------------------------------------------------------------------------------
108
109MessageWindow::~MessageWindow()
110{
111 XPLMSetWindowIsVisible(windowID, 0);
112 XPLMDestroyWindow(windowID);
113}
114
115//------------------------------------------------------------------------------
116
117void MessageWindow::show()
118{
119 showForced = true;
120 XPLMSetWindowIsVisible(windowID, 1);
121}
122
123//------------------------------------------------------------------------------
124
125void MessageWindow::hide()
126{
127 showForced = false;
128}
129
130//------------------------------------------------------------------------------
131
132void MessageWindow::reset()
133{
134 resetLocation();
135 XPLMSetWindowGeometry(windowID, left, top, right, bottom);
136}
137
138//------------------------------------------------------------------------------
139
140void MessageWindow::drawWindow()
141{
142 static float colour[3] = { 0.2, 1.0, 0.65 };
143
144 float now = XPLMGetElapsedTime();
145
146 float d = getNewMessage(displayedMessage);
147 if (d>0.0) {
148 hideTime = now + d;
149 }
150
151 if (now>=hideTime) hideTime = 0.0;
152
153 if (hideTime==0.0 && !showForced) {
154 XPLMSetWindowIsVisible(windowID, 0);
155 } else {
156 XPLMDrawTranslucentDarkBox(left, top, right, bottom);
157 if (hideTime!=0.0) {
158
159 string dm(displayedMessage, 0, maxMessageLength);
160
161 XPLMDrawString(colour,
162 left + horizontalMarginSize,
163 bottom + verticalMarginSize + baseLineSize,
164 const_cast<char*>(dm.c_str()), 0,
165 xplmFont_Basic);
166 }
167 }
168}
169
170//------------------------------------------------------------------------------
171
172void MessageWindow::handleKey(char key, XPLMKeyFlags flags, char virtualKey,
173 bool losingFocus)
174{
175 Util::debug("hu.varadiistvan.xplra.MessageWindow.handleKey: key=0x%02d (%c), flags=0x%04x, virtualKey=0x%02d (%c), losingFocus=%d\n",
176 key, key, flags, virtualKey, virtualKey, losingFocus);
177}
178
179//------------------------------------------------------------------------------
180
181bool MessageWindow::handleMouseClick(int x, int y, XPLMMouseStatus mouse)
182{
183 if (mouse==xplm_MouseDown) {
184 if (x <= (left + resizeArea) ) {
185 mouseMode = MOUSE_RESIZE_LEFT;
186 } else if (x > (right-resizeArea) ) {
187 mouseMode = MOUSE_RESIZE_RIGHT;
188 } else {
189 mouseMode = MOUSE_MOVE;
190 }
191 clickedX = x;
192 clickedY = y;
193 clickedLeft = left;
194 clickedTop = top;
195 clickedRight = right;
196 clickedBottom = bottom;
197 } else if (mouse==xplm_MouseDrag) {
198 int xDiff = x - clickedX;
199
200 if (mouseMode==MOUSE_MOVE) {
201 int newLeft = clickedLeft + xDiff;
202 int newRight = clickedRight + xDiff;
203
204 int screenWidth = XPLMGetDatai(widthDataRef);
205 if (newLeft>=0 && newRight<screenWidth) {
206 left = newLeft;
207 right = newRight;
208 }
209
210 int yDiff = y - clickedY;
211 int newTop = clickedTop + yDiff;
212 int newBottom = clickedBottom + yDiff;
213
214 int screenHeight = XPLMGetDatai(heightDataRef);
215 if (newTop<screenHeight && newBottom>=0) {
216 top = newTop;
217 bottom = newBottom;
218 }
219 } else if (mouseMode==MOUSE_RESIZE_LEFT) {
220 int newLeft = clickedLeft + xDiff;
221 if (newLeft>=0 && (right-newLeft)>=minimalWidth) {
222 left = newLeft;
223 recalculateMaxMessageLength();
224 }
225 } else if (mouseMode==MOUSE_RESIZE_RIGHT) {
226 int newRight = clickedRight + xDiff;
227 int screenWidth = XPLMGetDatai(widthDataRef);
228 if (newRight<screenWidth && (newRight-left)>=minimalWidth) {
229 right = newRight;
230 recalculateMaxMessageLength();
231 }
232 }
233
234 XPLMSetWindowGeometry(windowID, left, top, right, bottom);
235 }
236
237 return true;
238}
239
240//------------------------------------------------------------------------------
241
242float MessageWindow::getNewMessage(std::string& dest)
243{
244 mutex.lock();
245
246 float d = duration;
247 if (d>0.0) {
248 dest = message;
249
250 message.clear();
251 duration = 0.0;
252 }
253
254 mutex.unlock();
255
256 return d;
257}
258
259//------------------------------------------------------------------------------
260
261void MessageWindow::setNewMessage(const std::string& msg, float d)
262{
263 mutex.lock();
264 message = msg;
265 duration = d;
266 mutex.unlock();
267
268 XPLMSetWindowIsVisible(windowID, 1);
269}
270
271//------------------------------------------------------------------------------
272
273void MessageWindow::resetLocation()
274{
275 int screenWidth = XPLMGetDatai(widthDataRef);
276 int screenHeight = XPLMGetDatai(heightDataRef);
277
278 // Util::debug("hu.varadiistvan.xplra.MessageWindow: screenWidth=%d, screenHeight=%d\n",
279 // screenWidth, screenHeight);
280
281 left = 50;
282 right = screenWidth - left;
283
284 top = screenHeight * 9 / 10;
285 bottom = top - fontHeight - 2*verticalMarginSize;
286
287 recalculateMaxMessageLength();
288}
289
290//------------------------------------------------------------------------------
291
292void MessageWindow::recalculateMaxMessageLength()
293{
294 maxMessageLength = (right + 1 - left) - 2 * horizontalMarginSize;
295 maxMessageLength /= fontWidth;
296}
297
298//------------------------------------------------------------------------------
299
300// Local Variables:
301// mode: C++
302// c-basic-offset: 4
303// indent-tabs-mode: nil
304// End:
Note: See TracBrowser for help on using the repository browser.