source: xplra/src/plugin/src/xplra/MessageWindow.cc@ 51:bc776d590040

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

Added scrolling the message if needed

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