swift
Loading...
Searching...
No Matches
simulatorselector.cpp
1// SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3
5
6#include <QCheckBox>
7#include <QPointer>
8#include <QRadioButton>
9#include <QWidget>
10#include <QtGlobal>
11
12#include "ui_simulatorselector.h"
13
14#include "config/buildconfig.h"
16#include "gui/guiapplication.h"
17#include "gui/guiutility.h"
18#include "misc/icons.h"
20
21using namespace swift::config;
22using namespace swift::misc;
23using namespace swift::misc::simulation;
24using namespace swift::core::context;
25
27{
29 {
30 ui->setupUi(this);
31
32 this->addComboxBoxValues();
33 this->setMode(CheckBoxes, true);
34
35 connect(ui->rb_P3D, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
36 connect(ui->rb_FG, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
37 connect(ui->rb_XPlane, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
38 connect(ui->rb_MSFS, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
39 connect(ui->rb_MSFS2024, &QRadioButton::toggled, this, &CSimulatorSelector::radioButtonChanged);
40
41 connect(ui->cb_P3D, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
42 connect(ui->cb_FG, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
43 connect(ui->cb_XPlane, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
44 connect(ui->cb_MSFS, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
45 connect(ui->cb_MSFS2024, &QRadioButton::toggled, this, &CSimulatorSelector::checkBoxChanged);
46
47 connect(ui->cb_Simulators, &QComboBox::currentTextChanged, this, &CSimulatorSelector::comboBoxChanged);
48 }
49
51
53 {
54 if (m_mode == mode && !forced)
55 {
56 return;
57 }
58 m_mode = mode;
59
60 ui->wi_CheckBoxes->setVisible(false);
61 ui->wi_RadioButtons->setVisible(false);
62 ui->wi_ComboBox->setVisible(false);
63
64 switch (mode)
65 {
66 default:
67 case CheckBoxes: ui->wi_CheckBoxes->setVisible(true); break;
68 case RadioButtons: ui->wi_RadioButtons->setVisible(true); break;
69 case ComboBox: ui->wi_ComboBox->setVisible(true); break;
70 }
71 this->setToLastSelection();
72 }
73
75 {
76 if (m_noSelectionMeansAll && this->isUnselected())
77 {
79 }
80
81 switch (m_mode)
82 {
83 default:
84 case CheckBoxes:
85 return { ui->cb_XPlane->isChecked(), ui->cb_P3D->isChecked(), ui->cb_FG->isChecked(),
86 ui->cb_MSFS->isChecked(), ui->cb_MSFS2024->isChecked() };
87 case RadioButtons:
88 return { ui->rb_XPlane->isChecked(), ui->rb_P3D->isChecked(), ui->rb_FG->isChecked(),
89 ui->rb_MSFS->isChecked(), ui->rb_MSFS2024->isChecked() };
90 case ComboBox: return { ui->cb_Simulators->currentText() };
91 }
92 }
93
95 {
96 const CSimulatorInfo current(this->getValue());
97 if (simulator == current)
98 {
99 return;
100 } // avoid unnecessary signals
101
102 // checkboxes
103 ui->cb_XPlane->setChecked(simulator.isXPlane());
104 ui->cb_P3D->setChecked(simulator.isP3D());
105 ui->cb_FG->setChecked(simulator.isFG());
106 ui->cb_MSFS->setChecked(simulator.isMSFS());
107 ui->cb_MSFS2024->setChecked(simulator.isMSFS2024());
108
109 // Combo
110 ui->cb_Simulators->setCurrentText(simulator.toQString(true));
111
112 // radio buttons
113 if (simulator.isXPlane())
114 {
115 ui->rb_XPlane->setChecked(simulator.isXPlane());
116 return;
117 }
118 if (simulator.isP3D())
119 {
120 ui->rb_P3D->setChecked(simulator.isP3D());
121 return;
122 }
123 if (simulator.isFG())
124 {
125 ui->rb_FG->setChecked(simulator.isFG());
126 return;
127 }
128 if (simulator.isMSFS())
129 {
130 ui->rb_MSFS->setChecked(simulator.isMSFS());
131 return;
132 }
133 if (simulator.isMSFS2024())
134 {
135 ui->rb_MSFS2024->setChecked(simulator.isMSFS2024());
136 return;
137 }
138 }
139
141 {
142 const CSimulatorInfo simulator =
143 (m_mode == RadioButtons || m_mode == ComboBox) ? m_currentSimulator.get() : m_currentSimulators.get();
144 this->setValue(simulator);
145 }
146
148 {
149 if (sGui && sGui->supportsContexts() && sGui->getIContextSimulator())
150 {
151 const CSimulatorPluginInfo pluginInfo = sGui->getIContextSimulator()->getSimulatorPluginInfo();
152 if (!this->isSingleSelection())
153 {
154 this->setMode(RadioButtons);
155 } // only one sim can be connected
156
157 if (pluginInfo.isValid())
158 {
159 this->setReadOnly(makeReadOnly);
160 this->setValue(pluginInfo.getSimulator());
161 }
162 else
163 {
164 if (makeReadOnly)
165 {
166 this->setReadOnly(false);
167 }
168 const CSimulatorInfo simulator = sGui->getIContextSimulator()->getModelSetLoaderSimulator();
169 if (simulator.isSingleSimulator())
170 {
171 this->setValue(simulator);
172 }
173 }
174 }
175 else
176 {
177 if (makeReadOnly)
178 {
179 this->setReadOnly(false);
180 }
181 }
182 }
183
184 void CSimulatorSelector::setToConnectedSimulator(int deferredMs, bool makeReadOnly)
185 {
186 if (deferredMs < 1)
187 {
188 this->setToConnectedSimulator(makeReadOnly);
189 return;
190 }
191
192 if (!sGui || sGui->isShuttingDown())
193 {
194 return;
195 }
196 QPointer<CSimulatorSelector> myself(this);
197 QTimer::singleShot(deferredMs, this, [=, this] {
198 if (!sGui || sGui->isShuttingDown() || !myself)
199 {
200 return;
201 }
202 this->setToConnectedSimulator(makeReadOnly);
203 });
204 }
205
207 {
208 ui->cb_XPlane->setVisible(false);
209 ui->cb_FG->setVisible(false);
210 ui->rb_XPlane->setVisible(false);
211 ui->rb_FG->setVisible(false);
212 }
213
215 {
216 ui->cb_FG->setVisible(enabled);
217 ui->rb_FG->setVisible(enabled);
218 ui->cb_FG->setChecked(false);
219 ui->rb_FG->setChecked(false);
220 }
221
223 {
224 // checkboxes
225 ui->cb_XPlane->setChecked(true);
226 ui->cb_P3D->setChecked(true);
227 ui->cb_FG->setChecked(true);
228 ui->cb_MSFS->setChecked(true);
229 ui->cb_MSFS2024->setChecked(true);
230
231 // radio
232 ui->rb_P3D->setChecked(true);
233 }
234
236 {
237 // checkboxes
238 ui->cb_XPlane->setChecked(false);
239 ui->cb_P3D->setChecked(false);
240 ui->cb_FG->setChecked(false);
241 ui->cb_MSFS->setChecked(false);
242 ui->cb_MSFS2024->setChecked(false);
243 }
244
246 {
247 bool c = false;
248 switch (m_mode)
249 {
250 default:
251 case CheckBoxes:
252 c = ui->cb_XPlane->isChecked() || ui->cb_P3D->isChecked() || ui->cb_FG->isChecked() ||
253 ui->cb_MSFS->isChecked() || ui->cb_MSFS2024->isChecked();
254 break;
255 case RadioButtons:
256 c = ui->rb_XPlane->isChecked() || ui->rb_P3D->isChecked() || ui->rb_FG->isChecked() ||
257 ui->rb_MSFS->isChecked() || ui->rb_MSFS2024->isChecked();
258 break;
259 case ComboBox:
260 const int i = ui->cb_Simulators->currentIndex();
261 c = i < 0;
262 break;
263 }
264 return !c;
265 }
266
268 {
269 bool c = false;
270 switch (m_mode)
271 {
272 default:
273 case CheckBoxes:
274 c = ui->cb_XPlane->isChecked() && ui->cb_P3D->isChecked() && ui->cb_FG->isChecked() &&
275 ui->cb_MSFS->isChecked() && ui->cb_MSFS2024->isChecked();
276 break;
277 case RadioButtons:
278 // actually this should never be true
279 c = false;
280 break;
281 case ComboBox:
282 // actually this should never be true
283 c = false;
284 break;
285 }
286 return c;
287 }
288
290 {
291 QMargins m = ui->hl_RadioButtons->contentsMargins();
292 m.setLeft(margin);
293 ui->hl_RadioButtons->setContentsMargins(m);
294
295 m = ui->hl_CheckBoxes->contentsMargins();
296 m.setLeft(margin);
297 ui->hl_CheckBoxes->setContentsMargins(m);
298 }
299
305
307 {
308 if (m_mode == CheckBoxes)
309 {
310 this->uncheckAll();
311 }
312 }
313
314 bool CSimulatorSelector::isSingleSelection() const { return m_mode == RadioButtons || m_mode == ComboBox; }
315
317 {
318 CGuiUtility::checkBoxesReadOnly(this, readOnly);
319 ui->rb_XPlane->setEnabled(!readOnly);
320 ui->rb_P3D->setEnabled(!readOnly);
321 ui->rb_FG->setEnabled(!readOnly);
322 ui->rb_MSFS->setEnabled(!readOnly);
323 ui->rb_MSFS2024->setEnabled(!readOnly);
324
325 ui->cb_Simulators->setEnabled(!readOnly);
326
327 this->setEnabled(!readOnly);
328 }
329
330 void CSimulatorSelector::radioButtonChanged(bool checked)
331 {
332 if (m_mode != RadioButtons)
333 {
334 return;
335 }
336 if (!checked)
337 {
338 return;
339 } // only the checked ones are relevant, as the unchecked ones are accompanied with checked events
340 m_digestButtonsChanged.inputSignal();
341 }
342
343 void CSimulatorSelector::checkBoxChanged(bool checked)
344 {
345 if (m_mode != CheckBoxes)
346 {
347 return;
348 }
349 Q_UNUSED(checked);
350 m_digestButtonsChanged.inputSignal();
351 }
352
353 void CSimulatorSelector::comboBoxChanged(const QString &value)
354 {
355 if (m_mode != ComboBox)
356 {
357 return;
358 }
359 Q_UNUSED(value);
360 m_digestButtonsChanged.inputSignal();
361 }
362
363 void CSimulatorSelector::rememberSelection()
364 {
365 if (!m_rememberSelection)
366 {
367 return;
368 }
369 if (this->isSingleSelection())
370 {
371 // single
372 const CSimulatorInfo sim = this->getValue();
373 m_currentSimulator.set(sim);
374 }
375 else
376 {
377 // multiple
378 const CSimulatorInfo sim = this->getValue();
379 m_currentSimulators.set(sim);
380 }
381 }
382
383 void CSimulatorSelector::changedLastSelection()
384 {
385 // force decoupled update
386 this->triggerSetToLastSelection();
387 }
388
389 void CSimulatorSelector::changedLastSelectionRb()
390 {
391 // force decoupled update
392 if (m_mode != RadioButtons)
393 {
394 return;
395 }
396 this->triggerSetToLastSelection();
397 }
398
399 void CSimulatorSelector::changedLastSelectionCb()
400 {
401 // force decoupled update
402 if (m_mode != CheckBoxes)
403 {
404 return;
405 }
406 this->triggerSetToLastSelection();
407 }
408
409 void CSimulatorSelector::triggerSetToLastSelection()
410 {
411 QPointer<CSimulatorSelector> myself(this);
412 QTimer::singleShot(100, this, [=, this] {
413 if (!myself)
414 {
415 return;
416 }
417 this->setToLastSelection();
418 });
419 }
420
421 void CSimulatorSelector::emitChangedSignal()
422 {
423 const CSimulatorInfo simulator(this->getValue());
424 this->rememberSelection();
425 emit this->changed(simulator);
426 }
427
428 void CSimulatorSelector::addComboxBoxValues()
429 {
430 int cbi = 0;
431 ui->cb_Simulators->clear();
432 ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::p3d().toQString());
433 ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::xplane().toQString());
434 ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::fg().toQString());
435 ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::msfs().toQString());
436 ui->cb_Simulators->insertItem(cbi++, CSimulatorInfo::msfs2024().toQString());
437 }
438} // namespace swift::gui::components
static void checkBoxesReadOnly(QWidget *parent, bool readOnly)
Pseudo readonly state for checkboxes of widget.
void setToLastSelection()
Set to last selection.
CSimulatorSelector(QWidget *parent=nullptr)
Constructor.
void setMode(Mode mode, bool forced=false)
How to display.
bool isUnselected() const
Not selected at all.
bool isSingleSelection() const
Single selection mode (radio buttons).
void setRememberSelectionAndSetToLastSelection()
Remember selection.
void setReadOnly(bool readOnly)
Set read only.
void setValue(const swift::misc::simulation::CSimulatorInfo &simulator)
Set the value.
void setRememberSelection(bool remember)
Remember selection.
void setLeftMargin(int margin)
Set left margin.
void uncheckAll()
Unset all, only making sense with checkboxes.
void changed(const swift::misc::simulation::CSimulatorInfo &simulator)
Value has been changed.
void setToConnectedSimulator(bool makeReadOnly=true)
Set to the connected simulator.
swift::misc::simulation::CSimulatorInfo getValue() const
Get the value.
void checkAll()
Set all, only making sense with checkboxes.
void inputSignal()
Received input signal, or manually trigger.
QString toQString(bool i18n=false) const
Cast as QString.
Definition mixinstring.h:74
Simple hardcoded info about the corresponding simulator.
static const CSimulatorInfo & msfs()
Const simulator info objects.
static const CSimulatorInfo & xplane()
Const simulator info objects.
static const CSimulatorInfo & p3d()
Const simulator info objects.
static const CSimulatorInfo & fg()
Const simulator info objects.
static const CSimulatorInfo & allSimulators()
All simulators.
bool isSingleSimulator() const
Single simulator selected.
static const CSimulatorInfo & msfs2024()
Const simulator info objects.
const QString & getSimulator() const
Simulator.
bool isValid() const
Check if the provided plugin metadata is valid. Simulator plugin (driver) has to meet the following r...
High level reusable GUI components.
Free functions in swift::misc.
void toggled(bool checked)
void currentTextChanged(const QString &text)
QFrame(QWidget *parent, Qt::WindowFlags f)
void setLeft(int left)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
QWidget(QWidget *parent, Qt::WindowFlags f)