/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 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 as published by the
* Free Software Foundation, either version 3 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, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int KIUI::GetStdMargin()
{
// This is the value used in (most) wxFB dialogs
return 5;
}
SEVERITY SeverityFromString( const wxString& aSeverity )
{
if( aSeverity == wxT( "warning" ) )
return RPT_SEVERITY_WARNING;
else if( aSeverity == wxT( "ignore" ) )
return RPT_SEVERITY_IGNORE;
else
return RPT_SEVERITY_ERROR;
}
wxString SeverityToString( const SEVERITY& aSeverity )
{
if( aSeverity == RPT_SEVERITY_IGNORE )
return wxT( "ignore" );
else if( aSeverity == RPT_SEVERITY_WARNING )
return wxT( "warning" );
else
return wxT( "error" );
}
wxSize KIUI::GetTextSize( const wxString& aSingleLine, wxWindow* aWindow )
{
wxCoord width;
wxCoord height;
{
wxClientDC dc( aWindow );
dc.SetFont( aWindow->GetFont() );
dc.GetTextExtent( aSingleLine, &width, &height );
}
return wxSize( width, height );
}
wxFont KIUI::GetMonospacedUIFont()
{
static int guiFontSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
wxFont font( guiFontSize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
#ifdef __WXMAC__
// https://trac.wxwidgets.org/ticket/19210
if( font.GetFaceName().IsEmpty() )
font.SetFaceName( "Menlo" );
#endif
return font;
}
wxFont makeGUIFont( wxWindow* aWindow, int aDialogSize )
{
wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
// Using wxFont::SetSymbolicSize() fails on (at least) GTK with HiDPI screens, so we have
// to build our own version based off our icon scaling architecture.
int vert_size = aWindow->ConvertDialogToPixels( wxSize( 0, aDialogSize ) ).y;
if( Pgm().GetCommonSettings()->m_Appearance.icon_scale > 0 )
vert_size *= Pgm().GetCommonSettings()->m_Appearance.icon_scale / 4;
if( vert_size < 7 )
vert_size = 7;
if( vert_size < 10 )
vert_size += 1;
font.SetPointSize( vert_size );
#ifdef __WXMAC__
// https://trac.wxwidgets.org/ticket/19210
if( font.GetFaceName().IsEmpty() )
font.SetFaceName( "Lucida Grande" );
#endif
return font;
}
wxFont KIUI::GetControlFont( wxWindow* aWindow )
{
return makeGUIFont( aWindow, 7 );
}
wxFont KIUI::GetInfoFont( wxWindow* aWindow )
{
return makeGUIFont( aWindow, 6 );
}
wxFont KIUI::GetStatusFont( wxWindow* aWindow )
{
return makeGUIFont( aWindow, 5 );
}
bool KIUI::EnsureTextCtrlWidth( wxTextCtrl* aCtrl, const wxString* aString )
{
wxWindow* window = aCtrl->GetParent();
if( !window )
window = aCtrl;
wxString ctrlText;
if( !aString )
{
ctrlText = aCtrl->GetValue();
aString = &ctrlText;
}
wxSize textz = GetTextSize( *aString, window );
wxSize ctrlz = aCtrl->GetSize();
if( ctrlz.GetWidth() < textz.GetWidth() + 10 )
{
ctrlz.SetWidth( textz.GetWidth() + 10 );
aCtrl->SetSizeHints( ctrlz );
return true;
}
return false;
}
void KIUI::SelectReferenceNumber( wxTextEntry* aTextEntry )
{
wxString ref = aTextEntry->GetValue();
if( ref.find_first_of( '?' ) != ref.npos )
{
aTextEntry->SetSelection( ref.find_first_of( '?' ), ref.find_last_of( '?' ) + 1 );
}
else if( ref.find_first_of( '*' ) != ref.npos )
{
aTextEntry->SetSelection( ref.find_first_of( '*' ), ref.find_last_of( '*' ) + 1 );
}
else
{
wxString num = ref;
while( !num.IsEmpty() && ( !isdigit( num.Last() ) || !isdigit( num.GetChar( 0 ) ) ) )
{
// Trim non-digit from end
if( !isdigit( num.Last() ) )
num.RemoveLast();
// Trim non-digit from the start
if( !num.IsEmpty() && !isdigit( num.GetChar( 0 ) ) )
num = num.Right( num.Length() - 1 );
}
aTextEntry->SetSelection( ref.Find( num ), ref.Find( num ) + num.Length() );
if( num.IsEmpty() )
aTextEntry->SetSelection( -1, -1 );
}
}
bool KIUI::IsInputControlFocused( wxWindow* aFocus )
{
if( aFocus == nullptr )
aFocus = wxWindow::FindFocus();
if( !aFocus )
return false;
wxTextEntry* textEntry = dynamic_cast( aFocus );
wxStyledTextCtrl* styledText = dynamic_cast( aFocus );
wxListBox* listBox = dynamic_cast( aFocus );
wxSearchCtrl* searchCtrl = dynamic_cast( aFocus );
wxCheckBox* checkboxCtrl = dynamic_cast( aFocus );
wxChoice* choiceCtrl = dynamic_cast( aFocus );
wxRadioButton* radioBtn = dynamic_cast( aFocus );
wxSpinCtrl* spinCtrl = dynamic_cast( aFocus );
wxSpinCtrlDouble* spinDblCtrl = dynamic_cast( aFocus );
wxSlider* sliderCtl = dynamic_cast( aFocus );
// Data view control is annoying, the focus is on a "wxDataViewCtrlMainWindow" class that
// is not formerly exported via the header.
wxDataViewCtrl* dataViewCtrl = nullptr;
wxWindow* parent = aFocus->GetParent();
if( parent )
dataViewCtrl = dynamic_cast( parent );
return ( textEntry || styledText || listBox || searchCtrl || checkboxCtrl || choiceCtrl
|| radioBtn || spinCtrl || spinDblCtrl || sliderCtl || dataViewCtrl );
}
bool KIUI::IsInputControlEditable( wxWindow* aFocus )
{
wxTextEntry* textEntry = dynamic_cast( aFocus );
wxStyledTextCtrl* styledText = dynamic_cast( aFocus );
wxSearchCtrl* searchCtrl = dynamic_cast( aFocus );
if( textEntry )
return textEntry->IsEditable();
else if( styledText )
return styledText->IsEditable();
else if( searchCtrl )
return searchCtrl->IsEditable();
return true; // Must return true if we can't determine the state, intentionally true for non inputs as well
}
bool KIUI::IsModalDialogFocused()
{
return Pgm().m_ModalDialogCount > 0;
}