mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:20:06 +00:00 
			
		
		
		
	Handle held hotkeys on frame update (paintGL) rather than on key press
This commit is contained in:
		
							parent
							
								
									dcaba52db7
								
							
						
					
					
						commit
						7e99b5fb00
					
				
					 2 changed files with 124 additions and 79 deletions
				
			
		|  | @ -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() | ||||||
|  |  | ||||||
|  | @ -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,72 +382,105 @@ void MapWidgetImpl::HandleHotkey(types::Hotkey hotkey, bool isAutoRepeat) | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    case types::Hotkey::MapPanUp: |  | ||||||
|    { |  | ||||||
|       QPointF delta {0.0f, kMapPanFactor * hotkeyElapsed.count()}; |  | ||||||
|       map_->moveBy(delta); |  | ||||||
|       break; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    case types::Hotkey::MapPanDown: |  | ||||||
|    { |  | ||||||
|       QPointF delta {0.0f, -kMapPanFactor * hotkeyElapsed.count()}; |  | ||||||
|       map_->moveBy(delta); |  | ||||||
|       break; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    case types::Hotkey::MapPanLeft: |  | ||||||
|    { |  | ||||||
|       QPointF delta {kMapPanFactor * hotkeyElapsed.count(), 0.0f}; |  | ||||||
|       map_->moveBy(delta); |  | ||||||
|       break; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    case types::Hotkey::MapPanRight: |  | ||||||
|    { |  | ||||||
|       QPointF delta {-kMapPanFactor * hotkeyElapsed.count(), 0.0f}; |  | ||||||
|       map_->moveBy(delta); |  | ||||||
|       break; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    case types::Hotkey::MapRotateClockwise: |  | ||||||
|    { |  | ||||||
|       QPointF delta {-kMapRotateFactor * hotkeyElapsed.count(), 0.0f}; |  | ||||||
|       map_->rotateBy({}, delta); |  | ||||||
|       break; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    case types::Hotkey::MapRotateCounterclockwise: |  | ||||||
|    { |  | ||||||
|       QPointF delta {kMapRotateFactor * hotkeyElapsed.count(), 0.0f}; |  | ||||||
|       map_->rotateBy({}, delta); |  | ||||||
|       break; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    case types::Hotkey::MapZoomIn: |  | ||||||
|    { |  | ||||||
|       auto    widgetSize = widget_->size(); |  | ||||||
|       QPointF center = {widgetSize.width() * 0.5f, widgetSize.height() * 0.5f}; |  | ||||||
|       double  scale  = std::pow(2.0, hotkeyElapsed.count() / kMapScaleFactor); |  | ||||||
|       map_->scaleBy(scale, center); |  | ||||||
|       break; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    case types::Hotkey::MapZoomOut: |  | ||||||
|    { |  | ||||||
|       auto    widgetSize = widget_->size(); |  | ||||||
|       QPointF center = {widgetSize.width() * 0.5f, widgetSize.height() * 0.5f}; |  | ||||||
|       double  scale = |  | ||||||
|          1.0 / std::pow(2.0, hotkeyElapsed.count() / kMapScaleFactor); |  | ||||||
|       map_->scaleBy(scale, center); |  | ||||||
|       break; |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    default: |    default: | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    prevHotkey_     = hotkey; |    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: | ||||||
|  |       { | ||||||
|  |          QPointF delta {0.0f, kMapPanFactor * hotkeyElapsed.count()}; | ||||||
|  |          map_->moveBy(delta); | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       case types::Hotkey::MapPanDown: | ||||||
|  |       { | ||||||
|  |          QPointF delta {0.0f, -kMapPanFactor * hotkeyElapsed.count()}; | ||||||
|  |          map_->moveBy(delta); | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       case types::Hotkey::MapPanLeft: | ||||||
|  |       { | ||||||
|  |          QPointF delta {kMapPanFactor * hotkeyElapsed.count(), 0.0f}; | ||||||
|  |          map_->moveBy(delta); | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       case types::Hotkey::MapPanRight: | ||||||
|  |       { | ||||||
|  |          QPointF delta {-kMapPanFactor * hotkeyElapsed.count(), 0.0f}; | ||||||
|  |          map_->moveBy(delta); | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       case types::Hotkey::MapRotateClockwise: | ||||||
|  |       { | ||||||
|  |          QPointF delta {-kMapRotateFactor * hotkeyElapsed.count(), 0.0f}; | ||||||
|  |          map_->rotateBy({}, delta); | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       case types::Hotkey::MapRotateCounterclockwise: | ||||||
|  |       { | ||||||
|  |          QPointF delta {kMapRotateFactor * hotkeyElapsed.count(), 0.0f}; | ||||||
|  |          map_->rotateBy({}, delta); | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       case types::Hotkey::MapZoomIn: | ||||||
|  |       { | ||||||
|  |          auto    widgetSize = widget_->size(); | ||||||
|  |          QPointF center     = {widgetSize.width() * 0.5f, | ||||||
|  |                                widgetSize.height() * 0.5f}; | ||||||
|  |          double  scale = std::pow(2.0, hotkeyElapsed.count() / kMapScaleFactor); | ||||||
|  |          map_->scaleBy(scale, center); | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       case types::Hotkey::MapZoomOut: | ||||||
|  |       { | ||||||
|  |          auto    widgetSize = widget_->size(); | ||||||
|  |          QPointF center     = {widgetSize.width() * 0.5f, | ||||||
|  |                                widgetSize.height() * 0.5f}; | ||||||
|  |          double  scale = | ||||||
|  |             1.0 / std::pow(2.0, hotkeyElapsed.count() / kMapScaleFactor); | ||||||
|  |          map_->scaleBy(scale, center); | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       default: | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|    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_); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat