From b64a30f44b92f3bd515b8f3ee775f998333de611 Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Sun, 26 May 2024 13:02:37 +0300 Subject: [PATCH] Fix color swatches and color picker dialog on GTK with window scaling. --- common/dialogs/dialog_color_picker.cpp | 86 +++++++++++--------------- common/widgets/color_swatch.cpp | 52 +++++----------- include/widgets/color_swatch.h | 4 +- 3 files changed, 57 insertions(+), 85 deletions(-) diff --git a/common/dialogs/dialog_color_picker.cpp b/common/dialogs/dialog_color_picker.cpp index 2228ea5f4f..76aa024c83 100644 --- a/common/dialogs/dialog_color_picker.cpp +++ b/common/dialogs/dialog_color_picker.cpp @@ -129,13 +129,9 @@ void DIALOG_COLOR_PICKER::updatePreview( wxStaticBitmap* aStaticBitmap, COLOR4D& wxSize swatchSize = aStaticBitmap->GetSize(); wxSize checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU ); -#ifdef __WXMAC__ - // Adjust for Retina - swatchSize *= KIPLATFORM::UI::GetPixelScaleFactor( this ); - checkerboardSize *= KIPLATFORM::UI::GetPixelScaleFactor( this ); -#endif - - wxBitmap newBm = COLOR_SWATCH::MakeBitmap( aColor4D, COLOR4D::WHITE, swatchSize, checkerboardSize, + wxBitmap newBm = COLOR_SWATCH::MakeBitmap( aColor4D, COLOR4D::WHITE, + ToPhys( swatchSize ), + ToPhys( checkerboardSize ), aStaticBitmap->GetParent()->GetBackgroundColour() ); newBm.SetScaleFactor( GetDPIScaleFactor() ); @@ -185,17 +181,13 @@ void DIALOG_COLOR_PICKER::initDefinedColors( CUSTOM_COLORS_LIST* aPredefinedColo wxSize checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU ); COLOR4D checkboardBackground = m_OldColorRect->GetParent()->GetBackgroundColour(); -#ifdef __WXMAC__ - // Adjust for Retina - swatchSize *= KIPLATFORM::UI::GetPixelScaleFactor( this ); - checkerboardSize *= KIPLATFORM::UI::GetPixelScaleFactor( this ); -#endif - auto addSwatch = [&]( int aId, COLOR4D aColor, const wxString& aColorName ) { - wxBitmap bm = COLOR_SWATCH::MakeBitmap( aColor, COLOR4D::WHITE, swatchSize, - checkerboardSize, checkboardBackground ); + wxBitmap bm = COLOR_SWATCH::MakeBitmap( aColor, COLOR4D::WHITE, + ToPhys( swatchSize ), + ToPhys( checkerboardSize ), + checkboardBackground ); bm.SetScaleFactor( GetDPIScaleFactor() ); wxStaticBitmap* swatch = new wxStaticBitmap( m_panelDefinedColors, aId, bm ); @@ -254,7 +246,7 @@ void DIALOG_COLOR_PICKER::initDefinedColors( CUSTOM_COLORS_LIST* aPredefinedColo void DIALOG_COLOR_PICKER::createRGBBitmap() { - wxSize bmsize = m_RgbBitmap->GetSize(); + wxSize bmsize = ToPhys( m_RgbBitmap->GetSize() ); int half_size = std::min( bmsize.x, bmsize.y )/2; // We use here a Y axis from bottom to top and origin to center, So we need to map @@ -342,21 +334,14 @@ void DIALOG_COLOR_PICKER::createRGBBitmap() delete m_bitmapRGB; m_bitmapRGB = new wxBitmap( img, 24 ); - double scaleFactor = m_HsvBitmap->GetDPIScaleFactor(); - -#ifdef __WXMAC__ - // Adjust for Retina - scaleFactor /= KIPLATFORM::UI::GetPixelScaleFactor( this ); -#endif - - m_bitmapRGB->SetScaleFactor( scaleFactor ); + m_bitmapRGB->SetScaleFactor( GetDPIScaleFactor() ); m_RgbBitmap->SetBitmap( *m_bitmapRGB ); } void DIALOG_COLOR_PICKER::createHSVBitmap() { - wxSize bmsize = m_HsvBitmap->GetSize(); + wxSize bmsize = ToPhys( m_HsvBitmap->GetSize() ); int half_size = std::min( bmsize.x, bmsize.y )/2; // We use here a Y axis from bottom to top and origin to center, So we need to map @@ -415,27 +400,23 @@ void DIALOG_COLOR_PICKER::createHSVBitmap() delete m_bitmapHSV; m_bitmapHSV = new wxBitmap( img, 24 ); - double scaleFactor = m_HsvBitmap->GetDPIScaleFactor(); - -#ifdef __WXMAC__ - // Adjust for Retina - scaleFactor /= KIPLATFORM::UI::GetPixelScaleFactor( this ); -#endif - - m_bitmapHSV->SetScaleFactor( scaleFactor ); + m_bitmapHSV->SetScaleFactor( GetDPIScaleFactor() ); m_HsvBitmap->SetBitmap( *m_bitmapHSV ); } void DIALOG_COLOR_PICKER::drawRGBPalette() { - if( !m_bitmapRGB || m_bitmapRGB->GetSize() != m_RgbBitmap->GetSize() ) + if( !m_bitmapRGB || m_bitmapRGB->GetSize() != ToPhys( m_RgbBitmap->GetSize() ) ) createRGBBitmap(); wxMemoryDC bitmapDC; - wxSize bmsize = m_bitmapRGB->GetSize(); - int half_size = std::min( bmsize.x, bmsize.y )/2; + wxSize bmsize = m_bitmapRGB->GetSize(); + int half_size = std::min( bmsize.x, bmsize.y ) / 2; + wxBitmap newBm( *m_bitmapRGB ); + newBm.SetScaleFactor( 1.0 ); + bitmapDC.SelectObject( newBm ); // Use Y axis from bottom to top and origin to center @@ -488,6 +469,7 @@ void DIALOG_COLOR_PICKER::drawRGBPalette() bitmapDC.DrawLine( 0, 0, half_size, - half_size*slope ); // Blue axis (X 3D axis) bitmapDC.DrawLine( 0, 0, -half_size, - half_size*slope ); // green axis (Y 3D axis) + newBm.SetScaleFactor( GetDPIScaleFactor() ); m_RgbBitmap->SetBitmap( newBm ); /* Deselect the Tool Bitmap from DC, @@ -498,13 +480,16 @@ void DIALOG_COLOR_PICKER::drawRGBPalette() void DIALOG_COLOR_PICKER::drawHSVPalette() { - if( !m_bitmapHSV || m_bitmapHSV->GetSize() != m_HsvBitmap->GetSize() ) + if( !m_bitmapHSV || m_bitmapHSV->GetSize() != ToPhys( m_HsvBitmap->GetSize() ) ) createHSVBitmap(); wxMemoryDC bitmapDC; - wxSize bmsize = m_bitmapHSV->GetSize(); - int half_size = std::min( bmsize.x, bmsize.y ) / 2; + wxSize bmsize = m_bitmapHSV->GetSize(); + int half_size = std::min( bmsize.x, bmsize.y ) / 2; + wxBitmap newBm( *m_bitmapHSV ); + newBm.SetScaleFactor( 1.0 ); + bitmapDC.SelectObject( newBm ); // Use Y axis from bottom to top and origin to center @@ -532,6 +517,7 @@ void DIALOG_COLOR_PICKER::drawHSVPalette() m_cursorBitmapHSV.y - ( m_cursorsSize / 2 ), m_cursorsSize, m_cursorsSize ); + newBm.SetScaleFactor( GetDPIScaleFactor() ); m_HsvBitmap->SetBitmap( newBm ); /* Deselect the Tool Bitmap from DC, @@ -583,7 +569,7 @@ void DIALOG_COLOR_PICKER::SetEditVals( CHANGED_COLOR aChanged, bool aCheckTransp void DIALOG_COLOR_PICKER::updateHandleSize() { - m_cursorsSize = FromDIP( 8 ); // Size of square cursors drawn on color bitmaps + m_cursorsSize = ToPhys( FromDIP( 8 ) ); // Size of square cursors drawn on color bitmaps } @@ -632,11 +618,12 @@ void DIALOG_COLOR_PICKER::buttColorClick( wxMouseEvent& event ) void DIALOG_COLOR_PICKER::onRGBMouseClick( wxMouseEvent& event ) { m_allowMouseEvents = true; - wxPoint mousePos = event.GetPosition(); // The cursor position is relative to the m_bitmapHSV wxBitmap center - wxSize bmsize = m_bitmapRGB->GetSize(); - int half_size = std::min( bmsize.x, bmsize.y ) / 2; + wxPoint mousePos = ToPhys( event.GetPosition() ); + wxSize bmsize = m_bitmapRGB->GetSize(); + int half_size = std::min( bmsize.x, bmsize.y ) / 2; + mousePos.x -= half_size; mousePos.y -= half_size; mousePos.y = -mousePos.y; // Use the bottom to top vertical axis @@ -686,9 +673,10 @@ void DIALOG_COLOR_PICKER::onRGBMouseDrag( wxMouseEvent& event ) // Adjust the HSV cursor position to follow the mouse cursor // The cursor position is relative to the m_bitmapHSV wxBitmap center - wxPoint mousePos = event.GetPosition(); - wxSize bmsize = m_bitmapRGB->GetSize(); - int half_size = std::min( bmsize.x, bmsize.y ) / 2; + wxPoint mousePos = ToPhys( event.GetPosition() ); + wxSize bmsize = m_bitmapRGB->GetSize(); + int half_size = std::min( bmsize.x, bmsize.y ) / 2; + mousePos.x -= half_size; mousePos.y -= half_size; mousePos.y = -mousePos.y; // Use the bottom to top vertical axis @@ -770,9 +758,9 @@ void DIALOG_COLOR_PICKER::OnColorValueText( wxCommandEvent& event ) bool DIALOG_COLOR_PICKER::setHSvaluesFromCursor( const wxPoint& aMouseCursor ) { - wxPoint mousePos = aMouseCursor; - wxSize bmsize = m_bitmapHSV->GetSize(); - int half_size = std::min( bmsize.x, bmsize.y )/2; + wxPoint mousePos = ToPhys( aMouseCursor ); + wxSize bmsize = m_bitmapHSV->GetSize(); + int half_size = std::min( bmsize.x, bmsize.y ) / 2; // Make the cursor position relative to the m_bitmapHSV wxBitmap center mousePos.x -= half_size; diff --git a/common/widgets/color_swatch.cpp b/common/widgets/color_swatch.cpp index 96656171e9..d14895c2b3 100644 --- a/common/widgets/color_swatch.cpp +++ b/common/widgets/color_swatch.cpp @@ -49,6 +49,17 @@ wxBitmap COLOR_SWATCH::MakeBitmap( const COLOR4D& aColor, const COLOR4D& aBackgr } +wxBitmap COLOR_SWATCH::makeBitmap() +{ + wxBitmap bitmap = COLOR_SWATCH::MakeBitmap( m_color, m_background, + ToPhys( m_size ), ToPhys( m_checkerboardSize ), + m_checkerboardBg ); + + bitmap.SetScaleFactor( GetDPIScaleFactor() ); + return bitmap; +} + + void COLOR_SWATCH::RenderToDC( wxDC* aDC, const KIGFX::COLOR4D& aColor, const KIGFX::COLOR4D& aBackground, const wxRect& aRect, const wxSize& aCheckerboardSize, @@ -147,20 +158,10 @@ COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, const COLOR4D& aColor, int aID, m_checkerboardSize = ConvertDialogToPixels( CHECKERBOARD_SIZE_DU ); m_checkerboardBg = aParent->GetBackgroundColour(); -#ifdef __WXMAC__ - // Adjust for Retina - m_size *= KIPLATFORM::UI::GetPixelScaleFactor( aParent ); - m_checkerboardSize *= KIPLATFORM::UI::GetPixelScaleFactor( aParent ); -#endif - auto sizer = new wxBoxSizer( wxHORIZONTAL ); SetSizer( sizer ); - wxBitmap bitmap = COLOR_SWATCH::MakeBitmap( aColor, aBackground, m_size, m_checkerboardSize, - m_checkerboardBg ); - - bitmap.SetScaleFactor( GetDPIScaleFactor() ); - m_swatch = new wxStaticBitmap( this, aID, bitmap ); + m_swatch = new wxStaticBitmap( this, aID, makeBitmap() ); sizer->Add( m_swatch, 0, 0 ); @@ -187,10 +188,6 @@ COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, wxWindowID aID, const wxPoint& aP // Adjust for border m_size.x -= 2; m_size.y -= 2; - - // Adjust for Retina - m_size *= KIPLATFORM::UI::GetPixelScaleFactor( aParent ); - m_checkerboardSize *= KIPLATFORM::UI::GetPixelScaleFactor( aParent ); #endif SetSize( m_size ); @@ -198,11 +195,7 @@ COLOR_SWATCH::COLOR_SWATCH( wxWindow* aParent, wxWindowID aID, const wxPoint& aP auto sizer = new wxBoxSizer( wxHORIZONTAL ); SetSizer( sizer ); - wxBitmap bitmap = COLOR_SWATCH::MakeBitmap( COLOR4D::UNSPECIFIED, COLOR4D::UNSPECIFIED, - m_size, m_checkerboardSize, m_checkerboardBg ); - - bitmap.SetScaleFactor( GetDPIScaleFactor() ); - m_swatch = new wxStaticBitmap( this, aID, bitmap ); + m_swatch = new wxStaticBitmap( this, aID, makeBitmap() ); sizer->Add( m_swatch, 0, 0 ); @@ -276,10 +269,7 @@ void COLOR_SWATCH::SetSwatchColor( const COLOR4D& aColor, bool aSendEvent ) { m_color = aColor; - wxBitmap bm = MakeBitmap( m_color, m_background, m_size, m_checkerboardSize, m_checkerboardBg ); - - bm.SetScaleFactor( GetDPIScaleFactor() ); - m_swatch->SetBitmap( bm ); + m_swatch->SetBitmap( makeBitmap() ); if( aSendEvent ) sendSwatchChangeEvent( *this ); @@ -295,10 +285,8 @@ void COLOR_SWATCH::SetDefaultColor( const COLOR4D& aColor ) void COLOR_SWATCH::SetSwatchBackground( const COLOR4D& aBackground ) { m_background = aBackground; - wxBitmap bm = MakeBitmap( m_color, m_background, m_size, m_checkerboardSize, m_checkerboardBg ); - bm.SetScaleFactor( GetDPIScaleFactor() ); - m_swatch->SetBitmap( bm ); + m_swatch->SetBitmap( makeBitmap() ); } @@ -329,11 +317,7 @@ void COLOR_SWATCH::GetNewSwatchColor() { m_color = newColor; - wxBitmap bm = MakeBitmap( newColor, m_background, m_size, m_checkerboardSize, - m_checkerboardBg ); - - bm.SetScaleFactor( GetDPIScaleFactor() ); - m_swatch->SetBitmap( bm ); + m_swatch->SetBitmap( makeBitmap() ); sendSwatchChangeEvent( *this ); } @@ -344,8 +328,6 @@ void COLOR_SWATCH::GetNewSwatchColor() void COLOR_SWATCH::OnDarkModeToggle() { m_checkerboardBg = m_parent->GetBackgroundColour(); - wxBitmap bm = MakeBitmap( m_color, m_background, m_size, m_checkerboardSize, m_checkerboardBg ); - bm.SetScaleFactor( GetDPIScaleFactor() ); - m_swatch->SetBitmap( bm ); + m_swatch->SetBitmap( makeBitmap() ); } diff --git a/include/widgets/color_swatch.h b/include/widgets/color_swatch.h index e15bb42c18..6d35015c1f 100644 --- a/include/widgets/color_swatch.h +++ b/include/widgets/color_swatch.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017-2024 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -139,6 +139,8 @@ public: private: void setupEvents( bool aTriggerWithSingleClick ); + wxBitmap makeBitmap(); + /** * Pass unwanted events on to listeners of this object */