2 |
andreas |
1 |
/*
|
21 |
andreas |
2 |
* Copyright (C) 2020, 2021 by Andreas Theofilu <andreas@theosys.at>
|
2 |
andreas |
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 3 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 Free Software Foundation,
|
|
|
16 |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
17 |
*/
|
|
|
18 |
|
21 |
andreas |
19 |
/** @file tqtmain.cpp
|
|
|
20 |
* @brief Implements the surface of the application.
|
|
|
21 |
*
|
|
|
22 |
* This file implements the callback functions of the suface. While the most
|
|
|
23 |
* classes are drawing the elements, the methods here take the ready elements
|
|
|
24 |
* and display them. This file makes the surface completely independent of
|
|
|
25 |
* the rest of the application which makes it easy to change the surface by
|
|
|
26 |
* any other technology.
|
|
|
27 |
*/
|
2 |
andreas |
28 |
#include <QApplication>
|
14 |
andreas |
29 |
#include <QByteArray>
|
2 |
andreas |
30 |
#include <QCommandLineParser>
|
|
|
31 |
#include <QCommandLineOption>
|
9 |
andreas |
32 |
#include <QLabel>
|
2 |
andreas |
33 |
#include <QtWidgets>
|
10 |
andreas |
34 |
#include <QMouseEvent>
|
15 |
andreas |
35 |
#include <QMoveEvent>
|
5 |
andreas |
36 |
#include <QPalette>
|
9 |
andreas |
37 |
#include <QPixmap>
|
7 |
andreas |
38 |
#include <QFont>
|
|
|
39 |
#include <QFontDatabase>
|
21 |
andreas |
40 |
#include <QtMultimediaWidgets/QVideoWidget>
|
|
|
41 |
#include <QtMultimedia/QMediaPlayer>
|
|
|
42 |
#include <QtMultimedia/QMediaPlaylist>
|
|
|
43 |
#include <QUrl>
|
13 |
andreas |
44 |
#include <QThread>
|
2 |
andreas |
45 |
|
5 |
andreas |
46 |
#include <functional>
|
14 |
andreas |
47 |
#include <mutex>
|
5 |
andreas |
48 |
|
4 |
andreas |
49 |
#include "tpagemanager.h"
|
2 |
andreas |
50 |
#include "tqtmain.h"
|
|
|
51 |
#include "tconfig.h"
|
|
|
52 |
#include "tqtsettings.h"
|
5 |
andreas |
53 |
#include "tcolor.h"
|
2 |
andreas |
54 |
|
21 |
andreas |
55 |
/**
|
|
|
56 |
* @def __ANDROID__
|
|
|
57 |
* Here we've to define some extra place holders because on Android only 10
|
|
|
58 |
* place holders are defined by default. But we've a callback functions which
|
|
|
59 |
* need 13 place holders. The defination is taken from the original defination
|
|
|
60 |
* of place holders and expanded.
|
|
|
61 |
*/
|
|
|
62 |
#ifdef __ANDROID__
|
|
|
63 |
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
|
|
64 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _11;
|
|
|
65 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _12;
|
|
|
66 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _13;
|
|
|
67 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _14;
|
|
|
68 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _15;
|
|
|
69 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _16;
|
|
|
70 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _17;
|
|
|
71 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _18;
|
|
|
72 |
_LIBCPP_FUNC_VIS extern const std::placeholders::__ph<10> _19;
|
|
|
73 |
_LIBCPP_FUNC_VIS extern const _std::placeholders::_ph<10> _20;
|
|
|
74 |
#else
|
|
|
75 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<11> _11{};
|
|
|
76 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<12> _12{};
|
|
|
77 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<13> _13{};
|
|
|
78 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<14> _14{};
|
|
|
79 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<15> _15{};
|
|
|
80 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<16> _16{};
|
|
|
81 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<17> _17{};
|
|
|
82 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<18> _18{};
|
|
|
83 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<19> _19{};
|
|
|
84 |
/* _LIBCPP_INLINE_VAR */ constexpr std::placeholders::__ph<20> _20{};
|
|
|
85 |
#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
|
|
86 |
#endif
|
3 |
andreas |
87 |
|
21 |
andreas |
88 |
static TPageManager *pageManager = nullptr; //!< The pointer to the global defined main class.
|
|
|
89 |
std::mutex draw_mutex; //!< We're using threads and need to block execution sometimes
|
|
|
90 |
|
5 |
andreas |
91 |
using std::bind;
|
21 |
andreas |
92 |
using std::string;
|
5 |
andreas |
93 |
|
21 |
andreas |
94 |
/**
|
|
|
95 |
* @brief qtmain is used here as the entry point for the surface.
|
|
|
96 |
*
|
|
|
97 |
* The main entry function parses the command line parameters, if there were
|
|
|
98 |
* any and sets the basic attributes. It creates the main window and starts the
|
|
|
99 |
* application.
|
|
|
100 |
*
|
|
|
101 |
* @param argc The number of command line arguments
|
|
|
102 |
* @param argv A pointer to a 2 dimensional array containing the command
|
|
|
103 |
* line parameters.
|
|
|
104 |
* @param pmanager A pointer to the page manager class which is the main class
|
|
|
105 |
* managing everything.
|
|
|
106 |
*
|
|
|
107 |
* @return If no errors occured it returns 0.
|
|
|
108 |
*/
|
3 |
andreas |
109 |
int qtmain(int argc, char **argv, TPageManager *pmanager)
|
2 |
andreas |
110 |
{
|
3 |
andreas |
111 |
DECL_TRACER("qtmain(int argc, char **argv, width, int height)");
|
2 |
andreas |
112 |
|
3 |
andreas |
113 |
pageManager = pmanager;
|
|
|
114 |
|
21 |
andreas |
115 |
// Q_INIT_RESOURCE(tpanel);
|
2 |
andreas |
116 |
#ifdef Q_OS_ANDROID
|
5 |
andreas |
117 |
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
2 |
andreas |
118 |
#endif
|
|
|
119 |
|
5 |
andreas |
120 |
QApplication app(argc, argv);
|
|
|
121 |
QCoreApplication::setOrganizationName(TConfig::getProgName().c_str());
|
|
|
122 |
QCoreApplication::setApplicationName("AMX panel simulator");
|
|
|
123 |
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
|
|
|
124 |
QCommandLineParser parser;
|
|
|
125 |
parser.setApplicationDescription(QCoreApplication::applicationName());
|
|
|
126 |
parser.addHelpOption();
|
|
|
127 |
parser.addVersionOption();
|
|
|
128 |
parser.process(app);
|
2 |
andreas |
129 |
|
5 |
andreas |
130 |
MainWindow mainWin;
|
|
|
131 |
mainWin.show();
|
|
|
132 |
return app.exec();
|
2 |
andreas |
133 |
}
|
|
|
134 |
|
21 |
andreas |
135 |
/**
|
|
|
136 |
* @brief MainWindow::MainWindow constructor
|
|
|
137 |
*
|
|
|
138 |
* This method is the constructor for this class. It registers the callback
|
|
|
139 |
* functions to the class TPageManager and starts the main run loop.
|
|
|
140 |
*/
|
2 |
andreas |
141 |
MainWindow::MainWindow()
|
|
|
142 |
{
|
5 |
andreas |
143 |
DECL_TRACER("MainWindow::MainWindow()");
|
2 |
andreas |
144 |
|
14 |
andreas |
145 |
pageManager->registerCallbackDB(bind(&MainWindow::_displayButton, this,
|
5 |
andreas |
146 |
std::placeholders::_1,
|
|
|
147 |
std::placeholders::_2,
|
|
|
148 |
std::placeholders::_3,
|
|
|
149 |
std::placeholders::_4,
|
|
|
150 |
std::placeholders::_5,
|
|
|
151 |
std::placeholders::_6,
|
|
|
152 |
std::placeholders::_7,
|
|
|
153 |
std::placeholders::_8));
|
|
|
154 |
|
14 |
andreas |
155 |
pageManager->registerCallbackSP(bind(&MainWindow::_setPage, this,
|
5 |
andreas |
156 |
std::placeholders::_1,
|
|
|
157 |
std::placeholders::_2,
|
|
|
158 |
std::placeholders::_3));
|
|
|
159 |
|
14 |
andreas |
160 |
pageManager->registerCallbackSSP(bind(&MainWindow::_setSubPage, this,
|
5 |
andreas |
161 |
std::placeholders::_1,
|
|
|
162 |
std::placeholders::_2,
|
|
|
163 |
std::placeholders::_3,
|
|
|
164 |
std::placeholders::_4,
|
|
|
165 |
std::placeholders::_5));
|
|
|
166 |
|
14 |
andreas |
167 |
pageManager->registerCallbackSB(bind(&MainWindow::_setBackground, this,
|
5 |
andreas |
168 |
std::placeholders::_1,
|
|
|
169 |
std::placeholders::_2,
|
|
|
170 |
std::placeholders::_3,
|
|
|
171 |
std::placeholders::_4,
|
|
|
172 |
std::placeholders::_5));
|
|
|
173 |
|
14 |
andreas |
174 |
pageManager->registerCallbackFT(bind(&MainWindow::_setText, this,
|
7 |
andreas |
175 |
std::placeholders::_1,
|
|
|
176 |
std::placeholders::_2,
|
|
|
177 |
std::placeholders::_3,
|
|
|
178 |
std::placeholders::_4,
|
|
|
179 |
std::placeholders::_5,
|
|
|
180 |
std::placeholders::_6,
|
|
|
181 |
std::placeholders::_7,
|
|
|
182 |
std::placeholders::_8,
|
|
|
183 |
std::placeholders::_9,
|
|
|
184 |
std::placeholders::_10,
|
21 |
andreas |
185 |
#ifdef __ANDROID__
|
|
|
186 |
_11,
|
|
|
187 |
_12,
|
|
|
188 |
_13));
|
|
|
189 |
#else
|
7 |
andreas |
190 |
std::placeholders::_11,
|
|
|
191 |
std::placeholders::_12,
|
|
|
192 |
std::placeholders::_13));
|
21 |
andreas |
193 |
#endif
|
7 |
andreas |
194 |
|
14 |
andreas |
195 |
pageManager->regCallDropPage(bind(&MainWindow::_dropPage, this, std::placeholders::_1));
|
|
|
196 |
pageManager->regCallDropSubPage(bind(&MainWindow::_dropSubPage, this, std::placeholders::_1));
|
21 |
andreas |
197 |
pageManager->regCallPlayVideo(bind(&MainWindow::_playVideo, this,
|
|
|
198 |
std::placeholders::_1,
|
|
|
199 |
std::placeholders::_2,
|
|
|
200 |
std::placeholders::_3,
|
|
|
201 |
std::placeholders::_4,
|
|
|
202 |
std::placeholders::_5,
|
|
|
203 |
std::placeholders::_6,
|
|
|
204 |
std::placeholders::_7,
|
|
|
205 |
std::placeholders::_8,
|
|
|
206 |
std::placeholders::_9));
|
11 |
andreas |
207 |
|
5 |
andreas |
208 |
createActions();
|
|
|
209 |
|
2 |
andreas |
210 |
#ifndef QT_NO_SESSIONMANAGER
|
5 |
andreas |
211 |
QGuiApplication::setFallbackSessionManagementEnabled(false);
|
|
|
212 |
connect(qApp, &QGuiApplication::commitDataRequest,
|
|
|
213 |
this, &MainWindow::writeSettings);
|
2 |
andreas |
214 |
#endif
|
14 |
andreas |
215 |
|
|
|
216 |
qRegisterMetaType<size_t>("size_t");
|
|
|
217 |
qRegisterMetaType<QByteArray>("QByteArray");
|
|
|
218 |
|
15 |
andreas |
219 |
try
|
|
|
220 |
{
|
|
|
221 |
connect(this, &MainWindow::sigDisplayButton, this, &MainWindow::displayButton);
|
|
|
222 |
connect(this, &MainWindow::sigDisplayButton, // same sender and signal
|
|
|
223 |
this, // context object to break this connection
|
|
|
224 |
[this]() { // debug output
|
|
|
225 |
MSG_DEBUG("Direct? " << ((QThread::currentThread() == this->thread())?"YES":"NO"));
|
|
|
226 |
},
|
|
|
227 |
Qt::DirectConnection);
|
|
|
228 |
connect(this, &MainWindow::sigSetPage, this, &MainWindow::setPage);
|
|
|
229 |
connect(this, &MainWindow::sigSetSubPage, this, &MainWindow::setSubPage);
|
|
|
230 |
connect(this, &MainWindow::sigSetBackground, this, &MainWindow::setBackground);
|
|
|
231 |
connect(this, &MainWindow::sigSetText, this, &MainWindow::setText);
|
|
|
232 |
connect(this, &MainWindow::sigDropPage, this, &MainWindow::dropPage);
|
|
|
233 |
connect(this, &MainWindow::sigDropSubPage, this, &MainWindow::dropSubPage);
|
21 |
andreas |
234 |
connect(this, &MainWindow::sigPlayVideo, this, &MainWindow::playVideo);
|
15 |
andreas |
235 |
}
|
|
|
236 |
catch (std::exception& e)
|
|
|
237 |
{
|
|
|
238 |
MSG_ERROR("Connection error: " << e.what());
|
|
|
239 |
}
|
|
|
240 |
|
5 |
andreas |
241 |
setUnifiedTitleAndToolBarOnMac(true);
|
|
|
242 |
pageManager->run();
|
2 |
andreas |
243 |
}
|
|
|
244 |
|
21 |
andreas |
245 |
/**
|
|
|
246 |
* @brief MainWindow::closeEvent called when the application receives an exit event.
|
|
|
247 |
*
|
|
|
248 |
* If the user clicks on the exit icon or on the menu point _Exit_ this method
|
|
|
249 |
* is called. It makes sure everything is written to the configuration file
|
|
|
250 |
* and accepts the evernt.
|
|
|
251 |
*
|
|
|
252 |
* @param event The exit event
|
|
|
253 |
*/
|
2 |
andreas |
254 |
void MainWindow::closeEvent(QCloseEvent *event)
|
|
|
255 |
{
|
5 |
andreas |
256 |
DECL_TRACER("MainWindow::closeEvent(QCloseEvent *event)");
|
2 |
andreas |
257 |
|
5 |
andreas |
258 |
if (settingsChanged)
|
|
|
259 |
{
|
|
|
260 |
writeSettings();
|
|
|
261 |
event->accept();
|
|
|
262 |
}
|
|
|
263 |
else
|
|
|
264 |
{
|
|
|
265 |
// event->ignore();
|
21 |
andreas |
266 |
prg_stopped = true;
|
|
|
267 |
MSG_TRACE("Program will stop!");
|
5 |
andreas |
268 |
event->accept();
|
|
|
269 |
}
|
2 |
andreas |
270 |
}
|
|
|
271 |
|
21 |
andreas |
272 |
/**
|
|
|
273 |
* @brief MainWindow::eventFilter filters the QEvent::MouseMove event
|
|
|
274 |
* @param obj The object where the event occured.
|
|
|
275 |
* @param event The event.
|
|
|
276 |
* @return `true` when the event should be ignored.
|
|
|
277 |
*/
|
15 |
andreas |
278 |
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
|
|
|
279 |
{
|
|
|
280 |
// DECL_TRACER("MainWindow::eventFilter(QObject *obj, QEvent *event)");
|
|
|
281 |
|
|
|
282 |
if (event->type() == QEvent::MouseMove)
|
|
|
283 |
return true; // Filter event out, i.e. stop it being handled further.
|
|
|
284 |
|
|
|
285 |
return QMainWindow::eventFilter(obj, event);
|
|
|
286 |
}
|
|
|
287 |
|
21 |
andreas |
288 |
/**
|
|
|
289 |
* @brief MainWindow::createActions creates the configuration dialog window.
|
|
|
290 |
*/
|
2 |
andreas |
291 |
void MainWindow::createActions()
|
|
|
292 |
{
|
5 |
andreas |
293 |
DECL_TRACER("MainWindow::createActions()");
|
2 |
andreas |
294 |
|
4 |
andreas |
295 |
// Add a menu
|
5 |
andreas |
296 |
QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
|
2 |
andreas |
297 |
|
5 |
andreas |
298 |
const QIcon settingsIcon = QIcon::fromTheme("document-open", QIcon(":/images/settings-configure.png"));
|
|
|
299 |
QAction *settingsAct = new QAction(settingsIcon, tr("&Settings..."), this);
|
|
|
300 |
settingsAct->setStatusTip(tr("Change the settings"));
|
|
|
301 |
connect(settingsAct, &QAction::triggered, this, &MainWindow::settings);
|
|
|
302 |
editMenu->addAction(settingsAct);
|
2 |
andreas |
303 |
|
5 |
andreas |
304 |
const QIcon aboutIcon = QIcon::fromTheme("document-open", QIcon(":/images/help-about.png"));
|
|
|
305 |
QAction *aboutAct = new QAction(aboutIcon, tr("&About..."), this);
|
|
|
306 |
aboutAct->setShortcuts(QKeySequence::Open);
|
|
|
307 |
aboutAct->setStatusTip(tr("About this program"));
|
|
|
308 |
connect(aboutAct, &QAction::triggered, this, &MainWindow::about);
|
|
|
309 |
editMenu->addAction(aboutAct);
|
2 |
andreas |
310 |
|
5 |
andreas |
311 |
editMenu->addSeparator();
|
2 |
andreas |
312 |
|
5 |
andreas |
313 |
const QIcon exitIcon = QIcon::fromTheme("application-exit");
|
|
|
314 |
QAction *exitAct = editMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close);
|
|
|
315 |
exitAct->setShortcuts(QKeySequence::Quit);
|
|
|
316 |
exitAct->setStatusTip(tr("Exit the application"));
|
2 |
andreas |
317 |
}
|
|
|
318 |
|
21 |
andreas |
319 |
/**
|
|
|
320 |
* @brief MainWindow::mousePressEvent catches the event Qt::LeftButton.
|
|
|
321 |
*
|
|
|
322 |
* If the user presses the left mouse button somewhere in the main window, this
|
|
|
323 |
* method is triggered. It retrieves the position of the mouse pointer and
|
|
|
324 |
* sends it to the page manager TPageManager.
|
|
|
325 |
*
|
|
|
326 |
* @param event The event
|
|
|
327 |
*/
|
10 |
andreas |
328 |
void MainWindow::mousePressEvent(QMouseEvent* event)
|
|
|
329 |
{
|
|
|
330 |
if(event->button() == Qt::LeftButton)
|
|
|
331 |
{
|
|
|
332 |
pageManager->mouseEvent(event->x(), event->y(), true);
|
|
|
333 |
}
|
|
|
334 |
}
|
|
|
335 |
|
21 |
andreas |
336 |
/**
|
|
|
337 |
* @brief MainWindow::mouseReleaseEvent catches the event Qt::LeftButton.
|
|
|
338 |
*
|
|
|
339 |
* If the user releases the left mouse button somewhere in the main window, this
|
|
|
340 |
* method is triggered. It retrieves the position of the mouse pointer and
|
|
|
341 |
* sends it to the page manager TPageManager.
|
|
|
342 |
*
|
|
|
343 |
* @param event The event
|
|
|
344 |
*/
|
10 |
andreas |
345 |
void MainWindow::mouseReleaseEvent(QMouseEvent* event)
|
|
|
346 |
{
|
|
|
347 |
if(event->button() == Qt::LeftButton)
|
|
|
348 |
{
|
|
|
349 |
pageManager->mouseEvent(event->x(), event->y(), false);
|
|
|
350 |
}
|
|
|
351 |
}
|
|
|
352 |
|
21 |
andreas |
353 |
/**
|
|
|
354 |
* @brief MainWindow::settings initiates the configuration dialog.
|
|
|
355 |
*/
|
2 |
andreas |
356 |
void MainWindow::settings()
|
|
|
357 |
{
|
5 |
andreas |
358 |
DECL_TRACER("MainWindow::settings()");
|
2 |
andreas |
359 |
|
5 |
andreas |
360 |
TQtSettings *dlg_settings = new TQtSettings(this);
|
|
|
361 |
dlg_settings->show();
|
2 |
andreas |
362 |
}
|
|
|
363 |
|
21 |
andreas |
364 |
/**
|
|
|
365 |
* @brief MainWindow::writeSettings Writes the settings into the configuration file.
|
|
|
366 |
*/
|
2 |
andreas |
367 |
void MainWindow::writeSettings()
|
|
|
368 |
{
|
5 |
andreas |
369 |
DECL_TRACER("MainWindow::writeSettings()");
|
2 |
andreas |
370 |
}
|
|
|
371 |
|
21 |
andreas |
372 |
/**
|
|
|
373 |
* @brief MainWindow::about displays the _about_ dialog.
|
|
|
374 |
*/
|
2 |
andreas |
375 |
void MainWindow::about()
|
|
|
376 |
{
|
5 |
andreas |
377 |
DECL_TRACER("MainWindow::about()");
|
2 |
andreas |
378 |
|
5 |
andreas |
379 |
QMessageBox::about(this, tr(std::string("About ").append(TConfig::getProgName()).c_str()),
|
|
|
380 |
tr("Simulation of an AMX G4 panel\n"
|
|
|
381 |
"(C) Copyright 2020 by Andreas Theofilu <andreas@theosys.at>\n"
|
|
|
382 |
"This program is under the terms of GPL version 3"));
|
2 |
andreas |
383 |
}
|
|
|
384 |
|
14 |
andreas |
385 |
/******************* Signal handling *************************/
|
|
|
386 |
|
|
|
387 |
void MainWindow::_displayButton(ulong handle, ulong parent, unsigned char* buffer, int width, int height, int pixline, int left, int top)
|
4 |
andreas |
388 |
{
|
14 |
andreas |
389 |
DECL_TRACER("MainWindow::_displayButton(ulong handle, ulong parent, unsigned char* buffer, int width, int height, int pixline, int left, int top)");
|
|
|
390 |
|
21 |
andreas |
391 |
if (prg_stopped)
|
|
|
392 |
return;
|
|
|
393 |
|
14 |
andreas |
394 |
QByteArray buf;
|
|
|
395 |
|
|
|
396 |
if (buffer && pixline > 0)
|
|
|
397 |
{
|
|
|
398 |
size_t size = width * height * (pixline / width);
|
15 |
andreas |
399 |
MSG_DEBUG("Buffer size=" << size << ", width=" << width << ", height=" << height << ", left=" << left << ", top=" << top);
|
14 |
andreas |
400 |
buf.insert(0, (const char *)buffer, size);
|
|
|
401 |
}
|
|
|
402 |
|
15 |
andreas |
403 |
try
|
|
|
404 |
{
|
|
|
405 |
emit sigDisplayButton(handle, parent, buf, width, height, pixline, left, top);
|
|
|
406 |
}
|
|
|
407 |
catch (std::exception& e)
|
|
|
408 |
{
|
|
|
409 |
MSG_ERROR("Error triggering function \"displayButton()\": " << e.what());
|
|
|
410 |
}
|
14 |
andreas |
411 |
}
|
|
|
412 |
|
|
|
413 |
void MainWindow::_setPage(ulong handle, int width, int height)
|
|
|
414 |
{
|
|
|
415 |
DECL_TRACER("MainWindow::_setPage(ulong handle, int width, int height)");
|
|
|
416 |
|
21 |
andreas |
417 |
if (prg_stopped)
|
|
|
418 |
return;
|
|
|
419 |
|
14 |
andreas |
420 |
emit sigSetPage(handle, width, height);
|
|
|
421 |
}
|
|
|
422 |
|
|
|
423 |
void MainWindow::_setSubPage(ulong handle, int left, int top, int width, int height)
|
|
|
424 |
{
|
|
|
425 |
DECL_TRACER("MainWindow::_setSubPage(ulong handle, int left, int top, int width, int height)");
|
|
|
426 |
|
21 |
andreas |
427 |
if (prg_stopped)
|
|
|
428 |
return;
|
|
|
429 |
|
14 |
andreas |
430 |
emit sigSetSubPage(handle, left, top, width, height);
|
|
|
431 |
}
|
|
|
432 |
|
|
|
433 |
void MainWindow::_setBackground(ulong handle, unsigned char *image, size_t size, size_t rowBytes, ulong color)
|
|
|
434 |
{
|
|
|
435 |
DECL_TRACER("MainWindow::_setBackground(ulong handle, unsigned char *image, size_t size, size_t rowBytes, ulong color)");
|
|
|
436 |
|
21 |
andreas |
437 |
if (prg_stopped)
|
|
|
438 |
return;
|
|
|
439 |
|
14 |
andreas |
440 |
QByteArray buf;
|
|
|
441 |
|
|
|
442 |
if (image && size > 0)
|
|
|
443 |
buf.insert(0, (const char *)image, size);
|
|
|
444 |
|
|
|
445 |
emit sigSetBackground(handle, buf, rowBytes, color);
|
|
|
446 |
}
|
|
|
447 |
|
|
|
448 |
void MainWindow::_setText(ulong handle, const std::string& text, const std::string& font, const std::string& family, int size, int x, int y, ulong color, ulong effectColor, FONT_STYLE style, Button::TEXT_ORIENTATION ori, Button::TEXT_EFFECT effect, bool ww)
|
|
|
449 |
{
|
|
|
450 |
DECL_TRACER("MainWindow::_setText(ulong handle, const std::string& text, const std::string& font, const std::string& family, int size, int x, int y, ulong color, ulong effectColor, FONT_STYLE style, Button::TEXT_ORIENTATION ori, Button::TEXT_EFFECT effect, bool ww)");
|
|
|
451 |
|
21 |
andreas |
452 |
if (prg_stopped)
|
|
|
453 |
return;
|
|
|
454 |
|
14 |
andreas |
455 |
emit sigSetText(handle, text, font, family, size, x, y, color, effectColor, style, ori, effect, ww);
|
|
|
456 |
}
|
|
|
457 |
|
|
|
458 |
void MainWindow::_dropPage(ulong handle)
|
|
|
459 |
{
|
|
|
460 |
DECL_TRACER("MainWindow::_dropPage(ulong handle)");
|
|
|
461 |
|
|
|
462 |
emit sigDropPage(handle);
|
|
|
463 |
}
|
|
|
464 |
|
|
|
465 |
void MainWindow::_dropSubPage(ulong handle)
|
|
|
466 |
{
|
|
|
467 |
DECL_TRACER("MainWindow::_dropSubPage(ulong handle)");
|
|
|
468 |
|
|
|
469 |
emit sigDropSubPage(handle);
|
|
|
470 |
}
|
|
|
471 |
|
21 |
andreas |
472 |
void MainWindow::_playVideo(ulong handle, ulong parent, int left, int top, int width, int height, const string& url, const string& user, const string& pw)
|
|
|
473 |
{
|
|
|
474 |
DECL_TRACER("MainWindow::_playVideo(ulong handle, const string& url)");
|
|
|
475 |
|
|
|
476 |
if (prg_stopped)
|
|
|
477 |
return;
|
|
|
478 |
|
|
|
479 |
emit sigPlayVideo(handle, parent, left, top, width, height, url, user, pw);
|
|
|
480 |
}
|
|
|
481 |
|
14 |
andreas |
482 |
/******************* Draw elements *************************/
|
|
|
483 |
|
|
|
484 |
void MainWindow::displayButton(ulong handle, ulong parent, QByteArray buffer, int width, int height, int pixline, int left, int top)
|
|
|
485 |
{
|
|
|
486 |
draw_mutex.lock();
|
5 |
andreas |
487 |
DECL_TRACER("MainWindow::displayButton(ulong handle, unsigned char* buffer, size_t size, int width, int height, int pixline, int left, int top)");
|
4 |
andreas |
488 |
|
5 |
andreas |
489 |
OBJECT_t *obj = findObject(handle);
|
6 |
andreas |
490 |
OBJECT_t *par = findObject(parent);
|
|
|
491 |
MSG_DEBUG("Processing button " << handleToString(handle) << " from parent " << handleToString(parent));
|
5 |
andreas |
492 |
|
6 |
andreas |
493 |
if (!par)
|
|
|
494 |
{
|
21 |
andreas |
495 |
MSG_WARNING("Button " << handle << " has no parent (" << parent << ")! Ignoring it.");
|
14 |
andreas |
496 |
draw_mutex.unlock();
|
6 |
andreas |
497 |
return;
|
|
|
498 |
}
|
|
|
499 |
|
5 |
andreas |
500 |
if (!obj)
|
|
|
501 |
{
|
6 |
andreas |
502 |
MSG_DEBUG("Adding new object ...");
|
5 |
andreas |
503 |
obj = addObject();
|
|
|
504 |
|
|
|
505 |
if (!obj)
|
|
|
506 |
{
|
|
|
507 |
MSG_ERROR("Error creating an object!");
|
|
|
508 |
TError::setError();
|
14 |
andreas |
509 |
draw_mutex.unlock();
|
5 |
andreas |
510 |
return;
|
|
|
511 |
}
|
|
|
512 |
|
|
|
513 |
obj->type = OBJ_BUTTON;
|
|
|
514 |
obj->handle = handle;
|
|
|
515 |
obj->width = width;
|
|
|
516 |
obj->height = height;
|
|
|
517 |
obj->left = left;
|
|
|
518 |
obj->top = top;
|
6 |
andreas |
519 |
obj->object.label = new QLabel("", par->object.widget);
|
15 |
andreas |
520 |
obj->object.label->installEventFilter(this);
|
6 |
andreas |
521 |
}
|
14 |
andreas |
522 |
else
|
|
|
523 |
MSG_DEBUG("Object " << handleToString(handle) << " of type " << objectToString(obj->type) << " found!");
|
5 |
andreas |
524 |
|
6 |
andreas |
525 |
obj->object.label->setFixedSize(width, height);
|
|
|
526 |
obj->object.label->move(left, top);
|
10 |
andreas |
527 |
obj->object.label->setAttribute(Qt::WA_TransparentForMouseEvents);
|
6 |
andreas |
528 |
MSG_DEBUG("Geometry: l:" << left << ", t:" << top << ", w:" << width << ", h:" << height);
|
|
|
529 |
|
14 |
andreas |
530 |
if (buffer.size() > 0 && pixline > 0)
|
6 |
andreas |
531 |
{
|
14 |
andreas |
532 |
MSG_DEBUG("Adding image for " << handleToString(handle) << " ...");
|
|
|
533 |
QImage img((unsigned char *)buffer.data(), width, height, pixline, QImage::Format_ARGB32);
|
6 |
andreas |
534 |
QPixmap pixmap(width, height);
|
|
|
535 |
pixmap.convertFromImage(img);
|
|
|
536 |
obj->object.label->setPixmap(pixmap);
|
5 |
andreas |
537 |
}
|
6 |
andreas |
538 |
else
|
|
|
539 |
{
|
|
|
540 |
MSG_DEBUG("No image found.");
|
|
|
541 |
}
|
5 |
andreas |
542 |
|
6 |
andreas |
543 |
obj->object.label->show();
|
14 |
andreas |
544 |
draw_mutex.unlock();
|
4 |
andreas |
545 |
}
|
|
|
546 |
|
5 |
andreas |
547 |
void MainWindow::setPage(ulong handle, int width, int height)
|
|
|
548 |
{
|
14 |
andreas |
549 |
draw_mutex.lock();
|
5 |
andreas |
550 |
DECL_TRACER("MainWindow::setPage(ulong handle, int width, int height)");
|
4 |
andreas |
551 |
|
6 |
andreas |
552 |
QSize qs = menuBar()->sizeHint();
|
|
|
553 |
this->setMinimumSize(width, height + qs.height());
|
|
|
554 |
|
5 |
andreas |
555 |
OBJECT_t *obj = findObject(handle);
|
|
|
556 |
|
|
|
557 |
if (!obj)
|
|
|
558 |
{
|
|
|
559 |
obj = addObject();
|
|
|
560 |
|
|
|
561 |
if (!obj)
|
|
|
562 |
{
|
|
|
563 |
MSG_ERROR("Error crating an object for handle " << handleToString(handle));
|
|
|
564 |
TError::setError();
|
14 |
andreas |
565 |
draw_mutex.unlock();
|
5 |
andreas |
566 |
return;
|
|
|
567 |
}
|
|
|
568 |
|
|
|
569 |
obj->handle = handle;
|
|
|
570 |
obj->height = height;
|
|
|
571 |
obj->width = width;
|
|
|
572 |
obj->type = OBJ_PAGE;
|
|
|
573 |
}
|
6 |
andreas |
574 |
|
|
|
575 |
bool newBackground = false;
|
|
|
576 |
|
|
|
577 |
if (!mBackground)
|
|
|
578 |
{
|
|
|
579 |
mBackground = new QWidget();
|
|
|
580 |
mBackground->setAutoFillBackground(true);
|
|
|
581 |
mBackground->setFixedSize(obj->width, obj->height);
|
10 |
andreas |
582 |
QRect rectBack = mBackground->geometry();
|
|
|
583 |
QRect rectMain = this->geometry();
|
|
|
584 |
pageManager->setFirstTopPixel(rectMain.height() - rectBack.height());
|
6 |
andreas |
585 |
newBackground = true;
|
|
|
586 |
}
|
|
|
587 |
|
|
|
588 |
// By default set a transparent background
|
|
|
589 |
QPixmap pix(width, height);
|
|
|
590 |
pix.fill(QColor::fromRgba(qRgba(0,0,0,0xff)));
|
|
|
591 |
QPalette palette;
|
|
|
592 |
palette.setBrush(QPalette::Window, pix);
|
|
|
593 |
mBackground->setPalette(palette);
|
|
|
594 |
|
|
|
595 |
if (newBackground)
|
|
|
596 |
this->setCentralWidget(mBackground);
|
|
|
597 |
|
|
|
598 |
mBackground->show();
|
14 |
andreas |
599 |
draw_mutex.unlock();
|
5 |
andreas |
600 |
}
|
|
|
601 |
|
|
|
602 |
void MainWindow::setSubPage(ulong handle, int left, int top, int width, int height)
|
|
|
603 |
{
|
14 |
andreas |
604 |
draw_mutex.lock();
|
5 |
andreas |
605 |
DECL_TRACER("MainWindow::setSubPage(ulong handle, int left, int top, int width, int height)");
|
|
|
606 |
|
|
|
607 |
OBJECT_t *obj = addObject();
|
|
|
608 |
|
|
|
609 |
if (!obj)
|
|
|
610 |
{
|
|
|
611 |
MSG_ERROR("Error adding an object!");
|
|
|
612 |
TError::setError();
|
14 |
andreas |
613 |
draw_mutex.unlock();
|
5 |
andreas |
614 |
return;
|
|
|
615 |
}
|
|
|
616 |
|
|
|
617 |
obj->type = OBJ_SUBPAGE;
|
|
|
618 |
obj->handle = handle;
|
13 |
andreas |
619 |
obj->object.widget = new QWidget(centralWidget());
|
6 |
andreas |
620 |
obj->object.widget->setAutoFillBackground(true);
|
|
|
621 |
obj->object.widget->setFixedSize(width, height);
|
|
|
622 |
obj->object.widget->move(left, top);
|
5 |
andreas |
623 |
obj->left = left;
|
|
|
624 |
obj->top = top;
|
|
|
625 |
obj->width = width;
|
|
|
626 |
obj->height = height;
|
15 |
andreas |
627 |
// filter move event
|
|
|
628 |
obj->object.widget->installEventFilter(this);
|
5 |
andreas |
629 |
// By default set a transparent background
|
|
|
630 |
QPixmap pix(width, height);
|
|
|
631 |
pix.fill(QColor::fromRgba(qRgba(0,0,0,0xff)));
|
|
|
632 |
QPalette palette;
|
18 |
andreas |
633 |
palette.setBrush(QPalette::Window, QBrush(pix));
|
5 |
andreas |
634 |
obj->object.widget->setPalette(palette);
|
14 |
andreas |
635 |
draw_mutex.unlock();
|
5 |
andreas |
636 |
}
|
|
|
637 |
|
14 |
andreas |
638 |
void MainWindow::setBackground(ulong handle, QByteArray image, size_t rowBytes, ulong color)
|
5 |
andreas |
639 |
{
|
14 |
andreas |
640 |
draw_mutex.lock();
|
5 |
andreas |
641 |
DECL_TRACER("MainWindow::setBackground(ulong handle, unsigned char* image, size_t size, size_t rowBytes, ulong color)");
|
|
|
642 |
|
|
|
643 |
OBJECT_t *obj = findObject(handle);
|
|
|
644 |
|
|
|
645 |
if (!obj)
|
|
|
646 |
{
|
13 |
andreas |
647 |
MSG_WARNING("No object " << handleToString(handle) << " found!");
|
14 |
andreas |
648 |
draw_mutex.unlock();
|
5 |
andreas |
649 |
return;
|
|
|
650 |
}
|
|
|
651 |
|
14 |
andreas |
652 |
MSG_DEBUG("Object " << handleToString(handle) << " of type " << objectToString(obj->type) << " found!");
|
5 |
andreas |
653 |
|
6 |
andreas |
654 |
if (obj->type == OBJ_BUTTON || obj->type == OBJ_SUBPAGE)
|
5 |
andreas |
655 |
{
|
14 |
andreas |
656 |
MSG_DEBUG("Processing object " << objectToString(obj->type));
|
6 |
andreas |
657 |
QPixmap pix(obj->width, obj->height);
|
|
|
658 |
pix.fill(QColor::fromRgba(qRgba(TColor::getRed(color),TColor::getGreen(color),TColor::getBlue(color),TColor::getAlpha(color))));
|
5 |
andreas |
659 |
|
14 |
andreas |
660 |
if (image.size() > 0)
|
5 |
andreas |
661 |
{
|
18 |
andreas |
662 |
MSG_DEBUG("Setting image of size " << image.size());
|
14 |
andreas |
663 |
QImage img((unsigned char *)image.data(), obj->width, obj->height, rowBytes, QImage::Format_ARGB32);
|
6 |
andreas |
664 |
pix.convertFromImage(img);
|
|
|
665 |
}
|
|
|
666 |
|
|
|
667 |
if (obj->type == OBJ_BUTTON)
|
|
|
668 |
{
|
5 |
andreas |
669 |
obj->object.label->setPixmap(pix);
|
6 |
andreas |
670 |
obj->object.label->show();
|
5 |
andreas |
671 |
}
|
6 |
andreas |
672 |
else
|
5 |
andreas |
673 |
{
|
19 |
andreas |
674 |
MSG_DEBUG("Setting image as background for page " << ((handle >> 16) & 0x0000ffff));
|
5 |
andreas |
675 |
QPalette palette;
|
18 |
andreas |
676 |
palette.setBrush(QPalette::Window, QBrush(pix));
|
|
|
677 |
// FIXME: Background image is not visible!
|
6 |
andreas |
678 |
obj->object.widget->setPalette(palette);
|
|
|
679 |
obj->object.widget->show();
|
5 |
andreas |
680 |
}
|
|
|
681 |
}
|
6 |
andreas |
682 |
else if (obj->type == OBJ_PAGE)
|
5 |
andreas |
683 |
{
|
6 |
andreas |
684 |
bool newBackground = false;
|
5 |
andreas |
685 |
|
6 |
andreas |
686 |
if (!mBackground)
|
5 |
andreas |
687 |
{
|
6 |
andreas |
688 |
mBackground = new QWidget();
|
|
|
689 |
mBackground->setAutoFillBackground(true);
|
|
|
690 |
mBackground->setFixedSize(obj->width, obj->height);
|
|
|
691 |
newBackground = true;
|
|
|
692 |
MSG_DEBUG("New background image added to page with size " << obj->width << " x " << obj->height);
|
5 |
andreas |
693 |
}
|
6 |
andreas |
694 |
|
|
|
695 |
QPixmap pix(obj->width, obj->height);
|
|
|
696 |
pix.fill(QColor::fromRgba(qRgba(TColor::getRed(color),TColor::getGreen(color),TColor::getBlue(color),TColor::getAlpha(color))));
|
|
|
697 |
|
14 |
andreas |
698 |
if (image.size() > 0)
|
5 |
andreas |
699 |
{
|
14 |
andreas |
700 |
QImage img((unsigned char *)image.data(), obj->width, obj->height, rowBytes, QImage::Format_ARGB32);
|
5 |
andreas |
701 |
pix.convertFromImage(img);
|
6 |
andreas |
702 |
}
|
5 |
andreas |
703 |
|
6 |
andreas |
704 |
QPalette palette;
|
18 |
andreas |
705 |
palette.setBrush(QPalette::Window, QBrush(pix));
|
6 |
andreas |
706 |
mBackground->setPalette(palette);
|
|
|
707 |
|
|
|
708 |
if (newBackground)
|
|
|
709 |
this->setCentralWidget(mBackground);
|
|
|
710 |
|
|
|
711 |
mBackground->show();
|
|
|
712 |
MSG_DEBUG("Background set");
|
5 |
andreas |
713 |
}
|
14 |
andreas |
714 |
|
|
|
715 |
draw_mutex.unlock();
|
5 |
andreas |
716 |
}
|
|
|
717 |
|
7 |
andreas |
718 |
void MainWindow::setText(ulong handle, const std::string& text, const std::string& font, const std::string& family, int size, int x, int y, ulong color, ulong effectColor, FONT_STYLE style, Button::TEXT_ORIENTATION ori, Button::TEXT_EFFECT effect, bool ww)
|
|
|
719 |
{
|
14 |
andreas |
720 |
draw_mutex.lock();
|
7 |
andreas |
721 |
DECL_TRACER("MainWindow::setText(ulong handle, const std::string& text, const std::string& font, int size, int x, int y, ulong color, ulong effectColor, FONT_STYLE style, Button::TEXT_ORIENTATION ori, Button::TEXT_EFFECT effect, bool ww)");
|
5 |
andreas |
722 |
|
7 |
andreas |
723 |
OBJECT_t *obj = findObject(handle);
|
|
|
724 |
|
|
|
725 |
if (!obj)
|
|
|
726 |
{
|
|
|
727 |
MSG_ERROR("Object " << handleToString(handle) << " not found!");
|
|
|
728 |
TError::setError();
|
14 |
andreas |
729 |
draw_mutex.unlock();
|
7 |
andreas |
730 |
return;
|
|
|
731 |
}
|
|
|
732 |
|
|
|
733 |
if (!obj->object.label)
|
|
|
734 |
{
|
|
|
735 |
MSG_ERROR("Object " << handleToString(handle) << " contains no child element!");
|
|
|
736 |
TError::setError();
|
14 |
andreas |
737 |
draw_mutex.unlock();
|
7 |
andreas |
738 |
return;
|
|
|
739 |
}
|
14 |
andreas |
740 |
|
|
|
741 |
MSG_DEBUG("Object " << handleToString(handle) << " of type " << objectToString(obj->type) << " found!");
|
|
|
742 |
|
10 |
andreas |
743 |
#if !defined(QT_DISABLE_DEPRECATED_BEFORE) || (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
|
9 |
andreas |
744 |
QPixmap pix = *obj->object.label->pixmap();
|
|
|
745 |
#else
|
7 |
andreas |
746 |
QPixmap pix = obj->object.label->pixmap(Qt::ReturnByValue);
|
9 |
andreas |
747 |
#endif
|
7 |
andreas |
748 |
// Load the font
|
|
|
749 |
int fontID = 0;
|
|
|
750 |
|
|
|
751 |
if ((fontID = QFontDatabase::addApplicationFont(font.c_str())) == -1)
|
|
|
752 |
{
|
|
|
753 |
MSG_ERROR("Font " << font << " could not be loaded!");
|
|
|
754 |
TError::setError();
|
14 |
andreas |
755 |
draw_mutex.unlock();
|
7 |
andreas |
756 |
return;
|
|
|
757 |
}
|
|
|
758 |
|
|
|
759 |
QFont ft;
|
|
|
760 |
ft.setFamily(family.c_str());
|
|
|
761 |
ft.setPointSize(size);
|
|
|
762 |
|
|
|
763 |
switch (style)
|
|
|
764 |
{
|
|
|
765 |
case FONT_BOLD: ft.setBold(true); break;
|
|
|
766 |
case FONT_ITALIC: ft.setItalic(true); break;
|
|
|
767 |
case FONT_BOLD_ITALIC:
|
|
|
768 |
ft.setBold(true);
|
|
|
769 |
ft.setItalic(true);
|
|
|
770 |
break;
|
|
|
771 |
|
|
|
772 |
default:
|
|
|
773 |
ft.setBold(false);
|
|
|
774 |
ft.setItalic(false);
|
|
|
775 |
}
|
|
|
776 |
|
|
|
777 |
QPalette palette = obj->object.label->palette();
|
|
|
778 |
palette.setColor(QPalette::WindowText, QColor::fromRgba(qRgba(TColor::getRed(color),TColor::getGreen(color),TColor::getBlue(color),TColor::getAlpha(color))));
|
|
|
779 |
obj->object.label->setPalette(palette);
|
|
|
780 |
obj->object.label->setFont(ft);
|
|
|
781 |
obj->object.label->setWordWrap(ww);
|
|
|
782 |
obj->object.label->setIndent(4);
|
|
|
783 |
|
|
|
784 |
switch (ori)
|
|
|
785 |
{
|
|
|
786 |
case Button::ORI_ABSOLUT:
|
|
|
787 |
{
|
|
|
788 |
QString pos = "<font style=\"position: absolute;left:";
|
|
|
789 |
pos.append(x);
|
|
|
790 |
pos.append(";top:");
|
|
|
791 |
pos.append(y);
|
|
|
792 |
pos.append(";>");
|
|
|
793 |
pos.append(text.c_str());
|
|
|
794 |
pos.append("</font>");
|
|
|
795 |
MSG_DEBUG("Text: " << pos.data());
|
|
|
796 |
}
|
|
|
797 |
break;
|
|
|
798 |
|
|
|
799 |
case Button::ORI_TOP_LEFT: obj->object.label->setAlignment(Qt::AlignTop | Qt::AlignLeft); break;
|
|
|
800 |
case Button::ORI_TOP_MIDDLE: obj->object.label->setAlignment(Qt::AlignTop | Qt::AlignHCenter); break;
|
|
|
801 |
case Button::ORI_TOP_RIGHT: obj->object.label->setAlignment(Qt::AlignTop | Qt::AlignRight); break;
|
|
|
802 |
case Button::ORI_CENTER_LEFT: obj->object.label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); break;
|
|
|
803 |
case Button::ORI_CENTER_MIDDLE: obj->object.label->setAlignment(Qt::AlignCenter); break;
|
|
|
804 |
case Button::ORI_CENTER_RIGHT: obj->object.label->setAlignment(Qt::AlignVCenter | Qt::AlignRight); break;
|
|
|
805 |
case Button::ORI_BOTTOM_LEFT: obj->object.label->setAlignment(Qt::AlignBottom | Qt::AlignLeft); break;
|
|
|
806 |
case Button::ORI_BOTTOM_MIDDLE: obj->object.label->setAlignment(Qt::AlignBottom | Qt::AlignHCenter); break;
|
|
|
807 |
case Button::ORI_BOTTOM_RIGHT: obj->object.label->setAlignment(Qt::AlignBottom | Qt::AlignRight); break;
|
|
|
808 |
}
|
|
|
809 |
|
|
|
810 |
obj->object.label->setText(text.c_str());
|
14 |
andreas |
811 |
draw_mutex.unlock();
|
7 |
andreas |
812 |
}
|
|
|
813 |
|
11 |
andreas |
814 |
void MainWindow::dropPage(ulong handle)
|
|
|
815 |
{
|
14 |
andreas |
816 |
draw_mutex.lock();
|
11 |
andreas |
817 |
DECL_TRACER("MainWindow::dropPage(ulong handle)");
|
7 |
andreas |
818 |
|
11 |
andreas |
819 |
removeAllChilds(handle);
|
|
|
820 |
removeObject(handle);
|
|
|
821 |
|
|
|
822 |
if (mBackground)
|
|
|
823 |
{
|
|
|
824 |
delete mBackground;
|
|
|
825 |
mBackground = nullptr;
|
|
|
826 |
}
|
14 |
andreas |
827 |
|
|
|
828 |
draw_mutex.unlock();
|
11 |
andreas |
829 |
}
|
|
|
830 |
|
|
|
831 |
void MainWindow::dropSubPage(ulong handle)
|
|
|
832 |
{
|
14 |
andreas |
833 |
draw_mutex.lock();
|
11 |
andreas |
834 |
DECL_TRACER("MainWindow::dropSubPage(ulong handle)");
|
|
|
835 |
|
|
|
836 |
removeAllChilds(handle);
|
|
|
837 |
OBJECT_t *obj = findObject(handle);
|
|
|
838 |
|
|
|
839 |
if (!obj)
|
|
|
840 |
{
|
|
|
841 |
MSG_WARNING("Object " << handleToString(handle) << " does not exist. Ignoring!");
|
14 |
andreas |
842 |
draw_mutex.unlock();
|
11 |
andreas |
843 |
return;
|
|
|
844 |
}
|
|
|
845 |
|
14 |
andreas |
846 |
dropContent(obj);
|
11 |
andreas |
847 |
removeObject(handle);
|
14 |
andreas |
848 |
draw_mutex.unlock();
|
11 |
andreas |
849 |
}
|
|
|
850 |
|
21 |
andreas |
851 |
void MainWindow::playVideo(ulong handle, ulong parent, int left, int top, int width, int height, const string& url, const string& user, const string& pw)
|
|
|
852 |
{
|
|
|
853 |
draw_mutex.lock();
|
|
|
854 |
DECL_TRACER("MainWindow::playVideo(ulong handle, const string& url, const string& user, const string& pw))");
|
|
|
855 |
|
|
|
856 |
OBJECT_t *obj = findObject(handle);
|
|
|
857 |
OBJECT_t *par = findObject(parent);
|
|
|
858 |
MSG_DEBUG("Processing button " << handleToString(handle) << " from parent " << handleToString(parent));
|
|
|
859 |
|
|
|
860 |
if (!par)
|
|
|
861 |
{
|
|
|
862 |
MSG_WARNING("Button has no parent! Ignoring it.");
|
|
|
863 |
draw_mutex.unlock();
|
|
|
864 |
return;
|
|
|
865 |
}
|
|
|
866 |
|
|
|
867 |
if (!obj)
|
|
|
868 |
{
|
|
|
869 |
MSG_DEBUG("Adding new video object ...");
|
|
|
870 |
obj = addObject();
|
|
|
871 |
|
|
|
872 |
if (!obj)
|
|
|
873 |
{
|
|
|
874 |
MSG_ERROR("Error creating a video object!");
|
|
|
875 |
TError::setError();
|
|
|
876 |
draw_mutex.unlock();
|
|
|
877 |
return;
|
|
|
878 |
}
|
|
|
879 |
|
|
|
880 |
obj->type = OBJ_VIDEO;
|
|
|
881 |
obj->handle = handle;
|
|
|
882 |
obj->width = width;
|
|
|
883 |
obj->height = height;
|
|
|
884 |
obj->left = left;
|
|
|
885 |
obj->top = top;
|
|
|
886 |
obj->object.vwidget = new QVideoWidget(par->object.widget);
|
|
|
887 |
obj->object.vwidget->installEventFilter(this);
|
|
|
888 |
}
|
|
|
889 |
else
|
|
|
890 |
MSG_DEBUG("Object " << handleToString(handle) << " of type " << objectToString(obj->type) << " found!");
|
|
|
891 |
|
|
|
892 |
QMediaPlaylist *playlist = new QMediaPlaylist;
|
|
|
893 |
QUrl qurl(url.c_str());
|
|
|
894 |
|
|
|
895 |
if (!user.empty())
|
|
|
896 |
qurl.setUserName(user.c_str());
|
|
|
897 |
|
|
|
898 |
if (!pw.empty())
|
|
|
899 |
qurl.setPassword(pw.c_str());
|
|
|
900 |
|
|
|
901 |
playlist->addMedia(qurl);
|
|
|
902 |
obj->player = new QMediaPlayer;
|
|
|
903 |
obj->player->setPlaylist(playlist);
|
|
|
904 |
obj->player->setVideoOutput(obj->object.vwidget);
|
|
|
905 |
obj->object.vwidget->show();
|
|
|
906 |
obj->player->play();
|
|
|
907 |
}
|
|
|
908 |
|
2 |
andreas |
909 |
#ifndef QT_NO_SESSIONMANAGER
|
|
|
910 |
void MainWindow::commitData(QSessionManager &manager)
|
|
|
911 |
{
|
5 |
andreas |
912 |
if (manager.allowsInteraction())
|
|
|
913 |
{
|
|
|
914 |
if (!settingsChanged)
|
|
|
915 |
manager.cancel();
|
|
|
916 |
}
|
|
|
917 |
else
|
|
|
918 |
{
|
|
|
919 |
if (settingsChanged)
|
|
|
920 |
writeSettings();
|
|
|
921 |
}
|
2 |
andreas |
922 |
}
|
5 |
andreas |
923 |
#endif
|