swift
mainkeypadareacomponent.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <QLineEdit>
7 #include <QPointer>
8 #include <QPushButton>
9 #include <QtGlobal>
10 
11 #include "ui_mainkeypadareacomponent.h"
12 
17 #include "core/corefacade.h"
18 #include "gui/guiapplication.h"
21 
22 using namespace swift::misc;
23 using namespace swift::misc::aviation;
24 using namespace swift::misc::network;
25 using namespace swift::misc::simulation;
26 using namespace swift::core;
27 using namespace swift::core::context;
28 
29 namespace swift::gui::components
30 {
31  CMainKeypadAreaComponent::CMainKeypadAreaComponent(QWidget *parent)
32  : QFrame(parent), ui(new Ui::CMainKeypadAreaComponent)
33  {
34  ui->setupUi(this);
35 
36  // Info areas
37  // pressed collides, as this toggles button again
38  // using toggle collides, as checking/unchecking toggles again -> infinite loop
39  connect(ui->pb_MainAircrafts, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
40  connect(ui->pb_MainAtc, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
41  connect(ui->pb_MainCockpit, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
42  connect(ui->pb_MainFlightplan, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
43  connect(ui->pb_MainLog, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
44  connect(ui->pb_MainMappings, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
45  connect(ui->pb_MainInterpolation, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
46  connect(ui->pb_MainRadar, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
47  connect(ui->pb_MainSettings, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
48  connect(ui->pb_MainSimulator, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
49  connect(ui->pb_MainTextMessages, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
50  connect(ui->pb_MainUsers, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
51 
52  // non info areas
53  connect(ui->pb_Connect, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
54  connect(ui->pb_Opacity050, &QPushButton::pressed, this, &CMainKeypadAreaComponent::buttonSelected);
55  connect(ui->pb_Opacity100, &QPushButton::pressed, this, &CMainKeypadAreaComponent::buttonSelected);
56  connect(ui->pb_SoundMaxVolume, &QPushButton::pressed, this, &CMainKeypadAreaComponent::buttonSelected);
57  connect(ui->pb_CockpitIdent, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
58  connect(ui->pb_SoundMute, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
59  connect(ui->pb_Audio, &QPushButton::released, this, &CMainKeypadAreaComponent::buttonSelected);
60 
61  // command line
62  ui->lep_CommandLineInput->setIdentifier(m_identifier);
63  connect(ui->lep_CommandLineInput, &CCommandInput::commandEntered, this,
65  connect(ui->lep_CommandLineInput, &CCommandInput::textEntered, this, &CMainKeypadAreaComponent::textEntered);
66 
67  connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this,
68  &CMainKeypadAreaComponent::connectionStatusChanged);
69  connect(sGui->getIContextOwnAircraft(), &IContextOwnAircraft::changedAircraftCockpit, this,
70  &CMainKeypadAreaComponent::ownAircraftCockpitChanged);
71  connect(sGui->getCContextAudioBase(), &CContextAudioBase::changedOutputMute, this,
72  &CMainKeypadAreaComponent::outputMuteChanged);
73  connect(this, &CMainKeypadAreaComponent::commandEntered, sGui->getCoreFacade(), &CCoreFacade::parseCommandLine);
74 
75  QPointer<CMainKeypadAreaComponent> myself(this);
76  QTimer::singleShot(5000, this, [=] {
77  if (!myself || !sGui) { return; }
78  this->update();
79  });
80  }
81 
83 
84  void CMainKeypadAreaComponent::onMainInfoAreaChanged(int currentTabIndex, const QList<int> &dockedIndexes,
85  const QList<int> &floatingIndexes)
86  {
87  this->unsetInfoAreaButtons();
88  if (currentTabIndex >= 0)
89  {
90  QPushButton *pb =
91  this->mainInfoAreaToButton(static_cast<CMainInfoAreaComponent::InfoArea>(currentTabIndex));
92  if (pb)
93  {
94  Q_ASSERT(pb->isCheckable());
95  pb->setChecked(true);
96  }
97  }
98 
99  // check the floating
100  for (int floatingIndex : floatingIndexes)
101  {
102  QPushButton *pb = this->mainInfoAreaToButton(static_cast<CMainInfoAreaComponent::InfoArea>(floatingIndex));
103  if (pb) { pb->setChecked(true); }
104  }
105 
106  this->updateConnectionStatus();
107 
108  Q_UNUSED(dockedIndexes)
109  }
110 
111  void CMainKeypadAreaComponent::focusInEntryField() { ui->lep_CommandLineInput->setFocus(); }
112 
113  void CMainKeypadAreaComponent::buttonSelected()
114  {
115  if (!sGui || sGui->isShuttingDown()) { return; }
116  QPushButton *senderButton = static_cast<QPushButton *>(QObject::sender());
117  Q_ASSERT_X(senderButton, Q_FUNC_INFO, "No sender button");
118  if (!senderButton) { return; }
119  const CMainInfoAreaComponent::InfoArea infoArea = buttonToMainInfoArea(senderButton);
120  if (infoArea != CMainInfoAreaComponent::InfoAreaNone)
121  {
122  Q_ASSERT(senderButton->isCheckable());
123  emit this->selectedMainInfoAreaDockWidget(infoArea);
124  senderButton->setChecked(true); // re-check if got unchecked, we use checked buttons like normal buttons
125  return;
126  }
127  else if (senderButton == ui->pb_CockpitIdent && sGui->getIContextOwnAircraft()) { emit this->identPressed(); }
128  else if (senderButton == ui->pb_Opacity050) { emit this->changedOpacity(50); }
129  else if (senderButton == ui->pb_Opacity100) { emit this->changedOpacity(100); }
130  else if (senderButton == ui->pb_SoundMaxVolume && sGui->getIContextAudio())
131  {
133  }
134  else if (senderButton == ui->pb_SoundMute && sGui->getIContextAudio())
135  {
136  const bool mute = sGui->getCContextAudioBase()->isOutputMuted();
138  }
139  else if (senderButton == ui->pb_Connect)
140  {
141  emit this->connectPressed();
142  this->updateConnectionStatus();
143  }
144  else if (senderButton == ui->pb_Audio) { emit this->audioPressed(); }
145  }
146 
147  void CMainKeypadAreaComponent::connectionStatusChanged(const CConnectionStatus &from, const CConnectionStatus &to)
148  {
149  Q_UNUSED(from)
150 
151  // Connected button
152  if (to.isConnected())
153  {
154  ui->pb_Connect->setText("Connected");
155  ui->pb_Connect->setChecked(true);
156  // moved to stylesheet: ui->pb_Connect->setStyleSheet("background-color: green");
157  }
158  else
159  {
160  ui->pb_Connect->setText("Connect");
161  ui->pb_Connect->setChecked(false);
162  // moved to stylesheet: ui->pb_Connect->setStyleSheet("background-color: ");
163  }
164  }
165 
166  void CMainKeypadAreaComponent::ownAircraftCockpitChanged(const CSimulatedAircraft &aircraft,
167  const CIdentifier &originator)
168  {
169  Q_UNUSED(originator)
170  bool ident = aircraft.getTransponder().getTransponderMode() == CTransponder::StateIdent;
171 
172  // check state to avoid undelibarate signals
173  if (ident != ui->pb_CockpitIdent->isChecked()) { ui->pb_CockpitIdent->setChecked(ident); }
174  }
175 
176  void CMainKeypadAreaComponent::outputMuteChanged(bool muted)
177  {
178  // check state to avoid undelibarate signals
179  if (muted != ui->pb_SoundMute->isChecked()) { ui->pb_SoundMute->setChecked(muted); }
180  }
181 
182  CMainInfoAreaComponent::InfoArea CMainKeypadAreaComponent::buttonToMainInfoArea(const QObject *button) const
183  {
184  if (button == ui->pb_MainAircrafts) return CMainInfoAreaComponent::InfoAreaAircraft;
185  if (button == ui->pb_MainAtc) return CMainInfoAreaComponent::InfoAreaAtc;
186  if (button == ui->pb_MainCockpit) return CMainInfoAreaComponent::InfoAreaCockpit;
187  if (button == ui->pb_MainFlightplan) return CMainInfoAreaComponent::InfoAreaFlightPlan;
188  if (button == ui->pb_MainLog) return CMainInfoAreaComponent::InfoAreaLog;
189  if (button == ui->pb_MainMappings) return CMainInfoAreaComponent::InfoAreaMapping;
190  if (button == ui->pb_MainInterpolation) return CMainInfoAreaComponent::InfoAreaInterpolation;
191  if (button == ui->pb_MainRadar) return CMainInfoAreaComponent::InfoAreaRadar;
192  if (button == ui->pb_MainSettings) return CMainInfoAreaComponent::InfoAreaSettings;
193  if (button == ui->pb_MainSimulator) return CMainInfoAreaComponent::InfoAreaSimulator;
194  if (button == ui->pb_MainTextMessages) return CMainInfoAreaComponent::InfoAreaTextMessages;
195  if (button == ui->pb_MainUsers) return CMainInfoAreaComponent::InfoAreaUsers;
196  return CMainInfoAreaComponent::InfoAreaNone;
197  }
198 
199  QPushButton *CMainKeypadAreaComponent::mainInfoAreaToButton(CMainInfoAreaComponent::InfoArea area) const
200  {
201  switch (area)
202  {
203  case CMainInfoAreaComponent::InfoAreaAircraft: return ui->pb_MainAircrafts;
204  case CMainInfoAreaComponent::InfoAreaAtc: return ui->pb_MainAtc;
205  case CMainInfoAreaComponent::InfoAreaCockpit: return ui->pb_MainCockpit;
206  case CMainInfoAreaComponent::InfoAreaFlightPlan: return ui->pb_MainFlightplan;
207  case CMainInfoAreaComponent::InfoAreaLog: return ui->pb_MainLog;
208  case CMainInfoAreaComponent::InfoAreaMapping: return ui->pb_MainMappings;
209  case CMainInfoAreaComponent::InfoAreaInterpolation: return ui->pb_MainInterpolation;
210  case CMainInfoAreaComponent::InfoAreaRadar: return ui->pb_MainRadar;
211  case CMainInfoAreaComponent::InfoAreaSettings: return ui->pb_MainSettings;
212  case CMainInfoAreaComponent::InfoAreaSimulator: return ui->pb_MainSimulator;
213  case CMainInfoAreaComponent::InfoAreaTextMessages: return ui->pb_MainTextMessages;
214  case CMainInfoAreaComponent::InfoAreaUsers: return ui->pb_MainUsers;
215  default: break;
216  }
217  return nullptr;
218  }
219 
220  void CMainKeypadAreaComponent::unsetInfoAreaButtons()
221  {
222  ui->pb_MainAircrafts->setChecked(false);
223  ui->pb_MainAtc->setChecked(false);
224  ui->pb_MainCockpit->setChecked(false);
225  ui->pb_MainFlightplan->setChecked(false);
226  ui->pb_MainLog->setChecked(false);
227  ui->pb_MainMappings->setChecked(false);
228  ui->pb_MainInterpolation->setChecked(false);
229  ui->pb_MainRadar->setChecked(false);
230  ui->pb_MainSettings->setChecked(false);
231  ui->pb_MainSimulator->setChecked(false);
232  ui->pb_MainTextMessages->setChecked(false);
233  ui->pb_MainUsers->setChecked(false);
234 
235  this->updateConnectionStatus();
236  }
237 
238  void CMainKeypadAreaComponent::update()
239  {
240  if (!sGui || sGui->isShuttingDown() || !sGui->supportsContexts()) { return; }
241  if (sGui->getCContextAudioBase()) { this->outputMuteChanged(sGui->getCContextAudioBase()->isOutputMuted()); }
242  this->updateConnectionStatus();
243  }
244 
245  void CMainKeypadAreaComponent::updateConnectionStatus()
246  {
248  {
249  this->connectionStatusChanged(CConnectionStatus::Connected, CConnectionStatus::Connected);
250  }
251  else { this->connectionStatusChanged(CConnectionStatus::Disconnected, CConnectionStatus::Disconnected); }
252  }
253 } // namespace swift::gui::components
const context::IContextAudio * getIContextAudio() const
Direct access to contexts if a CCoreFacade has been initialized.
const context::IContextOwnAircraft * getIContextOwnAircraft() const
Direct access to contexts if a CCoreFacade has been initialized.
CCoreFacade * getCoreFacade()
Get the facade.
Definition: application.h:346
const context::IContextNetwork * getIContextNetwork() const
Direct access to contexts if a CCoreFacade has been initialized.
bool isShuttingDown() const
Is application shutting down?
const context::CContextAudioBase * getCContextAudioBase() const
Direct access to contexts if a CCoreFacade has been initialized.
bool supportsContexts(bool ignoreShutdownTest=false) const
Supports contexts.
void setMasterOutputVolume(int volume)
Volume.
void setOutputMute(bool muted)
Volume.
virtual bool isConnected() const =0
Network connected?
void commandEntered(const QString &command, const swift::misc::CIdentifier &originator)
Command was entered.
void textEntered(const QString &command, const swift::misc::CIdentifier &originator)
Text entered (which is not a command)
Main keypad area as used with main info area.
void commandEntered(const QString &commandLine, const swift::misc::CIdentifier &originator)
Command was entered.
void onMainInfoAreaChanged(int currentTabIndex, const QList< int > &dockedIndexes, const QList< int > &floatingIndexes)
Main info area changed.
void textEntered(const QString &commandLine, const swift::misc::CIdentifier &originator)
Command was entered.
void selectedMainInfoAreaDockWidget(CMainInfoAreaComponent::InfoArea infoArea)
Button to select main info area has been pressed.
void changedOpacity(int opacity)
Change opacity 0..30.
Value object encapsulating information identifying a component of a modular distributed swift process...
Definition: identifier.h:29
TransponderMode getTransponderMode() const
Transponder mode.
Definition: transponder.h:95
Value object encapsulating information about a connection status.
bool isConnected() const
Query status.
Comprehensive information of an aircraft.
const aviation::CTransponder & getTransponder() const
Get transponder.
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
Backend services of the swift project, like dealing with the network or the simulators.
Definition: actionbind.cpp:7
High level reusable GUI components.
Definition: aboutdialog.cpp:13
Free functions in swift::misc.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...
Definition: threadutils.h:30