forked from Blinue/Magpie
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CursorManager.h
94 lines (67 loc) · 2.26 KB
/
CursorManager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#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 alpha),A 通道已预先取反
// 这是为了减少着色器的计算量以及确保(可能进行的)双线性差值的准确性
// 计算公式: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;
};