Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVojtech Kral <vojtech@kral.hk>2019-04-02 13:00:50 +0300
committerVojtech Kral <vojtech@kral.hk>2019-04-08 12:34:46 +0300
commit7e32f2df711e524cac803aacaee5040509205bb8 (patch)
treedeffa079d0bd80c4fe83b14896b8d6e44d4ecfe6 /src/slic3r/GUI/GUI_Utils.cpp
parentaf05e5fc2ca33b5a5ac054356a83987977f4fbde (diff)
Implement per-screen DPI on Windows, DPI change event, wxDialog & wxFrame mixin base classes
Diffstat (limited to 'src/slic3r/GUI/GUI_Utils.cpp')
-rw-r--r--src/slic3r/GUI/GUI_Utils.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/slic3r/GUI/GUI_Utils.cpp b/src/slic3r/GUI/GUI_Utils.cpp
index 56d6eaeb5..6dc5c5b4c 100644
--- a/src/slic3r/GUI/GUI_Utils.cpp
+++ b/src/slic3r/GUI/GUI_Utils.cpp
@@ -4,9 +4,14 @@
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+
#include <wx/toplevel.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
+#include <wx/dcclient.h>
#include "libslic3r/Config.hpp"
@@ -48,6 +53,64 @@ void on_window_geometry(wxTopLevelWindow *tlw, std::function<void()> callback)
#endif
}
+wxDEFINE_EVENT(EVT_DPI_CHANGED, DpiChangedEvent);
+
+#ifdef _WIN32
+template<class F> typename F::FN winapi_get_function(const wchar_t *dll, const char *fn_name) {
+ static HINSTANCE dll_handle = LoadLibraryExW(dll, nullptr, 0);
+
+ if (dll_handle == nullptr) { return nullptr; }
+ return (F::FN)GetProcAddress(dll_handle, fn_name);
+}
+#endif
+
+int get_dpi_for_window(wxWindow *window)
+{
+#ifdef _WIN32
+ enum MONITOR_DPI_TYPE_ {
+ // This enum is inlined here to avoid build-time dependency
+ MDT_EFFECTIVE_DPI_ = 0,
+ MDT_ANGULAR_DPI_ = 1,
+ MDT_RAW_DPI_ = 2,
+ MDT_DEFAULT_ = MDT_EFFECTIVE_DPI_,
+ };
+
+ // Need strong types for winapi_get_function() to work
+ struct GetDpiForWindow_t { typedef HRESULT (WINAPI *FN)(HWND hwnd); };
+ struct GetDpiForMonitor_t { typedef HRESULT (WINAPI *FN)(HMONITOR hmonitor, MONITOR_DPI_TYPE_ dpiType, UINT *dpiX, UINT *dpiY); };
+
+ static auto GetDpiForWindow_fn = winapi_get_function<GetDpiForWindow_t>(L"User32.dll", "GetDpiForWindow");
+ static auto GetDpiForMonitor_fn = winapi_get_function<GetDpiForMonitor_t>(L"Shcore.dll", "GetDpiForMonitor");
+
+ const HWND hwnd = window->GetHandle();
+
+ if (GetDpiForWindow_fn != nullptr) {
+ // We're on Windows 10, we have per-screen DPI settings
+ return GetDpiForWindow_fn(hwnd);
+ } else if (GetDpiForMonitor_fn != nullptr) {
+ // We're on Windows 8.1, we have per-system DPI
+ // Note: MonitorFromWindow() is available on all Windows.
+
+ const HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+ UINT dpiX;
+ UINT dpiY;
+ return GetDpiForMonitor_fn(monitor, MDT_EFFECTIVE_DPI_, &dpiX, &dpiY) == S_OK ? dpiX : DPI_DEFAULT;
+ } else {
+ // We're on Windows earlier than 8.1, use DC
+
+ const HDC hdc = GetDC(hwnd);
+ if (hdc == NULL) { return DPI_DEFAULT; }
+ return GetDeviceCaps(hdc, LOGPIXELSX);
+ }
+#elif defined __linux__
+ // TODO
+ return DPI_DEFAULT;
+#elif defined __APPLE__
+ // TODO
+ return DPI_DEFAULT;
+#endif
+}
+
CheckboxFileDialog::ExtraPanel::ExtraPanel(wxWindow *parent)
: wxPanel(parent, wxID_ANY)