KiCad PCB EDA Suite
Loading...
Searching...
No Matches
toolbar_configuration.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 * @author Ian McInerney
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <magic_enum.hpp>
22#include <json_common.h>
23
24#include <tool/action_toolbar.h>
27
30
31void to_json( nlohmann::json& aJson, const TOOLBAR_ITEM& aItem )
32{
33 aJson = { { "type", magic_enum::enum_name( aItem.m_Type ) } };
34
35 switch( aItem.m_Type )
36 {
38 // Nothing to add for a separator
39 break;
40
42 aJson["size"] = aItem.m_Size;
43 break;
44
46 aJson["name"] = aItem.m_ControlName;
47 break;
48
50 aJson["name"] = aItem.m_ActionName;
51 break;
52
54 aJson["group_name"] = aItem.m_GroupName;
55
56 nlohmann::json grpItems = nlohmann::json::array();
57
58 for( const auto& it : aItem.m_GroupItems )
59 grpItems.push_back( it );
60
61 aJson["group_items"] = grpItems;
62
63 break;
64 }
65}
66
67
68void from_json( const nlohmann::json& aJson, TOOLBAR_ITEM& aItem )
69{
70 if( aJson.empty() )
71 return;
72
73 if( aJson.contains( "type" ) )
74 {
75 auto type = magic_enum::enum_cast<TOOLBAR_ITEM_TYPE>( aJson["type"].get<std::string>(),
76 magic_enum::case_insensitive );
77
78 if( type.has_value() )
79 aItem.m_Type = type.value();
80 }
81
82 switch( aItem.m_Type )
83 {
85 // Nothing to read for a separator
86 break;
87
89 if( aJson.contains( "size" ) )
90 aItem.m_Size = aJson["size"].get<int>();
91
92 break;
93
95 if( aJson.contains( "name" ) )
96 aItem.m_ControlName = aJson["name"].get<std::string>();
97
98 break;
99
101 if( aJson.contains( "name" ) )
102 aItem.m_ActionName = aJson["name"].get<std::string>();
103
104 break;
105
107 if( aJson.contains( "group_name" ) )
108 aItem.m_GroupName = aJson["group_name"].get<wxString>();
109
110 if( aJson.contains( "group_items" ) )
111 {
112 for( const nlohmann::json& it : aJson.at( "group_items" ) )
113 aItem.m_GroupItems.push_back( it.get<TOOLBAR_ITEM>() );
114 }
115 break;
116 }
117}
118
119
120void to_json( nlohmann::json& aJson, const TOOLBAR_CONFIGURATION& aConfig )
121{
122 aJson = nlohmann::json::array();
123
124 for( const TOOLBAR_ITEM& item : aConfig.m_toolbarItems )
125 aJson.push_back( item );
126}
127
128
129void from_json( const nlohmann::json& aJson, TOOLBAR_CONFIGURATION& aConfig )
130{
131 if( aJson.empty() )
132 return;
133
134 aConfig.m_toolbarItems.clear();
135
136 if( aJson.is_array() )
137 {
138 for( const nlohmann::json& item : aJson )
139 aConfig.m_toolbarItems.push_back( item.get<TOOLBAR_ITEM>() );
140 }
141}
142
143
144TOOLBAR_SETTINGS::TOOLBAR_SETTINGS( const wxString& aFullPath ) :
146{
147 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "toolbars",
148 [&]() -> nlohmann::json
149 {
150 // Serialize the toolbars
151 nlohmann::json js = nlohmann::json::array();
152
153 for( const auto& [loc, tb] : m_toolbars )
154 {
155 js.push_back( nlohmann::json( { { "name", magic_enum::enum_name( loc ) },
156 { "contents", tb } } ) );
157 }
158
159 return js;
160 },
161 [&]( const nlohmann::json& aObj )
162 {
163 // Deserialize the toolbars
164 m_toolbars.clear();
165
166 if( !aObj.is_array() )
167 return;
168
169 for( const auto& entry : aObj )
170 {
171 if( entry.empty() || !entry.is_object() )
172 continue;
173
174 auto loc = magic_enum::enum_cast<TOOLBAR_LOC>( entry["name"].get<std::string>(),
175 magic_enum::case_insensitive );
176
177 if( loc.has_value() )
178 {
179 m_toolbars.emplace(
180 std::make_pair( loc.value(),
181 entry["contents"].get<TOOLBAR_CONFIGURATION>() ) );
182 }
183 }
184 },
185 nlohmann::json::array() ) );
186}
187
188
189std::optional<TOOLBAR_CONFIGURATION> TOOLBAR_SETTINGS::GetToolbarConfig( TOOLBAR_LOC aToolbar, bool aAllowCustom )
190{
191 std::optional<TOOLBAR_CONFIGURATION> defaultConfig = DefaultToolbarConfig( aToolbar );
192
193 // If the frame does not support this toolbar location, ignore any stored custom config too
194 if( !defaultConfig.has_value() )
195 return std::nullopt;
196
197 // If custom is allowed, look for if a toolbar exists
198 if( aAllowCustom )
199 {
200 auto tb = m_toolbars.find( aToolbar );
201
202 if( tb != m_toolbars.end() )
203 return tb->second;
204 }
205
206 return DefaultToolbarConfig( aToolbar );
207}
208
209
210std::optional<TOOLBAR_CONFIGURATION> TOOLBAR_SETTINGS::GetStoredToolbarConfig( TOOLBAR_LOC aToolbar )
211{
212 auto tb = m_toolbars.find( aToolbar );
213
214 if( tb != m_toolbars.end() )
215 return tb->second;
216
217 // Return a nullopt if no toolbar is configured
218 return std::nullopt;
219}
220
221
224{
225 // Register the factory globally so JSON configs get the same menu
226 TOOLBAR_CONTEXT_MENU_REGISTRY::RegisterMenuFactory( m_item.m_ActionName, std::move( aFactory ) );
227 return m_parent;
228}
229
230
231// Forwarding methods for TOOLBAR_ITEM_REF to enable chaining
232
233TOOLBAR_ITEM_REF TOOLBAR_ITEM_REF::AppendAction( const std::string& aActionName )
234{
235 return m_parent.AppendAction( aActionName );
236}
237
238
240{
241 return m_parent.AppendAction( aAction );
242}
243
244
246{
247 return m_parent.AppendSeparator();
248}
249
250
252{
253 return m_parent.AppendSpacer( aSize );
254}
255
256
258{
259 return m_parent.AppendGroup( aGroup );
260}
261
262
264{
265 return m_parent.AppendControl( aControlName );
266}
267
268
270{
271 return m_parent.AppendControl( aControl );
272}
Class to hold basic information about controls that can be added to the toolbars.
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
JSON_SETTINGS(const wxString &aFilename, SETTINGS_LOC aLocation, int aSchemaVersion)
Like a normal param, but with custom getter and setter functions.
Definition parameters.h:297
std::vector< TOOLBAR_ITEM > m_toolbarItems
static void RegisterMenuFactory(const std::string &aActionName, MENU_FACTORY aFactory)
Register a context menu factory for an action.
std::function< std::unique_ptr< ACTION_MENU >(TOOL_MANAGER *)> MENU_FACTORY
Factory function type: takes TOOL_MANAGER, returns owned ACTION_MENU.
TOOLBAR_CONFIGURATION & AppendSeparator()
TOOLBAR_CONFIGURATION & WithContextMenu(TOOLBAR_CONTEXT_MENU_REGISTRY::MENU_FACTORY aFactory)
Associate a context menu factory with this action.
TOOLBAR_ITEM_REF(class TOOLBAR_CONFIGURATION &aParent, TOOLBAR_ITEM &aItem)
TOOLBAR_CONFIGURATION & AppendGroup(const TOOLBAR_GROUP_CONFIG &aGroup)
TOOLBAR_CONFIGURATION & m_parent
TOOLBAR_ITEM_REF AppendAction(const std::string &aActionName)
TOOLBAR_CONFIGURATION & AppendControl(const std::string &aControlName)
TOOLBAR_CONFIGURATION & AppendSpacer(int aSize)
std::vector< TOOLBAR_ITEM > m_GroupItems
std::string m_ActionName
TOOLBAR_ITEM_TYPE m_Type
std::string m_ControlName
TOOLBAR_SETTINGS(const wxString &aFilename)
virtual std::optional< TOOLBAR_CONFIGURATION > DefaultToolbarConfig(TOOLBAR_LOC aToolbar)
Get the default tools to show on the specified canvas toolbar.
std::optional< TOOLBAR_CONFIGURATION > GetStoredToolbarConfig(TOOLBAR_LOC aToolbar)
Get the stored configuration for the given toolbar.
std::optional< TOOLBAR_CONFIGURATION > GetToolbarConfig(TOOLBAR_LOC aToolbar, bool aAllowCustom=true)
Get the tools to show on the specified canvas toolbar.
std::map< TOOLBAR_LOC, TOOLBAR_CONFIGURATION > m_toolbars
Represent a single user action.
SETTINGS_LOC
@ TOOLBARS
The toolbar directory (e.g. ~/.config/kicad/toolbars/)
const int toolbarSchemaVersion
! Update the schema version whenever a migration is required
void to_json(nlohmann::json &aJson, const TOOLBAR_ITEM &aItem)
void from_json(const nlohmann::json &aJson, TOOLBAR_ITEM &aItem)