mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-20 18:11:42 +00:00
API: Show API actions alongside SWIG action plugins in preferences
This commit is contained in:
parent
ac73616e7c
commit
9eda526871
common
include
pcbnew
action_plugin.h
dialogs
panel_pcbnew_action_plugins.cpppanel_pcbnew_action_plugins.hpanel_pcbnew_action_plugins_base.cpppanel_pcbnew_action_plugins_base.fbppanel_pcbnew_action_plugins_base.h
pcb_edit_frame.hpython/scripting
scripting
@ -208,6 +208,13 @@ wxString API_PLUGIN::BasePath() const
|
||||
}
|
||||
|
||||
|
||||
wxString API_PLUGIN::ActionSettingsKey( const PLUGIN_ACTION& aAction ) const
|
||||
{
|
||||
return Identifier() + "." + aAction.identifier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::optional<PLUGIN_ACTION> API_PLUGIN::createActionFromJson( const nlohmann::json& aJson )
|
||||
{
|
||||
// TODO move to tl::expected and give user feedback about parse errors
|
||||
|
@ -132,6 +132,15 @@ void API_PLUGIN_MANAGER::ReloadPlugins()
|
||||
}
|
||||
|
||||
|
||||
std::optional<const PLUGIN_ACTION*> API_PLUGIN_MANAGER::GetAction( const wxString& aIdentifier )
|
||||
{
|
||||
if( !m_actionsCache.count( aIdentifier ) )
|
||||
return std::nullopt;
|
||||
|
||||
return m_actionsCache.at( aIdentifier );
|
||||
}
|
||||
|
||||
|
||||
void API_PLUGIN_MANAGER::InvokeAction( const wxString& aIdentifier )
|
||||
{
|
||||
if( !m_actionsCache.count( aIdentifier ) )
|
||||
|
@ -1365,19 +1365,72 @@ bool EDA_DRAW_FRAME::SaveCanvasImageToFile( const wxString& aFileName,
|
||||
}
|
||||
|
||||
|
||||
bool EDA_DRAW_FRAME::IsPluginActionButtonVisible( const PLUGIN_ACTION& aAction,
|
||||
APP_SETTINGS_BASE* aCfg )
|
||||
{
|
||||
wxCHECK( aCfg, aAction.show_button );
|
||||
|
||||
for( const auto& [identifier, visible] : aCfg->m_Plugins.actions )
|
||||
{
|
||||
if( identifier == aAction.identifier )
|
||||
return visible;
|
||||
}
|
||||
|
||||
return aAction.show_button;
|
||||
}
|
||||
|
||||
|
||||
std::vector<const PLUGIN_ACTION*> EDA_DRAW_FRAME::GetOrderedPluginActions(
|
||||
PLUGIN_ACTION_SCOPE aScope, APP_SETTINGS_BASE* aCfg )
|
||||
{
|
||||
std::vector<const PLUGIN_ACTION*> actions;
|
||||
wxCHECK( aCfg, actions );
|
||||
|
||||
#ifdef KICAD_IPC_API
|
||||
|
||||
API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager();
|
||||
std::vector<const PLUGIN_ACTION*> unsorted = mgr.GetActionsForScope( aScope );
|
||||
std::map<wxString, const PLUGIN_ACTION*> actionMap;
|
||||
std::set<const PLUGIN_ACTION*> handled;
|
||||
|
||||
for( const PLUGIN_ACTION* action : unsorted )
|
||||
actionMap[action->identifier] = action;
|
||||
|
||||
for( const auto& identifier : aCfg->m_Plugins.actions | std::views::keys )
|
||||
{
|
||||
if( actionMap.contains( identifier ) )
|
||||
{
|
||||
const PLUGIN_ACTION* action = actionMap[ identifier ];
|
||||
actions.emplace_back( action );
|
||||
handled.insert( action );
|
||||
}
|
||||
}
|
||||
|
||||
for( const auto& action : actionMap | std::views::values )
|
||||
{
|
||||
if( !handled.contains( action ) )
|
||||
actions.emplace_back( action );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::addApiPluginTools()
|
||||
{
|
||||
#ifdef KICAD_IPC_API
|
||||
// TODO: Add user control over visibility and order
|
||||
API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager();
|
||||
|
||||
mgr.ButtonBindings().clear();
|
||||
|
||||
std::vector<const PLUGIN_ACTION*> actions = mgr.GetActionsForScope( PluginActionScope() );
|
||||
std::vector<const PLUGIN_ACTION*> actions =
|
||||
GetOrderedPluginActions( PluginActionScope(), config() );
|
||||
|
||||
for( auto& action : actions )
|
||||
for( const PLUGIN_ACTION* action : actions )
|
||||
{
|
||||
if( !action->show_button )
|
||||
if( !IsPluginActionButtonVisible( *action, config() ) )
|
||||
continue;
|
||||
|
||||
const wxBitmapBundle& icon = KIPLATFORM::UI::IsDarkTheme() && action->icon_dark.IsOk()
|
||||
|
@ -41,6 +41,7 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
|
||||
m_Printing(),
|
||||
m_SearchPane(),
|
||||
m_System(),
|
||||
m_Plugins(),
|
||||
m_Window(),
|
||||
m_appSettingsSchemaVersion( aSchemaVersion )
|
||||
{
|
||||
@ -168,6 +169,39 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
|
||||
m_params.emplace_back( new PARAM<bool>( "system.show_import_issues",
|
||||
&m_System.show_import_issues, true ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "plugins.actions",
|
||||
[&]() -> nlohmann::json
|
||||
{
|
||||
nlohmann::json js = nlohmann::json::array();
|
||||
|
||||
for( const auto& [identifier, visible] : m_Plugins.actions )
|
||||
js.push_back( nlohmann::json( { { identifier.ToUTF8(), visible } } ) );
|
||||
|
||||
return js;
|
||||
},
|
||||
[&]( const nlohmann::json& aObj )
|
||||
{
|
||||
m_Plugins.actions.clear();
|
||||
|
||||
if( !aObj.is_array() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( const auto& entry : aObj )
|
||||
{
|
||||
if( entry.empty() || !entry.is_object() )
|
||||
continue;
|
||||
|
||||
for( const auto& pair : entry.items() )
|
||||
{
|
||||
m_Plugins.actions.emplace_back( std::make_pair(
|
||||
wxString( pair.key().c_str(), wxConvUTF8 ), pair.value() ) );
|
||||
}
|
||||
}
|
||||
},
|
||||
nlohmann::json::array() ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<wxString>( "appearance.color_theme",
|
||||
&m_ColorTheme, COLOR_SETTINGS::COLOR_BUILTIN_DEFAULT ) );
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <wx/dc.h>
|
||||
|
||||
#include <bitmaps.h>
|
||||
#include <kiplatform/ui.h>
|
||||
|
||||
|
||||
GRID_CELL_ICON_TEXT_RENDERER::GRID_CELL_ICON_TEXT_RENDERER( const std::vector<BITMAPS>& icons,
|
||||
@ -39,6 +40,14 @@ GRID_CELL_ICON_TEXT_RENDERER::GRID_CELL_ICON_TEXT_RENDERER( const std::vector<BI
|
||||
}
|
||||
|
||||
|
||||
GRID_CELL_ICON_TEXT_RENDERER::GRID_CELL_ICON_TEXT_RENDERER( const wxBitmapBundle& aIcon,
|
||||
wxSize aPreferredIconSize ) :
|
||||
m_icon( aIcon ),
|
||||
m_iconSize( aPreferredIconSize )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GRID_CELL_ICON_TEXT_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
|
||||
const wxRect& aRect, int aRow, int aCol, bool isSelected )
|
||||
{
|
||||
@ -51,17 +60,18 @@ void GRID_CELL_ICON_TEXT_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, w
|
||||
wxGridCellRenderer::Draw( aGrid, aAttr, aDC, aRect, aRow, aCol, isSelected );
|
||||
|
||||
// draw the icon
|
||||
// note that the set of icons might be smaller than the set of labels if the last
|
||||
// label is <...>.
|
||||
int position = m_names.Index( value );
|
||||
int leftCut = aDC.FromDIP( 4 );
|
||||
|
||||
if( position < (int) m_icons.size() && position != wxNOT_FOUND )
|
||||
if( m_icon.IsOk() )
|
||||
{
|
||||
wxBitmapBundle bundle = KiBitmapBundle( m_icons[position] );
|
||||
wxSize size = m_iconSize == wxDefaultSize
|
||||
? m_icon.GetPreferredBitmapSizeAtScale( aDC.GetContentScaleFactor() )
|
||||
: m_iconSize;
|
||||
double scale = KIPLATFORM::UI::GetPixelScaleFactor( &aGrid );
|
||||
wxBitmap bitmap = m_icon.GetBitmap( size * scale );
|
||||
|
||||
wxBitmap bitmap = bundle.GetBitmap(
|
||||
bundle.GetPreferredBitmapSizeAtScale( aDC.GetContentScaleFactor() ) );
|
||||
if( bitmap.IsOk() )
|
||||
bitmap.SetScaleFactor( scale );
|
||||
|
||||
aDC.DrawBitmap( bitmap,
|
||||
rect.GetLeft() + leftCut,
|
||||
@ -70,14 +80,35 @@ void GRID_CELL_ICON_TEXT_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, w
|
||||
|
||||
leftCut += bitmap.GetLogicalWidth();
|
||||
}
|
||||
else // still need a bitmap to fetch the width
|
||||
else
|
||||
{
|
||||
wxBitmapBundle bundle = KiBitmapBundle( m_icons[0] );
|
||||
// note that the set of icons might be smaller than the set of labels if the last
|
||||
// label is <...>.
|
||||
int position = m_names.Index( value );
|
||||
|
||||
wxBitmap bitmap = bundle.GetBitmap(
|
||||
bundle.GetPreferredBitmapSizeAtScale( aDC.GetContentScaleFactor() ) );
|
||||
if( position < (int) m_icons.size() && position != wxNOT_FOUND )
|
||||
{
|
||||
wxBitmapBundle bundle = KiBitmapBundle( m_icons[position] );
|
||||
|
||||
leftCut += bitmap.GetLogicalWidth();
|
||||
wxBitmap bitmap = bundle.GetBitmap(
|
||||
bundle.GetPreferredBitmapSizeAtScale( aDC.GetContentScaleFactor() ) );
|
||||
|
||||
aDC.DrawBitmap( bitmap,
|
||||
rect.GetLeft() + leftCut,
|
||||
rect.GetTop() + ( rect.GetHeight() - bitmap.GetLogicalHeight() ) / 2,
|
||||
true );
|
||||
|
||||
leftCut += bitmap.GetLogicalWidth();
|
||||
}
|
||||
else // still need a bitmap to fetch the width
|
||||
{
|
||||
wxBitmapBundle bundle = KiBitmapBundle( m_icons[0] );
|
||||
|
||||
wxBitmap bitmap = bundle.GetBitmap(
|
||||
bundle.GetPreferredBitmapSizeAtScale( aDC.GetContentScaleFactor() ) );
|
||||
|
||||
leftCut += bitmap.GetLogicalWidth();
|
||||
}
|
||||
}
|
||||
|
||||
leftCut += aDC.FromDIP( 4 );
|
||||
@ -90,19 +121,34 @@ void GRID_CELL_ICON_TEXT_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, w
|
||||
aGrid.DrawTextRectangle( aDC, value, rect, wxALIGN_LEFT, wxALIGN_CENTRE );
|
||||
}
|
||||
|
||||
|
||||
wxSize GRID_CELL_ICON_TEXT_RENDERER::GetBestSize( wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
|
||||
int row, int col )
|
||||
{
|
||||
int bmpIdx = ( row < (int) m_icons.size() && row >= 0 ) ? row : 0;
|
||||
wxBitmapBundle bundle = KiBitmapBundle( m_icons[bmpIdx] );
|
||||
wxBitmap bitmap;
|
||||
wxSize bitmapSize;
|
||||
|
||||
wxBitmap bitmap =
|
||||
bundle.GetBitmap( bundle.GetPreferredBitmapSizeAtScale( dc.GetContentScaleFactor() ) );
|
||||
if( m_icon.IsOk() )
|
||||
{
|
||||
bitmapSize = m_iconSize == wxDefaultSize
|
||||
? m_icon.GetPreferredBitmapSizeAtScale( dc.GetContentScaleFactor() )
|
||||
: m_iconSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
int bmpIdx = ( row < (int) m_icons.size() && row >= 0 ) ? row : 0;
|
||||
wxBitmapBundle bundle = KiBitmapBundle( m_icons[bmpIdx] );
|
||||
|
||||
bitmap = bundle.GetBitmap(
|
||||
bundle.GetPreferredBitmapSizeAtScale( dc.GetContentScaleFactor() ) );
|
||||
bitmapSize = wxSize( bitmap.GetLogicalWidth(), -1 );
|
||||
}
|
||||
|
||||
wxString text = grid.GetCellValue( row, col );
|
||||
wxSize size = wxGridCellStringRenderer::DoGetBestSize( attr, dc, text );
|
||||
|
||||
size.x += bitmap.GetLogicalWidth() + dc.FromDIP( 8 );
|
||||
size.x += bitmapSize.x + dc.FromDIP( 8 );
|
||||
size.y = std::max( size.y, bitmapSize.y + dc.FromDIP( 2 ) );
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -118,6 +118,8 @@ public:
|
||||
|
||||
const std::vector<PLUGIN_ACTION>& Actions() const;
|
||||
|
||||
wxString ActionSettingsKey( const PLUGIN_ACTION& aAction ) const;
|
||||
|
||||
private:
|
||||
friend struct API_PLUGIN_CONFIG;
|
||||
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
|
||||
void InvokeAction( const wxString& aIdentifier );
|
||||
|
||||
std::optional<const PLUGIN_ACTION*> GetAction( const wxString& aIdentifier );
|
||||
|
||||
std::vector<const PLUGIN_ACTION*> GetActionsForScope( PLUGIN_ACTION_SCOPE aScope );
|
||||
|
||||
std::map<int, wxString>& ButtonBindings() { return m_buttonBindings; }
|
||||
|
@ -512,6 +512,16 @@ public:
|
||||
|
||||
virtual PLUGIN_ACTION_SCOPE PluginActionScope() const { return PLUGIN_ACTION_SCOPE::INVALID; }
|
||||
|
||||
static bool IsPluginActionButtonVisible( const PLUGIN_ACTION& aAction, APP_SETTINGS_BASE* aCfg );
|
||||
|
||||
/**
|
||||
* Return ordered list of plugin actions for display in the toolbar
|
||||
* Must be static at the moment because this needs to be called from the preferences dialog,
|
||||
* which can exist without the frame in question actually being created.
|
||||
* @param aCfg is the settings to read the plugin ordering from
|
||||
*/
|
||||
static std::vector<const PLUGIN_ACTION*> GetOrderedPluginActions( PLUGIN_ACTION_SCOPE aScope,
|
||||
APP_SETTINGS_BASE* aCfg );
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
|
@ -158,6 +158,12 @@ public:
|
||||
bool show_import_issues;
|
||||
};
|
||||
|
||||
struct PLUGINS
|
||||
{
|
||||
/// Ordered list of plugin actions mapped to whether or not they are shown in the toolbar
|
||||
std::vector<std::pair<wxString, bool>> actions;
|
||||
};
|
||||
|
||||
APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaVersion );
|
||||
|
||||
virtual ~APP_SETTINGS_BASE() {}
|
||||
@ -183,6 +189,8 @@ public:
|
||||
|
||||
SYSTEM m_System;
|
||||
|
||||
PLUGINS m_Plugins;
|
||||
|
||||
WINDOW_SETTINGS m_Window;
|
||||
|
||||
/// Active color theme name
|
||||
|
@ -39,8 +39,20 @@ enum class BITMAPS : unsigned int;
|
||||
class GRID_CELL_ICON_TEXT_RENDERER : public wxGridCellStringRenderer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a renderer that maps a list of icons from the bitmap system to a list of strings
|
||||
* @param icons is a list of possible icons to render
|
||||
* @param names is a list of names to render - must be the same length as icons
|
||||
*/
|
||||
GRID_CELL_ICON_TEXT_RENDERER( const std::vector<BITMAPS>& icons, const wxArrayString& names );
|
||||
|
||||
/**
|
||||
* Construct a renderer that renders a single icon next to the cell's value text
|
||||
* @param aIcon is the icon to render next to the cell's value
|
||||
*/
|
||||
GRID_CELL_ICON_TEXT_RENDERER( const wxBitmapBundle& aIcon,
|
||||
wxSize aPreferredIconSize = wxDefaultSize );
|
||||
|
||||
void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
|
||||
const wxRect& aRect, int aRow, int aCol, bool isSelected ) override;
|
||||
wxSize GetBestSize( wxGrid & grid, wxGridCellAttr & attr, wxDC & dc, int row, int col ) override;
|
||||
@ -48,6 +60,10 @@ public:
|
||||
private:
|
||||
std::vector<BITMAPS> m_icons;
|
||||
wxArrayString m_names;
|
||||
|
||||
// For single-icon mode
|
||||
wxBitmapBundle m_icon;
|
||||
wxSize m_iconSize;
|
||||
};
|
||||
|
||||
//---- Grid helpers: custom wxGridCellRenderer that renders just an icon ----------------
|
||||
|
@ -53,6 +53,11 @@ public:
|
||||
|
||||
virtual wxString GetName() = 0;
|
||||
|
||||
/**
|
||||
* @return the name of the Python class defining the action
|
||||
*/
|
||||
virtual wxString GetClassName() = 0;
|
||||
|
||||
/**
|
||||
* @return a description of the action plugin.
|
||||
*/
|
||||
@ -212,4 +217,7 @@ private:
|
||||
static bool m_actionRunning;
|
||||
};
|
||||
|
||||
|
||||
typedef std::variant<ACTION_PLUGIN*, const PLUGIN_ACTION*> LEGACY_OR_API_PLUGIN;
|
||||
|
||||
#endif /* PCBNEW_ACTION_PLUGINS_H */
|
||||
|
@ -19,15 +19,19 @@
|
||||
*/
|
||||
|
||||
#include <action_plugin.h>
|
||||
#include <api/api_plugin.h>
|
||||
#include <bitmaps.h>
|
||||
#include <dialog_footprint_wizard_list.h>
|
||||
#include <grid_tricks.h>
|
||||
#include <kiface_base.h>
|
||||
#include <kiplatform/ui.h>
|
||||
#include <panel_pcbnew_action_plugins.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <python/scripting/pcbnew_scripting.h>
|
||||
#include <pcb_scripting_tool.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <pgm_base.h>
|
||||
#include <api/api_plugin_manager.h>
|
||||
#include <widgets/grid_icon_text_helpers.h>
|
||||
#include <widgets/paged_dialog.h>
|
||||
#include <widgets/wx_grid.h>
|
||||
@ -39,7 +43,7 @@
|
||||
PANEL_PCBNEW_ACTION_PLUGINS::PANEL_PCBNEW_ACTION_PLUGINS( wxWindow* aParent ) :
|
||||
PANEL_PCBNEW_ACTION_PLUGINS_BASE( aParent )
|
||||
{
|
||||
m_genericIcon = KiBitmap( BITMAPS::puzzle_piece );
|
||||
m_genericIcon = KiBitmapBundle( BITMAPS::puzzle_piece );
|
||||
m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
|
||||
m_grid->SetUseNativeColLabels();
|
||||
|
||||
@ -118,10 +122,9 @@ void PANEL_PCBNEW_ACTION_PLUGINS::SwapRows( int aRowA, int aRowB )
|
||||
{
|
||||
m_grid->Freeze();
|
||||
|
||||
// Swap all columns except icon
|
||||
wxString tempStr;
|
||||
|
||||
for( int column = 1; column < m_grid->GetNumberCols(); column++ )
|
||||
for( int column = 0; column < m_grid->GetNumberCols(); column++ )
|
||||
{
|
||||
tempStr = m_grid->GetCellValue( aRowA, column );
|
||||
m_grid->SetCellValue( aRowA, column, m_grid->GetCellValue( aRowB, column ) );
|
||||
@ -129,9 +132,10 @@ void PANEL_PCBNEW_ACTION_PLUGINS::SwapRows( int aRowA, int aRowB )
|
||||
}
|
||||
|
||||
// Swap icon column renderers
|
||||
auto cellRenderer = m_grid->GetCellRenderer( aRowA, COLUMN_ICON );
|
||||
m_grid->SetCellRenderer( aRowA, COLUMN_ICON, m_grid->GetCellRenderer( aRowB, COLUMN_ICON ) );
|
||||
m_grid->SetCellRenderer( aRowB, COLUMN_ICON, cellRenderer );
|
||||
auto cellRenderer = m_grid->GetCellRenderer( aRowA, COLUMN_ACTION_NAME );
|
||||
m_grid->SetCellRenderer( aRowA, COLUMN_ACTION_NAME,
|
||||
m_grid->GetCellRenderer( aRowB, COLUMN_ACTION_NAME ) );
|
||||
m_grid->SetCellRenderer( aRowB, COLUMN_ACTION_NAME, cellRenderer );
|
||||
|
||||
m_grid->Thaw();
|
||||
}
|
||||
@ -149,15 +153,27 @@ bool PANEL_PCBNEW_ACTION_PLUGINS::TransferDataFromWindow()
|
||||
PCBNEW_SETTINGS* settings = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
|
||||
wxASSERT( settings );
|
||||
|
||||
API_PLUGIN_MANAGER& mgr = Pgm().GetPluginManager();
|
||||
|
||||
if( settings )
|
||||
{
|
||||
settings->m_VisibleActionPlugins.clear();
|
||||
settings->m_Plugins.actions.clear();
|
||||
|
||||
for( int ii = 0; ii < m_grid->GetNumberRows(); ii++ )
|
||||
{
|
||||
settings->m_VisibleActionPlugins.emplace_back( std::make_pair(
|
||||
m_grid->GetCellValue( ii, COLUMN_PATH ),
|
||||
m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
|
||||
wxString id = m_grid->GetCellValue( ii, COLUMN_SETTINGS_IDENTIFIER );
|
||||
|
||||
if( mgr.GetAction( id ) != std::nullopt )
|
||||
{
|
||||
settings->m_Plugins.actions.emplace_back( std::make_pair(
|
||||
id, m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->m_VisibleActionPlugins.emplace_back( std::make_pair(
|
||||
id, m_grid->GetCellValue( ii, COLUMN_VISIBLE ) == wxT( "1" ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,30 +187,66 @@ bool PANEL_PCBNEW_ACTION_PLUGINS::TransferDataToWindow()
|
||||
|
||||
m_grid->ClearRows();
|
||||
|
||||
const auto& orderedPlugins = PCB_EDIT_FRAME::GetOrderedActionPlugins();
|
||||
const std::vector<LEGACY_OR_API_PLUGIN>& orderedPlugins =
|
||||
PCB_EDIT_FRAME::GetOrderedActionPlugins();
|
||||
m_grid->AppendRows( orderedPlugins.size() );
|
||||
|
||||
int size = Pgm().GetCommonSettings()->m_Appearance.toolbar_icon_size;
|
||||
wxSize iconSize( size, size );
|
||||
|
||||
for( size_t row = 0; row < orderedPlugins.size(); row++ )
|
||||
{
|
||||
ACTION_PLUGIN* ap = orderedPlugins[row];
|
||||
if( std::holds_alternative<ACTION_PLUGIN*>( orderedPlugins[row] ) )
|
||||
{
|
||||
auto ap = std::get<ACTION_PLUGIN*>( orderedPlugins[row] );
|
||||
|
||||
// Icon
|
||||
m_grid->SetCellRenderer( row, COLUMN_ICON, new GRID_CELL_ICON_RENDERER(
|
||||
ap->iconBitmap.IsOk() ? ap->iconBitmap : m_genericIcon ) );
|
||||
// Icon
|
||||
m_grid->SetCellRenderer( row, COLUMN_ACTION_NAME,
|
||||
new GRID_CELL_ICON_TEXT_RENDERER( ap->iconBitmap.IsOk()
|
||||
? wxBitmapBundle( ap->iconBitmap )
|
||||
: m_genericIcon,
|
||||
iconSize ) );
|
||||
m_grid->SetCellValue( row, COLUMN_ACTION_NAME, ap->GetName() );
|
||||
m_grid->SetCellValue( row, COLUMN_SETTINGS_IDENTIFIER, ap->GetPluginPath() );
|
||||
|
||||
// Toolbar button checkbox
|
||||
m_grid->SetCellRenderer( row, COLUMN_VISIBLE, new wxGridCellBoolRenderer() );
|
||||
m_grid->SetCellAlignment( row, COLUMN_VISIBLE, wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
// Toolbar button checkbox
|
||||
m_grid->SetCellRenderer( row, COLUMN_VISIBLE, new wxGridCellBoolRenderer() );
|
||||
m_grid->SetCellAlignment( row, COLUMN_VISIBLE, wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
bool show = PCB_EDIT_FRAME::GetActionPluginButtonVisible( ap->GetPluginPath(),
|
||||
ap->GetShowToolbarButton() );
|
||||
bool show = PCB_EDIT_FRAME::GetActionPluginButtonVisible( ap->GetPluginPath(),
|
||||
ap->GetShowToolbarButton() );
|
||||
|
||||
m_grid->SetCellValue( row, COLUMN_VISIBLE, show ? wxT( "1" ) : wxEmptyString );
|
||||
m_grid->SetCellValue( row, COLUMN_VISIBLE, show ? wxT( "1" ) : wxEmptyString );
|
||||
|
||||
m_grid->SetCellValue( row, COLUMN_NAME, ap->GetName() );
|
||||
m_grid->SetCellValue( row, COLUMN_CATEGORY, ap->GetCategoryName() );
|
||||
m_grid->SetCellValue( row, COLUMN_DESCRIPTION, ap->GetDescription() );
|
||||
m_grid->SetCellValue( row, COLUMN_PATH, ap->GetPluginPath() );
|
||||
m_grid->SetCellValue( row, COLUMN_PLUGIN_NAME, ap->GetClassName() );
|
||||
m_grid->SetCellValue( row, COLUMN_DESCRIPTION, ap->GetDescription() );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto action = std::get<const PLUGIN_ACTION*>( orderedPlugins[row] );
|
||||
|
||||
const wxBitmapBundle& icon = KIPLATFORM::UI::IsDarkTheme() && action->icon_dark.IsOk()
|
||||
? action->icon_dark
|
||||
: action->icon_light;
|
||||
|
||||
// Icon
|
||||
m_grid->SetCellRenderer( row, COLUMN_ACTION_NAME, new GRID_CELL_ICON_TEXT_RENDERER(
|
||||
icon.IsOk() ? icon : m_genericIcon, iconSize ) );
|
||||
m_grid->SetCellValue( row, COLUMN_ACTION_NAME, action->name );
|
||||
m_grid->SetCellValue( row, COLUMN_SETTINGS_IDENTIFIER, action->identifier );
|
||||
|
||||
// Toolbar button checkbox
|
||||
m_grid->SetCellRenderer( row, COLUMN_VISIBLE, new wxGridCellBoolRenderer() );
|
||||
m_grid->SetCellAlignment( row, COLUMN_VISIBLE, wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
bool show = PCB_EDIT_FRAME::GetActionPluginButtonVisible( action->identifier,
|
||||
action->show_button );
|
||||
|
||||
m_grid->SetCellValue( row, COLUMN_VISIBLE, show ? wxT( "1" ) : wxEmptyString );
|
||||
|
||||
m_grid->SetCellValue( row, COLUMN_PLUGIN_NAME, action->plugin.Name() );
|
||||
m_grid->SetCellValue( row, COLUMN_DESCRIPTION, action->description );
|
||||
}
|
||||
}
|
||||
|
||||
for( int col = 0; col < m_grid->GetNumberCols(); col++ )
|
||||
@ -209,6 +261,8 @@ bool PANEL_PCBNEW_ACTION_PLUGINS::TransferDataToWindow()
|
||||
}
|
||||
|
||||
m_grid->AutoSizeRows();
|
||||
m_grid->AutoSizeColumns();
|
||||
m_grid->HideCol( COLUMN_SETTINGS_IDENTIFIER );
|
||||
|
||||
m_grid->Thaw();
|
||||
|
||||
|
@ -63,15 +63,14 @@ private:
|
||||
|
||||
enum GRID_COLUMNS
|
||||
{
|
||||
COLUMN_ICON,
|
||||
COLUMN_ACTION_NAME,
|
||||
COLUMN_VISIBLE,
|
||||
COLUMN_NAME,
|
||||
COLUMN_CATEGORY,
|
||||
COLUMN_PLUGIN_NAME,
|
||||
COLUMN_DESCRIPTION,
|
||||
COLUMN_PATH
|
||||
COLUMN_SETTINGS_IDENTIFIER,
|
||||
};
|
||||
|
||||
wxBitmap m_genericIcon;
|
||||
wxBitmapBundle m_genericIcon;
|
||||
|
||||
void SwapRows( int aRowA, int aRowB );
|
||||
void SelectRow( int aRow );
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@ -14,6 +14,9 @@
|
||||
|
||||
PANEL_PCBNEW_ACTION_PLUGINS_BASE::PANEL_PCBNEW_ACTION_PLUGINS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
|
||||
{
|
||||
wxBoxSizer* bSizer4;
|
||||
bSizer4 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxBoxSizer* bPanelSizer;
|
||||
bPanelSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
@ -23,7 +26,7 @@ PANEL_PCBNEW_ACTION_PLUGINS_BASE::PANEL_PCBNEW_ACTION_PLUGINS_BASE( wxWindow* pa
|
||||
m_grid = new WX_GRID( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
||||
// Grid
|
||||
m_grid->CreateGrid( 3, 6 );
|
||||
m_grid->CreateGrid( 3, 5 );
|
||||
m_grid->EnableEditing( false );
|
||||
m_grid->EnableGridLines( true );
|
||||
m_grid->EnableDragGridSize( false );
|
||||
@ -33,12 +36,11 @@ PANEL_PCBNEW_ACTION_PLUGINS_BASE::PANEL_PCBNEW_ACTION_PLUGINS_BASE( wxWindow* pa
|
||||
m_grid->AutoSizeColumns();
|
||||
m_grid->EnableDragColMove( false );
|
||||
m_grid->EnableDragColSize( true );
|
||||
m_grid->SetColLabelValue( 0, _("Icon") );
|
||||
m_grid->SetColLabelValue( 0, _("Action") );
|
||||
m_grid->SetColLabelValue( 1, _("Show Button") );
|
||||
m_grid->SetColLabelValue( 2, _("Name") );
|
||||
m_grid->SetColLabelValue( 3, _("Category") );
|
||||
m_grid->SetColLabelValue( 4, _("Description") );
|
||||
m_grid->SetColLabelValue( 5, _("Path") );
|
||||
m_grid->SetColLabelValue( 2, _("Plugin") );
|
||||
m_grid->SetColLabelValue( 3, _("Description") );
|
||||
m_grid->SetColLabelValue( 4, wxEmptyString );
|
||||
m_grid->SetColLabelSize( wxGRID_AUTOSIZE );
|
||||
m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
@ -91,9 +93,12 @@ PANEL_PCBNEW_ACTION_PLUGINS_BASE::PANEL_PCBNEW_ACTION_PLUGINS_BASE( wxWindow* pa
|
||||
bPanelSizer->Add( bButtonsSizer, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bPanelSizer );
|
||||
bSizer4->Add( bPanelSizer, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bSizer4 );
|
||||
this->Layout();
|
||||
bPanelSizer->Fit( this );
|
||||
bSizer4->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( PANEL_PCBNEW_ACTION_PLUGINS_BASE::OnGridCellClick ), NULL, this );
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "pcb_base_edit_frame.h"
|
||||
#include "zones.h"
|
||||
#include <mail_type.h>
|
||||
#include <settings/app_settings.h>
|
||||
|
||||
class ACTION_PLUGIN;
|
||||
class PCB_SCREEN;
|
||||
@ -202,9 +203,9 @@ public:
|
||||
|
||||
/**
|
||||
* Return ordered list of plugins in sequence in which they should appear on toolbar or
|
||||
* in settings
|
||||
* in settings. Handles both legacy (SWIG) and API plugins, so returns a heterogenous list.
|
||||
*/
|
||||
static std::vector<ACTION_PLUGIN*> GetOrderedActionPlugins();
|
||||
static std::vector<std::variant<ACTION_PLUGIN*, const PLUGIN_ACTION*>> GetOrderedActionPlugins();
|
||||
|
||||
void SaveProjectLocalSettings() override;
|
||||
|
||||
|
@ -171,6 +171,14 @@ wxString PYTHON_ACTION_PLUGIN::GetCategoryName()
|
||||
}
|
||||
|
||||
|
||||
wxString PYTHON_ACTION_PLUGIN::GetClassName()
|
||||
{
|
||||
PyLOCK lock;
|
||||
|
||||
return CallRetStrMethod( "GetClassName" );
|
||||
}
|
||||
|
||||
|
||||
wxString PYTHON_ACTION_PLUGIN::GetName()
|
||||
{
|
||||
PyLOCK lock;
|
||||
@ -496,10 +504,16 @@ void PCB_EDIT_FRAME::buildActionPluginMenus( ACTION_MENU* actionMenu )
|
||||
void PCB_EDIT_FRAME::AddActionPluginTools()
|
||||
{
|
||||
bool need_separator = true;
|
||||
const std::vector<ACTION_PLUGIN*>& orderedPlugins = GetOrderedActionPlugins();
|
||||
const std::vector<LEGACY_OR_API_PLUGIN>& orderedPlugins = GetOrderedActionPlugins();
|
||||
|
||||
for( ACTION_PLUGIN* ap : orderedPlugins )
|
||||
for( const auto& entry : orderedPlugins )
|
||||
{
|
||||
// API plugins are handled by EDA_BASE_FRAME
|
||||
if( !std::holds_alternative<ACTION_PLUGIN*>( entry ) )
|
||||
continue;
|
||||
|
||||
ACTION_PLUGIN* ap = std::get<ACTION_PLUGIN*>( entry );
|
||||
|
||||
if( GetActionPluginButtonVisible( ap->GetPluginPath(), ap->GetShowToolbarButton() ) )
|
||||
{
|
||||
if( need_separator )
|
||||
@ -529,13 +543,13 @@ void PCB_EDIT_FRAME::AddActionPluginTools()
|
||||
}
|
||||
|
||||
|
||||
std::vector<ACTION_PLUGIN*> PCB_EDIT_FRAME::GetOrderedActionPlugins()
|
||||
std::vector<LEGACY_OR_API_PLUGIN> PCB_EDIT_FRAME::GetOrderedActionPlugins()
|
||||
{
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
PCBNEW_SETTINGS* cfg = mgr.GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" );
|
||||
|
||||
std::vector<ACTION_PLUGIN*> plugins;
|
||||
std::vector<ACTION_PLUGIN*> orderedPlugins;
|
||||
std::vector<LEGACY_OR_API_PLUGIN> orderedPlugins;
|
||||
|
||||
for( int i = 0; i < ACTION_PLUGINS::GetActionsCount(); i++ )
|
||||
plugins.push_back( ACTION_PLUGINS::GetAction( i ) );
|
||||
@ -560,6 +574,10 @@ std::vector<ACTION_PLUGIN*> PCB_EDIT_FRAME::GetOrderedActionPlugins()
|
||||
for( auto remaining_plugin : plugins )
|
||||
orderedPlugins.push_back( remaining_plugin );
|
||||
|
||||
// Finally append API plugins
|
||||
for( const PLUGIN_ACTION* action : GetOrderedPluginActions( PLUGIN_ACTION_SCOPE::PCB, cfg ) )
|
||||
orderedPlugins.push_back( action );
|
||||
|
||||
return orderedPlugins;
|
||||
}
|
||||
|
||||
@ -570,10 +588,16 @@ bool PCB_EDIT_FRAME::GetActionPluginButtonVisible( const wxString& aPluginPath,
|
||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||
PCBNEW_SETTINGS* cfg = mgr.GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" );
|
||||
|
||||
for( const auto& entry : cfg->m_VisibleActionPlugins )
|
||||
for( const auto& [path, visible] : cfg->m_VisibleActionPlugins )
|
||||
{
|
||||
if( entry.first == aPluginPath )
|
||||
return entry.second;
|
||||
if( path == aPluginPath )
|
||||
return visible;
|
||||
}
|
||||
|
||||
for( const auto& [identifier, visible] : cfg->m_Plugins.actions )
|
||||
{
|
||||
if( identifier == aPluginPath )
|
||||
return visible;
|
||||
}
|
||||
|
||||
// Plugin is not in settings, return default.
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
PYTHON_ACTION_PLUGIN( PyObject* action );
|
||||
~PYTHON_ACTION_PLUGIN();
|
||||
wxString GetCategoryName() override;
|
||||
wxString GetClassName() override;
|
||||
wxString GetName() override;
|
||||
wxString GetDescription() override;
|
||||
bool GetShowToolbarButton() override;
|
||||
|
@ -668,6 +668,9 @@ class ActionPlugin(KiCadPlugin, object):
|
||||
self.category = "Undefined"
|
||||
self.description = ""
|
||||
|
||||
def GetClassName(self):
|
||||
return type(self).__name__
|
||||
|
||||
def GetName( self ):
|
||||
return self.name
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user