From b04e54dbea53d2cfd750340918c744f5a7e09546 Mon Sep 17 00:00:00 2001
From: Ian McInerney <ian.s.mcinerney@ieee.org>
Date: Wed, 28 Sep 2022 02:15:19 +0100
Subject: [PATCH] Switch TOOL_EVENT and TOOL_ACTION to have a std::any
 parameter

Using std::any from C++17 allows for proper type handling in the
parameter field, removing the need for casting to void* and then casting
the void* to the desired type.
---
 3d-viewer/3d_viewer/tools/eda_3d_actions.cpp  | 540 ++++++++-----
 .../3d_viewer/tools/eda_3d_controller.cpp     |   4 +-
 common/tool/action_menu.cpp                   |   4 +-
 common/tool/actions.cpp                       | 268 ++++---
 common/tool/common_tools.cpp                  |  10 +-
 common/tool/grid_menu.cpp                     |   2 +-
 common/tool/tool_action.cpp                   |  27 +-
 common/tool/zoom_menu.cpp                     |   2 +-
 cvpcb/tools/cvpcb_actions.cpp                 |  97 +--
 cvpcb/tools/cvpcb_control.cpp                 |  14 +-
 eeschema/tools/ee_actions.cpp                 | 326 +++++---
 include/tool/tool_action.h                    |  43 +-
 include/tool/tool_event.h                     |  51 +-
 pagelayout_editor/tools/pl_actions.cpp        |  48 +-
 pcbnew/router/router_tool.cpp                 | 155 ++--
 pcbnew/tools/board_inspection_tool.cpp        |   6 +-
 pcbnew/tools/edit_tool.cpp                    |   2 +-
 pcbnew/tools/edit_tool_move_fct.cpp           |   2 +-
 pcbnew/tools/pcb_actions.cpp                  | 717 +++++++++++-------
 pcbnew/tools/pcb_selection_tool.cpp           |   2 +-
 pcbnew/tools/tool_event_utils.cpp             |   2 +-
 21 files changed, 1457 insertions(+), 865 deletions(-)

diff --git a/3d-viewer/3d_viewer/tools/eda_3d_actions.cpp b/3d-viewer/3d_viewer/tools/eda_3d_actions.cpp
index 3b5c74c0a5..11f9940134 100644
--- a/3d-viewer/3d_viewer/tools/eda_3d_actions.cpp
+++ b/3d-viewer/3d_viewer/tools/eda_3d_actions.cpp
@@ -23,6 +23,7 @@
 #include <3d_viewer_id.h>
 #include <3d_enums.h>
 #include "eda_3d_actions.h"
+#include "tool/tool_action.h"
 
 
 // Actions, being statically-defined, require specialized I18N handling.  We continue to
@@ -32,251 +33,386 @@
 #undef _
 #define _(s) s
 
