Magpie/Runtime/CursorManager.h

94 lines
2.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "pch.h"
class CursorManager {
public:
CursorManager() = default;
CursorManager(const CursorManager&) = delete;
CursorManager(CursorManager&&) = delete;
~CursorManager();
bool Initialize();
void OnBeginFrame();
bool HasCursor() const {
return !!_curCursor;
}
const POINT* GetCursorPos() const {
return _curCursor ? &_curCursorPos : nullptr;
}
struct CursorInfo {
POINT hotSpot{};
SIZE size{};
};
const CursorInfo* GetCursorInfo() const {
return _curCursor ? _curCursorInfo : nullptr;
}
enum class CursorType {
// 彩色光标,此时纹理中 RGB 通道已预乘 A 通道premultiplied alphaA 通道已预先取反
// 这是为了减少着色器的计算量以及确保(可能进行的)双线性差值的准确性
// 计算公式FinalColor = ScreenColor * CursorColor.a + CursorColor.rgb
Color = 0,
// 彩色掩码光标,此时 A 通道可能为 0 或 255
// 为 0 时表示 RGB 通道取代屏幕颜色,为 255 时表示 RGB 通道和屏幕颜色进行异或操作
MaskedColor,
// 单色光标,此时 R 通道为 AND 掩码G 通道为 XOR 掩码,其他通道不使用
// RG 通道的值只能是 0 或 255
Monochrome
};
bool GetCursorTexture(ID3D11Texture2D** texture, CursorManager::CursorType& cursorType);
void OnCursorCapturedOnOverlay();
void OnCursorReleasedOnOverlay();
void OnCursorHoverOverlay();
void OnCursorLeaveOverlay();
bool IsCursorCapturedOnOverlay() const noexcept {
return _isCapturedOnOverlay;
}
bool IsCursorOnOverlay() const noexcept {
return _isOnOverlay;
}
private:
void _StartCapture(POINT cursorPos);
void _StopCapture(POINT cursorPos, bool onDestroy = false);
bool _ResolveCursor(HCURSOR hCursor, bool resolveTexture);
void _AdjustCursorSpeed();
void _UpdateCursorClip();
bool _isUnderCapture = false;
RECT _curClips{};
bool _isCapturedOnOverlay = false;
bool _isOnOverlay = false;
INT _cursorSpeed = 0;
// 当前帧的光标,光标不可见则为 NULL
HCURSOR _curCursor = NULL;
POINT _curCursorPos{};
struct _CursorInfo : CursorInfo {
winrt::com_ptr<ID3D11Texture2D> texture = nullptr;
CursorType type = CursorType::Color;
};
_CursorInfo* _curCursorInfo = nullptr;
std::unordered_map<HCURSOR, _CursorInfo> _cursorInfos;
};