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.

212 lines
6.2 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software: you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation, either version 3 of the License, or (at your
  9. * option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "widgets/symbol_diff_widget.h"
  20. #include <wx/bmpbuttn.h>
  21. #include <wx/sizer.h>
  22. #include <wx/slider.h>
  23. #include <wx/stattext.h>
  24. #include <bitmaps.h>
  25. #include <hotkeys_basic.h>
  26. #include <lib_symbol.h>
  27. #include <sch_painter.h>
  28. #include <eeschema_settings.h>
  29. #include <settings/settings_manager.h>
  30. #include <sch_view.h>
  31. SYMBOL_DIFF_WIDGET::SYMBOL_DIFF_WIDGET( wxWindow* aParent,
  32. EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) :
  33. SYMBOL_PREVIEW_WIDGET( aParent, nullptr, false, aCanvasType ),
  34. m_libraryItem( nullptr ),
  35. m_slider( nullptr )
  36. {
  37. wxBoxSizer* bottomSizer = new wxBoxSizer( wxHORIZONTAL );
  38. wxStaticText* schLabel = new wxStaticText( this, wxID_ANY, _( "Schematic" ) );
  39. wxStaticText* libLabel = new wxStaticText( this, wxID_ANY, _( "Library" ) );
  40. m_slider = new wxSlider( this, wxID_ANY, 50, 0, 100 );
  41. bottomSizer->Add( schLabel, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxALIGN_CENTRE_VERTICAL, 6 );
  42. bottomSizer->Add( m_slider, 1, wxLEFT | wxRIGHT | wxALIGN_BOTTOM, 30 );
  43. bottomSizer->Add( libLabel, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxALIGN_CENTRE_VERTICAL, 6 );
  44. m_toggleButton = new wxBitmapButton( this, wxID_ANY, KiBitmapBundle( BITMAPS::swap ) );
  45. wxString toggleTooltip = _( "Toggle between A and B display" );
  46. toggleTooltip = AddHotkeyName( toggleTooltip, '/', HOTKEY_ACTION_TYPE::IS_COMMENT );
  47. m_toggleButton->SetToolTip( toggleTooltip );
  48. bottomSizer->Add( m_toggleButton, 0, wxLEFT | wxRIGHT | wxALIGN_CENTRE_VERTICAL, 6 );
  49. m_outerSizer->Add( bottomSizer, 0, wxTOP | wxLEFT | wxRIGHT | wxEXPAND, 10 );
  50. Layout();
  51. m_slider->Bind( wxEVT_SCROLL_TOP, &SYMBOL_DIFF_WIDGET::onSlider, this );
  52. m_slider->Bind( wxEVT_SCROLL_BOTTOM, &SYMBOL_DIFF_WIDGET::onSlider, this );
  53. m_slider->Bind( wxEVT_SCROLL_LINEUP, &SYMBOL_DIFF_WIDGET::onSlider, this );
  54. m_slider->Bind( wxEVT_SCROLL_LINEDOWN, &SYMBOL_DIFF_WIDGET::onSlider, this );
  55. m_slider->Bind( wxEVT_SCROLL_PAGEUP, &SYMBOL_DIFF_WIDGET::onSlider, this );
  56. m_slider->Bind( wxEVT_SCROLL_PAGEDOWN, &SYMBOL_DIFF_WIDGET::onSlider, this );
  57. m_slider->Bind( wxEVT_SCROLL_THUMBTRACK, &SYMBOL_DIFF_WIDGET::onSlider, this );
  58. m_slider->Bind( wxEVT_SCROLL_THUMBRELEASE, &SYMBOL_DIFF_WIDGET::onSlider, this );
  59. m_slider->Bind( wxEVT_SCROLL_CHANGED, &SYMBOL_DIFF_WIDGET::onSlider, this );
  60. Bind( wxEVT_CHAR_HOOK, &SYMBOL_DIFF_WIDGET::onCharHook, this );
  61. m_toggleButton->Bind( wxEVT_BUTTON,
  62. [this]( wxCommandEvent& aEvent )
  63. {
  64. ToggleAB();
  65. } );
  66. }
  67. SYMBOL_DIFF_WIDGET::~SYMBOL_DIFF_WIDGET()
  68. {
  69. delete m_libraryItem;
  70. }
  71. void SYMBOL_DIFF_WIDGET::DisplayDiff( LIB_SYMBOL* aSchSymbol, LIB_SYMBOL* aLibSymbol, int aUnit,
  72. int aConvert )
  73. {
  74. KIGFX::VIEW* view = m_preview->GetView();
  75. if( m_previewItem )
  76. {
  77. view->Remove( m_previewItem );
  78. delete m_previewItem;
  79. m_previewItem = nullptr;
  80. wxASSERT( m_libraryItem );
  81. view->Remove( m_libraryItem );
  82. delete m_libraryItem;
  83. m_libraryItem = nullptr;
  84. }
  85. if( aSchSymbol )
  86. {
  87. m_previewItem = aSchSymbol;
  88. // For symbols having a De Morgan body style, use the first style
  89. auto settings = static_cast<SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
  90. settings->m_ShowUnit = ( m_previewItem->IsMulti() && !aUnit ) ? 1 : aUnit;
  91. settings->m_ShowBodyStyle = ( m_previewItem->HasAlternateBodyStyle() && !aConvert ) ? 1 : aConvert;
  92. view->Add( m_previewItem );
  93. // Get the symbol size, in internal units
  94. m_itemBBox = m_previewItem->GetUnitBoundingBox( settings->m_ShowUnit,
  95. settings->m_ShowBodyStyle );
  96. // Calculate the draw scale to fit the drawing area
  97. fitOnDrawArea();
  98. wxASSERT( aLibSymbol );
  99. m_libraryItem = aLibSymbol;
  100. view->Add( m_libraryItem );
  101. }
  102. wxScrollEvent dummy;
  103. onSlider( dummy );
  104. m_preview->Show();
  105. Layout();
  106. }
  107. void SYMBOL_DIFF_WIDGET::ToggleAB()
  108. {
  109. const int val = m_slider->GetValue();
  110. if( val == 0 )
  111. m_slider->SetValue( 100 );
  112. else
  113. m_slider->SetValue( 0 );
  114. wxScrollEvent dummy;
  115. onSlider( dummy );
  116. }
  117. void SYMBOL_DIFF_WIDGET::onSlider( wxScrollEvent& aEvent )
  118. {
  119. KIGFX::VIEW* view = m_preview->GetView();
  120. double pct = (double) m_slider->GetValue() / 100.0;
  121. if( m_previewItem )
  122. {
  123. double val;
  124. if( pct < 0.5 )
  125. val = 0.0;
  126. else
  127. val = ( pct - 0.5 ) * 2;
  128. m_previewItem->SetForcedTransparency( val );
  129. view->Update( m_previewItem );
  130. for( SCH_ITEM& child : m_previewItem->GetDrawItems() )
  131. {
  132. child.SetForcedTransparency( val );
  133. view->Update( &child );
  134. }
  135. }
  136. if( m_libraryItem )
  137. {
  138. double val;
  139. if( pct > 0.5 )
  140. val = 0.0;
  141. else
  142. val = 1.0 - ( pct * 2 );
  143. m_libraryItem->SetForcedTransparency( val );
  144. view->Update( m_libraryItem );
  145. for( SCH_ITEM& child : m_libraryItem->GetDrawItems() )
  146. {
  147. child.SetForcedTransparency( val );
  148. view->Update( &child );
  149. }
  150. }
  151. m_preview->ForceRefresh();
  152. aEvent.Skip();
  153. }
  154. void SYMBOL_DIFF_WIDGET::onCharHook( wxKeyEvent& aEvent )
  155. {
  156. if( aEvent.GetKeyCode() == '/' )
  157. {
  158. ToggleAB();
  159. }
  160. else
  161. {
  162. aEvent.Skip();
  163. }
  164. }