-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMainWindow.h
208 lines (184 loc) · 7.73 KB
/
MainWindow.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*
Copyright (c) 2015-2021 hkrn All rights reserved
This file is part of emapp component and it's licensed under Mozilla Public License. see LICENSE.md for more details.
*/
#pragma once
#ifndef NANOEM_EMAPP_WIN32_MAINWINDOW_H_
#define NANOEM_EMAPP_WIN32_MAINWINDOW_H_
#include <Windows.h>
#include <dxgi.h>
#include <shellapi.h>
#include "Win32ApplicationMenuBuilder.h"
#include "emapp/BaseApplicationService.h"
#include "emapp/IFileManager.h"
#include "bx/os.h"
struct IProgressDialog;
struct ID3D12CommandQueue;
struct ID3D12Device;
namespace bx {
class CommandLine;
} /* namespace bx */
namespace nanoem {
class ThreadedApplicationClient;
namespace win32 {
class Dialog;
class Preference;
class Win32ThreadedApplicationService;
class MainWindow final {
public:
MainWindow(const bx::CommandLine *cmd, const Preference *preference,
win32::Win32ThreadedApplicationService *service, ThreadedApplicationClient *client, HINSTANCE hInstance,
const Vector4UI32 &rect, nanoem_f32_t devicePixelRatio);
~MainWindow();
bool initialize(HWND windowHandle, Error &error);
bool isRunning() const noexcept;
void processMessage(MSG *msg);
HWND windowHandle() noexcept;
HMENU menuHandle() noexcept;
void clearTitle();
void setTitle(const URI &fileURI);
private:
enum DisabledCursorState {
kDisabledCursorStateNone,
kDisabledCursorStateInitial,
kDisabledCursorStateMoving,
};
struct FPSThresholder {
FPSThresholder(uint32_t value, bool enabled)
: m_value(value)
, m_preferred(value)
, m_enabled(enabled)
{
}
void
operator=(uint32_t value)
{
m_value = value;
}
void
threshold(uint32_t displayFrequency)
{
if (m_enabled) {
const uint32_t value = m_value > 0 ? m_value : m_preferred;
if (value > 0 && value < displayFrequency) {
bx::sleep(uint32_t((1.0f / (value + 1)) * 1000.0f));
}
}
}
uint32_t m_value;
uint32_t m_preferred;
bool m_enabled;
};
typedef tinystl::vector<nanoem_u16_t, TinySTLAllocator> HandleList;
typedef tinystl::unordered_map<String, tinystl::pair<HANDLE, HandleList>, TinySTLAllocator> FileHandleListMap;
static LRESULT CALLBACK handleWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
static DWORD CALLBACK collectPerformanceMetricsPeriodically(void *userData);
static BaseApplicationService::KeyType translateKey(LPARAM lparam) noexcept;
static Vector2SI32 devicePixelScreenPosition(HWND hwnd, const Vector2SI32 &value) noexcept;
static int cursorModifiers() noexcept;
static int convertCursorType(UINT msg, WPARAM wparam) noexcept;
static void handleAddingWatchEffectSource(void *userData, nanoem_u16_t handle, const URI &fileURI);
static void handleRemovingWatchEffectSource(void *userData, uint16_t handle, const char *name);
void handleInitializeEvent();
void handleDestroyEvent();
void handleTerminateEvent();
bool handleWindowCreate(HWND hwnd, Error &error);
void handleWindowResize(HWND hwnd, WPARAM type);
void handleWindowPositionChange(HWND hwnd);
void handleWindowConstraint(HWND hwnd, LPMINMAXINFO info);
void handleWindowDropFile(HWND hwnd, HDROP drop);
void handleWindowClose(HWND hwnd);
void handleWindowDestroy(HWND hwnd);
void handleMouseDown(HWND hwnd, const Vector2SI32 &coord, int type);
void handleMouseMove(HWND hwnd, const Vector2SI32 &coord, int type);
void handleMouseUp(HWND hwnd, const Vector2SI32 &coord, int type);
void handleMouseWheel(HWND hwnd, const Vector2SI32 &delta);
void handleMenuItem(HWND hwnd, ApplicationMenuBuilder::MenuItemType menuType);
nanoem_f32_t invertedDevicePixelRatio() const noexcept;
void newProject();
void openProject();
void saveProject();
void saveProjectAs();
void loadFile(const Dialog &dialog, IFileManager::DialogType type);
void loadFile(const URI &fileURI, IFileManager::DialogType type);
void saveFile(const Dialog &dialog, IFileManager::DialogType type);
void saveFile(const URI &fileURI, IFileManager::DialogType type);
void exportImage();
void exportVideo();
bool setupDirectXRenderer(HWND windowHandle, int width, int height, bool &isLowPower, Error &error);
bool setupOpenGLRenderer(HWND windowHandle, Error &error);
void destroyRenderer();
void destroyWindow();
void registerAllPrerequisiteEventListeners();
bool openProgressDialog(IProgressDialog *&dialog);
void closeProgressDialog();
Vector2SI32 virtualLogicalCursorPosition(const Vector2SI32 &value) const;
Vector2SI32 lastLogicalCursorPosition() const;
bool isCursorHidden() const;
void setLastLogicalCursorPosition(const Vector2SI32 &value);
void setLastLogicalCursorPosition(const Vector2SI32 &value, const Vector2SI32 &delta);
void getWindowCenterPoint(LPPOINT devicePoint) const;
void setCursorPosition(POINT devicePoint);
void centerCursor(LPPOINT devicePoint);
void updateClipCursorRect();
void lockCursor(LPPOINT devicePoint);
void disableCursor(const Vector2SI32 &logicalCursorPosition);
void unlockCursor(const Vector2SI32 &logicalCursorPosition);
void enableCursor(const Vector2SI32 &logicalCursorPosition);
void setFocus();
void killFocus();
void recenterCursor();
void updateDisplayFrequency();
void resizeWindow();
void resizeWindow(const Vector2UI32 &logicalWindowSize);
void updatePreferredFPS(const POWERBROADCAST_SETTING *settings);
void enablePowerSaving(bool value);
bool isEditingDisplaySyncEnabled() const noexcept;
URIList cachedAggregateAllPlugins();
const char *localizedString(const char *text) const;
const wchar_t *localizedWideString(const char *text) const;
void loadProjectFromFile(const wchar_t *source);
void destroyAllWatchEffectSources();
using TranslatedMessageCache = tinystl::unordered_map<const char *, MutableWideString, TinySTLAllocator>;
mutable TranslatedMessageCache m_localizedMessageCache;
const Preference *m_preference;
const bx::CommandLine *m_commandLine;
Win32ThreadedApplicationService *m_service = nullptr;
Win32ApplicationMenuBuilder *m_menuBuilder = nullptr;
ThreadedApplicationClient *m_client = nullptr;
HWND m_windowHandle = nullptr;
HMENU m_menuHandle = nullptr;
HANDLE m_metricThreadHandle = nullptr;
HANDLE m_processHandle = nullptr;
void *m_sentryDllHandle = nullptr;
void *m_context = nullptr;
void *m_device = nullptr;
DXGI_SWAP_CHAIN_DESC m_swapChainDesc;
IDXGISwapChain *m_swapChain = nullptr;
ID3D12Device *m_device12 = nullptr;
ID3D12CommandQueue *m_commandQueue = nullptr;
tinystl::pair<IProgressDialog *, int> m_progressDialog =
tinystl::make_pair(static_cast<IProgressDialog *>(nullptr), 0);
HACCEL m_accelerators = nullptr;
RECT m_lastWindowRect;
URIList m_cachedPluginURIs;
FileHandleListMap m_watchEffectSourceHandles;
Vector2SI32 m_lastLogicalCursorPosition;
Vector2SI32 m_virtualLogicalCursorPosition;
Vector2SI32 m_restoreHiddenLogicalCursorPosition;
DisabledCursorState m_disabledCursorState = kDisabledCursorStateNone;
FPSThresholder m_playingThresholder;
FPSThresholder m_editingThresholder;
Vector2UI32 m_logicalWindowSize;
nanoem_f32_t m_devicePixelRatio = 1.0f;
uint32_t m_displayFrequency = 0;
bool m_disabledCursorResigned = false;
bool m_vsyncAtPlaying = true;
bool m_initialized = false;
bool m_isFullScreen = false;
bool m_renderable = true;
volatile bool m_running = true;
};
} /* namespace win32 */
} /* namespace nanoem */
#endif /* NANOEM_EMAPP_WIN32_MAINWINDOW_H_ */