Improve HiDPI handling of appearance/layer controls

(cherry picked from commit 43d3a18b86)
This commit is contained in:
Jon Evans 2023-02-22 00:15:14 -05:00
parent 64bc850d8f
commit ee0ba17c03
11 changed files with 124 additions and 27 deletions

View File

@ -45,6 +45,7 @@
#include <eda_base_frame.h>
#include <eda_draw_frame.h>
#include <paths.h>
#include <kiplatform/ui.h>
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;
}
if( scale )
{
wxLogTrace( traceHiDpi, wxS( "Scale factor (configured): %f" ), *scale );
}
return scale;
}
@ -83,11 +78,6 @@ static std::optional<double> getEnvironmentScale()
scale = ENV_VAR::GetEnvVar<double>( wxS( "GDK_SCALE" ) );
}
if( scale )
{
wxLogTrace( traceHiDpi, wxS( "Scale factor (environment): %f" ), *scale );
}
return scale;
}
@ -101,15 +91,18 @@ DPI_SCALING::DPI_SCALING( COMMON_SETTINGS* aConfig, const wxWindow* aWindow )
double DPI_SCALING::GetScaleFactor() 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 )
@ -117,17 +110,58 @@ double DPI_SCALING::GetScaleFactor() const
// 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::GetSystemScaleFactor( m_window );
wxLogTrace( traceHiDpi, wxS( "Scale factor (WX): %f" ), *val );
val = KIPLATFORM::UI::GetPixelScaleFactor( m_window );
src = wxS( "platform" );
}
if( !val )
{
// Nothing else we can do, give it a default value
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;
}

View File

@ -24,6 +24,7 @@
#include <widgets/color_swatch.h>
#include <wx/dcmemory.h>
#include <gal/dpi_scaling.h>
#include <dialogs/dialog_color_picker.h>
#include <memory>
@ -133,6 +134,16 @@ COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, const COLOR4D& aColor, int aID,
m_checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU );
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 );
SetSizer( sizer );
@ -300,4 +311,4 @@ void COLOR_SWATCH::OnDarkModeToggle()
m_checkerboardBg = m_parent->GetBackgroundColour();
wxBitmap bm = MakeBitmap( m_color, m_background, m_size, m_checkerboardSize, m_checkerboardBg );
m_swatch->SetBitmap( bm );
}
}

View File

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

View File

@ -55,6 +55,14 @@ public:
*/
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
*/

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;
@ -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 )
{
return wxSize( aWindow->GetSize().GetX() - wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ),

View File

@ -95,12 +95,19 @@ namespace KIPLATFORM
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.
* @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)

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();
}
double KIPLATFORM::UI::GetContentScaleFactor( const wxWindow* aWindow )
{
return aWindow->GetDPIScaleFactor();
}
wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow )
{
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();
}
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 )
{
return wxSize( aWindow->GetSize().GetX() - wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ),

View File

@ -84,8 +84,12 @@ void PCB_LAYER_BOX_SELECTOR::Resync()
Freeze();
Clear();
#ifdef __WXMSW__
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 activated = getEnabledLayers() & ~m_layerMaskDisable;

View File

@ -406,7 +406,9 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
m_lastSelectedUserPreset( 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 );
m_iconProvider = new ROW_ICON_PROVIDER( indicatorSize );
m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
@ -802,8 +804,8 @@ void APPEARANCE_CONTROLS::createControls()
wxSize APPEARANCE_CONTROLS::GetBestSize() const
{
wxSize size( 220, 480 );
// TODO(JE) appropriate logic
DPI_SCALING dpi( nullptr, m_frame );
wxSize size( 220 * dpi.GetScaleFactor(), 480 * dpi.GetScaleFactor() );
return size;
}