diff --git a/common/dialogs/panel_common_settings.cpp b/common/dialogs/panel_common_settings.cpp
index 41bab0e854..1804cb662c 100644
--- a/common/dialogs/panel_common_settings.cpp
+++ b/common/dialogs/panel_common_settings.cpp
@@ -190,6 +190,8 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
commonSettings->m_Appearance.show_scrollbars = m_showScrollbars->GetValue();
+ commonSettings->m_Appearance.grid_striping = m_gridStriping->GetValue();
+
double dimmingPercent = 80;
m_highContrastCtrl->GetValue().ToDouble( &dimmingPercent );
commonSettings->m_Appearance.hicontrast_dimming_factor = dimmingPercent / 100.0f;
@@ -276,6 +278,8 @@ void PANEL_COMMON_SETTINGS::applySettingsToPanel( COMMON_SETTINGS& aSettings )
m_checkBoxIconsInMenus->SetValue( aSettings.m_Appearance.use_icons_in_menus );
m_scaleFonts->SetValue( aSettings.m_Appearance.apply_icon_scale_to_fonts );
+ m_gridStriping->SetValue( aSettings.m_Appearance.grid_striping );
+
double dimmingPercent = aSettings.m_Appearance.hicontrast_dimming_factor * 100.0f;
m_highContrastCtrl->SetValue( wxString::Format( "%.0f", dimmingPercent ) );
diff --git a/common/dialogs/panel_common_settings_base.cpp b/common/dialogs/panel_common_settings_base.cpp
index 1696e70491..16d0525dfd 100644
--- a/common/dialogs/panel_common_settings_base.cpp
+++ b/common/dialogs/panel_common_settings_base.cpp
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
+// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -159,6 +159,11 @@ PANEL_COMMON_SETTINGS_BASE::PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWind
bSizer14->Add( m_hotkeyFeedback, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+ m_gridStriping = new wxCheckBox( this, wxID_ANY, _("Use alternating row colors in tables"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_gridStriping->SetToolTip( _("When enabled, use a different color for every other table row") );
+
+ bSizer14->Add( m_gridStriping, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
+
bUserInterfaceSizer->Add( bSizer14, 0, wxEXPAND, 5 );
diff --git a/common/dialogs/panel_common_settings_base.fbp b/common/dialogs/panel_common_settings_base.fbp
index 0ac075ada3..81fd4c4764 100644
--- a/common/dialogs/panel_common_settings_base.fbp
+++ b/common/dialogs/panel_common_settings_base.fbp
@@ -1,4566 +1,4698 @@
-
+
-
-
diff --git a/common/dialogs/panel_common_settings_base.h b/common/dialogs/panel_common_settings_base.h
index 6a1aca6e9f..9d15947f81 100644
--- a/common/dialogs/panel_common_settings_base.h
+++ b/common/dialogs/panel_common_settings_base.h
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
+// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -63,6 +63,7 @@ class PANEL_COMMON_SETTINGS_BASE : public RESETTABLE_PANEL
wxCheckBox* m_showScrollbars;
wxCheckBox* m_focusFollowSchPcb;
wxCheckBox* m_hotkeyFeedback;
+ wxCheckBox* m_gridStriping;
wxStaticText* m_stIconTheme;
wxRadioButton* m_rbIconThemeLight;
wxRadioButton* m_rbIconThemeDark;
diff --git a/common/gal/color4d.cpp b/common/gal/color4d.cpp
index 186b76f205..19468084ee 100644
--- a/common/gal/color4d.cpp
+++ b/common/gal/color4d.cpp
@@ -601,3 +601,27 @@ int COLOR4D::Compare( const COLOR4D& aRhs ) const
return 0;
}
+
+
+double COLOR4D::RelativeLuminance() const
+{
+ // Formula from https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
+ double cr = ( r <= 0.04045 ) ? ( r / 12.92 ) : std::pow( ( r + 0.055 ) / 1.055, 2.4 );
+ double cg = ( g <= 0.04045 ) ? ( g / 12.92 ) : std::pow( ( g + 0.055 ) / 1.055, 2.4 );
+ double cb = ( b <= 0.04045 ) ? ( b / 12.92 ) : std::pow( ( b + 0.055 ) / 1.055, 2.4 );
+
+ return 0.2126 * cr + 0.7152 * cg + 0.0722 * cb;
+}
+
+
+double COLOR4D::ContrastRatio( const COLOR4D& aLeft, const COLOR4D& aRight )
+{
+ // Formula from https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
+ double aRL = aLeft.RelativeLuminance();
+ double bRL = aRight.RelativeLuminance();
+
+ if( aRL > bRL )
+ return ( aRL + 0.05 ) / ( bRL + 0.05 );
+ else
+ return ( bRL + 0.05 ) / ( aRL + 0.05 );
+}
\ No newline at end of file
diff --git a/common/settings/common_settings.cpp b/common/settings/common_settings.cpp
index 4fb2b856ff..c10d0578e4 100644
--- a/common/settings/common_settings.cpp
+++ b/common/settings/common_settings.cpp
@@ -99,6 +99,9 @@ COMMON_SETTINGS::COMMON_SETTINGS() :
m_params.emplace_back( new PARAM( "appearance.toolbar_icon_size",
&m_Appearance.toolbar_icon_size, 24, 16, 64 ) );
+ m_params.emplace_back( new PARAM( "appearance.grid_striping",
+ &m_Appearance.grid_striping, false ) );
+
m_params.emplace_back( new PARAM( "auto_backup.enabled", &m_Backup.enabled, true ) );
m_params.emplace_back( new PARAM( "auto_backup.backup_on_autosave",
diff --git a/common/widgets/wx_grid.cpp b/common/widgets/wx_grid.cpp
index 7c08eab147..fd249fbd61 100644
--- a/common/widgets/wx_grid.cpp
+++ b/common/widgets/wx_grid.cpp
@@ -21,6 +21,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include
#include
#include
#include
@@ -30,6 +31,10 @@
#include
#include
#include
+#include
+
+#include
+#include
#define MIN_GRIDCELL_MARGIN FromDIP( 3 )
@@ -94,6 +99,59 @@ public:
};
+/**
+ * Attribute provider that provides attributes (or modifies the existing attribute) to alternate a row color
+ * between the odd and even rows.
+ */
+class WX_GRID_ALT_ROW_COLOR_PROVIDER : public wxGridCellAttrProvider
+{
+public:
+ WX_GRID_ALT_ROW_COLOR_PROVIDER( const wxColor& aBaseColor ) : wxGridCellAttrProvider(),
+ m_attrOdd( new wxGridCellAttr() )
+ {
+ UpdateColors( aBaseColor );
+ }
+
+
+ void UpdateColors( const wxColor& aBaseColor )
+ {
+ // Choose the default color, taking into account if the dark mode theme is enabled
+ wxColor rowColor = aBaseColor.ChangeLightness( KIPLATFORM::UI::IsDarkTheme() ? 105 : 95 );
+
+ m_attrOdd->SetBackgroundColour( rowColor );
+ }
+
+
+ wxGridCellAttr* GetAttr( int row, int col,
+ wxGridCellAttr::wxAttrKind kind ) const override
+ {
+ wxGridCellAttrPtr cellAttr( wxGridCellAttrProvider::GetAttr( row, col, kind ) );
+
+ // Just pass through the cell attribute on even rows
+ if( row % 2 )
+ return cellAttr.release();
+
+ if( !cellAttr )
+ {
+ cellAttr = m_attrOdd;
+ }
+ else
+ {
+ if( !cellAttr->HasBackgroundColour() )
+ {
+ cellAttr = cellAttr->Clone();
+ cellAttr->SetBackgroundColour( m_attrOdd->GetBackgroundColour() );
+ }
+ }
+
+ return cellAttr.release();
+ }
+
+private:
+ wxGridCellAttrPtr m_attrOdd;
+};
+
+
WX_GRID::WX_GRID( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
long style, const wxString& name ) :
wxGrid( parent, id, pos, size, style, name ),
@@ -179,6 +237,8 @@ void WX_GRID::SetTable( wxGridTableBase* aTable, bool aTakeOwnership )
delete[] formBuilderColWidths;
+ EnableAlternateRowColors( Pgm().GetCommonSettings()->m_Appearance.grid_striping );
+
Connect( wxEVT_GRID_COL_MOVE, wxGridEventHandler( WX_GRID::onGridColMove ), nullptr, this );
Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( WX_GRID::onGridCellSelect ), nullptr, this );
@@ -186,6 +246,25 @@ void WX_GRID::SetTable( wxGridTableBase* aTable, bool aTakeOwnership )
}
+void WX_GRID::EnableAlternateRowColors( bool aEnable )
+{
+ wxGridTableBase* table = wxGrid::GetTable();
+
+ wxCHECK_MSG( table, /* void */,
+ "Tried to enable alternate row colors without a table assigned to the grid" );
+
+ if( aEnable )
+ {
+ wxColor color = wxGrid::GetDefaultCellBackgroundColour();
+ table->SetAttrProvider( new WX_GRID_ALT_ROW_COLOR_PROVIDER( color ) );
+ }
+ else
+ {
+ table->SetAttrProvider( nullptr );
+ }
+}
+
+
void WX_GRID::onGridCellSelect( wxGridEvent& aEvent )
{
// Highlight the selected cell.
diff --git a/include/gal/color4d.h b/include/gal/color4d.h
index 0ca7bd9411..ae7a1452b3 100644
--- a/include/gal/color4d.h
+++ b/include/gal/color4d.h
@@ -189,7 +189,7 @@ public:
* @param aOutLightness is conversion result for value component (0 ... 1.0).
* @note saturation is set to 0.0 for black color if r = g = b,
*/
- void ToHSL( double& aOutHue, double& aOutSaturation, double& aOutValue ) const;
+ void ToHSL( double& aOutHue, double& aOutSaturation, double& aOutLightness ) const;
/**
* Change currently used color to the one given by hue, saturation and lightness parameters.
@@ -367,6 +367,22 @@ public:
int Compare( const COLOR4D& aRhs ) const;
+ /**
+ * Compute the relative luminance of a color using the formula from WCAG21.
+ *
+ * @return relative luminance between 0 and 1 where 0 is darkest black and 1 is lightest white.
+ */
+ double RelativeLuminance() const;
+
+ /**
+ * Compute the contrast ration between two colors using the formula from WCAG21.
+ *
+ * @param aLeft is the first color to use in the ratio
+ * @param aRight is the second color to use in the ratio
+ * @return contrast ratio between 1.0:1 and 21.0:1 between the two colors.
+ */
+ static double ContrastRatio( const COLOR4D& aLeft, const COLOR4D& aRight );
+
/**
* Returns a legacy color ID that is closest to the given 8-bit RGB values.
*/
diff --git a/include/settings/common_settings.h b/include/settings/common_settings.h
index e4e765e7c6..1372c70348 100644
--- a/include/settings/common_settings.h
+++ b/include/settings/common_settings.h
@@ -57,6 +57,7 @@ public:
double hicontrast_dimming_factor;
int text_editor_zoom;
int toolbar_icon_size;
+ bool grid_striping;
};
struct AUTO_BACKUP
diff --git a/include/widgets/wx_grid.h b/include/widgets/wx_grid.h
index 9fe4709801..584f10e2b4 100644
--- a/include/widgets/wx_grid.h
+++ b/include/widgets/wx_grid.h
@@ -58,6 +58,14 @@ public:
*/
void SetLabelFont( const wxFont& aFont ); // Yes, we're hiding a non-virtual method
+ /**
+ * Enable alternate row highlighting, where every odd row has a different background
+ * color than the even rows.s
+ *
+ * @param aEnable flag to specify to enable alternate row striping in the grid
+ */
+ void EnableAlternateRowColors( bool aEnable = true );
+
/**
* Get a tokenized string containing the shown column indexes.
* Tokens are separated by spaces.