Add configuration of Hi-DPI canvas scaling in OpenGL
First, add automatic detection of toolkit DPI scaling options. For now, this is, in order, * Check the GDK_SCALE option under GTK+ (users can set this to force the scaling) * Check the value from WX's GetContentScalingFactor(). This will start to work correctly from WX 3.1 and GTK+ 3.10. Then, add a user-settable override in the main prefs panel, next to the icon scaling. This is independent of the icon scaling options. DPI handling is performed in a standalone class, so they can be shared between the prefs UI and the OpenGL backend easily. Also means Cairo could use the same interface in future. Also adjust the OpenGL grid drawing code to use the computed scale factor, which avoids over-thick grids in scaled environments (the user can manually thicken the grid if wanted). Fixes: lp:1797308 * https://bugs.launchpad.net/kicad/+bug/1797308
This commit is contained in:
parent
ff73f69d3e
commit
567bdd9b9d
|
@ -295,6 +295,7 @@ set( COMMON_SRCS
|
|||
convert_basic_shapes_to_polygon.cpp
|
||||
dialog_shim.cpp
|
||||
displlst.cpp
|
||||
dpi_scaling.cpp
|
||||
draw_graphic_text.cpp
|
||||
dsnlexer.cpp
|
||||
eagle_parser.cpp
|
||||
|
|
|
@ -21,20 +21,50 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <pgm_base.h>
|
||||
#include <dialog_shim.h>
|
||||
#include <kiface_i.h>
|
||||
#include <bitmap_types.h>
|
||||
#include <bitmaps.h>
|
||||
#include <wx/graphics.h>
|
||||
#include "panel_common_settings.h"
|
||||
|
||||
PANEL_COMMON_SETTINGS::PANEL_COMMON_SETTINGS( DIALOG_SHIM* aDialog, wxWindow* aParent ) :
|
||||
PANEL_COMMON_SETTINGS_BASE( aParent ),
|
||||
m_dialog( aDialog ),
|
||||
m_last_scale( -1 )
|
||||
#include <bitmap_types.h>
|
||||
#include <bitmaps.h>
|
||||
#include <dialog_shim.h>
|
||||
#include <dpi_scaling.h>
|
||||
#include <kiface_i.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
#include <wx/graphics.h>
|
||||
|
||||
|
||||
static constexpr int dpi_scaling_precision = 1;
|
||||
static constexpr double dpi_scaling_increment = 0.5;
|
||||
|
||||
|
||||
PANEL_COMMON_SETTINGS::PANEL_COMMON_SETTINGS( DIALOG_SHIM* aDialog, wxWindow* aParent )
|
||||
: PANEL_COMMON_SETTINGS_BASE( aParent ),
|
||||
m_dialog( aDialog ),
|
||||
m_last_scale( -1 )
|
||||
{
|
||||
m_scaleSlider->SetStep( 25 );
|
||||
m_canvasScaleCtrl->SetRange(
|
||||
DPI_SCALING::GetMinScaleFactor(), DPI_SCALING::GetMaxScaleFactor() );
|
||||
m_canvasScaleCtrl->SetDigits( dpi_scaling_precision );
|
||||
m_canvasScaleCtrl->SetIncrement( dpi_scaling_increment );
|
||||
m_canvasScaleCtrl->SetValue( DPI_SCALING::GetDefaultScaleFactor() );
|
||||
|
||||
m_canvasScaleCtrl->SetToolTip(
|
||||
_( "Set the scale for the canvas."
|
||||
"\n\n"
|
||||
"On high-DPI displays on some platforms, KiCad cannot determine the "
|
||||
"scaling factor. In this case you may need to set this to a value to "
|
||||
"match your system's DPI scaling. 2.0 is a common value. "
|
||||
"\n\n"
|
||||
"If this does not match the system DPI scaling, the canvas will "
|
||||
"not match the window size and cursor position." ) );
|
||||
|
||||
m_canvasScaleAuto->SetToolTip(
|
||||
_( "Use an automatic value for the canvas scale."
|
||||
"\n\n"
|
||||
"On some platforms, the automatic value is incorrect and should be "
|
||||
"set manually." ) );
|
||||
|
||||
m_iconScaleSlider->SetStep( 25 );
|
||||
|
||||
m_textEditorBtn->SetBitmap( KiBitmap( folder_xpm ) );
|
||||
m_pdfViewerBtn->SetBitmap( KiBitmap( folder_xpm ) );
|
||||
|
@ -63,18 +93,24 @@ bool PANEL_COMMON_SETTINGS::TransferDataToWindow()
|
|||
commonSettings->Read( CAIRO_ANTIALIASING_MODE_KEY, &antialiasingMode, 0 );
|
||||
m_antialiasingFallback->SetSelection( antialiasingMode );
|
||||
|
||||
int scale_fourths;
|
||||
commonSettings->Read( ICON_SCALE_KEY, &scale_fourths );
|
||||
int icon_scale_fourths;
|
||||
commonSettings->Read( ICON_SCALE_KEY, &icon_scale_fourths );
|
||||
|
||||
if( scale_fourths <= 0 )
|
||||
if( icon_scale_fourths <= 0 )
|
||||
{
|
||||
m_scaleAuto->SetValue( true );
|
||||
m_scaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
|
||||
m_iconScaleAuto->SetValue( true );
|
||||
m_iconScaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scaleAuto->SetValue( false );
|
||||
m_scaleSlider->SetValue( scale_fourths * 25 );
|
||||
m_iconScaleAuto->SetValue( false );
|
||||
m_iconScaleSlider->SetValue( icon_scale_fourths * 25 );
|
||||
}
|
||||
|
||||
{
|
||||
const DPI_SCALING dpi( commonSettings, this );
|
||||
m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
|
||||
m_canvasScaleAuto->SetValue( dpi.GetCanvasIsAutoScaled() );
|
||||
}
|
||||
|
||||
bool option;
|
||||
|
@ -111,9 +147,14 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
|
|||
|
||||
commonSettings->Write( CAIRO_ANTIALIASING_MODE_KEY, m_antialiasingFallback->GetSelection() );
|
||||
|
||||
const int scale_fourths = m_scaleAuto->GetValue() ? -1 : m_scaleSlider->GetValue() / 25;
|
||||
const int scale_fourths = m_iconScaleAuto->GetValue() ? -1 : m_iconScaleSlider->GetValue() / 25;
|
||||
commonSettings->Write( ICON_SCALE_KEY, scale_fourths );
|
||||
|
||||
{
|
||||
DPI_SCALING dpi( commonSettings, this );
|
||||
dpi.SetDpiConfig( m_canvasScaleAuto->GetValue(), m_canvasScaleCtrl->GetValue() );
|
||||
}
|
||||
|
||||
commonSettings->Write( USE_ICONS_IN_MENUS_KEY, m_checkBoxIconsInMenus->GetValue() );
|
||||
commonSettings->Write( ENBL_ZOOM_NO_CENTER_KEY, !m_ZoomCenterOpt->GetValue() );
|
||||
commonSettings->Write( ENBL_MOUSEWHEEL_PAN_KEY, m_MousewheelPANOpt->GetValue() );
|
||||
|
@ -131,21 +172,42 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
|
|||
|
||||
void PANEL_COMMON_SETTINGS::OnScaleSlider( wxScrollEvent& aEvent )
|
||||
{
|
||||
m_scaleAuto->SetValue( false );
|
||||
m_iconScaleAuto->SetValue( false );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_COMMON_SETTINGS::OnScaleAuto( wxCommandEvent& aEvent )
|
||||
void PANEL_COMMON_SETTINGS::OnIconScaleAuto( wxCommandEvent& aEvent )
|
||||
{
|
||||
if( m_scaleAuto->GetValue() )
|
||||
if( m_iconScaleAuto->GetValue() )
|
||||
{
|
||||
m_last_scale = m_scaleSlider->GetValue();
|
||||
m_scaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
|
||||
m_last_scale = m_iconScaleAuto->GetValue();
|
||||
m_iconScaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_last_scale >= 0 )
|
||||
m_scaleSlider->SetValue( m_last_scale );
|
||||
m_iconScaleSlider->SetValue( m_last_scale );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PANEL_COMMON_SETTINGS::OnCanvasScaleChange( wxCommandEvent& aEvent )
|
||||
{
|
||||
m_canvasScaleAuto->SetValue( false );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_COMMON_SETTINGS::OnCanvasScaleAuto( wxCommandEvent& aEvent )
|
||||
{
|
||||
const bool automatic = m_canvasScaleAuto->GetValue();
|
||||
|
||||
if( automatic )
|
||||
{
|
||||
// set the scale to the auto value, without consulting the config
|
||||
DPI_SCALING dpi( nullptr, this );
|
||||
|
||||
// update the field (no events sent)
|
||||
m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,20 @@ protected:
|
|||
bool TransferDataToWindow() override;
|
||||
|
||||
void OnScaleSlider( wxScrollEvent& aEvent ) override;
|
||||
void OnScaleAuto( wxCommandEvent& aEvent ) override;
|
||||
void OnIconScaleAuto( wxCommandEvent& aEvent ) override;
|
||||
void OnTextEditorClick( wxCommandEvent& event ) override;
|
||||
void OnPDFViewerClick( wxCommandEvent& event ) override;
|
||||
void onUpdateUIPdfPath( wxUpdateUIEvent& event ) override;
|
||||
void onUpdateUIPdfPath( wxUpdateUIEvent& event ) override;
|
||||
|
||||
/**
|
||||
* Event fired when the canvas scale field is modified
|
||||
*/
|
||||
void OnCanvasScaleChange( wxCommandEvent& aEvent ) override;
|
||||
|
||||
/**
|
||||
* Event fired when the canvas auto-scale option is changed
|
||||
*/
|
||||
void OnCanvasScaleAuto( wxCommandEvent& aEvent ) override;
|
||||
|
||||
DIALOG_SHIM* m_dialog;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jan 5 2019)
|
||||
// C++ code generated with wxFormBuilder (version Nov 10 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -136,25 +136,26 @@ PANEL_COMMON_SETTINGS_BASE::PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWind
|
|||
|
||||
m_staticTexticonscale = new wxStaticText( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Icon scale:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTexticonscale->Wrap( -1 );
|
||||
fgSizer11->Add( m_staticTexticonscale, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 4 );
|
||||
fgSizer11->Add( m_staticTexticonscale, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 4 );
|
||||
|
||||
wxBoxSizer* bSizer4;
|
||||
bSizer4 = new wxBoxSizer( wxHORIZONTAL );
|
||||
m_iconScaleSlider = new STEPPED_SLIDER( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, 50, 50, 275, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL|wxSL_LABELS );
|
||||
m_iconScaleSlider->SetMinSize( wxSize( 240,-1 ) );
|
||||
|
||||
m_scaleSlider = new STEPPED_SLIDER( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, 50, 50, 275, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL|wxSL_LABELS );
|
||||
m_scaleSlider->SetMinSize( wxSize( 240,-1 ) );
|
||||
fgSizer11->Add( m_iconScaleSlider, 1, wxBOTTOM|wxEXPAND, 4 );
|
||||
|
||||
bSizer4->Add( m_scaleSlider, 1, wxBOTTOM|wxEXPAND, 4 );
|
||||
m_iconScaleAuto = new wxCheckBox( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Automatic"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer11->Add( m_iconScaleAuto, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 25 );
|
||||
|
||||
m_staticTextPerCent = new wxStaticText( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextPerCent->Wrap( -1 );
|
||||
bSizer4->Add( m_staticTextPerCent, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2 );
|
||||
m_staticTextCanvasScale = new wxStaticText( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Canvas scale:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticTextCanvasScale->Wrap( -1 );
|
||||
fgSizer11->Add( m_staticTextCanvasScale, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
m_canvasScaleCtrl = new wxSpinCtrlDouble( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 0, 1 );
|
||||
m_canvasScaleCtrl->SetDigits( 0 );
|
||||
fgSizer11->Add( m_canvasScaleCtrl, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
fgSizer11->Add( bSizer4, 1, wxEXPAND, 5 );
|
||||
|
||||
m_scaleAuto = new wxCheckBox( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Automatic"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer11->Add( m_scaleAuto, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 25 );
|
||||
m_canvasScaleAuto = new wxCheckBox( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Automatic"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer11->Add( m_canvasScaleAuto, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 25 );
|
||||
|
||||
|
||||
fgSizer11->Add( 0, 0, 0, wxEXPAND, 5 );
|
||||
|
@ -202,16 +203,18 @@ PANEL_COMMON_SETTINGS_BASE::PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWind
|
|||
m_PDFViewerPath->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_COMMON_SETTINGS_BASE::onUpdateUIPdfPath ), NULL, this );
|
||||
m_pdfViewerBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnPDFViewerClick ), NULL, this );
|
||||
m_pdfViewerBtn->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_COMMON_SETTINGS_BASE::onUpdateUIPdfPath ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_TOP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Connect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleAuto->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleAuto ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_TOP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Connect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleAuto->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnIconScaleAuto ), NULL, this );
|
||||
m_canvasScaleCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnCanvasScaleChange ), NULL, this );
|
||||
m_canvasScaleAuto->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnCanvasScaleAuto ), NULL, this );
|
||||
}
|
||||
|
||||
PANEL_COMMON_SETTINGS_BASE::~PANEL_COMMON_SETTINGS_BASE()
|
||||
|
@ -221,15 +224,17 @@ PANEL_COMMON_SETTINGS_BASE::~PANEL_COMMON_SETTINGS_BASE()
|
|||
m_PDFViewerPath->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_COMMON_SETTINGS_BASE::onUpdateUIPdfPath ), NULL, this );
|
||||
m_pdfViewerBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnPDFViewerClick ), NULL, this );
|
||||
m_pdfViewerBtn->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_COMMON_SETTINGS_BASE::onUpdateUIPdfPath ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_TOP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleSlider->Disconnect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_scaleAuto->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleAuto ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_TOP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleSlider->Disconnect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
|
||||
m_iconScaleAuto->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnIconScaleAuto ), NULL, this );
|
||||
m_canvasScaleCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnCanvasScaleChange ), NULL, this );
|
||||
m_canvasScaleAuto->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnCanvasScaleAuto ), NULL, this );
|
||||
|
||||
}
|
||||
|
|
|
@ -1219,7 +1219,7 @@
|
|||
<property name="vgap">0</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">4</property>
|
||||
<property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
|
@ -1278,142 +1278,70 @@
|
|||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">4</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer4</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">4</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxSlider" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maxValue">275</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minValue">50</property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">240,-1</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_scaleSlider</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxSL_HORIZONTAL|wxSL_LABELS</property>
|
||||
<property name="subclass">STEPPED_SLIDER; widgets/stepped_slider.h; Not forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value">50</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnScroll">OnScaleSlider</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">2</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">%</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticTextPerCent</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="wxSlider" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maxValue">275</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minValue">50</property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">240,-1</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_iconScaleSlider</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxSL_HORIZONTAL|wxSL_LABELS</property>
|
||||
<property name="subclass">STEPPED_SLIDER; widgets/stepped_slider.h; Not forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value">50</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnScroll">OnScaleSlider</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
|
@ -1457,7 +1385,7 @@
|
|||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_scaleAuto</property>
|
||||
<property name="name">m_iconScaleAuto</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
|
@ -1478,7 +1406,198 @@
|
|||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnCheckBox">OnScaleAuto</event>
|
||||
<event name="OnCheckBox">OnIconScaleAuto</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Canvas scale:</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticTextCanvasScale</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxSpinCtrlDouble" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="digits">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="inc">1</property>
|
||||
<property name="initial">0</property>
|
||||
<property name="max">100</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min">0</property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_canvasScaleCtrl</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxSP_ARROW_KEYS</property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnSpinCtrlText">OnCanvasScaleChange</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">25</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="checked">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Automatic</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_canvasScaleAuto</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnCheckBox">OnCanvasScaleAuto</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jan 5 2019)
|
||||
// C++ code generated with wxFormBuilder (version Nov 10 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -61,9 +61,11 @@ class PANEL_COMMON_SETTINGS_BASE : public wxPanel
|
|||
wxTextCtrl* m_PDFViewerPath;
|
||||
wxBitmapButton* m_pdfViewerBtn;
|
||||
wxStaticText* m_staticTexticonscale;
|
||||
STEPPED_SLIDER* m_scaleSlider;
|
||||
wxStaticText* m_staticTextPerCent;
|
||||
wxCheckBox* m_scaleAuto;
|
||||
STEPPED_SLIDER* m_iconScaleSlider;
|
||||
wxCheckBox* m_iconScaleAuto;
|
||||
wxStaticText* m_staticTextCanvasScale;
|
||||
wxSpinCtrlDouble* m_canvasScaleCtrl;
|
||||
wxCheckBox* m_canvasScaleAuto;
|
||||
wxCheckBox* m_checkBoxIconsInMenus;
|
||||
wxCheckBox* m_ZoomCenterOpt;
|
||||
wxCheckBox* m_MousewheelPANOpt;
|
||||
|
@ -74,7 +76,9 @@ class PANEL_COMMON_SETTINGS_BASE : public wxPanel
|
|||
virtual void onUpdateUIPdfPath( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
virtual void OnPDFViewerClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnScaleSlider( wxScrollEvent& event ) { event.Skip(); }
|
||||
virtual void OnScaleAuto( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnIconScaleAuto( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCanvasScaleChange( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCanvasScaleAuto( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 KiCad Developers, see CHANGELOG.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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <dpi_scaling.h>
|
||||
|
||||
#include <core/optional.h>
|
||||
|
||||
#include <env_vars.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
#include <wx/config.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
|
||||
/**
|
||||
* Flag to enable trace for HiDPI scaling factors
|
||||
*
|
||||
* Use "KICAD_TRACE_HIGH_DPI" to enable.
|
||||
*
|
||||
* @ingroup trace_env_vars
|
||||
*/
|
||||
const wxChar* const traceHiDpi = wxT( "KICAD_TRACE_HIGH_DPI" );
|
||||
|
||||
|
||||
/**
|
||||
* Get a user-configured scale factor from KiCad config file
|
||||
*
|
||||
* @return the scale factor, if set
|
||||
*/
|
||||
static OPT<double> getKiCadConfiguredScale( const wxConfigBase& aConfig )
|
||||
{
|
||||
OPT<double> scale;
|
||||
double canvas_scale = 0.0;
|
||||
aConfig.Read( CANVAS_SCALE_KEY, &canvas_scale, 0.0 );
|
||||
|
||||
if( canvas_scale > 0.0 )
|
||||
{
|
||||
scale = canvas_scale;
|
||||
}
|
||||
|
||||
if( scale )
|
||||
{
|
||||
wxLogTrace( traceHiDpi, "Scale factor (configured): %f", *scale );
|
||||
}
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the toolkit scale factor from a user-set environment variable
|
||||
* (for example GDK_SCALE on GTK).
|
||||
*
|
||||
* @return the scale factor, if set
|
||||
*/
|
||||
static OPT<double> getEnviromentScale()
|
||||
{
|
||||
const wxPortId port_id = wxPlatformInfo::Get().GetPortId();
|
||||
OPT<double> scale;
|
||||
|
||||
if( port_id == wxPORT_GTK )
|
||||
{
|
||||
// Under GTK, the user can use GDK_SCALE to force the scaling
|
||||
scale = GetEnvVar<double>( "GDK_SCALE" );
|
||||
}
|
||||
|
||||
if( scale )
|
||||
{
|
||||
wxLogTrace( traceHiDpi, "Scale factor (environment): %f", *scale );
|
||||
}
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
|
||||
DPI_SCALING::DPI_SCALING( wxConfigBase* aConfig, const wxWindow* aWindow )
|
||||
: m_config( aConfig ), m_window( aWindow )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
double DPI_SCALING::GetScaleFactor() const
|
||||
{
|
||||
OPT<double> val;
|
||||
|
||||
if( m_config )
|
||||
{
|
||||
val = getKiCadConfiguredScale( *m_config );
|
||||
}
|
||||
|
||||
if( !val )
|
||||
{
|
||||
val = getEnviromentScale();
|
||||
}
|
||||
|
||||
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 = m_window->GetContentScaleFactor();
|
||||
wxLogTrace( traceHiDpi, "Scale factor (WX): %f", *val );
|
||||
}
|
||||
|
||||
if( !val )
|
||||
{
|
||||
// Nothing else we can do, give it a default value
|
||||
val = GetDefaultScaleFactor();
|
||||
wxLogTrace( traceHiDpi, "Scale factor (default): %f", *val );
|
||||
}
|
||||
|
||||
return *val;
|
||||
}
|
||||
|
||||
|
||||
bool DPI_SCALING::GetCanvasIsAutoScaled() const
|
||||
{
|
||||
if( m_config == nullptr )
|
||||
{
|
||||
// No configuration given, so has to be automatic scaling
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool automatic = getKiCadConfiguredScale( *m_config ) == boost::none;
|
||||
wxLogTrace( traceHiDpi, "Scale is automatic: %d", automatic );
|
||||
return automatic;
|
||||
}
|
||||
|
||||
|
||||
void DPI_SCALING::SetDpiConfig( bool aAuto, double aValue )
|
||||
{
|
||||
wxCHECK_RET( m_config != nullptr, "Setting DPI config without a config store." );
|
||||
|
||||
const double value = aAuto ? 0.0 : aValue;
|
||||
|
||||
m_config->Write( CANVAS_SCALE_KEY, value );
|
||||
}
|
||||
|
||||
|
||||
double DPI_SCALING::GetMaxScaleFactor()
|
||||
{
|
||||
// displays with higher than 4.0 DPI are not really going to be useful
|
||||
// for KiCad (even an 8k display would be effectively only ~1080p at 4x)
|
||||
return 6.0;
|
||||
}
|
||||
|
||||
|
||||
double DPI_SCALING::GetMinScaleFactor()
|
||||
{
|
||||
// scales under 1.0 don't make sense from a HiDPI perspective
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
double DPI_SCALING::GetDefaultScaleFactor()
|
||||
{
|
||||
// no scaling => 1.0
|
||||
return 1.0;
|
||||
}
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include <common.h>
|
||||
|
||||
#include <wx/utils.h>
|
||||
|
||||
using STRING_MAP = std::map<wxString, wxString>;
|
||||
|
||||
/*
|
||||
|
@ -103,3 +105,36 @@ wxString LookUpEnvVarHelp( const wxString& aEnvVar )
|
|||
|
||||
return env_var_help_text[aEnvVar];
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
OPT<double> GetEnvVar( const wxString& aEnvVarName )
|
||||
{
|
||||
OPT<double> opt_value;
|
||||
|
||||
wxString env;
|
||||
if( wxGetEnv( aEnvVarName, &env ) )
|
||||
{
|
||||
double value;
|
||||
if( env.ToDouble( &value ) )
|
||||
{
|
||||
opt_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
return opt_value;
|
||||
}
|
||||
|
||||
template<>
|
||||
OPT<wxString> GetEnvVar( const wxString& aEnvVarName )
|
||||
{
|
||||
OPT<wxString> opt_value;
|
||||
|
||||
wxString env;
|
||||
if( wxGetEnv( aEnvVarName, &env ) )
|
||||
{
|
||||
opt_value = env;
|
||||
}
|
||||
|
||||
return opt_value;
|
||||
}
|
|
@ -22,9 +22,11 @@
|
|||
*/
|
||||
|
||||
#include <gal/gal_display_options.h>
|
||||
|
||||
#include <wx/config.h>
|
||||
|
||||
#include <config_map.h>
|
||||
#include <dpi_scaling.h>
|
||||
|
||||
using namespace KIGFX;
|
||||
|
||||
|
@ -55,7 +57,8 @@ GAL_DISPLAY_OPTIONS::GAL_DISPLAY_OPTIONS()
|
|||
m_gridMinSpacing( 10.0 ),
|
||||
m_axesEnabled( false ),
|
||||
m_fullscreenCursor( false ),
|
||||
m_forceDisplayCursor( false )
|
||||
m_forceDisplayCursor( false ),
|
||||
m_scaleFactor( DPI_SCALING::GetDefaultScaleFactor() )
|
||||
{}
|
||||
|
||||
|
||||
|
|
|
@ -26,16 +26,14 @@
|
|||
|
||||
#include <gal/hidpi_gl_canvas.h>
|
||||
|
||||
#include <dpi_scaling.h>
|
||||
|
||||
HIDPI_GL_CANVAS::HIDPI_GL_CANVAS( wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const int *attribList,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
long style,
|
||||
const wxString& name,
|
||||
const wxPalette& palette ) :
|
||||
wxGLCanvas( parent, id, attribList, pos, size, style, name, palette )
|
||||
|
||||
HIDPI_GL_CANVAS::HIDPI_GL_CANVAS( wxWindow* parent, wxWindowID id, const int* attribList,
|
||||
const wxPoint& pos, const wxSize& size, long style, const wxString& name,
|
||||
const wxPalette& palette )
|
||||
: wxGLCanvas( parent, id, attribList, pos, size, style, name, palette ),
|
||||
m_scale_factor( DPI_SCALING::GetDefaultScaleFactor() )
|
||||
{
|
||||
#ifdef RETINA_OPENGL_PATCH
|
||||
SetViewWantsBestResolution( true );
|
||||
|
@ -47,15 +45,14 @@ wxSize HIDPI_GL_CANVAS::GetNativePixelSize() const
|
|||
{
|
||||
wxSize size = wxGLCanvas::GetClientSize();
|
||||
|
||||
#ifdef RETINA_OPENGL_PATCH
|
||||
const float scaleFactor = GetBackingScaleFactor();
|
||||
size.x *= scaleFactor;
|
||||
size.y *= scaleFactor;
|
||||
#endif
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
float HIDPI_GL_CANVAS::GetBackingScaleFactor() const
|
||||
{
|
||||
#ifdef RETINA_OPENGL_PATCH
|
||||
|
@ -63,6 +60,20 @@ float HIDPI_GL_CANVAS::GetBackingScaleFactor() const
|
|||
// => clean up when it officially has arrived in wxWidgets
|
||||
return static_cast< wxGLCanvas* >( const_cast< HIDPI_GL_CANVAS* >( this ))->GetBackingScaleFactor();
|
||||
#else
|
||||
return 1.0f;
|
||||
|
||||
// Return the cached value (which originally was set from config or automatically)
|
||||
return m_scale_factor;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void HIDPI_GL_CANVAS::SetScaleFactor( double aNewScaleFactor )
|
||||
{
|
||||
m_scale_factor = aNewScaleFactor;
|
||||
}
|
||||
|
||||
|
||||
double HIDPI_GL_CANVAS::GetScaleFactor() const
|
||||
{
|
||||
return m_scale_factor;
|
||||
}
|
|
@ -336,6 +336,12 @@ bool OPENGL_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
|
|||
refresh = true;
|
||||
}
|
||||
|
||||
if( options.m_scaleFactor != GetScaleFactor() )
|
||||
{
|
||||
SetScaleFactor( options.m_scaleFactor );
|
||||
refresh = true;
|
||||
}
|
||||
|
||||
if( super::updatedGalDisplayOptions( aOptions ) || refresh )
|
||||
{
|
||||
Refresh();
|
||||
|
@ -1224,7 +1230,8 @@ void OPENGL_GAL::DrawGrid()
|
|||
nonCachedManager->EnableDepthTest( false );
|
||||
|
||||
// sub-pixel lines all render the same
|
||||
float minorLineWidth = std::fmax( 1.0f, gridLineWidth ) * getWorldPixelSize();
|
||||
float minorLineWidth =
|
||||
std::fmax( 1.0f, gridLineWidth ) * getWorldPixelSize() / GetBackingScaleFactor();
|
||||
float majorLineWidth = minorLineWidth * 2.0f;
|
||||
|
||||
// Draw the axis and grid
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include <page_info.h>
|
||||
#include <title_block.h>
|
||||
#include <advanced_config.h>
|
||||
#include <dpi_scaling.h>
|
||||
|
||||
/**
|
||||
* Definition for enabling and disabling scroll bar setting trace output. See the
|
||||
|
@ -301,6 +302,11 @@ void EDA_DRAW_FRAME::CommonSettingsChanged()
|
|||
settings->Read( CAIRO_ANTIALIASING_MODE_KEY, &tmp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
|
||||
m_galDisplayOptions.cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) tmp;
|
||||
|
||||
{
|
||||
const DPI_SCALING dpi{ settings, this };
|
||||
m_galDisplayOptions.m_scaleFactor = dpi.GetScaleFactor();
|
||||
}
|
||||
|
||||
m_galDisplayOptions.NotifyChanged();
|
||||
}
|
||||
|
||||
|
@ -852,6 +858,11 @@ void EDA_DRAW_FRAME::LoadSettings( wxConfigBase* aCfg )
|
|||
cmnCfg->Read( CAIRO_ANTIALIASING_MODE_KEY, &temp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
|
||||
m_galDisplayOptions.cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) temp;
|
||||
|
||||
{
|
||||
const DPI_SCALING dpi{ cmnCfg, this };
|
||||
m_galDisplayOptions.m_scaleFactor = dpi.GetScaleFactor();
|
||||
}
|
||||
|
||||
m_galDisplayOptions.NotifyChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <math/box2.h>
|
||||
#include <lockfile.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <dpi_scaling.h>
|
||||
|
||||
#include <wx/clipbrd.h>
|
||||
#include <fctsys.h>
|
||||
|
@ -303,6 +304,11 @@ void EDA_DRAW_FRAME::CommonSettingsChanged()
|
|||
settings->Read( CAIRO_ANTIALIASING_MODE_KEY, &tmp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
|
||||
m_galDisplayOptions.cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) tmp;
|
||||
|
||||
{
|
||||
const DPI_SCALING dpi{ settings, this };
|
||||
m_galDisplayOptions.m_scaleFactor = dpi.GetScaleFactor();
|
||||
}
|
||||
|
||||
m_galDisplayOptions.NotifyChanged();
|
||||
}
|
||||
|
||||
|
@ -871,6 +877,11 @@ void EDA_DRAW_FRAME::LoadSettings( wxConfigBase* aCfg )
|
|||
cmnCfg->Read( CAIRO_ANTIALIASING_MODE_KEY, &temp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
|
||||
m_galDisplayOptions.cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) temp;
|
||||
|
||||
{
|
||||
const DPI_SCALING dpi{ cmnCfg, this };
|
||||
m_galDisplayOptions.m_scaleFactor = dpi.GetScaleFactor();
|
||||
}
|
||||
|
||||
m_galDisplayOptions.NotifyChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 KiCad Developers, see CHANGELOG.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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef DPI_SCALING__H
|
||||
#define DPI_SCALING__H
|
||||
|
||||
#include <wx/config.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
/**
|
||||
* Class to handle configuration and automatic determination of the DPI
|
||||
* scale to use for canvases. This has several sources and the availability of
|
||||
* some of them are platform dependent.
|
||||
*/
|
||||
class DPI_SCALING
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a DPI scale provider.
|
||||
*
|
||||
* @param aConfig the config store to check for a user value (can be nullptr,
|
||||
* in which case on automatically determined values are considered)
|
||||
* @param aWindow a WX window to use for automatic DPI determination
|
||||
* @return the scaling factor (1.0 = no scaling)
|
||||
*/
|
||||
DPI_SCALING( wxConfigBase* aConfig, const wxWindow* aWindow );
|
||||
|
||||
/**
|
||||
* Get the DPI scale from all known sources in order:
|
||||
*
|
||||
* * user config, if given
|
||||
* * user's environment variables, if set and according to platform
|
||||
* * WX's internal determination of the DPI scaling (WX > 3.1)
|
||||
*/
|
||||
double GetScaleFactor() const;
|
||||
|
||||
/**
|
||||
* Is the current value auto scaled, or is it user-set in the config
|
||||
*/
|
||||
bool GetCanvasIsAutoScaled() const;
|
||||
|
||||
/**
|
||||
* Set the common DPI config in a given config object
|
||||
*
|
||||
* The encoding of the automatic/manual nature of the config is handled internally.
|
||||
*
|
||||
* @param aAuto store a value meaning "no user-set scale"
|
||||
* @param aValue the value to store (ignored if aAuto set)
|
||||
*/
|
||||
void SetDpiConfig( bool aAuto, double aValue );
|
||||
|
||||
/*
|
||||
* Get the maximum scaling factor that should be presented to the user.
|
||||
* This is only advisory, it has no real technical use other than for validation.
|
||||
*/
|
||||
static double GetMaxScaleFactor();
|
||||
|
||||
/*
|
||||
* Get the minimum scaling factor that should be presented to the user.
|
||||
* This is only advisory, it has no real technical use other than for validation.
|
||||
*/
|
||||
static double GetMinScaleFactor();
|
||||
|
||||
/**
|
||||
* Get the "default" scaling factor to use if not other config is available
|
||||
*/
|
||||
static double GetDefaultScaleFactor();
|
||||
|
||||
private:
|
||||
/**
|
||||
* The configuration object to use to get/set user setting. nullptr
|
||||
* if only automatic options are wanted
|
||||
*/
|
||||
wxConfigBase* m_config;
|
||||
|
||||
/**
|
||||
* The WX window to use for WX's automatic DPI checking
|
||||
*/
|
||||
const wxWindow* m_window;
|
||||
};
|
||||
|
||||
#endif // DPI_SCALING__H
|
|
@ -19,15 +19,18 @@
|
|||
|
||||
/**
|
||||
* @file env_vars.h
|
||||
* Functions to provide helpful hints about what environment vars do
|
||||
* Functions related to environment variables, including help functions
|
||||
*/
|
||||
|
||||
#ifndef ENV_VARS_H
|
||||
#define ENV_VARS_H
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <core/optional.h>
|
||||
|
||||
using ENV_VAR_LIST = std::vector<wxString>;
|
||||
|
||||
/**
|
||||
|
@ -56,4 +59,33 @@ const ENV_VAR_LIST& GetPredefinedEnvVars();
|
|||
*/
|
||||
wxString LookUpEnvVarHelp( const wxString& aEnvVar );
|
||||
|
||||
/**
|
||||
* Get an environment variable as a specific type, if set correctly
|
||||
*
|
||||
* @param aEnvVarName the name of the environment variable
|
||||
* @return an OPT containing the value, if set and parseable, otherwise empty.
|
||||
*/
|
||||
template <typename VAL_TYPE>
|
||||
OPT<VAL_TYPE> GetEnvVar( const wxString& aEnvVarName );
|
||||
|
||||
/**
|
||||
* Get a string environment variable, if it is set.
|
||||
*
|
||||
* @param aEnvVarName the name of the environment variable
|
||||
* @return an OPT containing the value, if set, otherwise empty.
|
||||
*/
|
||||
template<>
|
||||
OPT<wxString> GetEnvVar( const wxString& aEnvVarName );
|
||||
|
||||
/**
|
||||
* Get a double from an environment variable, if set
|
||||
*
|
||||
* @param aEnvVarName the name of the environment variable
|
||||
* @return an OPT containing the value, if set and parseable as a double,
|
||||
* otherwise empty.
|
||||
*/
|
||||
template <>
|
||||
OPT<double> GetEnvVar( const wxString& aEnvVarName );
|
||||
|
||||
|
||||
#endif /* ENV_VARS_H */
|
||||
|
|
|
@ -100,6 +100,9 @@ namespace KIGFX
|
|||
|
||||
///> Force cursor display
|
||||
bool m_forceDisplayCursor;
|
||||
|
||||
///> The pixel scale factor (>1 for hi-DPI scaled displays)
|
||||
double m_scaleFactor;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,22 @@ public:
|
|||
|
||||
virtual wxSize GetNativePixelSize() const;
|
||||
virtual float GetBackingScaleFactor() const;
|
||||
|
||||
/**
|
||||
* Set the canvas scale factor, probably for a hi-DPI display.
|
||||
*/
|
||||
void SetScaleFactor( double aFactor );
|
||||
|
||||
/**
|
||||
* Get the current scale factor
|
||||
*/
|
||||
double GetScaleFactor() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The current scale factor (e.g. for hi-DPI displays)
|
||||
*/
|
||||
double m_scale_factor;
|
||||
};
|
||||
|
||||
#endif // HIDPI_GL_CANVAS_H
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#define USE_ICONS_IN_MENUS_KEY wxT( "UseIconsInMenus" )
|
||||
#define ICON_SCALE_KEY wxT( "IconScale" )
|
||||
#define CANVAS_SCALE_KEY wxT( "CanvasScale" )
|
||||
#define AUTOSAVE_INTERVAL_KEY wxT( "AutoSaveInterval" )
|
||||
#define ENBL_ZOOM_NO_CENTER_KEY wxT( "ZoomNoCenter" )
|
||||
#define ENBL_MOUSEWHEEL_PAN_KEY wxT( "MousewheelPAN" )
|
||||
|
|
Loading…
Reference in New Issue