Improve HiDPI handling of appearance/layer controls

This commit is contained in:
Jon Evans 2023-02-22 00:15:14 -05:00
parent 89ef6b36f4
commit 43d3a18b86
11 changed files with 124 additions and 27 deletions

View File

@ -45,6 +45,7 @@
#include <eda_base_frame.h> #include <eda_base_frame.h>
#include <eda_draw_frame.h> #include <eda_draw_frame.h>
#include <paths.h> #include <paths.h>
#include <kiplatform/ui.h>
static std::unique_ptr<BITMAP_STORE> s_BitmapStore; static std::unique_ptr<BITMAP_STORE> s_BitmapStore;

View File

@ -57,11 +57,6 @@ static std::optional<double> getKiCadConfiguredScale( const COMMON_SETTINGS& aCo
scale = canvas_scale; scale = canvas_scale;
} }
if( scale )
{
wxLogTrace( traceHiDpi, wxS( "Scale factor (configured): %f" ), *scale );
}
return scale; return scale;
} }
@ -83,11 +78,6 @@ static std::optional<double> getEnvironmentScale()
scale = ENV_VAR::GetEnvVar<double>( wxS( "GDK_SCALE" ) ); scale = ENV_VAR::GetEnvVar<double>( wxS( "GDK_SCALE" ) );
} }
if( scale )
{
wxLogTrace( traceHiDpi, wxS( "Scale factor (environment): %f" ), *scale );
}
return scale; return scale;
} }
@ -101,15 +91,18 @@ DPI_SCALING::DPI_SCALING( COMMON_SETTINGS* aConfig, const wxWindow* aWindow )
double DPI_SCALING::GetScaleFactor() const double DPI_SCALING::GetScaleFactor() const
{ {
std::optional<double> val; std::optional<double> val;
wxString src;
if( m_config ) if( m_config )
{ {
val = getKiCadConfiguredScale( *m_config ); val = getKiCadConfiguredScale( *m_config );
src = wxS( "config" );
} }
if( !val ) if( !val )
{ {
val = getEnvironmentScale(); val = getEnvironmentScale();
src = wxS( "env" );
} }
if( !val && m_window ) if( !val && m_window )
@ -117,17 +110,58 @@ double DPI_SCALING::GetScaleFactor() const
// Use the native WX reporting. // Use the native WX reporting.
// On Linux, this will not work until WX 3.2 and GTK >= 3.10 // On Linux, this will not work until WX 3.2 and GTK >= 3.10
// Otherwise it returns 1.0 // Otherwise it returns 1.0
val = KIPLATFORM::UI::GetSystemScaleFactor( m_window ); val = KIPLATFORM::UI::GetPixelScaleFactor( m_window );
wxLogTrace( traceHiDpi, wxS( "Scale factor (WX): %f" ), *val ); src = wxS( "platform" );
} }
if( !val ) if( !val )
{ {
// Nothing else we can do, give it a default value // Nothing else we can do, give it a default value
val = GetDefaultScaleFactor(); val = GetDefaultScaleFactor();
wxLogTrace( traceHiDpi, wxS( "Scale factor (default): %f" ), *val ); src = wxS( "default" );
} }
wxLogTrace( traceHiDpi, wxS( "Scale factor (%s): %f" ), src, *val );
return *val;
}
double DPI_SCALING::GetContentScaleFactor() const
{
std::optional<double> val;
wxString src;
if( m_config )
{
val = getKiCadConfiguredScale( *m_config );
src = wxS( "config" );
}
if( !val )
{
val = getEnvironmentScale();
src = wxS( "env" );
}
if( !val && m_window )
{
// Use the native WX reporting.
// On Linux, this will not work until WX 3.2 and GTK >= 3.10
// Otherwise it returns 1.0
val = KIPLATFORM::UI::GetContentScaleFactor( m_window );
src = wxS( "platform" );
}
if( !val )
{
// Nothing else we can do, give it a default value
val = GetDefaultScaleFactor();
src = wxS( "default" );
}
wxLogTrace( traceHiDpi, wxS( "Content scale factor (%s): %f" ), src, *val );
return *val; return *val;
} }

View File

@ -24,6 +24,7 @@
#include <widgets/color_swatch.h> #include <widgets/color_swatch.h>
#include <wx/dcmemory.h> #include <wx/dcmemory.h>
#include <gal/dpi_scaling.h>
#include <dialogs/dialog_color_picker.h> #include <dialogs/dialog_color_picker.h>
#include <memory> #include <memory>
@ -133,6 +134,16 @@ COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, const COLOR4D& aColor, int aID,
m_checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU ); m_checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU );
m_checkerboardBg = aParent->GetBackgroundColour(); m_checkerboardBg = aParent->GetBackgroundColour();
#ifdef __WXMSW__
// These need additional scaling on Windows because of some discrepancy between pixel and
// content scaling that only affects certain widgets on Windows HiDPI. On other platforms, the
// value returned by ConvertDialogToPixels appears to be correct.
DPI_SCALING dpi( nullptr, aParent );
m_size /= dpi.GetContentScaleFactor();
m_checkerboardSize /= dpi.GetContentScaleFactor();
#endif
auto sizer = new wxBoxSizer( wxHORIZONTAL ); auto sizer = new wxBoxSizer( wxHORIZONTAL );
SetSizer( sizer ); SetSizer( sizer );
@ -300,4 +311,4 @@ void COLOR_SWATCH::OnDarkModeToggle()
m_checkerboardBg = m_parent->GetBackgroundColour(); m_checkerboardBg = m_parent->GetBackgroundColour();
wxBitmap bm = MakeBitmap( m_color, m_background, m_size, m_checkerboardSize, m_checkerboardBg ); wxBitmap bm = MakeBitmap( m_color, m_background, m_size, m_checkerboardSize, m_checkerboardBg );
m_swatch->SetBitmap( bm ); m_swatch->SetBitmap( bm );
} }

View File

