KiCad PCB EDA Suite
sch_base_frame.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 (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5  * Copyright (C) 2015-2021 KiCad Developers, see change_log.txt for contributors.
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, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <base_units.h>
26 #include <kiway.h>
27 #include <pgm_base.h>
28 #include <eeschema_settings.h>
30 #include <sch_draw_panel.h>
31 #include <sch_view.h>
32 #include <sch_painter.h>
34 #include <confirm.h>
36 #include <symbol_library.h>
37 #include <sch_base_frame.h>
38 #include <symbol_lib_table.h>
39 #include <tool/action_toolbar.h>
40 #include <tool/tool_manager.h>
41 #include <tool/tool_dispatcher.h>
42 #include <tools/ee_actions.h>
44 
45 
46 LIB_SYMBOL* SchGetLibSymbol( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable,
47  SYMBOL_LIB* aCacheLib, wxWindow* aParent, bool aShowErrorMsg )
48 {
49  wxCHECK_MSG( aLibTable, nullptr, wxT( "Invalid symbol library table." ) );
50 
51  LIB_SYMBOL* symbol = nullptr;
52 
53  try
54  {
55  symbol = aLibTable->LoadSymbol( aLibId );
56 
57  if( !symbol && aCacheLib )
58  {
59  wxCHECK_MSG( aCacheLib->IsCache(), nullptr, wxT( "Invalid cache library." ) );
60 
61  wxString cacheName = aLibId.GetLibNickname().wx_str();
62  cacheName += wxT( "_" ) + aLibId.GetLibItemName();
63  symbol = aCacheLib->FindSymbol( cacheName );
64  }
65  }
66  catch( const IO_ERROR& ioe )
67  {
68  if( aShowErrorMsg )
69  {
70  wxString msg = wxString::Format( _( "Error loading symbol %s from library '%s'." ),
71  aLibId.GetLibItemName().wx_str(),
72  aLibId.GetLibNickname().wx_str() );
73  DisplayErrorMessage( aParent, msg, ioe.What() );
74  }
75  }
76 
77  return symbol;
78 }
79 
80 
81 SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindowType,
82  const wxString& aTitle, const wxPoint& aPosition,
83  const wxSize& aSize, long aStyle, const wxString& aFrameName ) :
84  EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, aSize, aStyle, aFrameName ),
85  m_base_frame_defaults( nullptr, "base_Frame_defaults" )
86 {
87  createCanvas();
88 
89  Bind( wxEVT_IDLE,
90  [this]( wxIdleEvent& aEvent )
91  {
92  // Handle cursor adjustments. While we can get motion and key events through
93  // wxWidgets, we can't get modifier-key-up events.
94  if( m_toolManager )
95  {
97 
98  if( selTool )
99  selTool->OnIdle( aEvent );
100  }
101  } );
102 }
103 
104 
106 {
107 }
108 
109 
111 {
113 }
114 
115 
117 {
118  return dynamic_cast<EESCHEMA_SETTINGS*>( config() );
119 }
120 
121 
123 {
124  return dynamic_cast<SYMBOL_EDITOR_SETTINGS*>( config() );
125 }
126 
127 
128 void SCH_BASE_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
129 {
130  GetScreen()->SetPageSettings( aPageSettings );
131 }
132 
133 
135 {
136  return GetScreen()->GetPageSettings();
137 }
138 
139 
140 const wxSize SCH_BASE_FRAME::GetPageSizeIU() const
141 {
142  // GetSizeIU is compile time dependent:
143  return GetScreen()->GetPageSettings().GetSizeIU();
144 }
145 
146 
148 {
149  wxASSERT( GetScreen() );
150  return GetScreen()->GetTitleBlock();
151 }
152 
153 
154 void SCH_BASE_FRAME::SetTitleBlock( const TITLE_BLOCK& aTitleBlock )
155 {
156  wxASSERT( GetScreen() );
157  GetScreen()->SetTitleBlock( aTitleBlock );
158 }
159 
160 
162 {
163  wxString line;
164  BASE_SCREEN* screen = GetScreen();
165 
166  if( !screen )
167  return;
168 
170 
171  // Display absolute and relative coordinates
173  VECTOR2D d = cursorPos - screen->m_LocalOrigin;
174 
175  line.Printf( wxT( "X %s Y %s" ),
176  MessageTextFromValue( GetUserUnits(), cursorPos.x, false ),
177  MessageTextFromValue( GetUserUnits(), cursorPos.y, false ) );
178  SetStatusText( line, 2 );
179 
180  line.Printf( wxT( "dx %s dy %s dist %s" ),
181  MessageTextFromValue( GetUserUnits(), d.x, false ),
182  MessageTextFromValue( GetUserUnits(), d.y, false ),
183  MessageTextFromValue( GetUserUnits(), hypot( d.x, d.y ), false ) );
184  SetStatusText( line, 3 );
185 
186  // refresh grid display
187  DisplayGridMsg();
188 
189  // refresh units display
190  DisplayUnitsMsg();
191 }
192 
193 
194 LIB_SYMBOL* SCH_BASE_FRAME::GetLibSymbol( const LIB_ID& aLibId, bool aUseCacheLib,
195  bool aShowErrorMsg )
196 {
197  SYMBOL_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : nullptr;
198 
199  return SchGetLibSymbol( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowErrorMsg );
200 }
201 
202 
203 bool SCH_BASE_FRAME::saveSymbolLibTables( bool aGlobal, bool aProject )
204 {
205  wxString msg;
206  bool success = true;
207 
208  if( aGlobal )
209  {
210  try
211  {
213  }
214  catch( const IO_ERROR& ioe )
215  {
216  success = false;
217  msg.Printf( _( "Error saving global symbol library table:\n%s" ), ioe.What() );
218  wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
219  }
220  }
221 
222  if( aProject && !Prj().GetProjectName().IsEmpty() )
223  {
224  wxFileName fn( Prj().GetProjectPath(), SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
225 
226  try
227  {
228  Prj().SchSymbolLibTable()->Save( fn.GetFullPath() );
229  }
230  catch( const IO_ERROR& ioe )
231  {
232  success = false;
233  msg.Printf( _( "Error saving project-specific symbol library table:\n%s" ),
234  ioe.What() );
235  wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
236  }
237  }
238 
239  return success;
240 }
241 
242 
243 void SCH_BASE_FRAME::RedrawScreen( const wxPoint& aCenterPoint, bool aWarpPointer )
244 {
245  GetCanvas()->GetView()->SetCenter( aCenterPoint );
246 
247  if( aWarpPointer )
249 
250  GetCanvas()->Refresh();
251 }
252 
253 
254 void SCH_BASE_FRAME::CenterScreen( const wxPoint& aCenterPoint, bool aWarpPointer )
255 {
256  GetCanvas()->GetView()->SetCenter( aCenterPoint );
257 
258  if( aWarpPointer )
259  GetCanvas()->GetViewControls()->WarpCursor( aCenterPoint, true );
260 
261  GetCanvas()->Refresh();
262 }
263 
264 
266 {
267  if( GetCanvas() && GetCanvas()->GetView() )
268  {
270  GetCanvas()->ForceRefresh();
271  }
272 }
273 
274 
276 {
277  return static_cast<SCH_DRAW_PANEL*>( EDA_DRAW_FRAME::GetCanvas() );
278 }
279 
280 
282 {
283  if( GetCanvas() && GetCanvas()->GetView() )
284  {
285  if( KIGFX::PAINTER* painter = GetCanvas()->GetView()->GetPainter() )
286  return static_cast<KIGFX::SCH_RENDER_SETTINGS*>( painter->GetSettings() );
287  }
288 
289  return nullptr;
290 }
291 
292 
294 {
296 
297  SetCanvas( new SCH_DRAW_PANEL( this, wxID_ANY, wxPoint( 0, 0 ), m_frameSize,
300 }
301 
302 
303 void SCH_BASE_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aUpdateRtree )
304 {
305  EDA_ITEM* parent = aItem->GetParent();
306 
307  if( aItem->Type() == SCH_SHEET_PIN_T )
308  {
309  // Sheet pins aren't in the view. Refresh their parent.
310  if( parent )
311  GetCanvas()->GetView()->Update( parent );
312  }
313  else
314  {
315  if( !isAddOrDelete )
316  GetCanvas()->GetView()->Update( aItem );
317 
318  // Some children are drawn from their parents. Mark them for re-paint.
319  static KICAD_T parentTypes[] = { SCH_SYMBOL_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT };
320 
321  if( parent && parent->IsType( parentTypes ) )
322  GetCanvas()->GetView()->Update( parent, KIGFX::REPAINT );
323  }
324 
329  if( aUpdateRtree)
330  GetScreen()->Update( static_cast<SCH_ITEM*>( aItem ) );
331 
332  // Calling Refresh() here introduces a bi-stable state: when doing operations on a
333  // large number of items if at some point the refresh timer times out and does a
334  // refresh it will take long enough that the next item will also time out, and the
335  // next, and the next, etc.
336  // GetCanvas()->Refresh();
337 }
338 
339 
341 {
342  if( m_toolManager )
343  {
345  SELECTION& selection = selectionTool->GetSelection();
346  KIGFX::SCH_VIEW* view = GetCanvas()->GetView();
347 
348  for( EDA_ITEM* item : selection )
349  {
350  EDA_ITEM* parent = item->GetParent();
351 
352  if( item->Type() == SCH_SHEET_PIN_T )
353  {
354  // Sheet pins aren't in the view. Refresh their parent.
355  if( parent )
356  GetCanvas()->GetView()->Update( parent );
357  }
358  else
359  {
360  view->Update( item, KIGFX::REPAINT );
361 
362  // Symbol children are drawn from their parents. Mark them for re-paint.
363  if( parent && parent->Type() == SCH_SYMBOL_T )
364  GetCanvas()->GetView()->Update( parent, KIGFX::REPAINT );
365  }
366  }
367  }
368 }
369 
370 
372 {
373  auto screen = aScreen;
374 
375  if( aScreen == nullptr )
376  screen = GetScreen();
377 
378  screen->Append( (SCH_ITEM*) aItem );
379 
380  if( screen == GetScreen() )
381  {
382  GetCanvas()->GetView()->Add( aItem );
383  UpdateItem( aItem, true ); // handle any additional parent semantics
384  }
385 }
386 
387 
389 {
390  auto screen = aScreen;
391 
392  if( aScreen == nullptr )
393  screen = GetScreen();
394 
395  if( screen == GetScreen() )
396  GetCanvas()->GetView()->Remove( aItem );
397 
398  screen->Remove( (SCH_ITEM*) aItem );
399 
400  if( screen == GetScreen() )
401  UpdateItem( aItem, true ); // handle any additional parent semantics
402 }
403 
404 
406 {
408 }
409 
410 
412 {
413  return GetColorSettings()->GetColor( aLayer );
414 }
415 
416 
417 void SCH_BASE_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
418 {
419  EDA_DRAW_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
420 
421  EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
422  m_colorSettings = Pgm().GetSettingsManager().GetColorSettings( cfg->m_ColorTheme );
423 
425  GetCanvas()->Refresh();
426 }
427 
428 
430 {
431  if( !m_colorSettings )
432  {
433  SETTINGS_MANAGER& settingsManager = Pgm().GetSettingsManager();
434  EESCHEMA_SETTINGS* cfg = settingsManager.GetAppSettings<EESCHEMA_SETTINGS>();
435  COLOR_SETTINGS* colorSettings = settingsManager.GetColorSettings( cfg->m_ColorTheme );
436 
437  const_cast<SCH_BASE_FRAME*>( this )->m_colorSettings = colorSettings;
438  }
439 
440  return m_colorSettings;
441 }
442 
443 
445 {
447 }
448 
void RefreshSelection()
Mark selected items for refresh.
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
static const wxString & GetSymbolLibTableFileName()
static SYMBOL_LIB_TABLE & GetGlobalLibTable()
void OnIdle(wxIdleEvent &aEvent)
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:104
bool IsCache() const
const UTF8 & GetLibItemName() const
Definition: lib_id.h:104
SCH_BASE_FRAME(KIWAY *aKiway, wxWindow *aParent, FRAME_T aWindowType, const wxString &aTitle, const wxPoint &aPosition, const wxSize &aSize, long aStyle, const wxString &aFrameName)
void ForceRefresh()
Force a redraw.
KIGFX::VIEW_CONTROLS * GetViewControls() const
Return a pointer to the #VIEW_CONTROLS instance used in the panel.
virtual void RedrawScreen(const wxPoint &aCenterPoint, bool aWarpPointer)
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:292
KIGFX::GAL_DISPLAY_OPTIONS & GetGalDisplayOptions()
Return a reference to the gal rendering options used by GAL for rendering.
LIB_SYMBOL * FindSymbol(const wxString &aName) const
Find LIB_SYMBOL by aName.
virtual APP_SETTINGS_BASE * config() const
Returns the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
void HardRedraw() override
Rebuild the GAL and redraws the screen.
Implementation of conversion functions that require both schematic and board internal units.
This file is part of the common library.
Object used to load, save, search, and otherwise manipulate symbol library files.
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
Definition: frame_type.h:32
EDA_DRAW_PANEL_GAL::GAL_TYPE m_canvasType
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1482
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:350
COLOR4D GetLayerColor(SCH_LAYER_ID aLayer)
Helper to retrieve a layer color from the global color settings.
void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Remove an item from the screen (and view) aScreen is the screen the item is located on,...
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:156
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: sch_screen.h:133
KIGFX::SCH_RENDER_SETTINGS * GetRenderSettings()
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
LIB_SYMBOL * SchGetLibSymbol(const LIB_ID &aLibId, SYMBOL_LIB_TABLE *aLibTable, SYMBOL_LIB *aCacheLib, wxWindow *aParent, bool aShowErrorMsg)
Load symbol from symbol library table.
All except INITIAL_ADD.
Definition: view_item.h:53
The base class for create windows for drawing purpose.
Define a library symbol object.
Definition: lib_symbol.h:96
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
Hold the information shown in the lower right corner of a plot, printout, or editing view.
Definition: title_block.h:40
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:132
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
const wxSize GetPageSizeIU() const override
Works off of GetPageSettings() to return the size of the paper page in the internal units of this par...
void DisplayUnitsMsg()
Display current unit pane in the status bar.
EE_SELECTION & GetSelection()
Return the set of currently selected items.
EESCHEMA_SETTINGS * eeconfig() const
virtual void CenterOnCursor() const =0
Set the viewport center to the current cursor position and warps the cursor to the screen center.
virtual void WarpCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false)=0
If enabled (.
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
Contains all the knowledge about how to draw graphical object onto any particular output device.
Definition: painter.h:57
Item needs to be redrawn.
Definition: view_item.h:52
void SetCenter(const VECTOR2D &aCenter)
Set the center point of the VIEW (i.e.
Definition: view.cpp:578
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:335
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock) override
void SyncView()
Mark all items for refresh.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:53
Handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:40
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
T * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
virtual ~SCH_BASE_FRAME()
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:260
Definition for symbol library class.
bool saveSymbolLibTables(bool aGlobal, bool aProject)
Save Symbol Library Tables to disk.
EDA_ITEM * GetParent() const
Definition: eda_item.h:114
#define _(s)
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false, bool aUpdateRtree=false)
Mark an item for refresh.
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:90
SYMBOL_EDITOR_SETTINGS * libeditconfig() const
virtual bool IsType(const KICAD_T aScanTypes[]) const
Check whether the item is one of the listed types.
Definition: eda_item.h:182
virtual void ActivateGalCanvas()
Use to start up the GAL drawing canvas.
COLOR4D GetDrawBgColor() const override
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: sch_screen.h:158
COLOR_SETTINGS * GetColorSettings() const override
Returns a pointer to the active color theme settings.
void SetPageSettings(const PAGE_INFO &aPageSettings) override
COLOR_SETTINGS * m_colorSettings
The current canvas type.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
const PAGE_INFO & GetPageSettings() const override
void UpdateStatusBar() override
Update the status bar information.
void SetCanvas(EDA_DRAW_PANEL_GAL *aPanel)
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
EDA_DRAW_PANEL_GAL::GAL_TYPE loadCanvasTypeSetting()
Returns the canvas type stored in the application settings.
COLOR4D GetColor(int aLayer) const
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:158
see class PGM_BASE
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Add an item to the screen (and view) aScreen is the screen the item is located on,...
const TITLE_BLOCK & GetTitleBlock() const override
wxString wx_str() const
Definition: utf8.cpp:46
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:99
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
Store schematic specific render settings.
Definition: sch_painter.h:66
LIB_SYMBOL * LoadSymbol(const wxString &aNickname, const wxString &aName)
Load a LIB_SYMBOL having aName from the library given by aNickname.
Color settings are a bit different than most of the settings objects in that there can be more than o...
virtual void CenterScreen(const wxPoint &aCenterPoint, bool aWarpPointer)
LIB_SYMBOL * GetLibSymbol(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
Load symbol from symbol library table.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:320
void UpdateStatusBar() override
Update the status bar information.
void Update(SCH_ITEM *aItem)
Update aItem's bounding box in the tree.
Definition: sch_screen.cpp:266
virtual void DisplayGridMsg()
Display current grid size in the status bar.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:182
virtual BASE_SCREEN * GetScreen() const
Return a pointer to a BASE_SCREEN or one of its derivatives.
static wxString GetGlobalTableFileName()
Fetch the global symbol library table file name.
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1570
VECTOR2D m_LocalOrigin
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:90
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:112
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:184
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103