mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
refactor: 使用 CursorManager 获取光标信息
This commit is contained in:
parent
fd06ecc6a9
commit
e293bcd1b2
9 changed files with 73 additions and 37 deletions
|
|
@ -13,6 +13,7 @@
|
|||
#include "Win32Utils.h"
|
||||
#include "ScalingWindow.h"
|
||||
#include "Renderer.h"
|
||||
#include "CursorManager.h"
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
|
|
@ -97,7 +98,10 @@ bool CursorDrawer::Initialize(DeviceResources& deviceResources, ID3D11Texture2D*
|
|||
return true;
|
||||
}
|
||||
|
||||
void CursorDrawer::Draw(HCURSOR hCursor, POINT cursorPos) noexcept {
|
||||
void CursorDrawer::Draw() noexcept {
|
||||
const CursorManager& cursorManager = ScalingWindow::Get().CursorManager();
|
||||
const HCURSOR hCursor = cursorManager.Cursor();
|
||||
|
||||
if (!hCursor) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -107,8 +111,10 @@ void CursorDrawer::Draw(HCURSOR hCursor, POINT cursorPos) noexcept {
|
|||
return;
|
||||
}
|
||||
|
||||
const POINT cursorPos = cursorManager.CursorPos();
|
||||
|
||||
const float cursorScaling = ScalingWindow::Get().Options().cursorScaling;
|
||||
SIZE cursorSize{ lroundf(ci->size.cx * cursorScaling), lroundf(ci->size.cy * cursorScaling) };
|
||||
const SIZE cursorSize{ lroundf(ci->size.cx * cursorScaling), lroundf(ci->size.cy * cursorScaling) };
|
||||
RECT cursorRect;
|
||||
cursorRect.left = lroundf(cursorPos.x - ci->hotSpot.x * cursorScaling);
|
||||
cursorRect.top = lroundf(cursorPos.y - ci->hotSpot.y * cursorScaling);
|
||||
|
|
@ -168,6 +174,7 @@ void CursorDrawer::Draw(HCURSOR hCursor, POINT cursorPos) noexcept {
|
|||
1.0f
|
||||
};
|
||||
d3dDC->RSSetViewports(1, &vp);
|
||||
d3dDC->RSSetState(nullptr);
|
||||
}
|
||||
|
||||
CursorInterpolationMode interpolationMode = ScalingWindow::Get().Options().cursorInterpolationMode;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public:
|
|||
|
||||
bool Initialize(DeviceResources& deviceResources, ID3D11Texture2D* backBuffer) noexcept;
|
||||
|
||||
void Draw(HCURSOR hCursor, POINT cursorPos) noexcept;
|
||||
void Draw() noexcept;
|
||||
|
||||
private:
|
||||
enum class _CursorType {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Magpie::Core {
|
|||
|
||||
// 将源窗口的光标位置映射到缩放后的光标位置
|
||||
// 当光标位于源窗口之外,与源窗口的距离不会缩放
|
||||
static POINT SrcToScaling(POINT pt, bool screenCoord) noexcept {
|
||||
static POINT SrcToScaling(POINT pt) noexcept {
|
||||
const Renderer& renderer = ScalingWindow::Get().Renderer();
|
||||
const RECT& srcRect = renderer.SrcRect();
|
||||
const RECT& destRect = renderer.DestRect();
|
||||
|
|
@ -39,11 +39,6 @@ static POINT SrcToScaling(POINT pt, bool screenCoord) noexcept {
|
|||
result.y = std::lround(pos * (destRect.bottom - destRect.top - 1)) + destRect.top;
|
||||
}
|
||||
|
||||
if (!screenCoord) {
|
||||
result.x -= scalingRect.left;
|
||||
result.y -= scalingRect.top;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -104,33 +99,33 @@ bool CursorManager::Initialize() noexcept {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::pair<HCURSOR, POINT> CursorManager::Update() noexcept {
|
||||
void CursorManager::Update() noexcept {
|
||||
_UpdateCursorClip();
|
||||
|
||||
std::pair<HCURSOR, POINT> result{NULL,
|
||||
{ std::numeric_limits<LONG>::max(), std::numeric_limits<LONG>::max() }};
|
||||
_hCursor = NULL;
|
||||
|
||||
const ScalingOptions& options = ScalingWindow::Get().Options();
|
||||
|
||||
if (!options.IsDrawCursor() || !_isUnderCapture) {
|
||||
// 不绘制光标
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
CURSORINFO ci{ sizeof(CURSORINFO) };
|
||||
if (!GetCursorInfo(&ci)) {
|
||||
Logger::Get().Win32Error("GetCursorPos 失败");
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ci.hCursor && ci.flags != CURSOR_SHOWING) {
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
result.first = ci.hCursor;
|
||||
result.second = SrcToScaling(ci.ptScreenPos, false);
|
||||
|
||||
return result;
|
||||
_hCursor = ci.hCursor;
|
||||
_cursorPos = SrcToScaling(ci.ptScreenPos);
|
||||
const RECT& scalingRect = ScalingWindow::Get().WndRect();
|
||||
_cursorPos.x -= scalingRect.left;
|
||||
_cursorPos.y -= scalingRect.top;
|
||||
}
|
||||
|
||||
void CursorManager::_ShowSystemCursor(bool show) {
|
||||
|
|
@ -326,7 +321,7 @@ void CursorManager::_UpdateCursorClip() noexcept {
|
|||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
HWND hwndCur = WindowFromPoint(hwndScaling, scalingRect, SrcToScaling(cursorPos, true), false);
|
||||
HWND hwndCur = WindowFromPoint(hwndScaling, scalingRect, SrcToScaling(cursorPos), false);
|
||||
|
||||
if (hwndCur != hwndScaling) {
|
||||
// 主窗口被遮挡
|
||||
|
|
@ -460,7 +455,7 @@ void CursorManager::_UpdateCursorClip() noexcept {
|
|||
// 处理屏幕之间存在间隙的情况。解决办法是 _StopCapture 只在目标位置存在屏幕时才取消捕获,
|
||||
// 当光标试图移动到间隙中时将被挡住。如果光标的速度足以跨越间隙,则它依然可以在屏幕间移动。
|
||||
::GetCursorPos(&cursorPos);
|
||||
POINT hostPos = false ? cursorPos : SrcToScaling(cursorPos, true);
|
||||
POINT hostPos = false ? cursorPos : SrcToScaling(cursorPos);
|
||||
|
||||
RECT clips{ LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX };
|
||||
|
||||
|
|
@ -556,7 +551,7 @@ void CursorManager::_StopCapture(POINT cursorPos, bool onDestroy) noexcept {
|
|||
//
|
||||
// 在有黑边的情况下自动将光标调整到全屏窗口外
|
||||
|
||||
POINT newCursorPos = SrcToScaling(cursorPos, true);
|
||||
POINT newCursorPos = SrcToScaling(cursorPos);
|
||||
|
||||
if (onDestroy || MonitorFromPoint(newCursorPos, MONITOR_DEFAULTTONULL)) {
|
||||
SetCursorPos(newCursorPos.x, newCursorPos.y);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,16 @@ public:
|
|||
|
||||
bool Initialize() noexcept;
|
||||
|
||||
std::pair<HCURSOR, POINT> Update() noexcept;
|
||||
void Update() noexcept;
|
||||
|
||||
HCURSOR Cursor() const noexcept {
|
||||
return _hCursor;
|
||||
}
|
||||
|
||||
// 缩放窗口局部坐标
|
||||
POINT CursorPos() const noexcept {
|
||||
return _cursorPos;
|
||||
}
|
||||
|
||||
private:
|
||||
void _ShowSystemCursor(bool show);
|
||||
|
|
@ -25,6 +34,9 @@ private:
|
|||
|
||||
void _StopCapture(POINT cursorPos, bool onDestroy = false) noexcept;
|
||||
|
||||
HCURSOR _hCursor = NULL;
|
||||
POINT _cursorPos{};
|
||||
|
||||
RECT _curClips{};
|
||||
int _originCursorSpeed = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "Logger.h"
|
||||
#include "Win32Utils.h"
|
||||
#include "ScalingWindow.h"
|
||||
#include "CursorManager.h"
|
||||
|
||||
namespace Magpie::Core {
|
||||
|
||||
|
|
@ -276,9 +277,9 @@ void ImGuiImpl::Tooltip(const char* /*content*/, float /*maxWidth*/) {
|
|||
}
|
||||
|
||||
void ImGuiImpl::_UpdateMousePos() noexcept {
|
||||
/*ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
if (MagApp::Get().GetOptions().Is3DGameMode() && !MagApp::Get().GetRenderer().IsUIVisiable()) {
|
||||
/*if (ScalingWindow::Get().Options().Is3DGameMode() && !MagApp::Get().GetRenderer().IsUIVisiable()) {
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
return;
|
||||
}
|
||||
|
|
@ -298,13 +299,22 @@ void ImGuiImpl::_UpdateMousePos() noexcept {
|
|||
const RECT& hostRect = MagApp::Get().GetHostWndRect();
|
||||
pos.x -= hostRect.left;
|
||||
pos.y -= hostRect.top;
|
||||
}*/
|
||||
|
||||
const CursorManager& cursorManager = ScalingWindow::Get().CursorManager();
|
||||
if (!cursorManager.Cursor()) {
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
const RECT& outputRect = MagApp::Get().GetRenderer().GetOutputRect();
|
||||
pos.x -= outputRect.left;
|
||||
pos.y -= outputRect.top;
|
||||
const POINT cursorPos = cursorManager.CursorPos();
|
||||
const RECT& scalingRect = ScalingWindow::Get().WndRect();
|
||||
const RECT& destRect = ScalingWindow::Get().Renderer().DestRect();
|
||||
|
||||
io.MousePos = ImVec2((float)pos.x, (float)pos.y);*/
|
||||
io.MousePos = ImVec2(
|
||||
float(cursorPos.x + scalingRect.left - destRect.left),
|
||||
float(cursorPos.y + scalingRect.top - destRect.top)
|
||||
);
|
||||
}
|
||||
|
||||
void ImGuiImpl::ClearStates() {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <dispatcherqueue.h>
|
||||
#include "ScalingWindow.h"
|
||||
#include "OverlayDrawer.h"
|
||||
#include "CursorManager.h"
|
||||
|
||||
namespace Magpie::Core {
|
||||
|
||||
|
|
@ -236,7 +237,7 @@ void Renderer::_FrontendRender() noexcept {
|
|||
}
|
||||
|
||||
// 绘制光标
|
||||
_cursorDrawer.Draw(_lastCursorHandle, _lastCursorPos);
|
||||
_cursorDrawer.Draw();
|
||||
|
||||
// 两个垂直同步之间允许渲染数帧,SyncInterval = 0 只呈现最新的一帧,旧帧被丢弃
|
||||
_swapChain->Present(0, 0);
|
||||
|
|
@ -245,11 +246,20 @@ void Renderer::_FrontendRender() noexcept {
|
|||
d3dDC->DiscardView(backBufferRtv);
|
||||
}
|
||||
|
||||
void Renderer::Render(HCURSOR hCursor, POINT cursorPos) noexcept {
|
||||
void Renderer::Render() noexcept {
|
||||
const CursorManager& cursorManager = ScalingWindow::Get().CursorManager();
|
||||
const HCURSOR hCursor = cursorManager.Cursor();
|
||||
const POINT cursorPos = cursorManager.CursorPos();
|
||||
|
||||
// 有新帧或光标改变则渲染新的帧
|
||||
if (_lastAccessMutexKey == _sharedTextureMutexKey) {
|
||||
if (_lastAccessMutexKey == 0 || (hCursor == _lastCursorHandle && cursorPos == _lastCursorPos)) {
|
||||
// 第一帧尚未完成或光标没有移动
|
||||
if (_lastAccessMutexKey == 0) {
|
||||
// 第一帧尚未完成
|
||||
return;
|
||||
}
|
||||
|
||||
if (hCursor == _lastCursorHandle && (!hCursor || cursorPos == _lastCursorPos)) {
|
||||
// 光标没有移动
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public:
|
|||
|
||||
bool Initialize() noexcept;
|
||||
|
||||
void Render(HCURSOR hCursor, POINT cursorPos) noexcept;
|
||||
void Render() noexcept;
|
||||
|
||||
void ToggleOverlay() noexcept;
|
||||
|
||||
|
|
|
|||
|
|
@ -199,8 +199,8 @@ void ScalingWindow::Render() noexcept {
|
|||
return;
|
||||
}
|
||||
|
||||
std::pair<HCURSOR, POINT> cursorInfo = _cursorManager->Update();
|
||||
_renderer->Render(cursorInfo.first, cursorInfo.second);
|
||||
_cursorManager->Update();
|
||||
_renderer->Render();
|
||||
}
|
||||
|
||||
void ScalingWindow::ToggleOverlay() noexcept {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
namespace Magpie::Core {
|
||||
|
||||
class CursorManager;
|
||||
|
||||
class ScalingWindow : public WindowBase<ScalingWindow> {
|
||||
friend class base_type;
|
||||
|
||||
|
|
@ -35,7 +37,7 @@ public:
|
|||
return *_renderer;
|
||||
}
|
||||
|
||||
class CursorManager& CursorManager() noexcept {
|
||||
CursorManager& CursorManager() noexcept {
|
||||
return *_cursorManager;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue