refs #617, allow to use CGuiActionBindHandler with buttons

* used for weather enable/disable
* use actionBindWasDestroyed when corresponding BlackCore::CActionBind is destroyed
This commit is contained in:
Klaus Basan
2017-02-03 20:43:33 +01:00
committed by Mathew Sutcliffe
parent 1889270011
commit 74d608b5df
5 changed files with 101 additions and 31 deletions

View File

@@ -58,8 +58,11 @@ namespace BlackCore
std::function<void()> m_deleteCallback; //!< called when deleted
};
//! Single binding
using CActionBinding = QSharedPointer<CActionBind>;
//! List of bindings
using CActionBindings = QList<QSharedPointer<CActionBind>>;
using CActionBindings = QList<CActionBinding>;
}
#endif

View File

@@ -11,6 +11,7 @@
#include "blackgui/infoarea.h"
#include "blackgui/views/viewbase.h"
#include "blackgui/guiapplication.h"
#include "blackgui/guiactionbind.h"
#include "blackcore/context/contextapplication.h"
#include "blackcore/context/contextsimulator.h"
#include "blackcore/context/contextownaircraft.h"
@@ -43,21 +44,24 @@ namespace BlackGui
ui(new Ui::CWeatherComponent)
{
ui->setupUi(this);
m_weatherScenarios = CWeatherGrid::getAllScenarios();
for (const auto &scenario : m_weatherScenarios)
m_weatherScenarios = CWeatherGrid::getAllScenarios();
for (const auto &scenario : as_const(m_weatherScenarios))
{
ui->cb_weatherScenario->addItem(scenario.getName(), QVariant::fromValue(scenario));
}
auto scenario = m_weatherScenarioSetting.get();
ui->cb_weatherScenario->setCurrentIndex(scenario.getIndex());
const auto scenario = m_weatherScenarioSetting.get();
ui->cb_weatherScenario->setCurrentIndex(scenario.getIndex());
ui->pb_ActivateWeather->setIcon(CIcons::metar());
setupConnections();
setupInputValidators();
setupCompleter();
// hotkeys
m_hotkeyBindings.append(CGuiActionBindHandler::bindButton(ui->pb_ActivateWeather, "Weather/Toggle weather", true));
// Set interval to 5 min
m_weatherUpdateTimer.setInterval(1000 * 60 * 5);
@@ -146,7 +150,7 @@ namespace BlackGui
{
Q_ASSERT(sGui->getIContextOwnAircraft());
position = sGui->getIContextOwnAircraft()->getOwnAircraft().getPosition();
if(position == CCoordinateGeodetic())
if (position == CCoordinateGeodetic())
{
ui->le_LatOrIcao->setText("N/A");
ui->le_Lon->setText("N/A");
@@ -187,7 +191,7 @@ namespace BlackGui
if (CWeatherScenario::isRealWeatherScenario(scenario))
{
if (!useOwnAcftPosition ||
calculateGreatCircleDistance(position, m_lastOwnAircraftPosition).value(CLengthUnit::km()) > 20 )
calculateGreatCircleDistance(position, m_lastOwnAircraftPosition).value(CLengthUnit::km()) > 20)
{
requestWeatherGrid(position);
m_lastOwnAircraftPosition = position;
@@ -201,7 +205,7 @@ namespace BlackGui
void CWeatherComponent::weatherGridReceived(const CWeatherGrid &weatherGrid, const CIdentifier &identifier)
{
if(!isMyIdentifier(identifier)) { return; }
if (!isMyIdentifier(identifier)) { return; }
ui->lb_Status->setText({});
setWeatherGrid(weatherGrid);
}

View File

@@ -12,8 +12,9 @@
#ifndef BLACKGUI_WEATHERCOMPONENT_H
#define BLACKGUI_WEATHERCOMPONENT_H
#include "blackgui/blackguiexport.h"
#include "blackgui/components/enablefordockwidgetinfoarea.h"
#include "blackgui/blackguiexport.h"
#include "blackcore/actionbind.h"
#include "blackmisc/geo/coordinategeodetic.h"
#include "blackmisc/simulation/simulatorsettings.h"
#include "blackmisc/weather/weatherscenario.h"
@@ -77,6 +78,7 @@ namespace BlackGui
QTimer m_weatherUpdateTimer { this };
BlackMisc::Geo::CCoordinateGeodetic m_lastOwnAircraftPosition;
BlackMisc::CSetting<BlackMisc::Simulation::TSelectedWeatherScenario> m_weatherScenarioSetting { this };
BlackCore::CActionBindings m_hotkeyBindings;
bool m_isWeatherActivated = false;
};
} // namespace

View File

@@ -15,9 +15,14 @@ using namespace BlackCore;
namespace BlackGui
{
CGuiActionBindHandler::CGuiActionBindHandler(QAction *action) : QObject(action)
CGuiActionBindHandler::CGuiActionBindHandler(QAction *action) : QObject(action), m_action(action)
{
this->setAction(action);
this->connectDestroy(action);
}
CGuiActionBindHandler::CGuiActionBindHandler(QAbstractButton *button) : QObject(button), m_button(button)
{
this->connectDestroy(button);
}
CGuiActionBindHandler::~CGuiActionBindHandler()
@@ -27,6 +32,7 @@ namespace BlackGui
CActionBindings CGuiActionBindHandler::bindMenu(QMenu *menu, const QString &path)
{
Q_ASSERT(menu);
CActionBindings boundActions;
if (!menu || menu->isEmpty()) { return boundActions; }
for (QAction *action : menu->actions())
@@ -41,19 +47,36 @@ namespace BlackGui
}
CGuiActionBindHandler *bindHandler = new CGuiActionBindHandler(action);
QSharedPointer<CActionBind> actionBind(new CActionBind(pathNew, bindHandler, &CGuiActionBindHandler::boundFunction, [bindHandler]() { bindHandler->deleteLater(); }));
bindHandler->m_index = actionBind->getIndex();
boundActions.append(actionBind); // takes ownership
CActionBinding actionBinding(new CActionBind(pathNew, bindHandler, &CGuiActionBindHandler::boundFunction, [bindHandler]() { CGuiActionBindHandler::actionBindWasDestroyed(bindHandler); }));
bindHandler->m_index = actionBinding->getIndex();
boundActions.append(actionBinding); // takes ownership
}
return boundActions;
}
void CGuiActionBindHandler::setAction(QAction *action)
CActionBinding CGuiActionBindHandler::bindButton(QAbstractButton *button, const QString &path, bool absoluteName)
{
this->m_action = action;
Q_ASSERT(button);
const QString pathNew = absoluteName ?
path :
CGuiActionBindHandler::appendPath(path, button->text()).remove('&'); // remove E&xit key codes
CGuiActionBindHandler *bindHandler = new CGuiActionBindHandler(button);
CActionBinding actionBinding(new CActionBind(pathNew, bindHandler, &CGuiActionBindHandler::boundFunction, [bindHandler]() { CGuiActionBindHandler::actionBindWasDestroyed(bindHandler); }));
bindHandler->m_index = actionBinding->getIndex();
return actionBinding;
}
void CGuiActionBindHandler::actionBindWasDestroyed(CGuiActionBindHandler *bindHandler)
{
if (!bindHandler) { return; }
bindHandler->reset();
// do not delete, as it might be still referenced somewhere
}
void CGuiActionBindHandler::connectDestroy(QObject *object)
{
// if the action is destroyed from somewhere else I unbind myself
QObject::connect(action, &QAction::destroyed, [ = ]
QObject::connect(object, &QObject::destroyed, [ = ]
{
this->unbind();
});
@@ -61,21 +84,39 @@ namespace BlackGui
void CGuiActionBindHandler::unbind()
{
if (!this->m_action) { return; }
this->m_action = nullptr;
if (CInputManager::instance())
if (this->hasTarget())
{
CInputManager::instance()->unbind(this->m_index);
m_index = -1;
if (CInputManager::instance())
{
CInputManager::instance()->unbind(this->m_index);
}
}
this->reset();
}
void CGuiActionBindHandler::reset()
{
m_index = -1;
m_button = nullptr;
m_action = nullptr;
}
bool CGuiActionBindHandler::hasTarget() const
{
return (m_button || m_action) && m_index >= 0;
}
void CGuiActionBindHandler::boundFunction(bool enabled)
{
if (!enabled) { return; }
if (!m_action) { return; }
if (m_index < 0) { return; }
m_action->trigger();
if (!enabled || !this->hasTarget()) { return; }
if (m_action)
{
m_action->trigger();
}
else if (m_button)
{
m_button->click();
}
}
QString CGuiActionBindHandler::appendPath(const QString &path, const QString &name)

View File

@@ -17,6 +17,8 @@
#include <QMenu>
#include <QList>
#include <QPushButton>
#include <QToolButton>
#include <QScopedPointer>
namespace BlackGui
@@ -27,9 +29,6 @@ namespace BlackGui
Q_OBJECT
public:
//! Constructor
CGuiActionBindHandler(QAction *action);
//! Destructor
virtual ~CGuiActionBindHandler();
@@ -37,23 +36,44 @@ namespace BlackGui
void boundFunction(bool enabled);
//! Bind whole menu
//! \remark keep BlackCore::CActionBindings as long you want to keep this binding alive
static BlackCore::CActionBindings bindMenu(QMenu *menu, const QString &path = {});
//! Bind button, with relative name
//! \remark keep BlackCore::CActionBinding as long you want to keep this binding alive
static BlackCore::CActionBinding bindButton(QAbstractButton *button, const QString &path, bool absoluteName);
//! Corresponding BlackCore::CActionBind died, so delete CGuiActionBindHandler
static void actionBindWasDestroyed(CGuiActionBindHandler *bindHandler);
private:
//! Constructor for QAction
CGuiActionBindHandler(QAction *action);
//! Constructor for QPushButton
CGuiActionBindHandler(QAbstractButton *button);
//! Corresponding action destroyed
void destroyed();
//! Set the action
void setAction(QAction *action);
void connectDestroy(QObject *action);
//! Unbind this action
void unbind();
//! Reset
void reset();
//! Target available?
bool hasTarget() const;
//! Append path for action
static QString appendPath(const QString &path, const QString &name);
int m_index = -1;
QAction *m_action = nullptr;
QAction *m_action = nullptr;
QAbstractButton *m_button = nullptr;
};
} // namespace