diff --git a/src/kiwano/platform/Runner.cpp b/src/kiwano/platform/Runner.cpp index 90099f3a..737e294b 100644 --- a/src/kiwano/platform/Runner.cpp +++ b/src/kiwano/platform/Runner.cpp @@ -103,7 +103,10 @@ void Runner::InitSettings() } // Create frame ticker - frame_ticker_ = Ticker::Create(settings_.frame_interval, -1); + if (!settings_.frame_interval.IsZero()) + { + frame_ticker_ = Ticker::Create(settings_.frame_interval, -1); + } } bool Runner::MainLoop(Duration dt) diff --git a/src/kiwano/platform/Runner.h b/src/kiwano/platform/Runner.h index 68743408..7240c573 100644 --- a/src/kiwano/platform/Runner.h +++ b/src/kiwano/platform/Runner.h @@ -43,7 +43,7 @@ struct Settings uint32_t width; ///< 窗口宽度 uint32_t height; ///< 窗口高度 String title; ///< 窗口标题 - uint32_t icon; ///< 窗口图标 + Icon icon; ///< 窗口图标 bool resizable; ///< 窗口大小可调整 bool fullscreen; ///< 窗口全屏 Color bg_color; ///< 窗口背景色 @@ -59,8 +59,8 @@ struct Settings , resizable(false) , fullscreen(false) , bg_color(Color::Black) - , frame_interval(16) - , vsync_enabled(false) + , frame_interval(0) + , vsync_enabled(true) , debug_mode(false) { } diff --git a/src/kiwano/platform/Window.h b/src/kiwano/platform/Window.h index 5a6c89b6..8b002286 100644 --- a/src/kiwano/platform/Window.h +++ b/src/kiwano/platform/Window.h @@ -56,6 +56,31 @@ struct Resolution uint32_t refresh_rate; ///< 刷新率 }; +/** + * \~chinese + * @brief 图标 + */ +struct Icon +{ + Icon() = default; + + Icon(const String& file_path) + : file_path(file_path) + { + } + + String file_path; ///< 文件路径 + +#if defined(KGE_PLATFORM_WINDOWS) + uint32_t resource_id = 0; ///< 资源ID,仅在windows上生效 + + Icon(uint32_t resource_id) + : resource_id(resource_id) + { + } +#endif +}; + #if defined(KGE_PLATFORM_WINDOWS) typedef HWND WindowHandle; @@ -79,7 +104,7 @@ public: * @param resizable 窗口大小可拉伸 * @throw kiwano::SystemError 窗口创建失败时抛出 */ - static WindowPtr Create(const String& title, uint32_t width, uint32_t height, uint32_t icon = 0, + static WindowPtr Create(const String& title, uint32_t width, uint32_t height, Icon icon = Icon(), bool resizable = false, bool fullscreen = false); /** @@ -138,9 +163,9 @@ public: /** * \~chinese * @brief 设置窗口图标 - * @param icon_resource 图标资源ID + * @param icon 图标 */ - virtual void SetIcon(uint32_t icon_resource) = 0; + virtual void SetIcon(Icon icon) = 0; /** * \~chinese diff --git a/src/kiwano/platform/win32/WindowImpl.cpp b/src/kiwano/platform/win32/WindowImpl.cpp index 21634135..b920bd34 100644 --- a/src/kiwano/platform/win32/WindowImpl.cpp +++ b/src/kiwano/platform/win32/WindowImpl.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include // GET_X_LPARAM, GET_Y_LPARAM #include // ImmAssociateContext @@ -48,11 +49,11 @@ public: virtual ~WindowWin32Impl(); - void Init(const String& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable, bool fullscreen); + void Init(const String& title, uint32_t width, uint32_t height, Icon icon, bool resizable, bool fullscreen); void SetTitle(const String& title) override; - void SetIcon(uint32_t icon_resource) override; + void SetIcon(Icon icon) override; void SetMinimumSize(uint32_t width, uint32_t height) override; @@ -87,7 +88,7 @@ private: std::array key_map_; }; -WindowPtr Window::Create(const String& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable, +WindowPtr Window::Create(const String& title, uint32_t width, uint32_t height, Icon icon, bool resizable, bool fullscreen) { WindowWin32ImplPtr ptr = memory::New(); @@ -205,7 +206,7 @@ WindowWin32Impl::~WindowWin32Impl() ::timeEndPeriod(0); } -void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable, +void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, Icon icon, bool resizable, bool fullscreen) { HINSTANCE hinst = GetModuleHandle(nullptr); @@ -222,11 +223,20 @@ void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, wcex.lpszMenuName = nullptr; wcex.hCursor = ::LoadCursor(hinst, IDC_ARROW); - if (icon) + if (icon.resource_id != 0 && IS_INTRESOURCE(icon.resource_id)) { - wcex.hIcon = (HICON)::LoadImage(hinst, MAKEINTRESOURCE(icon), IMAGE_ICON, 0, 0, + wcex.hIcon = (HICON)::LoadImage(hinst, MAKEINTRESOURCE(icon.resource_id), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); } + else + { + String full_path = FileSystem::GetInstance().GetFullPathForFile(icon.file_path); + if (!full_path.empty()) + { + wcex.hIcon = (HICON)::LoadImageA(NULL, full_path.c_str(), IMAGE_ICON, 0, 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE); + } + } ::RegisterClassExA(&wcex); @@ -307,16 +317,30 @@ void WindowWin32Impl::SetTitle(const String& title) ::SetWindowTextA(handle_, title.c_str()); } -void WindowWin32Impl::SetIcon(uint32_t icon_resource) +void WindowWin32Impl::SetIcon(Icon icon) { KGE_ASSERT(handle_); - HINSTANCE hinstance = ::GetModuleHandle(nullptr); - HICON icon = (HICON)::LoadImage(hinstance, MAKEINTRESOURCE(icon_resource), IMAGE_ICON, 0, 0, - LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); + HICON hicon = NULL; + if (icon.resource_id != 0 && IS_INTRESOURCE(icon.resource_id)) + { + HINSTANCE hinstance = ::GetModuleHandle(nullptr); - ::SendMessage(handle_, WM_SETICON, ICON_BIG, (LPARAM)icon); - ::SendMessage(handle_, WM_SETICON, ICON_SMALL, (LPARAM)icon); + hicon = (HICON)::LoadImage(hinstance, MAKEINTRESOURCE(icon.resource_id), IMAGE_ICON, 0, 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); + } + else + { + String full_path = FileSystem::GetInstance().GetFullPathForFile(icon.file_path); + if (!full_path.empty()) + { + hicon = (HICON)::LoadImageA(NULL, full_path.c_str(), IMAGE_ICON, 0, 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE); + } + } + + ::SendMessage(handle_, WM_SETICON, ICON_BIG, (LPARAM)hicon); + ::SendMessage(handle_, WM_SETICON, ICON_SMALL, (LPARAM)hicon); } void WindowWin32Impl::SetMinimumSize(uint32_t width, uint32_t height)