+// No description, it is not supposed to be shown anywhere
+TOOL_ACTION EDA_3D_ACTIONS::controlActivate( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control" )
+        .Scope( AS_GLOBAL )
+        .Flags( AF_ACTIVATE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::controlActivate( "3DViewer.Control", AS_GLOBAL,
-        0, "", "", "",
-        BITMAPS::INVALID_BITMAP, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
+TOOL_ACTION EDA_3D_ACTIONS::pivotCenter( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.pivotCenter" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( ' ' )
+        .MenuText( _( "Center pivot rotation" ) )
+        .Tooltip( _( "Center pivot rotation (middle mouse click)" ) )
+        .Flags( AF_NONE )
+        .Parameter( WXK_SPACE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::pivotCenter( "3DViewer.Control.pivotCenter",
-        AS_ACTIVE,
-        ' ', "",
-        _( "Center pivot rotation" ), _( "Center pivot rotation (middle mouse click)" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) WXK_SPACE );
+TOOL_ACTION EDA_3D_ACTIONS::rotateXCW( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.rotateXclockwise" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Rotate X Clockwise" ) )
+        .Tooltip( _( "Rotate X Clockwise" ) )
+        .Icon( BITMAPS::rotate_cw_x )
+        .Flags( AF_NONE )
+        .Parameter( ROTATION_DIR::X_CW ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::rotateXCW( "3DViewer.Control.rotateXclockwise",
-        AS_GLOBAL, 0, "",
-        _( "Rotate X Clockwise" ), _( "Rotate X Clockwise" ),
-        BITMAPS::rotate_cw_x, AF_NONE, (void*) ROTATION_DIR::X_CW );
+TOOL_ACTION EDA_3D_ACTIONS::rotateXCCW( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.rotateXcounterclockwise" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Rotate X Counterclockwise" ) )
+        .Tooltip( _( "Rotate X Counterclockwise" ) )
+        .Icon( BITMAPS::rotate_ccw_x )
+        .Flags( AF_NONE )
+        .Parameter( ROTATION_DIR::X_CCW ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::rotateXCCW( "3DViewer.Control.rotateXcounterclockwise",
-        AS_GLOBAL, 0, "",
-        _( "Rotate X Counterclockwise" ), _( "Rotate X Counterclockwise" ),
-        BITMAPS::rotate_ccw_x, AF_NONE, (void*) ROTATION_DIR::X_CCW );
+TOOL_ACTION EDA_3D_ACTIONS::rotateYCW( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.rotateYclockwise" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Rotate Y Clockwise" ) )
+        .Tooltip( _( "Rotate Y Clockwise" ) )
+        .Icon( BITMAPS::rotate_cw_y )
+        .Flags( AF_NONE )
+        .Parameter( ROTATION_DIR::Y_CW ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::rotateYCW( "3DViewer.Control.rotateYclockwise",
-        AS_GLOBAL, 0, "",
-        _( "Rotate Y Clockwise" ), _( "Rotate Y Clockwise" ),
-        BITMAPS::rotate_cw_y, AF_NONE, (void*) ROTATION_DIR::Y_CW );
+TOOL_ACTION EDA_3D_ACTIONS::rotateYCCW( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.rotateYcounterclockwise" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Rotate Y Counterclockwise" ) )
+        .Tooltip( _( "Rotate Y Counterclockwise" ) )
+        .Icon( BITMAPS::rotate_ccw_y )
+        .Flags( AF_NONE )
+        .Parameter( ROTATION_DIR::Y_CCW ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::rotateYCCW( "3DViewer.Control.rotateYcounterclockwise",
-        AS_GLOBAL, 0, "",
-        _( "Rotate Y Counterclockwise" ), _( "Rotate Y Counterclockwise" ),
-        BITMAPS::rotate_ccw_y, AF_NONE, (void*) ROTATION_DIR::Y_CCW );
+TOOL_ACTION EDA_3D_ACTIONS::rotateZCW( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.rotateZclockwise" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Rotate Z Clockwise" ) )
+        .Tooltip( _( "Rotate Z Clockwise" ) )
+        .Icon( BITMAPS::rotate_cw_z )
+        .Flags( AF_NONE )
+        .Parameter( ROTATION_DIR::Z_CW ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::rotateZCW( "3DViewer.Control.rotateZclockwise",
-        AS_GLOBAL, 0, "",
-        _( "Rotate Z Clockwise" ), _( "Rotate Z Clockwise" ),
-        BITMAPS::rotate_cw_z, AF_NONE, (void*) ROTATION_DIR::Z_CW );
+TOOL_ACTION EDA_3D_ACTIONS::rotateZCCW( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.rotateZcounterclockwise" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Rotate Z Counterclockwise" ) )
+        .Tooltip( _( "Rotate Z Counterclockwise" ) )
+        .Icon( BITMAPS::rotate_ccw_z )
+        .Flags( AF_NONE )
+        .Parameter( ROTATION_DIR::Z_CCW ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::rotateZCCW( "3DViewer.Control.rotateZcounterclockwise",
-        AS_GLOBAL, 0, "",
-        _( "Rotate Z Counterclockwise" ), _( "Rotate Z Counterclockwise" ),
-        BITMAPS::rotate_ccw_z, AF_NONE, (void*) ROTATION_DIR::Z_CCW );
+TOOL_ACTION EDA_3D_ACTIONS::moveLeft( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.moveLeft" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( WXK_LEFT )
+        .MenuText( _( "Move board Left" ) )
+        .Tooltip( _( "Move board Left" ) )
+        .Icon( BITMAPS::left )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_LEFT ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::moveLeft( "3DViewer.Control.moveLeft",
-        AS_ACTIVE,
-        WXK_LEFT, "",
-        _( "Move board Left" ), _( "Move board Left" ),
-        BITMAPS::left, AF_NONE, (void*) CURSOR_LEFT );
+TOOL_ACTION EDA_3D_ACTIONS::moveRight( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.moveRight" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( WXK_RIGHT )
+        .MenuText( _( "Move board Right" ) )
+        .Tooltip( _( "Move board Right" ) )
+        .Icon( BITMAPS::right )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_RIGHT ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::moveRight( "3DViewer.Control.moveRight",
-        AS_ACTIVE,
-        WXK_RIGHT, "",
-        _( "Move board Right" ), _( "Move board Right" ),
-        BITMAPS::right, AF_NONE, (void*) CURSOR_RIGHT );
+TOOL_ACTION EDA_3D_ACTIONS::moveUp( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.moveUp" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( WXK_UP )
+        .MenuText( _( "Move board Up" ) )
+        .Tooltip( _( "Move board Up" ) )
+        .Icon( BITMAPS::up )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_UP ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::moveUp( "3DViewer.Control.moveUp",
-        AS_ACTIVE,
-        WXK_UP, "",
-        _( "Move board Up" ), _( "Move board Up" ),
-        BITMAPS::up, AF_NONE, (void*) CURSOR_UP );
+TOOL_ACTION EDA_3D_ACTIONS::moveDown( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.moveDown" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( WXK_DOWN )
+        .MenuText( _( "Move board Down" ) )
+        .Tooltip( _( "Move board Down" ) )
+        .Icon( BITMAPS::down )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_DOWN ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::moveDown( "3DViewer.Control.moveDown",
-        AS_ACTIVE,
-        WXK_DOWN, "",
-        _( "Move board Down" ), _( "Move board Down" ),
-        BITMAPS::down, AF_NONE, (void*) CURSOR_DOWN );
+TOOL_ACTION EDA_3D_ACTIONS::homeView( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.homeView" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( WXK_HOME )
+        .MenuText ( _( "Home view" ) )
+        .Tooltip( _( "Home view" ) )
+        .Flags( AF_NONE )
+        .Parameter( WXK_HOME ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::homeView( "3DViewer.Control.homeView",
-        AS_ACTIVE,
-        WXK_HOME, "",
-        _( "Home view" ), _( "Home view" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) WXK_HOME );
+TOOL_ACTION EDA_3D_ACTIONS::resetView( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.resetView" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'R' )
+        .MenuText( _( "Reset view" ) )
+        .Tooltip( _( "Reset view" ) )
+        .Flags( AF_NONE )
+        .Parameter( ID_VIEW3D_RESET ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::resetView( "3DViewer.Control.resetView",
-        AS_ACTIVE,
-        'R', "",
-        _( "Reset view" ), _( "Reset view" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ID_VIEW3D_RESET );
+TOOL_ACTION EDA_3D_ACTIONS::flipView( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.flipView" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'F' )
+        .MenuText( _( "Flip Board" ) )
+        .Tooltip( _( "Flip the board view" ) )
+        .Icon( BITMAPS::flip_board )
+        .Flags( AF_NONE )
+        .Parameter( ID_VIEW3D_FLIP ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::flipView( "3DViewer.Control.flipView",
-        AS_ACTIVE,
-        'F', "",
-        _( "Flip Board" ), _( "Flip the board view" ),
-        BITMAPS::flip_board, AF_NONE, (void*) ID_VIEW3D_FLIP );
+TOOL_ACTION EDA_3D_ACTIONS::toggleOrtho( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleOrtho" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle orthographic projection" ) )
+        .Tooltip( _( "Enable/disable orthographic projection" ) )
+        .Icon( BITMAPS::ortho ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleOrtho( "3DViewer.Control.toggleOrtho",
-        AS_GLOBAL, 0, "",
-        _( "Toggle orthographic projection" ), _( "Enable/disable orthographic projection" ),
-        BITMAPS::ortho );
+TOOL_ACTION EDA_3D_ACTIONS::viewFront( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.viewFront" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'Y' )
+        .MenuText( _( "View Front" ) )
+        .Tooltip( _( "View Front" ) )
+        .Icon( BITMAPS::axis3d_front )
+        .Flags( AF_NONE )
+        .Parameter( ID_VIEW3D_FRONT ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::viewFront( "3DViewer.Control.viewFront",
-        AS_ACTIVE,
-        'Y', "",
-        _( "View Front" ), _( "View Front" ),
-        BITMAPS::axis3d_front, AF_NONE, (void*) ID_VIEW3D_FRONT );
+TOOL_ACTION EDA_3D_ACTIONS::viewBack( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.viewBack" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( MD_SHIFT + 'Y' )
+        .MenuText( _( "View Back" ) )
+        .Tooltip( _( "View Back" ) )
+        .Icon( BITMAPS::axis3d_back )
+        .Flags( AF_NONE )
+        .Parameter( ID_VIEW3D_BACK ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::viewBack( "3DViewer.Control.viewBack",
-        AS_ACTIVE,
-        MD_SHIFT + 'Y', "",
-        _( "View Back" ), _( "View Back" ),
-        BITMAPS::axis3d_back, AF_NONE, (void*) ID_VIEW3D_BACK );
+TOOL_ACTION EDA_3D_ACTIONS::viewLeft( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.viewLeft" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( MD_SHIFT + 'X' )
+        .MenuText( _( "View Left" ) )
+        .Tooltip( _( "View Left" ) )
+        .Icon( BITMAPS::axis3d_left )
+        .Flags( AF_NONE )
+        .Parameter( ID_VIEW3D_LEFT ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::viewLeft( "3DViewer.Control.viewLeft",
-        AS_ACTIVE,
-        MD_SHIFT + 'X', "",
-        _( "View Left" ), _( "View Left" ),
-        BITMAPS::axis3d_left, AF_NONE, (void*) ID_VIEW3D_LEFT );
+TOOL_ACTION EDA_3D_ACTIONS::viewRight( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.viewRight" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'X' )
+        .MenuText( _( "View Right" ) )
+        .Tooltip( _( "View Right" ) )
+        .Icon( BITMAPS::axis3d_right )
+        .Flags( AF_NONE )
+        .Parameter( ID_VIEW3D_RIGHT ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::viewRight( "3DViewer.Control.viewRight",
-        AS_ACTIVE,
-        'X', "",
-        _( "View Right" ), _( "View Right" ),
-        BITMAPS::axis3d_right, AF_NONE, (void*) ID_VIEW3D_RIGHT );
+TOOL_ACTION EDA_3D_ACTIONS::viewTop( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.viewTop" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'Z' )
+        .MenuText( _( "View Top" ) )
+        .Tooltip( _( "View Top" ) )
+        .Icon( BITMAPS::axis3d_top )
+        .Flags( AF_NONE )
+        .Parameter( ID_VIEW3D_TOP ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::viewTop( "3DViewer.Control.viewTop",
-        AS_ACTIVE,
-        'Z', "",
-        _( "View Top" ), _( "View Top" ),
-        BITMAPS::axis3d_top, AF_NONE, (void*) ID_VIEW3D_TOP );
+TOOL_ACTION EDA_3D_ACTIONS::viewBottom( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.viewBottom" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( MD_SHIFT + 'Z' )
+        .MenuText( _( "View Bottom" ) )
+        .Tooltip( _( "View Bottom" ) )
+        .Icon( BITMAPS::axis3d_bottom )
+        .Flags( AF_NONE )
+        .Parameter( ID_VIEW3D_BOTTOM ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::viewBottom( "3DViewer.Control.viewBottom",
-        AS_ACTIVE,
-        MD_SHIFT + 'Z', "",
-        _( "View Bottom" ), _( "View Bottom" ),
-        BITMAPS::axis3d_bottom, AF_NONE, (void*) ID_VIEW3D_BOTTOM );
+TOOL_ACTION EDA_3D_ACTIONS::noGrid( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.noGrid" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "No 3D Grid" ) )
+        .Tooltip( _( "No 3D Grid" ) )
+        .Flags( AF_NONE )
+        .Parameter( GRID3D_TYPE::NONE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::noGrid( "3DViewer.Control.noGrid",
-        AS_GLOBAL, 0, "",
-        _( "No 3D Grid" ), _( "No 3D Grid" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::NONE );
+TOOL_ACTION EDA_3D_ACTIONS::show10mmGrid( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.show10mmGrid" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "3D Grid 10mm" ) )
+        .Tooltip( _( "3D Grid 10mm" ) )
+        .Flags( AF_NONE )
+        .Parameter( GRID3D_TYPE::GRID_10MM ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::show10mmGrid( "3DViewer.Control.show10mmGrid",
-        AS_GLOBAL, 0, "",
-        _( "3D Grid 10mm" ), _( "3D Grid 10mm" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_10MM );
+TOOL_ACTION EDA_3D_ACTIONS::show5mmGrid( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.show5mmGrid" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "3D Grid 5mm" ) )
+        .Tooltip( _( "3D Grid 5mm" ) )
+        .Flags( AF_NONE )
+        .Parameter( GRID3D_TYPE::GRID_5MM ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::show5mmGrid( "3DViewer.Control.show5mmGrid",
-        AS_GLOBAL, 0, "",
-        _( "3D Grid 5mm" ), _( "3D Grid 5mm" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_5MM );
+TOOL_ACTION EDA_3D_ACTIONS::show2_5mmGrid( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.show2_5mmGrid" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "3D Grid 2.5mm" ) )
+        .Tooltip( _( "3D Grid 2.5mm" ) )
+        .Flags( AF_NONE )
+        .Parameter( GRID3D_TYPE::GRID_2P5MM ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::show2_5mmGrid( "3DViewer.Control.show2_5mmGrid",
-        AS_GLOBAL, 0, "",
-        _( "3D Grid 2.5mm" ), _( "3D Grid 2.5mm" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_2P5MM );
+TOOL_ACTION EDA_3D_ACTIONS::show1mmGrid( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.show1mmGrid" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "3D Grid 1mm" ) )
+        .Tooltip( _( "3D Grid 1mm" ) )
+        .Flags( AF_NONE )
+        .Parameter( GRID3D_TYPE::GRID_1MM ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::show1mmGrid( "3DViewer.Control.show1mmGrid",
-        AS_GLOBAL, 0, "",
-        _( "3D Grid 1mm" ), _( "3D Grid 1mm" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) GRID3D_TYPE::GRID_1MM );
+TOOL_ACTION EDA_3D_ACTIONS::materialNormal( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.materialNormal" )
+        .Scope( AS_ACTIVE )
+        .MenuText( _( "Render Realistic Materials" ) )
+        .Tooltip( _( "Use all material properties from each 3D model file" ) )
+        .Flags( AF_NONE )
+        .Parameter( MATERIAL_MODE::NORMAL ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::materialNormal( "3DViewer.Control.materialNormal",
-        AS_ACTIVE,
-        0, "",
-        _( "Render Realistic Materials" ),
-        _( "Use all material properties from each 3D model file" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::NORMAL );
+TOOL_ACTION EDA_3D_ACTIONS::materialDiffuse( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.materialDiffuse" )
+        .Scope( AS_ACTIVE )
+        .MenuText( _( "Render Solid Colors" ) )
+        .Tooltip( _( "Use only the diffuse color property from model 3D model file" ) )
+        .Flags( AF_NONE )
+        .Parameter( MATERIAL_MODE::DIFFUSE_ONLY ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::materialDiffuse( "3DViewer.Control.materialDiffuse",
-        AS_ACTIVE,
-        0, "",
-        _( "Render Solid Colors" ),
-        _( "Use only the diffuse color property from 3D model file" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::DIFFUSE_ONLY );
+TOOL_ACTION EDA_3D_ACTIONS::materialCAD( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.materialCAD" )
+        .Scope( AS_ACTIVE )
+        .MenuText( _( "Render CAD Colors" ) )
+        .Tooltip( _( "Use a CAD color style based on the diffuse color of the material" ) )
+        .Flags( AF_NONE )
+        .Parameter( MATERIAL_MODE::CAD_MODE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::materialCAD( "3DViewer.Control.materialCAD",
-        AS_ACTIVE,
-        0, "",
-        _( "Render CAD Colors" ),
-        _( "Use a CAD color style based on the diffuse color of the material" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) MATERIAL_MODE::CAD_MODE );
+TOOL_ACTION EDA_3D_ACTIONS::showTHT( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.attributesTHT" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'T' )
+        .MenuText( _( "Toggle Through Hole 3D models" ) )
+        .Tooltip( _( "Toggle 3D models for 'Through hole' type components" ) )
+        .Icon( BITMAPS::show_tht )
+        .Flags( AF_NONE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::showTHT( "3DViewer.Control.attributesTHT",
-        AS_ACTIVE,
-        'T', "",
-        _( "Toggle Through Hole 3D models" ),
-        _( "Toggle 3D models for 'Through hole' type components" ),
-        BITMAPS::show_tht, AF_NONE );
+TOOL_ACTION EDA_3D_ACTIONS::showSMD( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.attributesSMD" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'S' )
+        .MenuText( _( "Toggle SMD 3D models" ) )
+        .Tooltip( _( "Toggle 3D models for 'Surface mount' type components" ) )
+        .Icon( BITMAPS::show_smt )
+        .Flags( AF_NONE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::showSMD( "3DViewer.Control.attributesSMD",
-        AS_ACTIVE,
-        'S', "",
-        _( "Toggle SMD 3D models" ),
-        _( "Toggle 3D models for 'Surface mount' type components" ),
-        BITMAPS::show_smt, AF_NONE );
+TOOL_ACTION EDA_3D_ACTIONS::showVirtual( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.attributesOther" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'V' )
+        .MenuText( _( "Toggle unspecified 3D models" ) )
+        .Tooltip( _( "Toggle 3D models for 'unspecified' type components" ) )
+        .Icon( BITMAPS::show_other )
+        .Flags( AF_NONE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::showVirtual( "3DViewer.Control.attributesOther",
-        AS_ACTIVE,
-        'V', "",
-        _( "Toggle unspecified 3D models" ), _( "Toggle 3D models for 'unspecified' type components" ),
-        BITMAPS::show_other, AF_NONE );
+TOOL_ACTION EDA_3D_ACTIONS::showNotInPosFile( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.attribute_not_in_posfile" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'P' )
+        .MenuText( _( "Toggle 3D models not in pos file" ) )
+        .Tooltip( _( "Toggle 3D models not in pos file" ) )
+        .Icon( BITMAPS::show_not_in_posfile )
+        .Flags( AF_NONE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::showNotInPosFile( "3DViewer.Control.attribute_not_in_posfile",
-        AS_ACTIVE,
-        'P', "",
-        _( "Toggle 3D models not in pos file" ), _( "Toggle 3D models not in pos file" ),
-        BITMAPS::show_not_in_posfile, AF_NONE );
+TOOL_ACTION EDA_3D_ACTIONS::showDNP( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.attribute_dnp" )
+        .Scope( AS_ACTIVE )
+        .DefaultHotkey( 'D' )
+        .MenuText( _( "Toggle 3D models marked DNP" ) )
+        .Tooltip( _( "Toggle 3D models for components marked 'Do Not Place'" ) )
+        .Icon( BITMAPS::show_dnp )
+        .Flags( AF_NONE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::showDNP( "3DViewer.Control.attribute_dnp",
-        AS_ACTIVE,
-        'D', "",
-        _( "Toggle 3D models marked DNP" ), _( "Toggle 3D models for components marked 'Do Not Place'" ),
-        BITMAPS::show_dnp, AF_NONE );
+TOOL_ACTION EDA_3D_ACTIONS::showBBoxes( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.showBoundingBoxes" )
+         .Scope( AS_GLOBAL )
+         .MenuText( _( "Show Model Bounding Boxes" ) )
+         .Tooltip( _( "Show Model Bounding Boxes" ) )
+         .Icon( BITMAPS::ortho )
+         .Flags( AF_NONE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::showBBoxes( "3DViewer.Control.showBoundingBoxes",
-         AS_GLOBAL, 0, "",
-         _( "Show Model Bounding Boxes" ), _( "Show Model Bounding Boxes" ),
-         BITMAPS::ortho, AF_NONE );
+TOOL_ACTION EDA_3D_ACTIONS::toggleRealisticMode( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleRealisticMode" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle realistic mode" ) )
+        .Tooltip( _( "Toggle realistic mode" ) ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleRealisticMode( "3DViewer.Control.toggleRealisticMode",
-        AS_GLOBAL, 0, "",
-        _( "Toggle realistic mode" ), _( "Toggle realistic mode" ) );
+TOOL_ACTION EDA_3D_ACTIONS::toggleBoardBody( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleBoardBody" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle board body display" ) )
+        .Tooltip( _( "Toggle board body display" ) ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleBoardBody( "3DViewer.Control.toggleBoardBody",
-        AS_GLOBAL, 0, "",
-        _( "Toggle board body display" ), _( "Toggle board body display" ) );
+TOOL_ACTION EDA_3D_ACTIONS::showAxis( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.showAxis" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Show 3D Axis" ) )
+        .Tooltip( _( "Show 3D Axis" ) )
+        .Icon( BITMAPS::axis3d_front )
+        .Flags( AF_NONE ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::showAxis( "3DViewer.Control.showAxis",
-        AS_GLOBAL, 0, "",
-        _( "Show 3D Axis" ), _( "Show 3D Axis" ),
-        BITMAPS::axis3d_front, AF_NONE );
+TOOL_ACTION EDA_3D_ACTIONS::toggleZones( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleZones" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle zone display" ) )
+        .Tooltip( _( "Toggle zone display" ) ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleZones( "3DViewer.Control.toggleZones",
-        AS_GLOBAL, 0, "",
-        _( "Toggle zone display" ), _( "Toggle zone display" ) );
+TOOL_ACTION EDA_3D_ACTIONS::toggleAdhesive( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleAdhesive" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle adhesive display" ) )
+        .Tooltip( _( "Toggle display of adhesive layers" ) ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleAdhesive( "3DViewer.Control.toggleAdhesive",
-        AS_GLOBAL, 0, "",
-        _( "Toggle adhesive display" ), _( "Toggle display of adhesive layers" ) );
+TOOL_ACTION EDA_3D_ACTIONS::toggleSilk( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleSilk" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle silkscreen display" ) )
+        .Tooltip( _( "Toggle display of silkscreen layers" ) ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleSilk( "3DViewer.Control.toggleSilk",
-        AS_GLOBAL, 0, "",
-        _( "Toggle silkscreen display" ), _( "Toggle display of silkscreen layers" ) );
+TOOL_ACTION EDA_3D_ACTIONS::toggleSolderMask( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleSolderMask" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle solder mask display" ) )
+        .Tooltip( _( "Toggle display of solder mask layers" ) ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleSolderMask( "3DViewer.Control.toggleSolderMask",
-        AS_GLOBAL, 0, "",
-        _( "Toggle solder mask display" ), _( "Toggle display of solder mask layers" ) );
+TOOL_ACTION EDA_3D_ACTIONS::toggleSolderPaste( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleSolderPaste" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle solder paste display" ) )
+        .Tooltip( _( "Toggle display of solder paste layers" ) ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleSolderPaste( "3DViewer.Control.toggleSolderPaste",
-        AS_GLOBAL, 0, "",
-        _( "Toggle solder paste display" ), _( "Toggle display of solder paste layers" ) );
+TOOL_ACTION EDA_3D_ACTIONS::toggleComments( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleComments" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle comments display" ) )
+        .Tooltip( _( "Toggle display of comments and drawings layers" ) ) );
 
-TOOL_ACTION EDA_3D_ACTIONS::toggleComments( "3DViewer.Control.toggleComments",
-        AS_GLOBAL, 0, "",
-        _( "Toggle comments display" ), _( "Toggle display of comments and drawings layers" ) );
-
-TOOL_ACTION EDA_3D_ACTIONS::toggleECO( "3DViewer.Control.toggleECO",
-        AS_GLOBAL, 0, "",
-        _( "Toggle ECO display" ), _( "Toggle display of ECO layers" ) );
+TOOL_ACTION EDA_3D_ACTIONS::toggleECO( TOOL_ACTION_ARGS()
+        .Name( "3DViewer.Control.toggleECO" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Toggle ECO display" ) )
+        .Tooltip( _( "Toggle display of ECO layers" ) ) );
 
diff --git a/3d-viewer/3d_viewer/tools/eda_3d_controller.cpp b/3d-viewer/3d_viewer/tools/eda_3d_controller.cpp
index 73870c94ab..65b7c6964e 100644
--- a/3d-viewer/3d_viewer/tools/eda_3d_controller.cpp
+++ b/3d-viewer/3d_viewer/tools/eda_3d_controller.cpp
@@ -152,7 +152,7 @@ int EDA_3D_CONTROLLER::Main( const TOOL_EVENT& aEvent )
 
 int EDA_3D_CONTROLLER::ViewControl( const TOOL_EVENT& aEvent )
 {
-    m_canvas->SetView3D( aEvent.Parameter<intptr_t>() );
+    m_canvas->SetView3D( aEvent.Parameter<int>() );
 
     return 0;
 }
@@ -160,7 +160,7 @@ int EDA_3D_CONTROLLER::ViewControl( const TOOL_EVENT& aEvent )
 
 int EDA_3D_CONTROLLER::PanControl( const TOOL_EVENT& aEvent )
 {
-    switch( aEvent.Parameter<intptr_t>() )
+    switch( aEvent.Parameter<ACTIONS::CURSOR_EVENT_TYPE>() )
     {
     case ACTIONS::CURSOR_UP:    m_canvas->SetView3D( WXK_UP );    break;
     case ACTIONS::CURSOR_DOWN:  m_canvas->SetView3D( WXK_DOWN );  break;
diff --git a/common/tool/action_menu.cpp b/common/tool/action_menu.cpp
index de60c3a360..6b77d32079 100644
--- a/common/tool/action_menu.cpp
+++ b/common/tool/action_menu.cpp
@@ -527,8 +527,8 @@ void ACTION_MENU::OnMenuEvent( wxMenuEvent& aEvent )
                 else
                     menuText = GetLabelText( aEvent.GetId() );
 
-                evt = TOOL_EVENT( TC_COMMAND, TA_CHOICE_MENU_CHOICE, m_selected, AS_GLOBAL,
-                                  &menuText );
+                evt = TOOL_EVENT( TC_COMMAND, TA_CHOICE_MENU_CHOICE, m_selected, AS_GLOBAL );
+                evt->SetParameter( &menuText );
             }
         }
     }
diff --git a/common/tool/actions.cpp b/common/tool/actions.cpp
index f2ec2d07b8..97ce0e8e89 100644
--- a/common/tool/actions.cpp
+++ b/common/tool/actions.cpp
@@ -121,11 +121,13 @@ TOOL_ACTION ACTIONS::cancelInteractive( "common.Interactive.cancel",
         _( "Cancel" ), _( "Cancel current tool" ),
         BITMAPS::cancel, AF_NONE );
 
-TOOL_ACTION ACTIONS::showContextMenu( "common.Control.showContextMenu",
-        AS_GLOBAL,
-        0, "",
-        _( "Show Context Menu" ), _( "Perform the right-mouse-button action" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_RIGHT_CLICK );
+TOOL_ACTION ACTIONS::showContextMenu( TOOL_ACTION_ARGS()
+        .Name( "common.Control.showContextMenu" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Show Context Menu" ) )
+        .Tooltip( _( "Perform the right-mouse-button action" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_RIGHT_CLICK ) );
 
 TOOL_ACTION ACTIONS::updateMenu( "common.Interactive.updateMenu",
         AS_GLOBAL );
@@ -375,66 +377,90 @@ TOOL_ACTION ACTIONS::centerContents( "common.Control.centerContents",
         AS_GLOBAL );
 
 // Cursor control
-TOOL_ACTION ACTIONS::cursorUp( "common.Control.cursorUp",
-        AS_GLOBAL,
-        WXK_UP, "",
-        _( "Cursor Up" ), "",
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_UP );
+TOOL_ACTION ACTIONS::cursorUp( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorUp" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_UP )
+        .MenuText( _( "Cursor Up" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_UP ) );
 
-TOOL_ACTION ACTIONS::cursorDown( "common.Control.cursorDown",
-        AS_GLOBAL,
-        WXK_DOWN, "",
-        _( "Cursor Down" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_DOWN );
+TOOL_ACTION ACTIONS::cursorDown( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorDown" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_DOWN )
+        .MenuText( _( "Cursor Down" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_DOWN ) );
 
-TOOL_ACTION ACTIONS::cursorLeft( "common.Control.cursorLeft",
-        AS_GLOBAL,
-        WXK_LEFT, "",
-        _( "Cursor Left" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_LEFT );
+TOOL_ACTION ACTIONS::cursorLeft( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorLeft" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_LEFT )
+        .MenuText( _( "Cursor Left" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_LEFT ) );
 
-TOOL_ACTION ACTIONS::cursorRight( "common.Control.cursorRight",
-        AS_GLOBAL,
-        WXK_RIGHT, "",
-        _( "Cursor Right" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_RIGHT );
+TOOL_ACTION ACTIONS::cursorRight( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorRight" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_RIGHT )
+        .MenuText( _( "Cursor Right" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_RIGHT ) );
 
 
-TOOL_ACTION ACTIONS::cursorUpFast( "common.Control.cursorUpFast",
-        AS_GLOBAL,
-        MD_CTRL + WXK_UP, "",
-        _( "Cursor Up Fast" ), "",
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ( CURSOR_UP | CURSOR_FAST_MOVE ) );
+TOOL_ACTION ACTIONS::cursorUpFast( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorUpFast" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_CTRL + WXK_UP )
+        .MenuText( _( "Cursor Up Fast" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_UP | CURSOR_FAST_MOVE ) );
 
-TOOL_ACTION ACTIONS::cursorDownFast( "common.Control.cursorDownFast",
-        AS_GLOBAL,
-        MD_CTRL + WXK_DOWN, "",
-        _( "Cursor Down Fast" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ( CURSOR_DOWN | CURSOR_FAST_MOVE ) );
+TOOL_ACTION ACTIONS::cursorDownFast( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorDownFast" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_CTRL + WXK_DOWN )
+        .MenuText( _( "Cursor Down Fast" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_DOWN | CURSOR_FAST_MOVE ) );
 
-TOOL_ACTION ACTIONS::cursorLeftFast( "common.Control.cursorLeftFast",
-        AS_GLOBAL,
-        MD_CTRL + WXK_LEFT, "",
-        _( "Cursor Left Fast" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ( CURSOR_LEFT | CURSOR_FAST_MOVE ) );
+TOOL_ACTION ACTIONS::cursorLeftFast( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorLeftFast" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_CTRL + WXK_LEFT )
+        .MenuText( _( "Cursor Left Fast" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_LEFT | CURSOR_FAST_MOVE ) );
 
-TOOL_ACTION ACTIONS::cursorRightFast( "common.Control.cursorRightFast",
-        AS_GLOBAL,
-        MD_CTRL + WXK_RIGHT, "",
-        _( "Cursor Right Fast" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ( CURSOR_RIGHT | CURSOR_FAST_MOVE ) );
+TOOL_ACTION ACTIONS::cursorRightFast( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorRightFast" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_CTRL + WXK_RIGHT )
+        .MenuText( _( "Cursor Right Fast" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_RIGHT | CURSOR_FAST_MOVE ) );
 
-TOOL_ACTION ACTIONS::cursorClick( "common.Control.cursorClick",
-        AS_GLOBAL,
-        WXK_RETURN, LEGACY_HK_NAME( "Mouse Left Click" ),
-        _( "Click" ), _( "Performs left mouse button click" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_CLICK );
+TOOL_ACTION ACTIONS::cursorClick( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorClick" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_RETURN )
+        .LegacyHotkeyName( "Mouse Left Click" )
+        .MenuText( _( "Click" ) )
+        .Tooltip( _( "Performs left mouse button click" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_CLICK ) );
 
-TOOL_ACTION ACTIONS::cursorDblClick( "common.Control.cursorDblClick",
-        AS_GLOBAL,
-        WXK_END, LEGACY_HK_NAME( "Mouse Left Double Click" ),
-        _( "Double-click" ), _( "Performs left mouse button double-click" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_DBL_CLICK );
+TOOL_ACTION ACTIONS::cursorDblClick( TOOL_ACTION_ARGS()
+        .Name( "common.Control.cursorDblClick" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_END )
+        .LegacyHotkeyName( "Mouse Left Double Click" )
+        .MenuText( _( "Double-click" ) )
+        .Tooltip( _( "Performs left mouse button double-click" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_DBL_CLICK ) );
 
 TOOL_ACTION ACTIONS::refreshPreview( "common.Control.refreshPreview",
         AS_GLOBAL );
@@ -449,29 +475,37 @@ TOOL_ACTION ACTIONS::unpinLibrary( "common.Control.unpinLibrary",
         _( "Unpin Library" ),
         _( "No longer keep the library at the top of the list" ) );
 
-TOOL_ACTION ACTIONS::panUp( "common.Control.panUp",
-        AS_GLOBAL,
-        MD_SHIFT + WXK_UP, "",
-        _( "Pan Up" ), "",
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_UP );
+TOOL_ACTION ACTIONS::panUp( TOOL_ACTION_ARGS()
+        .Name( "common.Control.panUp" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + WXK_UP )
+        .MenuText( _( "Pan Up" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_UP ) );
 
-TOOL_ACTION ACTIONS::panDown( "common.Control.panDown",
-        AS_GLOBAL,
-        MD_SHIFT + WXK_DOWN, "",
-        _( "Pan Down" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_DOWN );
+TOOL_ACTION ACTIONS::panDown( TOOL_ACTION_ARGS()
+        .Name( "common.Control.panDown" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + WXK_DOWN )
+        .MenuText( _( "Pan Down" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_DOWN ) );
 
-TOOL_ACTION ACTIONS::panLeft( "common.Control.panLeft",
-        AS_GLOBAL,
-        MD_SHIFT + WXK_LEFT, "",
-        _( "Pan Left" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_LEFT );
+TOOL_ACTION ACTIONS::panLeft( TOOL_ACTION_ARGS()
+        .Name( "common.Control.panLeft" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + WXK_LEFT )
+        .MenuText( _( "Pan Left" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_LEFT ) );
 
-TOOL_ACTION ACTIONS::panRight( "common.Control.panRight",
-        AS_GLOBAL,
-        MD_SHIFT + WXK_RIGHT, "",
-        _( "Pan Right" ), "" ,
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) CURSOR_RIGHT );
+TOOL_ACTION ACTIONS::panRight( TOOL_ACTION_ARGS()
+        .Name( "common.Control.panRight" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + WXK_RIGHT )
+        .MenuText( _( "Pan Right" ) )
+        .Flags( AF_NONE )
+        .Parameter( CURSOR_RIGHT ) );
 
 // Grid control
 TOOL_ACTION ACTIONS::gridFast1( "common.Control.gridFast1",
@@ -517,20 +551,32 @@ TOOL_ACTION ACTIONS::gridProperties( "common.Control.gridProperties",
         _( "Grid Properties..." ), _( "Set grid dimensions" ),
         BITMAPS::grid_select );
 
-TOOL_ACTION ACTIONS::inchesUnits( "common.Control.imperialUnits",
-        AS_GLOBAL, 0, "",
-        _( "Inches" ), _( "Use inches" ),
-        BITMAPS::unit_inch, AF_NONE, (void*) EDA_UNITS::INCHES );
+TOOL_ACTION ACTIONS::inchesUnits( TOOL_ACTION_ARGS()
+        .Name( "common.Control.imperialUnits" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Inches" ) )
+        .Tooltip( _( "Use inches" ) )
+        .Icon( BITMAPS::unit_inch )
+        .Flags( AF_NONE )
+        .Parameter( EDA_UNITS::INCHES ) );
 
-TOOL_ACTION ACTIONS::milsUnits( "common.Control.mils",
-        AS_GLOBAL, 0, "",
-        _( "Mils" ), _( "Use mils" ),
-        BITMAPS::unit_mil, AF_NONE, (void*) EDA_UNITS::MILS );
+TOOL_ACTION ACTIONS::milsUnits( TOOL_ACTION_ARGS()
+        .Name( "common.Control.mils" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Mils" ) )
+        .Tooltip( _( "Use mils" ) )
+        .Icon( BITMAPS::unit_mil )
+        .Flags( AF_NONE )
+        .Parameter( EDA_UNITS::MILS ) );
 
-TOOL_ACTION ACTIONS::millimetersUnits( "common.Control.metricUnits",
-        AS_GLOBAL, 0, "",
-        _( "Millimeters" ), _( "Use millimeters" ),
-        BITMAPS::unit_mm, AF_NONE, (void*) EDA_UNITS::MILLIMETRES );
+TOOL_ACTION ACTIONS::millimetersUnits( TOOL_ACTION_ARGS()
+        .Name( "common.Control.metricUnits" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Millimeters" ) )
+        .Tooltip( _( "Use millimeters" ) )
+        .Icon( BITMAPS::unit_mm )
+        .Flags( AF_NONE )
+        .Parameter( EDA_UNITS::MILLIMETRES ) );
 
 TOOL_ACTION ACTIONS::updateUnits( "common.Control.updateUnits",
         AS_GLOBAL );
@@ -615,25 +661,41 @@ TOOL_ACTION ACTIONS::show3DViewer( "common.Control.show3DViewer",
         _( "3D Viewer" ), _( "Show 3D viewer window" ),
         BITMAPS::three_d );
 
-TOOL_ACTION ACTIONS::showSymbolBrowser( "common.Control.showSymbolBrowser",
-        AS_GLOBAL, 0, "",
-        _( "Symbol Library Browser" ), _( "Browse symbol libraries" ),
-        BITMAPS::library_browser, AF_NONE, (void*) FRAME_SCH_VIEWER );
+TOOL_ACTION ACTIONS::showSymbolBrowser( TOOL_ACTION_ARGS()
+        .Name( "common.Control.showSymbolBrowser" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Symbol Library Browser" ) )
+        .Tooltip( _( "Browse symbol libraries" ) )
+        .Icon( BITMAPS::library_browser )
+        .Flags( AF_NONE)
+        .Parameter( FRAME_SCH_VIEWER ) );
 
-TOOL_ACTION ACTIONS::showSymbolEditor( "common.Control.showSymbolEditor",
-        AS_GLOBAL, 0, "",
-        _( "Symbol Editor" ), _( "Create, delete and edit symbols" ),
-        BITMAPS::libedit, AF_NONE, (void*) FRAME_SCH_SYMBOL_EDITOR );
+TOOL_ACTION ACTIONS::showSymbolEditor( TOOL_ACTION_ARGS()
+        .Name( "common.Control.showSymbolEditor" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Symbol Editor" ) )
+        .Tooltip( _( "Create, delete and edit symbols" ) )
+        .Icon( BITMAPS::libedit )
+        .Flags( AF_NONE )
+        .Parameter( FRAME_SCH_SYMBOL_EDITOR ) );
 
-TOOL_ACTION ACTIONS::showFootprintBrowser( "common.Control.showFootprintBrowser",
-        AS_GLOBAL, 0, "",
-        _( "Footprint Library Browser" ), _( "Browse footprint libraries" ),
-        BITMAPS::library_browser, AF_NONE, (void*) FRAME_FOOTPRINT_VIEWER );
+TOOL_ACTION ACTIONS::showFootprintBrowser( TOOL_ACTION_ARGS()
+        .Name( "common.Control.showFootprintBrowser" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Footprint Library Browser" ) )
+        .Tooltip( _( "Browse footprint libraries" ) )
+        .Icon( BITMAPS::library_browser )
+        .Flags( AF_NONE )
+        .Parameter( FRAME_FOOTPRINT_VIEWER ) );
 
-TOOL_ACTION ACTIONS::showFootprintEditor( "common.Control.showFootprintEditor",
-        AS_GLOBAL, 0, "",
-        _( "Footprint Editor" ), _( "Create, delete and edit footprints" ),
-        BITMAPS::module_editor, AF_NONE, (void*) FRAME_FOOTPRINT_EDITOR );
+TOOL_ACTION ACTIONS::showFootprintEditor( TOOL_ACTION_ARGS()
+        .Name( "common.Control.showFootprintEditor" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Footprint Editor" ) )
+        .Tooltip( _( "Create, delete and edit footprints" ) )
+        .Icon( BITMAPS::module_editor )
+        .Flags( AF_NONE )
+        .Parameter( FRAME_FOOTPRINT_EDITOR ) );
 
 TOOL_ACTION ACTIONS::updatePcbFromSchematic( "common.Control.updatePcbFromSchematic",
         AS_GLOBAL,
diff --git a/common/tool/common_tools.cpp b/common/tool/common_tools.cpp
index 10ecc98111..b960723707 100644
--- a/common/tool/common_tools.cpp
+++ b/common/tool/common_tools.cpp
@@ -103,7 +103,7 @@ int COMMON_TOOLS::SelectionTool( const TOOL_EVENT& aEvent )
 // Cursor control
 int COMMON_TOOLS::CursorControl( const TOOL_EVENT& aEvent )
 {
-    long type = aEvent.Parameter<intptr_t>();
+    long type = aEvent.Parameter<long>();
     bool fastMove = type & ACTIONS::CURSOR_FAST_MOVE;
     type &= ~ACTIONS::CURSOR_FAST_MOVE;
     bool mirroredX = getView()->IsMirroredX();
@@ -151,7 +151,7 @@ int COMMON_TOOLS::CursorControl( const TOOL_EVENT& aEvent )
             button = BUT_RIGHT;
 
         TOOL_EVENT evt( TC_MOUSE, action, button | modifiers );
-        evt.SetParameter( static_cast<intptr_t>( type ) );
+        evt.SetParameter( type );
         evt.SetMousePosition( getViewControls()->GetCursorPosition() );
         m_toolMgr->ProcessEvent( evt );
 
@@ -170,7 +170,7 @@ int COMMON_TOOLS::CursorControl( const TOOL_EVENT& aEvent )
 
 int COMMON_TOOLS::PanControl( const TOOL_EVENT& aEvent )
 {
-    long type = aEvent.Parameter<intptr_t>();
+    long type = aEvent.Parameter<long>();
     KIGFX::VIEW* view = getView();
     VECTOR2D center = view->GetCenter();
     VECTOR2D gridSize = getView()->GetGAL()->GetGridSize() * 10;
@@ -383,7 +383,7 @@ int COMMON_TOOLS::CenterContents( const TOOL_EVENT& aEvent )
 
 int COMMON_TOOLS::ZoomPreset( const TOOL_EVENT& aEvent )
 {
-    unsigned int idx = aEvent.Parameter<intptr_t>();
+    unsigned int idx = aEvent.Parameter<unsigned int>();
     return doZoomToPreset( (int) idx, false );
 }
 
@@ -450,7 +450,7 @@ int COMMON_TOOLS::GridPrev( const TOOL_EVENT& aEvent )
 
 int COMMON_TOOLS::GridPreset( const TOOL_EVENT& aEvent )
 {
-    return GridPreset( aEvent.Parameter<intptr_t>() );
+    return GridPreset( aEvent.Parameter<int>() );
 }
 
 
diff --git a/common/tool/grid_menu.cpp b/common/tool/grid_menu.cpp
index 299065484d..b1c6129184 100644
--- a/common/tool/grid_menu.cpp
+++ b/common/tool/grid_menu.cpp
@@ -54,7 +54,7 @@ GRID_MENU::GRID_MENU( EDA_DRAW_FRAME* aParent ) :
 OPT_TOOL_EVENT GRID_MENU::eventHandler( const wxMenuEvent& aEvent )
 {
     OPT_TOOL_EVENT event( ACTIONS::gridPreset.MakeEvent() );
-    event->SetParameter( (intptr_t) aEvent.GetId() - ID_POPUP_GRID_START );
+    event->SetParameter( aEvent.GetId() - ID_POPUP_GRID_START );
     return event;
 }
 
diff --git a/common/tool/tool_action.cpp b/common/tool/tool_action.cpp
index 294c2c8006..744a2b897e 100644
--- a/common/tool/tool_action.cpp
+++ b/common/tool/tool_action.cpp
@@ -36,7 +36,7 @@
 TOOL_ACTION::TOOL_ACTION( const std::string& aName, TOOL_ACTION_SCOPE aScope,
                           int aDefaultHotKey, const std::string& aLegacyHotKeyName,
                           const wxString& aLabel, const wxString& aTooltip,
-                          BITMAPS aIcon, TOOL_ACTION_FLAGS aFlags, void* aParam ) :
+                          BITMAPS aIcon, TOOL_ACTION_FLAGS aFlags ) :
         m_name( aName ),
         m_scope( aScope ),
         m_defaultHotKey( aDefaultHotKey ),
@@ -45,8 +45,7 @@ TOOL_ACTION::TOOL_ACTION( const std::string& aName, TOOL_ACTION_SCOPE aScope,
         m_tooltip( aTooltip ),
         m_icon( aIcon ),
         m_id( -1 ),
-        m_flags( aFlags ),
-        m_param( aParam )
+        m_flags( aFlags )
 {
     SetHotKey( aDefaultHotKey );
     ACTION_MANAGER::GetActionList().push_back( this );
@@ -58,8 +57,7 @@ TOOL_ACTION::TOOL_ACTION() :
         m_defaultHotKey( 0 ),
         m_icon( BITMAPS::INVALID_BITMAP ),
         m_id( -1 ),
-        m_flags( AF_NONE ),
-        m_param( nullptr )
+        m_flags( AF_NONE )
 {
     SetHotKey( 0 );
 }
@@ -76,8 +74,7 @@ TOOL_ACTION::TOOL_ACTION( const TOOL_ACTION_ARGS& aArgs ) :
         m_icon( aArgs.m_icon.value_or( BITMAPS::INVALID_BITMAP) ),
         m_id( -1 ),
         m_uiid( std::nullopt ),
-        m_flags( aArgs.m_flags.value_or( AF_NONE ) ),
-        m_param( aArgs.m_param.value_or( nullptr ) )
+        m_flags( aArgs.m_flags.value_or( AF_NONE ) )
 {
     // Action name is the only mandatory part
     assert( !m_name.empty() );
@@ -85,6 +82,9 @@ TOOL_ACTION::TOOL_ACTION( const TOOL_ACTION_ARGS& aArgs ) :
     if( aArgs.m_uiid.has_value() )
         m_uiid = aArgs.m_uiid.value();
 
+    if( aArgs.m_param.has_value() )
+        m_param = aArgs.m_param;
+
     ACTION_MANAGER::GetActionList().push_back( this );
 }
 
@@ -97,12 +97,19 @@ TOOL_ACTION::~TOOL_ACTION()
 
 TOOL_EVENT TOOL_ACTION::MakeEvent() const
 {
+    TOOL_EVENT evt;
+
     if( IsActivation() )
-        return TOOL_EVENT( TC_COMMAND, TA_ACTIVATE, m_name, m_scope, m_param );
+        evt = TOOL_EVENT( TC_COMMAND, TA_ACTIVATE, m_name, m_scope );
     else if( IsNotification() )
-        return TOOL_EVENT( TC_MESSAGE, TA_NONE, m_name, m_scope, m_param );
+        evt = TOOL_EVENT( TC_MESSAGE, TA_NONE, m_name, m_scope );
     else
-        return TOOL_EVENT( TC_COMMAND, TA_ACTION, m_name, m_scope, m_param );
+        evt = TOOL_EVENT( TC_COMMAND, TA_ACTION, m_name, m_scope );
+
+    if( m_param.has_value() )
+        evt.SetParameter( m_param );
+
+    return evt;
 }
 
 
diff --git a/common/tool/zoom_menu.cpp b/common/tool/zoom_menu.cpp
index 12380e001f..b93df5b7fb 100644
--- a/common/tool/zoom_menu.cpp
+++ b/common/tool/zoom_menu.cpp
@@ -46,7 +46,7 @@ ZOOM_MENU::ZOOM_MENU( EDA_DRAW_FRAME* aParent ) :
 OPT_TOOL_EVENT ZOOM_MENU::eventHandler( const wxMenuEvent& aEvent )
 {
     OPT_TOOL_EVENT event( ACTIONS::zoomPreset.MakeEvent() );
-    event->SetParameter( (intptr_t) aEvent.GetId() - ID_POPUP_ZOOM_LEVEL_START );
+    event->SetParameter( aEvent.GetId() - ID_POPUP_ZOOM_LEVEL_START );
     return event;
 }
 
diff --git a/cvpcb/tools/cvpcb_actions.cpp b/cvpcb/tools/cvpcb_actions.cpp
index 962a345964..18b28d935d 100644
--- a/cvpcb/tools/cvpcb_actions.cpp
+++ b/cvpcb/tools/cvpcb_actions.cpp
@@ -18,6 +18,7 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "tool/tool_action.h"
 #include <bitmaps.h>
 
 #include <cvpcb_mainframe.h>
@@ -76,36 +77,38 @@ TOOL_ACTION CVPCB_ACTIONS::saveAssociationsToFile( "cvpcb.Control.SaveAssociatio
         BITMAPS::save );
 
 // Actions to navigate the display
-TOOL_ACTION CVPCB_ACTIONS::changeFocusRight( "cvpcb.Control.changeFocusRight",
-        AS_GLOBAL,
-        WXK_TAB, "",
-        "",
-        "",
-        BITMAPS::INVALID_BITMAP, AF_NONE,
-        (void*) CVPCB_MAINFRAME::CHANGE_FOCUS_RIGHT );
+TOOL_ACTION CVPCB_ACTIONS::changeFocusRight( TOOL_ACTION_ARGS()
+        .Name( "cvpcb.Control.changeFocusRight" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_TAB )
+        .Flags( AF_NONE )
+        .Parameter( CVPCB_MAINFRAME::CHANGE_FOCUS_RIGHT ) );
 
-TOOL_ACTION CVPCB_ACTIONS::changeFocusLeft( "cvpcb.Control.changeFocusLeft",
-        AS_GLOBAL,
-        MD_SHIFT + WXK_TAB, "",
-        "",
-        "",
-        BITMAPS::INVALID_BITMAP, AF_NONE,
-        (void*) CVPCB_MAINFRAME::CHANGE_FOCUS_LEFT );
+TOOL_ACTION CVPCB_ACTIONS::changeFocusLeft( TOOL_ACTION_ARGS()
+        .Name( "cvpcb.Control.changeFocusLeft" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + WXK_TAB )
+        .Flags( AF_NONE )
+        .Parameter( CVPCB_MAINFRAME::CHANGE_FOCUS_LEFT ) );
 
 // Actions to navigate the component list
-TOOL_ACTION CVPCB_ACTIONS::gotoNextNA( "cvpcb.Control.GotoNextNA",
-        AS_GLOBAL, 0, "",
-        _( "Select next unassigned symbol" ),
-        _( "Select next symbol with no footprint assignment" ),
-        BITMAPS::right, AF_NONE,
-        (void*) CVPCB_MAINFRAME::ITEM_NEXT );
+TOOL_ACTION CVPCB_ACTIONS::gotoNextNA( TOOL_ACTION_ARGS()
+        .Name( "cvpcb.Control.GotoNextNA" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Select next unassigned symbol" ) )
+        .Tooltip( _( "Select next symbol with no footprint assignment" ) )
+        .Icon( BITMAPS::right )
+        .Flags( AF_NONE )
+        .Parameter( CVPCB_MAINFRAME::ITEM_NEXT ) );
 
-TOOL_ACTION CVPCB_ACTIONS::gotoPreviousNA( "cvpcb.Control.GotoPreviousNA",
-        AS_GLOBAL, 0, "",
-        _( "Select previous unassigned symbol" ),
-        _( "Select previous symbol with no footprint assignment" ),
-        BITMAPS::left, AF_NONE,
-        (void*) CVPCB_MAINFRAME::ITEM_PREV );
+TOOL_ACTION CVPCB_ACTIONS::gotoPreviousNA( TOOL_ACTION_ARGS()
+        .Name( "cvpcb.Control.GotoPreviousNA" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Select previous unassigned symbol" ) )
+        .Tooltip( _( "Select previous symbol with no footprint assignment" ) )
+        .Icon( BITMAPS::left )
+        .Flags( AF_NONE )
+        .Parameter( CVPCB_MAINFRAME::ITEM_PREV ) );
 
 
 // Actions to modify component associations
@@ -137,23 +140,29 @@ TOOL_ACTION CVPCB_ACTIONS::deleteAll( "cvpcb.Association.DeleteAll",
 
 
 // Actions to filter the footprint list
-TOOL_ACTION CVPCB_ACTIONS::FilterFPbyFPFilters( "cvpcb.Control.FilterFPbyFPFilters",
-        AS_GLOBAL, 0, "",
-        _( "Use symbol footprint filters" ),
-        _( "Filter footprint list by footprint filters defined in the symbol" ),
-        BITMAPS::module_filtered_list, AF_NONE,
-        (void*) FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_FP_FILTERS );
+TOOL_ACTION CVPCB_ACTIONS::FilterFPbyFPFilters( TOOL_ACTION_ARGS()
+        .Name( "cvpcb.Control.FilterFPbyFPFilters" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Use symbol footprint filters" ) )
+        .Tooltip( _( "Filter footprint list by footprint filters defined in the symbol" ) )
+        .Icon( BITMAPS::module_filtered_list )
+        .Flags( AF_NONE )
+        .Parameter( FOOTPRINTS_LISTBOX::FILTERING_BY_COMPONENT_FP_FILTERS ) );
 
-TOOL_ACTION CVPCB_ACTIONS::filterFPbyPin( "cvpcb.Control.FilterFPByPin",
-        AS_GLOBAL, 0, "",
-        _( "Filter by pin count" ),
-        _( "Filter footprint list by pin count" ),
-        BITMAPS::module_pin_filtered_list, AF_NONE,
-        (void*) FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT );
+TOOL_ACTION CVPCB_ACTIONS::filterFPbyPin( TOOL_ACTION_ARGS()
+        .Name( "cvpcb.Control.FilterFPByPin" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Filter by pin count" ) )
+        .Tooltip( _( "Filter footprint list by pin count" ) )
+        .Icon( BITMAPS::module_pin_filtered_list )
+        .Flags( AF_NONE )
+        .Parameter( FOOTPRINTS_LISTBOX::FILTERING_BY_PIN_COUNT ) );
 
-TOOL_ACTION CVPCB_ACTIONS::FilterFPbyLibrary( "cvpcb.Control.FilterFPbyLibrary",
-        AS_GLOBAL, 0, "",
-        _( "Filter by library" ),
-        _( "Filter footprint list by library" ),
-        BITMAPS::module_library_list, AF_NONE,
-        (void*) FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY );
+TOOL_ACTION CVPCB_ACTIONS::FilterFPbyLibrary( TOOL_ACTION_ARGS()
+        .Name( "cvpcb.Control.FilterFPbyLibrary" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Filter by library" ) )
+        .Tooltip( _( "Filter footprint list by library" ) )
+        .Icon( BITMAPS::module_library_list )
+        .Flags( AF_NONE )
+        .Parameter( FOOTPRINTS_LISTBOX::FILTERING_BY_LIBRARY ) );
diff --git a/cvpcb/tools/cvpcb_control.cpp b/cvpcb/tools/cvpcb_control.cpp
index d32135d7e1..2353074612 100644
--- a/cvpcb/tools/cvpcb_control.cpp
+++ b/cvpcb/tools/cvpcb_control.cpp
@@ -96,9 +96,7 @@ int CVPCB_CONTROL::Main( const TOOL_EVENT& aEvent )
 
 int CVPCB_CONTROL::ChangeFocus( const TOOL_EVENT& aEvent )
 {
-    int tmp = aEvent.Parameter<intptr_t>();
-    CVPCB_MAINFRAME::FOCUS_DIR dir =
-            static_cast<CVPCB_MAINFRAME::FOCUS_DIR>( tmp );
+    CVPCB_MAINFRAME::FOCUS_DIR dir = aEvent.Parameter<CVPCB_MAINFRAME::FOCUS_DIR>();
 
     switch( dir )
     {
@@ -217,10 +215,8 @@ int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
 
 int CVPCB_CONTROL::ToggleFootprintFilter( const TOOL_EVENT& aEvent )
 {
-    m_frame->SetFootprintFilter(
-            static_cast<FOOTPRINTS_LISTBOX::FP_FILTER_T>( aEvent.Parameter<intptr_t>() ),
-            CVPCB_MAINFRAME::FILTER_TOGGLE );
-
+    m_frame->SetFootprintFilter( aEvent.Parameter<FOOTPRINTS_LISTBOX::FP_FILTER_T>(),
+                                 CVPCB_MAINFRAME::FILTER_TOGGLE );
     return 0;
 }
 
@@ -250,9 +246,7 @@ int CVPCB_CONTROL::SaveAssociationsToSchematic( const TOOL_EVENT& aEvent )
 
 int CVPCB_CONTROL::ToNA( const TOOL_EVENT& aEvent )
 {
-    int tmp = aEvent.Parameter<intptr_t>();
-    CVPCB_MAINFRAME::ITEM_DIR dir =
-            static_cast<CVPCB_MAINFRAME::ITEM_DIR>( tmp );
+    CVPCB_MAINFRAME::ITEM_DIR dir = aEvent.Parameter<CVPCB_MAINFRAME::ITEM_DIR>();
 
     std::vector<unsigned int> naComp = m_frame->GetComponentIndices( CVPCB_MAINFRAME::NA_COMPONENTS );
     std::vector<unsigned int> tempSel = m_frame->GetComponentIndices( CVPCB_MAINFRAME::SEL_COMPONENTS );
diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp
index 1b6be61119..73646c2111 100644
--- a/eeschema/tools/ee_actions.cpp
+++ b/eeschema/tools/ee_actions.cpp
@@ -243,31 +243,52 @@ TOOL_ACTION EE_ACTIONS::toggleSyncedPinsMode( "eeschema.SymbolLibraryControl.tog
 
 // SYMBOL_EDITOR_DRAWING_TOOLS
 //
-TOOL_ACTION EE_ACTIONS::placeSymbolPin( "eeschema.SymbolDrawing.placeSymbolPin",
-        AS_GLOBAL,
-        'P', LEGACY_HK_NAME( "Create Pin" ),
-        _( "Add Pin" ), _( "Draw pins" ),
-        BITMAPS::pin, AF_ACTIVATE, (void*) LIB_PIN_T );
+TOOL_ACTION EE_ACTIONS::placeSymbolPin( TOOL_ACTION_ARGS()
+        .Name( "eeschema.SymbolDrawing.placeSymbolPin" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'P' )
+        .LegacyHotkeyName( "Create Pin" )
+        .MenuText( _( "Add Pin" ) )
+        .Tooltip( _( "Add a pin" ) )
+        .Icon( BITMAPS::pin )
+        .Flags( AF_ACTIVATE )
+        .Parameter( LIB_PIN_T ) );
 
-TOOL_ACTION EE_ACTIONS::placeSymbolText( "eeschema.SymbolDrawing.placeSymbolText",
-        AS_GLOBAL, 0, "",
-        _( "Add Text" ), _( "Draw text items" ),
-        BITMAPS::text, AF_ACTIVATE, (void*) LIB_TEXT_T );
+TOOL_ACTION EE_ACTIONS::placeSymbolText( TOOL_ACTION_ARGS()
+        .Name( "eeschema.SymbolDrawing.placeSymbolText" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Text" ) )
+        .Tooltip( _( "Add a text item" ) )
+        .Icon( BITMAPS::text )
+        .Flags( AF_ACTIVATE )
+        .Parameter( LIB_TEXT_T ) );
 
-TOOL_ACTION EE_ACTIONS::drawSymbolTextBox( "eeschema.SymbolDrawing.drawSymbolTextBox",
-        AS_GLOBAL, 0, "",
-        _( "Add Text Box" ), _( "Draw text box items" ),
-        BITMAPS::add_textbox, AF_ACTIVATE, (void*) LIB_TEXTBOX_T );
+TOOL_ACTION EE_ACTIONS::drawSymbolTextBox( TOOL_ACTION_ARGS()
+        .Name( "eeschema.SymbolDrawing.drawSymbolTextBox" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Text Box" ) )
+        .Tooltip( _( "Add a text box item" ) )
+        .Icon( BITMAPS::add_textbox )
+        .Flags( AF_ACTIVATE )
+        .Parameter( LIB_TEXTBOX_T ) );
 
-TOOL_ACTION EE_ACTIONS::drawSymbolLines( "eeschema.SymbolDrawing.drawSymbolLines",
-        AS_GLOBAL, 0, "",
-        _( "Add Lines" ), _( "Draw lines" ),
-        BITMAPS::add_graphical_segments, AF_ACTIVATE, (void*) SHAPE_T::SEGMENT );
+TOOL_ACTION EE_ACTIONS::drawSymbolLines( TOOL_ACTION_ARGS()
+        .Name( "eeschema.SymbolDrawing.drawSymbolLines" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Lines" ) )
+        .Tooltip( _( "Add connected graphic lines" ) )
+        .Icon( BITMAPS::add_graphical_segments )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SHAPE_T::POLY ) );
 
-TOOL_ACTION EE_ACTIONS::drawSymbolPolygon( "eeschema.SymbolDrawing.drawSymbolPolygon",
-        AS_GLOBAL, 0, "",
-        _( "Add Polygon" ), _( "Draw polygons" ),
-        BITMAPS::add_graphical_polygon, AF_ACTIVATE, (void*) SHAPE_T::POLY );
+TOOL_ACTION EE_ACTIONS::drawSymbolPolygon( TOOL_ACTION_ARGS()
+        .Name( "eeschema.SymbolDrawing.drawSymbolPolygon" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Polygon" ) )
+        .Tooltip( _( "Draw polygons" ) )
+        .Icon( BITMAPS::add_graphical_polygon )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SHAPE_T::POLY ) );
 
 TOOL_ACTION EE_ACTIONS::placeSymbolAnchor( "eeschema.SymbolDrawing.placeSymbolAnchor",
         AS_GLOBAL, 0, "",
@@ -311,23 +332,38 @@ TOOL_ACTION EE_ACTIONS::placePower( "eeschema.InteractiveDrawing.placePowerSymbo
         _( "Add Power" ), _( "Add power symbols" ),
         BITMAPS::add_power, AF_ACTIVATE );
 
-TOOL_ACTION EE_ACTIONS::placeNoConnect( "eeschema.InteractiveDrawing.placeNoConnect",
-        AS_GLOBAL,
-        'Q', LEGACY_HK_NAME( "Add No Connect Flag" ),
-        _( "Add No Connect Flag" ), _( "Draw no-connection flags" ),
-        BITMAPS::noconn, AF_ACTIVATE, (void*) SCH_NO_CONNECT_T );
+TOOL_ACTION EE_ACTIONS::placeNoConnect( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawing.placeNoConnect" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'Q' )
+        .LegacyHotkeyName( "Add No Connect Flag" )
+        .MenuText( _( "Add No Connect Flag" ) )
+        .Tooltip( _( "Draw no-connection flags" ) )
+        .Icon( BITMAPS::noconn )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SCH_NO_CONNECT_T ) );
 
-TOOL_ACTION EE_ACTIONS::placeJunction( "eeschema.InteractiveDrawing.placeJunction",
-        AS_GLOBAL,
-        'J', LEGACY_HK_NAME( "Add Junction" ),
-        _( "Add Junction" ), _( "Draw junctions" ),
-        BITMAPS::add_junction, AF_ACTIVATE, (void*) SCH_JUNCTION_T );
+TOOL_ACTION EE_ACTIONS::placeJunction( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawing.placeJunction" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'J' )
+        .LegacyHotkeyName( "Add Junction" )
+        .MenuText( _( "Add Junction" ) )
+        .Tooltip( _( "Draw junctions" ) )
+        .Icon( BITMAPS::add_junction )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SCH_JUNCTION_T ) );
 
-TOOL_ACTION EE_ACTIONS::placeBusWireEntry( "eeschema.InteractiveDrawing.placeBusWireEntry",
-        AS_GLOBAL,
-        'Z', LEGACY_HK_NAME( "Add Wire Entry" ),
-        _( "Add Wire to Bus Entry" ), _( "Add a wire entry to a bus" ),
-        BITMAPS::add_line2bus, AF_ACTIVATE, (void*) SCH_BUS_WIRE_ENTRY_T );
+TOOL_ACTION EE_ACTIONS::placeBusWireEntry( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawing.placeBusWireEntry" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'Z' )
+        .LegacyHotkeyName( "Add Wire Entry" )
+        .MenuText( _( "Add Wire to Bus Entry" ) )
+        .Tooltip( _( "Add a wire entry to a bus" ) )
+        .Icon( BITMAPS::add_line2bus )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SCH_BUS_WIRE_ENTRY_T ) );
 
 TOOL_ACTION EE_ACTIONS::placeLabel( "eeschema.InteractiveDrawing.placeLabel",
         AS_GLOBAL,
@@ -346,11 +382,16 @@ TOOL_ACTION EE_ACTIONS::placeHierLabel( "eeschema.InteractiveDrawing.placeHierar
         _( "Add Hierarchical Label" ), _( "Add hierarchical labels" ),
         BITMAPS::add_hierarchical_label, AF_ACTIVATE );
 
-TOOL_ACTION EE_ACTIONS::drawSheet( "eeschema.InteractiveDrawing.drawSheet",
-        AS_GLOBAL,
-        'S', LEGACY_HK_NAME( "Add Sheet" ),
-        _( "Add Sheet" ), _( "Draw hierarchical sheets" ),
-        BITMAPS::add_hierarchical_subsheet, AF_ACTIVATE, (void*) SCH_SHEET_T );
+TOOL_ACTION EE_ACTIONS::drawSheet( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawing.drawSheet" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'S' )
+        .LegacyHotkeyName( "Add Sheet" )
+        .MenuText( _( "Add Sheet" ) )
+        .Tooltip( _( "Draw hierarchical sheets" ) )
+        .Icon( BITMAPS::add_hierarchical_subsheet )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SCH_SHEET_T ) );
 
 TOOL_ACTION EE_ACTIONS::importSheetPin( "eeschema.InteractiveDrawing.importSheetPin",
         AS_GLOBAL, 0, "",
@@ -369,25 +410,41 @@ TOOL_ACTION EE_ACTIONS::placeSchematicText( "eeschema.InteractiveDrawing.placeSc
         _( "Add Text" ), _( "Draw text items" ),
         BITMAPS::text, AF_ACTIVATE );
 
-TOOL_ACTION EE_ACTIONS::drawTextBox( "eeschema.InteractiveDrawing.drawTextBox",
-        AS_GLOBAL, 0, "",
-        _( "Add Text Box" ), _( "Draw text box items" ),
-        BITMAPS::add_textbox, AF_ACTIVATE, (void*) SHAPE_T::RECT );
+TOOL_ACTION EE_ACTIONS::drawTextBox( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawing.drawTextBox" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Text Box" ) )
+        .Tooltip( _( "Draw text box items" ) )
+        .Icon( BITMAPS::add_textbox )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SHAPE_T::RECT ) );
 
-TOOL_ACTION EE_ACTIONS::drawRectangle( "eeschema.InteractiveDrawing.drawRectangle",
-        AS_GLOBAL, 0, "",
-        _( "Add Rectangle" ), _( "Draw rectangles" ),
-        BITMAPS::add_rectangle, AF_ACTIVATE, (void*) SHAPE_T::RECT );
+TOOL_ACTION EE_ACTIONS::drawRectangle( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawing.drawRectangle" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Rectangle" ) )
+        .Tooltip( _( "Draw rectangles" ) )
+        .Icon( BITMAPS::add_rectangle )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SHAPE_T::RECT ) );
 
-TOOL_ACTION EE_ACTIONS::drawCircle( "eeschema.InteractiveDrawing.drawCircle",
-        AS_GLOBAL, 0, "",
-        _( "Add Circle" ), _( "Draw circles" ),
-        BITMAPS::add_circle, AF_ACTIVATE, (void*) SHAPE_T::CIRCLE );
+TOOL_ACTION EE_ACTIONS::drawCircle( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawing.drawCircle" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Circle" ) )
+        .Tooltip( _( "Draw circles" ) )
+        .Icon( BITMAPS::add_circle )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SHAPE_T::CIRCLE ) );
 
-TOOL_ACTION EE_ACTIONS::drawArc( "eeschema.InteractiveDrawing.drawArc",
-        AS_GLOBAL, 0, "",
-        _( "Add Arc" ), _( "Draw arcs" ),
-        BITMAPS::add_arc, AF_ACTIVATE, (void*) SHAPE_T::ARC );
+TOOL_ACTION EE_ACTIONS::drawArc( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawing.drawArc" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Arc" ) )
+        .Tooltip( _( "Draw arcs" ) )
+        .Icon( BITMAPS::add_arc )
+        .Flags( AF_ACTIVATE )
+        .Parameter( SHAPE_T::ARC ) );
 
 TOOL_ACTION EE_ACTIONS::placeImage( "eeschema.InteractiveDrawing.placeImage",
         AS_GLOBAL, 0, "",
@@ -514,35 +571,59 @@ TOOL_ACTION EE_ACTIONS::showDeMorganAlternate( "eeschema.InteractiveEdit.showDeM
         _( "De Morgan Alternate" ), _( "Switch to alternate De Morgan representation" ),
         BITMAPS::morgan2 );
 
-TOOL_ACTION EE_ACTIONS::toLabel( "eeschema.InteractiveEdit.toLabel",
-        AS_GLOBAL, 0, "",
-        _( "Change to Label" ), _( "Change existing item to a label" ),
-        BITMAPS::add_line_label, AF_NONE, (void*) SCH_LABEL_T );
+TOOL_ACTION EE_ACTIONS::toLabel( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveEdit.toLabel" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Change to Label" ) )
+        .Tooltip( _( "Change existing item to a label" ) )
+        .Icon( BITMAPS::add_line_label )
+        .Flags( AF_NONE )
+        .Parameter( SCH_LABEL_T ) );
 
-TOOL_ACTION EE_ACTIONS::toCLabel( "eeschema.InteractiveEdit.toCLabel",
-        AS_GLOBAL, 0, "",
-        _( "Change to Directive Label" ), _( "Change existing item to a directive label" ),
-        BITMAPS::add_class_flag, AF_NONE, (void*) SCH_DIRECTIVE_LABEL_T );
+TOOL_ACTION EE_ACTIONS::toCLabel( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveEdit.toCLabel" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Change to Directive Label" ) )
+        .Tooltip( _( "Change existing item to a directive label" ) )
+        .Icon( BITMAPS::add_class_flag )
+        .Flags( AF_NONE )
+        .Parameter( SCH_DIRECTIVE_LABEL_T ) );
 
-TOOL_ACTION EE_ACTIONS::toHLabel( "eeschema.InteractiveEdit.toHLabel",
-        AS_GLOBAL, 0, "",
-        _( "Change to Hierarchical Label" ), _( "Change existing item to a hierarchical label" ),
-        BITMAPS::add_hierarchical_label, AF_NONE, (void*) SCH_HIER_LABEL_T );
+TOOL_ACTION EE_ACTIONS::toHLabel( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveEdit.toHLabel" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Change to Hierarchical Label" ) )
+        .Tooltip( _( "Change existing item to a hierarchical label" ) )
+        .Icon( BITMAPS::add_hierarchical_label )
+        .Flags( AF_NONE )
+        .Parameter( SCH_HIER_LABEL_T ) );
 
-TOOL_ACTION EE_ACTIONS::toGLabel( "eeschema.InteractiveEdit.toGLabel",
-        AS_GLOBAL, 0, "",
-        _( "Change to Global Label" ), _( "Change existing item to a global label" ),
-        BITMAPS::add_glabel, AF_NONE, (void*) SCH_GLOBAL_LABEL_T );
+TOOL_ACTION EE_ACTIONS::toGLabel( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveEdit.toGLabel" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Change to Global Label" ) )
+        .Tooltip( _( "Change existing item to a global label" ) )
+        .Icon( BITMAPS::add_glabel )
+        .Flags( AF_NONE )
+        .Parameter( SCH_GLOBAL_LABEL_T ) );
 
-TOOL_ACTION EE_ACTIONS::toText( "eeschema.InteractiveEdit.toText",
-        AS_GLOBAL, 0, "",
-        _( "Change to Text" ), _( "Change existing item to a text comment" ),
-        BITMAPS::text, AF_NONE, (void*) SCH_TEXT_T );
+TOOL_ACTION EE_ACTIONS::toText( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveEdit.toText" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Change to Text" ) )
+        .Tooltip( _( "Change existing item to a text comment" ) )
+        .Icon( BITMAPS::text )
+        .Flags( AF_NONE )
+        .Parameter( SCH_TEXT_T ) );
 
-TOOL_ACTION EE_ACTIONS::toTextBox( "eeschema.InteractiveEdit.toTextBox",
-        AS_GLOBAL, 0, "",
-        _( "Change to Text Box" ), _( "Change existing item to a text box" ),
-        BITMAPS::add_textbox, AF_NONE, (void*) SCH_TEXTBOX_T );
+TOOL_ACTION EE_ACTIONS::toTextBox( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveEdit.toTextBox" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Change to Text Box" ) )
+        .Tooltip( _( "Change existing item to a text box" ) )
+        .Icon( BITMAPS::add_textbox )
+        .Flags( AF_NONE )
+        .Parameter( SCH_TEXTBOX_T ) );
 
 TOOL_ACTION EE_ACTIONS::cleanupSheetPins( "eeschema.InteractiveEdit.cleanupSheetPins",
         AS_GLOBAL, 0, "",
@@ -798,22 +879,32 @@ TOOL_ACTION EE_ACTIONS::toggleOPCurrents( "eeschema.EditorControl.showOperatingP
         _( "Show OP Currents" ),
         _( "Show operating point current data from simulation" ) );
 
-TOOL_ACTION EE_ACTIONS::lineModeFree( "eeschema.EditorControl.lineModeFree",
-        AS_GLOBAL, 0, "",
-        _( "Line Mode for Wires and Buses" ), _( "Draw and drag at any angle" ),
-        BITMAPS::lines_any, AF_NONE, (void*) LINE_MODE::LINE_MODE_FREE );
+TOOL_ACTION EE_ACTIONS::lineModeFree( TOOL_ACTION_ARGS()
+        .Name( "eeschema.EditorControl.lineModeFree" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Line Mode for Wires and Buses" ) )
+        .Tooltip( _( "Draw and drag at any angle" ) )
+        .Icon( BITMAPS::lines_any )
+        .Flags( AF_NONE )
+        .Parameter( LINE_MODE::LINE_MODE_FREE ) );
 
-TOOL_ACTION EE_ACTIONS::lineMode90( "eeschema.EditorControl.lineModeOrthonal",
-        AS_GLOBAL, 0, "",
-        _( "Line Mode for Wires and Buses" ),
-        _( "Constrain drawing and dragging to horizontal or vertical motions" ),
-        BITMAPS::lines90, AF_NONE, (void*) LINE_MODE::LINE_MODE_90);
+TOOL_ACTION EE_ACTIONS::lineMode90( TOOL_ACTION_ARGS()
+        .Name( "eeschema.EditorControl.lineModeOrthonal" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Line Mode for Wires and Buses" ) )
+        .Tooltip( _( "Constrain drawing and dragging to horizontal or vertical motions" ) )
+        .Icon( BITMAPS::lines90 )
+        .Flags( AF_NONE )
+        .Parameter( LINE_MODE::LINE_MODE_90) );
 
-TOOL_ACTION EE_ACTIONS::lineMode45( "eeschema.EditorControl.lineMode45",
-        AS_GLOBAL, 0, "",
-        _( "Line Mode for Wires and Buses" ),
-        _( "Constrain drawing and dragging to horizontal, vertical, or 45-degree angle motions" ),
-        BITMAPS::hv45mode, AF_NONE, (void*) LINE_MODE::LINE_MODE_45);
+TOOL_ACTION EE_ACTIONS::lineMode45( TOOL_ACTION_ARGS()
+        .Name( "eeschema.EditorControl.lineMode45" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Line Mode for Wires and Buses" ) )
+        .Tooltip( _( "Constrain drawing and dragging to horizontal, vertical, or 45-degree angle motions" ) )
+        .Icon( BITMAPS::hv45mode )
+        .Flags( AF_NONE )
+        .Parameter( LINE_MODE::LINE_MODE_45 ) );
 
 TOOL_ACTION EE_ACTIONS::lineModeNext( "eeschema.EditorControl.lineModeNext",
         AS_GLOBAL, MD_SHIFT + WXK_SPACE, "",
@@ -894,18 +985,28 @@ TOOL_ACTION EE_ACTIONS::showHierarchy( "eeschema.EditorTool.showHierarchy",
 // SCH_LINE_WIRE_BUS_TOOL
 //
 const DRAW_SEGMENT_EVENT_PARAMS drawWireActionParam = { LAYER_WIRE, false, nullptr };
-TOOL_ACTION EE_ACTIONS::drawWire( "eeschema.InteractiveDrawingLineWireBus.drawWires",
-        AS_GLOBAL,
-        'W', LEGACY_HK_NAME( "Begin Wire" ),
-        _( "Add Wire" ), _( "Add a wire" ),
-        BITMAPS::add_line, AF_ACTIVATE, (void*) &drawWireActionParam );
+TOOL_ACTION EE_ACTIONS::drawWire( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawingLineWireBus.drawWires" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'W' )
+        .LegacyHotkeyName( "Begin Wire" )
+        .MenuText( _( "Add Wire" ) )
+        .Tooltip( _( "Add a wire" ) )
+        .Icon( BITMAPS::add_line )
+        .Flags( AF_ACTIVATE )
+        .Parameter( &drawWireActionParam ) );
 
 const DRAW_SEGMENT_EVENT_PARAMS drawBusActionParam = { LAYER_BUS, false, nullptr };
-TOOL_ACTION EE_ACTIONS::drawBus( "eeschema.InteractiveDrawingLineWireBus.drawBuses",
-        AS_GLOBAL,
-        'B', LEGACY_HK_NAME( "Begin Bus" ),
-        _( "Add Bus" ), _( "Add a bus" ),
-        BITMAPS::add_bus, AF_ACTIVATE, (void*) &drawBusActionParam );
+TOOL_ACTION EE_ACTIONS::drawBus( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawingLineWireBus.drawBuses" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'B' )
+        .LegacyHotkeyName( "Begin Bus" )
+        .MenuText( _( "Add Bus" ) )
+        .Tooltip( _( "Add a bus" ) )
+        .Icon( BITMAPS::add_bus )
+        .Flags( AF_ACTIVATE )
+        .Parameter( &drawBusActionParam ) );
 
 TOOL_ACTION EE_ACTIONS::unfoldBus( "eeschema.InteractiveDrawingLineWireBus.unfoldBus",
         AS_GLOBAL,
@@ -914,11 +1015,16 @@ TOOL_ACTION EE_ACTIONS::unfoldBus( "eeschema.InteractiveDrawingLineWireBus.unfol
                                    BITMAPS::INVALID_BITMAP, AF_ACTIVATE );
 
 const DRAW_SEGMENT_EVENT_PARAMS drawLinesActionParam = { LAYER_NOTES, false, nullptr };
-TOOL_ACTION EE_ACTIONS::drawLines( "eeschema.InteractiveDrawingLineWireBus.drawLines",
-        AS_GLOBAL,
-        'I', LEGACY_HK_NAME( "Add Graphic PolyLine" ),
-        _( "Add Lines" ), _( "Draw graphic lines" ),
-        BITMAPS::add_graphical_segments, AF_ACTIVATE, (void*) &drawLinesActionParam );
+TOOL_ACTION EE_ACTIONS::drawLines( TOOL_ACTION_ARGS()
+        .Name( "eeschema.InteractiveDrawingLineWireBus.drawLines" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'I' )
+        .LegacyHotkeyName( "Add Graphic PolyLine" )
+        .MenuText( _( "Add Lines" ) )
+        .Tooltip( _( "Draw graphic lines" ) )
+        .Icon( BITMAPS::add_graphical_segments )
+        .Flags( AF_ACTIVATE )
+        .Parameter( &drawLinesActionParam ) );
 
 TOOL_ACTION EE_ACTIONS::undoLastSegment( "eeschema.InteractiveDrawingLineWireBus.undoLastSegment",
         AS_GLOBAL,
diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h
index 1a32aa43c0..5d5c48641f 100644
--- a/include/tool/tool_action.h
+++ b/include/tool/tool_action.h
@@ -28,6 +28,7 @@
 #ifndef __TOOL_ACTION_H
 #define __TOOL_ACTION_H
 
+#include <any>
 #include <string>
 #include <cassert>
 #include <optional>
@@ -142,7 +143,7 @@ public:
     /**
      * Custom parameter to pass information to the tool.
      */
-    TOOL_ACTION_ARGS& Parameter( void* aParam )
+    TOOL_ACTION_ARGS& Parameter( std::any aParam )
     {
         m_param = aParam;
         return *this;
@@ -175,7 +176,7 @@ protected:
 
     std::optional<BITMAPS>              m_icon;
 
-    std::optional<void*>                m_param;
+    std::any                            m_param;
 };
 
 /**
@@ -197,8 +198,7 @@ public:
                  int aDefaultHotKey = 0, const std::string& aLegacyHotKeyName = "",
                  const wxString& aMenuText = wxEmptyString,
                  const wxString& aTooltip = wxEmptyString,
-                 BITMAPS aIcon = static_cast<BITMAPS>( 0 ), TOOL_ACTION_FLAGS aFlags = AF_NONE,
-                 void* aParam = nullptr );
+                 BITMAPS aIcon = static_cast<BITMAPS>( 0 ), TOOL_ACTION_FLAGS aFlags = AF_NONE);
 
     ~TOOL_ACTION();
 
@@ -278,7 +278,38 @@ public:
 
     TOOL_ACTION_SCOPE GetScope() const { return m_scope; }
 
-    void* GetParam() const { return m_param; }
+    /**
+     * Return a non-standard parameter assigned to the action.
+     */
+    template<typename T>
+    T GetParam() const
+    {
+#ifdef WX_COMPATIBILITY
+        wxASSERT_MSG( m_param.has_value(), "Attempted to get a parameter from an action with no parameter." );
+#else
+        assert( m_param.has_value() );
+#endif
+
+        T param;
+
+        try
+        {
+            param = std::any_cast<T>( m_param );
+        }
+        catch( const std::bad_any_cast& e )
+        {
+#ifdef WX_COMPATIBILITY
+            wxASSERT_MSG( false,
+                          wxString::Format( "Requested parameter type %s from action with parameter type %s.",
+                                            typeid(T).name(), m_param.type().name() ) );
+#else
+            assert( false );
+#endif
+        }
+
+        return param;
+    }
+
 
     /**
      * Return name of the tool associated with the action. It is basically the action name
@@ -337,7 +368,7 @@ protected:
     std::optional<int>   m_uiid;           // ID to use when interacting with the UI (if empty, generate one)
 
     TOOL_ACTION_FLAGS    m_flags;
-    void*                m_param;          // Generic parameter
+    std::any             m_param;          // Generic parameter
 };
 
 #endif
diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h
index 5a7b36e9a1..5e5e7145b8 100644
--- a/include/tool/tool_event.h
+++ b/include/tool/tool_event.h
@@ -27,6 +27,7 @@
 #ifndef __TOOL_EVENT_H
 #define __TOOL_EVENT_H
 
+#include <any>
 #include <cstdio>
 #include <deque>
 #include <iterator>
@@ -163,28 +164,26 @@ public:
     const std::string Format() const;
 
     TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory = TC_NONE, TOOL_ACTIONS aAction = TA_NONE,
-                TOOL_ACTION_SCOPE aScope = AS_GLOBAL, void* aParameter = nullptr ) :
+                TOOL_ACTION_SCOPE aScope = AS_GLOBAL ) :
         m_category( aCategory ),
         m_actions( aAction ),
         m_scope( aScope ),
         m_mouseButtons( 0 ),
         m_keyCode( 0 ),
         m_modifiers( 0 ),
-        m_param( aParameter ),
         m_firstResponder( nullptr )
     {
         init();
     }
 
     TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction, int aExtraParam,
-                TOOL_ACTION_SCOPE aScope = AS_GLOBAL, void* aParameter = nullptr ) :
+                TOOL_ACTION_SCOPE aScope = AS_GLOBAL ) :
         m_category( aCategory ),
         m_actions( aAction ),
         m_scope( aScope ),
         m_mouseButtons( 0 ),
         m_keyCode( 0 ),
         m_modifiers( 0 ),
-        m_param( aParameter ),
         m_firstResponder( nullptr )
     {
         if( aCategory == TC_MOUSE )
@@ -209,15 +208,13 @@ public:
     }
 
     TOOL_EVENT( TOOL_EVENT_CATEGORY aCategory, TOOL_ACTIONS aAction,
-            const std::string& aExtraParam, TOOL_ACTION_SCOPE aScope = AS_GLOBAL,
-            void* aParameter = nullptr ) :
+            const std::string& aExtraParam, TOOL_ACTION_SCOPE aScope = AS_GLOBAL ) :
         m_category( aCategory ),
         m_actions( aAction ),
         m_scope( aScope ),
         m_mouseButtons( 0 ),
         m_keyCode( 0 ),
         m_modifiers( 0 ),
-        m_param( aParameter ),
         m_firstResponder( nullptr )
     {
         if( aCategory == TC_COMMAND || aCategory == TC_MESSAGE )
@@ -439,15 +436,32 @@ public:
      * target tool.
      */
     template<typename T>
-    inline T Parameter() const
+    T Parameter() const
     {
-        // Exhibit #798 on why I love to hate C++
-        // - reinterpret_cast needs to be used for pointers
-        // - static_cast must be used for enums
-        // - templates can't usefully distinguish between pointer and non-pointer types
-        // Fortunately good old C's cast can be a reinterpret_cast or a static_cast, and
-        // C99 gave us intptr_t which is guaranteed to be round-trippable with a pointer.
-        return (T) reinterpret_cast<intptr_t>( m_param );
+#ifdef WX_COMPATIBILITY
+        wxASSERT_MSG( m_param.has_value(), "Attempted to get a parameter from an event with no parameter." );
+#else
+        assert( m_param.has_value() );
+#endif
+
+        T param;
+
+        try
+        {
+            param = std::any_cast<T>( m_param );
+        }
+        catch( const std::bad_any_cast& e )
+        {
+#ifdef WX_COMPATIBILITY
+            wxASSERT_MSG( false,
+                          wxString::Format( "Requested parameter type %s from event with parameter type %s.",
+                                            typeid(T).name(), m_param.type().name() ) );
+#else
+            assert( false );
+#endif
+        }
+
+        return param;
     }
 
     /**
@@ -456,10 +470,9 @@ public:
      *
      * @param aParam is the new parameter.
      */
-    template<typename T>
-    void SetParameter(T aParam)
+    void SetParameter(const std::any& aParam)
     {
-        m_param = reinterpret_cast<void*>( aParam );
+        m_param = aParam;
     }
 
     std::optional<int> GetCommandId() const
@@ -545,7 +558,7 @@ private:
     int m_modifiers;
 
     ///< Generic parameter used for passing non-standard data.
-    void* m_param;
+    std::any m_param;
 
     ///< The first tool to receive the event
     TOOL_BASE* m_firstResponder;
diff --git a/pagelayout_editor/tools/pl_actions.cpp b/pagelayout_editor/tools/pl_actions.cpp
index 4ce2cb32e5..f9746621f6 100644
--- a/pagelayout_editor/tools/pl_actions.cpp
+++ b/pagelayout_editor/tools/pl_actions.cpp
@@ -39,25 +39,41 @@
 
 // PL_DRAWING_TOOLS
 //
-TOOL_ACTION PL_ACTIONS::drawLine( "plEditor.InteractiveDrawing.drawLine",
-        AS_GLOBAL, 0, "",
-        _( "Add Line" ), _( "Add a line" ),
-        BITMAPS::add_graphical_segments, AF_ACTIVATE, (void*) DS_DATA_ITEM::DS_SEGMENT );
+TOOL_ACTION PL_ACTIONS::drawLine( TOOL_ACTION_ARGS()
+        .Name( "plEditor.InteractiveDrawing.drawLine" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Line" ) )
+        .Tooltip( _( "Add a line" ) )
+        .Icon( BITMAPS::add_graphical_segments )
+        .Flags( AF_ACTIVATE )
+        .Parameter( DS_DATA_ITEM::DS_SEGMENT ) );
 
-TOOL_ACTION PL_ACTIONS::drawRectangle( "plEditor.InteractiveDrawing.drawRectangle",
-        AS_GLOBAL, 0, "",
-        _( "Add Rectangle" ), _( "Add a rectangle" ),
-        BITMAPS::add_rectangle, AF_ACTIVATE, (void*) DS_DATA_ITEM::DS_RECT );
+TOOL_ACTION PL_ACTIONS::drawRectangle( TOOL_ACTION_ARGS()
+        .Name( "plEditor.InteractiveDrawing.drawRectangle" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Rectangle" ) )
+        .Tooltip( _( "Add a rectangle" ) )
+        .Icon( BITMAPS::add_rectangle )
+        .Flags( AF_ACTIVATE )
+        .Parameter( DS_DATA_ITEM::DS_RECT ) );
 
-TOOL_ACTION PL_ACTIONS::placeText( "plEditor.InteractiveDrawing.placeText",
-        AS_GLOBAL, 0, "",
-        _( "Add Text" ), _( "Add a text item" ),
-        BITMAPS::text, AF_ACTIVATE, (void*) DS_DATA_ITEM::DS_TEXT );
+TOOL_ACTION PL_ACTIONS::placeText( TOOL_ACTION_ARGS()
+        .Name( "plEditor.InteractiveDrawing.placeText" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Text" ) )
+        .Tooltip( _( "Add a text item" ) )
+        .Icon( BITMAPS::text )
+        .Flags( AF_ACTIVATE )
+        .Parameter( DS_DATA_ITEM::DS_TEXT ) );
 
-TOOL_ACTION PL_ACTIONS::placeImage( "plEditor.InteractiveDrawing.placeImage",
-        AS_GLOBAL, 0, "",
-        _( "Add Bitmap" ), _( "Add a bitmap image" ),
-        BITMAPS::image, AF_ACTIVATE, (void*) DS_DATA_ITEM::DS_BITMAP );
+TOOL_ACTION PL_ACTIONS::placeImage( TOOL_ACTION_ARGS()
+        .Name( "plEditor.InteractiveDrawing.placeImage" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Bitmap" ) )
+        .Tooltip( _( "Add a bitmap image" ) )
+        .Icon( BITMAPS::image )
+        .Flags( AF_ACTIVATE )
+        .Parameter( DS_DATA_ITEM::DS_BITMAP ) );
 
 
 // PL_EDIT_TOOL
diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp
index 7dfed8a7d1..73eb1d396b 100644
--- a/pcbnew/router/router_tool.cpp
+++ b/pcbnew/router/router_tool.cpp
@@ -20,6 +20,7 @@
  * with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "tool/tool_action.h"
 #include <wx/hyperlink.h>
 #include <advanced_config.h>
 
@@ -102,79 +103,103 @@ enum VIA_ACTION_FLAGS
 #undef _
 #define _(s) s
 
-static const TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack",
-        AS_CONTEXT,
-        WXK_END, "",
-        _( "Finish Track" ),  _( "Stops laying the current track." ),
-        BITMAPS::checked_ok );
+static const TOOL_ACTION ACT_EndTrack( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.EndTrack" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( WXK_END )
+        .MenuText( _( "Finish Track" ) )
+        .Tooltip( _( "Stops laying the current track." ) )
+        .Icon( BITMAPS::checked_ok ) );
 
-static const TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia",
-        AS_CONTEXT,
-        'V', LEGACY_HK_NAME( "Add Through Via" ),
-        _( "Place Through Via" ),
-        _( "Adds a through-hole via at the end of currently routed track." ),
-        BITMAPS::via, AF_NONE, (void*) VIA_ACTION_FLAGS::VIA );
+static const TOOL_ACTION ACT_PlaceThroughVia( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.PlaceVia" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( 'V' )
+        .LegacyHotkeyName( "Add Through Via" )
+        .MenuText( _( "Place Through Via" ) )
+        .Tooltip( _( "Adds a through-hole via at the end of currently routed track." ) )
+        .Icon( BITMAPS::via )
+        .Flags( AF_NONE )
+        .Parameter( VIA_ACTION_FLAGS::VIA ) );
 
-static const TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia",
-        AS_CONTEXT,
-        MD_ALT + MD_SHIFT + 'V', LEGACY_HK_NAME( "Add Blind/Buried Via" ),
-        _( "Place Blind/Buried Via" ),
-        _( "Adds a blind or buried via at the end of currently routed track."),
-        BITMAPS::via_buried, AF_NONE, (void*) VIA_ACTION_FLAGS::BLIND_VIA );
+static const TOOL_ACTION ACT_PlaceBlindVia( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.PlaceBlindVia" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( MD_ALT + MD_SHIFT + 'V' )
+        .LegacyHotkeyName( "Add Blind/Buried Via" )
+        .MenuText( _( "Place Blind/Buried Via" ) )
+        .Tooltip( _( "Adds a blind or buried via at the end of currently routed track.") )
+        .Icon( BITMAPS::via_buried )
+        .Flags( AF_NONE )
+        .Parameter( VIA_ACTION_FLAGS::BLIND_VIA ) );
 
-static const TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia",
-        AS_CONTEXT,
-        MD_CTRL + 'V', LEGACY_HK_NAME( "Add MicroVia" ),
-        _( "Place Microvia" ), _( "Adds a microvia at the end of currently routed track." ),
-        BITMAPS::via_microvia, AF_NONE, (void*) VIA_ACTION_FLAGS::MICROVIA );
+static const TOOL_ACTION ACT_PlaceMicroVia( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.PlaceMicroVia" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( MD_CTRL + 'V' )
+        .LegacyHotkeyName( "Add MicroVia" )
+        .MenuText( _( "Place Microvia" ) )
+        .Tooltip( _( "Adds a microvia at the end of currently routed track." ) )
+        .Icon( BITMAPS::via_microvia )
+        .Flags( AF_NONE )
+        .Parameter( VIA_ACTION_FLAGS::MICROVIA ) );
 
-static const TOOL_ACTION ACT_SelLayerAndPlaceThroughVia(
-        "pcbnew.InteractiveRouter.SelLayerAndPlaceVia",
-        AS_CONTEXT,
-        '<', LEGACY_HK_NAME( "Select Layer and Add Through Via" ),
-        _( "Select Layer and Place Through Via..." ),
-        _( "Select a layer, then add a through-hole via at the end of currently routed track." ),
-        BITMAPS::select_w_layer, AF_NONE,
-        (void*) ( VIA_ACTION_FLAGS::VIA | VIA_ACTION_FLAGS::SELECT_LAYER ) );
+static const TOOL_ACTION ACT_SelLayerAndPlaceThroughVia( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.SelLayerAndPlaceVia" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( '<' )
+        .LegacyHotkeyName( "Select Layer and Add Through Via" )
+        .MenuText( _( "Select Layer and Place Through Via..." ) )
+        .Tooltip( _( "Select a layer, then add a through-hole via at the end of currently routed track." ) )
+        .Icon( BITMAPS::select_w_layer )
+        .Flags( AF_NONE )
+        .Parameter( VIA_ACTION_FLAGS::VIA | VIA_ACTION_FLAGS::SELECT_LAYER ) );
 
-static const TOOL_ACTION ACT_SelLayerAndPlaceBlindVia(
-        "pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia",
-        AS_CONTEXT,
-        MD_ALT + '<', LEGACY_HK_NAME( "Select Layer and Add Blind/Buried Via" ),
-        _( "Select Layer and Place Blind/Buried Via..." ),
-        _( "Select a layer, then add a blind or buried via at the end of currently routed track." ),
-        BITMAPS::select_w_layer, AF_NONE,
-        (void*) ( VIA_ACTION_FLAGS::BLIND_VIA | VIA_ACTION_FLAGS::SELECT_LAYER ) );
+static const TOOL_ACTION ACT_SelLayerAndPlaceBlindVia( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.SelLayerAndPlaceBlindVia" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( MD_ALT + '<' )
+        .LegacyHotkeyName( "Select Layer and Add Blind/Buried Via" )
+        .MenuText( _( "Select Layer and Place Blind/Buried Via..." ) )
+        .Tooltip( _( "Select a layer, then add a blind or buried via at the end of currently routed track." ) )
+        .Icon( BITMAPS::select_w_layer )
+        .Flags( AF_NONE )
+        .Parameter( VIA_ACTION_FLAGS::BLIND_VIA | VIA_ACTION_FLAGS::SELECT_LAYER ) );
 
-static const TOOL_ACTION ACT_SelLayerAndPlaceMicroVia(
-        "pcbnew.InteractiveRouter.SelLayerAndPlaceMicroVia",
-        AS_CONTEXT,
-        0, "",
-        _( "Select Layer and Place Micro Via..." ),
-        _( "Select a layer, then add a micro via at the end of currently routed track." ),
-        BITMAPS::select_w_layer, AF_NONE,
-        (void*) ( VIA_ACTION_FLAGS::MICROVIA | VIA_ACTION_FLAGS::SELECT_LAYER ) );
+static const TOOL_ACTION ACT_SelLayerAndPlaceMicroVia( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.SelLayerAndPlaceMicroVia" )
+        .Scope( AS_CONTEXT )
+        .MenuText( _( "Select Layer and Place Micro Via..." ) )
+        .Tooltip( _( "Select a layer, then add a micro via at the end of currently routed track." ) )
+        .Icon( BITMAPS::select_w_layer )
+        .Flags( AF_NONE )
+        .Parameter( VIA_ACTION_FLAGS::MICROVIA | VIA_ACTION_FLAGS::SELECT_LAYER ) );
 
-static const TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackViaSize",
-        AS_CONTEXT,
-        'Q', LEGACY_HK_NAME( "Custom Track/Via Size" ),
-        _( "Custom Track/Via Size..." ),
-        _( "Shows a dialog for changing the track width and via size." ),
-        BITMAPS::width_track );
+static const TOOL_ACTION ACT_CustomTrackWidth( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.CustomTrackViaSize" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( 'Q' )
+        .LegacyHotkeyName( "Custom Track/Via Size" )
+        .MenuText( _( "Custom Track/Via Size..." ) )
+        .Tooltip( _( "Shows a dialog for changing the track width and via size." ) )
+        .Icon( BITMAPS::width_track ) );
 
-static const TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture",
-        AS_CONTEXT,
-        '/', LEGACY_HK_NAME( "Switch Track Posture" ),
-        _( "Switch Track Posture" ),
-        _( "Switches posture of the currently routed track." ),
-        BITMAPS::change_entry_orient );
+static const TOOL_ACTION ACT_SwitchPosture( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.SwitchPosture" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( '/' )
+        .LegacyHotkeyName( "Switch Track Posture" )
+        .MenuText( _( "Switch Track Posture" ) )
+        .Tooltip( _( "Switches posture of the currently routed track." ) )
+        .Icon( BITMAPS::change_entry_orient ) );
 
-static const TOOL_ACTION ACT_SwitchCornerMode( "pcbnew.InteractiveRouter.SwitchRounding",
-        AS_CONTEXT,
-        MD_CTRL + '/', "",
-        _( "Track Corner Mode" ),
-        _( "Switches between sharp/rounded and 45°/90° corners when routing tracks." ),
-        BITMAPS::switch_corner_rounding_shape );
+static const TOOL_ACTION ACT_SwitchCornerMode( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.SwitchRounding" )
+        .Scope( AS_CONTEXT )
+        .DefaultHotkey( MD_CTRL + '/' )
+        .MenuText( _( "Track Corner Mode" ) )
+        .Tooltip( _( "Switches between sharp/rounded and 45°/90° corners when routing tracks." ) )
+        .Icon( BITMAPS::switch_corner_rounding_shape ) );
 
 #undef _
 #define _(s) wxGetTranslation((s))
@@ -1013,7 +1038,7 @@ int ROUTER_TOOL::handleLayerSwitch( const TOOL_EVENT& aEvent, bool aForceVia )
     // Otherwise it is one of the router-specific via commands
     if( targetLayer == UNDEFINED_LAYER )
     {
-        const int actViaFlags = aEvent.Parameter<intptr_t>();
+        const int actViaFlags = aEvent.Parameter<int>();
         selectLayer           = actViaFlags & VIA_ACTION_FLAGS::SELECT_LAYER;
 
         viaType = getViaTypeFromFlags( actViaFlags );
diff --git a/pcbnew/tools/board_inspection_tool.cpp b/pcbnew/tools/board_inspection_tool.cpp
index 6cf17f92fa..c8eb1bc305 100644
--- a/pcbnew/tools/board_inspection_tool.cpp
+++ b/pcbnew/tools/board_inspection_tool.cpp
@@ -1684,7 +1684,7 @@ int BOARD_INSPECTION_TOOL::HighlightItem( const TOOL_EVENT& aEvent )
 
 int BOARD_INSPECTION_TOOL::HighlightNet( const TOOL_EVENT& aEvent )
 {
-    int                     netcode     = aEvent.Parameter<intptr_t>();
+    int                     netcode     = aEvent.Parameter<int>();
     KIGFX::RENDER_SETTINGS* settings    = m_toolMgr->GetView()->GetPainter()->GetSettings();
     const std::set<int>&    highlighted = settings->GetHighlightNetCodes();
 
@@ -1946,14 +1946,14 @@ int BOARD_INSPECTION_TOOL::ListNets( const TOOL_EVENT& aEvent )
 
 int BOARD_INSPECTION_TOOL::HideNetInRatsnest( const TOOL_EVENT& aEvent )
 {
-    doHideRatsnestNet( aEvent.Parameter<intptr_t>(), true );
+    doHideRatsnestNet( aEvent.Parameter<int>(), true );
     return 0;
 }
 
 
 int BOARD_INSPECTION_TOOL::ShowNetInRatsnest( const TOOL_EVENT& aEvent )
 {
-    doHideRatsnestNet( aEvent.Parameter<intptr_t>(), false );
+    doHideRatsnestNet( aEvent.Parameter<int>(), false );
     return 0;
 }
 
diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp
index cbbdebfc94..79f91f91c6 100644
--- a/pcbnew/tools/edit_tool.cpp
+++ b/pcbnew/tools/edit_tool.cpp
@@ -689,7 +689,7 @@ int EDIT_TOOL::DragArcTrack( const TOOL_EVENT& aEvent )
                 || evt->IsDblClick( BUT_LEFT ) )
         {
             // Eat mouse-up/-click events that leaked through from the lock dialog
-            if( eatFirstMouseUp && evt->Parameter<intptr_t>() != ACTIONS::CURSOR_CLICK )
+            if( eatFirstMouseUp && evt->Parameter<ACTIONS::CURSOR_EVENT_TYPE>() != ACTIONS::CURSOR_CLICK )
             {
                 eatFirstMouseUp = false;
                 continue;
diff --git a/pcbnew/tools/edit_tool_move_fct.cpp b/pcbnew/tools/edit_tool_move_fct.cpp
index 42403afd86..9b22bbcd9c 100644
--- a/pcbnew/tools/edit_tool_move_fct.cpp
+++ b/pcbnew/tools/edit_tool_move_fct.cpp
@@ -716,7 +716,7 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, const wxString& aCommi
         else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) || isSkip )
         {
             // Eat mouse-up/-click events that leaked through from the lock dialog
-            if( eatFirstMouseUp && evt->Parameter<intptr_t>() != ACTIONS::CURSOR_CLICK )
+            if( eatFirstMouseUp && evt->Parameter<ACTIONS::CURSOR_EVENT_TYPE>() != ACTIONS::CURSOR_CLICK )
             {
                 eatFirstMouseUp = false;
                 continue;
diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp
index cac3d5dfc0..ac351e4585 100644
--- a/pcbnew/tools/pcb_actions.cpp
+++ b/pcbnew/tools/pcb_actions.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "pcb_actions.h"
+#include "tool/tool_action.h"
 #include "tool/tool_event.h"
 #include <pcbnew_id.h>
 #include <bitmaps.h>
@@ -82,11 +83,16 @@ TOOL_ACTION PCB_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line",
         _( "Draw Line" ), _( "Draw a line" ),
         BITMAPS::add_graphical_segments, AF_ACTIVATE );
 
-TOOL_ACTION PCB_ACTIONS::drawPolygon( "pcbnew.InteractiveDrawing.graphicPolygon",
-        AS_GLOBAL,
-        MD_SHIFT + MD_CTRL + 'P', LEGACY_HK_NAME( "Draw Graphic Polygon" ),
-        _( "Draw Graphic Polygon" ), _( "Draw a graphic polygon" ),
-        BITMAPS::add_graphical_polygon, AF_ACTIVATE, (void*) ZONE_MODE::GRAPHIC_POLYGON );
+TOOL_ACTION PCB_ACTIONS::drawPolygon( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveDrawing.graphicPolygon" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + MD_CTRL + 'P' )
+        .LegacyHotkeyName( "Draw Graphic Polygon" )
+        .MenuText( _( "Draw Graphic Polygon" ) )
+        .Tooltip( _( "Draw a graphic polygon" ) )
+        .Icon( BITMAPS::add_graphical_polygon )
+        .Flags( AF_ACTIVATE )
+        .Parameter( ZONE_MODE::GRAPHIC_POLYGON ) );
 
 TOOL_ACTION PCB_ACTIONS::drawRectangle( "pcbnew.InteractiveDrawing.rectangle",
         AS_GLOBAL, 0, "",
@@ -159,16 +165,20 @@ TOOL_ACTION PCB_ACTIONS::drawLeader( "pcbnew.InteractiveDrawing.leader",
         _( "Add Leader" ), _( "Add a leader dimension" ),
         BITMAPS::add_leader, AF_ACTIVATE );
 
-TOOL_ACTION PCB_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone",
-        AS_GLOBAL,
+TOOL_ACTION PCB_ACTIONS::drawZone( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveDrawing.zone" )
+        .Scope( AS_GLOBAL )
 #ifdef __WXOSX_MAC__
-        MD_ALT + 'Z',
+        .DefaultHotkey( MD_ALT + 'Z' )
 #else
-        MD_SHIFT + MD_CTRL + 'Z',
+        .DefaultHotkey( MD_SHIFT + MD_CTRL + 'Z' )
 #endif
-        LEGACY_HK_NAME( "Add Filled Zone" ),
-        _( "Add Filled Zone" ), _( "Add a filled zone" ),
-        BITMAPS::add_zone, AF_ACTIVATE, (void*) ZONE_MODE::ADD );
+        .LegacyHotkeyName( "Add Filled Zone" )
+        .MenuText( _( "Add Filled Zone" ) )
+        .Tooltip( _( "Add a filled zone" ) )
+        .Icon( BITMAPS::add_zone )
+        .Flags( AF_ACTIVATE )
+        .Parameter( ZONE_MODE::ADD ) );
 
 TOOL_ACTION PCB_ACTIONS::drawVia( "pcbnew.InteractiveDrawing.via",
         AS_GLOBAL,
@@ -176,23 +186,38 @@ TOOL_ACTION PCB_ACTIONS::drawVia( "pcbnew.InteractiveDrawing.via",
         _( "Add Vias" ), _( "Add free-standing vias" ),
         BITMAPS::add_via, AF_ACTIVATE );
 
-TOOL_ACTION PCB_ACTIONS::drawRuleArea( "pcbnew.InteractiveDrawing.ruleArea",
-        AS_GLOBAL,
-        MD_SHIFT + MD_CTRL + 'K', LEGACY_HK_NAME( "Add Keepout Area" ),
-        _( "Add Rule Area" ), _( "Add a rule area (keepout)" ),
-        BITMAPS::add_keepout_area, AF_ACTIVATE, (void*) ZONE_MODE::ADD );
+TOOL_ACTION PCB_ACTIONS::drawRuleArea( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveDrawing.ruleArea" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + MD_CTRL + 'K' )
+        .LegacyHotkeyName( "Add Keepout Area" )
+        .MenuText( _( "Add Rule Area" ) )
+        .Tooltip( _( "Add a rule area (keepout)" ) )
+        .Icon( BITMAPS::add_keepout_area )
+        .Flags( AF_ACTIVATE )
+        .Parameter( ZONE_MODE::ADD ) );
 
-TOOL_ACTION PCB_ACTIONS::drawZoneCutout( "pcbnew.InteractiveDrawing.zoneCutout",
-        AS_GLOBAL,
-        MD_SHIFT + 'C', LEGACY_HK_NAME( "Add a Zone Cutout" ),
-        _( "Add a Zone Cutout" ), _( "Add a cutout area of an existing zone" ),
-        BITMAPS::add_zone_cutout, AF_ACTIVATE, (void*) ZONE_MODE::CUTOUT );
+TOOL_ACTION PCB_ACTIONS::drawZoneCutout( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveDrawing.zoneCutout" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + 'C' )
+        .LegacyHotkeyName( "Add a Zone Cutout" )
+        .MenuText( _( "Add a Zone Cutout" ) )
+        .Tooltip( _( "Add a cutout area of an existing zone" ) )
+        .Icon( BITMAPS::add_zone_cutout )
+        .Flags(  AF_ACTIVATE )
+        .Parameter( ZONE_MODE::CUTOUT ) );
 
-TOOL_ACTION PCB_ACTIONS::drawSimilarZone( "pcbnew.InteractiveDrawing.similarZone",
-        AS_GLOBAL,
-        MD_SHIFT + MD_CTRL + '.', LEGACY_HK_NAME( "Add a Similar Zone" ),
-        _( "Add a Similar Zone" ), _( "Add a zone with the same settings as an existing zone" ),
-        BITMAPS::add_zone, AF_ACTIVATE, (void*) ZONE_MODE::SIMILAR );
+TOOL_ACTION PCB_ACTIONS::drawSimilarZone( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveDrawing.similarZone" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + MD_CTRL + '.' )
+        .LegacyHotkeyName( "Add a Similar Zone" )
+        .MenuText( _( "Add a Similar Zone" ) )
+        .Tooltip( _( "Add a zone with the same settings as an existing zone" ) )
+        .Icon( BITMAPS::add_zone )
+        .Flags( AF_ACTIVATE )
+        .Parameter( ZONE_MODE::SIMILAR ) );
 
 TOOL_ACTION PCB_ACTIONS::placeImportedGraphics( "pcbnew.InteractiveDrawing.placeImportedGraphics",
         AS_GLOBAL,
@@ -307,18 +332,28 @@ TOOL_ACTION PCB_ACTIONS::createArray( "pcbnew.InteractiveEdit.createArray",
         _( "Create Array..." ), _( "Create array" ),
         BITMAPS::array, AF_ACTIVATE );
 
-TOOL_ACTION PCB_ACTIONS::rotateCw( "pcbnew.InteractiveEdit.rotateCw",
-        AS_GLOBAL,
+TOOL_ACTION PCB_ACTIONS::rotateCw( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveEdit.rotateCw" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + 'R' )
         // Don't be tempted to remove "Modern Toolset only".  It's in the legacy property name.
-        MD_SHIFT + 'R', LEGACY_HK_NAME( "Rotate Item Clockwise (Modern Toolset only)" ),
-        _( "Rotate Clockwise" ), _( "Rotates selected item(s) clockwise" ),
-        BITMAPS::rotate_cw, AF_NONE, (void*) -1 );
+        .LegacyHotkeyName( "Rotate Item Clockwise (Modern Toolset only)" )
+        .MenuText( _( "Rotate Clockwise" ) )
+        .Tooltip( _( "Rotates selected item(s) clockwise" ) )
+        .Icon( BITMAPS::rotate_cw )
+        .Flags( AF_NONE )
+        .Parameter( -1 ) );
 
-TOOL_ACTION PCB_ACTIONS::rotateCcw( "pcbnew.InteractiveEdit.rotateCcw",
-        AS_GLOBAL,
-        'R', LEGACY_HK_NAME( "Rotate Item" ),
-        _( "Rotate Counterclockwise" ), _( "Rotates selected item(s) counterclockwise" ),
-        BITMAPS::rotate_ccw, AF_NONE, (void*) 1 );
+TOOL_ACTION PCB_ACTIONS::rotateCcw( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveEdit.rotateCcw" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'R' )
+        .LegacyHotkeyName( "Rotate Item" )
+        .MenuText( _( "Rotate Counterclockwise" ) )
+        .Tooltip( _( "Rotates selected item(s) counterclockwise" ) )
+        .Icon( BITMAPS::rotate_ccw )
+        .Flags( AF_NONE )
+        .Parameter( 1 ) );
 
 TOOL_ACTION PCB_ACTIONS::flip( "pcbnew.InteractiveEdit.flip",
         AS_GLOBAL,
@@ -367,11 +402,16 @@ TOOL_ACTION PCB_ACTIONS::filletLines( "pcbnew.InteractiveEdit.filletLines",
         AS_GLOBAL, 0, "",
         _( "Fillet Lines" ), _( "Adds arcs tangent to the selected lines" ) );
 
-TOOL_ACTION PCB_ACTIONS::deleteFull( "pcbnew.InteractiveEdit.deleteFull",
-        AS_GLOBAL,
-        MD_SHIFT + WXK_DELETE, LEGACY_HK_NAME( "Delete Full Track" ),
-        _( "Delete Full Track" ), _( "Deletes selected item(s) and copper connections" ),
-        BITMAPS::delete_cursor, AF_NONE, (void*) REMOVE_FLAGS::ALT );
+TOOL_ACTION PCB_ACTIONS::deleteFull( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveEdit.deleteFull" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + WXK_DELETE )
+        .LegacyHotkeyName( "Delete Full Track" )
+        .MenuText( _( "Delete Full Track" ) )
+        .Tooltip( _( "Deletes selected item(s) and copper connections" ) )
+        .Icon( BITMAPS::delete_cursor )
+        .Flags( AF_NONE )
+        .Parameter( REMOVE_FLAGS::ALT ) );
 
 TOOL_ACTION PCB_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
         AS_GLOBAL,
@@ -531,28 +571,41 @@ TOOL_ACTION PCB_ACTIONS::cleanupGraphics( "pcbnew.GlobalEdit.cleanupGraphics",
 
 // MICROWAVE_TOOL
 //
-TOOL_ACTION PCB_ACTIONS::microwaveCreateGap( "pcbnew.MicrowaveTool.createGap",
-        AS_GLOBAL, 0, "",
-        _( "Add Microwave Gap" ), _( "Create gap of specified length for microwave applications" ),
-        BITMAPS::mw_add_gap, AF_ACTIVATE, (void*) MICROWAVE_FOOTPRINT_SHAPE::GAP );
+TOOL_ACTION PCB_ACTIONS::microwaveCreateGap( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.MicrowaveTool.createGap" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Microwave Gap" ) )
+        .Tooltip( _( "Create gap of specified length for microwave applications" ) )
+        .Icon( BITMAPS::mw_add_gap )
+        .Flags( AF_ACTIVATE )
+        .Parameter( MICROWAVE_FOOTPRINT_SHAPE::GAP ) );
 
-TOOL_ACTION PCB_ACTIONS::microwaveCreateStub( "pcbnew.MicrowaveTool.createStub",
-        AS_GLOBAL, 0, "",
-        _( "Add Microwave Stub" ),
-        _( "Create stub of specified length for microwave applications" ),
-        BITMAPS::mw_add_stub, AF_ACTIVATE, (void*) MICROWAVE_FOOTPRINT_SHAPE::STUB );
+TOOL_ACTION PCB_ACTIONS::microwaveCreateStub( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.MicrowaveTool.createStub" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Microwave Stub" ) )
+        .Tooltip( _( "Create stub of specified length for microwave applications" ) )
+        .Icon( BITMAPS::mw_add_stub )
+        .Flags( AF_ACTIVATE )
+        .Parameter( MICROWAVE_FOOTPRINT_SHAPE::STUB ) );
 
-TOOL_ACTION PCB_ACTIONS::microwaveCreateStubArc( "pcbnew.MicrowaveTool.createStubArc",
-        AS_GLOBAL, 0, "",
-        _( "Add Microwave Arc Stub" ),
-        _( "Create stub (arc) of specified size for microwave applications" ),
-        BITMAPS::mw_add_stub_arc, AF_ACTIVATE, (void*) MICROWAVE_FOOTPRINT_SHAPE::STUB_ARC );
+TOOL_ACTION PCB_ACTIONS::microwaveCreateStubArc( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.MicrowaveTool.createStubArc" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Microwave Arc Stub" ) )
+        .Tooltip( _( "Create stub (arc) of specified size for microwave applications" ) )
+        .Icon( BITMAPS::mw_add_stub_arc )
+        .Flags( AF_ACTIVATE )
+        .Parameter( MICROWAVE_FOOTPRINT_SHAPE::STUB_ARC ) );
 
-TOOL_ACTION PCB_ACTIONS::microwaveCreateFunctionShape( "pcbnew.MicrowaveTool.createFunctionShape",
-        AS_GLOBAL, 0, "",
-        _( "Add Microwave Polygonal Shape" ),
-        _( "Create a microwave polygonal shape from a list of vertices" ),
-        BITMAPS::mw_add_shape, AF_ACTIVATE, (void*) MICROWAVE_FOOTPRINT_SHAPE::FUNCTION_SHAPE );
+TOOL_ACTION PCB_ACTIONS::microwaveCreateFunctionShape( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.MicrowaveTool.createFunctionShape" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Add Microwave Polygonal Shape" ) )
+        .Tooltip( _( "Create a microwave polygonal shape from a list of vertices" ) )
+        .Icon( BITMAPS::mw_add_shape )
+        .Flags( AF_ACTIVATE )
+        .Parameter( MICROWAVE_FOOTPRINT_SHAPE::FUNCTION_SHAPE ) );
 
 TOOL_ACTION PCB_ACTIONS::microwaveCreateLine( "pcbnew.MicrowaveTool.createLine",
         AS_GLOBAL, 0, "",
@@ -957,173 +1010,271 @@ TOOL_ACTION PCB_ACTIONS::zoneDisplayToggle( "pcbnew.Control.zoneDisplayToggle",
 
 
 // Layer control
-TOOL_ACTION PCB_ACTIONS::layerTop( "pcbnew.Control.layerTop",
-        AS_GLOBAL,
-        WXK_PAGEUP, LEGACY_HK_NAME( "Switch to Component (F.Cu) layer" ),
-        _( "Switch to Component (F.Cu) layer" ), _( "Switch to Component (F.Cu) layer" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) F_Cu );
+TOOL_ACTION PCB_ACTIONS::layerTop( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerTop" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_PAGEUP )
+        .LegacyHotkeyName( "Switch to Component (F.Cu) layer" )
+        .MenuText( _( "Switch to Component (F.Cu) layer" ) )
+        .Tooltip( _( "Switch to Component (F.Cu) layer" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( F_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner1( "pcbnew.Control.layerInner1",
-        AS_GLOBAL,
-        0, LEGACY_HK_NAME( "Switch to Inner layer 1" ),
-        _( "Switch to Inner layer 1" ), _( "Switch to Inner layer 1" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In1_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner1( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner1" )
+        .Scope( AS_GLOBAL )
+        .LegacyHotkeyName( "Switch to Inner layer 1" )
+        .MenuText( _( "Switch to Inner layer 1" ) )
+        .Tooltip( _( "Switch to Inner layer 1" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In1_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner2( "pcbnew.Control.layerInner2",
-        AS_GLOBAL,
-        0, LEGACY_HK_NAME( "Switch to Inner layer 2" ),
-        _( "Switch to Inner layer 2" ), _( "Switch to Inner layer 2" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In2_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner2( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner2" )
+        .Scope( AS_GLOBAL )
+        .LegacyHotkeyName( "Switch to Inner layer 2" )
+        .MenuText( _( "Switch to Inner layer 2" ) )
+        .Tooltip( _( "Switch to Inner layer 2" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In2_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner3( "pcbnew.Control.layerInner3",
-        AS_GLOBAL,
-        0, LEGACY_HK_NAME( "Switch to Inner layer 3" ),
-        _( "Switch to Inner layer 3" ), _( "Switch to Inner layer 3" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In3_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner3( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner3" )
+        .Scope( AS_GLOBAL )
+        .LegacyHotkeyName( "Switch to Inner layer 3" )
+        .MenuText( _( "Switch to Inner layer 3" ) )
+        .Tooltip( _( "Switch to Inner layer 3" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In3_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner4( "pcbnew.Control.layerInner4",
-        AS_GLOBAL,
-        0, LEGACY_HK_NAME( "Switch to Inner layer 4" ),
-        _( "Switch to Inner layer 4" ), _( "Switch to Inner layer 4" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In4_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner4( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner4" )
+        .Scope( AS_GLOBAL )
+        .LegacyHotkeyName( "Switch to Inner layer 4" )
+        .MenuText( _( "Switch to Inner layer 4" ) )
+        .Tooltip( _( "Switch to Inner layer 4" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In4_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner5( "pcbnew.Control.layerInner5",
-        AS_GLOBAL,
-        0, LEGACY_HK_NAME( "Switch to Inner layer 5" ),
-        _( "Switch to Inner layer 5" ), _( "Switch to Inner layer 5" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In5_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner5( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner5" )
+        .Scope( AS_GLOBAL )
+        .LegacyHotkeyName( "Switch to Inner layer 5" )
+        .MenuText( _( "Switch to Inner layer 5" ) )
+        .Tooltip( _( "Switch to Inner layer 5" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In5_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner6( "pcbnew.Control.layerInner6",
-        AS_GLOBAL,
-        0, LEGACY_HK_NAME( "Switch to Inner layer 6" ),
-        _( "Switch to Inner layer 6" ), _( "Switch to Inner layer 6" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In6_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner6( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner6" )
+        .Scope( AS_GLOBAL )
+        .LegacyHotkeyName( "Switch to Inner layer 6" )
+        .MenuText( _( "Switch to Inner layer 6" ) )
+        .Tooltip( _( "Switch to Inner layer 6" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In6_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner7( "pcbnew.Control.layerInner7",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 7" ), _( "Switch to Inner layer 7" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In7_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner7( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner7" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 7" ) )
+        .Tooltip( _( "Switch to Inner layer 7" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In7_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner8( "pcbnew.Control.layerInner8",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 8" ), _( "Switch to Inner layer 8" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In8_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner8( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner8" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 8" ) )
+        .Tooltip( _( "Switch to Inner layer 8" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In8_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner9( "pcbnew.Control.layerInner9",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 9" ), _( "Switch to Inner layer 9" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In9_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner9( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner9" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 9" ) )
+        .Tooltip( _( "Switch to Inner layer 9" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In9_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner10( "pcbnew.Control.layerInner10",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 10" ), _( "Switch to Inner layer 10" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In10_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner10( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner10" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 10" ) )
+        .Tooltip( _( "Switch to Inner layer 10" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In10_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner11( "pcbnew.Control.layerInner11",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 11" ), _( "Switch to Inner layer 11" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In11_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner11( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner11" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 11" ) )
+        .Tooltip( _( "Switch to Inner layer 11" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In11_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner12( "pcbnew.Control.layerInner12",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 12" ), _( "Switch to Inner layer 12" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In12_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner12( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner12" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 12" ) )
+        .Tooltip( _( "Switch to Inner layer 12" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In12_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner13( "pcbnew.Control.layerInner13",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 13" ), _( "Switch to Inner layer 13" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In13_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner13( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner13" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 13" ) )
+        .Tooltip( _( "Switch to Inner layer 13" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In13_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner14( "pcbnew.Control.layerInner14",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 14" ), _( "Switch to Inner layer 14" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In14_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner14( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner14" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 14" ) )
+        .Tooltip( _( "Switch to Inner layer 14" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In14_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner15( "pcbnew.Control.layerInner15",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 15" ), _( "Switch to Inner layer 15" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In15_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner15( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner15" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 15" ) )
+        .Tooltip( _( "Switch to Inner layer 15" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In15_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner16( "pcbnew.Control.layerInner16",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 16" ), _( "Switch to Inner layer 16" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In16_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner16( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner16" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 16" ) )
+        .Tooltip( _( "Switch to Inner layer 16" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In16_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner17( "pcbnew.Control.layerInner17",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 17" ), _( "Switch to Inner layer 17" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In17_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner17( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner17" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 17" ) )
+        .Tooltip( _( "Switch to Inner layer 17" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In17_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner18( "pcbnew.Control.layerInner18",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 18" ), _( "Switch to Inner layer 18" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In18_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner18( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner18" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 18" ) )
+        .Tooltip( _( "Switch to Inner layer 18" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In18_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner19( "pcbnew.Control.layerInner19",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 19" ), _( "Switch to Inner layer 19" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In19_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner19( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner19" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 19" ) )
+        .Tooltip( _( "Switch to Inner layer 19" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In19_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner20( "pcbnew.Control.layerInner20",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 20" ), _( "Switch to Inner layer 20" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In20_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner20( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner20" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 20" ) )
+        .Tooltip( _( "Switch to Inner layer 20" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In20_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner21( "pcbnew.Control.layerInner21",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 21" ), _( "Switch to Inner layer 21" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In21_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner21( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner21" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 21" ) )
+        .Tooltip( _( "Switch to Inner layer 21" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In21_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner22( "pcbnew.Control.layerInner22",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 22" ), _( "Switch to Inner layer 22" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In22_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner22( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner22" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 22" ) )
+        .Tooltip( _( "Switch to Inner layer 22" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In22_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner23( "pcbnew.Control.layerInner23",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 23" ), _( "Switch to Inner layer 23" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In23_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner23( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner23" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 23" ) )
+        .Tooltip( _( "Switch to Inner layer 23" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In23_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner24( "pcbnew.Control.layerInner24",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 24" ), _( "Switch to Inner layer 24" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In24_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner24( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner24" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 24" ) )
+        .Tooltip( _( "Switch to Inner layer 24" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In24_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner25( "pcbnew.Control.layerInner25",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 25" ), _( "Switch to Inner layer 25" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In25_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner25( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner25" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 25" ) )
+        .Tooltip( _( "Switch to Inner layer 25" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In25_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner26( "pcbnew.Control.layerInner26",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 26" ), _( "Switch to Inner layer 26" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In26_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner26( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner26" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 26" ) )
+        .Tooltip( _( "Switch to Inner layer 26" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In26_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner27( "pcbnew.Control.layerInner27",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 27" ), _( "Switch to Inner layer 27" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In27_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner27( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner27" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 27" ) )
+        .Tooltip( _( "Switch to Inner layer 27" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In27_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner28( "pcbnew.Control.layerInner28",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 28" ), _( "Switch to Inner layer 28" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In28_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner28( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner28" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 28" ) )
+        .Tooltip( _( "Switch to Inner layer 28" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In28_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner29( "pcbnew.Control.layerInner29",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 29" ), _( "Switch to Inner layer 29" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In29_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner29( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner29" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 29" ) )
+        .Tooltip( _( "Switch to Inner layer 29" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In29_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerInner30( "pcbnew.Control.layerInner30",
-        AS_GLOBAL, 0, "",
-        _( "Switch to Inner layer 30" ), _( "Switch to Inner layer 30" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) In30_Cu );
+TOOL_ACTION PCB_ACTIONS::layerInner30( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerInner30" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Switch to Inner layer 30" ) )
+        .Tooltip( _( "Switch to Inner layer 30" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( In30_Cu ) );
 
-TOOL_ACTION PCB_ACTIONS::layerBottom( "pcbnew.Control.layerBottom",
-        AS_GLOBAL,
-        WXK_PAGEDOWN, LEGACY_HK_NAME( "Switch to Copper (B.Cu) layer" ),
-        _( "Switch to Copper (B.Cu) layer" ), _( "Switch to Copper (B.Cu) layer" ),
-        BITMAPS::INVALID_BITMAP, AF_NOTIFY, (void*) B_Cu );
+TOOL_ACTION PCB_ACTIONS::layerBottom( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.Control.layerBottom" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( WXK_PAGEDOWN )
+        .LegacyHotkeyName( "Switch to Copper (B.Cu) layer" )
+        .MenuText( _( "Switch to Copper (B.Cu) layer" ) )
+        .Tooltip( _( "Switch to Copper (B.Cu) layer" ) )
+        .Flags( AF_NOTIFY )
+        .Parameter( B_Cu ) );
 
 TOOL_ACTION PCB_ACTIONS::layerNext( "pcbnew.Control.layerNext",
         AS_GLOBAL,
@@ -1263,17 +1414,19 @@ TOOL_ACTION PCB_ACTIONS::pointEditorRemoveCorner( "pcbnew.PointEditor.removeCorn
         _( "Remove Corner" ), _( "Remove corner" ),
         BITMAPS::delete_cursor );
 
-TOOL_ACTION PCB_ACTIONS::pointEditorArcKeepCenter( "pcbnew.PointEditor.arcKeepCenter",
-        AS_GLOBAL, 0, "",
-        _( "Keep arc center, adjust radius" ),
-        _( "Switch arc editing mode to keep center, adjust radius and endpoints" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ARC_EDIT_MODE::KEEP_CENTER_ADJUST_ANGLE_RADIUS );
+TOOL_ACTION PCB_ACTIONS::pointEditorArcKeepCenter( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.PointEditor.arcKeepCenter" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Keep arc center, adjust radius" ) )
+        .Tooltip( _( "Switch arc editing mode to keep center, adjust radius and endpoints" ) )
+        .Parameter( ARC_EDIT_MODE::KEEP_CENTER_ADJUST_ANGLE_RADIUS ) );
 
-TOOL_ACTION PCB_ACTIONS::pointEditorArcKeepEndpoint( "pcbnew.PointEditor.arcKeepEndpoint",
-        AS_GLOBAL, 0, "",
-        _( "Keep arc endpoints or direction of starting point" ),
-        _( "Switch arc editing mode to keep endpoints, or to keep direction of the other point" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) ARC_EDIT_MODE::KEEP_ENDPOINTS_OR_START_DIRECTION );
+TOOL_ACTION PCB_ACTIONS::pointEditorArcKeepEndpoint( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.PointEditor.arcKeepEndpoint" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Keep arc endpoints or direction of starting point" ) )
+        .Tooltip( _( "Switch arc editing mode to keep endpoints, or to keep direction of the other point" ) )
+        .Parameter( ARC_EDIT_MODE::KEEP_ENDPOINTS_OR_START_DIRECTION ) );
 
 
 // GROUP_TOOL
@@ -1435,18 +1588,28 @@ TOOL_ACTION PCB_ACTIONS::autoplaceOffboardComponents( "pcbnew.Autoplacer.autopla
 
 // ROUTER_TOOL
 //
-TOOL_ACTION PCB_ACTIONS::routeSingleTrack( "pcbnew.InteractiveRouter.SingleTrack",
-        AS_GLOBAL,
-        'X', LEGACY_HK_NAME( "Add New Track" ),
-        _( "Route Single Track" ), _( "Route tracks" ),
-        BITMAPS::add_tracks, AF_ACTIVATE, (void*) PNS::PNS_MODE_ROUTE_SINGLE );
+TOOL_ACTION PCB_ACTIONS::routeSingleTrack( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.SingleTrack" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( 'X' )
+        .LegacyHotkeyName( "Add New Track" )
+        .MenuText( _( "Route Single Track" ) )
+        .Tooltip( _( "Route tracks" ) )
+        .Icon( BITMAPS::add_tracks )
+        .Flags( AF_ACTIVATE )
+        .Parameter( PNS::PNS_MODE_ROUTE_SINGLE ) );
 
-TOOL_ACTION PCB_ACTIONS::routeDiffPair( "pcbnew.InteractiveRouter.DiffPair",
-        AS_GLOBAL,
+TOOL_ACTION PCB_ACTIONS::routeDiffPair( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.DiffPair" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( '6' )
         // Don't be tempted to remove "Modern Toolset only".  It's in the legacy property name.
-        '6', LEGACY_HK_NAME( "Route Differential Pair (Modern Toolset only)" ),
-        _( "Route Differential Pair" ), _( "Route differential pairs" ),
-        BITMAPS::ps_diff_pair, AF_ACTIVATE, (void*) PNS::PNS_MODE_ROUTE_DIFF_PAIR );
+        .LegacyHotkeyName( "Route Differential Pair (Modern Toolset only)" )
+        .MenuText( _( "Route Differential Pair" ) )
+        .Tooltip( _( "Route differential pairs" ) )
+        .Icon( BITMAPS::ps_diff_pair )
+        .Flags( AF_ACTIVATE )
+        .Parameter( PNS::PNS_MODE_ROUTE_DIFF_PAIR ) );
 
 TOOL_ACTION PCB_ACTIONS::routerSettingsDialog( "pcbnew.InteractiveRouter.SettingsDialog",
         AS_GLOBAL,
@@ -1459,20 +1622,29 @@ TOOL_ACTION PCB_ACTIONS::routerDiffPairDialog( "pcbnew.InteractiveRouter.DiffPai
         _( "Differential Pair Dimensions..." ), _( "Open Differential Pair Dimension settings" ),
         BITMAPS::ps_diff_pair_gap );
 
-TOOL_ACTION PCB_ACTIONS::routerHighlightMode( "pcbnew.InteractiveRouter.HighlightMode",
-        AS_GLOBAL, 0, "",
-        _( "Router Highlight Mode" ), _( "Switch router to highlight mode" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) PNS::RM_MarkObstacles );
+TOOL_ACTION PCB_ACTIONS::routerHighlightMode( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.HighlightMode" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Router Highlight Mode" ) )
+        .Tooltip( _( "Switch router to highlight mode" ) )
+        .Flags( AF_NONE )
+        .Parameter( PNS::RM_MarkObstacles ) );
 
-TOOL_ACTION PCB_ACTIONS::routerShoveMode( "pcbnew.InteractiveRouter.ShoveMode",
-        AS_GLOBAL, 0, "",
-        _( "Router Shove Mode" ), _( "Switch router to shove mode" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) PNS::RM_Shove );
+TOOL_ACTION PCB_ACTIONS::routerShoveMode( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.ShoveMode" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Router Shove Mode" ) )
+        .Tooltip( _( "Switch router to shove mode" ) )
+        .Flags( AF_NONE )
+        .Parameter( PNS::RM_Shove ) );
 
-TOOL_ACTION PCB_ACTIONS::routerWalkaroundMode( "pcbnew.InteractiveRouter.WalkaroundMode",
-        AS_GLOBAL, 0, "",
-        _( "Router Walkaround Mode" ), _( "Switch router to walkaround mode" ),
-        BITMAPS::INVALID_BITMAP, AF_NONE, (void*) PNS::RM_Walkaround );
+TOOL_ACTION PCB_ACTIONS::routerWalkaroundMode( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.WalkaroundMode" )
+        .Scope( AS_GLOBAL )
+        .MenuText( _( "Router Walkaround Mode" ) )
+        .Tooltip( _( "Switch router to walkaround mode" ) )
+        .Flags( AF_NONE )
+        .Parameter( PNS::RM_Walkaround ) );
 
 TOOL_ACTION PCB_ACTIONS::cycleRouterMode( "pcbnew.InteractiveRouter.CycleRouterMode",
         AS_GLOBAL, 0, "",
@@ -1484,26 +1656,41 @@ TOOL_ACTION PCB_ACTIONS::selectLayerPair( "pcbnew.InteractiveRouter.SelectLayerP
         _( "Set Layer Pair..." ), _( "Change active layer pair for routing" ),
         BITMAPS::select_layer_pair, AF_ACTIVATE );
 
-TOOL_ACTION PCB_ACTIONS::routerTuneSingleTrace( "pcbnew.LengthTuner.TuneSingleTrack",
-        AS_GLOBAL,
+TOOL_ACTION PCB_ACTIONS::routerTuneSingleTrace( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.LengthTuner.TuneSingleTrack" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( '7' )
         // Don't be tempted to remove "Modern Toolset only".  It's in the legacy property name.
-        '7', LEGACY_HK_NAME( "Tune Single Track (Modern Toolset only)" ),
-        _( "Tune length of a single track" ), _( "Tune length of a single track" ),
-        BITMAPS::ps_tune_length, AF_ACTIVATE, (void*) PNS::PNS_MODE_TUNE_SINGLE );
+        .LegacyHotkeyName( "Tune Single Track (Modern Toolset only)" )
+        .MenuText( _( "Tune length of a single track" ) )
+        .Tooltip( _( "Tune length of a single track" ) )
+        .Icon( BITMAPS::ps_tune_length )
+        .Flags( AF_ACTIVATE )
+        .Parameter( PNS::PNS_MODE_TUNE_SINGLE ) );
 
-TOOL_ACTION PCB_ACTIONS::routerTuneDiffPair( "pcbnew.LengthTuner.TuneDiffPair",
-        AS_GLOBAL,
+TOOL_ACTION PCB_ACTIONS::routerTuneDiffPair( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.LengthTuner.TuneDiffPair" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( '8' )
         // Don't be tempted to remove "Modern Toolset only".  It's in the legacy property name.
-        '8', LEGACY_HK_NAME( "Tune Differential Pair Length (Modern Toolset only)" ),
-        _( "Tune length of a differential pair" ), _( "Tune length of a differential pair" ),
-        BITMAPS::ps_diff_pair_tune_length, AF_ACTIVATE, (void*) PNS::PNS_MODE_TUNE_DIFF_PAIR );
+        .LegacyHotkeyName( "Tune Differential Pair Length (Modern Toolset only)" )
+        .MenuText( _( "Tune length of a differential pair" ) )
+        .Tooltip( _( "Tune length of a differential pair" ) )
+        .Icon( BITMAPS::ps_diff_pair_tune_length )
+        .Flags( AF_ACTIVATE )
+        .Parameter( PNS::PNS_MODE_TUNE_DIFF_PAIR ) );
 
-TOOL_ACTION PCB_ACTIONS::routerTuneDiffPairSkew( "pcbnew.LengthTuner.TuneDiffPairSkew",
-        AS_GLOBAL,
+TOOL_ACTION PCB_ACTIONS::routerTuneDiffPairSkew( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.LengthTuner.TuneDiffPairSkew" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( '9' )
         // Don't be tempted to remove "Modern Toolset only".  It's in the legacy property name.
-        '9', LEGACY_HK_NAME( "Tune Differential Pair Skew (Modern Toolset only)" ),
-        _( "Tune skew of a differential pair" ), _( "Tune skew of a differential pair" ),
-        BITMAPS::ps_diff_pair_tune_phase, AF_ACTIVATE, (void*) PNS::PNS_MODE_TUNE_DIFF_PAIR_SKEW );
+        .LegacyHotkeyName( "Tune Differential Pair Skew (Modern Toolset only)" )
+        .MenuText( _( "Tune skew of a differential pair" ) )
+        .Tooltip( _( "Tune skew of a differential pair" ) )
+        .Icon( BITMAPS::ps_diff_pair_tune_phase )
+        .Flags( AF_ACTIVATE )
+        .Parameter( PNS::PNS_MODE_TUNE_DIFF_PAIR_SKEW ) );
 
 TOOL_ACTION PCB_ACTIONS::routerInlineDrag( "pcbnew.InteractiveRouter.InlineDrag",
         AS_CONTEXT );
@@ -1525,26 +1712,32 @@ TOOL_ACTION PCB_ACTIONS::routerAttemptFinish( "pcbnew.InteractiveRouter.AttemptF
         _( "Attempt Finish" ),
         _( "Attempts to complete current route to nearest ratsnest end." ) );
 
-TOOL_ACTION PCB_ACTIONS::routerRouteSelected( "pcbnew.InteractiveRouter.RouteSelected",
-        AS_GLOBAL,
-        MD_SHIFT + 'X', "",
-        _( "Route Selected" ),
-        _( "Sequentially route selected items from ratsnest anchor." ),
-        BITMAPS::INVALID_BITMAP, AF_ACTIVATE, (void *) PNS::PNS_MODE_ROUTE_SINGLE);
+TOOL_ACTION PCB_ACTIONS::routerRouteSelected( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.RouteSelected" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + 'X' )
+        .MenuText( _( "Route Selected" ) )
+        .Tooltip( _( "Sequentially route selected items from ratsnest anchor." ) )
+        .Flags( AF_ACTIVATE )
+        .Parameter( PNS::PNS_MODE_ROUTE_SINGLE ) );
 
-TOOL_ACTION PCB_ACTIONS::routerRouteSelectedFromEnd( "pcbnew.InteractiveRouter.RouteSelectedFromEnd",
-        AS_GLOBAL,
-        MD_SHIFT + 'E', "",
-        _( "Route Selected From Other End" ),
-        _( "Sequentially route selected items from other end of ratsnest anchor." ),
-        BITMAPS::INVALID_BITMAP, AF_ACTIVATE, (void *) PNS::PNS_MODE_ROUTE_SINGLE);
+TOOL_ACTION PCB_ACTIONS::routerRouteSelectedFromEnd( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.RouteSelectedFromEnd" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + 'E' )
+        .MenuText( _( "Route Selected From Other End" ) )
+        .Tooltip( _( "Sequentially route selected items from other end of ratsnest anchor." ) )
+        .Flags( AF_ACTIVATE )
+        .Parameter( PNS::PNS_MODE_ROUTE_SINGLE ) );
 
-TOOL_ACTION PCB_ACTIONS::routerAutorouteSelected( "pcbnew.InteractiveRouter.Autoroute",
-        AS_GLOBAL,
-        MD_SHIFT + 'F', "",
-        _( "Attempt Finish Selected (Autoroute)" ),
-        _( "Sequentially attempt to automatically route all selected pads." ),
-        BITMAPS::INVALID_BITMAP, AF_ACTIVATE, (void *) PNS::PNS_MODE_ROUTE_SINGLE);
+TOOL_ACTION PCB_ACTIONS::routerAutorouteSelected( TOOL_ACTION_ARGS()
+        .Name( "pcbnew.InteractiveRouter.Autoroute" )
+        .Scope( AS_GLOBAL )
+        .DefaultHotkey( MD_SHIFT + 'F' )
+        .MenuText( _( "Attempt Finish Selected (Autoroute)" ) )
+        .Tooltip( _( "Sequentially attempt to automatically route all selected pads." ) )
+        .Flags( AF_ACTIVATE )
+        .Parameter( PNS::PNS_MODE_ROUTE_SINGLE ) );
 
 TOOL_ACTION PCB_ACTIONS::breakTrack( "pcbnew.InteractiveRouter.BreakTrack",
         AS_GLOBAL, 0, "",
diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp
index 579157f12b..4dd8ed7a55 100644
--- a/pcbnew/tools/pcb_selection_tool.cpp
+++ b/pcbnew/tools/pcb_selection_tool.cpp
@@ -1567,7 +1567,7 @@ int PCB_SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
     bool select = aEvent.IsAction( &PCB_ACTIONS::selectNet );
 
     // If we've been passed an argument, just select that netcode1
-    int netcode = (int) aEvent.Parameter<intptr_t>();
+    int netcode = aEvent.Parameter<int>();
 
     if( netcode > 0 )
     {
diff --git a/pcbnew/tools/tool_event_utils.cpp b/pcbnew/tools/tool_event_utils.cpp
index 781c9906ce..3d83283ba6 100644
--- a/pcbnew/tools/tool_event_utils.cpp
+++ b/pcbnew/tools/tool_event_utils.cpp
@@ -39,7 +39,7 @@ EDA_ANGLE TOOL_EVT_UTILS::GetEventRotationAngle( const PCB_BASE_EDIT_FRAME& aFra
     wxASSERT_MSG( IsRotateToolEvt( aEvent ), wxT( "Expected rotation event" ) );
 
     EDA_ANGLE rotAngle = aFrame.GetRotationAngle();
-    const int angleMultiplier = aEvent.Parameter<intptr_t>();
+    const int angleMultiplier = aEvent.Parameter<int>();
 
     wxASSERT_MSG( angleMultiplier == 1 || angleMultiplier == -1, "Expected 1 or -1" );