Horizontal/vertical zoom for Simulator plots

ADDED: Horizontal/vertical zoom for simulator plots, via mouse wheel,
toolbar buttons, menu commands, and hotkeys.

ADDED: Simulator preferences panel, populated with mouse wheel
and trackpad settings that control pan and zoom of simulator plots.

ADDED: Zoom In/Out Horizontally/Vertically commands that can be bound
to hotkeys.

CHANGED: Simulator plot scroll wheel gestures are no longer hard-coded
and can now be configured via the new Simulator preferences panel.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16597

Other unreported bugs that were fixed:

- Fixed wierd, jumpy simulator plot view limiting behavior.

- Fixed Zoom In Center and Zoom Out Center commands not preserving
  the simulator plot center point.

- Fixed simulator plot nudging when exported as PNGs.

- Fixed rectangular selection zoom being able to exceed simulator plot
  view limits.

Notes:

- Provided new SIM_PREFERENCES struct to be used for future
  simulator preferences set via the simulator preferences dialog.

- Bundled pre-existing EESCHEMA_SETTINGS::SIMULATOR settings into
  EESCHEMA_SETTINGS::SIMULATOR::VIEW.

- Replaced mpWindow::EnableMouseWheelPan with more general
  SetMouseWheelActions.

- Refactored and tidied up wxMathPlot's mpWindow code involved with
  fitting, zooming, and panning.

- Consolidated long lists of duplicated member variable initializers to
  a new mpWindow private delegated constructor.

- Provided provisional Zoom In/Out Horizontally/Vertically toolbar
  icons that need improvement by a graphics designer.

- Provided gitignore entries for the Qt Creator IDE
This commit is contained in:
ecorm 2024-01-22 21:02:50 -04:00 committed by Jeff Young
parent 1bf24da385
commit 16de0a666c
78 changed files with 3704 additions and 359 deletions

4
.gitignore vendored
View File

@ -113,6 +113,10 @@ compile_commands.json
.kdev4/ .kdev4/
*.kdev4 *.kdev4
# Qt Creator
CMakeLists.txt.user
*.autosave
# Translations # Translations
*.mo *.mo
i18n_status.svg i18n_status.svg

View File

@ -51,6 +51,7 @@ Thomas Pointhuber <thomas.pointhuber[at]gmx-dot-at>
Roberto Fernandez Bautista <roberto.fer.bau[at]gmail-dot-com> Roberto Fernandez Bautista <roberto.fer.bau[at]gmail-dot-com>
Mikołaj Wielgus <wielgusmikolaj[at]gmail-dot-com> Mikołaj Wielgus <wielgusmikolaj[at]gmail-dot-com>
Mike Williams <mike[at]mikebwilliams-dot-com> Mike Williams <mike[at]mikebwilliams-dot-com>
Emile Cormier <emile.cormier.jr[at]gmail-dot-com>
See git repo on GitLab for contributors at See git repo on GitLab for contributors at
https://gitlab.com/kicad/code/kicad/-/graphs/master https://gitlab.com/kicad/code/kicad/-/graphs/master

View File

@ -755,6 +755,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_24.png" ), 24, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_24.png" ), 24, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_24.png" ), 24, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_24.png" ), 24, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_24.png" ), 24, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_24.png" ), 24, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_24.png" ), 24, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_24.png" ), 24, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_24.png" ), 24, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_24.png" ), 24, wxT( "dark" ) );
@ -1157,6 +1161,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_24.png" ), 24, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_24.png" ), 24, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_16.png" ), 16, wxT( "light" ) );
@ -1559,6 +1567,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_16.png" ), 16, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_16.png" ), 16, wxT( "dark" ) );
@ -1961,6 +1973,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_16.png" ), 16, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_32.png" ), 32, wxT( "light" ) );
@ -2363,6 +2379,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_32.png" ), 32, wxT( "dark" ) );
@ -2765,6 +2785,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_32.png" ), 32, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_48.png" ), 48, wxT( "light" ) );
@ -3167,6 +3191,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_48.png" ), 48, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_48.png" ), 48, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_48.png" ), 48, wxT( "dark" ) );
@ -3569,6 +3597,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_48.png" ), 48, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_48.png" ), 48, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_64.png" ), 64, wxT( "light" ) );
@ -3971,6 +4003,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_64.png" ), 64, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_64.png" ), 64, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::about].emplace_back( BITMAPS::about, wxT( "about_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::add_aligned_dimension].emplace_back( BITMAPS::add_aligned_dimension, wxT( "add_aligned_dimension_dark_64.png" ), 64, wxT( "dark" ) );
@ -4373,6 +4409,10 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_center_on_screen].emplace_back( BITMAPS::zoom_center_on_screen, wxT( "zoom_center_on_screen_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_in].emplace_back( BITMAPS::zoom_in, wxT( "zoom_in_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_out].emplace_back( BITMAPS::zoom_out, wxT( "zoom_out_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_horizontally].emplace_back( BITMAPS::zoom_in_horizontally, wxT( "zoom_in_horizontally_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_horizontally].emplace_back( BITMAPS::zoom_out_horizontally, wxT( "zoom_out_horizontally_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_in_vertically].emplace_back( BITMAPS::zoom_in_vertically, wxT( "zoom_in_vertically_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_out_vertically].emplace_back( BITMAPS::zoom_out_vertically, wxT( "zoom_out_vertically_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_64.png" ), 64, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::zoom_selection].emplace_back( BITMAPS::zoom_selection, wxT( "zoom_selection_dark_64.png" ), 64, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::icon_bitmap2component_32].emplace_back( BITMAPS::icon_bitmap2component_32, wxT( "icon_bitmap2component_32_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::icon_bitmap2component_32].emplace_back( BITMAPS::icon_bitmap2component_32, wxT( "icon_bitmap2component_32_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::icon_eeschema_32].emplace_back( BITMAPS::icon_eeschema_32, wxT( "icon_eeschema_32_32.png" ), 32, wxT( "light" ) ); aBitmapInfoCache[BITMAPS::icon_eeschema_32].emplace_back( BITMAPS::icon_eeschema_32, wxT( "icon_eeschema_32_32.png" ), 32, wxT( "light" ) );

View File

@ -1137,6 +1137,7 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_ANNO_OPTIONS ), _( "Annotation Options" ) ); book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_ANNO_OPTIONS ), _( "Annotation Options" ) );
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_COLORS ), _( "Colors" ) ); book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_COLORS ), _( "Colors" ) );
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_FIELD_NAME_TEMPLATES ), _( "Field Name Templates" ) ); book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_FIELD_NAME_TEMPLATES ), _( "Field Name Templates" ) );
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_SIMULATOR ), _( "Simulator" ) );
} }
catch( ... ) catch( ... )
{ {

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019-2023 CERN * Copyright (C) 2019-2023 CERN
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -568,6 +568,34 @@ TOOL_ACTION ACTIONS::zoomOutCenter( TOOL_ACTION_ARGS()
.FriendlyName( _( "Zoom Out" ) ) .FriendlyName( _( "Zoom Out" ) )
.Icon( BITMAPS::zoom_out ) ); .Icon( BITMAPS::zoom_out ) );
TOOL_ACTION ACTIONS::zoomInHorizontally( TOOL_ACTION_ARGS()
.Name( "common.Control.zoomInHorizontally" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Zoom In Horizontally" ) )
.Tooltip( _( "Zoom In Horizontally" ) )
.Icon( BITMAPS::zoom_in_horizontally ) );
TOOL_ACTION ACTIONS::zoomOutHorizontally( TOOL_ACTION_ARGS()
.Name( "common.Control.zoomOutHorizontally" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Zoom Out Horizontally" ) )
.Tooltip( _( "Zoom Out Horizontally" ) )
.Icon( BITMAPS::zoom_out_horizontally ) );
TOOL_ACTION ACTIONS::zoomInVertically( TOOL_ACTION_ARGS()
.Name( "common.Control.zoomInVertically" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Zoom In Vertically" ) )
.Tooltip( _( "Zoom In Vertically" ) )
.Icon( BITMAPS::zoom_in_vertically ) );
TOOL_ACTION ACTIONS::zoomOutVertically( TOOL_ACTION_ARGS()
.Name( "common.Control.zoomOutVertically" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Zoom Out Vertically" ) )
.Tooltip( _( "Zoom Out Vertically" ) )
.Icon( BITMAPS::zoom_out_vertically ) );
TOOL_ACTION ACTIONS::zoomCenter( TOOL_ACTION_ARGS() TOOL_ACTION ACTIONS::zoomCenter( TOOL_ACTION_ARGS()
.Name( "common.Control.zoomCenter" ) .Name( "common.Control.zoomCenter" )
.Scope( AS_GLOBAL ) .Scope( AS_GLOBAL )

View File

@ -5,9 +5,9 @@
// Maintainer: Davide Rondini // Maintainer: Davide Rondini
// Contributors: Jose Luis Blanco, Val Greene, Maciej Suminski, Tomasz Wlostowski // Contributors: Jose Luis Blanco, Val Greene, Maciej Suminski, Tomasz Wlostowski
// Created: 21/07/2003 // Created: 21/07/2003
// Last edit: 2023 // Last edit: 2024
// Copyright: (c) David Schalig, Davide Rondini // Copyright: (c) David Schalig, Davide Rondini
// Copyright (c) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors. // Copyright (c) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -1367,82 +1367,14 @@ EVT_MENU( mpID_ZOOM_REDO, mpWindow::onZoomRedo )
END_EVENT_TABLE() END_EVENT_TABLE()
mpWindow::mpWindow() : mpWindow::mpWindow() :
wxWindow(), mpWindow( DelegatingContructorTag() )
m_minX( 0.0 ),
m_maxX( 0.0 ),
m_minY( 0.0 ),
m_maxY( 0.0 ),
m_scaleX( 1.0 ),
m_scaleY( 1.0 ),
m_posX( 0.0 ),
m_posY( 0.0 ),
m_scrX( 64 ),
m_scrY( 64 ),
m_clickedX( 0 ),
m_clickedY( 0 ),
m_yLocked( false ),
m_desiredXmin( 0.0 ),
m_desiredXmax( 1.0 ),
m_desiredYmin( 0.0 ),
m_desiredYmax( 1.0 ),
m_marginTop( 0 ),
m_marginRight( 0 ),
m_marginBottom( 0 ),
m_marginLeft( 0 ),
m_last_lx( 0 ),
m_last_ly( 0 ),
m_buff_bmp( nullptr ),
m_enableDoubleBuffer( false ),
m_enableMouseNavigation( true ),
m_enableMouseWheelPan( false ),
m_enableLimitedView( false ),
m_movingInfoLayer( nullptr ),
m_zooming( false )
{ {
if( wxGraphicsContext *ctx = m_buff_dc.GetGraphicsContext() ) initializeGraphicsContext();
{
if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
|| !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
{
ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
}
ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
}
} }
mpWindow::mpWindow( wxWindow* parent, wxWindowID id ) : mpWindow::mpWindow( wxWindow* parent, wxWindowID id ) :
wxWindow( parent, id, wxDefaultPosition, wxDefaultSize, 0, wxT( "mathplot" ) ), mpWindow( DelegatingContructorTag(),
m_minX( 0.0 ), parent, id, wxDefaultPosition, wxDefaultSize, 0, wxT( "mathplot" ) )
m_maxX( 0.0 ),
m_minY( 0.0 ),
m_maxY( 0.0 ),
m_scaleX( 1.0 ),
m_scaleY( 1.0 ),
m_posX( 0.0 ),
m_posY( 0.0 ),
m_scrX( 64 ),
m_scrY( 64 ),
m_clickedX( 0 ),
m_clickedY( 0 ),
m_yLocked( false ),
m_desiredXmin( 0.0 ),
m_desiredXmax( 1.0 ),
m_desiredYmin( 0.0 ),
m_desiredYmax( 1.0 ),
m_marginTop( 0 ),
m_marginRight( 0 ),
m_marginBottom( 0 ),
m_marginLeft( 0 ),
m_last_lx( 0 ),
m_last_ly( 0 ),
m_buff_bmp( nullptr ),
m_enableDoubleBuffer( false ),
m_enableMouseNavigation( true ),
m_enableMouseWheelPan( false ),
m_enableLimitedView( false ),
m_movingInfoLayer( nullptr ),
m_zooming( false )
{ {
m_popmenu.Append( mpID_ZOOM_UNDO, _( "Undo Last Zoom" ), _( "Return zoom to level prior to last zoom action" ) ); m_popmenu.Append( mpID_ZOOM_UNDO, _( "Undo Last Zoom" ), _( "Return zoom to level prior to last zoom action" ) );
m_popmenu.Append( mpID_ZOOM_REDO, _( "Redo Last Zoom" ), _( "Return zoom to level prior to last zoom undo" ) ); m_popmenu.Append( mpID_ZOOM_REDO, _( "Redo Last Zoom" ), _( "Return zoom to level prior to last zoom undo" ) );
@ -1462,17 +1394,7 @@ mpWindow::mpWindow( wxWindow* parent, wxWindowID id ) :
// J.L.Blanco: Eliminates the "flick" with the double buffer. // J.L.Blanco: Eliminates the "flick" with the double buffer.
SetBackgroundStyle( wxBG_STYLE_CUSTOM ); SetBackgroundStyle( wxBG_STYLE_CUSTOM );
if( wxGraphicsContext* ctx = m_buff_dc.GetGraphicsContext() ) initializeGraphicsContext();
{
if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
|| !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
{
ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
}
ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
}
UpdateAll(); UpdateAll();
} }
@ -1524,56 +1446,37 @@ void mpWindow::onMouseWheel( wxMouseEvent& event )
return; return;
} }
int change = event.GetWheelRotation(); const wxMouseWheelAxis axis = event.GetWheelAxis();
const int axis = event.GetWheelAxis(); const int modifiers = event.GetModifiers();
double changeUnitsX = change / m_scaleX; MouseWheelAction action = MouseWheelAction::NONE;
double changeUnitsY = change / m_scaleY;
if( ( !m_enableMouseWheelPan && ( event.ControlDown() || event.ShiftDown() ) ) if( axis == wxMOUSE_WHEEL_HORIZONTAL )
|| ( m_enableMouseWheelPan && !event.ControlDown() ) )
{ {
// Scrolling action = m_mouseWheelActions.horizontal;
if( m_enableMouseWheelPan )
{
if( axis == wxMOUSE_WHEEL_HORIZONTAL || event.ShiftDown() )
{
SetXView( m_posX + changeUnitsX, m_desiredXmax + changeUnitsX,
m_desiredXmin + changeUnitsX );
} }
else if( !m_yLocked ) else if( modifiers == wxMOD_NONE )
{ {
SetYView( m_posY + changeUnitsY, m_desiredYmax + changeUnitsY, action = m_mouseWheelActions.verticalUnmodified;
m_desiredYmin + changeUnitsY );
} }
else if( modifiers == wxMOD_CONTROL )
{
action = m_mouseWheelActions.verticalWithCtrl;
}
else if( modifiers == wxMOD_SHIFT )
{
action = m_mouseWheelActions.verticalWithShift;
}
else if( modifiers == wxMOD_ALT )
{
action = m_mouseWheelActions.verticalWithAlt;
} }
else else
{ {
if( event.ControlDown() ) event.Skip();
{
SetXView( m_posX + changeUnitsX, m_desiredXmax + changeUnitsX,
m_desiredXmin + changeUnitsX );
}
else if( !m_yLocked )
{
SetYView( m_posY + changeUnitsY, m_desiredYmax + changeUnitsY,
m_desiredYmin + changeUnitsY );
}
}
UpdateAll();
}
else
{
// zoom in/out
wxPoint clickPt( event.GetX(), event.GetY() );
if( event.GetWheelRotation() > 0 )
ZoomIn( clickPt );
else
ZoomOut( clickPt );
return; return;
} }
PerformMouseWheelAction( event, action );
} }
@ -1716,107 +1619,151 @@ void mpWindow::Fit()
// JL // JL
void mpWindow::Fit( double xMin, double xMax, double yMin, double yMax, void mpWindow::Fit( double xMin, double xMax, double yMin, double yMax,
const wxCoord* printSizeX, const wxCoord* printSizeY ) const wxCoord* printSizeX, const wxCoord* printSizeY,
wxOrientation directions )
{ {
const bool isPrinting = printSizeX != nullptr && printSizeY != nullptr;
// Save desired borders: // Save desired borders:
m_desiredXmin = xMin; m_desiredXmax = xMax; double newDesiredXmin = xMin;
m_desiredYmin = yMin; m_desiredYmax = yMax; double newDesiredXmax = xMax;
double newDesiredYmin = yMin;
double newDesiredYmax = yMax;
// Give a small margin to plot area // Provide a gap between the extrema of the curve and the top/bottom edges of the
double xExtra = fabs( xMax - xMin ) * 0.00; // plot area. Not to be confused with the left/right/top/bottom margins outside the plot area.
double yExtra = fabs( yMax - yMin ) * 0.03; const double xGap = fabs( xMax - xMin ) * m_leftRightPlotGapFactor;
const double yGap = fabs( yMax - yMin ) * m_topBottomPlotGapFactor;
xMin -= xGap;
xMax += xGap;
yMin -= yGap;
yMax += yGap;
xMin -= xExtra; int newScrX = m_scrX;
xMax += xExtra; int newScrY = m_scrY;
yMin -= yExtra;
yMax += yExtra;
if( printSizeX != nullptr && printSizeY != nullptr ) if( isPrinting )
{ {
// Printer: // Printer:
m_scrX = *printSizeX; newScrX = *printSizeX;
m_scrY = *printSizeY; newScrY = *printSizeY;
} }
else else
{ {
// Normal case (screen): // Normal case (screen):
GetClientSize( &m_scrX, &m_scrY ); GetClientSize( &newScrX, &newScrY );
} }
double Ax = xMax - xMin; // Compute the width/height in pixels for the plot area.
double Ay = yMax - yMin; const int plotScreenWidth = newScrX - m_marginLeft - m_marginRight;
const int plotScreenHeight = newScrY - m_marginTop - m_marginBottom;
m_scaleX = (Ax != 0) ? (m_scrX - m_marginLeft - m_marginRight) / Ax : 1; // Adjust scale so that desired X/Y span plus extra gap fits in the plot area
m_scaleY = (Ay != 0) ? (m_scrY - m_marginTop - m_marginBottom) / Ay : 1; double desiredSpanX = xMax - xMin;
double desiredSpanY = yMax - yMin;
double newScaleX = (desiredSpanX != 0) ? double(plotScreenWidth) / desiredSpanX : 1;
double newScaleY = (desiredSpanY != 0) ? double(plotScreenHeight) / desiredSpanY : 1;
// Adjusts corner coordinates: This should be simply: // Adjust corner coordinates:
// m_posX = m_minX; // Upstream's aspect lock code has been removed, so no need to account for centering.
// m_posY = m_maxY; double newPosX = xMin - (m_marginLeft / newScaleX);
// But account for centering if we have lock aspect: double newPosY = yMax + (m_marginTop / newScaleY);
m_posX = (xMin + xMax) / 2 - ( (m_scrX - m_marginLeft - m_marginRight) / 2 + m_marginLeft ) /
m_scaleX;
m_posY = (yMin + yMax) / 2 + ( (m_scrY - m_marginTop - m_marginBottom) / 2 + m_marginTop ) /
m_scaleY;
// It is VERY IMPORTANT to DO NOT call Refresh if we are drawing to the printer!! // Commit above changes to member variables only if enabled for their respective dimension.
if( ((directions & wxHORIZONTAL) != 0) || isPrinting )
{
// Don't commit the passed desired bounds when printing
if (!isPrinting)
{
m_desiredXmin = newDesiredXmin;
m_desiredXmax = newDesiredXmax;
}
m_scrX = newScrX;
m_scaleX = newScaleX;
m_posX = newPosX;
}
if( ((directions & wxVERTICAL) != 0) || isPrinting )
{
// Don't commit the passed desired bounds when printing
if (!isPrinting)
{
m_desiredYmin = newDesiredYmin;
m_desiredYmax = newDesiredYmax;
}
m_scrY = newScrY;
m_scaleY = newScaleY;
m_posY = newPosY;
}
// It is VERY IMPORTANT to NOT call Refresh if we are drawing to the printer!!
// Otherwise, the DC dimensions will be those of the window instead of the printer device // Otherwise, the DC dimensions will be those of the window instead of the printer device
if( printSizeX == nullptr || printSizeY == nullptr ) // The caller wanting to print should perform another Fit() afterwards to restore this
// object's state.
if( !isPrinting )
UpdateAll(); UpdateAll();
} }
void mpWindow::AdjustLimitedView() void mpWindow::AdjustLimitedView( wxOrientation directions )
{ {
if( !m_enableLimitedView ) if( !m_enableLimitedView )
return; return;
// m_min and m_max are plot limits for curves // The m_desired* members are expressed in plot coordinates.
// xMin, xMax, yMin, yMax are the full limits (plot limit + margin) // They should be clamped against their respective m_minX, m_maxX, m_minY, m_maxY limits.
const double xMin = m_minX - m_marginLeft / m_scaleX;
const double xMax = m_maxX + m_marginRight / m_scaleX;
const double yMin = m_minY - m_marginBottom / m_scaleY;
const double yMax = m_maxY + m_marginTop / m_scaleY;
if( m_desiredXmin < xMin ) if( (directions & wxHORIZONTAL) != 0 )
{ {
double diff = xMin - m_desiredXmin; if( m_desiredXmin < m_minX )
{
double diff = m_minX - m_desiredXmin;
m_posX += diff; m_posX += diff;
m_desiredXmax += diff; m_desiredXmax += diff;
m_desiredXmin = xMin; m_desiredXmin = m_minX;
} }
if( m_desiredXmax > xMax ) if( m_desiredXmax > m_maxX )
{ {
double diff = m_desiredXmax - xMax; double diff = m_desiredXmax - m_maxX;
m_posX -= diff; m_posX -= diff;
m_desiredXmin -= diff; m_desiredXmin -= diff;
m_desiredXmax = xMax; m_desiredXmax = m_maxX;
}
} }
if( m_desiredYmin < yMin ) if( (directions & wxVERTICAL) != 0 )
{ {
double diff = yMin - m_desiredYmin; if( m_desiredYmin < m_minY )
{
double diff = m_minY - m_desiredYmin;
m_posY += diff; m_posY += diff;
m_desiredYmax += diff; m_desiredYmax += diff;
m_desiredYmin = yMin; m_desiredYmin = m_minY;
} }
if( m_desiredYmax > yMax ) if( m_desiredYmax > m_maxY )
{ {
double diff = m_desiredYmax - yMax; double diff = m_desiredYmax - m_maxY;
m_posY -= diff; m_posY -= diff;
m_desiredYmin -= diff; m_desiredYmin -= diff;
m_desiredYmax = yMax; m_desiredYmax = m_maxY;
}
} }
} }
bool mpWindow::SetXView( double pos, double desiredMax, double desiredMin ) bool mpWindow::SetXView( double pos, double desiredMax, double desiredMin )
{ {
// TODO (ecorm): Investigate X scale flickering when panning at minimum zoom level
// Possible cause: When AdjustLimitedView subtracts the out-of-bound delta, it does not
// revert back to the exact same original coordinates due to floating point rounding errors.
m_posX = pos; m_posX = pos;
m_desiredXmax = desiredMax; m_desiredXmax = desiredMax;
m_desiredXmin = desiredMin; m_desiredXmin = desiredMin;
AdjustLimitedView(); AdjustLimitedView( wxHORIZONTAL );
return true; return true;
} }
@ -1827,7 +1774,7 @@ bool mpWindow::SetYView( double pos, double desiredMax, double desiredMin )
m_posY = pos; m_posY = pos;
m_desiredYmax = desiredMax; m_desiredYmax = desiredMax;
m_desiredYmin = desiredMin; m_desiredYmin = desiredMin;
AdjustLimitedView(); AdjustLimitedView( wxVERTICAL );
return true; return true;
} }
@ -1835,116 +1782,28 @@ bool mpWindow::SetYView( double pos, double desiredMax, double desiredMin )
void mpWindow::ZoomIn( const wxPoint& centerPoint ) void mpWindow::ZoomIn( const wxPoint& centerPoint )
{ {
ZoomIn( centerPoint, zoomIncrementalFactor ); ZoomIn( centerPoint, zoomIncrementalFactor, wxBOTH );
} }
void mpWindow::ZoomIn( const wxPoint& centerPoint, double zoomFactor ) void mpWindow::ZoomIn( const wxPoint& centerPoint, double zoomFactor, wxOrientation directions )
{ {
pushZoomUndo( { m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax } ); DoZoom( centerPoint, zoomFactor, directions );
wxPoint c( centerPoint );
if( c == wxDefaultPosition )
{
GetClientSize( &m_scrX, &m_scrY );
c.x = (m_scrX - m_marginLeft - m_marginRight) / 2 + m_marginLeft; // c.x = m_scrX/2;
c.y = (m_scrY - m_marginTop - m_marginBottom) / 2 - m_marginTop; // c.y = m_scrY/2;
}
else
{
c.x = std::max( c.x, m_marginLeft );
c.x = std::min( c.x, m_scrX - m_marginRight );
c.y = std::max( c.y, m_marginTop );
c.y = std::min( c.y, m_scrY - m_marginBottom );
}
// Preserve the position of the clicked point:
double prior_layer_x = p2x( c.x );
double prior_layer_y = p2y( c.y );
// Zoom in:
const double MAX_SCALE = 1e6;
double newScaleX = m_scaleX * zoomFactor;
double newScaleY = m_scaleY * zoomFactor;
// Baaaaad things happen when you zoom in too much..
if( newScaleX <= MAX_SCALE && newScaleY <= MAX_SCALE )
{
m_scaleX = newScaleX;
if( !m_yLocked )
m_scaleY = newScaleY;
}
else
{
return;
}
// Adjust the new m_posx/y:
m_posX = prior_layer_x - c.x / m_scaleX;
if( !m_yLocked )
m_posY = prior_layer_y + c.y / m_scaleY;
m_desiredXmin = m_posX;
m_desiredXmax = m_posX + (m_scrX - m_marginLeft - m_marginRight) / m_scaleX;
m_desiredYmax = m_posY;
m_desiredYmin = m_posY - (m_scrY - m_marginTop - m_marginBottom) / m_scaleY;
AdjustLimitedView();
UpdateAll();
} }
void mpWindow::ZoomOut( const wxPoint& centerPoint ) void mpWindow::ZoomOut( const wxPoint& centerPoint )
{ {
ZoomOut( centerPoint, zoomIncrementalFactor ); ZoomOut( centerPoint, zoomIncrementalFactor, wxBOTH );
} }
void mpWindow::ZoomOut( const wxPoint& centerPoint, double zoomFactor ) void mpWindow::ZoomOut( const wxPoint& centerPoint, double zoomFactor,
wxOrientation directions )
{ {
pushZoomUndo( { m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax } ); if (zoomFactor == 0)
zoomFactor = 1.0;
wxPoint c( centerPoint ); DoZoom( centerPoint, 1.0 / zoomFactor, directions );
if( c == wxDefaultPosition )
{
GetClientSize( &m_scrX, &m_scrY );
c.x = (m_scrX - m_marginLeft - m_marginRight) / 2 + m_marginLeft;
c.y = (m_scrY - m_marginTop - m_marginBottom) / 2 - m_marginTop;
}
// Preserve the position of the clicked point:
double prior_layer_x = p2x( c.x );
double prior_layer_y = p2y( c.y );
// Zoom out:
m_scaleX = m_scaleX / zoomFactor;
if( !m_yLocked )
m_scaleY = m_scaleY / zoomFactor;
// Adjust the new m_posx/y:
m_posX = prior_layer_x - c.x / m_scaleX;
if( !m_yLocked )
m_posY = prior_layer_y + c.y / m_scaleY;
m_desiredXmin = m_posX;
m_desiredXmax = m_posX + (m_scrX - m_marginLeft - m_marginRight) / m_scaleX;
m_desiredYmax = m_posY;
m_desiredYmin = m_posY - (m_scrY - m_marginTop - m_marginBottom) / m_scaleY;
AdjustLimitedView();
if( !CheckXLimits( m_desiredXmax, m_desiredXmin )
|| !CheckYLimits( m_desiredYmax, m_desiredYmin ) )
{
Fit();
}
UpdateAll();
} }
@ -1952,6 +1811,20 @@ void mpWindow::ZoomRect( wxPoint p0, wxPoint p1 )
{ {
pushZoomUndo( { m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax } ); pushZoomUndo( { m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax } );
// Constrain given rectangle to plot area
const int pMinX = m_marginLeft;
const int pMaxX = m_scrX - m_marginRight;
const int pMinY = m_marginTop;
const int pMaxY = m_scrY - m_marginBottom;
p0.x = std::max( p0.x, pMinX );
p0.x = std::min( p0.x, pMaxX );
p0.y = std::max( p0.y, pMinY );
p0.y = std::min( p0.y, pMaxY );
p1.x = std::max( p1.x, pMinX );
p1.x = std::min( p1.x, pMaxX );
p1.y = std::max( p1.y, pMinY );
p1.y = std::min( p1.y, pMaxY );
// Compute the 2 corners in graph coordinates: // Compute the 2 corners in graph coordinates:
double p0x = p2x( p0.x ); double p0x = p2x( p0.x );
double p0y = p2y( p0.y ); double p0y = p2y( p0.y );
@ -1971,7 +1844,16 @@ void mpWindow::ZoomRect( wxPoint p0, wxPoint p1 )
} }
Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max ); Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max );
// Even with the input rectangle contrained to the plot area, it's still possible for the
// resulting view to exceed limits when a portion of the gap is grabbed.
AdjustLimitedView(); AdjustLimitedView();
// These additional checks are needed because AdjustLimitedView only adjusts the position
// and not the scale.
wxOrientation directionsNeedingRefitting = ViewNeedsRefitting( wxBOTH );
if( directionsNeedingRefitting != 0 )
Fit( m_minX, m_maxX, m_minY, m_maxY, nullptr, nullptr, directionsNeedingRefitting );
} }
@ -2043,6 +1925,18 @@ void mpWindow::OnCenter( wxCommandEvent& WXUNUSED( event ) )
} }
mpWindow::MouseWheelActionSet mpWindow::defaultMouseWheelActions()
{
MouseWheelActionSet actions;
actions.verticalUnmodified = MouseWheelAction::ZOOM;
actions.verticalWithCtrl = MouseWheelAction::PAN_LEFT_RIGHT;
actions.verticalWithShift = MouseWheelAction::PAN_UP_DOWN;
actions.verticalWithAlt = MouseWheelAction::NONE;
actions.horizontal = MouseWheelAction::NONE;
return actions;
}
void mpWindow::onZoomIn( wxCommandEvent& WXUNUSED( event ) ) void mpWindow::onZoomIn( wxCommandEvent& WXUNUSED( event ) )
{ {
ZoomIn( wxPoint( m_mouseMClick.x, m_mouseMClick.y ) ); ZoomIn( wxPoint( m_mouseMClick.x, m_mouseMClick.y ) );
@ -2188,6 +2082,199 @@ void mpWindow::OnPaint( wxPaintEvent& WXUNUSED( event ) )
paintDC.Blit( 0, 0, m_scrX, m_scrY, targetDC, 0, 0 ); paintDC.Blit( 0, 0, m_scrX, m_scrY, targetDC, 0, 0 );
} }
void mpWindow::DoZoom( const wxPoint& centerPoint, double zoomFactor,
wxOrientation directions )
{
if( m_yLocked )
{
if( directions == wxVERTICAL )
return;
directions = wxHORIZONTAL;
}
const bool horizontally = (directions & wxHORIZONTAL) != 0;
const bool vertically = (directions & wxVERTICAL) != 0;
pushZoomUndo( { m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax } );
// Preserve the position of the clicked point:
wxPoint c( centerPoint );
if( c == wxDefaultPosition )
{
GetClientSize( &m_scrX, &m_scrY );
c.x = (m_scrX - m_marginLeft - m_marginRight) / 2 + m_marginLeft;
c.y = (m_scrY - m_marginTop - m_marginBottom) / 2 + m_marginTop;
}
else
{
c.x = std::max( c.x, m_marginLeft );
c.x = std::min( c.x, m_scrX - m_marginRight );
c.y = std::max( c.y, m_marginTop );
c.y = std::min( c.y, m_scrY - m_marginBottom );
}
// Zoom in/out:
const double MAX_SCALE = 1e6;
const double newScaleX = horizontally ? (m_scaleX * zoomFactor) : m_scaleX;
const double newScaleY = vertically ? (m_scaleY * zoomFactor) : m_scaleY;
// Baaaaad things happen when you zoom in too much..
if( newScaleX > MAX_SCALE || newScaleY > MAX_SCALE )
return;
if ( horizontally )
{
// Transform the clicked X point to layer coordinates:
const double prior_layer_x = p2x( c.x );
// Adjust the new X scale and plot X origin:
m_scaleX = newScaleX;
m_posX = prior_layer_x - c.x / newScaleX;
// Recompute the desired X view extents:
RecomputeDesiredX( m_desiredXmin, m_desiredXmax );
}
if ( vertically )
{
// Transform the clicked Y point to layer coordinates:
const double prior_layer_y = p2y( c.y );
// Adjust the new Y scale and plot Y origin:
m_scaleY = newScaleY;
m_posY = prior_layer_y + c.y / newScaleY;
// Recompute the desired Y view extents:
RecomputeDesiredY( m_desiredYmin, m_desiredYmax );
}
AdjustLimitedView( directions );
if (zoomFactor < 1.0)
{
// These additional checks are needed because AdjustLimitedView only adjusts the position
// and not the scale.
wxOrientation directionsNeedingRefitting = ViewNeedsRefitting( directions );
// If the view is still out-of-limits after AdjustLimitedView is called, perform a Fit
// along the offending dimension(s).
if( directionsNeedingRefitting != 0 )
Fit( m_minX, m_maxX, m_minY, m_maxY, nullptr, nullptr, directionsNeedingRefitting );
}
UpdateAll();
}
void mpWindow::RecomputeDesiredX( double& min, double& max )
{
const int plotScreenWidth = m_scrX - m_marginLeft - m_marginRight;
const double plotSpanX = plotScreenWidth / m_scaleX;
const double desiredSpanX = plotSpanX / ( 2*m_leftRightPlotGapFactor + 1 );
const double xGap = desiredSpanX * m_leftRightPlotGapFactor;
min = m_posX + ( m_marginLeft / m_scaleX ) + xGap;
max = m_desiredXmin + desiredSpanX;
}
void mpWindow::RecomputeDesiredY( double& min, double& max )
{
const int plotScreenHeight = m_scrY - m_marginTop - m_marginBottom;
const double plotSpanY = plotScreenHeight / m_scaleY;
const double desiredSpanY = plotSpanY / ( 2*m_topBottomPlotGapFactor + 1 );
const double yGap = desiredSpanY * m_topBottomPlotGapFactor;
max = m_posY - ( m_marginTop / m_scaleY) - yGap;
min = m_desiredYmax - desiredSpanY;
}
wxOrientation mpWindow::ViewNeedsRefitting( wxOrientation directions ) const
{
if( !m_enableLimitedView )
return static_cast<wxOrientation>( 0 );
// Allow a gap between the extrema of the curve and the edges of the plot area. Not to be
// confused with the left/right/top/bottom margins outside the plot area.
const double xGap = fabs( m_maxX - m_minX ) * m_leftRightPlotGapFactor;
const double yGap = fabs( m_maxY - m_minY ) * m_topBottomPlotGapFactor;
wxOrientation result = {};
if ( (directions & wxHORIZONTAL) != 0 )
{
if ( ( m_desiredXmax > m_maxX + xGap ) || ( m_desiredXmin < m_minX - xGap ) )
result = static_cast<wxOrientation>( result | wxHORIZONTAL );
}
if ( (directions & wxVERTICAL) != 0 )
{
if ( ( m_desiredYmax > m_maxY + yGap ) || ( m_desiredYmin < m_minY - yGap ) )
result = static_cast<wxOrientation>( result | wxVERTICAL );
}
return result;
}
void mpWindow::PerformMouseWheelAction( wxMouseEvent& event, MouseWheelAction action )
{
const int change = event.GetWheelRotation();
const double changeUnitsX = change / m_scaleX;
const double changeUnitsY = change / m_scaleY;
const wxPoint clickPt( event.GetX(), event.GetY() );
switch (action)
{
case MouseWheelAction::NONE:
break;
case MouseWheelAction::PAN_LEFT_RIGHT:
SetXView( m_posX + changeUnitsX, m_desiredXmax + changeUnitsX,
m_desiredXmin + changeUnitsX );
UpdateAll();
break;
case MouseWheelAction::PAN_RIGHT_LEFT:
SetXView( m_posX - changeUnitsX, m_desiredXmax - changeUnitsX,
m_desiredXmin - changeUnitsX );
UpdateAll();
break;
case MouseWheelAction::PAN_UP_DOWN:
if( !m_yLocked )
{
SetYView( m_posY + changeUnitsY, m_desiredYmax + changeUnitsY,
m_desiredYmin + changeUnitsY );
UpdateAll();
}
break;
case MouseWheelAction::ZOOM:
if( event.GetWheelRotation() > 0 )
ZoomIn( clickPt );
else
ZoomOut( clickPt );
break;
case MouseWheelAction::ZOOM_HORIZONTALLY:
if( event.GetWheelRotation() > 0 )
ZoomIn( clickPt, zoomIncrementalFactor, wxHORIZONTAL );
else
ZoomOut( clickPt, zoomIncrementalFactor, wxHORIZONTAL );
break;
case MouseWheelAction::ZOOM_VERTICALLY:
if( event.GetWheelRotation() > 0 )
ZoomIn( clickPt, zoomIncrementalFactor, wxVERTICAL );
else
ZoomOut( clickPt, zoomIncrementalFactor, wxVERTICAL );
break;
default:
break;
}
}
bool mpWindow::UpdateBBox() bool mpWindow::UpdateBBox()
{ {
@ -2392,6 +2479,59 @@ void mpWindow::SetColourTheme( const wxColour& bgColour, const wxColour& drawCol
} }
template <typename... Ts>
mpWindow::mpWindow( DelegatingContructorTag, Ts&&... windowArgs ) :
wxWindow( std::forward<Ts>( windowArgs )... ),
m_minX( 0.0 ),
m_maxX( 0.0 ),
m_minY( 0.0 ),
m_maxY( 0.0 ),
m_scaleX( 1.0 ),
m_scaleY( 1.0 ),
m_posX( 0.0 ),
m_posY( 0.0 ),
m_scrX( 64 ),
m_scrY( 64 ),
m_clickedX( 0 ),
m_clickedY( 0 ),
m_yLocked( false ),
m_desiredXmin( 0.0 ),
m_desiredXmax( 1.0 ),
m_desiredYmin( 0.0 ),
m_desiredYmax( 1.0 ),
m_topBottomPlotGapFactor( 0.03 ),
m_leftRightPlotGapFactor( 0.0 ),
m_marginTop( 0 ),
m_marginRight( 0 ),
m_marginBottom( 0 ),
m_marginLeft( 0 ),
m_last_lx( 0 ),
m_last_ly( 0 ),
m_buff_bmp( nullptr ),
m_enableDoubleBuffer( false ),
m_enableMouseNavigation( true ),
m_enableLimitedView( false ),
m_mouseWheelActions( defaultMouseWheelActions() ),
m_movingInfoLayer( nullptr ),
m_zooming( false )
{}
void mpWindow::initializeGraphicsContext()
{
if( wxGraphicsContext* ctx = m_buff_dc.GetGraphicsContext() )
{
if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
|| !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
{
ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
}
ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// mpFXYVector implementation - by Jose Luis Blanco (AGO-2007) // mpFXYVector implementation - by Jose Luis Blanco (AGO-2007)
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -186,6 +186,8 @@ set( EESCHEMA_DLGS
dialogs/panel_setup_formatting_base.cpp dialogs/panel_setup_formatting_base.cpp
dialogs/panel_setup_pinmap.cpp dialogs/panel_setup_pinmap.cpp
dialogs/panel_setup_pinmap_base.cpp dialogs/panel_setup_pinmap_base.cpp
dialogs/panel_simulator_preferences.cpp
dialogs/panel_simulator_preferences_base.cpp
dialogs/panel_sym_color_settings.cpp dialogs/panel_sym_color_settings.cpp
dialogs/panel_sym_color_settings_base.cpp dialogs/panel_sym_color_settings_base.cpp
dialogs/panel_sym_display_options.cpp dialogs/panel_sym_display_options.cpp

View File

@ -0,0 +1,168 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
*/
#include <type_traits>
#include <wx/defs.h>
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include "panel_simulator_preferences.h"
#include "../eeschema_settings.h"
PANEL_SIMULATOR_PREFERENCES::PANEL_SIMULATOR_PREFERENCES( wxWindow* aParent ) :
PANEL_SIMULATOR_PREFERENCES_BASE( aParent )
{
#ifdef __WXOSX_MAC__
m_lblVScrollCtrl->SetLabel( _( "Cmd" ) );
m_lblVScrollAlt->SetLabel( _( "Option" ) );
#endif
// Populate the wxChoice items programmatically here instead of via the form builder
// to ease maintenance.
static const wxString verticalChoiceItems[] =
{
_("No action"),
_("Pan left/right"),
_("Pan right/left"),
_("Pan up/down"),
_("Zoom"),
_("Zoom horizontally"),
_("Zoom vertically")
};
static constexpr auto ACTION_COUNT = static_cast<unsigned>( SIM_MOUSE_WHEEL_ACTION::COUNT );
static_assert( std::extent<decltype(verticalChoiceItems)>::value == ACTION_COUNT,
"verticalChoiceItems size does not match VERTICAL_SCROLL_ACTION::COUNT" );
m_choiceVScrollUnmodified->Set( ACTION_COUNT, verticalChoiceItems );
m_choiceVScrollCtrl ->Set( ACTION_COUNT, verticalChoiceItems );
m_choiceVScrollShift ->Set( ACTION_COUNT, verticalChoiceItems );
m_choiceVScrollAlt ->Set( ACTION_COUNT, verticalChoiceItems );
static const wxString horizontalChoiceItems[] =
{
_("No action"),
_("Pan left/right"),
_("Zoom horizontally")
};
m_choiceHScroll->Set( std::extent<decltype(horizontalChoiceItems)>::value,
horizontalChoiceItems );
}
PANEL_SIMULATOR_PREFERENCES::~PANEL_SIMULATOR_PREFERENCES() = default;
void PANEL_SIMULATOR_PREFERENCES::ResetPanel()
{
applyMouseScrollActionsToPanel( SIM_MOUSE_WHEEL_ACTION_SET::GetMouseDefaults() );
}
bool PANEL_SIMULATOR_PREFERENCES::TransferDataFromWindow()
{
static constexpr auto toAction =
[]( const wxChoice* aChoice )
{
return static_cast<SIM_MOUSE_WHEEL_ACTION>( aChoice->GetSelection() );
};
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
EESCHEMA_SETTINGS* settings = mgr.GetAppSettings<EESCHEMA_SETTINGS>();
SIM_MOUSE_WHEEL_ACTION_SET& actions = settings->m_Simulator.preferences.mouse_wheel_actions;
actions.vertical_unmodified = toAction( m_choiceVScrollUnmodified );
actions.vertical_with_ctrl = toAction( m_choiceVScrollCtrl );
actions.vertical_with_shift = toAction( m_choiceVScrollShift );
actions.vertical_with_alt = toAction( m_choiceVScrollAlt );
actions.horizontal = horizontalScrollSelectionToAction( m_choiceHScroll->GetSelection() );
return true;
}
bool PANEL_SIMULATOR_PREFERENCES::TransferDataToWindow()
{
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
const EESCHEMA_SETTINGS* settings = mgr.GetAppSettings<EESCHEMA_SETTINGS>();
applyMouseScrollActionsToPanel( settings->m_Simulator.preferences.mouse_wheel_actions );
return true;
}
void PANEL_SIMULATOR_PREFERENCES::onMouseDefaults( wxCommandEvent& )
{
applyMouseScrollActionsToPanel( SIM_MOUSE_WHEEL_ACTION_SET::GetMouseDefaults() );
}
void PANEL_SIMULATOR_PREFERENCES::onTrackpadDefaults( wxCommandEvent& )
{
applyMouseScrollActionsToPanel( SIM_MOUSE_WHEEL_ACTION_SET::GetTrackpadDefaults() );
}
SIM_MOUSE_WHEEL_ACTION
PANEL_SIMULATOR_PREFERENCES::horizontalScrollSelectionToAction( int aSelection )
{
switch( aSelection )
{
case 0: return SIM_MOUSE_WHEEL_ACTION::NONE;
case 1: return SIM_MOUSE_WHEEL_ACTION::PAN_LEFT_RIGHT;
case 2: return SIM_MOUSE_WHEEL_ACTION::ZOOM_HORIZONTALLY;
default: break;
}
return SIM_MOUSE_WHEEL_ACTION::NONE;
}
int PANEL_SIMULATOR_PREFERENCES::actionToHorizontalScrollSelection( SIM_MOUSE_WHEEL_ACTION a )
{
switch( a )
{
case SIM_MOUSE_WHEEL_ACTION::NONE: return 0;
case SIM_MOUSE_WHEEL_ACTION::PAN_LEFT_RIGHT: return 1;
case SIM_MOUSE_WHEEL_ACTION::ZOOM_HORIZONTALLY: return 2;
default: break;
}
return 0;
}
void PANEL_SIMULATOR_PREFERENCES::applyMouseScrollActionsToPanel(
const SIM_MOUSE_WHEEL_ACTION_SET& anActionSet )
{
static constexpr auto setSelection =
[]( wxChoice* aChoice, auto action )
{
aChoice->SetSelection( static_cast<int>( action ) );
};
setSelection( m_choiceVScrollUnmodified, anActionSet.vertical_unmodified );
setSelection( m_choiceVScrollCtrl, anActionSet.vertical_with_ctrl );
setSelection( m_choiceVScrollShift, anActionSet.vertical_with_shift );
setSelection( m_choiceVScrollAlt, anActionSet.vertical_with_alt );
m_choiceHScroll->SetSelection( actionToHorizontalScrollSelection( anActionSet.horizontal ) );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 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 <http://www.gnu.org/licenses/>.
*/
#ifndef KICAD_PANEL_SIMULATOR_PREFERENCES_H
#define KICAD_PANEL_SIMULATOR_PREFERENCES_H
#include "panel_simulator_preferences_base.h"
#include <sim/sim_preferences.h>
class PANEL_SIMULATOR_PREFERENCES : public PANEL_SIMULATOR_PREFERENCES_BASE
{
public:
PANEL_SIMULATOR_PREFERENCES( wxWindow* aParent );
~PANEL_SIMULATOR_PREFERENCES();
void ResetPanel() override;
protected:
bool TransferDataFromWindow() override;
bool TransferDataToWindow() override;
void onMouseDefaults( wxCommandEvent& ) override;
void onTrackpadDefaults( wxCommandEvent& ) override;
private:
static SIM_MOUSE_WHEEL_ACTION horizontalScrollSelectionToAction( int aSelection );
static int actionToHorizontalScrollSelection( SIM_MOUSE_WHEEL_ACTION anAction );
void applyMouseScrollActionsToPanel( const SIM_MOUSE_WHEEL_ACTION_SET& anActionSet );
};
#endif

View File

@ -0,0 +1,166 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "panel_simulator_preferences_base.h"
///////////////////////////////////////////////////////////////////////////
PANEL_SIMULATOR_PREFERENCES_BASE::PANEL_SIMULATOR_PREFERENCES_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : RESETTABLE_PANEL( parent, id, pos, size, style, name )
{
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bScrollSizer;
bScrollSizer = new wxBoxSizer( wxVERTICAL );
m_lblScrollHeading = new wxStaticText( this, wxID_ANY, _("Scroll Gestures"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblScrollHeading->Wrap( -1 );
bScrollSizer->Add( m_lblScrollHeading, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 13 );
m_scrollLine = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bScrollSizer->Add( m_scrollLine, 0, wxEXPAND|wxBOTTOM, 5 );
wxBoxSizer* bScrollMargins;
bScrollMargins = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bScrollSizerLeft;
bScrollSizerLeft = new wxBoxSizer( wxVERTICAL );
m_lblVScrollMovement = new wxStaticText( this, wxID_ANY, _("Vertical touchpad or scroll wheel movement:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblVScrollMovement->Wrap( -1 );
bScrollSizerLeft->Add( m_lblVScrollMovement, 0, wxLEFT|wxRIGHT, 5 );
bScrollSizerLeft->Add( 0, 10, 0, wxEXPAND, 5 );
wxFlexGridSizer* fgVScroll;
fgVScroll = new wxFlexGridSizer( 0, 2, 0, 0 );
fgVScroll->AddGrowableCol( 0 );
fgVScroll->SetFlexibleDirection( wxBOTH );
fgVScroll->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_lblVScrollModifier = new wxStaticText( this, wxID_ANY, _("Modifier"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblVScrollModifier->Wrap( -1 );
fgVScroll->Add( m_lblVScrollModifier, 0, wxALIGN_BOTTOM, 5 );
m_lblVScrollAction = new wxStaticText( this, wxID_ANY, _("Action"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblVScrollAction->Wrap( -1 );
fgVScroll->Add( m_lblVScrollAction, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 5 );
m_lblVScrollUnmodified = new wxStaticText( this, wxID_ANY, _("None:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblVScrollUnmodified->Wrap( -1 );
fgVScroll->Add( m_lblVScrollUnmodified, 0, wxALIGN_CENTER_VERTICAL, 5 );
wxArrayString m_choiceVScrollUnmodifiedChoices;
m_choiceVScrollUnmodified = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceVScrollUnmodifiedChoices, 0 );
m_choiceVScrollUnmodified->SetSelection( 0 );
fgVScroll->Add( m_choiceVScrollUnmodified, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_lblVScrollCtrl = new wxStaticText( this, wxID_ANY, _("Ctrl:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblVScrollCtrl->Wrap( -1 );
fgVScroll->Add( m_lblVScrollCtrl, 0, wxALIGN_CENTER_VERTICAL, 5 );
wxArrayString m_choiceVScrollCtrlChoices;
m_choiceVScrollCtrl = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceVScrollCtrlChoices, 0 );
m_choiceVScrollCtrl->SetSelection( 0 );
fgVScroll->Add( m_choiceVScrollCtrl, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_lblVScrollShift = new wxStaticText( this, wxID_ANY, _("Shift:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblVScrollShift->Wrap( -1 );
fgVScroll->Add( m_lblVScrollShift, 0, wxALIGN_CENTER_VERTICAL, 5 );
wxArrayString m_choiceVScrollShiftChoices;
m_choiceVScrollShift = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceVScrollShiftChoices, 0 );
m_choiceVScrollShift->SetSelection( 0 );
fgVScroll->Add( m_choiceVScrollShift, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_lblVScrollAlt = new wxStaticText( this, wxID_ANY, _("Alt:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblVScrollAlt->Wrap( -1 );
fgVScroll->Add( m_lblVScrollAlt, 0, wxALIGN_CENTER_VERTICAL, 5 );
wxArrayString m_choiceVScrollAltChoices;
m_choiceVScrollAlt = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceVScrollAltChoices, 0 );
m_choiceVScrollAlt->SetSelection( 0 );
fgVScroll->Add( m_choiceVScrollAlt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bScrollSizerLeft->Add( fgVScroll, 0, wxRIGHT|wxLEFT, 24 );
bScrollSizerLeft->Add( 0, 10, 0, wxEXPAND, 5 );
m_lblHScrollMovement = new wxStaticText( this, wxID_ANY, _("Horizontal touchpad movement:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblHScrollMovement->Wrap( -1 );
bScrollSizerLeft->Add( m_lblHScrollMovement, 0, wxALL, 5 );
bScrollSizerLeft->Add( 0, 10, 0, wxEXPAND, 5 );
wxFlexGridSizer* fgHScroll;
fgHScroll = new wxFlexGridSizer( 0, 2, 0, 0 );
fgHScroll->AddGrowableCol( 0 );
fgHScroll->SetFlexibleDirection( wxBOTH );
fgHScroll->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_lblHScrollModifier = new wxStaticText( this, wxID_ANY, _("Modifier"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblHScrollModifier->Wrap( -1 );
fgHScroll->Add( m_lblHScrollModifier, 0, wxALIGN_BOTTOM, 5 );
m_lblHScrollAction = new wxStaticText( this, wxID_ANY, _("Action"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblHScrollAction->Wrap( -1 );
fgHScroll->Add( m_lblHScrollAction, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 5 );
m_lblHScrollAny = new wxStaticText( this, wxID_ANY, _("Any:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lblHScrollAny->Wrap( -1 );
fgHScroll->Add( m_lblHScrollAny, 0, wxALIGN_CENTER_VERTICAL, 5 );
wxArrayString m_choiceHScrollChoices;
m_choiceHScroll = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceHScrollChoices, 0 );
m_choiceHScroll->SetSelection( 0 );
fgHScroll->Add( m_choiceHScroll, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bScrollSizerLeft->Add( fgHScroll, 0, wxRIGHT|wxLEFT, 24 );
bScrollMargins->Add( bScrollSizerLeft, 0, wxEXPAND|wxLEFT, 5 );
wxBoxSizer* bScrollSizerRight;
bScrollSizerRight = new wxBoxSizer( wxVERTICAL );
m_btnMouseDefaults = new wxButton( this, wxID_ANY, _("Reset to Mouse Defaults"), wxDefaultPosition, wxDefaultSize, 0 );
bScrollSizerRight->Add( m_btnMouseDefaults, 0, wxALL|wxEXPAND, 5 );
m_btnTrackpadDefaults = new wxButton( this, wxID_ANY, _("Reset to Trackpad Defaults"), wxDefaultPosition, wxDefaultSize, 0 );
bScrollSizerRight->Add( m_btnTrackpadDefaults, 0, wxALL|wxEXPAND, 5 );
bScrollMargins->Add( bScrollSizerRight, 0, wxTOP|wxLEFT|wxEXPAND, 5 );
bScrollSizer->Add( bScrollMargins, 1, wxEXPAND|wxTOP|wxRIGHT, 10 );
bMainSizer->Add( bScrollSizer, 1, 0, 5 );
this->SetSizer( bMainSizer );
this->Layout();
bMainSizer->Fit( this );
// Connect Events
m_btnMouseDefaults->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SIMULATOR_PREFERENCES_BASE::onMouseDefaults ), NULL, this );
m_btnTrackpadDefaults->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SIMULATOR_PREFERENCES_BASE::onTrackpadDefaults ), NULL, this );
}
PANEL_SIMULATOR_PREFERENCES_BASE::~PANEL_SIMULATOR_PREFERENCES_BASE()
{
// Disconnect Events
m_btnMouseDefaults->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SIMULATOR_PREFERENCES_BASE::onMouseDefaults ), NULL, this );
m_btnTrackpadDefaults->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SIMULATOR_PREFERENCES_BASE::onTrackpadDefaults ), NULL, this );
}

View File

@ -0,0 +1,72 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "widgets/resettable_panel.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/statline.h>
#include <wx/choice.h>
#include <wx/sizer.h>
#include <wx/button.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_SIMULATOR_PREFERENCES_BASE
///////////////////////////////////////////////////////////////////////////////
class PANEL_SIMULATOR_PREFERENCES_BASE : public RESETTABLE_PANEL
{
private:
protected:
wxStaticText* m_lblScrollHeading;
wxStaticLine* m_scrollLine;
wxStaticText* m_lblVScrollMovement;
wxStaticText* m_lblVScrollModifier;
wxStaticText* m_lblVScrollAction;
wxStaticText* m_lblVScrollUnmodified;
wxChoice* m_choiceVScrollUnmodified;
wxStaticText* m_lblVScrollCtrl;
wxChoice* m_choiceVScrollCtrl;
wxStaticText* m_lblVScrollShift;
wxChoice* m_choiceVScrollShift;
wxStaticText* m_lblVScrollAlt;
wxChoice* m_choiceVScrollAlt;
wxStaticText* m_lblHScrollMovement;
wxStaticText* m_lblHScrollModifier;
wxStaticText* m_lblHScrollAction;
wxStaticText* m_lblHScrollAny;
wxChoice* m_choiceHScroll;
wxButton* m_btnMouseDefaults;
wxButton* m_btnTrackpadDefaults;
// Virtual event handlers, override them in your derived class
virtual void onMouseDefaults( wxCommandEvent& event ) { event.Skip(); }
virtual void onTrackpadDefaults( wxCommandEvent& event ) { event.Skip(); }
public:
PANEL_SIMULATOR_PREFERENCES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_SIMULATOR_PREFERENCES_BASE();
};

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2023 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2004-2024 KiCad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -39,6 +39,7 @@
#include <symbol_lib_table.h> #include <symbol_lib_table.h>
#include <dialogs/dialog_global_sym_lib_table_config.h> #include <dialogs/dialog_global_sym_lib_table_config.h>
#include <dialogs/panel_grid_settings.h> #include <dialogs/panel_grid_settings.h>
#include <dialogs/panel_simulator_preferences.h>
#include <dialogs/panel_sym_lib_table.h> #include <dialogs/panel_sym_lib_table.h>
#include <kiway.h> #include <kiway.h>
#include <settings/settings_manager.h> #include <settings/settings_manager.h>
@ -294,6 +295,9 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
case PANEL_SCH_FIELD_NAME_TEMPLATES: case PANEL_SCH_FIELD_NAME_TEMPLATES:
return new PANEL_TEMPLATE_FIELDNAMES( aParent, nullptr ); return new PANEL_TEMPLATE_FIELDNAMES( aParent, nullptr );
case PANEL_SCH_SIMULATOR:
return new PANEL_SIMULATOR_PREFERENCES( aParent );
default: default:
return nullptr; return nullptr;
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -531,22 +531,57 @@ EESCHEMA_SETTINGS::EESCHEMA_SETTINGS() :
&m_Simulator.window.perspective, "" ) ); &m_Simulator.window.perspective, "" ) );
m_params.emplace_back( new PARAM<int>( "simulator.plot_panel_width", m_params.emplace_back( new PARAM<int>( "simulator.plot_panel_width",
&m_Simulator.plot_panel_width, 0 ) ); &m_Simulator.view.plot_panel_width, 0 ) );
m_params.emplace_back( new PARAM<int>( "simulator.plot_panel_height", m_params.emplace_back( new PARAM<int>( "simulator.plot_panel_height",
&m_Simulator.plot_panel_height, 0 ) ); &m_Simulator.view.plot_panel_height, 0 ) );
m_params.emplace_back( new PARAM<int>( "simulator.signal_panel_height", m_params.emplace_back( new PARAM<int>( "simulator.signal_panel_height",
&m_Simulator.signal_panel_height, 0 ) ); &m_Simulator.view.signal_panel_height, 0 ) );
m_params.emplace_back( new PARAM<int>( "simulator.cursors_panel_height", m_params.emplace_back( new PARAM<int>( "simulator.cursors_panel_height",
&m_Simulator.cursors_panel_height, 0 ) ); &m_Simulator.view.cursors_panel_height, 0 ) );
m_params.emplace_back( new PARAM<int>( "simulator.measurements_panel_height", m_params.emplace_back( new PARAM<int>( "simulator.measurements_panel_height",
&m_Simulator.measurements_panel_height, 0 ) ); &m_Simulator.view.measurements_panel_height, 0 ) );
m_params.emplace_back( new PARAM<bool>( "simulator.white_background", m_params.emplace_back( new PARAM<bool>( "simulator.white_background",
&m_Simulator.white_background, false ) ); &m_Simulator.view.white_background, false ) );
m_params.emplace_back( new PARAM_ENUM<SIM_MOUSE_WHEEL_ACTION>(
"simulator.mouse_wheel_actions.vertical_unmodified",
&m_Simulator.preferences.mouse_wheel_actions.vertical_unmodified,
SIM_MOUSE_WHEEL_ACTION::ZOOM,
SIM_MOUSE_WHEEL_ACTION::NONE,
SIM_MOUSE_WHEEL_ACTION::ZOOM_VERTICALLY ) );
m_params.emplace_back( new PARAM_ENUM<SIM_MOUSE_WHEEL_ACTION>(
"simulator.mouse_wheel_actions.vertical_with_ctrl",
&m_Simulator.preferences.mouse_wheel_actions.vertical_with_ctrl,
SIM_MOUSE_WHEEL_ACTION::PAN_LEFT_RIGHT,
SIM_MOUSE_WHEEL_ACTION::NONE,
SIM_MOUSE_WHEEL_ACTION::ZOOM_VERTICALLY ) );
m_params.emplace_back( new PARAM_ENUM<SIM_MOUSE_WHEEL_ACTION>(
"simulator.mouse_wheel_actions.vertical_with_shift",
&m_Simulator.preferences.mouse_wheel_actions.vertical_with_shift,
SIM_MOUSE_WHEEL_ACTION::PAN_UP_DOWN,
SIM_MOUSE_WHEEL_ACTION::NONE,
SIM_MOUSE_WHEEL_ACTION::ZOOM_VERTICALLY) );
m_params.emplace_back( new PARAM_ENUM<SIM_MOUSE_WHEEL_ACTION>(
"simulator.mouse_wheel_actions.vertical_with_alt",
&m_Simulator.preferences.mouse_wheel_actions.vertical_with_alt,
SIM_MOUSE_WHEEL_ACTION::NONE,
SIM_MOUSE_WHEEL_ACTION::NONE,
SIM_MOUSE_WHEEL_ACTION::ZOOM_VERTICALLY) );
m_params.emplace_back( new PARAM_ENUM<SIM_MOUSE_WHEEL_ACTION>(
"simulator.mouse_wheel_actions.horizontal",
&m_Simulator.preferences.mouse_wheel_actions.horizontal,
SIM_MOUSE_WHEEL_ACTION::NONE,
SIM_MOUSE_WHEEL_ACTION::NONE,
SIM_MOUSE_WHEEL_ACTION::ZOOM_VERTICALLY) );
m_params.emplace_back( new PARAM<int>( "symbol_chooser.sash_pos_h", m_params.emplace_back( new PARAM<int>( "symbol_chooser.sash_pos_h",
&m_SymChooserPanel.sash_pos_h, -1 ) ); &m_SymChooserPanel.sash_pos_h, -1 ) );

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -27,7 +27,7 @@
#include <wx/aui/framemanager.h> #include <wx/aui/framemanager.h>
#include <settings/app_settings.h> #include <settings/app_settings.h>
#include <sim/sim_preferences.h>
using KIGFX::COLOR4D; using KIGFX::COLOR4D;
@ -277,6 +277,8 @@ public:
}; };
struct SIMULATOR struct SIMULATOR
{
struct VIEW
{ {
int plot_panel_width; int plot_panel_width;
int plot_panel_height; int plot_panel_height;
@ -284,7 +286,11 @@ public:
int cursors_panel_height; int cursors_panel_height;
int measurements_panel_height; int measurements_panel_height;
bool white_background; bool white_background;
};
VIEW view;
WINDOW_SETTINGS window; WINDOW_SETTINGS window;
SIM_PREFERENCES preferences;
}; };
struct FIND_REPLACE_EXTRA struct FIND_REPLACE_EXTRA

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2023 CERN * Copyright (C) 2016-2023 CERN
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
@ -195,6 +195,12 @@ public:
virtual ~SIM_PLOT_TAB(); virtual ~SIM_PLOT_TAB();
void ApplyPreferences( const SIM_PREFERENCES& aPrefs ) override
{
m_plotWin->SetMouseWheelActions(
convertMouseWheelActions( aPrefs.mouse_wheel_actions ) );
}
wxString GetLabelX() const wxString GetLabelX() const
{ {
return m_axis_x ? m_axis_x->GetName() : wxString( wxS( "" ) ); return m_axis_x ? m_axis_x->GetName() : wxString( wxS( "" ) );
@ -359,6 +365,22 @@ public:
wxPoint m_LastLegendPosition; wxPoint m_LastLegendPosition;
private: private:
static mpWindow::MouseWheelActionSet
convertMouseWheelActions(const SIM_MOUSE_WHEEL_ACTION_SET& s)
{
static_assert( static_cast<unsigned>(mpWindow::MouseWheelAction::COUNT) ==
static_cast<unsigned>(SIM_MOUSE_WHEEL_ACTION::COUNT),
"mpWindow::MouseWheelAction enum must match SIM_MOUSE_WHEEL_ACTION" );
using A = mpWindow::MouseWheelAction;
mpWindow::MouseWheelActionSet m;
m.verticalUnmodified = static_cast<A>( s.vertical_unmodified );
m.verticalWithCtrl = static_cast<A>( s.vertical_with_ctrl );
m.verticalWithShift = static_cast<A>( s.vertical_with_shift );
m.verticalWithAlt = static_cast<A>( s.vertical_with_alt );
return m;
}
wxString getTraceId( const wxString& aVectorName, int aType ) const wxString getTraceId( const wxString& aVectorName, int aType ) const
{ {
return wxString::Format( wxS( "%s%d" ), aVectorName, aType & SPT_Y_AXIS_MASK ); return wxString::Format( wxS( "%s%d" ), aVectorName, aType & SPT_Y_AXIS_MASK );

View File

@ -0,0 +1,101 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2024 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, you may find one here:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __SIM_PREFERENCES__
#define __SIM_PREFERENCES__
/**
* @file sim_preferences.h
*
* Contains preferences pertaining to the simulator.
*/
/**
* Enumerates the possible mouse wheel actions that can be performed on simulator plots.
*/
enum class SIM_MOUSE_WHEEL_ACTION
{
// Directly using mpWindow::MouseWheelAction would leak wxMathPlot via the eeschema_settings.h
// header, so we duplicate it here in this miminal header.
NONE,
PAN_LEFT_RIGHT,
PAN_RIGHT_LEFT,
PAN_UP_DOWN,
ZOOM,
ZOOM_HORIZONTALLY,
ZOOM_VERTICALLY,
COUNT // Internal use only
};
/**
* Contains the set of modified mouse wheel actions that can be performed on a simulator plot.
*/
struct SIM_MOUSE_WHEEL_ACTION_SET
{
// Directly using mpWindow::MouseWheelActionSet would leak wxMathPlot via the
// eeschema_settings.h header, so we duplicate it here in this miminal header.
SIM_MOUSE_WHEEL_ACTION vertical_unmodified;
SIM_MOUSE_WHEEL_ACTION vertical_with_ctrl;
SIM_MOUSE_WHEEL_ACTION vertical_with_shift;
SIM_MOUSE_WHEEL_ACTION vertical_with_alt;
SIM_MOUSE_WHEEL_ACTION horizontal;
static SIM_MOUSE_WHEEL_ACTION_SET GetMouseDefaults()
{
// Returns defaults equivalent to the global Mouse and Touchpad default settings
SIM_MOUSE_WHEEL_ACTION_SET actions;
actions.vertical_unmodified = SIM_MOUSE_WHEEL_ACTION::ZOOM;
actions.vertical_with_ctrl = SIM_MOUSE_WHEEL_ACTION::PAN_LEFT_RIGHT;
actions.vertical_with_shift = SIM_MOUSE_WHEEL_ACTION::PAN_UP_DOWN;
actions.vertical_with_alt = SIM_MOUSE_WHEEL_ACTION::NONE;
actions.horizontal = SIM_MOUSE_WHEEL_ACTION::NONE;
return actions;
}
static SIM_MOUSE_WHEEL_ACTION_SET GetTrackpadDefaults()
{
// Returns defaults equivalent to the global Mouse and Touchpad default settings
SIM_MOUSE_WHEEL_ACTION_SET actions;
actions.vertical_unmodified = SIM_MOUSE_WHEEL_ACTION::PAN_UP_DOWN;
actions.vertical_with_ctrl = SIM_MOUSE_WHEEL_ACTION::ZOOM;
actions.vertical_with_shift = SIM_MOUSE_WHEEL_ACTION::PAN_LEFT_RIGHT;
actions.vertical_with_alt = SIM_MOUSE_WHEEL_ACTION::NONE;
actions.horizontal = SIM_MOUSE_WHEEL_ACTION::PAN_LEFT_RIGHT;
return actions;
}
};
/**
* Contains preferences pertaining to the simulator.
*/
struct SIM_PREFERENCES
{
SIM_MOUSE_WHEEL_ACTION_SET mouse_wheel_actions;
};
#endif // __SIM_PREFERENCES__

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2023 CERN * Copyright (C) 2016-2023 CERN
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
* @author Sylwester Kocjan <s.kocjan@o2.pl> * @author Sylwester Kocjan <s.kocjan@o2.pl>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -67,6 +67,10 @@ bool SIM_TAB::IsPlottable( SIM_TYPE aSimType )
} }
} }
void SIM_TAB::ApplyPreferences( const SIM_PREFERENCES& /*aPrefs*/ )
{
}
SIM_TYPE SIM_TAB::GetSimType() const SIM_TYPE SIM_TAB::GetSimType() const
{ {

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2023 CERN * Copyright (C) 2016-2023 CERN
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* @author Sylwester Kocjan <s.kocjan@o2.pl> * @author Sylwester Kocjan <s.kocjan@o2.pl>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -26,6 +26,7 @@
#ifndef __SIM_PLOT_PANEL_BASE_H #ifndef __SIM_PLOT_PANEL_BASE_H
#define __SIM_PLOT_PANEL_BASE_H #define __SIM_PLOT_PANEL_BASE_H
#include <sim/sim_preferences.h>
#include <sim/sim_types.h> #include <sim/sim_types.h>
#include <sim/spice_circuit_model.h> #include <sim/spice_circuit_model.h>
#include <wx/panel.h> #include <wx/panel.h>
@ -44,6 +45,8 @@ public:
virtual void OnLanguageChanged() = 0; virtual void OnLanguageChanged() = 0;
virtual void ApplyPreferences( const SIM_PREFERENCES& aPrefs );
SIM_TYPE GetSimType() const; SIM_TYPE GetSimType() const;
const wxString& GetSimCommand() const { return m_simCommand; } const wxString& GetSimCommand() const { return m_simCommand; }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2023 CERN * Copyright (C) 2016-2023 CERN
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
@ -272,6 +272,16 @@ void SIMULATOR_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
} }
void SIMULATOR_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
{
KIWAY_PLAYER::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
auto* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( m_toolManager->GetSettings() );
wxASSERT( cfg != nullptr );
m_ui->ApplyPreferences( cfg->m_Simulator.preferences );
}
WINDOW_SETTINGS* SIMULATOR_FRAME::GetWindowSettings( APP_SETTINGS_BASE* aCfg ) WINDOW_SETTINGS* SIMULATOR_FRAME::GetWindowSettings( APP_SETTINGS_BASE* aCfg )
{ {
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg ); EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2023 CERN * Copyright (C) 2016-2023 CERN
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
@ -162,6 +162,8 @@ public:
void SaveSettings( APP_SETTINGS_BASE* aCfg ) override; void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
WINDOW_SETTINGS* GetWindowSettings( APP_SETTINGS_BASE* aCfg ) override; WINDOW_SETTINGS* GetWindowSettings( APP_SETTINGS_BASE* aCfg ) override;
SCH_EDIT_FRAME* GetSchematicFrame() const { return m_schematicFrame; } SCH_EDIT_FRAME* GetSchematicFrame() const { return m_schematicFrame; }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2023 CERN * Copyright (C) 2016-2023 CERN
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
@ -605,24 +605,45 @@ void SIMULATOR_FRAME_UI::ShowChangedLanguage()
void SIMULATOR_FRAME_UI::LoadSettings( EESCHEMA_SETTINGS* aCfg ) void SIMULATOR_FRAME_UI::LoadSettings( EESCHEMA_SETTINGS* aCfg )
{ {
const EESCHEMA_SETTINGS::SIMULATOR& settings = aCfg->m_Simulator;
// Read subwindows sizes (should be > 0 ) // Read subwindows sizes (should be > 0 )
m_splitterLeftRightSashPosition = aCfg->m_Simulator.plot_panel_width; m_splitterLeftRightSashPosition = settings.view.plot_panel_width;
m_splitterPlotAndConsoleSashPosition = aCfg->m_Simulator.plot_panel_height; m_splitterPlotAndConsoleSashPosition = settings.view.plot_panel_height;
m_splitterSignalsSashPosition = aCfg->m_Simulator.signal_panel_height; m_splitterSignalsSashPosition = settings.view.signal_panel_height;
m_splitterCursorsSashPosition = aCfg->m_Simulator.cursors_panel_height; m_splitterCursorsSashPosition = settings.view.cursors_panel_height;
m_splitterTuneValuesSashPosition = aCfg->m_Simulator.measurements_panel_height; m_splitterTuneValuesSashPosition = settings.view.measurements_panel_height;
m_darkMode = !aCfg->m_Simulator.white_background; m_darkMode = !settings.view.white_background;
m_preferences = settings.preferences;
} }
void SIMULATOR_FRAME_UI::SaveSettings( EESCHEMA_SETTINGS* aCfg ) void SIMULATOR_FRAME_UI::SaveSettings( EESCHEMA_SETTINGS* aCfg )
{ {
aCfg->m_Simulator.plot_panel_width = m_splitterLeftRight->GetSashPosition(); EESCHEMA_SETTINGS::SIMULATOR& settings = aCfg->m_Simulator;
aCfg->m_Simulator.plot_panel_height = m_splitterPlotAndConsole->GetSashPosition();
aCfg->m_Simulator.signal_panel_height = m_splitterSignals->GetSashPosition(); settings.view.plot_panel_width = m_splitterLeftRight->GetSashPosition();
aCfg->m_Simulator.cursors_panel_height = m_splitterCursors->GetSashPosition(); settings.view.plot_panel_height = m_splitterPlotAndConsole->GetSashPosition();
aCfg->m_Simulator.measurements_panel_height = m_splitterMeasurements->GetSashPosition(); settings.view.signal_panel_height = m_splitterSignals->GetSashPosition();
aCfg->m_Simulator.white_background = !m_darkMode; settings.view.cursors_panel_height = m_splitterCursors->GetSashPosition();
settings.view.measurements_panel_height = m_splitterMeasurements->GetSashPosition();
settings.view.white_background = !m_darkMode;
}
void SIMULATOR_FRAME_UI::ApplyPreferences( const SIM_PREFERENCES& aPrefs )
{
m_preferences = aPrefs;
const std::size_t pageCount = m_plotNotebook->GetPageCount();
for( std::size_t i = 0; i<pageCount; ++i )
{
wxWindow* page = m_plotNotebook->GetPage( i );
auto simTab = dynamic_cast<SIM_TAB*>( page );
wxASSERT( simTab != nullptr );
simTab->ApplyPreferences( aPrefs );
}
} }
@ -943,9 +964,7 @@ SIM_TAB* SIMULATOR_FRAME_UI::NewSimTab( const wxString& aSimCommand )
{ {
SIM_PLOT_TAB* panel = new SIM_PLOT_TAB( aSimCommand, m_plotNotebook ); SIM_PLOT_TAB* panel = new SIM_PLOT_TAB( aSimCommand, m_plotNotebook );
simTab = panel; simTab = panel;
panel->ApplyPreferences( m_preferences );
COMMON_SETTINGS::INPUT cfg = Pgm().GetCommonSettings()->m_Input;
panel->GetPlotWin()->EnableMouseWheelPan( cfg.scroll_modifier_zoom != 0 );
} }
else else
{ {

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016-2023 CERN * Copyright (C) 2016-2023 CERN
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
@ -32,6 +32,7 @@
#include <sim/simulator_frame_ui_base.h> #include <sim/simulator_frame_ui_base.h>
#include <sim/sim_types.h> #include <sim/sim_types.h>
#include <sim/sim_plot_tab.h> #include <sim/sim_plot_tab.h>
#include <sim/sim_preferences.h>
#include <wx/event.h> #include <wx/event.h>
@ -185,6 +186,11 @@ public:
void SaveSettings( EESCHEMA_SETTINGS* aCfg ); void SaveSettings( EESCHEMA_SETTINGS* aCfg );
/**
* Called when settings are changed via the common Preferences dialog.
*/
void ApplyPreferences( const SIM_PREFERENCES& aPrefs );
// adjust the sash dimension of splitter windows after reading // adjust the sash dimension of splitter windows after reading
// the config settings // the config settings
// must be called after the config settings are read, and once the // must be called after the config settings are read, and once the
@ -342,6 +348,7 @@ private:
bool m_darkMode; bool m_darkMode;
unsigned int m_plotNumber; unsigned int m_plotNumber;
wxTimer m_refreshTimer; wxTimer m_refreshTimer;
SIM_PREFERENCES m_preferences;
}; };
#endif // SIMULATOR_FRAME_UI_H #endif // SIMULATOR_FRAME_UI_H

View File

@ -58,6 +58,10 @@ void SIMULATOR_FRAME::ReCreateHToolbar()
m_toolBar->AddScaledSeparator( this ); m_toolBar->AddScaledSeparator( this );
m_toolBar->Add( ACTIONS::zoomInCenter ); m_toolBar->Add( ACTIONS::zoomInCenter );
m_toolBar->Add( ACTIONS::zoomOutCenter ); m_toolBar->Add( ACTIONS::zoomOutCenter );
m_toolBar->Add( ACTIONS::zoomInHorizontally );
m_toolBar->Add( ACTIONS::zoomOutHorizontally );
m_toolBar->Add( ACTIONS::zoomInVertically );
m_toolBar->Add( ACTIONS::zoomOutVertically );
m_toolBar->Add( ACTIONS::zoomFitScreen ); m_toolBar->Add( ACTIONS::zoomFitScreen );
m_toolBar->AddScaledSeparator( this ); m_toolBar->AddScaledSeparator( this );
@ -117,6 +121,10 @@ void SIMULATOR_FRAME::doReCreateMenuBar()
viewMenu->AppendSeparator(); viewMenu->AppendSeparator();
viewMenu->Add( ACTIONS::zoomInCenter ); viewMenu->Add( ACTIONS::zoomInCenter );
viewMenu->Add( ACTIONS::zoomOutCenter ); viewMenu->Add( ACTIONS::zoomOutCenter );
viewMenu->Add( ACTIONS::zoomInHorizontally );
viewMenu->Add( ACTIONS::zoomOutHorizontally );
viewMenu->Add( ACTIONS::zoomInVertically );
viewMenu->Add( ACTIONS::zoomOutVertically );
viewMenu->Add( ACTIONS::zoomFitScreen ); viewMenu->Add( ACTIONS::zoomFitScreen );
viewMenu->AppendSeparator(); viewMenu->AppendSeparator();

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2023-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -248,18 +248,36 @@ int SIMULATOR_CONTROL::Zoom( const TOOL_EVENT& aEvent )
{ {
if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) ) if( SIM_PLOT_TAB* plotTab = dynamic_cast<SIM_PLOT_TAB*>( getCurrentSimTab() ) )
{ {
mpWindow* plot = plotTab->GetPlotWin();
if( aEvent.IsAction( &ACTIONS::zoomInCenter ) ) if( aEvent.IsAction( &ACTIONS::zoomInCenter ) )
{ {
plotTab->GetPlotWin()->ZoomIn(); plot->ZoomIn();
} }
else if( aEvent.IsAction( &ACTIONS::zoomOutCenter ) ) else if( aEvent.IsAction( &ACTIONS::zoomOutCenter ) )
{ {
plotTab->GetPlotWin()->ZoomOut(); plot->ZoomOut();
}
else if( aEvent.IsAction( &ACTIONS::zoomInHorizontally ) )
{
plot->ZoomIn( wxDefaultPosition, mpWindow::zoomIncrementalFactor, wxHORIZONTAL );
}
else if( aEvent.IsAction( &ACTIONS::zoomOutHorizontally ) )
{
plot->ZoomOut( wxDefaultPosition, mpWindow::zoomIncrementalFactor, wxHORIZONTAL );
}
else if( aEvent.IsAction( &ACTIONS::zoomInVertically ) )
{
plot->ZoomIn( wxDefaultPosition, mpWindow::zoomIncrementalFactor, wxVERTICAL );
}
else if( aEvent.IsAction( &ACTIONS::zoomOutVertically ) )
{
plot->ZoomOut( wxDefaultPosition, mpWindow::zoomIncrementalFactor, wxVERTICAL );
} }
else if( aEvent.IsAction( &ACTIONS::zoomFitScreen ) ) else if( aEvent.IsAction( &ACTIONS::zoomFitScreen ) )
{ {
wxCommandEvent dummy; wxCommandEvent dummy;
plotTab->GetPlotWin()->OnFit( dummy ); plot->OnFit( dummy );
} }
} }
@ -519,6 +537,10 @@ void SIMULATOR_CONTROL::setTransitions()
Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomInCenter.MakeEvent() ); Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomInCenter.MakeEvent() );
Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomOutCenter.MakeEvent() ); Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomOutCenter.MakeEvent() );
Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomInHorizontally.MakeEvent() );
Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomOutHorizontally.MakeEvent() );
Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomInVertically.MakeEvent() );
Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomOutVertically.MakeEvent() );
Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomFitScreen.MakeEvent() ); Go( &SIMULATOR_CONTROL::Zoom, ACTIONS::zoomFitScreen.MakeEvent() );
Go( &SIMULATOR_CONTROL::UndoZoom, ACTIONS::zoomUndo.MakeEvent() ); Go( &SIMULATOR_CONTROL::UndoZoom, ACTIONS::zoomUndo.MakeEvent() );
Go( &SIMULATOR_CONTROL::RedoZoom, ACTIONS::zoomRedo.MakeEvent() ); Go( &SIMULATOR_CONTROL::RedoZoom, ACTIONS::zoomRedo.MakeEvent() );

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2023-2024 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -28,6 +28,7 @@
#include <tool/tool_interactive.h> #include <tool/tool_interactive.h>
class SIMULATOR_FRAME; class SIMULATOR_FRAME;
class SCH_EDIT_FRAME;
class SPICE_CIRCUIT_MODEL; class SPICE_CIRCUIT_MODEL;
class SPICE_SIMULATOR; class SPICE_SIMULATOR;
class SIM_TAB; class SIM_TAB;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2007-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2007-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.TXT for contributors. * Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.TXT for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -653,6 +653,10 @@ enum class BITMAPS : unsigned int
zoom_fit_to_objects, zoom_fit_to_objects,
zoom_in, zoom_in,
zoom_out, zoom_out,
zoom_in_horizontally,
zoom_out_horizontally,
zoom_in_vertically,
zoom_out_vertically,
zoom_page, zoom_page,
zoom_selection, zoom_selection,
}; };

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2014 CERN * Copyright (C) 2014 CERN
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -80,6 +80,7 @@ enum FRAME_T
PANEL_SCH_ANNO_OPTIONS, PANEL_SCH_ANNO_OPTIONS,
PANEL_SCH_COLORS, PANEL_SCH_COLORS,
PANEL_SCH_FIELD_NAME_TEMPLATES, PANEL_SCH_FIELD_NAME_TEMPLATES,
PANEL_SCH_SIMULATOR,
PANEL_FP_DISPLAY_OPTIONS, PANEL_FP_DISPLAY_OPTIONS,
PANEL_FP_GRIDS, PANEL_FP_GRIDS,

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2013-2016 CERN * Copyright (C) 2013-2016 CERN
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -116,6 +116,10 @@ public:
static TOOL_ACTION zoomOut; static TOOL_ACTION zoomOut;
static TOOL_ACTION zoomInCenter; static TOOL_ACTION zoomInCenter;
static TOOL_ACTION zoomOutCenter; static TOOL_ACTION zoomOutCenter;
static TOOL_ACTION zoomInHorizontally;
static TOOL_ACTION zoomOutHorizontally;
static TOOL_ACTION zoomInVertically;
static TOOL_ACTION zoomOutVertically;
static TOOL_ACTION zoomCenter; static TOOL_ACTION zoomCenter;
static TOOL_ACTION zoomFitScreen; static TOOL_ACTION zoomFitScreen;
static TOOL_ACTION zoomFitObjects; // Zooms to bbox of items on screen (except page border) static TOOL_ACTION zoomFitObjects; // Zooms to bbox of items on screen (except page border)

View File

@ -7,7 +7,7 @@
// Created: 21/07/2003 // Created: 21/07/2003
// Last edit: 05/08/2016 // Last edit: 05/08/2016
// Copyright: (c) David Schalig, Davide Rondini // Copyright: (c) David Schalig, Davide Rondini
// Copyright (c) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors. // Copyright (c) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -905,6 +905,38 @@ typedef std::deque<mpLayer*> wxLayerList;
class WXDLLIMPEXP_MATHPLOT mpWindow : public wxWindow class WXDLLIMPEXP_MATHPLOT mpWindow : public wxWindow
{ {
public: public:
/**
* Enumerates the possible mouse wheel actions that can be performed on the plot.
*/
enum class MouseWheelAction
{
NONE,
PAN_LEFT_RIGHT,
PAN_RIGHT_LEFT,
PAN_UP_DOWN,
ZOOM,
ZOOM_HORIZONTALLY,
ZOOM_VERTICALLY,
COUNT // Internal use only
};
/**
* Contains the set of modified mouse wheel actions that can be performed on the plot.
*/
struct MouseWheelActionSet
{
/* If this bundled wxMathPlot implementation is to remain single-header and not dependent
* on any part of KiCad, then the SIM_MOUSE_WHEEL_ACTION_SET struct must be duplicated
* here. SIM_PLOT_TAB::convertMouseWheelActions is used to convert from
* SIM_MOUSE_WHEEL_ACTION_SET to mpWindow::MouseWheelActionSet. */
MouseWheelAction verticalUnmodified;
MouseWheelAction verticalWithCtrl;
MouseWheelAction verticalWithShift;
MouseWheelAction verticalWithAlt;
MouseWheelAction horizontal;
};
mpWindow(); mpWindow();
mpWindow( wxWindow* parent, wxWindowID id ); mpWindow( wxWindow* parent, wxWindowID id );
~mpWindow(); ~mpWindow();
@ -1068,9 +1100,8 @@ public:
*/ */
void EnableMousePanZoom( bool enabled ) { m_enableMouseNavigation = enabled; } void EnableMousePanZoom( bool enabled ) { m_enableMouseNavigation = enabled; }
/** Enable/disable trackpad friendly panning (2-axis scroll wheel) /** Set the pan/zoom actions corresponding to mousewheel/trackpad events. */
*/ void SetMouseWheelActions( const MouseWheelActionSet& s ) {m_mouseWheelActions = s;}
void EnableMouseWheelPan( bool enabled ) { m_enableMouseWheelPan = enabled; }
/** Set view to fit global bounding box of all plot layers and refresh display. /** Set view to fit global bounding box of all plot layers and refresh display.
* Scale and position will be set to show all attached mpLayers. * Scale and position will be set to show all attached mpLayers.
@ -1085,21 +1116,24 @@ public:
* as the "desired borders", since this use will be invoked only when printing. * as the "desired borders", since this use will be invoked only when printing.
*/ */
void Fit( double xMin, double xMax, double yMin, double yMax, void Fit( double xMin, double xMax, double yMin, double yMax,
const wxCoord* printSizeX = nullptr, const wxCoord* printSizeY = nullptr ); const wxCoord* printSizeX = nullptr, const wxCoord* printSizeY = nullptr,
wxOrientation directions = wxBOTH );
/** Zoom into current view and refresh display /** Zoom into current view and refresh display
* @param centerPoint The point (pixel coordinates) that will stay in the same * @param centerPoint The point (pixel coordinates) that will stay in the same
* position on the screen after the zoom (by default, the center of the mpWindow). * position on the screen after the zoom (by default, the center of the mpWindow).
*/ */
void ZoomIn( const wxPoint& centerPoint = wxDefaultPosition ); void ZoomIn( const wxPoint& centerPoint = wxDefaultPosition );
void ZoomIn( const wxPoint& centerPoint, double zoomFactor ); void ZoomIn( const wxPoint& centerPoint, double zoomFactor,
wxOrientation directions = wxBOTH );
/** Zoom out current view and refresh display /** Zoom out current view and refresh display
* @param centerPoint The point (pixel coordinates) that will stay in the same * @param centerPoint The point (pixel coordinates) that will stay in the same
* position on the screen after the zoom (by default, the center of the mpWindow). * position on the screen after the zoom (by default, the center of the mpWindow).
*/ */
void ZoomOut( const wxPoint& centerPoint = wxDefaultPosition ); void ZoomOut( const wxPoint& centerPoint = wxDefaultPosition );
void ZoomOut( const wxPoint& centerPoint, double zoomFactor ); void ZoomOut( const wxPoint& centerPoint, double zoomFactor,
wxOrientation directions = wxBOTH );
/** Zoom view fitting given coordinates to the window (p0 and p1 do not need to be in any specific order) /** Zoom view fitting given coordinates to the window (p0 and p1 do not need to be in any specific order)
*/ */
@ -1219,7 +1253,7 @@ public:
* @return reference to axis colour used in theme */ * @return reference to axis colour used in theme */
const wxColour& GetAxesColour() { return m_axColour; }; const wxColour& GetAxesColour() { return m_axColour; };
/** Limit zooming & panning to the area used by the plots */ /** Enable limiting of zooming & panning to the area used by the plots */
void LimitView( bool aEnable ) void LimitView( bool aEnable )
{ {
m_enableLimitedView = aEnable; m_enableLimitedView = aEnable;
@ -1233,12 +1267,15 @@ public:
int UndoZoomStackSize() const { return m_undoZoomStack.size(); } int UndoZoomStackSize() const { return m_undoZoomStack.size(); }
int RedoZoomStackSize() const { return m_redoZoomStack.size(); } int RedoZoomStackSize() const { return m_redoZoomStack.size(); }
void AdjustLimitedView(); /** Limits the zoomed or panned view to the area used by the plots. */
void AdjustLimitedView( wxOrientation directions = wxBOTH );
void OnFit( wxCommandEvent& event ); void OnFit( wxCommandEvent& event );
void OnCenter( wxCommandEvent& event ); void OnCenter( wxCommandEvent& event );
protected: protected:
static MouseWheelActionSet defaultMouseWheelActions();
void pushZoomUndo( const std::array<double, 4>& aZoom ); void pushZoomUndo( const std::array<double, 4>& aZoom );
void OnPaint( wxPaintEvent& event ); // !< Paint handler, will plot all attached layers void OnPaint( wxPaintEvent& event ); // !< Paint handler, will plot all attached layers
@ -1258,19 +1295,12 @@ protected:
void onMouseLeftDown( wxMouseEvent& event ); // !< Mouse left click (for rect zoom) void onMouseLeftDown( wxMouseEvent& event ); // !< Mouse left click (for rect zoom)
void onMouseLeftRelease( wxMouseEvent& event ); // !< Mouse left click (for rect zoom) void onMouseLeftRelease( wxMouseEvent& event ); // !< Mouse left click (for rect zoom)
bool CheckXLimits( double& desiredMax, double& desiredMin ) const void DoZoom( const wxPoint& centerPoint, double zoomFactor, wxOrientation directions );
{ void RecomputeDesiredX( double& min, double& max );
return !( m_enableLimitedView void RecomputeDesiredY( double& min, double& max );
&& (desiredMax > m_maxX - m_marginRight / m_scaleX wxOrientation ViewNeedsRefitting( wxOrientation directions ) const;
|| desiredMin < m_minX - m_marginLeft / m_scaleX) );
}
bool CheckYLimits( double& desiredMax, double& desiredMin ) const void PerformMouseWheelAction( wxMouseEvent& event, MouseWheelAction action );
{
return !( m_enableLimitedView
&& (desiredMax > m_maxY + m_marginTop / m_scaleY
|| desiredMin < m_minY - m_marginBottom / m_scaleY) );
}
/** Recalculate global layer bounding box, and save it in m_minX,... /** Recalculate global layer bounding box, and save it in m_minX,...
* \return true if there is any valid BBox information. * \return true if there is any valid BBox information.
@ -1309,11 +1339,19 @@ protected:
bool m_yLocked; bool m_yLocked;
/** These are updated in Fit() only, and may be different from the real borders /** These are updated in Fit, ZoomIn, ZoomOut, ZoomRect, SetXView, SetYView and may be different
* (layer coordinates) only if lock aspect ratio is true. * from the real borders (layer coordinates) only if lock aspect ratio is true.
*
* @note They use the plot area as their coordinate system, and not the layer coordinate
* system used by m_posX/Y.
*/ */
double m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax; double m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax;
// These are gaps between the curve extrema and the edges of the plot area, expressed as
// a factor of global layer bounding box width/height.
double m_topBottomPlotGapFactor;
double m_leftRightPlotGapFactor;
int m_marginTop, m_marginRight, m_marginBottom, m_marginLeft; int m_marginTop, m_marginRight, m_marginBottom, m_marginLeft;
int m_last_lx, m_last_ly; // !< For double buffering int m_last_lx, m_last_ly; // !< For double buffering
@ -1321,8 +1359,8 @@ protected:
wxBitmap* m_buff_bmp; // !< For double buffering wxBitmap* m_buff_bmp; // !< For double buffering
bool m_enableDoubleBuffer; // !< For double buffering bool m_enableDoubleBuffer; // !< For double buffering
bool m_enableMouseNavigation; // !< For pan/zoom with the mouse. bool m_enableMouseNavigation; // !< For pan/zoom with the mouse.
bool m_enableMouseWheelPan; // !< Trackpad pan/zoom
bool m_enableLimitedView; bool m_enableLimitedView;
MouseWheelActionSet m_mouseWheelActions;
wxPoint m_mouseMClick; // !< For the middle button "drag" feature wxPoint m_mouseMClick; // !< For the middle button "drag" feature
wxPoint m_mouseLClick; // !< Starting coords for rectangular zoom selection wxPoint m_mouseLClick; // !< Starting coords for rectangular zoom selection
mpInfoLayer* m_movingInfoLayer; // !< For moving info layers over the window area mpInfoLayer* m_movingInfoLayer; // !< For moving info layers over the window area
@ -1333,6 +1371,14 @@ protected:
DECLARE_DYNAMIC_CLASS( mpWindow ) DECLARE_DYNAMIC_CLASS( mpWindow )
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
private:
struct DelegatingContructorTag {};
template <typename... Ts>
mpWindow( DelegatingContructorTag, Ts&&... windowArgs );
void initializeGraphicsContext();
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 24 24"
version="1.1"
sodipodi:docname="zoom_in_horizontally.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1055"
id="namedview30"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="2.2679306"
inkscape:cy="11.120012"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>zoom_in</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160583">
<style
id="style160581">.cls-1{fill:#545454;}.cls-2{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160585">zoom_in</title>
<path
class="cls-1"
d="m 12.030079,17.085044 a 5.0417076,5.0427552 0 1 1 3.566044,-8.6077709 v 0 a 5.0402266,5.041274 0 0 1 -3.566044,8.6077709 z m 0,-9.1210729 a 4.0790482,4.0798958 0 1 0 2.886163,1.1933245 4.0685378,4.0693832 0 0 0 -2.886163,-1.1931334 z"
id="path160587"
style="fill:#ded3dd;fill-opacity:1;stroke-width:0.56030625;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
class="cls-1"
d="m 18.722544,19.333092 a 0.60055078,0.60055078 0 0 1 -0.42591,-0.17651 L 14.835681,15.69563 A 0.61229794,0.61229794 0 0 1 15.6875,14.84375 l 3.461014,3.460954 a 0.60241827,0.60241827 0 0 1 -0.42597,1.028388 z"
id="path160589"
style="fill:#ded3dd;stroke-width:0.56030625;fill-opacity:1"
inkscape:connector-curvature="0" />
<line
class="cls-2"
x1="10.070324"
y1="12.052376"
x2="13.989662"
y2="12.052376"
id="line160591"
style="fill:none;stroke:#ded3dd;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
<line
class="cls-2"
x1="12.031396"
y1="10.092473"
x2="12.031396"
y2="14.011817"
id="line160593"
style="fill:none;stroke:#ded3dd;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
<path
style="fill:#ded3dd;stroke-width:0.45214424;fill-opacity:1"
d="m 0.50000015,12 3.11398625,6.4965 v -4.048501 h 1.3846088 l 0.0014,-4.8800529 h -1.385992 l 0,-4.064446 z"
id="polygon27451"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#ded3dd;stroke-width:0.45214424;fill-opacity:1"
d="M 23.5,12 20.386014,5.5035001 v 4.048501 h -1.384609 l -0.0014,4.8800529 h 1.385987 V 18.4965 Z"
id="polygon27451-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 24 24"
version="1.1"
sodipodi:docname="zoom_in_vertically.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1055"
id="namedview30"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="-10.669569"
inkscape:cy="10.807512"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>zoom_in</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160583">
<style
id="style160581">.cls-1{fill:#545454;}.cls-2{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160585">zoom_in</title>
<path
class="cls-1"
d="m 12.030079,17.085044 a 5.0417076,5.0427552 0 1 1 3.566044,-8.6077709 v 0 a 5.0402266,5.041274 0 0 1 -3.566044,8.6077709 z m 0,-9.1210729 a 4.0790482,4.0798958 0 1 0 2.886163,1.1933245 4.0685378,4.0693832 0 0 0 -2.886163,-1.1931334 z"
id="path160587"
style="fill:#ded3dd;fill-opacity:1;stroke-width:0.56030625;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
class="cls-1"
d="m 18.722544,19.333092 a 0.60055078,0.60055078 0 0 1 -0.42591,-0.17651 L 14.835681,15.69563 A 0.61229794,0.61229794 0 0 1 15.6875,14.84375 l 3.461014,3.460954 a 0.60241827,0.60241827 0 0 1 -0.42597,1.028388 z"
id="path160589"
style="fill:#ded3dd;stroke-width:0.56030625;fill-opacity:1"
inkscape:connector-curvature="0" />
<line
class="cls-2"
x1="10.070324"
y1="12.052376"
x2="13.989662"
y2="12.052376"
id="line160591"
style="fill:none;stroke:#ded3dd;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
<line
class="cls-2"
x1="12.031396"
y1="10.092473"
x2="12.031396"
y2="14.011817"
id="line160593"
style="fill:none;stroke:#ded3dd;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
<path
style="fill:#ded3dd;stroke-width:0.45214424;fill-opacity:1"
d="M 12,0.5 5.5035003,3.6139863 H 9.552001 V 4.9985951 L 14.432054,5 V 3.614008 H 18.4965 Z"
id="polygon27451"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#ded3dd;stroke-width:0.45214424;fill-opacity:1"
d="m 12,23.5 6.4965,-3.113986 h -4.048501 v -1.384609 l -4.8800527,-0.0014 v 1.385987 h -4.064446 z"
id="polygon27451-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 24 24"
version="1.1"
sodipodi:docname="zoom_out_horizontally.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1055"
id="namedview30"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="1.0179306"
inkscape:cy="9.620012"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>zoom_in</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160583">
<style
id="style160581">.cls-1{fill:#545454;}.cls-2{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160585">zoom_in</title>
<path
class="cls-1"
d="m 12.030079,17.085044 a 5.0417076,5.0427552 0 1 1 3.566044,-8.6077709 v 0 a 5.0402266,5.041274 0 0 1 -3.566044,8.6077709 z m 0,-9.1210729 a 4.0790482,4.0798958 0 1 0 2.886163,1.1933245 4.0685378,4.0693832 0 0 0 -2.886163,-1.1931334 z"
id="path160587"
style="fill:#ded3dd;fill-opacity:1;stroke-width:0.56030625;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
class="cls-1"
d="m 18.722544,19.333092 a 0.60055078,0.60055078 0 0 1 -0.42591,-0.17651 L 14.835681,15.69563 A 0.61229794,0.61229794 0 0 1 15.6875,14.84375 l 3.461014,3.460954 a 0.60241827,0.60241827 0 0 1 -0.42597,1.028388 z"
id="path160589"
style="fill:#ded3dd;stroke-width:0.56030625;fill-opacity:1"
inkscape:connector-curvature="0" />
<line
class="cls-2"
x1="10.070324"
y1="12.052376"
x2="13.989662"
y2="12.052376"
id="line160591"
style="fill:none;stroke:#ded3dd;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
<path
style="fill:#ded3dd;stroke-width:0.45214424;fill-opacity:1"
d="m 4.9999952,12 -3.1139863,-6.4964999 0,4.048501 H 0.50140015 l -0.0014,4.8800529 H 1.8859921 l 0,4.064446 z"
id="polygon27451"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#ded3dd;stroke-width:0.45214424;fill-opacity:1"
d="m 19.000005,12 3.113986,6.4965 V 14.447999 H 23.4986 L 23.5,9.5679461 h -1.385987 l 0,-4.064446 z"
id="polygon27451-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 24 24"
version="1.1"
sodipodi:docname="zoom_out_vertically.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1055"
id="namedview30"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="-10.232069"
inkscape:cy="10.307512"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>zoom_in</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160583">
<style
id="style160581">.cls-1{fill:#545454;}.cls-2{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160585">zoom_in</title>
<path
class="cls-1"
d="m 12.030079,17.085044 a 5.0417076,5.0427552 0 1 1 3.566044,-8.6077709 v 0 a 5.0402266,5.041274 0 0 1 -3.566044,8.6077709 z m 0,-9.1210729 a 4.0790482,4.0798958 0 1 0 2.886163,1.1933245 4.0685378,4.0693832 0 0 0 -2.886163,-1.1931334 z"
id="path160587"
style="fill:#ded3dd;fill-opacity:1;stroke-width:0.56030625;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
class="cls-1"
d="m 18.722544,19.333092 a 0.60055078,0.60055078 0 0 1 -0.42591,-0.17651 L 14.835681,15.69563 A 0.61229794,0.61229794 0 0 1 15.6875,14.84375 l 3.461014,3.460954 a 0.60241827,0.60241827 0 0 1 -0.42597,1.028388 z"
id="path160589"
style="fill:#ded3dd;stroke-width:0.56030625;fill-opacity:1"
inkscape:connector-curvature="0" />
<line
class="cls-2"
x1="10.070324"
y1="12.052376"
x2="13.989662"
y2="12.052376"
id="line160591"
style="fill:none;stroke:#ded3dd;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
<path
style="fill:#ded3dd;stroke-width:0.45214424;fill-opacity:1"
d="m 12,19.000005 -6.4964999,3.113986 h 4.048501 V 23.4986 L 14.432054,23.5 V 22.114008 H 18.4965 Z"
id="polygon27451"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#ded3dd;stroke-width:0.45214424;fill-opacity:1"
d="m 12,4.9999951 6.4965,-3.113986 H 14.447999 V 0.50140012 l -4.8800529,-0.0014 V 1.8859871 h -4.064446 z"
id="polygon27451-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 24 24"
version="1.1"
sodipodi:docname="zoom_in_horizontally.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1055"
id="namedview30"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="1.3304306"
inkscape:cy="10.307512"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>zoom_in</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160583">
<style
id="style160581">.cls-1{fill:#545454;}.cls-2{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160585">zoom_in</title>
<path
class="cls-1"
d="m 12.030079,17.085044 a 5.0417076,5.0427552 0 1 1 3.566044,-8.6077709 v 0 a 5.0402266,5.041274 0 0 1 -3.566044,8.6077709 z m 0,-9.1210729 a 4.0790482,4.0798958 0 1 0 2.886163,1.1933245 4.0685378,4.0693832 0 0 0 -2.886163,-1.1931334 z"
id="path160587"
style="fill:#545454;fill-opacity:1;stroke-width:0.56030625;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
class="cls-1"
d="m 18.722544,19.333092 a 0.60055078,0.60055078 0 0 1 -0.42591,-0.17651 L 14.835681,15.69563 A 0.61229794,0.61229794 0 0 1 15.6875,14.84375 l 3.461014,3.460954 a 0.60241827,0.60241827 0 0 1 -0.42597,1.028388 z"
id="path160589"
style="fill:#545454;stroke-width:0.56030625"
inkscape:connector-curvature="0" />
<line
class="cls-2"
x1="10.070324"
y1="12.052376"
x2="13.989662"
y2="12.052376"
id="line160591"
style="fill:none;stroke:#545454;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round" />
<line
class="cls-2"
x1="12.031396"
y1="10.092473"
x2="12.031396"
y2="14.011817"
id="line160593"
style="fill:none;stroke:#545454;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round" />
<path
style="fill:#545454;stroke-width:0.45214424"
d="m 0.50000015,12 3.11398625,6.4965 v -4.048501 h 1.3846088 l 0.0014,-4.8800529 h -1.385992 l 0,-4.064446 z"
id="polygon27451"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#545454;stroke-width:0.45214424"
d="M 23.5,12 20.386014,5.5035001 v 4.048501 h -1.384609 l -0.0014,4.8800529 h 1.385987 V 18.4965 Z"
id="polygon27451-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 24 24"
version="1.1"
sodipodi:docname="zoom_out_vertically.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1055"
id="namedview30"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="0.89293055"
inkscape:cy="10.807512"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>zoom_in</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160583">
<style
id="style160581">.cls-1{fill:#545454;}.cls-2{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160585">zoom_in</title>
<path
class="cls-1"
d="m 12.030079,17.085044 a 5.0417076,5.0427552 0 1 1 3.566044,-8.6077709 v 0 a 5.0402266,5.041274 0 0 1 -3.566044,8.6077709 z m 0,-9.1210729 a 4.0790482,4.0798958 0 1 0 2.886163,1.1933245 4.0685378,4.0693832 0 0 0 -2.886163,-1.1931334 z"
id="path160587"
style="fill:#545454;fill-opacity:1;stroke-width:0.56030625;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
class="cls-1"
d="m 18.722544,19.333092 a 0.60055078,0.60055078 0 0 1 -0.42591,-0.17651 L 14.835681,15.69563 A 0.61229794,0.61229794 0 0 1 15.6875,14.84375 l 3.461014,3.460954 a 0.60241827,0.60241827 0 0 1 -0.42597,1.028388 z"
id="path160589"
style="fill:#545454;stroke-width:0.56030625"
inkscape:connector-curvature="0" />
<line
class="cls-2"
x1="10.070324"
y1="12.052376"
x2="13.989662"
y2="12.052376"
id="line160591"
style="fill:none;stroke:#545454;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round" />
<line
class="cls-2"
x1="12.031396"
y1="10.092473"
x2="12.031396"
y2="14.011817"
id="line160593"
style="fill:none;stroke:#545454;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round" />
<path
style="fill:#545454;stroke-width:0.45214424"
d="M 12,0.5 5.5035003,3.6139863 H 9.552001 V 4.9985951 L 14.432054,5 V 3.614008 H 18.4965 Z"
id="polygon27451"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#545454;stroke-width:0.45214424"
d="m 12,23.5 6.4965,-3.113986 h -4.048501 v -1.384609 l -4.8800527,-0.0014 v 1.385987 h -4.064446 z"
id="polygon27451-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 24 24"
version="1.1"
sodipodi:docname="zoom_out_horizontally.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1055"
id="namedview30"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="1.3304306"
inkscape:cy="10.307512"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>zoom_in</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160583">
<style
id="style160581">.cls-1{fill:#545454;}.cls-2{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160585">zoom_in</title>
<path
class="cls-1"
d="m 12.030079,17.085044 a 5.0417076,5.0427552 0 1 1 3.566044,-8.6077709 v 0 a 5.0402266,5.041274 0 0 1 -3.566044,8.6077709 z m 0,-9.1210729 a 4.0790482,4.0798958 0 1 0 2.886163,1.1933245 4.0685378,4.0693832 0 0 0 -2.886163,-1.1931334 z"
id="path160587"
style="fill:#545454;fill-opacity:1;stroke-width:0.56030625;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
class="cls-1"
d="m 18.722544,19.333092 a 0.60055078,0.60055078 0 0 1 -0.42591,-0.17651 L 14.835681,15.69563 A 0.61229794,0.61229794 0 0 1 15.6875,14.84375 l 3.461014,3.460954 a 0.60241827,0.60241827 0 0 1 -0.42597,1.028388 z"
id="path160589"
style="fill:#545454;stroke-width:0.56030625"
inkscape:connector-curvature="0" />
<line
class="cls-2"
x1="10.070324"
y1="12.052376"
x2="13.989662"
y2="12.052376"
id="line160591"
style="fill:none;stroke:#545454;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round" />
<path
style="fill:#545454;stroke-width:0.45214424"
d="m 4.9999952,12 -3.1139863,-6.4964999 0,4.048501 H 0.50140015 l -0.0014,4.8800529 H 1.8859921 l 0,4.064446 z"
id="polygon27451"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#545454;stroke-width:0.45214424"
d="m 19.000005,12 3.113986,6.4965 V 14.447999 H 23.4986 L 23.5,9.5679461 h -1.385987 l 0,-4.064446 z"
id="polygon27451-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 24 24"
version="1.1"
sodipodi:docname="zoom_out_vertically.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1055"
id="namedview30"
showgrid="true"
inkscape:zoom="16"
inkscape:cx="1.3304306"
inkscape:cy="10.307512"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>zoom_in</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160583">
<style
id="style160581">.cls-1{fill:#545454;}.cls-2{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160585">zoom_in</title>
<path
class="cls-1"
d="m 12.030079,17.085044 a 5.0417076,5.0427552 0 1 1 3.566044,-8.6077709 v 0 a 5.0402266,5.041274 0 0 1 -3.566044,8.6077709 z m 0,-9.1210729 a 4.0790482,4.0798958 0 1 0 2.886163,1.1933245 4.0685378,4.0693832 0 0 0 -2.886163,-1.1931334 z"
id="path160587"
style="fill:#545454;fill-opacity:1;stroke-width:0.56030625;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
class="cls-1"
d="m 18.722544,19.333092 a 0.60055078,0.60055078 0 0 1 -0.42591,-0.17651 L 14.835681,15.69563 A 0.61229794,0.61229794 0 0 1 15.6875,14.84375 l 3.461014,3.460954 a 0.60241827,0.60241827 0 0 1 -0.42597,1.028388 z"
id="path160589"
style="fill:#545454;stroke-width:0.56030625"
inkscape:connector-curvature="0" />
<line
class="cls-2"
x1="10.070324"
y1="12.052376"
x2="13.989662"
y2="12.052376"
id="line160591"
style="fill:none;stroke:#545454;stroke-width:1.1206125px;stroke-linecap:round;stroke-linejoin:round" />
<path
style="fill:#545454;stroke-width:0.45214424"
d="m 12,19.000005 -6.4964999,3.113986 h 4.048501 V 23.4986 L 14.432054,23.5 V 22.114008 H 18.4965 Z"
id="polygon27451"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#545454;stroke-width:0.45214424"
d="m 12,4.9999951 6.4965,-3.113986 H 14.447999 V 0.50140012 l -4.8800529,-0.0014 V 1.8859871 h -4.064446 z"
id="polygon27451-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB