You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
5.4 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2014 CERN
  5. * Author: Maciej Suminski <maciej.suminski@cern.ch>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #include "wxunittext.h"
  25. #include <wx/stattext.h>
  26. #include <wx/sizer.h>
  27. #include <wx/textctrl.h>
  28. #include <limits>
  29. #include <base_units.h>
  30. #if wxCHECK_VERSION( 2, 9, 0 )
  31. #include <wx/valnum.h>
  32. #endif
  33. #include <boost/optional.hpp>
  34. WX_UNIT_TEXT::WX_UNIT_TEXT( wxWindow* aParent, const wxString& aLabel, double aValue, double aStep ) :
  35. wxPanel( aParent, wxID_ANY ),
  36. m_step( aStep )
  37. {
  38. // Use the currently selected units
  39. m_units = g_UserUnit;
  40. wxBoxSizer* sizer;
  41. sizer = new wxBoxSizer( wxHORIZONTAL );
  42. // Helper label
  43. m_inputLabel = new wxStaticText( this, wxID_ANY, aLabel,
  44. wxDefaultPosition, wxDefaultSize, 0 );
  45. wxSize size = m_inputLabel->GetMinSize();
  46. size.SetWidth( 150 );
  47. m_inputLabel->SetMinSize( size );
  48. sizer->Add( m_inputLabel, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
  49. // Main input control
  50. m_inputValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
  51. wxTE_PROCESS_ENTER );
  52. SetValue( aValue );
  53. sizer->Add( m_inputValue, 0, wxALIGN_CENTER_VERTICAL | wxALL );
  54. #if wxCHECK_VERSION( 2, 9, 0 ) // Sorry guys, I am tired of dealing with 2.8 compatibility
  55. wxFloatingPointValidator<double> validator( 4, NULL, wxNUM_VAL_NO_TRAILING_ZEROES );
  56. validator.SetRange( 0.0, std::numeric_limits<double>::max() );
  57. m_inputValue->SetValidator( validator );
  58. // Spin buttons for modifying values using the mouse
  59. m_spinButton = new wxSpinButton( this, wxID_ANY );
  60. m_spinButton->SetRange( std::numeric_limits<int>::min(), std::numeric_limits<int>::max() );
  61. m_spinButton->SetCanFocus( false );
  62. sizer->Add( m_spinButton, 0, wxALIGN_CENTER_VERTICAL | wxALL );
  63. Connect( wxEVT_SPIN_UP, wxSpinEventHandler( WX_UNIT_TEXT::onSpinUpEvent ), NULL, this );
  64. Connect( wxEVT_SPIN_DOWN, wxSpinEventHandler( WX_UNIT_TEXT::onSpinDownEvent ), NULL, this );
  65. #endif
  66. sizer->AddSpacer( 5 );
  67. // Create units label
  68. m_unitLabel = new wxStaticText( this, wxID_ANY, GetUnitsLabel( g_UserUnit ),
  69. wxDefaultPosition, wxDefaultSize, 0 );
  70. sizer->Add( m_unitLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL );
  71. SetSizer( sizer );
  72. Layout();
  73. }
  74. WX_UNIT_TEXT::~WX_UNIT_TEXT()
  75. {
  76. }
  77. void WX_UNIT_TEXT::SetUnits( EDA_UNITS_T aUnits, bool aConvert )
  78. {
  79. assert( !aConvert ); // TODO conversion does not work yet
  80. m_unitLabel->SetLabel( GetUnitsLabel( g_UserUnit ) );
  81. }
  82. void WX_UNIT_TEXT::SetValue( double aValue )
  83. {
  84. if( aValue >= 0.0 )
  85. {
  86. m_inputValue->SetValue( wxString( Double2Str( aValue ).c_str(), wxConvUTF8 ) );
  87. m_inputValue->MarkDirty();
  88. }
  89. else
  90. {
  91. m_inputValue->SetValue( DEFAULT_VALUE );
  92. }
  93. }
  94. /*boost::optional<double> WX_UNIT_TEXT::GetValue( EDA_UNITS_T aUnit ) const
  95. {
  96. if( aUnit == m_units )
  97. return GetValue(); // no conversion needed
  98. switch( m_units )
  99. {
  100. case MILLIMETRES:
  101. switch( aUnit )
  102. {
  103. case INCHES:
  104. iu = Mils2iu( GetValue() * 1000.0 );
  105. break;
  106. case UNSCALED_UNITS:
  107. iu = GetValue();
  108. break;
  109. }
  110. break;
  111. case INCHES:
  112. switch( aUnit )
  113. {
  114. case MILLIMETRES:
  115. return Mils2mm( GetValue() * 1000.0 );
  116. break;
  117. case UNSCALED_UNITS:
  118. return Mils2iu( GetValue() * 1000.0 );
  119. break;
  120. }
  121. break;
  122. case UNSCALED_UNITS:
  123. switch( aUnit )
  124. {
  125. case MILLIMETRES:
  126. return Iu2Mils( GetValue() ) / 1000.0;
  127. break;
  128. // case INCHES:
  129. // return
  130. // break;
  131. }
  132. break;
  133. }
  134. assert( false ); // seems that there are some conversions missing
  135. return 0.0;
  136. }*/
  137. boost::optional<double> WX_UNIT_TEXT::GetValue() const
  138. {
  139. wxString text = m_inputValue->GetValue();
  140. double value;
  141. if( text == DEFAULT_VALUE )
  142. return boost::optional<double>( -1.0 );
  143. if( !text.ToDouble( &value ) )
  144. return boost::optional<double>();
  145. return boost::optional<double>( value );
  146. }
  147. void WX_UNIT_TEXT::onSpinUpEvent( wxSpinEvent& aEvent )
  148. {
  149. SetValue( *GetValue() + m_step );
  150. }
  151. void WX_UNIT_TEXT::onSpinDownEvent( wxSpinEvent& aEvent )
  152. {
  153. double newValue = *GetValue() - m_step;
  154. if( newValue >= 0.0 )
  155. SetValue( newValue );
  156. }
  157. const wxString WX_UNIT_TEXT::DEFAULT_VALUE = _( "default ");