mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-10 22:15:34 +08:00
Ref T384, ATC button component and integration in text message component
This commit is contained in:
133
src/blackgui/components/atcbuttoncomponent.cpp
Normal file
133
src/blackgui/components/atcbuttoncomponent.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "atcbuttoncomponent.h"
|
||||
#include "ui_atcbuttoncomponent.h"
|
||||
|
||||
#include "blackgui/guiapplication.h"
|
||||
#include "blackgui/guiutility.h"
|
||||
#include "blackmisc/aviation/atcstationlist.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Aviation;
|
||||
using namespace BlackCore;
|
||||
using namespace BlackCore::Context;
|
||||
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Components
|
||||
{
|
||||
CAtcButtonComponent::CAtcButtonComponent(QWidget *parent) :
|
||||
QFrame(parent),
|
||||
ui(new Ui::CAtcButtonComponent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
if (sGui && sGui->getIContextNetwork())
|
||||
{
|
||||
connect(sGui->getIContextNetwork(), &IContextNetwork::changedAtcStationsOnlineDigest, this, &CAtcButtonComponent::onChangedAtcStations);
|
||||
connect(sGui->getIContextNetwork(), &IContextNetwork::connectionStatusChanged, this, &CAtcButtonComponent::onConnectionStatusChanged);
|
||||
}
|
||||
|
||||
this->setVisible(false); // will be changed when ATC stations are reported
|
||||
}
|
||||
|
||||
CAtcButtonComponent::~CAtcButtonComponent()
|
||||
{ }
|
||||
|
||||
void CAtcButtonComponent::updateStations()
|
||||
{
|
||||
this->setVisible(false);
|
||||
this->setMinimumHeight(0);
|
||||
|
||||
if (!sGui || !sGui->getIContextNetwork()) { return; }
|
||||
if (m_maxNumber < 1) { return; }
|
||||
const int max = qMin(m_maxNumber, m_rows * m_cols);
|
||||
CAtcStationList stations = sGui->getIContextNetwork()->getClosestAtcStationsOnline(max);
|
||||
if (stations.isEmpty()) { return; }
|
||||
|
||||
CGuiUtility::deleteLayout(this->layout(), true);
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
layout->setObjectName("gl_CAtcButtonComponent");
|
||||
layout->setSpacing(4);
|
||||
layout->setMargin(0);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
int added = 0;
|
||||
for (const CAtcStation &station : as_const(stations))
|
||||
{
|
||||
if (m_ignoreNonAtc)
|
||||
{
|
||||
// strict check, only "real ATC stations", no supervisors etc
|
||||
if (!station.getCallsign().hasAtcSuffix()) { continue; }
|
||||
}
|
||||
|
||||
QPushButton *button = new QPushButton(this);
|
||||
button->setText(station.getCallsignAsString());
|
||||
button->setIcon(station.toPixmap());
|
||||
QObject::connect(button, &QPushButton::released, this, &CAtcButtonComponent::onButtonClicked);
|
||||
const CVariant atcv = CVariant::fromValue(station);
|
||||
layout->addWidget(button, row, col++);
|
||||
button->show();
|
||||
button->setProperty("atc", atcv.getQVariant());
|
||||
added++;
|
||||
|
||||
if (col >= m_cols)
|
||||
{
|
||||
if (row == m_rows) { break; }
|
||||
row++;
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (added > 0)
|
||||
{
|
||||
this->setVisible(true);
|
||||
this->setMinimumHeight(row * 25);
|
||||
}
|
||||
}
|
||||
|
||||
void CAtcButtonComponent::setRowsColumns(int rows, int cols, bool setMaxElements)
|
||||
{
|
||||
m_rows = rows;
|
||||
m_cols = cols;
|
||||
if (setMaxElements) { m_maxNumber = rows * cols; }
|
||||
}
|
||||
|
||||
void CAtcButtonComponent::onChangedAtcStations()
|
||||
{
|
||||
if (!m_backgroundUpdates) { return; }
|
||||
this->updateStations();
|
||||
}
|
||||
|
||||
void CAtcButtonComponent::onConnectionStatusChanged(INetwork::ConnectionStatus from, INetwork::ConnectionStatus to)
|
||||
{
|
||||
Q_UNUSED(from);
|
||||
if (INetwork::isDisconnectedStatus(to))
|
||||
{
|
||||
this->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CAtcButtonComponent::onButtonClicked()
|
||||
{
|
||||
QPushButton *button = qobject_cast<QPushButton *>(QObject::sender());
|
||||
if (!button) { return; }
|
||||
const CVariant v(button->property("atc"));
|
||||
if (!v.isValid() || !v.canConvert<CAtcStation>()) { return; }
|
||||
const CAtcStation station = v.value<CAtcStation>();
|
||||
emit this->requestAtcStation(station);
|
||||
}
|
||||
} // ns
|
||||
} // ns
|
||||
78
src/blackgui/components/atcbuttoncomponent.h
Normal file
78
src/blackgui/components/atcbuttoncomponent.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* Copyright (C) 2018
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKGUI_COMPONENTS_ATCBUTTONCOMPONENT_H
|
||||
#define BLACKGUI_COMPONENTS_ATCBUTTONCOMPONENT_H
|
||||
|
||||
#include "blackcore/context/contextnetwork.h"
|
||||
#include <QFrame>
|
||||
#include <QScopedPointer>
|
||||
|
||||
namespace Ui { class CAtcButtonComponent; }
|
||||
namespace BlackGui
|
||||
{
|
||||
namespace Components
|
||||
{
|
||||
//! ATC stations as button bar
|
||||
class CAtcButtonComponent : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Ctor
|
||||
explicit CAtcButtonComponent(QWidget *parent = nullptr);
|
||||
|
||||
//! Dtor
|
||||
virtual ~CAtcButtonComponent();
|
||||
|
||||
//! Update
|
||||
void updateStations();
|
||||
|
||||
//! Max.number
|
||||
void setMaxNumber(int number) { m_maxNumber = number; }
|
||||
|
||||
//! Max.number
|
||||
int getMaxNumber() const { return m_maxNumber; }
|
||||
|
||||
//! Rows/columns
|
||||
void setRowsColumns(int rows, int cols, bool setMaxElements);
|
||||
|
||||
//! Ignore non ATC callsigns
|
||||
void setIgnoreNonAtcCallsigns(bool ignore) { m_ignoreNonAtc = ignore; }
|
||||
|
||||
//! Background updates
|
||||
void setBackgroundUpdates(bool backgroundUpdates) { m_backgroundUpdates = backgroundUpdates; }
|
||||
|
||||
signals:
|
||||
//! ATC station clicked
|
||||
void requestAtcStation(const BlackMisc::Aviation::CAtcStation &station);
|
||||
|
||||
private:
|
||||
//! Changed ATC stations
|
||||
void onChangedAtcStations();
|
||||
|
||||
//! Connection status did change
|
||||
void onConnectionStatusChanged(BlackCore::INetwork::ConnectionStatus from, BlackCore::INetwork::ConnectionStatus to);
|
||||
|
||||
//! Button has been clicked
|
||||
void onButtonClicked();
|
||||
|
||||
QScopedPointer<Ui::CAtcButtonComponent> ui;
|
||||
bool m_ignoreNonAtc = true;
|
||||
bool m_backgroundUpdates = true;
|
||||
int m_maxNumber = 8;
|
||||
int m_rows = 2;
|
||||
int m_cols = 4;
|
||||
};
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
#endif // guard
|
||||
25
src/blackgui/components/atcbuttoncomponent.ui
Normal file
25
src/blackgui/components/atcbuttoncomponent.ui
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CAtcButtonComponent</class>
|
||||
<widget class="QFrame" name="CAtcButtonComponent">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>25</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Frame</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -69,10 +69,12 @@ namespace BlackGui
|
||||
ui->tvp_TextMessagesAll->setResizeMode(CTextMessageView::ResizingAuto);
|
||||
|
||||
// lep_textMessages is the own line edit
|
||||
bool c = connect(ui->lep_textMessages, &CLineEditHistory::returnPressed, this, &CTextMessageComponent::textMessageEntered, Qt::QueuedConnection);
|
||||
bool c = connect(ui->lep_textMessages, &CLineEditHistory::returnPressed, this, &CTextMessageComponent::textMessageEntered);
|
||||
Q_ASSERT_X(c, Q_FUNC_INFO, "Missing connect");
|
||||
c = connect(ui->gb_Settings, &QGroupBox::toggled, this, &CTextMessageComponent::onSettingsChecked);
|
||||
Q_ASSERT_X(c, Q_FUNC_INFO, "Missing connect");
|
||||
c = connect(ui->comp_AtcStations, &CAtcButtonComponent::requestAtcStation, this, &CTextMessageComponent::onAtcButtonClicked);
|
||||
Q_ASSERT_X(c, Q_FUNC_INFO, "Missing connect");
|
||||
|
||||
// style sheet
|
||||
c = connect(sGui, &CGuiApplication::styleSheetsChanged, this, &CTextMessageComponent::onStyleSheetChanged, Qt::QueuedConnection);
|
||||
@@ -252,6 +254,12 @@ namespace BlackGui
|
||||
this->onSettingsChanged();
|
||||
}
|
||||
|
||||
void CTextMessageComponent::onAtcButtonClicked(const CAtcStation &station)
|
||||
{
|
||||
if (station.getCallsign().isEmpty()) { return; }
|
||||
this->addNewTextMessageTab(station.getCallsign());
|
||||
}
|
||||
|
||||
void CTextMessageComponent::updateSettings()
|
||||
{
|
||||
const QString style = ui->comp_SettingsStyle->getStyle();
|
||||
@@ -327,7 +335,9 @@ namespace BlackGui
|
||||
|
||||
QWidget *CTextMessageComponent::addNewTextMessageTab(const CCallsign &callsign)
|
||||
{
|
||||
Q_ASSERT(!callsign.isEmpty());
|
||||
if (callsign.isEmpty()) { return nullptr; }
|
||||
QWidget *w = this->findTextMessageTabByCallsign(callsign, false);
|
||||
if (w) { return w; }
|
||||
return this->addNewTextMessageTab(callsign.asString());
|
||||
}
|
||||
|
||||
@@ -349,11 +359,10 @@ namespace BlackGui
|
||||
const int index = ui->tw_TextMessages->addTab(newTab, tabName);
|
||||
QToolButton *closeButtonInTab = new QToolButton(newTab);
|
||||
closeButtonInTab->setText("[X]");
|
||||
ui->tw_TextMessages->tabBar()->setTabButton(index, QTabBar::RightSide, closeButtonInTab);
|
||||
ui->tw_TextMessages->tabBar()->setTabButton(index, QTabBar::RightSide, closeButtonInTab); // changes parent
|
||||
ui->tw_TextMessages->setCurrentIndex(index);
|
||||
|
||||
closeButton->setProperty("messageTabIndex", index);
|
||||
closeButtonInTab->setProperty("messageTabIndex", index);
|
||||
closeButton->setProperty("tabName", tabName);
|
||||
closeButtonInTab->setProperty("tabName", tabName);
|
||||
|
||||
connect(closeButton, &QPushButton::released, this, &CTextMessageComponent::closeTextMessageTab);
|
||||
connect(closeButtonInTab, &QPushButton::released, this, &CTextMessageComponent::closeTextMessageTab);
|
||||
@@ -398,18 +407,19 @@ namespace BlackGui
|
||||
if (w) { return w; }
|
||||
if (!callsignResolution) { return nullptr; }
|
||||
|
||||
// resolve callsign
|
||||
// resolve callsign to COM tab
|
||||
if (!sGui || !sGui->getIContextNetwork()) { return nullptr; }
|
||||
const CAtcStation station(sGui->getIContextNetwork()->getOnlineStationForCallsign(callsign));
|
||||
if (!station.getCallsign().isEmpty())
|
||||
{
|
||||
const CSimulatedAircraft ownAircraft(this->getOwnAircraft());
|
||||
if (ownAircraft.getCom1System().isActiveFrequencyWithin25kHzChannel(station.getFrequency()))
|
||||
{
|
||||
return getTabWidget(TextMessagesCom1);
|
||||
return this->getTabWidget(TextMessagesCom1);
|
||||
}
|
||||
else if (ownAircraft.getCom2System().isActiveFrequencyWithin25kHzChannel(station.getFrequency()))
|
||||
{
|
||||
return getTabWidget(TextMessagesCom2);
|
||||
return this->getTabWidget(TextMessagesCom2);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -433,17 +443,12 @@ namespace BlackGui
|
||||
{
|
||||
QObject *sender = QObject::sender();
|
||||
QWidget *parentWidget = qobject_cast<QWidget *>(sender->parent());
|
||||
Q_ASSERT(parentWidget);
|
||||
int index = -1;
|
||||
const QVariant qvi = sender->property("messageTabIndex");
|
||||
if (qvi.isValid()) { index = qvi.toInt(); }
|
||||
|
||||
// the while loop is the old version
|
||||
// should not really be needed anymore
|
||||
while (index < 0 && parentWidget)
|
||||
int index = ui->tw_TextMessages->indexOf(parentWidget);
|
||||
if (index < 0)
|
||||
{
|
||||
index = ui->tw_TextMessages->indexOf(parentWidget);
|
||||
parentWidget = parentWidget->parentWidget();
|
||||
const QString tabName = sender->property("tabName").toString();
|
||||
QWidget *tw = this->findTextMessageTabByName(tabName);
|
||||
if (tw) { index = ui->tw_TextMessages->indexOf(tw); }
|
||||
}
|
||||
if (index >= 0) { ui->tw_TextMessages->removeTab(index); }
|
||||
}
|
||||
@@ -574,14 +579,18 @@ namespace BlackGui
|
||||
CLogMessage(this).warning("No callsign to display text message");
|
||||
return;
|
||||
}
|
||||
QWidget *w = findTextMessageTabByCallsign(callsign, true);
|
||||
if (!w && sGui->getIContextNetwork())
|
||||
QWidget *w = this->findTextMessageTabByCallsign(callsign, true);
|
||||
if (!w && sGui && sGui->getIContextNetwork())
|
||||
{
|
||||
CSimulatedAircraft aircraft(sGui->getIContextNetwork()->getAircraftInRangeForCallsign(callsign));
|
||||
if (!aircraft.getCallsign().isEmpty())
|
||||
if (callsign.isAtcCallsign() && sGui->getIContextNetwork()->isAircraftInRange(callsign))
|
||||
{
|
||||
// we assume a private message
|
||||
w = this->addNewTextMessageTab(aircraft.getCallsign());
|
||||
w = this->addNewTextMessageTab(callsign);
|
||||
}
|
||||
else if (sGui->getIContextNetwork()->isOnlineStation(callsign))
|
||||
{
|
||||
// we assume a private message
|
||||
w = this->addNewTextMessageTab(callsign);
|
||||
}
|
||||
}
|
||||
if (!w) { return; }
|
||||
@@ -612,6 +621,21 @@ namespace BlackGui
|
||||
}
|
||||
}
|
||||
|
||||
void CTextMessageComponent::setAtcButtonsRowsColumns(int rows, int cols, bool setMaxElements)
|
||||
{
|
||||
ui->comp_AtcStations->setRowsColumns(rows, cols, setMaxElements);
|
||||
}
|
||||
|
||||
void CTextMessageComponent::setAtcButtonsBackgroundUpdates(bool backgroundUpdates)
|
||||
{
|
||||
ui->comp_AtcStations->setBackgroundUpdates(backgroundUpdates);
|
||||
}
|
||||
|
||||
void CTextMessageComponent::updateAtcButtonStations()
|
||||
{
|
||||
ui->comp_AtcStations->updateStations();
|
||||
}
|
||||
|
||||
bool CTextMessageComponent::hasAllMessagesTab() const
|
||||
{
|
||||
return ui->tw_TextMessages->widget(0) == ui->tb_TextMessagesAll;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "blackgui/settings/textmessagesettings.h"
|
||||
#include "blackgui/components/enablefordockwidgetinfoarea.h"
|
||||
#include "blackgui/blackguiexport.h"
|
||||
#include "blackmisc/aviation/atcstation.h"
|
||||
#include "blackmisc/simulation/simulatedaircraft.h"
|
||||
#include "blackmisc/identifier.h"
|
||||
#include "blackmisc/variant.h"
|
||||
@@ -77,9 +78,20 @@ namespace BlackGui
|
||||
//! Remove the all tab, the operation cannot be undone
|
||||
void removeAllMessagesTab();
|
||||
|
||||
// ---------- overlay test messages -------------
|
||||
|
||||
//! Used as overlay and not dock widget
|
||||
void setAsUsedInOverlayMode() { m_usedAsOverlayWidget = true; }
|
||||
|
||||
//! Rows/columns
|
||||
void setAtcButtonsRowsColumns(int rows, int cols, bool setMaxElements);
|
||||
|
||||
//! Background updates or explicitly called
|
||||
void setAtcButtonsBackgroundUpdates(bool backgroundUpdates);
|
||||
|
||||
//! Update buttons
|
||||
void updateAtcButtonStations();
|
||||
|
||||
signals:
|
||||
//! Message to be displayed in info window
|
||||
void displayInInfoWindow(const BlackMisc::CVariant &message, int displayDurationMs) const;
|
||||
@@ -160,6 +172,9 @@ namespace BlackGui
|
||||
//! Style sheet has been changed
|
||||
void onStyleSheetChanged();
|
||||
|
||||
//! ATC Button
|
||||
void onAtcButtonClicked(const BlackMisc::Aviation::CAtcStation &station);
|
||||
|
||||
//! Update settings
|
||||
void updateSettings();
|
||||
|
||||
|
||||
@@ -221,6 +221,16 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="BlackGui::Components::CAtcButtonComponent" name="comp_AtcStations">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gb_Settings">
|
||||
<property name="title">
|
||||
@@ -308,6 +318,12 @@
|
||||
<header>blackgui/components/settingstextmessagestyle.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>BlackGui::Components::CAtcButtonComponent</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>blackgui/components/atcbuttoncomponent.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>tw_TextMessages</tabstop>
|
||||
|
||||
Reference in New Issue
Block a user