mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:30:05 +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) | ||||
| { | ||||
|    logger_->trace("HandleKeyPress: {}, {}", | ||||
|                   ev->keyCombination().toCombined(), | ||||
|                   ev->isAutoRepeat()); | ||||
| 
 | ||||
|    for (auto& hotkey : p->hotkeys_) | ||||
|    { | ||||
|       if (hotkey.second.count() == 1 && | ||||
|  | @ -78,7 +82,16 @@ void HotkeyManager::HandleKeyPress(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() | ||||
|  |  | |||
|  | @ -149,7 +149,9 @@ public: | |||
|                           const std::string& before); | ||||
|    void ConnectMapSignals(); | ||||
|    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 InitializeNewRadarProductView(const std::string& colorPalette); | ||||
|    void RadarProductManagerConnect(); | ||||
|  | @ -232,8 +234,9 @@ public: | |||
|    double prevBearing_; | ||||
|    double prevPitch_; | ||||
| 
 | ||||
|    types::Hotkey                         prevHotkey_ = types::Hotkey::Unknown; | ||||
|    std::set<types::Hotkey>               activeHotkeys_ {}; | ||||
|    std::chrono::system_clock::time_point prevHotkeyTime_ {}; | ||||
| 
 | ||||
| public slots: | ||||
|    void Update(); | ||||
| }; | ||||
|  | @ -342,23 +345,16 @@ void MapWidgetImpl::ConnectSignals() | |||
|    connect(hotkeyManager_.get(), | ||||
|            &manager::HotkeyManager::HotkeyPressed, | ||||
|            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; | ||||
|    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; | ||||
|    Q_UNUSED(isAutoRepeat); | ||||
| 
 | ||||
|    switch (hotkey) | ||||
|    { | ||||
|  | @ -386,72 +382,105 @@ void MapWidgetImpl::HandleHotkey(types::Hotkey hotkey, bool isAutoRepeat) | |||
|       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: | ||||
|       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; | ||||
| } | ||||
| 
 | ||||
|  | @ -1319,6 +1348,9 @@ void MapWidget::paintGL() | |||
| 
 | ||||
|    p->frameDraws_++; | ||||
| 
 | ||||
|    // Handle hotkey updates
 | ||||
|    p->HandleHotkeyUpdates(); | ||||
| 
 | ||||
|    // Setup ImGui Frame
 | ||||
|    ImGui::SetCurrentContext(p->imGuiContext_); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat