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
116 break;
117 }
118}
119
120
121void to_json( nlohmann::json& aJson, const TOOLBAR_CONFIGURATION& aConfig )
122{
123 aJson = nlohmann::json::array();
124
125 for( const TOOLBAR_ITEM& item : aConfig.m_toolbarItems )
126 aJson.push_back( item );
127}
128
129
130void from_json( const nlohmann::json& aJson, TOOLBAR_CONFIGURATION& aConfig )
131{
132 if( aJson.empty() )
133 return;
134
135 aConfig.m_toolbarItems.clear();
136
137 if( aJson.is_array() )
138 {
139 for( const nlohmann::json& item : aJson )
140 aConfig.m_toolbarItems.push_back( item.get<TOOLBAR_ITEM>() );
141 }
142}
143
144
145TOOLBAR_SETTINGS::TOOLBAR_SETTINGS( const wxString& aFullPath ) :
147{
148 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "toolbars",
149 [&]() -> nlohmann::json
150 {
151 // Serialize the toolbars
152 nlohmann::json js = nlohmann::json::array();
153
154 for( const auto& [loc, tb] : m_toolbars )
155 {
156 js.push_back( nlohmann::json( { { "name", magic_enum::enum_name( loc ) },
157 { "contents", tb } } ) );
158 }
159
160 return js;
161 },
162 [&]( const nlohmann::json& aObj )
163 {
164 // Deserialize the toolbars
165 m_toolbars.clear();
166
167 if( !aObj.is_array() )
168 return;
169
170 for( const auto& entry : aObj )
171 {
172 if( entry.empty() || !entry.is_object() )
173 continue;
174
175 auto loc = magic_enum::enum_cast<TOOLBAR_LOC>( entry["name"].get<std::string>(),
176 magic_enum::case_insensitive );
177
178 if( loc.has_value() )
179 {
180 m_toolbars.emplace( 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
223{
224 // Register the factory globally so JSON configs get the same menu
225 TOOLBAR_CONTEXT_MENU_REGISTRY::RegisterMenuFactory( m_item.m_ActionName, std::move( aFactory ) );
226 return m_parent;
227}
228
229
230// Forwarding methods for TOOLBAR_ITEM_REF to enable chaining
231
232TOOLBAR_ITEM_REF TOOLBAR_ITEM_REF::AppendAction( const std::string& aActionName )
233{
234 return m_parent.AppendAction( aActionName );
235}
236
237
239{
240 return m_parent.AppendAction( aAction );
241}
242
243
245{
246 return m_parent.AppendSeparator();
247}
248
249
251{
252 return m_parent.AppendSpacer( aSize );
253}
254
255
257{
258 return m_parent.AppendGroup( aGroup );
259}
260
261
263{
264 return m_parent.AppendControl( aControlName );
265}
266
267
269{
270 return m_parent.AppendControl( aControl );
271}
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:299
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)