Handle held hotkeys on frame update (paintGL) rather than on key press

This commit is contained in:
Dan Paulat 2024-04-12 00:37:27 -05:00
parent dcaba52db7
commit 7e99b5fb00
2 changed files with 124 additions and 79 deletions

View file

@ -66,6 +66,10 @@ void HotkeyManager::Impl::UpdateHotkey(types::Hotkey hotkey,
void HotkeyManager::HandleKeyPress(QKeyEvent* ev) void HotkeyManager::HandleKeyPress(QKeyEvent* ev)
{ {
logger_->trace("HandleKeyPress: {}, {}",
ev->keyCombination().toCombined(),
ev->isAutoRepeat());
for (auto& hotkey : p->hotkeys_) for (auto& hotkey : p->hotkeys_)
{ {
if (hotkey.second.count() == 1 && if (hotkey.second.count() == 1 &&
@ -78,7 +82,16 @@ void HotkeyManager::HandleKeyPress(QKeyEvent* ev)
void HotkeyManager::HandleKeyRelease(QKeyEvent* ev) void HotkeyManager::HandleKeyRelease(QKeyEvent* ev)
{ {
Q_UNUSED(ev); logger_->trace("HandleKeyRelease: {}", ev->keyCombination().toCombined());
for (auto& hotkey : p->hotkeys_)
{
if (hotkey.second.count() == 1 &&
hotkey.second[0] == ev->keyCombination())
{
Q_EMIT HotkeyReleased(hotkey.first);
}
}
} }
std::shared_ptr<HotkeyManager> HotkeyManager::Instance() std::shared_ptr<HotkeyManager> HotkeyManager::Instance()

View file

@ -149,7 +149,9 @@ public:
const std::string& before); const std::string& before);
void ConnectMapSignals(); void ConnectMapSignals();
void ConnectSignals(); void ConnectSignals();
void HandleHotkey(types::Hotkey hotkey, bool isAutoRepeat); void HandleHotkeyPressed(types::Hotkey hotkey, bool isAutoRepeat);
void HandleHotkeyReleased(types::Hotkey hotkey);
void HandleHotkeyUpdates();
void ImGuiCheckFonts(); void ImGuiCheckFonts();
void InitializeNewRadarProductView(const std::string& colorPalette); void InitializeNewRadarProductView(const std::string& colorPalette);
void RadarProductManagerConnect(); void RadarProductManagerConnect();
@ -232,8 +234,9 @@ public:
double prevBearing_; double prevBearing_;
double prevPitch_; double prevPitch_;
types::Hotkey prevHotkey_ = types::Hotkey::Unknown; std::set<types::Hotkey> activeHotkeys_ {};
std::chrono::system_clock::time_point prevHotkeyTime_ {}; std::chrono::system_clock::time_point prevHotkeyTime_ {};
public slots: public slots:
void Update(); void Update();
}; };
@ -342,23 +345,16 @@ void MapWidgetImpl::ConnectSignals()
connect(hotkeyManager_.get(), connect(hotkeyManager_.get(),
&manager::HotkeyManager::HotkeyPressed, &manager::HotkeyManager::HotkeyPressed,
this, this,
&MapWidgetImpl::HandleHotkey); &MapWidgetImpl::HandleHotkeyPressed);
connect(hotkeyManager_.get(),
&manager::HotkeyManager::HotkeyReleased,
this,
&MapWidgetImpl::HandleHotkeyReleased);
} }
void MapWidgetImpl::HandleHotkey(types::Hotkey hotkey, bool isAutoRepeat) void MapWidgetImpl::HandleHotkeyPressed(types::Hotkey hotkey, bool isAutoRepeat)
{ {
static constexpr float kMapPanFactor = 0.2f; Q_UNUSED(isAutoRepeat);
static constexpr float kMapRotateFactor = 0.2f;
static constexpr double kMapScaleFactor = 1000.0;
using namespace std::chrono_literals;
std::chrono::system_clock::time_point hotkeyTime =
std::chrono::system_clock::now();
std::chrono::milliseconds hotkeyElapsed =
isAutoRepeat ? std::chrono::duration_cast<std::chrono::milliseconds>(
hotkeyTime - prevHotkeyTime_) :
100ms;
switch (hotkey) switch (hotkey)
{ {
@ -386,6 +382,37 @@ void MapWidgetImpl::HandleHotkey(types::Hotkey hotkey, bool isAutoRepeat)
break; break;
} }
default:
break;
}
activeHotkeys_.insert(hotkey);
}
void MapWidgetImpl::HandleHotkeyReleased(types::Hotkey hotkey)
{
activeHotkeys_.erase(hotkey);
}
void MapWidgetImpl::HandleHotkeyUpdates()
{
using namespace std::chrono_literals;
static constexpr float kMapPanFactor = 0.2f;
static constexpr float kMapRotateFactor = 0.2f;
static constexpr double kMapScaleFactor = 1000.0;
std::chrono::system_clock::time_point hotkeyTime =
std::chrono::system_clock::now();
std::chrono::milliseconds hotkeyElapsed =
std::min(std::chrono::duration_cast<std::chrono::milliseconds>(
hotkeyTime - prevHotkeyTime_),
100ms);
for (auto& hotkey : activeHotkeys_)
{
switch (hotkey)
{
case types::Hotkey::MapPanUp: case types::Hotkey::MapPanUp:
{ {
QPointF delta {0.0f, kMapPanFactor * hotkeyElapsed.count()}; QPointF delta {0.0f, kMapPanFactor * hotkeyElapsed.count()};
@ -431,7 +458,8 @@ void MapWidgetImpl::HandleHotkey(types::Hotkey hotkey, bool isAutoRepeat)
case types::Hotkey::MapZoomIn: case types::Hotkey::MapZoomIn:
{ {
auto widgetSize = widget_->size(); auto widgetSize = widget_->size();
QPointF center = {widgetSize.width() * 0.5f, widgetSize.height() * 0.5f}; QPointF center = {widgetSize.width() * 0.5f,
widgetSize.height() * 0.5f};
double scale = std::pow(2.0, hotkeyElapsed.count() / kMapScaleFactor); double scale = std::pow(2.0, hotkeyElapsed.count() / kMapScaleFactor);
map_->scaleBy(scale, center); map_->scaleBy(scale, center);
break; break;
@ -440,7 +468,8 @@ void MapWidgetImpl::HandleHotkey(types::Hotkey hotkey, bool isAutoRepeat)
case types::Hotkey::MapZoomOut: case types::Hotkey::MapZoomOut:
{ {
auto widgetSize = widget_->size(); auto widgetSize = widget_->size();
QPointF center = {widgetSize.width() * 0.5f, widgetSize.height() * 0.5f}; QPointF center = {widgetSize.width() * 0.5f,
widgetSize.height() * 0.5f};
double scale = double scale =
1.0 / std::pow(2.0, hotkeyElapsed.count() / kMapScaleFactor); 1.0 / std::pow(2.0, hotkeyElapsed.count() / kMapScaleFactor);
map_->scaleBy(scale, center); map_->scaleBy(scale, center);
@ -450,8 +479,8 @@ void MapWidgetImpl::HandleHotkey(types::Hotkey hotkey, bool isAutoRepeat)
default: default:
break; break;
} }
}
prevHotkey_ = hotkey;
prevHotkeyTime_ = hotkeyTime; prevHotkeyTime_ = hotkeyTime;
} }
@ -1319,6 +1348,9 @@ void MapWidget::paintGL()
p->frameDraws_++; p->frameDraws_++;
// Handle hotkey updates
p->HandleHotkeyUpdates();
// Setup ImGui Frame // Setup ImGui Frame
ImGui::SetCurrentContext(p->imGuiContext_); ImGui::SetCurrentContext(p->imGuiContext_);