Improvements of High DPI scaling on Windows.
This commit is contained in:
parent
045879f68a
commit
c9cd4818c7
@ -340,15 +340,19 @@ void GUI_App::init_fonts()
|
||||
#endif /*__WXMAC__*/
|
||||
}
|
||||
|
||||
void GUI_App::update_fonts()
|
||||
void GUI_App::update_fonts(const MainFrame *main_frame)
|
||||
{
|
||||
/* Only normal and bold fonts are used for an application rescale,
|
||||
* because of under MSW small and normal fonts are the same.
|
||||
* To avoid same rescaling twice, just fill this values
|
||||
* from rescaled MainFrame
|
||||
*/
|
||||
m_normal_font = mainframe->normal_font();
|
||||
m_bold_font = mainframe->normal_font().Bold();
|
||||
if (main_frame == nullptr)
|
||||
main_frame = this->mainframe;
|
||||
m_normal_font = main_frame->normal_font();
|
||||
m_small_font = m_normal_font;
|
||||
m_bold_font = main_frame->normal_font().Bold();
|
||||
m_em_unit = main_frame->em_unit();
|
||||
}
|
||||
|
||||
void GUI_App::set_label_clr_modified(const wxColour& clr) {
|
||||
@ -773,14 +777,14 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
|
||||
// to notify the user whether he is aware that some preset changes will be lost.
|
||||
bool GUI_App::check_unsaved_changes()
|
||||
{
|
||||
std::string dirty;
|
||||
wxString dirty;
|
||||
PrinterTechnology printer_technology = preset_bundle->printers.get_edited_preset().printer_technology();
|
||||
for (Tab *tab : tabs_list)
|
||||
if (tab->supports_printer_technology(printer_technology) && tab->current_preset_is_dirty())
|
||||
if (dirty.empty())
|
||||
dirty = tab->name();
|
||||
dirty = _(tab->name());
|
||||
else
|
||||
dirty += std::string(", ") + tab->name();
|
||||
dirty += wxString(", ") + _(tab->name());
|
||||
if (dirty.empty())
|
||||
// No changes, the application may close or reload presets.
|
||||
return true;
|
||||
|
@ -100,7 +100,7 @@ public:
|
||||
void init_label_colours();
|
||||
void update_label_colours_from_appconfig();
|
||||
void init_fonts();
|
||||
void update_fonts();
|
||||
void update_fonts(const MainFrame *main_frame = nullptr);
|
||||
void set_label_clr_modified(const wxColour& clr);
|
||||
void set_label_clr_sys(const wxColour& clr);
|
||||
|
||||
|
@ -64,6 +64,7 @@ template<class F> typename F::FN winapi_get_function(const wchar_t *dll, const c
|
||||
}
|
||||
#endif
|
||||
|
||||
// If called with nullptr, a DPI for the primary monitor is returned.
|
||||
int get_dpi_for_window(wxWindow *window)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@ -82,7 +83,8 @@ int get_dpi_for_window(wxWindow *window)
|
||||
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();
|
||||
// Desktop Window is the window of the primary monitor.
|
||||
const HWND hwnd = (window == nullptr) ? ::GetDesktopWindow() : window->GetHandle();
|
||||
|
||||
if (GetDpiForWindow_fn != nullptr) {
|
||||
// We're on Windows 10, we have per-screen DPI settings
|
||||
|
@ -59,13 +59,16 @@ public:
|
||||
: P(parent, id, title, pos, size, style, name)
|
||||
{
|
||||
m_scale_factor = (float)get_dpi_for_window(this) / (float)DPI_DEFAULT;
|
||||
m_normal_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
m_prev_scale_factor = m_scale_factor;
|
||||
float scale_primary_display = (float)get_dpi_for_window(nullptr) / (float)DPI_DEFAULT;
|
||||
m_normal_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
if (std::abs(m_scale_factor - scale_primary_display) > 1e-6)
|
||||
m_normal_font = m_normal_font.Scale(m_scale_factor / scale_primary_display);
|
||||
|
||||
// An analog of em_unit value from GUI_App.
|
||||
m_em_unit = std::max<size_t>(10, 10 * m_scale_factor);
|
||||
|
||||
m_prev_scale_factor = m_scale_factor;
|
||||
|
||||
recalc_font();
|
||||
// recalc_font();
|
||||
|
||||
this->Bind(EVT_DPI_CHANGED, [this](const DpiChangedEvent &evt) {
|
||||
m_scale_factor = (float)evt.dpi / (float)DPI_DEFAULT;
|
||||
@ -107,7 +110,7 @@ public:
|
||||
float prev_scale_factor() const { return m_prev_scale_factor; }
|
||||
|
||||
int em_unit() const { return m_em_unit; }
|
||||
int font_size() const { return m_font_size; }
|
||||
// int font_size() const { return m_font_size; }
|
||||
const wxFont& normal_font() const { return m_normal_font; }
|
||||
|
||||
protected:
|
||||
@ -116,19 +119,19 @@ protected:
|
||||
private:
|
||||
float m_scale_factor;
|
||||
int m_em_unit;
|
||||
int m_font_size;
|
||||
// int m_font_size;
|
||||
|
||||
wxFont m_normal_font;
|
||||
float m_prev_scale_factor;
|
||||
bool m_can_rescale{ true };
|
||||
|
||||
void recalc_font()
|
||||
{
|
||||
wxClientDC dc(this);
|
||||
const auto metrics = dc.GetFontMetrics();
|
||||
m_font_size = metrics.height;
|
||||
// void recalc_font()
|
||||
// {
|
||||
// wxClientDC dc(this);
|
||||
// const auto metrics = dc.GetFontMetrics();
|
||||
// m_font_size = metrics.height;
|
||||
// m_em_unit = metrics.averageWidth;
|
||||
}
|
||||
// }
|
||||
|
||||
// check if new scale is differ from previous
|
||||
bool is_new_scale_factor() const { return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; }
|
||||
|
@ -36,6 +36,12 @@ MainFrame::MainFrame() :
|
||||
DPIFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, "mainframe"),
|
||||
m_printhost_queue_dlg(new PrintHostQueueDialog(this))
|
||||
{
|
||||
// Fonts were created by the DPIFrame constructor for the monitor, on which the window opened.
|
||||
wxGetApp().update_fonts(this);
|
||||
this->SetFont(this->normal_font());
|
||||
// initialize default width_unit according to the width of the one symbol ("m") of the currently active font of this window.
|
||||
wxGetApp().set_em_unit(std::max<size_t>(10, GetTextExtent("m").x - 1));
|
||||
|
||||
// Load the icon either from the exe, or from the ico file.
|
||||
#if _WIN32
|
||||
{
|
||||
@ -54,11 +60,6 @@ DPIFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAU
|
||||
SLIC3R_VERSION +
|
||||
_(L(" - Remember to check for updates at http://github.com/prusa3d/slic3r/releases")));
|
||||
|
||||
|
||||
// initialize default width_unit according to the width of the one symbol ("x") of the current system font
|
||||
const wxSize size = GetTextExtent("m");
|
||||
wxGetApp().set_em_unit(std::max<size_t>(10, size.x - 1));
|
||||
|
||||
/* Load default preset bitmaps before a tabpanel initialization,
|
||||
* but after filling of an em_unit value
|
||||
*/
|
||||
@ -141,6 +142,7 @@ void MainFrame::init_tabpanel()
|
||||
// wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
|
||||
// with multiple high resolution displays connected.
|
||||
m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
|
||||
m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||
|
||||
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
|
||||
auto panel = m_tabpanel->GetCurrentPage();
|
||||
@ -278,10 +280,9 @@ bool MainFrame::can_delete_all() const
|
||||
void MainFrame::on_dpi_changed(const wxRect &suggested_rect)
|
||||
{
|
||||
wxGetApp().update_fonts();
|
||||
|
||||
// _strange_ workaround for correct em_unit calculation
|
||||
const int new_em_unit = scale_factor() * 10;
|
||||
wxGetApp().set_em_unit(std::max<size_t>(10, new_em_unit));
|
||||
this->SetFont(this->normal_font());
|
||||
// initialize default width_unit according to the width of the one symbol ("m") of the currently active font of this window.
|
||||
wxGetApp().set_em_unit(std::max<size_t>(10, GetTextExtent("m").x - 1));
|
||||
|
||||
/* Load default preset bitmaps before a tabpanel initialization,
|
||||
* but after filling of an em_unit value
|
||||
|
@ -1377,6 +1377,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
||||
, view_toolbar(GLToolbar::Radio)
|
||||
#endif // ENABLE_SVG_ICONS
|
||||
{
|
||||
this->q->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||
|
||||
arranging = false;
|
||||
rotoptimizing = false;
|
||||
background_process.set_fff_print(&fff_print);
|
||||
|
@ -32,6 +32,7 @@ ProgressStatusBar::ProgressStatusBar(wxWindow *parent, int id):
|
||||
m_prog->Hide();
|
||||
m_cancelbutton->Hide();
|
||||
|
||||
self->SetFont(GUI::wxGetApp().normal_font());
|
||||
self->SetFieldsCount(3);
|
||||
int w[] = {-1, 150, 155};
|
||||
self->SetStatusWidths(3, w);
|
||||
|
@ -42,6 +42,7 @@ Tab::Tab(wxNotebook* parent, const wxString& title, const char* name) :
|
||||
m_parent(parent), m_title(title), m_name(name)
|
||||
{
|
||||
Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL, name);
|
||||
this->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||
set_type();
|
||||
|
||||
m_compatible_printers.type = Preset::TYPE_PRINTER;
|
||||
|
@ -299,9 +299,13 @@ int em_unit(wxWindow* win)
|
||||
{
|
||||
if (win)
|
||||
{
|
||||
Slic3r::GUI::DPIDialog* dlg = dynamic_cast<Slic3r::GUI::DPIDialog*>(Slic3r::GUI::find_toplevel_parent(win));
|
||||
wxTopLevelWindow *toplevel = Slic3r::GUI::find_toplevel_parent(win);
|
||||
Slic3r::GUI::DPIDialog* dlg = dynamic_cast<Slic3r::GUI::DPIDialog*>(toplevel);
|
||||
if (dlg)
|
||||
return dlg->em_unit();
|
||||
Slic3r::GUI::DPIFrame* frame = dynamic_cast<Slic3r::GUI::DPIFrame*>(toplevel);
|
||||
if (frame)
|
||||
return frame->em_unit();
|
||||
}
|
||||
|
||||
return Slic3r::GUI::wxGetApp().em_unit();
|
||||
|
Loading…
Reference in New Issue
Block a user