diff options
author | chai <chaifix@163.com> | 2021-10-17 11:14:00 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-17 11:14:00 +0800 |
commit | d35db57d457132dd9d83fa2bd51491b148530655 (patch) | |
tree | b5a29675f091f268577b5991988c723f273b0bd1 /Editor/GUI | |
parent | 7b0a6d1fe0117cf42a5776aaabda2db78599e5b8 (diff) |
*GUI
Diffstat (limited to 'Editor/GUI')
-rw-r--r-- | Editor/GUI/ContainnerWindow.cpp | 291 | ||||
-rw-r--r-- | Editor/GUI/EditorWindows.cpp | 171 | ||||
-rw-r--r-- | Editor/GUI/EditorWindows.h | 89 | ||||
-rw-r--r-- | Editor/GUI/GUIWindow.cpp | 211 | ||||
-rw-r--r-- | Editor/GUI/MenuController.h | 11 | ||||
-rw-r--r-- | Editor/GUI/MenuManager.cpp | 61 | ||||
-rw-r--r-- | Editor/GUI/MenuManager.h | 30 | ||||
-rw-r--r-- | Editor/GUI/SplitWindow.cpp (renamed from Editor/GUI/MenuController.cpp) | 0 | ||||
-rw-r--r-- | Editor/GUI/WinUtils.cpp | 4 | ||||
-rw-r--r-- | Editor/GUI/WindowManager.cpp | 17 | ||||
-rw-r--r-- | Editor/GUI/WindowUtil.cpp | 19 |
11 files changed, 715 insertions, 189 deletions
diff --git a/Editor/GUI/ContainnerWindow.cpp b/Editor/GUI/ContainnerWindow.cpp new file mode 100644 index 0000000..5e6c356 --- /dev/null +++ b/Editor/GUI/ContainnerWindow.cpp @@ -0,0 +1,291 @@ +#include <string> + +#include "EditorWindows.h" +#include "WinUtils.h" +#include "Editor/Utils/HelperFuncs.h" +#include "MenuManager.h" +#include "Runtime/Utilities/Assert.h" + +using namespace std; + +static PAINTSTRUCT ps; +LRESULT CALLBACK ContainnerWindow::ContainerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + log_info("WndProc", "ContainnerWindow::ContainerWndProc()"); + + ContainnerWindow *self = (ContainnerWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (!self) + { + log_warning("Nullptr ContainnerWindow"); + return DefWindowProcW(hWnd, message, wParam, lParam); + } + + switch (message) + { + case WM_MENUSELECT: + { + if (self->m_ShowMode != ShowMode::kShowMainWindow) + return 0; + uint menuId = LOWORD(wParam); + uint flags = HIWORD(wParam); + HMENU menu = (HMENU)lParam; + MenuManager::Instance()->HandleMenuItemEvent(menu, menuId, flags); + return 0; + } + case WM_SETICON: + return WM_SETICON; + case WM_PAINT: + { + log_info("WM_PAINT"); + self->SetAsRenderContext(); + glEnable(GL_BLEND); + float c = 26 / 255.f; + glClearColor(c, c, c, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glFlush(); + BeginPaint(self->m_Window, &ps); + EndPaint(self->m_Window, &ps); + UpdateWindow(self->m_Window); + return 0; + } + } + + long flag = DefWindowProcW(hWnd, message, wParam, lParam); + return flag; +} + +ContainnerWindow::ContainnerWindow() +{ +} + +ContainnerWindow::~ContainnerWindow() +{ + +} + +void ContainnerWindow::DoPaint() +{ + SetWindowLongPtr(m_Window, GWLP_USERDATA, (LONG_PTR)this); + SendMessage(m_Window, WM_PAINT, 0, 0); +} + +void ContainnerWindow::SetAsRenderContext() +{ + Assert(m_DC != NULL); + Assert(m_RC != NULL); + Assert(wglMakeCurrent(m_DC, m_RC)); + RECT rect; + GetWindowRect(m_Window, &rect); + glViewport(0, 0, rect.right - rect.left, rect.bottom - rect.top); +} + +bool ContainnerWindow::SetRenderContext() +{ + m_DC = ::GetDC(m_Window); + if (!m_DC) + log_error("Can't create DC"); + + int bits = 32; + + //static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be + //{ + // sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + // 1, // Version Number + // PFD_DRAW_TO_WINDOW | // Format Must Support Window + // PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + // PFD_DOUBLEBUFFER, // Must Support Double Buffering + // PFD_TYPE_RGBA, // Request An RGBA Format + // bits, // Select Our Color Depth + // 0, 0, 0, 0, 0, 0, // Color Bits Ignored + // 0, // No Alpha Buffer + // 0, // Shift Bit Ignored + // 0, // No Accumulation Buffer + // 0, 0, 0, 0, // Accumulation Bits Ignored + // 16, // 16Bit Z-Buffer (Depth Buffer) + // 0, // No Stencil Buffer + // 0, // No Auxiliary Buffer + // PFD_MAIN_PLANE, // Main Drawing Layer + // 0, // Reserved + // 0, 0, 0 // Layer Masks Ignored + //}; + static PIXELFORMATDESCRIPTOR pfd; + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + + GLuint PixelFormat; + + if (!(PixelFormat = ChoosePixelFormat(m_DC, &pfd))) // Did Windows Find A Matching Pixel Format? + { + MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (!SetPixelFormat(m_DC, PixelFormat, &pfd)) // Are We Able To Set The Pixel Format? + { + MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + int pf = 0; + DescribePixelFormat(m_DC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + if (!(m_RC = wglCreateContext(m_DC))) // Are We Able To Get A Rendering Context? + { + MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + +} + +HWND ContainnerWindow::GetWindowHandle() +{ + return m_Window; +} + +// 初始化,创建窗口 +void ContainnerWindow::Init(Rectf pixelRect, int showMode, const Vector2f& minSize, const Vector2f& maxSize) +{ + // Aux windows are mac only. on windows they look just like normal utility windows. + if (showMode == kShowAuxWindow) + showMode = kShowUtility; + + m_ShowMode = static_cast<ShowMode>(showMode); + m_IsClosing = false; + m_InMenuLoop = false; + m_CloseFromScriptDontShutdown = false; + + bool shouldMaximize = false; + if (showMode == kShowMainWindow) + { + //shouldMaximize = s_IsMainWindowMaximized = EditorPrefs::GetBool(kIsMainWindowMaximized, false); + //GetRestoredMainWindowDimensions(); + } + + RECT rect; + rect.left = pixelRect.x; + rect.right = pixelRect.x + pixelRect.width; + rect.top = pixelRect.y; + rect.bottom = pixelRect.y + pixelRect.height; + m_InternalRect.x = m_InternalRect.y = m_InternalRect.width = m_InternalRect.height = 0.0f; + + DWORD windowStyle = 0; + DWORD extendedStyle = 0; + LPCWSTR windowClass = WindowUtil::kContainerWindowClassName; + + switch (showMode) { + // 容纳GUIPanel的非主窗口 + case kShowNormalWindow: + windowStyle = WS_POPUP | WS_CLIPCHILDREN | WS_THICKFRAME; + extendedStyle = WS_EX_TOOLWINDOW; + break; + // 主窗口,含菜单 + case kShowMainWindow: + windowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_CLIPCHILDREN | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; + extendedStyle = 0; + break; + case kShowPopupMenu: + windowStyle = WS_POPUP | WS_CLIPCHILDREN; + extendedStyle = WS_EX_TOOLWINDOW; + windowClass = WindowUtil::kPopupWindowClassName; + break; + case kShowNoShadow: + windowStyle = WS_POPUP | WS_CLIPCHILDREN; + extendedStyle = WS_EX_TOOLWINDOW; + break; + case kShowUtility: + windowStyle = WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU; + extendedStyle = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW; + break; + default: + // ErrorString("Unknown container show mode"); + break; + } + + HWND parentWindow = NULL; + if (showMode == kShowMainWindow) + { + parentWindow = NULL; + } + else + { + // parentWindow = GetMainEditorWindow(); + } + + bool notSizeable = (minSize == maxSize) && (minSize != Vector2f::zero); + if (notSizeable) + windowStyle &= ~(WS_THICKFRAME); + + AdjustWindowRectEx(&rect, windowStyle, showMode == kShowMainWindow, extendedStyle); + int extraX = rect.right - rect.left - 200; + int extraY = rect.bottom - rect.top - 200; + + m_MinSize.x = minSize.x + extraX; + m_MinSize.y = minSize.y + extraY; + m_MaxSize.x = maxSize.x + extraX; + m_MaxSize.y = maxSize.y + extraY; + + //if (showMode == kShowUtility) + // s_ZUtilityWindows.push_back(m_ContainerListNode); + // Create window + m_Window = CreateWindowExW( + extendedStyle, + windowClass, + L"", + windowStyle, + rect.left, + rect.top, + rect.right - rect.left, + rect.bottom - rect.top, + parentWindow, + NULL, + winutils::GetInstanceHandle(), + NULL + ); + SetWindowLongPtr(m_Window, GWLP_USERDATA, (LONG_PTR)this); + //UpdateMaxMaximizedRect(); + + if (pixelRect.width > 10 || pixelRect.height > 10) + { + //SetRect(pixelRect); + if (shouldMaximize) + SetWindowLong(m_Window, GWL_STYLE, windowStyle | WS_MAXIMIZE); + } + + if (showMode == kShowMainWindow) + { + //SetMainEditorWindow(m_Window); + //HMENU menu = GetMainMenuHandle(); + //if (menu) + // SetMenu(m_Window, menu); + //GetApplication().UpdateMainWindowTitle(); + //GetApplication().UpdateDocumentEdited(); + } + ShowWindow(m_Window, SW_SHOW); + + //s_ContainerWindows.insert(this); + + //ShowInTaskbarIfNoMainWindow(m_Window); + + SetRenderContext(); +} + +void ContainnerWindow::SetTitle(const char* title) +{ + SetWindowTextA(m_Window, title); +} + +void ContainnerWindow::SetIcon(LPCSTR iconName) +{ + Assert(m_ShowMode == ShowMode::kShowMainWindow); + + HICON hWindowIcon = (HICON )LoadImage(winutils::GetInstanceHandle(), iconName, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE); + if (hWindowIcon == NULL) + log_error("icon error: " + to_string(GetLastError())); + if (SendMessage(m_Window, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon) != WM_SETICON) + log_error("icon error: " + to_string(GetLastError())); + if (SendMessage(m_Window, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon) != WM_SETICON) + log_error("icon error: " + to_string(GetLastError())); +} diff --git a/Editor/GUI/EditorWindows.cpp b/Editor/GUI/EditorWindows.cpp deleted file mode 100644 index 6d24dbd..0000000 --- a/Editor/GUI/EditorWindows.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "EditorWindows.h"
-#include "WinUtils.h"
-
-static const wchar_t* kContainerWindowClassName = L"GameLabContainerWndClass"; -static const wchar_t* kPopupWindowClassName = L"GameLabPopupWndClass"; -static const wchar_t* kViewportClassName = L"GameLabViewportWndClass"; -static const char* kIsMainWindowMaximized = "IsMainWindowMaximized"; - -static ATOM s_ContainerWindowClassAtom; -static ATOM s_PopupWindowClassAtom; -static ATOM s_GUIViewClassAtom; -
-void RegisterWindowClasses()
-{
- s_ContainerWindowClassAtom = winutils::RegisterWindowClass(kContainerWindowClassName, ContainnerWindow::ContainerWndProc, CS_HREDRAW | CS_VREDRAW); - s_PopupWindowClassAtom = winutils::RegisterWindowClass(kPopupWindowClassName, ContainnerWindow::ContainerWndProc, CS_HREDRAW | CS_VREDRAW | CS_DROPSHADOW);//CS_HREDRAW宽度(水平)变化时重绘、CS_VREDRAW高度(垂直)变化时重绘 - s_GUIViewClassAtom = winutils::RegisterWindowClass(kViewportClassName, GUIView::GUIViewWndProc, CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS); -}
-
-LRESULT CALLBACK ContainnerWindow::ContainerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- long flag = DefWindowProcW(hWnd, message, wParam, lParam); - return flag; -}
-
-ContainnerWindow::ContainnerWindow()
-{
-}
-
-
-ContainnerWindow::~ContainnerWindow()
-{
-
-}
-
-void ContainnerWindow::Init(Rectf pixelRect, int showMode, const Vector2f& minSize, const Vector2f& maxSize)
-{ - // Aux windows are mac only. on windows they look just like normal utility windows. - if (showMode == kShowAuxWindow) - showMode = kShowUtility; - - m_ShowMode = static_cast<ShowMode>(showMode); - m_IsClosing = false; - m_InMenuLoop = false; - m_CloseFromScriptDontShutdown = false; - - bool shouldMaximize = false; - if (showMode == kShowMainWindow) - { - //shouldMaximize = s_IsMainWindowMaximized = EditorPrefs::GetBool(kIsMainWindowMaximized, false); - //GetRestoredMainWindowDimensions(); - } - - RECT rect = { 120, 120, 220, 220 }; - m_InternalRect.x = m_InternalRect.y = m_InternalRect.width = m_InternalRect.height = 0.0f; - - DWORD windowStyle = 0; - DWORD extendedStyle = 0; - LPCWSTR windowClass = kContainerWindowClassName; - - switch (showMode) { - // 容纳GUIPanel的非主窗口 - case kShowNormalWindow: - windowStyle = WS_POPUP | WS_CLIPCHILDREN | WS_THICKFRAME; - extendedStyle = WS_EX_TOOLWINDOW; - break; - // 主窗口,含菜单 - case kShowMainWindow: - windowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_CLIPCHILDREN | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; - extendedStyle = 0; - break; - case kShowPopupMenu: - windowStyle = WS_POPUP | WS_CLIPCHILDREN; - extendedStyle = WS_EX_TOOLWINDOW; - windowClass = kPopupWindowClassName; - break; - case kShowNoShadow: - windowStyle = WS_POPUP | WS_CLIPCHILDREN; - extendedStyle = WS_EX_TOOLWINDOW; - break; - case kShowUtility: - windowStyle = WS_POPUP | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU; - extendedStyle = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW; - break; - default: - // ErrorString("Unknown container show mode"); - break; - } - - HWND parentWindow = NULL; - if (showMode == kShowMainWindow) - { - parentWindow = NULL; - } - else - { - // parentWindow = GetMainEditorWindow(); - } - - bool notSizeable = (minSize == maxSize) && (minSize != Vector2f::zero); - if (notSizeable) - windowStyle &= ~(WS_THICKFRAME); - - AdjustWindowRectEx(&rect, windowStyle, showMode == kShowMainWindow, extendedStyle); - int extraX = rect.right - rect.left - 200; - int extraY = rect.bottom - rect.top - 200; - - m_MinSize.x = minSize.x + extraX; - m_MinSize.y = minSize.y + extraY; - m_MaxSize.x = maxSize.x + extraX; - m_MaxSize.y = maxSize.y + extraY; - - - //if (showMode == kShowUtility) - // s_ZUtilityWindows.push_back(m_ContainerListNode); - // Create window - m_Window = CreateWindowExW( - extendedStyle, - windowClass, - L"", - windowStyle, - rect.left, - rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - parentWindow, - NULL, - winutils::GetInstanceHandle(), - NULL - ); - SetWindowLongPtr(m_Window, GWLP_USERDATA, (LONG_PTR)this); - //UpdateMaxMaximizedRect(); - - if (pixelRect.width > 10 || pixelRect.height > 10) - { - //SetRect(pixelRect); - if (shouldMaximize) - SetWindowLong(m_Window, GWL_STYLE, windowStyle | WS_MAXIMIZE); - } - - - if (showMode == kShowMainWindow) - { - //SetMainEditorWindow(m_Window); - //HMENU menu = GetMainMenuHandle(); - //if (menu) - // SetMenu(m_Window, menu); - //GetApplication().UpdateMainWindowTitle(); - //GetApplication().UpdateDocumentEdited(); - } - ShowWindow(m_Window, SW_SHOW); - - //s_ContainerWindows.insert(this); - - //ShowInTaskbarIfNoMainWindow(m_Window);
-
-}
-
-//------------------------------------------------------------------------------------------------------------------
-
-LRESULT CALLBACK GUIView::GUIViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- long flag = DefWindowProcW(hWnd, message, wParam, lParam); - return flag; -} - -void GUIView::DoPaint() -{
-
- -}
\ No newline at end of file diff --git a/Editor/GUI/EditorWindows.h b/Editor/GUI/EditorWindows.h index 4bd33ec..33d99c1 100644 --- a/Editor/GUI/EditorWindows.h +++ b/Editor/GUI/EditorWindows.h @@ -2,15 +2,38 @@ #define EDITOR_WINDOW_H #include <windows.h> +#include <vector> #include "Runtime/Math/Rect.h" #include "Runtime/Scripting/LuaBind.h" +#include "Runtime/Utilities/Singleton.h" +#include "Editor/Utils/Log.h" +#include "Runtime/Graphics/OpenGL.h" -void RegisterWindowClasses(); +class GUIWindow; + +class WindowUtil +{ +public : + static void Init(); + + static const wchar_t* kContainerWindowClassName; + static const wchar_t* kPopupWindowClassName; + static const wchar_t* kGUIWindowClassName; +}; + +class WindowManager : Singleton<WindowManager> +{ +public: + static Vector2f GetMousePosition(); + static GUIWindow* GetMouseOverWindow(); +}; // 一个containner window中有多个viewport class ContainnerWindow { public: + static LRESULT CALLBACK ContainerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + enum ShowMode { kShowNormalWindow = 0, // normal window with max/min/close buttons kShowPopupMenu = 1, // popup menu - no title bar @@ -23,12 +46,22 @@ public: ContainnerWindow(); ~ContainnerWindow(); - static LRESULT CALLBACK ContainerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - void Init(Rectf size, int showMode, const Vector2f& minSize, const Vector2f& maxSize); + void SetTitle(const char* title); + void SetIcon(LPCSTR iconName); + void SetAsRenderContext(); + void DoPaint(); + + HWND GetWindowHandle(); + HDC GetDC() { return m_DC; } + HGLRC GetRC() { return m_RC; } private: + bool SetRenderContext(); + HWND m_Window; + HDC m_DC; + HGLRC m_RC; POINT m_Size; ShowMode m_ShowMode; // 窗口类型 bool m_IsClosing; @@ -40,20 +73,62 @@ private: }; +// 窗口基类 +class WindowBase +{ +}; + +// 抽象窗口,用来做布局 +class SplitWindow : public WindowBase +{ +public: + enum SplitMode + { + Horizontal, + Vertical, + }; + + SplitMode GetSplitMode() { return m_SplitMode; } + +private: + SplitMode m_SplitMode; + + GUIWindow* m_GUIWindow; + std::vector<GUIWindow*> m_GUIWindows; -// 窗口内的单个子窗口,是事件相应、绘制、布局的单元 -class GUIView +}; + +// GUI窗口,事件相应、绘制、布局的单元 +// 和unity不一样的地方在于一个GUIWindow只会有一个EditorWindow,即一个切页,因为在实际开发中我发现很少会频繁的切换切页,UE逻辑更像blender +// 好处也在于比较好组织 +class GUIWindow : public WindowBase { public: static LRESULT CALLBACK GUIViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + static void RepaintAll(); + void Init(); void DoPaint(); + void SetContainnerWindow(ContainnerWindow* wnd); + void Focus(); + void SetPosition(Rectf position); + void SetAsRenderContext(); + + void OnFocus(); + void OnLostFocus(); + + HDC GetDC() { return m_DC; } + HGLRC GetRC() { return m_RC; } private: - HWND m_View; + bool SetRenderContext(); - LuaBind::Ref m_Script; + ContainnerWindow* m_ContainnerWindow; + HWND m_Handle; + HDC m_DC; + HGLRC m_RC; + LuaBind::Ref m_Script; }; diff --git a/Editor/GUI/GUIWindow.cpp b/Editor/GUI/GUIWindow.cpp new file mode 100644 index 0000000..e13770e --- /dev/null +++ b/Editor/GUI/GUIWindow.cpp @@ -0,0 +1,211 @@ +#include "EditorWindows.h" +#include "WinUtils.h" +#include "Runtime/Graphics/OpenGL.h" + +static PAINTSTRUCT ps; +LRESULT CALLBACK GUIWindow::GUIViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + log_info("WndProc", "GUIWindow::GUIViewWndProc(), hWnd=" /*+ (long)hWnd*/); + + GUIWindow* wnd = (GUIWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (!wnd) + { + log_warning("GUIWindow::GUIViewWndProc(), lParam为空"); + return DefWindowProcW(hWnd, message, wParam, lParam); + } + + switch (message) + { + case WM_PAINT: + { + log_info("WM_PAINT"); + wnd->SetAsRenderContext(); + glEnable(GL_BLEND); + glClearColor(1,0,0,1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glFlush(); + BeginPaint(wnd->m_Handle, &ps); + EndPaint(wnd->m_Handle, &ps); + UpdateWindow(wnd->m_Handle); + return 0; + } + } + + long flag = DefWindowProcW(hWnd, message, wParam, lParam); + return flag; +} + +void GUIWindow::RepaintAll() +{ +} + +////////////////////////////////////////////////////////////////////////////////////////// + +void GUIWindow::Init() +{ + log_info("Init GUIWindow " /*+ (long)this*/); + + DWORD windowStyle = WS_CHILD; + //DWORD windowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_CLIPCHILDREN | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; + DWORD extendedStyle = WS_EX_TOOLWINDOW; + + Rectf pixelRect; + pixelRect.x = 0; + pixelRect.y = 0; + pixelRect.width = 32; + pixelRect.height = 32; + + RECT rc; + rc.left = pixelRect.x; + rc.top = pixelRect.y; + rc.right = pixelRect.x + pixelRect.width; + rc.bottom = pixelRect.y + pixelRect.height; + AdjustWindowRectEx(&rc, windowStyle, FALSE, extendedStyle); + + m_Handle = CreateWindowExW( + extendedStyle, + WindowUtil::kGUIWindowClassName, + L"", + windowStyle, + rc.left, + rc.top, + rc.right - rc.left, + rc.bottom - rc.top, + HWND_MESSAGE, // message only + NULL, + winutils::GetInstanceHandle(), + NULL + ); + + SetWindowLongPtr(m_Handle, GWLP_USERDATA, (LONG_PTR)this); + + ShowWindow(m_Handle, SW_SHOW); + + if (!SetRenderContext()) + log_error("Failed to setup rendering context"); + + log_info("Created GUIWindow " /*+ (long)this*/); +} + +bool GUIWindow::SetRenderContext() +{ + m_DC = ::GetDC(m_Handle); + if (!m_DC) + log_error("Can't create DC"); + + int bits = 32; + + //static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be + //{ + // sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + // 1, // Version Number + // PFD_DRAW_TO_WINDOW | // Format Must Support Window + // PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + // PFD_DOUBLEBUFFER, // Must Support Double Buffering + // PFD_TYPE_RGBA, // Request An RGBA Format + // bits, // Select Our Color Depth + // 0, 0, 0, 0, 0, 0, // Color Bits Ignored + // 0, // No Alpha Buffer + // 0, // Shift Bit Ignored + // 0, // No Accumulation Buffer + // 0, 0, 0, 0, // Accumulation Bits Ignored + // 16, // 16Bit Z-Buffer (Depth Buffer) + // 0, // No Stencil Buffer + // 0, // No Auxiliary Buffer + // PFD_MAIN_PLANE, // Main Drawing Layer + // 0, // Reserved + // 0, 0, 0 // Layer Masks Ignored + //}; + static PIXELFORMATDESCRIPTOR pfd; + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + + GLuint PixelFormat; + + if (!(PixelFormat = ChoosePixelFormat(m_DC, &pfd))) // Did Windows Find A Matching Pixel Format? + { + MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (!SetPixelFormat(m_DC, PixelFormat, &pfd)) // Are We Able To Set The Pixel Format? + { + MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + int pf = 0; + DescribePixelFormat(m_DC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + if (!(m_RC = wglCreateContext(m_DC))) // Are We Able To Get A Rendering Context? + { + MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + return true; +} + +void GUIWindow::DoPaint() +{ + SetWindowLongPtr(m_Handle, GWLP_USERDATA,(LONG_PTR ) this); + SendMessage(m_Handle, WM_PAINT, 0, 0); +} + +void GUIWindow::OnFocus() +{ +} + +void GUIWindow::OnLostFocus() +{ +} + +void GUIWindow::SetPosition(Rectf position) +{ + log_info("GUIWindow::SetPosition()"); + RECT rc; + rc.left = position.x; + rc.top = position.y; + rc.right = position.x + position.width; + rc.bottom = position.y + position.height; + ::SetWindowPos(m_Handle, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_FRAMECHANGED | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOZORDER); +} + +void GUIWindow::SetAsRenderContext() +{ + Assert(m_DC != NULL); + Assert(m_RC != NULL); + Assert(wglMakeCurrent(m_DC, m_RC)); + RECT rect; + GetWindowRect(m_Handle, &rect); + glViewport(0, 0, rect.right - rect.left, rect.bottom - rect.top); +} + +void GUIWindow::Focus() +{ + log_info("Focus GUIWindow " + (long)this); + if (m_Handle) + { + if (::GetForegroundWindow() != m_ContainnerWindow->GetWindowHandle()) + ::SetForegroundWindow(m_ContainnerWindow->GetWindowHandle()); + SetFocus(m_Handle); + } +} + +void GUIWindow::SetContainnerWindow(ContainnerWindow* wnd) +{ + Assert(wnd != NULL); + + m_ContainnerWindow = wnd; + + if (wnd->GetWindowHandle() != m_Handle) + { + HWND parentWindowHandle = wnd->GetWindowHandle(); + if (::GetParent(m_Handle) != parentWindowHandle) + ::SetParent(m_Handle, parentWindowHandle); + ::ShowWindow(m_Handle, SW_SHOWNORMAL); + } +}
\ No newline at end of file diff --git a/Editor/GUI/MenuController.h b/Editor/GUI/MenuController.h deleted file mode 100644 index 9abe9e5..0000000 --- a/Editor/GUI/MenuController.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef MENU_CONTROLLER_H -#define MENU_CONTROLLER_H - -// 管理menu item - -class MenuController { - -}; - - -#endif
\ No newline at end of file diff --git a/Editor/GUI/MenuManager.cpp b/Editor/GUI/MenuManager.cpp new file mode 100644 index 0000000..53dfd5a --- /dev/null +++ b/Editor/GUI/MenuManager.cpp @@ -0,0 +1,61 @@ +//https://stackoverflow.com/questions/30135494/win32-api-c-menu-bar +//https://docs.microsoft.com/en-us/windows/win32/menurc/using-menus + +#include <string> + +#include "MenuManager.h" +#include "../EditorManager.h" + +const int IDM_FILE_NEW = 10; +const int IDM_ASSET = 20; + +using namespace std; + +MenuManager::MenuManager() + : m_Menus() +{ +} + +void MenuManager::Init() +{ + ContainnerWindow* mainWnd = EditorManager::Instance()->GetMainWindow(); + Assert(mainWnd != NULL); + + HMENU hMenubar = CreateMenu(); + + HMENU hMenu = CreateMenu(); + HMENU hSubMenu = CreatePopupMenu(); + HMENU asserMenu = CreateMenu(); + + AppendMenuW(hMenu, MF_STRING, IDM_FILE_NEW, L"&New"); + AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL); + + AppendMenuW(asserMenu, MF_STRING, IDM_ASSET, L"Import &mail &assets"); + AppendMenuW(hSubMenu, MF_STRING | MF_POPUP, (UINT_PTR)asserMenu, L"Import &mail"); + AppendMenuW(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hSubMenu, L"&Import"); + + AppendMenuW(hMenubar, MF_POPUP, (UINT_PTR)hMenu, L"&File"); + + AppendMenuW(hMenu, MF_STRING, IDM_FILE_NEW + 5, L"New 2"); + //InsertMenu(hMenu, 1, MF_SEPARATOR | MF_BYPOSITION, 0, NULL); + + SetMenu(mainWnd->GetWindowHandle(), hMenubar); + +} + +void MenuManager::AddMenuItem(std::string name, int order) +{ + log_info("Menu", " Add menu item \"" + name + "\""); + +} + +void MenuManager::HandleMenuItemEvent(HMENU menu, unsigned int menuId, unsigned int flags) +{ + log_info("Menu", "menuId=" + to_string(menuId) + ", flags=" + to_string(flags)); + + if (flags & MF_CHECKED) // clicked + { + log_info("Menu", "checked"); + + } +}
\ No newline at end of file diff --git a/Editor/GUI/MenuManager.h b/Editor/GUI/MenuManager.h new file mode 100644 index 0000000..8d0339d --- /dev/null +++ b/Editor/GUI/MenuManager.h @@ -0,0 +1,30 @@ +#ifndef MENU_CONTROLLER_H +#define MENU_CONTROLLER_H + +#include <string> +#include <unordered_map> +#include <windows.h> + +#include "Runtime/Utilities/Singleton.h" + +class MenuItem +{ + +}; + +class MenuManager : public Singleton<MenuManager> +{ +public: + MenuManager(); + + void Init(); + void AddMenuItem(std::string name, int order = 0); + void HandleMenuItemEvent(HMENU menu, unsigned int menuId, unsigned int flags); + +private: + std::unordered_map<std::string, HMENU> m_Menus; + +}; + + +#endif
\ No newline at end of file diff --git a/Editor/GUI/MenuController.cpp b/Editor/GUI/SplitWindow.cpp index e69de29..e69de29 100644 --- a/Editor/GUI/MenuController.cpp +++ b/Editor/GUI/SplitWindow.cpp diff --git a/Editor/GUI/WinUtils.cpp b/Editor/GUI/WinUtils.cpp index e7b2d5b..84d0e37 100644 --- a/Editor/GUI/WinUtils.cpp +++ b/Editor/GUI/WinUtils.cpp @@ -7,6 +7,10 @@ namespace winutils HINSTANCE GetInstanceHandle() { + if (gInstanceHandle == NULL) + { + gInstanceHandle = GetModuleHandle(NULL); + } return gInstanceHandle; }
diff --git a/Editor/GUI/WindowManager.cpp b/Editor/GUI/WindowManager.cpp new file mode 100644 index 0000000..add2066 --- /dev/null +++ b/Editor/GUI/WindowManager.cpp @@ -0,0 +1,17 @@ +#include "EditorWindows.h" +#include "WinUtils.h" + +GUIWindow* WindowManager::GetMouseOverWindow() +{ + return NULL; +} + +Vector2f WindowManager::GetMousePosition() +{ + POINT pt; + if (!GetCursorPos(&pt)) + return Vector2f(0, 0); + + return Vector2f(pt.x, pt.y); + +} diff --git a/Editor/GUI/WindowUtil.cpp b/Editor/GUI/WindowUtil.cpp new file mode 100644 index 0000000..fc32719 --- /dev/null +++ b/Editor/GUI/WindowUtil.cpp @@ -0,0 +1,19 @@ +#include "EditorWindows.h" +#include "WinUtils.h" + +const wchar_t* WindowUtil::kContainerWindowClassName = L"GameLabContainerWndClass"; +const wchar_t* WindowUtil::kPopupWindowClassName = L"GameLabPopupWndClass"; +const wchar_t* WindowUtil::kGUIWindowClassName = L"GUIViewWindowClassName"; + +static ATOM ContainerWindowClassAtom; +static ATOM PopupWindowClassAtom; +static ATOM GUIViewClassAtom; + +void WindowUtil::Init() +{ + log_info("WindowUtil::Init()"); + + ContainerWindowClassAtom = winutils::RegisterWindowClass(kContainerWindowClassName, ContainnerWindow::ContainerWndProc, CS_HREDRAW | CS_VREDRAW); + PopupWindowClassAtom = winutils::RegisterWindowClass(kPopupWindowClassName, ContainnerWindow::ContainerWndProc, CS_HREDRAW | CS_VREDRAW | CS_DROPSHADOW);//CS_HREDRAW宽度(水平)变化时重绘、CS_VREDRAW高度(垂直)变化时重绘 + GUIViewClassAtom = winutils::RegisterWindowClass(kGUIWindowClassName, GUIWindow::GUIViewWndProc, CS_HREDRAW | CS_VREDRAW | CS_DROPSHADOW); +}
\ No newline at end of file |