@ -26,14 +26,24 @@
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <gerber_file_image_list.h> #include <gerber_file_image_list.h>
#ifdef __WXMSW__
#include <gal/dpi_scaling.h>
#endif
#include "gbr_layer_box_selector.h" #include "gbr_layer_box_selector.h"
void GBR_LAYER_BOX_SELECTOR::Resync() void GBR_LAYER_BOX_SELECTOR::Resync()
{ {
#define BM_SIZE 14
Freeze(); Freeze();
Clear(); Clear();
#ifdef __WXMSW__
DPI_SCALING dpi( nullptr, this );
int size = static_cast<int>( 14 / dpi.GetContentScaleFactor() );
#else
const int size = 14;
#endif7
GERBER_FILE_IMAGE_LIST& images = GERBER_FILE_IMAGE_LIST::GetImagesList(); GERBER_FILE_IMAGE_LIST& images = GERBER_FILE_IMAGE_LIST::GetImagesList();
for( unsigned layerid = 0; layerid < images.ImagesMaxCount(); ++layerid ) for( unsigned layerid = 0; layerid < images.ImagesMaxCount(); ++layerid )
@ -46,7 +56,7 @@ void GBR_LAYER_BOX_SELECTOR::Resync()
continue; continue;
// Prepare Bitmap // Prepare Bitmap
wxBitmap bmp( BM_SIZE, BM_SIZE ); wxBitmap bmp( size, size );
DrawColorSwatch( bmp, getLayerColor( LAYER_PCB_BACKGROUND ), getLayerColor( layerid ) ); DrawColorSwatch( bmp, getLayerColor( LAYER_PCB_BACKGROUND ), getLayerColor( layerid ) );
Append( getLayerName( layerid ), bmp, (void*)(intptr_t) layerid ); Append( getLayerName( layerid ), bmp, (void*)(intptr_t) layerid );
@ -65,7 +75,7 @@ void GBR_LAYER_BOX_SELECTOR::Resync()
SetMinSize( wxSize( -1, -1 ) ); SetMinSize( wxSize( -1, -1 ) );
wxSize bestSize = GetBestSize(); wxSize bestSize = GetBestSize();
bestSize.x = GetBestSize().x + BM_SIZE + 10; bestSize.x = GetBestSize().x + size + 10;
SetMinSize( bestSize ); SetMinSize( bestSize );
SetSelection( wxNOT_FOUND ); SetSelection( wxNOT_FOUND );

View File

@ -55,6 +55,14 @@ public:
*/ */
double GetScaleFactor() const; double GetScaleFactor() const;
/**
* Get the content scale factor, which may be different from the scale
* factor on some platforms. This value should be used for scaling
* user interface elements (fonts, icons, etc) whereas the scale
* factor should be used for scaling canvases.
*/
double GetContentScaleFactor() const;
/** /**
* Is the current value auto scaled, or is it user-set in the config * Is the current value auto scaled, or is it user-set in the config
*/ */

View File

@ -110,7 +110,7 @@ void KIPLATFORM::UI::EllipsizeChoiceBox( wxChoice* aChoice )
} }
double KIPLATFORM::UI::GetSystemScaleFactor( const wxWindow* aWindow ) double KIPLATFORM::UI::GetPixelScaleFactor( const wxWindow* aWindow )
{ {
double val = 1.0; double val = 1.0;
@ -123,6 +123,13 @@ double KIPLATFORM::UI::GetSystemScaleFactor( const wxWindow* aWindow )
} }
double KIPLATFORM::UI::GetContentScaleFactor( const wxWindow* aWindow )
{
// TODO: Do we need something different here?
return GetPixelScaleFactor( aWindow );
}
wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow ) wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow )
{ {
return wxSize( aWindow->GetSize().GetX() - wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ), return wxSize( aWindow->GetSize().GetX() - wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ),

View File

@ -95,12 +95,19 @@ namespace KIPLATFORM
void EllipsizeChoiceBox( wxChoice* aChoice ); void EllipsizeChoiceBox( wxChoice* aChoice );
/** /**
* Tries to determine the system scaling factor currently in use for the window. Under wx3.0, GTK * Tries to determine the pixel scaling factor currently in use for the window. Under wx3.0, GTK
* fails to properly detect the scale factor. * fails to properly detect the scale factor.
* @param aWindow pointer to the window to check * @param aWindow pointer to the window to check
* @return System scale factor in use, defaulting to the wxWidgets method * @return Pixel scale factor in use, defaulting to the wxWidgets method
*/ */
double GetSystemScaleFactor( const wxWindow* aWindow ); double GetPixelScaleFactor( const wxWindow* aWindow );
/**
* Tries to determine the content scaling factor currently in use for the window.
* The content scaling factor is typically settable by the user and may differ from the
* pixel scaling factor.
*/
double GetContentScaleFactor( const wxWindow* aWindow );
/** /**
* Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl, wxGrid) * Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl, wxGrid)

View File

@ -116,12 +116,18 @@ void KIPLATFORM::UI::EllipsizeChoiceBox( wxChoice* aChoice )
} }
double KIPLATFORM::UI::GetSystemScaleFactor( const wxWindow* aWindow ) double KIPLATFORM::UI::GetPixelScaleFactor( const wxWindow* aWindow )
{ {
return aWindow->GetContentScaleFactor(); return aWindow->GetContentScaleFactor();
} }
double KIPLATFORM::UI::GetContentScaleFactor( const wxWindow* aWindow )
{
return aWindow->GetDPIScaleFactor();
}
wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow ) wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow )
{ {
return aWindow->GetClientSize(); return aWindow->GetClientSize();

View File

@ -115,12 +115,19 @@ void KIPLATFORM::UI::EllipsizeChoiceBox( wxChoice* aChoice )
} }
double KIPLATFORM::UI::GetSystemScaleFactor( const wxWindow* aWindow ) double KIPLATFORM::UI::GetPixelScaleFactor( const wxWindow* aWindow )
{ {
return aWindow->GetContentScaleFactor(); return aWindow->GetContentScaleFactor();
} }
double KIPLATFORM::UI::GetContentScaleFactor( const wxWindow* aWindow )
{
// TODO: Check if this should be different on macOS
return GetPixelScaleFactor( aWindow );
}
wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow ) wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow )
{ {
return wxSize( aWindow->GetSize().GetX() - wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ), return wxSize( aWindow->GetSize().GetX() - wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ),

View File

@ -84,8 +84,12 @@ void PCB_LAYER_BOX_SELECTOR::Resync()
Freeze(); Freeze();
Clear(); Clear();
#ifdef __WXMSW__
DPI_SCALING dpi( nullptr, this ); DPI_SCALING dpi( nullptr, this );
int size = static_cast<int>( 14 / dpi.GetScaleFactor() ); int size = static_cast<int>( 14 / dpi.GetContentScaleFactor() );
#else
const int size = 14;
#endif
LSET show = LSET::AllLayersMask() & ~m_layerMaskDisable; LSET show = LSET::AllLayersMask() & ~m_layerMaskDisable;
LSET activated = getEnabledLayers() & ~m_layerMaskDisable; LSET activated = getEnabledLayers() & ~m_layerMaskDisable;

View File

@ -406,7 +406,9 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
m_lastSelectedUserPreset( nullptr ), m_lastSelectedUserPreset( nullptr ),
m_layerContextMenu( nullptr ) m_layerContextMenu( nullptr )
{ {
int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x; DPI_SCALING dpi( nullptr, m_frame );
int indicatorSize = ConvertDialogToPixels( wxSize( 6, 6 ) ).x / dpi.GetContentScaleFactor();
int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y ); int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
m_iconProvider = new ROW_ICON_PROVIDER( indicatorSize ); m_iconProvider = new ROW_ICON_PROVIDER( indicatorSize );
m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize(); m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
@ -802,8 +804,8 @@ void APPEARANCE_CONTROLS::createControls()
wxSize APPEARANCE_CONTROLS::GetBestSize() const wxSize APPEARANCE_CONTROLS::GetBestSize() const
{ {
wxSize size( 220, 480 ); DPI_SCALING dpi( nullptr, m_frame );
// TODO(JE) appropriate logic wxSize size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
return size; return size;
} }