Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
8db19bbd
Commit
8db19bbd
authored
Sep 23, 2011
by
jean-pierre charras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Preparing hotkeys/shortcuts changes in place menu.
parent
edd35b4e
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
2822 additions
and
2767 deletions
+2822
-2767
class_layer_box_selector.cpp
common/class_layer_box_selector.cpp
+1
-1
hotkeys_basic.cpp
common/hotkeys_basic.cpp
+54
-15
menubar.cpp
eeschema/menubar.cpp
+185
-185
tool_lib.cpp
eeschema/tool_lib.cpp
+6
-6
tool_sch.cpp
eeschema/tool_sch.cpp
+7
-7
tool_viewlib.cpp
eeschema/tool_viewlib.cpp
+4
-4
class_aperture_macro.cpp
gerbview/class_aperture_macro.cpp
+814
-814
class_gerbview_layer_widget.cpp
gerbview/class_gerbview_layer_widget.cpp
+290
-290
events_called_functions.cpp
gerbview/events_called_functions.cpp
+298
-298
toolbars_gerber.cpp
gerbview/toolbars_gerber.cpp
+4
-4
hotkeys_basic.h
include/hotkeys_basic.h
+17
-3
class_netinfo.h
pcbnew/class_netinfo.h
+401
-401
class_pcb_layer_widget.cpp
pcbnew/class_pcb_layer_widget.cpp
+373
-373
drc_marker_functions.cpp
pcbnew/drc_marker_functions.cpp
+175
-175
menubar_pcbframe.cpp
pcbnew/menubar_pcbframe.cpp
+20
-18
tool_modedit.cpp
pcbnew/tool_modedit.cpp
+4
-4
tool_pcb.cpp
pcbnew/tool_pcb.cpp
+7
-7
zones_convert_to_polygons_aux_functions.cpp
pcbnew/zones_convert_to_polygons_aux_functions.cpp
+162
-162
No files found.
common/class_layer_box_selector.cpp
View file @
8db19bbd
...
...
@@ -143,7 +143,7 @@ void LAYER_BOX_SELECTOR::Resync()
layername
=
board
->
GetLayerName
(
layerid
);
if
(
m_layerhotkeys
&&
m_hotkeys
!=
NULL
)
layername
=
AddHotkeyName
(
layername
,
m_hotkeys
,
layerhk
[
layerid
],
false
);
layername
=
AddHotkeyName
(
layername
,
m_hotkeys
,
layerhk
[
layerid
],
IS_COMMENT
);
Append
(
layername
,
layerbmp
,
(
void
*
)
layerid
);
}
...
...
common/hotkeys_basic.cpp
View file @
8db19bbd
...
...
@@ -171,17 +171,40 @@ wxString ReturnKeyNameFromKeyCode( int aKeycode, bool* aIsFound )
}
/*
* helper function use in AddHotkeyName to calculate an accelerator string
* In some menus, accelerators do not perform exactely the same action as
* the hotkey that perfoms a similar action.
* this is usually the case when this action uses the current mouse position
* for instance zoom action is ran from the F1 key or the Zoom menu.
* a zoom uses the mouse position from a hot key and not from the menu
* In this case, the accelerator if Shift+<hotkey>
* But for some keys, the Shift modifier is not usable, and the accelerator is Alt+<hotkey>
*/
static
void
AddModifierToKey
(
wxString
&
aFullKey
,
const
wxString
&
aKey
)
{
#if 1 // set to 0 for new behavior, 1 for old
aFullKey
<<
wxT
(
" <"
)
<<
aKey
<<
wxT
(
">"
);
#else
if
(
aKey
.
IsSameAs
(
wxT
(
"/"
)
)
)
aFullKey
<<
wxT
(
"
\t
"
)
<<
MODIFIER_ALT
<<
aKey
;
else
aFullKey
<<
wxT
(
"
\t
"
)
<<
MODIFIER_SHIFT
<<
aKey
;
#endif
}
/* AddHotkeyName
* Add the key name from the Command id value ( m_Idcommand member value)
* aText = a wxString. returns aText + key name
* aList = pointer to a Ki_HotkeyInfo list of commands
* aCommandId = Command Id value
* aIsShortCut = true to add <tab><keyname> (active shortcuts in menus)
* = false to add <spaces><(keyname)>
* aShortCutType = IS_HOTKEY to add <tab><keyname> (shortcuts in menus, same as hotkeys)
* IS_ACCELERATOR to add <tab><Shift+keyname> (accelerators in menus, not hotkeys)
* IS_COMMENT to add <spaces><(keyname)> mainly in tooltips
* Return a wxString (aTest + key name) if key found or aText without modification
*/
wxString
AddHotkeyName
(
const
wxString
&
aText
,
Ki_HotkeyInfo
**
aList
,
int
aCommandId
,
bool
aIsShortCut
)
int
aCommandId
,
HOTKEY_ACTION_TYPE
aShortCutType
)
{
wxString
msg
=
aText
;
wxString
keyname
;
...
...
@@ -191,10 +214,18 @@ wxString AddHotkeyName( const wxString& aText, Ki_HotkeyInfo** aList,
if
(
!
keyname
.
IsEmpty
()
)
{
if
(
aIsShortCut
)
msg
<<
wxT
(
"
\t
"
)
<<
keyname
;
else
msg
<<
wxT
(
" <"
)
<<
keyname
<<
wxT
(
">"
);
switch
(
aShortCutType
)
{
case
IS_HOTKEY
:
msg
<<
wxT
(
"
\t
"
)
<<
keyname
;
break
;
case
IS_ACCELERATOR
:
AddModifierToKey
(
msg
,
keyname
);
break
;
case
IS_COMMENT
:
msg
<<
wxT
(
" ("
)
<<
keyname
<<
wxT
(
")"
);
break
;
}
}
return
msg
;
...
...
@@ -206,14 +237,15 @@ wxString AddHotkeyName( const wxString& aText, Ki_HotkeyInfo** aList,
* aText = a wxString. returns aText + key name
* aList = pointer to a Ki_HotkeyInfoSectionDescriptor DescrList of commands
* aCommandId = Command Id value
* aIsShortCut = true to add <tab><keyname> (active shortcuts in menus)
* = false to add <spaces><(keyname)>
* aShortCutType = IS_HOTKEY to add <tab><keyname> (active shortcuts in menus)
* IS_ACCELERATOR to add <tab><Shift+keyname> (active accelerators in menus)
* IS_COMMENT to add <spaces><(keyname)>
* Return a wxString (aText + key name) if key found or aText without modification
*/
wxString
AddHotkeyName
(
const
wxString
&
aText
,
struct
Ki_HotkeyInfoSectionDescriptor
*
aDescList
,
int
aCommandId
,
bool
aIsShortCut
)
HOTKEY_ACTION_TYPE
aShortCutType
)
{
wxString
msg
=
aText
;
wxString
keyname
;
...
...
@@ -228,11 +260,18 @@ wxString AddHotkeyName( const wxString& aText,
if
(
!
keyname
.
IsEmpty
()
)
{
if
(
aIsShortCut
)
msg
<<
wxT
(
"
\t
"
)
<<
keyname
;
else
msg
<<
wxT
(
" <"
)
<<
keyname
<<
wxT
(
">"
);
switch
(
aShortCutType
)
{
case
IS_HOTKEY
:
msg
<<
wxT
(
"
\t
"
)
<<
keyname
;
break
;
case
IS_ACCELERATOR
:
AddModifierToKey
(
msg
,
keyname
);
break
;
case
IS_COMMENT
:
msg
<<
wxT
(
" ("
)
<<
keyname
<<
wxT
(
")"
);
break
;
}
break
;
}
}
...
...
eeschema/menubar.cpp
View file @
8db19bbd
...
...
@@ -42,17 +42,17 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// New
AddMenuItem
(
fileMenu
,
ID_NEW_PROJECT
,
_
(
"&New
\t
Ctrl+N"
),
_
(
"New schematic project"
),
KiBitmap
(
new_xpm
)
);
ID_NEW_PROJECT
,
_
(
"&New
\t
Ctrl+N"
),
_
(
"New schematic project"
),
KiBitmap
(
new_xpm
)
);
// Open
AddMenuItem
(
fileMenu
,
ID_LOAD_PROJECT
,
_
(
"&Open
\t
Ctrl+O"
),
_
(
"Open an existing schematic project"
),
KiBitmap
(
open_document_xpm
)
);
ID_LOAD_PROJECT
,
_
(
"&Open
\t
Ctrl+O"
),
_
(
"Open an existing schematic project"
),
KiBitmap
(
open_document_xpm
)
);
// Open Recent submenu
static
wxMenu
*
openRecentMenu
;
...
...
@@ -66,106 +66,106 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
wxGetApp
().
m_fileHistory
.
UseMenu
(
openRecentMenu
);
wxGetApp
().
m_fileHistory
.
AddFilesToMenu
(
openRecentMenu
);
AddMenuItem
(
fileMenu
,
openRecentMenu
,
wxID_ANY
,
_
(
"Open &Recent"
),
_
(
"Open a recent opened schematic project"
),
KiBitmap
(
open_project_xpm
)
);
wxID_ANY
,
_
(
"Open &Recent"
),
_
(
"Open a recent opened schematic project"
),
KiBitmap
(
open_project_xpm
)
);
// Separator
fileMenu
->
AppendSeparator
();
// Save schematic project
AddMenuItem
(
fileMenu
,
ID_SAVE_PROJECT
,
_
(
"&Save Whole Schematic Project
\t
Ctrl+S"
),
_
(
"Save all sheets in the schematic project"
),
KiBitmap
(
save_project_xpm
)
);
ID_SAVE_PROJECT
,
_
(
"&Save Whole Schematic Project
\t
Ctrl+S"
),
_
(
"Save all sheets in the schematic project"
),
KiBitmap
(
save_project_xpm
)
);
// Save current sheet
AddMenuItem
(
fileMenu
,
ID_SAVE_ONE_SHEET
,
_
(
"Save &Current Sheet Only"
),
_
(
"Save only current schematic sheet"
),
KiBitmap
(
save_xpm
)
);
ID_SAVE_ONE_SHEET
,
_
(
"Save &Current Sheet Only"
),
_
(
"Save only current schematic sheet"
),
KiBitmap
(
save_xpm
)
);
// Save current sheet as
AddMenuItem
(
fileMenu
,
ID_SAVE_ONE_SHEET_AS
,
_
(
"Save Current Sheet &as"
),
_
(
"Save current schematic sheet as..."
),
KiBitmap
(
save_as_xpm
)
);
ID_SAVE_ONE_SHEET_AS
,
_
(
"Save Current Sheet &as"
),
_
(
"Save current schematic sheet as..."
),
KiBitmap
(
save_as_xpm
)
);
// Separator
fileMenu
->
AppendSeparator
();
// Page settings
AddMenuItem
(
fileMenu
,
ID_SHEET_SET
,
_
(
"P&age Settings"
),
_
(
"Settigns for page size and information"
),
KiBitmap
(
sheetset_xpm
)
);
ID_SHEET_SET
,
_
(
"P&age Settings"
),
_
(
"Settigns for page size and information"
),
KiBitmap
(
sheetset_xpm
)
);
// Print
AddMenuItem
(
fileMenu
,
wxID_PRINT
,
_
(
"P&rint"
),
_
(
"Print schematic"
),
KiBitmap
(
print_button_xpm
)
);
wxID_PRINT
,
_
(
"P&rint"
),
_
(
"Print schematic"
),
KiBitmap
(
print_button_xpm
)
);
// Plot submenu
wxMenu
*
choice_plot_fmt
=
new
wxMenu
;
// Plot PostScript
AddMenuItem
(
choice_plot_fmt
,
ID_GEN_PLOT_PS
,
_
(
"Plot PostScript"
),
_
(
"Plot schematic sheet in PostScript format"
),
KiBitmap
(
plot_ps_xpm
)
);
_
(
"Plot PostScript"
),
_
(
"Plot schematic sheet in PostScript format"
),
KiBitmap
(
plot_ps_xpm
)
);
// Plot HPGL
AddMenuItem
(
choice_plot_fmt
,
ID_GEN_PLOT_HPGL
,
_
(
"Plot HPGL"
),
_
(
"Plot schematic sheet in HPGL format"
),
KiBitmap
(
plot_hpg_xpm
)
);
ID_GEN_PLOT_HPGL
,
_
(
"Plot HPGL"
),
_
(
"Plot schematic sheet in HPGL format"
),
KiBitmap
(
plot_hpg_xpm
)
);
// Plot SVG
AddMenuItem
(
choice_plot_fmt
,
ID_GEN_PLOT_SVG
,
_
(
"Plot SVG"
),
_
(
"Plot schematic sheet in SVG format"
),
KiBitmap
(
plot_xpm
)
);
ID_GEN_PLOT_SVG
,
_
(
"Plot SVG"
),
_
(
"Plot schematic sheet in SVG format"
),
KiBitmap
(
plot_xpm
)
);
// Plot DXF
AddMenuItem
(
choice_plot_fmt
,
ID_GEN_PLOT_DXF
,
_
(
"Plot DXF"
),
_
(
"Plot schematic sheet in DXF format"
),
KiBitmap
(
plot_xpm
)
);
ID_GEN_PLOT_DXF
,
_
(
"Plot DXF"
),
_
(
"Plot schematic sheet in DXF format"
),
KiBitmap
(
plot_xpm
)
);
// Plot to Clipboard (Windows only)
#ifdef __WINDOWS__
AddMenuItem
(
choice_plot_fmt
,
ID_GEN_COPY_SHEET_TO_CLIPBOARD
,
_
(
"Plot to Clipboard"
),
_
(
"Export drawings to clipboard"
),
KiBitmap
(
copy_button_xpm
)
);
_
(
"Plot to Clipboard"
),
_
(
"Export drawings to clipboard"
),
KiBitmap
(
copy_button_xpm
)
);
#endif // __WINDOWS__
// Plot submenu
AddMenuItem
(
fileMenu
,
choice_plot_fmt
,
ID_GEN_PLOT
,
_
(
"&Plot"
),
_
(
"Plot schematic sheet in HPGL, PostScript or SVG format"
),
KiBitmap
(
plot_xpm
)
);
ID_GEN_PLOT
,
_
(
"&Plot"
),
_
(
"Plot schematic sheet in HPGL, PostScript or SVG format"
),
KiBitmap
(
plot_xpm
)
);
// Separator
fileMenu
->
AppendSeparator
();
// Quit
AddMenuItem
(
fileMenu
,
wxID_EXIT
,
_
(
"&Quit"
),
_
(
"Quit EESchema"
),
KiBitmap
(
exit_xpm
)
);
wxID_EXIT
,
_
(
"&Quit"
),
_
(
"Quit EESchema"
),
KiBitmap
(
exit_xpm
)
);
// Menu Edit:
wxMenu
*
editMenu
=
new
wxMenu
;
...
...
@@ -183,8 +183,8 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Delete
editMenu
->
AppendSeparator
();
AddMenuItem
(
editMenu
,
ID_SCHEMATIC_DELETE_ITEM_BUTT
,
_
(
"Delete"
),
HELP_DELETE_ITEMS
,
KiBitmap
(
delete_body_xpm
)
);
_
(
"Delete"
),
HELP_DELETE_ITEMS
,
KiBitmap
(
delete_body_xpm
)
);
// Find
editMenu
->
AppendSeparator
();
...
...
@@ -194,10 +194,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Backannotate
editMenu
->
AppendSeparator
();
AddMenuItem
(
editMenu
,
ID_BACKANNO_ITEMS
,
_
(
"&Backannotate"
),
_
(
"Back annotate the footprint fields"
),
KiBitmap
(
import_footprint_names_xpm
)
);
ID_BACKANNO_ITEMS
,
_
(
"&Backannotate"
),
_
(
"Back annotate the footprint fields"
),
KiBitmap
(
import_footprint_names_xpm
)
);
// Menu View:
wxMenu
*
viewMenu
=
new
wxMenu
;
...
...
@@ -219,12 +219,12 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Zoom in
text
=
AddHotkeyName
(
_
(
"Zoom In"
),
s_Schematic_Hokeys_Descr
,
ID_ZOOM_IN
,
false
);
// add comment
, not a shortcut
HK_ZOOM_IN
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
viewMenu
,
ID_ZOOM_IN
,
text
,
HELP_ZOOM_IN
,
KiBitmap
(
zoom_in_xpm
)
);
// Zoom out
text
=
AddHotkeyName
(
_
(
"Zoom Out"
),
s_Schematic_Hokeys_Descr
,
ID_ZOOM_OUT
,
false
);
// add comment
, not a shortcut
HK_ZOOM_OUT
,
IS_ACCELERATOR
);
// add accelerator
, not a shortcut
AddMenuItem
(
viewMenu
,
ID_ZOOM_OUT
,
text
,
HELP_ZOOM_OUT
,
KiBitmap
(
zoom_out_xpm
)
);
// Fit on screen
...
...
@@ -237,10 +237,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Hierarchy
AddMenuItem
(
viewMenu
,
ID_HIERARCHY
,
_
(
"H&ierarchy"
),
_
(
"Navigate schematic hierarchy"
),
KiBitmap
(
hierarchy_nav_xpm
)
);
ID_HIERARCHY
,
_
(
"H&ierarchy"
),
_
(
"Navigate schematic hierarchy"
),
KiBitmap
(
hierarchy_nav_xpm
)
);
// Redraw
text
=
AddHotkeyName
(
_
(
"Redraw"
),
s_Schematic_Hokeys_Descr
,
HK_ZOOM_REDRAW
);
...
...
@@ -252,155 +252,155 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Component
text
=
AddHotkeyName
(
_
(
"Component"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_NEW_COMPONENT
,
false
);
// add comment
, not a shortcut
HK_ADD_NEW_COMPONENT
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_SCH_PLACE_COMPONENT
,
text
,
HELP_PLACE_COMPONENTS
,
KiBitmap
(
add_component_xpm
)
);
HELP_PLACE_COMPONENTS
,
KiBitmap
(
add_component_xpm
)
);
// Power port
text
=
AddHotkeyName
(
_
(
"Power Port"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_NEW_POWER
,
false
);
// add comment
, not a shortcut
HK_ADD_NEW_POWER
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_PLACE_POWER_BUTT
,
text
,
HELP_PLACE_POWERPORT
,
KiBitmap
(
add_power_xpm
)
);
HELP_PLACE_POWERPORT
,
KiBitmap
(
add_power_xpm
)
);
// Wire
text
=
AddHotkeyName
(
_
(
"Wire"
),
s_Schematic_Hokeys_Descr
,
HK_BEGIN_WIRE
,
false
);
// add comment
, not a shortcut
HK_BEGIN_WIRE
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_WIRE_BUTT
,
text
,
HELP_PLACE_WIRE
,
KiBitmap
(
add_line_xpm
)
);
HELP_PLACE_WIRE
,
KiBitmap
(
add_line_xpm
)
);
// Bus
text
=
AddHotkeyName
(
_
(
"Bus"
),
s_Schematic_Hokeys_Descr
,
HK_BEGIN_BUS
,
false
);
// add comment
, not a shortcut
HK_BEGIN_BUS
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_BUS_BUTT
,
text
,
HELP_PLACE_BUS
,
KiBitmap
(
add_bus_xpm
)
);
HELP_PLACE_BUS
,
KiBitmap
(
add_bus_xpm
)
);
// Wire to Bus entry
text
=
AddHotkeyName
(
_
(
"Wire to Bus Entry"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_WIRE_ENTRY
,
false
);
// add comment
, not a shortcut
HK_ADD_WIRE_ENTRY
,
IS_ACCELERATOR
);
// addan accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_WIRETOBUS_ENTRY_BUTT
,
text
,
HELP_PLACE_WIRE2BUS_ENTRY
,
KiBitmap
(
add_line2bus_xpm
)
);
HELP_PLACE_WIRE2BUS_ENTRY
,
KiBitmap
(
add_line2bus_xpm
)
);
// Bus to Bus entry
text
=
AddHotkeyName
(
_
(
"Bus to Bus Entry"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_BUS_ENTRY
,
false
);
// add comment
, not a shortcut
HK_ADD_BUS_ENTRY
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_BUSTOBUS_ENTRY_BUTT
,
text
,
HELP_PLACE_BUS2BUS_ENTRY
,
KiBitmap
(
add_bus2bus_xpm
)
);
HELP_PLACE_BUS2BUS_ENTRY
,
KiBitmap
(
add_bus2bus_xpm
)
);
// No Connect Flag
text
=
AddHotkeyName
(
_
(
"No Connect Flag"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_NOCONN_FLAG
,
false
);
// add comment
, not a shortcut
HK_ADD_NOCONN_FLAG
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_NOCONN_BUTT
,
text
,
HELP_PLACE_NC_FLAG
,
KiBitmap
(
noconn_xpm
)
);
// Net name
text
=
AddHotkeyName
(
_
(
"Label"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_LABEL
,
false
);
// add comment
, not a shortcut
HK_ADD_LABEL
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_LABEL_BUTT
,
text
,
HELP_PLACE_NETLABEL
,
KiBitmap
(
add_line_label_xpm
)
);
HELP_PLACE_NETLABEL
,
KiBitmap
(
add_line_label_xpm
)
);
// Global label
text
=
AddHotkeyName
(
_
(
"Global Label"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_GLABEL
,
false
);
// add comment
, not a shortcut
HK_ADD_GLABEL
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_GLABEL_BUTT
,
text
,
HELP_PLACE_GLOBALLABEL
,
KiBitmap
(
add_glabel_xpm
)
);
HELP_PLACE_GLOBALLABEL
,
KiBitmap
(
add_glabel_xpm
)
);
// Junction
text
=
AddHotkeyName
(
_
(
"Junction"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_JUNCTION
,
false
);
// add comment
, not a shortcut
HK_ADD_JUNCTION
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_JUNCTION_BUTT
,
text
,
HELP_PLACE_JUNCTION
,
KiBitmap
(
add_junction_xpm
)
);
HELP_PLACE_JUNCTION
,
KiBitmap
(
add_junction_xpm
)
);
// Separator
placeMenu
->
AppendSeparator
();
// Hierarchical label
text
=
AddHotkeyName
(
_
(
"Hierarchical Label"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_HLABEL
,
false
);
// add comment
, not a shortcut
HK_ADD_HLABEL
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
text
=
AddHotkeyName
(
_
(
"Hierarchical Label"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_HLABEL
,
false
);
// add comment
, not a shortcut
HK_ADD_HLABEL
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_HIERLABEL_BUTT
,
text
,
HELP_PLACE_HIER_LABEL
,
KiBitmap
(
add_hierarchical_label_xpm
)
);
text
,
HELP_PLACE_HIER_LABEL
,
KiBitmap
(
add_hierarchical_label_xpm
)
);
// Hierarchical sheet
text
=
AddHotkeyName
(
_
(
"Hierarchical Sheet"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_HIER_SHEET
,
false
);
// add comment
, not a shortcut
HK_ADD_HIER_SHEET
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_SHEET_SYMBOL_BUTT
,
text
,
HELP_PLACE_SHEET
,
KiBitmap
(
add_hierarchical_subsheet_xpm
)
);
HELP_PLACE_SHEET
,
KiBitmap
(
add_hierarchical_subsheet_xpm
)
);
// Import hierarchical sheet
AddMenuItem
(
placeMenu
,
ID_IMPORT_HLABEL_BUTT
,
_
(
"Import Hierarchical Label"
),
HELP_IMPORT_SHEETPIN
,
KiBitmap
(
import_hierarchical_label_xpm
)
);
ID_IMPORT_HLABEL_BUTT
,
_
(
"Import Hierarchical Label"
),
HELP_IMPORT_SHEETPIN
,
KiBitmap
(
import_hierarchical_label_xpm
)
);
// Add hierarchical Pin to Sheet
AddMenuItem
(
placeMenu
,
ID_SHEET_PIN_BUTT
,
_
(
"Hierarchical Pin to Sheet"
),
HELP_PLACE_SHEETPIN
,
KiBitmap
(
add_hierar_pin_xpm
)
);
ID_SHEET_PIN_BUTT
,
_
(
"Hierarchical Pin to Sheet"
),
HELP_PLACE_SHEETPIN
,
KiBitmap
(
add_hierar_pin_xpm
)
);
// Separator
placeMenu
->
AppendSeparator
();
// Graphic line or polygon
text
=
AddHotkeyName
(
_
(
"Graphic Polyline"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_GRAPHIC_POLYLINE
,
false
);
// add comment
, not a shortcut
HK_ADD_GRAPHIC_POLYLINE
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_LINE_COMMENT_BUTT
,
text
,
HELP_PLACE_GRAPHICLINES
,
KiBitmap
(
add_dashed_line_xpm
)
);
HELP_PLACE_GRAPHICLINES
,
KiBitmap
(
add_dashed_line_xpm
)
);
// Graphic text
text
=
AddHotkeyName
(
_
(
"Graphic Text"
),
s_Schematic_Hokeys_Descr
,
HK_ADD_GRAPHIC_TEXT
,
false
);
// add comment
, not a shortcut
HK_ADD_GRAPHIC_TEXT
,
IS_ACCELERATOR
);
// add an accelerator
, not a shortcut
AddMenuItem
(
placeMenu
,
ID_TEXT_COMMENT_BUTT
,
text
,
HELP_PLACE_GRAPHICTEXTS
,
KiBitmap
(
add_text_xpm
)
);
HELP_PLACE_GRAPHICTEXTS
,
KiBitmap
(
add_text_xpm
)
);
// Graphic image
AddMenuItem
(
placeMenu
,
ID_ADD_IMAGE_BUTT
,
_
(
"Image"
),
HELP_PLACE_GRAPHICIMAGES
,
KiBitmap
(
image_xpm
)
);
AddMenuItem
(
placeMenu
,
ID_ADD_IMAGE_BUTT
,
_
(
"Image"
),
HELP_PLACE_GRAPHICIMAGES
,
KiBitmap
(
image_xpm
)
);
// Menu Preferences:
wxMenu
*
preferencesMenu
=
new
wxMenu
;
// Library
AddMenuItem
(
preferencesMenu
,
ID_CONFIG_REQ
,
_
(
"&Library"
),
_
(
"Library preferences"
),
KiBitmap
(
library_xpm
)
);
ID_CONFIG_REQ
,
_
(
"&Library"
),
_
(
"Library preferences"
),
KiBitmap
(
library_xpm
)
);
// Colors
AddMenuItem
(
preferencesMenu
,
ID_COLORS_SETUP
,
_
(
"&Colors"
),
_
(
"Color preferences"
),
KiBitmap
(
palette_xpm
)
);
ID_COLORS_SETUP
,
_
(
"&Colors"
),
_
(
"Color preferences"
),
KiBitmap
(
palette_xpm
)
);
// Options (Preferences on WXMAC)
#ifdef __WXMAC__
preferencesMenu
->
Append
(
wxID_PREFERENCES
);
preferencesMenu
->
Append
(
wxID_PREFERENCES
);
#else
AddMenuItem
(
preferencesMenu
,
wxID_PREFERENCES
,
_
(
"&Options"
),
_
(
"EESchema preferences"
),
KiBitmap
(
preference_xpm
)
);
wxID_PREFERENCES
,
_
(
"&Options"
),
_
(
"EESchema preferences"
),
KiBitmap
(
preference_xpm
)
);
#endif // __WXMAC__
...
...
@@ -415,83 +415,83 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Save preferences
AddMenuItem
(
preferencesMenu
,
ID_CONFIG_SAVE
,
_
(
"&Save Preferences"
),
_
(
"Save application preferences"
),
KiBitmap
(
save_setup_xpm
)
);
ID_CONFIG_SAVE
,
_
(
"&Save Preferences"
),
_
(
"Save application preferences"
),
KiBitmap
(
save_setup_xpm
)
);
// Read preferences
AddMenuItem
(
preferencesMenu
,
ID_CONFIG_READ
,
_
(
"&Read Preferences"
),
_
(
"Read application preferences"
),
KiBitmap
(
read_setup_xpm
)
);
ID_CONFIG_READ
,
_
(
"&Read Preferences"
),
_
(
"Read application preferences"
),
KiBitmap
(
read_setup_xpm
)
);
// Menu Tools:
wxMenu
*
toolsMenu
=
new
wxMenu
;
// Library viewer
AddMenuItem
(
toolsMenu
,
ID_TO_LIBRARY
,
_
(
"Library &Browser"
),
_
(
"Library browser"
),
KiBitmap
(
library_browse_xpm
)
);
ID_TO_LIBRARY
,
_
(
"Library &Browser"
),
_
(
"Library browser"
),
KiBitmap
(
library_browse_xpm
)
);
// Library editor
AddMenuItem
(
toolsMenu
,
ID_TO_LIBRARY
,
_
(
"Library &Editor"
),
_
(
"Library editor"
),
KiBitmap
(
libedit_xpm
)
);
ID_TO_LIBRARY
,
_
(
"Library &Editor"
),
_
(
"Library editor"
),
KiBitmap
(
libedit_xpm
)
);
// Separator
toolsMenu
->
AppendSeparator
();
// Annotate
AddMenuItem
(
toolsMenu
,
ID_GET_ANNOTATE
,
_
(
"&Annotate"
),
_
(
"Annotate the components in the schematic"
),
KiBitmap
(
annotate_xpm
)
);
ID_GET_ANNOTATE
,
_
(
"&Annotate"
),
_
(
"Annotate the components in the schematic"
),
KiBitmap
(
annotate_xpm
)
);
// ERC
AddMenuItem
(
toolsMenu
,
ID_GET_ERC
,
_
(
"ER&C"
),
_
(
"Perform electrical rule check"
),
KiBitmap
(
erc_xpm
)
);
ID_GET_ERC
,
_
(
"ER&C"
),
_
(
"Perform electrical rule check"
),
KiBitmap
(
erc_xpm
)
);
// Generate netlist
AddMenuItem
(
toolsMenu
,
ID_GET_NETLIST
,
_
(
"Generate &Netlist"
),
_
(
"Generate the component netlist"
),
KiBitmap
(
netlist_xpm
)
);
ID_GET_NETLIST
,
_
(
"Generate &Netlist"
),
_
(
"Generate the component netlist"
),
KiBitmap
(
netlist_xpm
)
);
// Generate bill of materials
AddMenuItem
(
toolsMenu
,
ID_GET_TOOLS
,
_
(
"Generate Bill of Materials"
),
_
(
"Generate bill of materials"
),
KiBitmap
(
tools_xpm
)
);
ID_GET_TOOLS
,
_
(
"Generate Bill of Materials"
),
_
(
"Generate bill of materials"
),
KiBitmap
(
tools_xpm
)
);
// Separator
toolsMenu
->
AppendSeparator
();
//Run CVPcb
AddMenuItem
(
toolsMenu
,
ID_TO_CVPCB
,
_
(
"A&ssign Component Footprints"
),
_
(
"Run CVPcb"
),
KiBitmap
(
cvpcb_xpm
)
);
ID_TO_CVPCB
,
_
(
"A&ssign Component Footprints"
),
_
(
"Run CVPcb"
),
KiBitmap
(
cvpcb_xpm
)
);
// Run PCBNew
AddMenuItem
(
toolsMenu
,
ID_TO_PCB
,
_
(
"&Layout Printed Circuit Board"
),
_
(
"Run PCBNew"
),
KiBitmap
(
pcbnew_xpm
)
);
ID_TO_PCB
,
_
(
"&Layout Printed Circuit Board"
),
_
(
"Run PCBNew"
),
KiBitmap
(
pcbnew_xpm
)
);
// Help Menu:
...
...
@@ -502,23 +502,23 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
// Contents
AddMenuItem
(
helpMenu
,
wxID_HELP
,
_
(
"&Contents"
),
_
(
"Open the Eeschema handbook"
),
KiBitmap
(
online_help_xpm
)
);
wxID_HELP
,
_
(
"&Contents"
),
_
(
"Open the Eeschema handbook"
),
KiBitmap
(
online_help_xpm
)
);
AddMenuItem
(
helpMenu
,
wxID_INDEX
,
_
(
"&Getting Started in KiCad"
),
_
(
"Open the
\"
Getting Started in KiCad
\"
guide for beginners"
),
KiBitmap
(
help_xpm
)
);
wxID_INDEX
,
_
(
"&Getting Started in KiCad"
),
_
(
"Open the
\"
Getting Started in KiCad
\"
guide for beginners"
),
KiBitmap
(
help_xpm
)
);
// About EESchema
helpMenu
->
AppendSeparator
();
AddMenuItem
(
helpMenu
,
wxID_ABOUT
,
_
(
"&About EESchema"
),
_
(
"About EESchema schematic designer"
),
KiBitmap
(
info_xpm
)
);
wxID_ABOUT
,
_
(
"&About EESchema"
),
_
(
"About EESchema schematic designer"
),
KiBitmap
(
info_xpm
)
);
// Create the menubar and append all submenus
menuBar
->
Append
(
fileMenu
,
_
(
"&File"
)
);
...
...
eeschema/tool_lib.cpp
View file @
8db19bbd
...
...
@@ -116,9 +116,9 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
_
(
"Save current component to new library"
)
);
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
_
(
"Undo last command"
),
s_Schematic_Hokeys_Descr
,
HK_UNDO
,
false
);
msg
=
AddHotkeyName
(
_
(
"Undo last command"
),
s_Schematic_Hokeys_Descr
,
HK_UNDO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
wxID_UNDO
,
wxEmptyString
,
KiBitmap
(
undo_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Redo the last command"
),
s_Schematic_Hokeys_Descr
,
HK_REDO
,
false
);
msg
=
AddHotkeyName
(
_
(
"Redo the last command"
),
s_Schematic_Hokeys_Descr
,
HK_REDO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
wxID_REDO
,
wxEmptyString
,
KiBitmap
(
redo_xpm
),
msg
);
m_HToolBar
->
AddSeparator
();
...
...
@@ -133,16 +133,16 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
_
(
"Test for duplicate pins and off grid pins"
)
);
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
HELP_ZOOM_IN
,
s_Libedit_Hokeys_Descr
,
HK_ZOOM_IN
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_IN
,
s_Libedit_Hokeys_Descr
,
HK_ZOOM_IN
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_IN
,
wxEmptyString
,
KiBitmap
(
zoom_in_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_OUT
,
s_Libedit_Hokeys_Descr
,
HK_ZOOM_OUT
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_OUT
,
s_Libedit_Hokeys_Descr
,
HK_ZOOM_OUT
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_OUT
,
wxEmptyString
,
KiBitmap
(
zoom_out_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_REDRAW
,
s_Libedit_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_REDRAW
,
s_Libedit_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_REDRAW
,
wxEmptyString
,
KiBitmap
(
zoom_redraw_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_FIT
,
s_Libedit_Hokeys_Descr
,
HK_ZOOM_AUTO
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_FIT
,
s_Libedit_Hokeys_Descr
,
HK_ZOOM_AUTO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_PAGE
,
wxEmptyString
,
KiBitmap
(
zoom_fit_in_page_xpm
),
msg
);
m_HToolBar
->
AddSeparator
();
...
...
eeschema/tool_sch.cpp
View file @
8db19bbd
...
...
@@ -64,33 +64,33 @@ void SCH_EDIT_FRAME::ReCreateHToolbar()
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
HELP_UNDO
,
s_Schematic_Hokeys_Descr
,
HK_UNDO
,
false
);
msg
=
AddHotkeyName
(
HELP_UNDO
,
s_Schematic_Hokeys_Descr
,
HK_UNDO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
wxID_UNDO
,
wxEmptyString
,
KiBitmap
(
undo_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_REDO
,
s_Schematic_Hokeys_Descr
,
HK_REDO
,
false
);
msg
=
AddHotkeyName
(
HELP_REDO
,
s_Schematic_Hokeys_Descr
,
HK_REDO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
wxID_REDO
,
wxEmptyString
,
KiBitmap
(
redo_xpm
),
msg
);
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
HELP_FIND
,
s_Schematic_Hokeys_Descr
,
HK_FIND_ITEM
,
false
);
msg
=
AddHotkeyName
(
HELP_FIND
,
s_Schematic_Hokeys_Descr
,
HK_FIND_ITEM
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_FIND_ITEMS
,
wxEmptyString
,
KiBitmap
(
find_xpm
),
msg
);
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
HELP_ZOOM_IN
,
s_Schematic_Hokeys_Descr
,
HK_ZOOM_IN
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_IN
,
s_Schematic_Hokeys_Descr
,
HK_ZOOM_IN
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_IN
,
wxEmptyString
,
KiBitmap
(
zoom_in_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_OUT
,
s_Schematic_Hokeys_Descr
,
HK_ZOOM_OUT
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_OUT
,
s_Schematic_Hokeys_Descr
,
HK_ZOOM_OUT
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_OUT
,
wxEmptyString
,
KiBitmap
(
zoom_out_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_REDRAW
,
s_Schematic_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_REDRAW
,
s_Schematic_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_REDRAW
,
wxEmptyString
,
KiBitmap
(
zoom_redraw_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_FIT
,
s_Schematic_Hokeys_Descr
,
HK_ZOOM_AUTO
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_FIT
,
s_Schematic_Hokeys_Descr
,
HK_ZOOM_AUTO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_PAGE
,
wxEmptyString
,
KiBitmap
(
zoom_fit_in_page_xpm
),
msg
);
...
...
eeschema/tool_viewlib.cpp
View file @
8db19bbd
...
...
@@ -47,22 +47,22 @@ void LIB_VIEW_FRAME::ReCreateHToolbar()
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
_
(
"Zoom in"
),
s_Viewlib_Hokeys_Descr
,
HK_ZOOM_IN
,
false
);
HK_ZOOM_IN
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_IN
,
wxEmptyString
,
KiBitmap
(
zoom_in_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Zoom out"
),
s_Viewlib_Hokeys_Descr
,
HK_ZOOM_OUT
,
false
);
HK_ZOOM_OUT
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_OUT
,
wxEmptyString
,
KiBitmap
(
zoom_out_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Redraw view"
),
s_Viewlib_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
false
);
HK_ZOOM_REDRAW
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_REDRAW
,
wxEmptyString
,
KiBitmap
(
zoom_redraw_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Zoom auto"
),
s_Viewlib_Hokeys_Descr
,
HK_ZOOM_AUTO
,
false
);
HK_ZOOM_AUTO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_PAGE
,
wxEmptyString
,
KiBitmap
(
zoom_fit_in_page_xpm
),
msg
);
...
...
gerbview/class_aperture_macro.cpp
View file @
8db19bbd
/****************************/
/* class_aperture_macro.cpp */
/****************************/
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "fctsys.h"
#include "common.h"
#include "macros.h"
#include "trigo.h"
#include "gr_basic.h"
#include "gerbview.h"
#include "class_GERBER.h"
/**
* Function scale
* converts a distance given in floating point to our deci-mils
*/
extern
int
scale
(
double
aCoord
,
bool
isMetric
);
// defined it rs274d.cpp
/**
* Function mapPt
* translates a point from the aperture macro coordinate system to our
* deci-mils coordinate system.
* @return wxPoint - The gerbview coordinate system vector.
*/
static
wxPoint
mapPt
(
double
x
,
double
y
,
bool
isMetric
)
{
wxPoint
ret
(
scale
(
x
,
isMetric
),
scale
(
y
,
isMetric
)
);
return
ret
;
}
/**
* Function mapExposure
* translates the first parameter from an aperture macro into a current
* exposure setting.
* @param aParent = a GERBER_DRAW_ITEM that handle:
* ** m_Exposure A dynamic setting which can change throughout the
* reading of the gerber file, and it indicates whether the current tool
* is lit or not.
* ** m_ImageNegative A dynamic setting which can change throughout the reading
* of the gerber file, and it indicates whether the current D codes are to
* be interpreted as erasures or not.
* @return true to draw with current color, false to draw with alt color (erase)
*/
bool
AM_PRIMITIVE
::
mapExposure
(
GERBER_DRAW_ITEM
*
aParent
)
{
bool
exposure
;
switch
(
primitive_id
)
{
case
AMP_CIRCLE
:
case
AMP_LINE2
:
case
AMP_LINE20
:
case
AMP_LINE_CENTER
:
case
AMP_LINE_LOWER_LEFT
:
case
AMP_OUTLINE
:
case
AMP_THERMAL
:
case
AMP_POLYGON
:
// All have an exposure parameter and can return true or false
switch
(
GetExposure
(
aParent
)
)
{
case
0
:
// exposure always OFF
exposure
=
false
;
break
;
default
:
case
1
:
// exposure always OON
exposure
=
true
;
break
;
case
2
:
// reverse exposure
exposure
=
!
aParent
->
GetLayerPolarity
();
}
break
;
case
AMP_MOIRE
:
case
AMP_EOF
:
case
AMP_UNKNOWN
:
default
:
return
true
;
// All have no exposure parameter and must return true (no change for exposure)
break
;
}
return
exposure
^
aParent
->
m_imageParams
->
m_ImageNegative
;
}
/**
* Function GetExposure
* returns the first parameter in integer form. Some but not all primitives
* use the first parameter as an exposure control.
*/
int
AM_PRIMITIVE
::
GetExposure
(
GERBER_DRAW_ITEM
*
aParent
)
const
{
// No D_CODE* for GetValue()
wxASSERT
(
params
.
size
()
&&
params
[
0
].
IsImmediate
()
);
return
(
int
)
params
[
0
].
GetValue
(
aParent
->
GetDcodeDescr
()
);
}
/**
* Function DrawBasicShape
* Draw the primitive shape for flashed items.
*/
void
AM_PRIMITIVE
::
DrawBasicShape
(
GERBER_DRAW_ITEM
*
aParent
,
EDA_RECT
*
aClipBox
,
wxDC
*
aDC
,
int
aColor
,
int
aAltColor
,
wxPoint
aShapePos
,
bool
aFilledShape
)
{
static
std
::
vector
<
wxPoint
>
polybuffer
;
// create a static buffer to avoid a lot of memory reallocation
polybuffer
.
clear
();
wxPoint
curPos
=
aShapePos
;
D_CODE
*
tool
=
aParent
->
GetDcodeDescr
();
int
rotation
;
if
(
mapExposure
(
aParent
)
==
false
)
{
EXCHG
(
aColor
,
aAltColor
);
}
switch
(
primitive_id
)
{
case
AMP_CIRCLE
:
// Circle, given diameter and position
{
/* Generated by an aperture macro declaration like:
* "1,1,0.3,0.5, 1.0*"
* type (1), exposure, diameter, pos.x, pos.y
* type is not stored in parameters list, so the first parameter is exposure
*/
curPos
+=
mapPt
(
params
[
2
].
GetValue
(
tool
),
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
);
curPos
=
aParent
->
GetABPosition
(
curPos
);
int
radius
=
scale
(
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
if
(
!
aFilledShape
)
GRCircle
(
aClipBox
,
aDC
,
curPos
,
radius
,
0
,
aColor
);
else
GRFilledCircle
(
aClipBox
,
aDC
,
curPos
,
radius
,
aColor
);
}
break
;
case
AMP_LINE2
:
case
AMP_LINE20
:
// Line with rectangle ends. (Width, start and end pos + rotation)
{
/* Generated by an aperture macro declaration like:
* "2,1,0.3,0,0, 0.5, 1.0,-135*"
* type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// shape rotation:
rotation
=
wxRound
(
params
[
6
].
GetValue
(
tool
)
*
10.0
);
if
(
rotation
)
{
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
}
// Move to current position:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_LINE_CENTER
:
{
/* Generated by an aperture macro declaration like:
* "21,1,0.3,0.03,0,0,-135*"
* type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// shape rotation:
rotation
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
*
10.0
);
if
(
rotation
)
{
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
}
// Move to current position:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_LINE_LOWER_LEFT
:
{
/* Generated by an aperture macro declaration like:
* "22,1,0.3,0.03,0,0,-135*"
* type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// shape rotation:
rotation
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
*
10.0
);
if
(
rotation
)
{
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
}
// Move to current position:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_THERMAL
:
{
/* Generated by an aperture macro declaration like:
* "7, 0,0,1.0,0.3,0.01,-13*"
* type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
* type is not stored in parameters list, so the first parameter is center.x
*/
curPos
+=
mapPt
(
params
[
0
].
GetValue
(
tool
),
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// shape rotation:
rotation
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
*
10.0
);
// Because a thermal shape has 4 identical sub-shapes, only one is created in polybuffer.
// We must draw 4 sub-shapes rotated by 90 deg
std
::
vector
<
wxPoint
>
subshape_poly
;
for
(
int
ii
=
0
;
ii
<
4
;
ii
++
)
{
subshape_poly
=
polybuffer
;
int
sub_rotation
=
rotation
+
900
*
ii
;
for
(
unsigned
jj
=
0
;
jj
<
subshape_poly
.
size
();
jj
++
)
RotatePoint
(
&
subshape_poly
[
jj
],
-
sub_rotation
);
// Move to current position:
for
(
unsigned
jj
=
0
;
jj
<
subshape_poly
.
size
();
jj
++
)
{
subshape_poly
[
jj
]
+=
curPos
;
subshape_poly
[
jj
]
=
aParent
->
GetABPosition
(
subshape_poly
[
jj
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
subshape_poly
.
size
(),
&
subshape_poly
[
0
],
true
,
aAltColor
,
aAltColor
);
}
}
break
;
case
AMP_MOIRE
:
// A cross hair with n concentric circles
{
curPos
+=
mapPt
(
params
[
0
].
GetValue
(
tool
),
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
/* Generated by an aperture macro declaration like:
* "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
* type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation
* type is not stored in parameters list, so the first parameter is pos.x
*/
int
outerDiam
=
scale
(
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
int
penThickness
=
scale
(
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
);
int
gap
=
scale
(
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
);
int
numCircles
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
);
// Draw circles:
wxPoint
center
=
aParent
->
GetABPosition
(
curPos
);
// adjust outerDiam by this on each nested circle
int
diamAdjust
=
(
gap
+
penThickness
);
//*2; //Should we use * 2 ?
for
(
int
i
=
0
;
i
<
numCircles
;
++
i
,
outerDiam
-=
diamAdjust
)
{
if
(
outerDiam
<=
0
)
break
;
if
(
!
aFilledShape
)
{
// draw the border of the pen's path using two circles, each as narrow as possible
GRCircle
(
aClipBox
,
aDC
,
center
,
outerDiam
/
2
,
0
,
aColor
);
GRCircle
(
aClipBox
,
aDC
,
center
,
outerDiam
/
2
-
penThickness
,
0
,
aColor
);
}
else
// Filled mode
{
GRCircle
(
aClipBox
,
aDC
,
center
,
(
outerDiam
-
penThickness
)
/
2
,
penThickness
,
aColor
);
}
}
// Draw the cross:
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
rotation
=
wxRound
(
params
[
8
].
GetValue
(
tool
)
*
10.0
);
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
// shape rotation:
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
// Move to current position:
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_OUTLINE
:
{
/* Generated by an aperture macro declaration like:
* "4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25"
* type(4), exposure, corners count, corner1.x, corner.1y, ..., rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
int
numPoints
=
(
int
)
params
[
1
].
GetValue
(
tool
);
rotation
=
wxRound
(
params
[
numPoints
*
2
+
4
].
GetValue
(
tool
)
*
10.0
);
wxPoint
pos
;
// Read points. numPoints does not include the starting point, so add 1.
for
(
int
i
=
0
;
i
<
numPoints
+
1
;
++
i
)
{
int
jj
=
i
*
2
+
2
;
pos
.
x
=
scale
(
params
[
jj
].
GetValue
(
tool
),
m_GerbMetric
);
pos
.
y
=
scale
(
params
[
jj
+
1
].
GetValue
(
tool
),
m_GerbMetric
);
polybuffer
.
push_back
(
pos
);
}
// rotate polygon and move it to the actual position
// shape rotation:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
}
// Move to current position:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_POLYGON
:
// Is a regular polygon
/* Generated by an aperture macro declaration like:
* "5,1,0.6,0,0,0.5,25"
* type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
curPos
+=
mapPt
(
params
[
2
].
GetValue
(
tool
),
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
);
// Creates the shape:
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// rotate polygon and move it to the actual position
rotation
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
*
10.0
);
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
break
;
case
AMP_EOF
:
// not yet supported, waiting for you.
break
;
case
AMP_UNKNOWN
:
default
:
D
(
printf
(
"AM_PRIMITIVE::DrawBasicShape() err: unknown prim id %d
\n
"
,
primitive_id
)
);
break
;
}
}
/**
* Function ConvertShapeToPolygon (virtual)
* convert a shape to an equivalent polygon.
* Arcs and circles are approximated by segments
* Useful when a shape is not a graphic primitive (shape with hole,
* rotated shape ... ) and cannot be easily drawn.
* note for some schapes conbining circles and solid lines (rectangles), only rectangles are converted
* because circles are very easy to draw (no rotation problem) so convert them in polygons,
* and draw them as polygons is not a good idea.
*/
void
AM_PRIMITIVE
::
ConvertShapeToPolygon
(
GERBER_DRAW_ITEM
*
aParent
,
std
::
vector
<
wxPoint
>&
aBuffer
)
{
D_CODE
*
tool
=
aParent
->
GetDcodeDescr
();
switch
(
primitive_id
)
{
case
AMP_CIRCLE
:
// Circle, currently convertion not needed
break
;
case
AMP_LINE2
:
case
AMP_LINE20
:
// Line with rectangle ends. (Width, start and end pos + rotation)
{
int
width
=
scale
(
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
start
=
mapPt
(
params
[
2
].
GetValue
(
tool
),
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
end
=
mapPt
(
params
[
4
].
GetValue
(
tool
),
params
[
5
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
delta
=
end
-
start
;
int
len
=
wxRound
(
hypot
(
delta
.
x
,
delta
.
y
)
);
// To build the polygon, we must create a horizonta polygon starting to "start"
// and rotate it to have it end point to "end"
wxPoint
currpt
;
currpt
.
y
+=
width
/
2
;
// Upper left
aBuffer
.
push_back
(
currpt
);
currpt
.
x
=
len
;
// Upper right
aBuffer
.
push_back
(
currpt
);
currpt
.
y
-=
width
;
// lower right
aBuffer
.
push_back
(
currpt
);
currpt
.
x
=
0
;
// Upper left
aBuffer
.
push_back
(
currpt
);
// Rotate rectangle and move it to the actual start point
int
angle
=
wxRound
(
atan2
(
(
double
)
delta
.
y
,
(
double
)
delta
.
x
)
*
1800.0
/
M_PI
);
for
(
unsigned
ii
=
0
;
ii
<
4
;
ii
++
)
{
RotatePoint
(
&
aBuffer
[
ii
],
-
angle
);
aBuffer
[
ii
]
+=
start
;
}
}
break
;
case
AMP_LINE_CENTER
:
{
wxPoint
size
=
mapPt
(
params
[
1
].
GetValue
(
tool
),
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
pos
=
mapPt
(
params
[
3
].
GetValue
(
tool
),
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
);
// Build poly:
pos
.
x
-=
size
.
x
/
2
;
pos
.
y
-=
size
.
y
/
2
;
// Lower left
aBuffer
.
push_back
(
pos
);
pos
.
y
+=
size
.
y
;
// Upper left
aBuffer
.
push_back
(
pos
);
pos
.
x
+=
size
.
x
;
// Upper right
aBuffer
.
push_back
(
pos
);
pos
.
y
-=
size
.
y
;
// lower right
aBuffer
.
push_back
(
pos
);
}
break
;
case
AMP_LINE_LOWER_LEFT
:
{
wxPoint
size
=
mapPt
(
params
[
1
].
GetValue
(
tool
),
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
lowerLeft
=
mapPt
(
params
[
3
].
GetValue
(
tool
),
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
);
// Build poly:
aBuffer
.
push_back
(
lowerLeft
);
lowerLeft
.
y
+=
size
.
y
;
// Upper left
aBuffer
.
push_back
(
lowerLeft
);
lowerLeft
.
x
+=
size
.
x
;
// Upper right
aBuffer
.
push_back
(
lowerLeft
);
lowerLeft
.
y
-=
size
.
y
;
// lower right
aBuffer
.
push_back
(
lowerLeft
);
}
break
;
case
AMP_THERMAL
:
{
// Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
// rotated by 90, 180 and 270 deg.
// params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
int
outerRadius
=
scale
(
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
int
innerRadius
=
scale
(
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
int
halfthickness
=
scale
(
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
int
angle_start
=
wxRound
(
asin
(
(
double
)
halfthickness
/
innerRadius
)
*
1800
/
M_PI
);
// Draw shape in the first cadrant (X and Y > 0)
wxPoint
pos
,
startpos
;
// Inner arc
startpos
.
x
=
innerRadius
;
int
angle_end
=
900
-
angle_start
;
int
angle
;
for
(
angle
=
angle_start
;
angle
<
angle_end
;
angle
+=
100
)
{
pos
=
startpos
;
RotatePoint
(
&
pos
,
angle
);
aBuffer
.
push_back
(
pos
);
}
// Last point
pos
=
startpos
;
RotatePoint
(
&
pos
,
angle_end
);
aBuffer
.
push_back
(
pos
);
// outer arc
startpos
.
x
=
outerRadius
;
startpos
.
y
=
0
;
angle_start
=
wxRound
(
asin
(
(
double
)
halfthickness
/
outerRadius
)
*
1800
/
M_PI
);
angle_end
=
900
-
angle_start
;
// First point, near Y axis, outer arc
for
(
angle
=
angle_end
;
angle
>
angle_start
;
angle
-=
100
)
{
pos
=
startpos
;
RotatePoint
(
&
pos
,
angle
);
aBuffer
.
push_back
(
pos
);
}
// last point
pos
=
startpos
;
RotatePoint
(
&
pos
,
angle_start
);
aBuffer
.
push_back
(
pos
);
aBuffer
.
push_back
(
aBuffer
[
0
]
);
// Close poly
}
break
;
case
AMP_MOIRE
:
// A cross hair with n concentric circles. Only the cros is build as polygon
// because circles can be drawn easily
{
int
crossHairThickness
=
scale
(
params
[
6
].
GetValue
(
tool
),
m_GerbMetric
);
int
crossHairLength
=
scale
(
params
[
7
].
GetValue
(
tool
),
m_GerbMetric
);
// Create cross. First create 1/4 of the shape.
// Others point are the same, totated by 90, 180 and 270 deg
wxPoint
pos
(
crossHairThickness
/
2
,
crossHairLength
/
2
);
aBuffer
.
push_back
(
pos
);
pos
.
y
=
crossHairThickness
/
2
;
aBuffer
.
push_back
(
pos
);
pos
.
x
=
-
crossHairLength
/
2
;
aBuffer
.
push_back
(
pos
);
pos
.
y
=
-
crossHairThickness
/
2
;
aBuffer
.
push_back
(
pos
);
// Copy the 4 shape, rotated by 90, 180 and 270 deg
for
(
int
jj
=
1
;
jj
<=
3
;
jj
++
)
{
for
(
int
ii
=
0
;
ii
<
4
;
ii
++
)
{
pos
=
aBuffer
[
ii
];
RotatePoint
(
&
pos
,
jj
*
900
);
aBuffer
.
push_back
(
pos
);
}
}
}
break
;
case
AMP_OUTLINE
:
// already is a polygon. Do nothing
break
;
case
AMP_POLYGON
:
// Creates a regular polygon
{
int
vertexcount
=
wxRound
(
params
[
1
].
GetValue
(
tool
)
);
int
radius
=
scale
(
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
// rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
if
(
vertexcount
<
3
)
vertexcount
=
3
;
if
(
vertexcount
>
10
)
vertexcount
=
10
;
for
(
int
ii
=
0
;
ii
<=
vertexcount
;
ii
++
)
{
wxPoint
pos
(
radius
,
0
);
RotatePoint
(
&
pos
,
ii
*
3600
/
vertexcount
);
aBuffer
.
push_back
(
pos
);
}
}
break
;
case
AMP_COMMENT
:
case
AMP_UNKNOWN
:
case
AMP_EOF
:
break
;
}
}
/** GetShapeDim
* Calculate a value that can be used to evaluate the size of text
* when displaying the D-Code of an item
* due to the complexity of the shape of some primitives
* one cannot calculate the "size" of a shape (only abounding box)
* but here, the "dimension" of the shape is the diameter of the primitive
* or for lines the width of the line
* @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
* @return a dimension, or -1 if no dim to calculate
*/
int
AM_PRIMITIVE
::
GetShapeDim
(
GERBER_DRAW_ITEM
*
aParent
)
{
int
dim
=
-
1
;
D_CODE
*
tool
=
aParent
->
GetDcodeDescr
();
switch
(
primitive_id
)
{
case
AMP_CIRCLE
:
// params = exposure, diameter, pos.x, pos.y
dim
=
scale
(
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
// Diameter
break
;
case
AMP_LINE2
:
case
AMP_LINE20
:
// Line with rectangle ends. (Width, start and end pos + rotation)
dim
=
scale
(
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
// linne width
break
;
case
AMP_LINE_CENTER
:
{
wxPoint
size
=
mapPt
(
params
[
1
].
GetValue
(
tool
),
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
dim
=
MIN
(
size
.
x
,
size
.
y
);
}
break
;
case
AMP_LINE_LOWER_LEFT
:
{
wxPoint
size
=
mapPt
(
params
[
1
].
GetValue
(
tool
),
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
dim
=
MIN
(
size
.
x
,
size
.
y
);
}
break
;
case
AMP_THERMAL
:
{
// Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
// rotated by 90, 180 and 270 deg.
// params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
dim
=
scale
(
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
// Outer diam
}
break
;
case
AMP_MOIRE
:
// A cross hair with n concentric circles.
dim
=
scale
(
params
[
7
].
GetValue
(
tool
),
m_GerbMetric
);
// = cross hair len
break
;
case
AMP_OUTLINE
:
// a free polygon :
// dim = min side of the bounding box (this is a poor criteria, but what is a good criteria b?)
{
// exposure, corners count, corner1.x, corner.1y, ..., rotation
int
numPoints
=
(
int
)
params
[
1
].
GetValue
(
tool
);
// Read points. numPoints does not include the starting point, so add 1.
// and calculate the bounding box;
wxSize
pos_min
,
pos_max
,
pos
;
for
(
int
i
=
0
;
i
<
numPoints
+
1
;
++
i
)
{
int
jj
=
i
*
2
+
2
;
pos
.
x
=
scale
(
params
[
jj
].
GetValue
(
tool
),
m_GerbMetric
);
pos
.
y
=
scale
(
params
[
jj
+
1
].
GetValue
(
tool
),
m_GerbMetric
);
if
(
i
==
0
)
pos_min
=
pos_max
=
pos
;
else
{
// upper right corner:
if
(
pos_min
.
x
>
pos
.
x
)
pos_min
.
x
=
pos
.
x
;
if
(
pos_min
.
y
>
pos
.
y
)
pos_min
.
y
=
pos
.
y
;
// lower left corner:
if
(
pos_max
.
x
<
pos
.
x
)
pos_max
.
x
=
pos
.
x
;
if
(
pos_max
.
y
<
pos
.
y
)
pos_max
.
y
=
pos
.
y
;
}
}
// calculate dim
wxSize
size
;
size
.
x
=
pos_max
.
x
-
pos_min
.
x
;
size
.
y
=
pos_max
.
y
-
pos_min
.
y
;
dim
=
MIN
(
size
.
x
,
size
.
y
);
}
break
;
case
AMP_POLYGON
:
// Regular polygon
dim
=
scale
(
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
// Radius
break
;
case
AMP_COMMENT
:
case
AMP_UNKNOWN
:
case
AMP_EOF
:
break
;
}
return
dim
;
}
/**
* Function DrawApertureMacroShape
* Draw the primitive shape for flashed items.
* When an item is flashed, this is the shape of the item
*/
void
APERTURE_MACRO
::
DrawApertureMacroShape
(
GERBER_DRAW_ITEM
*
aParent
,
EDA_RECT
*
aClipBox
,
wxDC
*
aDC
,
int
aColor
,
int
aAltColor
,
wxPoint
aShapePos
,
bool
aFilledShape
)
{
for
(
AM_PRIMITIVES
::
iterator
prim_macro
=
primitives
.
begin
();
prim_macro
!=
primitives
.
end
();
++
prim_macro
)
{
prim_macro
->
DrawBasicShape
(
aParent
,
aClipBox
,
aDC
,
aColor
,
aAltColor
,
aShapePos
,
aFilledShape
);
}
}
/* Function HasNegativeItems
* return true if this macro has at least one aperture primitives
* that must be drawn in background color
* used to optimize screen refresh
*/
bool
APERTURE_MACRO
::
HasNegativeItems
(
GERBER_DRAW_ITEM
*
aParent
)
{
for
(
AM_PRIMITIVES
::
iterator
prim_macro
=
primitives
.
begin
();
prim_macro
!=
primitives
.
end
();
++
prim_macro
)
{
if
(
prim_macro
->
mapExposure
(
aParent
)
==
false
)
// = is negative
return
true
;
}
return
false
;
}
/** GetShapeDim
* Calculate a value that can be used to evaluate the size of text
* when displaying the D-Code of an item
* due to the complexity of a shape using many primitives
* one cannot calculate the "size" of a shape (only abounding box)
* but most of aperture macro are using one or few primitives
* and the "dimension" of the shape is the diameter of the primitive
* (or the max diameter of primitives)
* @return a dimension, or -1 if no dim to calculate
*/
int
APERTURE_MACRO
::
GetShapeDim
(
GERBER_DRAW_ITEM
*
aParent
)
{
int
dim
=
-
1
;
for
(
AM_PRIMITIVES
::
iterator
prim_macro
=
primitives
.
begin
();
prim_macro
!=
primitives
.
end
();
++
prim_macro
)
{
int
pdim
=
prim_macro
->
GetShapeDim
(
aParent
);
if
(
dim
<
pdim
)
dim
=
pdim
;
}
return
dim
;
}
/**
* function GetLocalParam
* Usually, parameters are defined inside the aperture primitive
* using immediate mode or defered mode.
* in defered mode the value is defined in a DCODE that want to use the aperture macro.
* But some parameters are defined outside the aperture primitive
* and are local to the aperture macro
* @return the value of a defered parameter defined inside the aperture macro
* @param aParamId = the param id (defined by $3 or $5 ..) to evaluate
*/
double
APERTURE_MACRO
::
GetLocalParam
(
const
D_CODE
*
aDcode
,
unsigned
aParamId
)
const
{
// find parameter descr.
const
AM_PARAM
*
param
=
NULL
;
for
(
unsigned
ii
=
0
;
ii
<
m_localparamStack
.
size
();
ii
++
)
{
if
(
m_localparamStack
[
ii
].
GetIndex
()
==
aParamId
)
{
param
=
&
m_localparamStack
[
ii
];
break
;
}
}
if
(
param
==
NULL
)
// not found
return
0.0
;
// Evaluate parameter
double
value
=
param
->
GetValue
(
aDcode
);
return
value
;
}
/****************************/
/* class_aperture_macro.cpp */
/****************************/
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "fctsys.h"
#include "common.h"
#include "macros.h"
#include "trigo.h"
#include "gr_basic.h"
#include "gerbview.h"
#include "class_GERBER.h"
/**
* Function scale
* converts a distance given in floating point to our deci-mils
*/
extern
int
scale
(
double
aCoord
,
bool
isMetric
);
// defined it rs274d.cpp
/**
* Function mapPt
* translates a point from the aperture macro coordinate system to our
* deci-mils coordinate system.
* @return wxPoint - The gerbview coordinate system vector.
*/
static
wxPoint
mapPt
(
double
x
,
double
y
,
bool
isMetric
)
{
wxPoint
ret
(
scale
(
x
,
isMetric
),
scale
(
y
,
isMetric
)
);
return
ret
;
}
/**
* Function mapExposure
* translates the first parameter from an aperture macro into a current
* exposure setting.
* @param aParent = a GERBER_DRAW_ITEM that handle:
* ** m_Exposure A dynamic setting which can change throughout the
* reading of the gerber file, and it indicates whether the current tool
* is lit or not.
* ** m_ImageNegative A dynamic setting which can change throughout the reading
* of the gerber file, and it indicates whether the current D codes are to
* be interpreted as erasures or not.
* @return true to draw with current color, false to draw with alt color (erase)
*/
bool
AM_PRIMITIVE
::
mapExposure
(
GERBER_DRAW_ITEM
*
aParent
)
{
bool
exposure
;
switch
(
primitive_id
)
{
case
AMP_CIRCLE
:
case
AMP_LINE2
:
case
AMP_LINE20
:
case
AMP_LINE_CENTER
:
case
AMP_LINE_LOWER_LEFT
:
case
AMP_OUTLINE
:
case
AMP_THERMAL
:
case
AMP_POLYGON
:
// All have an exposure parameter and can return true or false
switch
(
GetExposure
(
aParent
)
)
{
case
0
:
// exposure always OFF
exposure
=
false
;
break
;
default
:
case
1
:
// exposure always OON
exposure
=
true
;
break
;
case
2
:
// reverse exposure
exposure
=
!
aParent
->
GetLayerPolarity
();
}
break
;
case
AMP_MOIRE
:
case
AMP_EOF
:
case
AMP_UNKNOWN
:
default
:
return
true
;
// All have no exposure parameter and must return true (no change for exposure)
break
;
}
return
exposure
^
aParent
->
m_imageParams
->
m_ImageNegative
;
}
/**
* Function GetExposure
* returns the first parameter in integer form. Some but not all primitives
* use the first parameter as an exposure control.
*/
int
AM_PRIMITIVE
::
GetExposure
(
GERBER_DRAW_ITEM
*
aParent
)
const
{
// No D_CODE* for GetValue()
wxASSERT
(
params
.
size
()
&&
params
[
0
].
IsImmediate
()
);
return
(
int
)
params
[
0
].
GetValue
(
aParent
->
GetDcodeDescr
()
);
}
/**
* Function DrawBasicShape
* Draw the primitive shape for flashed items.
*/
void
AM_PRIMITIVE
::
DrawBasicShape
(
GERBER_DRAW_ITEM
*
aParent
,
EDA_RECT
*
aClipBox
,
wxDC
*
aDC
,
int
aColor
,
int
aAltColor
,
wxPoint
aShapePos
,
bool
aFilledShape
)
{
static
std
::
vector
<
wxPoint
>
polybuffer
;
// create a static buffer to avoid a lot of memory reallocation
polybuffer
.
clear
();
wxPoint
curPos
=
aShapePos
;
D_CODE
*
tool
=
aParent
->
GetDcodeDescr
();
int
rotation
;
if
(
mapExposure
(
aParent
)
==
false
)
{
EXCHG
(
aColor
,
aAltColor
);
}
switch
(
primitive_id
)
{
case
AMP_CIRCLE
:
// Circle, given diameter and position
{
/* Generated by an aperture macro declaration like:
* "1,1,0.3,0.5, 1.0*"
* type (1), exposure, diameter, pos.x, pos.y
* type is not stored in parameters list, so the first parameter is exposure
*/
curPos
+=
mapPt
(
params
[
2
].
GetValue
(
tool
),
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
);
curPos
=
aParent
->
GetABPosition
(
curPos
);
int
radius
=
scale
(
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
if
(
!
aFilledShape
)
GRCircle
(
aClipBox
,
aDC
,
curPos
,
radius
,
0
,
aColor
);
else
GRFilledCircle
(
aClipBox
,
aDC
,
curPos
,
radius
,
aColor
);
}
break
;
case
AMP_LINE2
:
case
AMP_LINE20
:
// Line with rectangle ends. (Width, start and end pos + rotation)
{
/* Generated by an aperture macro declaration like:
* "2,1,0.3,0,0, 0.5, 1.0,-135*"
* type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// shape rotation:
rotation
=
wxRound
(
params
[
6
].
GetValue
(
tool
)
*
10.0
);
if
(
rotation
)
{
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
}
// Move to current position:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_LINE_CENTER
:
{
/* Generated by an aperture macro declaration like:
* "21,1,0.3,0.03,0,0,-135*"
* type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// shape rotation:
rotation
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
*
10.0
);
if
(
rotation
)
{
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
}
// Move to current position:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_LINE_LOWER_LEFT
:
{
/* Generated by an aperture macro declaration like:
* "22,1,0.3,0.03,0,0,-135*"
* type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// shape rotation:
rotation
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
*
10.0
);
if
(
rotation
)
{
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
}
// Move to current position:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_THERMAL
:
{
/* Generated by an aperture macro declaration like:
* "7, 0,0,1.0,0.3,0.01,-13*"
* type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
* type is not stored in parameters list, so the first parameter is center.x
*/
curPos
+=
mapPt
(
params
[
0
].
GetValue
(
tool
),
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// shape rotation:
rotation
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
*
10.0
);
// Because a thermal shape has 4 identical sub-shapes, only one is created in polybuffer.
// We must draw 4 sub-shapes rotated by 90 deg
std
::
vector
<
wxPoint
>
subshape_poly
;
for
(
int
ii
=
0
;
ii
<
4
;
ii
++
)
{
subshape_poly
=
polybuffer
;
int
sub_rotation
=
rotation
+
900
*
ii
;
for
(
unsigned
jj
=
0
;
jj
<
subshape_poly
.
size
();
jj
++
)
RotatePoint
(
&
subshape_poly
[
jj
],
-
sub_rotation
);
// Move to current position:
for
(
unsigned
jj
=
0
;
jj
<
subshape_poly
.
size
();
jj
++
)
{
subshape_poly
[
jj
]
+=
curPos
;
subshape_poly
[
jj
]
=
aParent
->
GetABPosition
(
subshape_poly
[
jj
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
subshape_poly
.
size
(),
&
subshape_poly
[
0
],
true
,
aAltColor
,
aAltColor
);
}
}
break
;
case
AMP_MOIRE
:
// A cross hair with n concentric circles
{
curPos
+=
mapPt
(
params
[
0
].
GetValue
(
tool
),
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
/* Generated by an aperture macro declaration like:
* "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
* type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation
* type is not stored in parameters list, so the first parameter is pos.x
*/
int
outerDiam
=
scale
(
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
int
penThickness
=
scale
(
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
);
int
gap
=
scale
(
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
);
int
numCircles
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
);
// Draw circles:
wxPoint
center
=
aParent
->
GetABPosition
(
curPos
);
// adjust outerDiam by this on each nested circle
int
diamAdjust
=
(
gap
+
penThickness
);
//*2; //Should we use * 2 ?
for
(
int
i
=
0
;
i
<
numCircles
;
++
i
,
outerDiam
-=
diamAdjust
)
{
if
(
outerDiam
<=
0
)
break
;
if
(
!
aFilledShape
)
{
// draw the border of the pen's path using two circles, each as narrow as possible
GRCircle
(
aClipBox
,
aDC
,
center
,
outerDiam
/
2
,
0
,
aColor
);
GRCircle
(
aClipBox
,
aDC
,
center
,
outerDiam
/
2
-
penThickness
,
0
,
aColor
);
}
else
// Filled mode
{
GRCircle
(
aClipBox
,
aDC
,
center
,
(
outerDiam
-
penThickness
)
/
2
,
penThickness
,
aColor
);
}
}
// Draw the cross:
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
rotation
=
wxRound
(
params
[
8
].
GetValue
(
tool
)
*
10.0
);
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
// shape rotation:
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
// Move to current position:
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_OUTLINE
:
{
/* Generated by an aperture macro declaration like:
* "4,1,3,0.0,0.0,0.0,0.5,0.5,0.5,0.5,0.0,-25"
* type(4), exposure, corners count, corner1.x, corner.1y, ..., rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
int
numPoints
=
(
int
)
params
[
1
].
GetValue
(
tool
);
rotation
=
wxRound
(
params
[
numPoints
*
2
+
4
].
GetValue
(
tool
)
*
10.0
);
wxPoint
pos
;
// Read points. numPoints does not include the starting point, so add 1.
for
(
int
i
=
0
;
i
<
numPoints
+
1
;
++
i
)
{
int
jj
=
i
*
2
+
2
;
pos
.
x
=
scale
(
params
[
jj
].
GetValue
(
tool
),
m_GerbMetric
);
pos
.
y
=
scale
(
params
[
jj
+
1
].
GetValue
(
tool
),
m_GerbMetric
);
polybuffer
.
push_back
(
pos
);
}
// rotate polygon and move it to the actual position
// shape rotation:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
}
// Move to current position:
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
}
break
;
case
AMP_POLYGON
:
// Is a regular polygon
/* Generated by an aperture macro declaration like:
* "5,1,0.6,0,0,0.5,25"
* type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
* type is not stored in parameters list, so the first parameter is exposure
*/
curPos
+=
mapPt
(
params
[
2
].
GetValue
(
tool
),
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
);
// Creates the shape:
ConvertShapeToPolygon
(
aParent
,
polybuffer
);
// rotate polygon and move it to the actual position
rotation
=
wxRound
(
params
[
5
].
GetValue
(
tool
)
*
10.0
);
for
(
unsigned
ii
=
0
;
ii
<
polybuffer
.
size
();
ii
++
)
{
RotatePoint
(
&
polybuffer
[
ii
],
-
rotation
);
polybuffer
[
ii
]
+=
curPos
;
polybuffer
[
ii
]
=
aParent
->
GetABPosition
(
polybuffer
[
ii
]
);
}
GRClosedPoly
(
aClipBox
,
aDC
,
polybuffer
.
size
(),
&
polybuffer
[
0
],
aFilledShape
,
aColor
,
aColor
);
break
;
case
AMP_EOF
:
// not yet supported, waiting for you.
break
;
case
AMP_UNKNOWN
:
default
:
D
(
printf
(
"AM_PRIMITIVE::DrawBasicShape() err: unknown prim id %d
\n
"
,
primitive_id
)
);
break
;
}
}
/**
* Function ConvertShapeToPolygon (virtual)
* convert a shape to an equivalent polygon.
* Arcs and circles are approximated by segments
* Useful when a shape is not a graphic primitive (shape with hole,
* rotated shape ... ) and cannot be easily drawn.
* note for some schapes conbining circles and solid lines (rectangles), only rectangles are converted
* because circles are very easy to draw (no rotation problem) so convert them in polygons,
* and draw them as polygons is not a good idea.
*/
void
AM_PRIMITIVE
::
ConvertShapeToPolygon
(
GERBER_DRAW_ITEM
*
aParent
,
std
::
vector
<
wxPoint
>&
aBuffer
)
{
D_CODE
*
tool
=
aParent
->
GetDcodeDescr
();
switch
(
primitive_id
)
{
case
AMP_CIRCLE
:
// Circle, currently convertion not needed
break
;
case
AMP_LINE2
:
case
AMP_LINE20
:
// Line with rectangle ends. (Width, start and end pos + rotation)
{
int
width
=
scale
(
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
start
=
mapPt
(
params
[
2
].
GetValue
(
tool
),
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
end
=
mapPt
(
params
[
4
].
GetValue
(
tool
),
params
[
5
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
delta
=
end
-
start
;
int
len
=
wxRound
(
hypot
(
delta
.
x
,
delta
.
y
)
);
// To build the polygon, we must create a horizonta polygon starting to "start"
// and rotate it to have it end point to "end"
wxPoint
currpt
;
currpt
.
y
+=
width
/
2
;
// Upper left
aBuffer
.
push_back
(
currpt
);
currpt
.
x
=
len
;
// Upper right
aBuffer
.
push_back
(
currpt
);
currpt
.
y
-=
width
;
// lower right
aBuffer
.
push_back
(
currpt
);
currpt
.
x
=
0
;
// Upper left
aBuffer
.
push_back
(
currpt
);
// Rotate rectangle and move it to the actual start point
int
angle
=
wxRound
(
atan2
(
(
double
)
delta
.
y
,
(
double
)
delta
.
x
)
*
1800.0
/
M_PI
);
for
(
unsigned
ii
=
0
;
ii
<
4
;
ii
++
)
{
RotatePoint
(
&
aBuffer
[
ii
],
-
angle
);
aBuffer
[
ii
]
+=
start
;
}
}
break
;
case
AMP_LINE_CENTER
:
{
wxPoint
size
=
mapPt
(
params
[
1
].
GetValue
(
tool
),
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
pos
=
mapPt
(
params
[
3
].
GetValue
(
tool
),
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
);
// Build poly:
pos
.
x
-=
size
.
x
/
2
;
pos
.
y
-=
size
.
y
/
2
;
// Lower left
aBuffer
.
push_back
(
pos
);
pos
.
y
+=
size
.
y
;
// Upper left
aBuffer
.
push_back
(
pos
);
pos
.
x
+=
size
.
x
;
// Upper right
aBuffer
.
push_back
(
pos
);
pos
.
y
-=
size
.
y
;
// lower right
aBuffer
.
push_back
(
pos
);
}
break
;
case
AMP_LINE_LOWER_LEFT
:
{
wxPoint
size
=
mapPt
(
params
[
1
].
GetValue
(
tool
),
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
wxPoint
lowerLeft
=
mapPt
(
params
[
3
].
GetValue
(
tool
),
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
);
// Build poly:
aBuffer
.
push_back
(
lowerLeft
);
lowerLeft
.
y
+=
size
.
y
;
// Upper left
aBuffer
.
push_back
(
lowerLeft
);
lowerLeft
.
x
+=
size
.
x
;
// Upper right
aBuffer
.
push_back
(
lowerLeft
);
lowerLeft
.
y
-=
size
.
y
;
// lower right
aBuffer
.
push_back
(
lowerLeft
);
}
break
;
case
AMP_THERMAL
:
{
// Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
// rotated by 90, 180 and 270 deg.
// params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
int
outerRadius
=
scale
(
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
int
innerRadius
=
scale
(
params
[
3
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
int
halfthickness
=
scale
(
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
int
angle_start
=
wxRound
(
asin
(
(
double
)
halfthickness
/
innerRadius
)
*
1800
/
M_PI
);
// Draw shape in the first cadrant (X and Y > 0)
wxPoint
pos
,
startpos
;
// Inner arc
startpos
.
x
=
innerRadius
;
int
angle_end
=
900
-
angle_start
;
int
angle
;
for
(
angle
=
angle_start
;
angle
<
angle_end
;
angle
+=
100
)
{
pos
=
startpos
;
RotatePoint
(
&
pos
,
angle
);
aBuffer
.
push_back
(
pos
);
}
// Last point
pos
=
startpos
;
RotatePoint
(
&
pos
,
angle_end
);
aBuffer
.
push_back
(
pos
);
// outer arc
startpos
.
x
=
outerRadius
;
startpos
.
y
=
0
;
angle_start
=
wxRound
(
asin
(
(
double
)
halfthickness
/
outerRadius
)
*
1800
/
M_PI
);
angle_end
=
900
-
angle_start
;
// First point, near Y axis, outer arc
for
(
angle
=
angle_end
;
angle
>
angle_start
;
angle
-=
100
)
{
pos
=
startpos
;
RotatePoint
(
&
pos
,
angle
);
aBuffer
.
push_back
(
pos
);
}
// last point
pos
=
startpos
;
RotatePoint
(
&
pos
,
angle_start
);
aBuffer
.
push_back
(
pos
);
aBuffer
.
push_back
(
aBuffer
[
0
]
);
// Close poly
}
break
;
case
AMP_MOIRE
:
// A cross hair with n concentric circles. Only the cros is build as polygon
// because circles can be drawn easily
{
int
crossHairThickness
=
scale
(
params
[
6
].
GetValue
(
tool
),
m_GerbMetric
);
int
crossHairLength
=
scale
(
params
[
7
].
GetValue
(
tool
),
m_GerbMetric
);
// Create cross. First create 1/4 of the shape.
// Others point are the same, totated by 90, 180 and 270 deg
wxPoint
pos
(
crossHairThickness
/
2
,
crossHairLength
/
2
);
aBuffer
.
push_back
(
pos
);
pos
.
y
=
crossHairThickness
/
2
;
aBuffer
.
push_back
(
pos
);
pos
.
x
=
-
crossHairLength
/
2
;
aBuffer
.
push_back
(
pos
);
pos
.
y
=
-
crossHairThickness
/
2
;
aBuffer
.
push_back
(
pos
);
// Copy the 4 shape, rotated by 90, 180 and 270 deg
for
(
int
jj
=
1
;
jj
<=
3
;
jj
++
)
{
for
(
int
ii
=
0
;
ii
<
4
;
ii
++
)
{
pos
=
aBuffer
[
ii
];
RotatePoint
(
&
pos
,
jj
*
900
);
aBuffer
.
push_back
(
pos
);
}
}
}
break
;
case
AMP_OUTLINE
:
// already is a polygon. Do nothing
break
;
case
AMP_POLYGON
:
// Creates a regular polygon
{
int
vertexcount
=
wxRound
(
params
[
1
].
GetValue
(
tool
)
);
int
radius
=
scale
(
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
// rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
if
(
vertexcount
<
3
)
vertexcount
=
3
;
if
(
vertexcount
>
10
)
vertexcount
=
10
;
for
(
int
ii
=
0
;
ii
<=
vertexcount
;
ii
++
)
{
wxPoint
pos
(
radius
,
0
);
RotatePoint
(
&
pos
,
ii
*
3600
/
vertexcount
);
aBuffer
.
push_back
(
pos
);
}
}
break
;
case
AMP_COMMENT
:
case
AMP_UNKNOWN
:
case
AMP_EOF
:
break
;
}
}
/** GetShapeDim
* Calculate a value that can be used to evaluate the size of text
* when displaying the D-Code of an item
* due to the complexity of the shape of some primitives
* one cannot calculate the "size" of a shape (only abounding box)
* but here, the "dimension" of the shape is the diameter of the primitive
* or for lines the width of the line
* @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
* @return a dimension, or -1 if no dim to calculate
*/
int
AM_PRIMITIVE
::
GetShapeDim
(
GERBER_DRAW_ITEM
*
aParent
)
{
int
dim
=
-
1
;
D_CODE
*
tool
=
aParent
->
GetDcodeDescr
();
switch
(
primitive_id
)
{
case
AMP_CIRCLE
:
// params = exposure, diameter, pos.x, pos.y
dim
=
scale
(
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
// Diameter
break
;
case
AMP_LINE2
:
case
AMP_LINE20
:
// Line with rectangle ends. (Width, start and end pos + rotation)
dim
=
scale
(
params
[
1
].
GetValue
(
tool
),
m_GerbMetric
);
// linne width
break
;
case
AMP_LINE_CENTER
:
{
wxPoint
size
=
mapPt
(
params
[
1
].
GetValue
(
tool
),
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
dim
=
MIN
(
size
.
x
,
size
.
y
);
}
break
;
case
AMP_LINE_LOWER_LEFT
:
{
wxPoint
size
=
mapPt
(
params
[
1
].
GetValue
(
tool
),
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
);
dim
=
MIN
(
size
.
x
,
size
.
y
);
}
break
;
case
AMP_THERMAL
:
{
// Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
// rotated by 90, 180 and 270 deg.
// params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
dim
=
scale
(
params
[
2
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
// Outer diam
}
break
;
case
AMP_MOIRE
:
// A cross hair with n concentric circles.
dim
=
scale
(
params
[
7
].
GetValue
(
tool
),
m_GerbMetric
);
// = cross hair len
break
;
case
AMP_OUTLINE
:
// a free polygon :
// dim = min side of the bounding box (this is a poor criteria, but what is a good criteria b?)
{
// exposure, corners count, corner1.x, corner.1y, ..., rotation
int
numPoints
=
(
int
)
params
[
1
].
GetValue
(
tool
);
// Read points. numPoints does not include the starting point, so add 1.
// and calculate the bounding box;
wxSize
pos_min
,
pos_max
,
pos
;
for
(
int
i
=
0
;
i
<
numPoints
+
1
;
++
i
)
{
int
jj
=
i
*
2
+
2
;
pos
.
x
=
scale
(
params
[
jj
].
GetValue
(
tool
),
m_GerbMetric
);
pos
.
y
=
scale
(
params
[
jj
+
1
].
GetValue
(
tool
),
m_GerbMetric
);
if
(
i
==
0
)
pos_min
=
pos_max
=
pos
;
else
{
// upper right corner:
if
(
pos_min
.
x
>
pos
.
x
)
pos_min
.
x
=
pos
.
x
;
if
(
pos_min
.
y
>
pos
.
y
)
pos_min
.
y
=
pos
.
y
;
// lower left corner:
if
(
pos_max
.
x
<
pos
.
x
)
pos_max
.
x
=
pos
.
x
;
if
(
pos_max
.
y
<
pos
.
y
)
pos_max
.
y
=
pos
.
y
;
}
}
// calculate dim
wxSize
size
;
size
.
x
=
pos_max
.
x
-
pos_min
.
x
;
size
.
y
=
pos_max
.
y
-
pos_min
.
y
;
dim
=
MIN
(
size
.
x
,
size
.
y
);
}
break
;
case
AMP_POLYGON
:
// Regular polygon
dim
=
scale
(
params
[
4
].
GetValue
(
tool
),
m_GerbMetric
)
/
2
;
// Radius
break
;
case
AMP_COMMENT
:
case
AMP_UNKNOWN
:
case
AMP_EOF
:
break
;
}
return
dim
;
}
/**
* Function DrawApertureMacroShape
* Draw the primitive shape for flashed items.
* When an item is flashed, this is the shape of the item
*/
void
APERTURE_MACRO
::
DrawApertureMacroShape
(
GERBER_DRAW_ITEM
*
aParent
,
EDA_RECT
*
aClipBox
,
wxDC
*
aDC
,
int
aColor
,
int
aAltColor
,
wxPoint
aShapePos
,
bool
aFilledShape
)
{
for
(
AM_PRIMITIVES
::
iterator
prim_macro
=
primitives
.
begin
();
prim_macro
!=
primitives
.
end
();
++
prim_macro
)
{
prim_macro
->
DrawBasicShape
(
aParent
,
aClipBox
,
aDC
,
aColor
,
aAltColor
,
aShapePos
,
aFilledShape
);
}
}
/* Function HasNegativeItems
* return true if this macro has at least one aperture primitives
* that must be drawn in background color
* used to optimize screen refresh
*/
bool
APERTURE_MACRO
::
HasNegativeItems
(
GERBER_DRAW_ITEM
*
aParent
)
{
for
(
AM_PRIMITIVES
::
iterator
prim_macro
=
primitives
.
begin
();
prim_macro
!=
primitives
.
end
();
++
prim_macro
)
{
if
(
prim_macro
->
mapExposure
(
aParent
)
==
false
)
// = is negative
return
true
;
}
return
false
;
}
/** GetShapeDim
* Calculate a value that can be used to evaluate the size of text
* when displaying the D-Code of an item
* due to the complexity of a shape using many primitives
* one cannot calculate the "size" of a shape (only abounding box)
* but most of aperture macro are using one or few primitives
* and the "dimension" of the shape is the diameter of the primitive
* (or the max diameter of primitives)
* @return a dimension, or -1 if no dim to calculate
*/
int
APERTURE_MACRO
::
GetShapeDim
(
GERBER_DRAW_ITEM
*
aParent
)
{
int
dim
=
-
1
;
for
(
AM_PRIMITIVES
::
iterator
prim_macro
=
primitives
.
begin
();
prim_macro
!=
primitives
.
end
();
++
prim_macro
)
{
int
pdim
=
prim_macro
->
GetShapeDim
(
aParent
);
if
(
dim
<
pdim
)
dim
=
pdim
;
}
return
dim
;
}
/**
* function GetLocalParam
* Usually, parameters are defined inside the aperture primitive
* using immediate mode or defered mode.
* in defered mode the value is defined in a DCODE that want to use the aperture macro.
* But some parameters are defined outside the aperture primitive
* and are local to the aperture macro
* @return the value of a defered parameter defined inside the aperture macro
* @param aParamId = the param id (defined by $3 or $5 ..) to evaluate
*/
double
APERTURE_MACRO
::
GetLocalParam
(
const
D_CODE
*
aDcode
,
unsigned
aParamId
)
const
{
// find parameter descr.
const
AM_PARAM
*
param
=
NULL
;
for
(
unsigned
ii
=
0
;
ii
<
m_localparamStack
.
size
();
ii
++
)
{
if
(
m_localparamStack
[
ii
].
GetIndex
()
==
aParamId
)
{
param
=
&
m_localparamStack
[
ii
];
break
;
}
}
if
(
param
==
NULL
)
// not found
return
0.0
;
// Evaluate parameter
double
value
=
param
->
GetValue
(
aDcode
);
return
value
;
}
gerbview/class_gerbview_layer_widget.cpp
View file @
8db19bbd
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*********************************************************/
/* class_gerbview_layer_widget.cpp - gerbview layers manager. */
/*********************************************************/
#include "fctsys.h"
#include "common.h"
#include "class_drawpanel.h"
#include "pcbstruct.h"
#include "macros.h"
#include "class_layer_box_selector.h"
#include "gerbview.h"
#include "class_GERBER.h"
#include "layer_widget.h"
#include "class_gerbview_layer_widget.h"
/*
* Class GERBER_LAYER_WIDGET
* is here to implement the abtract functions of LAYER_WIDGET so they
* may be tied into the GERBVIEW_FRAME's data and so we can add a popup
* menu which is specific to PCBNEW's needs.
*/
GERBER_LAYER_WIDGET
::
GERBER_LAYER_WIDGET
(
GERBVIEW_FRAME
*
aParent
,
wxWindow
*
aFocusOwner
,
int
aPointSize
)
:
LAYER_WIDGET
(
aParent
,
aFocusOwner
,
aPointSize
),
myframe
(
aParent
)
{
ReFillRender
();
// Update default tabs labels for gerbview
SetLayersManagerTabsText
(
);
//-----<Popup menu>-------------------------------------------------
// handle the popup menu over the layer window.
m_LayerScrolledWindow
->
Connect
(
wxEVT_RIGHT_DOWN
,
wxMouseEventHandler
(
GERBER_LAYER_WIDGET
::
onRightDownLayers
),
NULL
,
this
);
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
// and not m_LayerScrolledWindow->Connect()
Connect
(
ID_SHOW_ALL_COPPERS
,
ID_SHOW_NO_COPPERS
,
wxEVT_COMMAND_MENU_SELECTED
,
wxCommandEventHandler
(
GERBER_LAYER_WIDGET
::
onPopupSelection
),
NULL
,
this
);
// install the right click handler into each control at end of ReFill()
// using installRightLayerClickHandler
}
/**
* Function SetLayersManagerTabsText
* Update the layer manager tabs labels
* Useful when changing Language or to set labels to a non default value
*/
void
GERBER_LAYER_WIDGET
::
SetLayersManagerTabsText
(
)
{
m_notebook
->
SetPageText
(
0
,
_
(
"Layer"
)
);
m_notebook
->
SetPageText
(
1
,
_
(
"Render"
)
);
}
/**
* Function ReFillRender
* Rebuild Render for instance after the config is read
*/
void
GERBER_LAYER_WIDGET
::
ReFillRender
()
{
BOARD
*
board
=
myframe
->
GetBoard
();
ClearRenderRows
();
// Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
// is changed before appending to the LAYER_WIDGET. This is an automatic variable
// not a static variable, change the color & state after copying from code to renderRows
// on the stack.
LAYER_WIDGET
::
ROW
renderRows
[
2
]
=
{
#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
// text id color tooltip checked
RR
(
_
(
"Grid"
),
GERBER_GRID_VISIBLE
,
WHITE
,
_
(
"Show the (x,y) grid dots"
)
),
RR
(
_
(
"DCodes"
),
DCODES_VISIBLE
,
WHITE
,
_
(
"Show DCodes identification"
)
),
};
for
(
unsigned
row
=
0
;
row
<
DIM
(
renderRows
);
++
row
)
{
if
(
renderRows
[
row
].
color
!=
-
1
)
// does this row show a color?
{
// this window frame must have an established BOARD, i.e. after SetBoard()
renderRows
[
row
].
color
=
board
->
GetVisibleElementColor
(
renderRows
[
row
].
id
);
}
renderRows
[
row
].
state
=
board
->
IsElementVisible
(
renderRows
[
row
].
id
);
}
AppendRenderRows
(
renderRows
,
DIM
(
renderRows
)
);
}
void
GERBER_LAYER_WIDGET
::
installRightLayerClickHandler
()
{
int
rowCount
=
GetLayerRowCount
();
for
(
int
row
=
0
;
row
<
rowCount
;
++
row
)
{
for
(
int
col
=
0
;
col
<
LYR_COLUMN_COUNT
;
++
col
)
{
wxWindow
*
w
=
getLayerComp
(
row
,
col
);
w
->
Connect
(
wxEVT_RIGHT_DOWN
,
wxMouseEventHandler
(
GERBER_LAYER_WIDGET
::
onRightDownLayers
),
NULL
,
this
);
}
}
}
void
GERBER_LAYER_WIDGET
::
onRightDownLayers
(
wxMouseEvent
&
event
)
{
wxMenu
menu
;
// menu text is capitalized:
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_ALL_COPPERS
,
_
(
"Show All Layers"
)
)
);
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_NO_COPPERS
,
_
(
"Hide All Layers"
)
)
);
PopupMenu
(
&
menu
);
passOnFocus
();
}
void
GERBER_LAYER_WIDGET
::
onPopupSelection
(
wxCommandEvent
&
event
)
{
int
rowCount
;
int
menuId
=
event
.
GetId
();
bool
visible
=
(
menuId
==
ID_SHOW_ALL_COPPERS
)
?
true
:
false
;;
int
visibleLayers
=
0
;
switch
(
menuId
)
{
case
ID_SHOW_ALL_COPPERS
:
case
ID_SHOW_NO_COPPERS
:
rowCount
=
GetLayerRowCount
();
for
(
int
row
=
0
;
row
<
rowCount
;
++
row
)
{
wxCheckBox
*
cb
=
(
wxCheckBox
*
)
getLayerComp
(
row
,
3
);
cb
->
SetValue
(
visible
);
if
(
visible
)
visibleLayers
|=
(
1
<<
row
);
else
visibleLayers
&=
~
(
1
<<
row
);
}
myframe
->
GetBoard
()
->
SetVisibleLayers
(
visibleLayers
);
myframe
->
DrawPanel
->
Refresh
();
break
;
}
}
void
GERBER_LAYER_WIDGET
::
ReFill
()
{
BOARD
*
brd
=
myframe
->
GetBoard
();
int
layer
;
ClearLayerRows
();
for
(
layer
=
0
;
layer
<
LAYER_COUNT
;
layer
++
)
{
wxString
msg
;
msg
.
Printf
(
_
(
"Layer %d"
),
layer
+
1
);
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
msg
,
layer
,
brd
->
GetLayerColor
(
layer
),
wxEmptyString
,
true
)
);
}
installRightLayerClickHandler
();
}
//-----<LAYER_WIDGET callbacks>-------------------------------------------
void
GERBER_LAYER_WIDGET
::
OnLayerColorChange
(
int
aLayer
,
int
aColor
)
{
myframe
->
GetBoard
()
->
SetLayerColor
(
aLayer
,
aColor
);
myframe
->
m_SelLayerBox
->
ResyncBitmapOnly
();
myframe
->
DrawPanel
->
Refresh
();
}
bool
GERBER_LAYER_WIDGET
::
OnLayerSelect
(
int
aLayer
)
{
// the layer change from the GERBER_LAYER_WIDGET can be denied by returning
// false from this function.
int
layer
=
myframe
->
getActiveLayer
(
);
myframe
->
setActiveLayer
(
aLayer
,
false
);
myframe
->
syncLayerBox
();
if
(
layer
!=
myframe
->
getActiveLayer
(
)
)
myframe
->
DrawPanel
->
Refresh
();
return
true
;
}
void
GERBER_LAYER_WIDGET
::
OnLayerVisible
(
int
aLayer
,
bool
isVisible
,
bool
isFinal
)
{
BOARD
*
brd
=
myframe
->
GetBoard
();
int
visibleLayers
=
brd
->
GetVisibleLayers
();
if
(
isVisible
)
visibleLayers
|=
(
1
<<
aLayer
);
else
visibleLayers
&=
~
(
1
<<
aLayer
);
brd
->
SetVisibleLayers
(
visibleLayers
);
if
(
isFinal
)
myframe
->
DrawPanel
->
Refresh
();
}
void
GERBER_LAYER_WIDGET
::
OnRenderColorChange
(
int
aId
,
int
aColor
)
{
myframe
->
GetBoard
()
->
SetVisibleElementColor
(
aId
,
aColor
);
myframe
->
DrawPanel
->
Refresh
();
}
void
GERBER_LAYER_WIDGET
::
OnRenderEnable
(
int
aId
,
bool
isEnabled
)
{
BOARD
*
brd
=
myframe
->
GetBoard
();
brd
->
SetElementVisibility
(
aId
,
isEnabled
);
myframe
->
DrawPanel
->
Refresh
();
}
//-----</LAYER_WIDGET callbacks>------------------------------------------
/*
* Virtual Function useAlternateBitmap
* return true if bitmaps shown in Render layer list
* must be alternate bitmaps, or false to use "normal" bitmaps
*/
bool
GERBER_LAYER_WIDGET
::
useAlternateBitmap
(
int
aRow
)
{
bool
inUse
=
false
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
aRow
];
if
(
gerber
!=
NULL
&&
gerber
->
m_InUse
)
inUse
=
true
;
return
inUse
;
}
/**
* Function UpdateLayerIcons
* Update the layer manager icons (layers only)
* Useful when loading a file or clearing a layer because they change
*/
void
GERBER_LAYER_WIDGET
::
UpdateLayerIcons
()
{
int
row_count
=
GetLayerRowCount
();
for
(
int
row
=
0
;
row
<
row_count
;
row
++
)
{
wxStaticBitmap
*
bm
=
(
wxStaticBitmap
*
)
getLayerComp
(
row
,
0
);
if
(
bm
==
NULL
)
continue
;
if
(
row
==
m_CurrentRow
)
bm
->
SetBitmap
(
useAlternateBitmap
(
row
)
?
*
m_RightArrowAlternateBitmap
:
*
m_RightArrowBitmap
);
else
bm
->
SetBitmap
(
useAlternateBitmap
(
row
)
?
*
m_BlankAlternateBitmap
:
*
m_BlankBitmap
);
}
}
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*********************************************************/
/* class_gerbview_layer_widget.cpp - gerbview layers manager. */
/*********************************************************/
#include "fctsys.h"
#include "common.h"
#include "class_drawpanel.h"
#include "pcbstruct.h"
#include "macros.h"
#include "class_layer_box_selector.h"
#include "gerbview.h"
#include "class_GERBER.h"
#include "layer_widget.h"
#include "class_gerbview_layer_widget.h"
/*
* Class GERBER_LAYER_WIDGET
* is here to implement the abtract functions of LAYER_WIDGET so they
* may be tied into the GERBVIEW_FRAME's data and so we can add a popup
* menu which is specific to PCBNEW's needs.
*/
GERBER_LAYER_WIDGET
::
GERBER_LAYER_WIDGET
(
GERBVIEW_FRAME
*
aParent
,
wxWindow
*
aFocusOwner
,
int
aPointSize
)
:
LAYER_WIDGET
(
aParent
,
aFocusOwner
,
aPointSize
),
myframe
(
aParent
)
{
ReFillRender
();
// Update default tabs labels for gerbview
SetLayersManagerTabsText
(
);
//-----<Popup menu>-------------------------------------------------
// handle the popup menu over the layer window.
m_LayerScrolledWindow
->
Connect
(
wxEVT_RIGHT_DOWN
,
wxMouseEventHandler
(
GERBER_LAYER_WIDGET
::
onRightDownLayers
),
NULL
,
this
);
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
// and not m_LayerScrolledWindow->Connect()
Connect
(
ID_SHOW_ALL_COPPERS
,
ID_SHOW_NO_COPPERS
,
wxEVT_COMMAND_MENU_SELECTED
,
wxCommandEventHandler
(
GERBER_LAYER_WIDGET
::
onPopupSelection
),
NULL
,
this
);
// install the right click handler into each control at end of ReFill()
// using installRightLayerClickHandler
}
/**
* Function SetLayersManagerTabsText
* Update the layer manager tabs labels
* Useful when changing Language or to set labels to a non default value
*/
void
GERBER_LAYER_WIDGET
::
SetLayersManagerTabsText
(
)
{
m_notebook
->
SetPageText
(
0
,
_
(
"Layer"
)
);
m_notebook
->
SetPageText
(
1
,
_
(
"Render"
)
);
}
/**
* Function ReFillRender
* Rebuild Render for instance after the config is read
*/
void
GERBER_LAYER_WIDGET
::
ReFillRender
()
{
BOARD
*
board
=
myframe
->
GetBoard
();
ClearRenderRows
();
// Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
// is changed before appending to the LAYER_WIDGET. This is an automatic variable
// not a static variable, change the color & state after copying from code to renderRows
// on the stack.
LAYER_WIDGET
::
ROW
renderRows
[
2
]
=
{
#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
// text id color tooltip checked
RR
(
_
(
"Grid"
),
GERBER_GRID_VISIBLE
,
WHITE
,
_
(
"Show the (x,y) grid dots"
)
),
RR
(
_
(
"DCodes"
),
DCODES_VISIBLE
,
WHITE
,
_
(
"Show DCodes identification"
)
),
};
for
(
unsigned
row
=
0
;
row
<
DIM
(
renderRows
);
++
row
)
{
if
(
renderRows
[
row
].
color
!=
-
1
)
// does this row show a color?
{
// this window frame must have an established BOARD, i.e. after SetBoard()
renderRows
[
row
].
color
=
board
->
GetVisibleElementColor
(
renderRows
[
row
].
id
);
}
renderRows
[
row
].
state
=
board
->
IsElementVisible
(
renderRows
[
row
].
id
);
}
AppendRenderRows
(
renderRows
,
DIM
(
renderRows
)
);
}
void
GERBER_LAYER_WIDGET
::
installRightLayerClickHandler
()
{
int
rowCount
=
GetLayerRowCount
();
for
(
int
row
=
0
;
row
<
rowCount
;
++
row
)
{
for
(
int
col
=
0
;
col
<
LYR_COLUMN_COUNT
;
++
col
)
{
wxWindow
*
w
=
getLayerComp
(
row
,
col
);
w
->
Connect
(
wxEVT_RIGHT_DOWN
,
wxMouseEventHandler
(
GERBER_LAYER_WIDGET
::
onRightDownLayers
),
NULL
,
this
);
}
}
}
void
GERBER_LAYER_WIDGET
::
onRightDownLayers
(
wxMouseEvent
&
event
)
{
wxMenu
menu
;
// menu text is capitalized:
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_ALL_COPPERS
,
_
(
"Show All Layers"
)
)
);
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_NO_COPPERS
,
_
(
"Hide All Layers"
)
)
);
PopupMenu
(
&
menu
);
passOnFocus
();
}
void
GERBER_LAYER_WIDGET
::
onPopupSelection
(
wxCommandEvent
&
event
)
{
int
rowCount
;
int
menuId
=
event
.
GetId
();
bool
visible
=
(
menuId
==
ID_SHOW_ALL_COPPERS
)
?
true
:
false
;;
int
visibleLayers
=
0
;
switch
(
menuId
)
{
case
ID_SHOW_ALL_COPPERS
:
case
ID_SHOW_NO_COPPERS
:
rowCount
=
GetLayerRowCount
();
for
(
int
row
=
0
;
row
<
rowCount
;
++
row
)
{
wxCheckBox
*
cb
=
(
wxCheckBox
*
)
getLayerComp
(
row
,
3
);
cb
->
SetValue
(
visible
);
if
(
visible
)
visibleLayers
|=
(
1
<<
row
);
else
visibleLayers
&=
~
(
1
<<
row
);
}
myframe
->
GetBoard
()
->
SetVisibleLayers
(
visibleLayers
);
myframe
->
DrawPanel
->
Refresh
();
break
;
}
}
void
GERBER_LAYER_WIDGET
::
ReFill
()
{
BOARD
*
brd
=
myframe
->
GetBoard
();
int
layer
;
ClearLayerRows
();
for
(
layer
=
0
;
layer
<
LAYER_COUNT
;
layer
++
)
{
wxString
msg
;
msg
.
Printf
(
_
(
"Layer %d"
),
layer
+
1
);
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
msg
,
layer
,
brd
->
GetLayerColor
(
layer
),
wxEmptyString
,
true
)
);
}
installRightLayerClickHandler
();
}
//-----<LAYER_WIDGET callbacks>-------------------------------------------
void
GERBER_LAYER_WIDGET
::
OnLayerColorChange
(
int
aLayer
,
int
aColor
)
{
myframe
->
GetBoard
()
->
SetLayerColor
(
aLayer
,
aColor
);
myframe
->
m_SelLayerBox
->
ResyncBitmapOnly
();
myframe
->
DrawPanel
->
Refresh
();
}
bool
GERBER_LAYER_WIDGET
::
OnLayerSelect
(
int
aLayer
)
{
// the layer change from the GERBER_LAYER_WIDGET can be denied by returning
// false from this function.
int
layer
=
myframe
->
getActiveLayer
(
);
myframe
->
setActiveLayer
(
aLayer
,
false
);
myframe
->
syncLayerBox
();
if
(
layer
!=
myframe
->
getActiveLayer
(
)
)
myframe
->
DrawPanel
->
Refresh
();
return
true
;
}
void
GERBER_LAYER_WIDGET
::
OnLayerVisible
(
int
aLayer
,
bool
isVisible
,
bool
isFinal
)
{
BOARD
*
brd
=
myframe
->
GetBoard
();
int
visibleLayers
=
brd
->
GetVisibleLayers
();
if
(
isVisible
)
visibleLayers
|=
(
1
<<
aLayer
);
else
visibleLayers
&=
~
(
1
<<
aLayer
);
brd
->
SetVisibleLayers
(
visibleLayers
);
if
(
isFinal
)
myframe
->
DrawPanel
->
Refresh
();
}
void
GERBER_LAYER_WIDGET
::
OnRenderColorChange
(
int
aId
,
int
aColor
)
{
myframe
->
GetBoard
()
->
SetVisibleElementColor
(
aId
,
aColor
);
myframe
->
DrawPanel
->
Refresh
();
}
void
GERBER_LAYER_WIDGET
::
OnRenderEnable
(
int
aId
,
bool
isEnabled
)
{
BOARD
*
brd
=
myframe
->
GetBoard
();
brd
->
SetElementVisibility
(
aId
,
isEnabled
);
myframe
->
DrawPanel
->
Refresh
();
}
//-----</LAYER_WIDGET callbacks>------------------------------------------
/*
* Virtual Function useAlternateBitmap
* return true if bitmaps shown in Render layer list
* must be alternate bitmaps, or false to use "normal" bitmaps
*/
bool
GERBER_LAYER_WIDGET
::
useAlternateBitmap
(
int
aRow
)
{
bool
inUse
=
false
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
aRow
];
if
(
gerber
!=
NULL
&&
gerber
->
m_InUse
)
inUse
=
true
;
return
inUse
;
}
/**
* Function UpdateLayerIcons
* Update the layer manager icons (layers only)
* Useful when loading a file or clearing a layer because they change
*/
void
GERBER_LAYER_WIDGET
::
UpdateLayerIcons
()
{
int
row_count
=
GetLayerRowCount
();
for
(
int
row
=
0
;
row
<
row_count
;
row
++
)
{
wxStaticBitmap
*
bm
=
(
wxStaticBitmap
*
)
getLayerComp
(
row
,
0
);
if
(
bm
==
NULL
)
continue
;
if
(
row
==
m_CurrentRow
)
bm
->
SetBitmap
(
useAlternateBitmap
(
row
)
?
*
m_RightArrowAlternateBitmap
:
*
m_RightArrowBitmap
);
else
bm
->
SetBitmap
(
useAlternateBitmap
(
row
)
?
*
m_BlankAlternateBitmap
:
*
m_BlankBitmap
);
}
}
gerbview/events_called_functions.cpp
View file @
8db19bbd
/**
* @file events_called_functions.cpp
* @brief Gerbview command event functions.
*/
#include "fctsys.h"
#include "appl_wxstruct.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "common.h"
#include "gestfich.h"
#include "gerbview.h"
#include "kicad_device_context.h"
#include "gerbview_id.h"
#include "class_GERBER.h"
#include "dialog_helpers.h"
#include "class_DCodeSelectionbox.h"
#include "class_gerbview_layer_widget.h"
// Event table:
BEGIN_EVENT_TABLE
(
GERBVIEW_FRAME
,
PCB_BASE_FRAME
)
EVT_CLOSE
(
GERBVIEW_FRAME
::
OnCloseWindow
)
EVT_SIZE
(
GERBVIEW_FRAME
::
OnSize
)
EVT_TOOL
(
wxID_FILE
,
GERBVIEW_FRAME
::
Files_io
)
EVT_TOOL
(
ID_GERBVIEW_ERASE_ALL
,
GERBVIEW_FRAME
::
Files_io
)
EVT_TOOL
(
ID_GERBVIEW_LOAD_DRILL_FILE
,
GERBVIEW_FRAME
::
Files_io
)
EVT_TOOL
(
ID_GERBVIEW_LOAD_DCODE_FILE
,
GERBVIEW_FRAME
::
Files_io
)
EVT_TOOL
(
ID_NEW_BOARD
,
GERBVIEW_FRAME
::
Files_io
)
// Menu Files:
EVT_MENU
(
wxID_FILE
,
GERBVIEW_FRAME
::
Files_io
)
EVT_MENU
(
ID_NEW_BOARD
,
GERBVIEW_FRAME
::
Files_io
)
EVT_MENU
(
ID_GEN_PLOT
,
GERBVIEW_FRAME
::
ToPlotter
)
EVT_MENU
(
ID_GERBVIEW_EXPORT_TO_PCBNEW
,
GERBVIEW_FRAME
::
ExportDataInPcbnewFormat
)
EVT_MENU_RANGE
(
wxID_FILE1
,
wxID_FILE9
,
GERBVIEW_FRAME
::
OnGbrFileHistory
)
EVT_MENU_RANGE
(
ID_GERBVIEW_DRILL_FILE1
,
ID_GERBVIEW_DRILL_FILE9
,
GERBVIEW_FRAME
::
OnDrlFileHistory
)
EVT_MENU
(
wxID_EXIT
,
GERBVIEW_FRAME
::
OnQuit
)
// menu Preferences
EVT_MENU_RANGE
(
ID_PREFERENCES_HOTKEY_START
,
ID_PREFERENCES_HOTKEY_END
,
GERBVIEW_FRAME
::
Process_Config
)
EVT_MENU
(
ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_MENU
(
wxID_PREFERENCES
,
GERBVIEW_FRAME
::
InstallGerberOptionsDialog
)
EVT_MENU_RANGE
(
ID_LANGUAGE_CHOICE
,
ID_LANGUAGE_CHOICE_END
,
EDA_DRAW_FRAME
::
SetLanguage
)
// menu Postprocess
EVT_MENU
(
ID_GERBVIEW_SHOW_LIST_DCODES
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_MENU
(
ID_GERBVIEW_SHOW_SOURCE
,
GERBVIEW_FRAME
::
OnShowGerberSourceFile
)
EVT_MENU
(
ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR
,
EDA_BASE_FRAME
::
OnSelectPreferredEditor
)
// menu Miscellaneous
EVT_MENU
(
ID_GERBVIEW_GLOBAL_DELETE
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
// Menu Help
EVT_MENU
(
wxID_HELP
,
EDA_DRAW_FRAME
::
GetKicadHelp
)
EVT_MENU
(
wxID_ABOUT
,
EDA_DRAW_FRAME
::
GetKicadAbout
)
EVT_TOOL
(
wxID_CUT
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_TOOL
(
wxID_COPY
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_TOOL
(
wxID_PASTE
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_TOOL
(
wxID_UNDO
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_TOOL
(
wxID_PRINT
,
GERBVIEW_FRAME
::
ToPrinter
)
EVT_COMBOBOX
(
ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER
,
GERBVIEW_FRAME
::
OnSelectActiveLayer
)
EVT_SELECT_DCODE
(
ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE
,
GERBVIEW_FRAME
::
OnSelectActiveDCode
)
// Vertical toolbar:
EVT_TOOL
(
ID_NO_TOOL_SELECTED
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_MENU_RANGE
(
ID_POPUP_GENERAL_START_RANGE
,
ID_POPUP_GENERAL_END_RANGE
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
// Option toolbar
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_LINES_SKETCH
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_DCODES
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL_RANGE
(
ID_TB_OPTIONS_SHOW_GBR_MODE_0
,
ID_TB_OPTIONS_SHOW_GBR_MODE_2
,
GERBVIEW_FRAME
::
OnSelectDisplayMode
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH
,
GERBVIEW_FRAME
::
OnUpdateFlashedItemsDrawMode
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_LINES_SKETCH
,
GERBVIEW_FRAME
::
OnUpdateLinesDrawMode
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH
,
GERBVIEW_FRAME
::
OnUpdatePolygonsDrawMode
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_DCODES
,
GERBVIEW_FRAME
::
OnUpdateShowDCodes
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR
,
GERBVIEW_FRAME
::
OnUpdateShowLayerManager
)
EVT_UPDATE_UI
(
ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE
,
GERBVIEW_FRAME
::
OnUpdateSelectDCode
)
EVT_UPDATE_UI
(
ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER
,
GERBVIEW_FRAME
::
OnUpdateLayerSelectBox
)
EVT_UPDATE_UI_RANGE
(
ID_TB_OPTIONS_SHOW_GBR_MODE_0
,
ID_TB_OPTIONS_SHOW_GBR_MODE_2
,
GERBVIEW_FRAME
::
OnUpdateDrawMode
)
END_EVENT_TABLE
()
/* Handles the selection of tools, menu, and popup menu commands.
*/
void
GERBVIEW_FRAME
::
Process_Special_Functions
(
wxCommandEvent
&
event
)
{
int
id
=
event
.
GetId
();
switch
(
id
)
{
case
wxID_CUT
:
case
wxID_COPY
:
case
ID_POPUP_DELETE_BLOCK
:
case
ID_POPUP_PLACE_BLOCK
:
case
ID_POPUP_ZOOM_BLOCK
:
break
;
case
ID_POPUP_CANCEL_CURRENT_COMMAND
:
DrawPanel
->
EndMouseCapture
();
if
(
GetScreen
()
->
m_BlockLocate
.
m_Command
!=
BLOCK_IDLE
)
{
/* Should not be executed, except bug */
GetScreen
()
->
m_BlockLocate
.
m_Command
=
BLOCK_IDLE
;
GetScreen
()
->
m_BlockLocate
.
m_State
=
STATE_NO_BLOCK
;
GetScreen
()
->
m_BlockLocate
.
ClearItemsList
();
}
if
(
GetToolId
()
==
ID_NO_TOOL_SELECTED
)
SetToolID
(
ID_NO_TOOL_SELECTED
,
DrawPanel
->
GetDefaultCursor
(),
wxEmptyString
);
else
DrawPanel
->
SetCursor
(
DrawPanel
->
GetCurrentCursor
()
);
break
;
default
:
DrawPanel
->
EndMouseCapture
();
break
;
}
INSTALL_UNBUFFERED_DC
(
dc
,
DrawPanel
);
switch
(
id
)
{
case
ID_GERBVIEW_GLOBAL_DELETE
:
Erase_Current_Layer
(
true
);
ClearMsgPanel
();
break
;
case
ID_NO_TOOL_SELECTED
:
SetToolID
(
ID_NO_TOOL_SELECTED
,
DrawPanel
->
GetDefaultCursor
(),
wxEmptyString
);
break
;
case
ID_POPUP_CLOSE_CURRENT_TOOL
:
SetToolID
(
ID_NO_TOOL_SELECTED
,
DrawPanel
->
GetDefaultCursor
(),
wxEmptyString
);
break
;
case
ID_POPUP_CANCEL_CURRENT_COMMAND
:
break
;
case
ID_GERBVIEW_SHOW_LIST_DCODES
:
Liste_D_Codes
();
break
;
case
ID_POPUP_PLACE_BLOCK
:
GetScreen
()
->
m_BlockLocate
.
m_Command
=
BLOCK_MOVE
;
DrawPanel
->
m_AutoPAN_Request
=
FALSE
;
HandleBlockPlace
(
&
dc
);
break
;
case
ID_POPUP_ZOOM_BLOCK
:
GetScreen
()
->
m_BlockLocate
.
m_Command
=
BLOCK_ZOOM
;
GetScreen
()
->
m_BlockLocate
.
SetMessageBlock
(
this
);
HandleBlockEnd
(
&
dc
);
break
;
case
ID_POPUP_DELETE_BLOCK
:
GetScreen
()
->
m_BlockLocate
.
m_Command
=
BLOCK_DELETE
;
GetScreen
()
->
m_BlockLocate
.
SetMessageBlock
(
this
);
HandleBlockEnd
(
&
dc
);
break
;
default
:
wxFAIL_MSG
(
wxT
(
"GERBVIEW_FRAME::Process_Special_Functions error"
)
);
break
;
}
}
/* Selects the active DCode for the current active layer.
* Items using this DCode are hightlighted
*/
void
GERBVIEW_FRAME
::
OnSelectActiveDCode
(
wxCommandEvent
&
event
)
{
GERBER_IMAGE
*
gerber_image
=
g_GERBER_List
[
getActiveLayer
()];
if
(
gerber_image
)
{
int
tool
=
m_DCodeSelector
->
GetSelectedDCodeId
();
if
(
tool
!=
gerber_image
->
m_Selected_Tool
)
{
gerber_image
->
m_Selected_Tool
=
tool
;
DrawPanel
->
Refresh
();
}
}
}
/* Selects the active layer:
* - if a file is loaded, it is loaded in this layer
* _ this layer is displayed on top of other layers
*/
void
GERBVIEW_FRAME
::
OnSelectActiveLayer
(
wxCommandEvent
&
event
)
{
int
layer
=
getActiveLayer
();
setActiveLayer
(
event
.
GetSelection
()
);
if
(
layer
!=
getActiveLayer
()
)
DrawPanel
->
Refresh
();
}
/* Call preferred editor to show (and edit) the gerber source file
* loaded in the active layer
*/
void
GERBVIEW_FRAME
::
OnShowGerberSourceFile
(
wxCommandEvent
&
event
)
{
int
layer
=
getActiveLayer
();
GERBER_IMAGE
*
gerber_layer
=
g_GERBER_List
[
layer
];
if
(
gerber_layer
)
{
wxString
editorname
=
wxGetApp
().
GetEditorName
();
if
(
!
editorname
.
IsEmpty
()
)
{
wxFileName
fn
(
gerber_layer
->
m_FileName
);
ExecuteFile
(
this
,
editorname
,
QuoteFullPath
(
fn
)
);
}
else
{
wxMessageBox
(
_
(
"No editor defined. Please select one"
)
);
}
}
}
/* Function OnSelectDisplayMode: called to select display mode
* (fast display, or exact mode with stacked images or with transparency
*/
void
GERBVIEW_FRAME
::
OnSelectDisplayMode
(
wxCommandEvent
&
event
)
{
int
oldMode
=
GetDisplayMode
();
switch
(
event
.
GetId
()
)
{
case
ID_TB_OPTIONS_SHOW_GBR_MODE_0
:
SetDisplayMode
(
0
);
break
;
case
ID_TB_OPTIONS_SHOW_GBR_MODE_1
:
SetDisplayMode
(
1
);
break
;
case
ID_TB_OPTIONS_SHOW_GBR_MODE_2
:
SetDisplayMode
(
2
);
break
;
}
if
(
GetDisplayMode
()
!=
oldMode
)
DrawPanel
->
Refresh
();
}
void
GERBVIEW_FRAME
::
OnQuit
(
wxCommandEvent
&
event
)
{
Close
(
true
);
}
/**
* Function SetLanguage
* called on a language menu selection
* Update Layer manager title and tabs texts
*/
void
GERBVIEW_FRAME
::
SetLanguage
(
wxCommandEvent
&
event
)
{
EDA_DRAW_FRAME
::
SetLanguage
(
event
);
m_LayersManager
->
SetLayersManagerTabsText
();
wxAuiPaneInfo
&
pane_info
=
m_auimgr
.
GetPane
(
m_LayersManager
);
pane_info
.
Caption
(
_
(
"Visibles"
)
);
m_auimgr
.
Update
();
ReFillLayerWidget
();
}
/**
* @file events_called_functions.cpp
* @brief Gerbview command event functions.
*/
#include "fctsys.h"
#include "appl_wxstruct.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "common.h"
#include "gestfich.h"
#include "gerbview.h"
#include "kicad_device_context.h"
#include "gerbview_id.h"
#include "class_GERBER.h"
#include "dialog_helpers.h"
#include "class_DCodeSelectionbox.h"
#include "class_gerbview_layer_widget.h"
// Event table:
BEGIN_EVENT_TABLE
(
GERBVIEW_FRAME
,
PCB_BASE_FRAME
)
EVT_CLOSE
(
GERBVIEW_FRAME
::
OnCloseWindow
)
EVT_SIZE
(
GERBVIEW_FRAME
::
OnSize
)
EVT_TOOL
(
wxID_FILE
,
GERBVIEW_FRAME
::
Files_io
)
EVT_TOOL
(
ID_GERBVIEW_ERASE_ALL
,
GERBVIEW_FRAME
::
Files_io
)
EVT_TOOL
(
ID_GERBVIEW_LOAD_DRILL_FILE
,
GERBVIEW_FRAME
::
Files_io
)
EVT_TOOL
(
ID_GERBVIEW_LOAD_DCODE_FILE
,
GERBVIEW_FRAME
::
Files_io
)
EVT_TOOL
(
ID_NEW_BOARD
,
GERBVIEW_FRAME
::
Files_io
)
// Menu Files:
EVT_MENU
(
wxID_FILE
,
GERBVIEW_FRAME
::
Files_io
)
EVT_MENU
(
ID_NEW_BOARD
,
GERBVIEW_FRAME
::
Files_io
)
EVT_MENU
(
ID_GEN_PLOT
,
GERBVIEW_FRAME
::
ToPlotter
)
EVT_MENU
(
ID_GERBVIEW_EXPORT_TO_PCBNEW
,
GERBVIEW_FRAME
::
ExportDataInPcbnewFormat
)
EVT_MENU_RANGE
(
wxID_FILE1
,
wxID_FILE9
,
GERBVIEW_FRAME
::
OnGbrFileHistory
)
EVT_MENU_RANGE
(
ID_GERBVIEW_DRILL_FILE1
,
ID_GERBVIEW_DRILL_FILE9
,
GERBVIEW_FRAME
::
OnDrlFileHistory
)
EVT_MENU
(
wxID_EXIT
,
GERBVIEW_FRAME
::
OnQuit
)
// menu Preferences
EVT_MENU_RANGE
(
ID_PREFERENCES_HOTKEY_START
,
ID_PREFERENCES_HOTKEY_END
,
GERBVIEW_FRAME
::
Process_Config
)
EVT_MENU
(
ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_MENU
(
wxID_PREFERENCES
,
GERBVIEW_FRAME
::
InstallGerberOptionsDialog
)
EVT_MENU_RANGE
(
ID_LANGUAGE_CHOICE
,
ID_LANGUAGE_CHOICE_END
,
EDA_DRAW_FRAME
::
SetLanguage
)
// menu Postprocess
EVT_MENU
(
ID_GERBVIEW_SHOW_LIST_DCODES
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_MENU
(
ID_GERBVIEW_SHOW_SOURCE
,
GERBVIEW_FRAME
::
OnShowGerberSourceFile
)
EVT_MENU
(
ID_MENU_GERBVIEW_SELECT_PREFERED_EDITOR
,
EDA_BASE_FRAME
::
OnSelectPreferredEditor
)
// menu Miscellaneous
EVT_MENU
(
ID_GERBVIEW_GLOBAL_DELETE
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
// Menu Help
EVT_MENU
(
wxID_HELP
,
EDA_DRAW_FRAME
::
GetKicadHelp
)
EVT_MENU
(
wxID_ABOUT
,
EDA_DRAW_FRAME
::
GetKicadAbout
)
EVT_TOOL
(
wxID_CUT
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_TOOL
(
wxID_COPY
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_TOOL
(
wxID_PASTE
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_TOOL
(
wxID_UNDO
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_TOOL
(
wxID_PRINT
,
GERBVIEW_FRAME
::
ToPrinter
)
EVT_COMBOBOX
(
ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER
,
GERBVIEW_FRAME
::
OnSelectActiveLayer
)
EVT_SELECT_DCODE
(
ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE
,
GERBVIEW_FRAME
::
OnSelectActiveDCode
)
// Vertical toolbar:
EVT_TOOL
(
ID_NO_TOOL_SELECTED
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
EVT_MENU_RANGE
(
ID_POPUP_GENERAL_START_RANGE
,
ID_POPUP_GENERAL_END_RANGE
,
GERBVIEW_FRAME
::
Process_Special_Functions
)
// Option toolbar
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_LINES_SKETCH
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL
(
ID_TB_OPTIONS_SHOW_DCODES
,
GERBVIEW_FRAME
::
OnSelectOptionToolbar
)
EVT_TOOL_RANGE
(
ID_TB_OPTIONS_SHOW_GBR_MODE_0
,
ID_TB_OPTIONS_SHOW_GBR_MODE_2
,
GERBVIEW_FRAME
::
OnSelectDisplayMode
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH
,
GERBVIEW_FRAME
::
OnUpdateFlashedItemsDrawMode
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_LINES_SKETCH
,
GERBVIEW_FRAME
::
OnUpdateLinesDrawMode
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH
,
GERBVIEW_FRAME
::
OnUpdatePolygonsDrawMode
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_DCODES
,
GERBVIEW_FRAME
::
OnUpdateShowDCodes
)
EVT_UPDATE_UI
(
ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR
,
GERBVIEW_FRAME
::
OnUpdateShowLayerManager
)
EVT_UPDATE_UI
(
ID_TOOLBARH_GERBER_SELECT_ACTIVE_DCODE
,
GERBVIEW_FRAME
::
OnUpdateSelectDCode
)
EVT_UPDATE_UI
(
ID_TOOLBARH_GERBVIEW_SELECT_ACTIVE_LAYER
,
GERBVIEW_FRAME
::
OnUpdateLayerSelectBox
)
EVT_UPDATE_UI_RANGE
(
ID_TB_OPTIONS_SHOW_GBR_MODE_0
,
ID_TB_OPTIONS_SHOW_GBR_MODE_2
,
GERBVIEW_FRAME
::
OnUpdateDrawMode
)
END_EVENT_TABLE
()
/* Handles the selection of tools, menu, and popup menu commands.
*/
void
GERBVIEW_FRAME
::
Process_Special_Functions
(
wxCommandEvent
&
event
)
{
int
id
=
event
.
GetId
();
switch
(
id
)
{
case
wxID_CUT
:
case
wxID_COPY
:
case
ID_POPUP_DELETE_BLOCK
:
case
ID_POPUP_PLACE_BLOCK
:
case
ID_POPUP_ZOOM_BLOCK
:
break
;
case
ID_POPUP_CANCEL_CURRENT_COMMAND
:
DrawPanel
->
EndMouseCapture
();
if
(
GetScreen
()
->
m_BlockLocate
.
m_Command
!=
BLOCK_IDLE
)
{
/* Should not be executed, except bug */
GetScreen
()
->
m_BlockLocate
.
m_Command
=
BLOCK_IDLE
;
GetScreen
()
->
m_BlockLocate
.
m_State
=
STATE_NO_BLOCK
;
GetScreen
()
->
m_BlockLocate
.
ClearItemsList
();
}
if
(
GetToolId
()
==
ID_NO_TOOL_SELECTED
)
SetToolID
(
ID_NO_TOOL_SELECTED
,
DrawPanel
->
GetDefaultCursor
(),
wxEmptyString
);
else
DrawPanel
->
SetCursor
(
DrawPanel
->
GetCurrentCursor
()
);
break
;
default
:
DrawPanel
->
EndMouseCapture
();
break
;
}
INSTALL_UNBUFFERED_DC
(
dc
,
DrawPanel
);
switch
(
id
)
{
case
ID_GERBVIEW_GLOBAL_DELETE
:
Erase_Current_Layer
(
true
);
ClearMsgPanel
();
break
;
case
ID_NO_TOOL_SELECTED
:
SetToolID
(
ID_NO_TOOL_SELECTED
,
DrawPanel
->
GetDefaultCursor
(),
wxEmptyString
);
break
;
case
ID_POPUP_CLOSE_CURRENT_TOOL
:
SetToolID
(
ID_NO_TOOL_SELECTED
,
DrawPanel
->
GetDefaultCursor
(),
wxEmptyString
);
break
;
case
ID_POPUP_CANCEL_CURRENT_COMMAND
:
break
;
case
ID_GERBVIEW_SHOW_LIST_DCODES
:
Liste_D_Codes
();
break
;
case
ID_POPUP_PLACE_BLOCK
:
GetScreen
()
->
m_BlockLocate
.
m_Command
=
BLOCK_MOVE
;
DrawPanel
->
m_AutoPAN_Request
=
FALSE
;
HandleBlockPlace
(
&
dc
);
break
;
case
ID_POPUP_ZOOM_BLOCK
:
GetScreen
()
->
m_BlockLocate
.
m_Command
=
BLOCK_ZOOM
;
GetScreen
()
->
m_BlockLocate
.
SetMessageBlock
(
this
);
HandleBlockEnd
(
&
dc
);
break
;
case
ID_POPUP_DELETE_BLOCK
:
GetScreen
()
->
m_BlockLocate
.
m_Command
=
BLOCK_DELETE
;
GetScreen
()
->
m_BlockLocate
.
SetMessageBlock
(
this
);
HandleBlockEnd
(
&
dc
);
break
;
default
:
wxFAIL_MSG
(
wxT
(
"GERBVIEW_FRAME::Process_Special_Functions error"
)
);
break
;
}
}
/* Selects the active DCode for the current active layer.
* Items using this DCode are hightlighted
*/
void
GERBVIEW_FRAME
::
OnSelectActiveDCode
(
wxCommandEvent
&
event
)
{
GERBER_IMAGE
*
gerber_image
=
g_GERBER_List
[
getActiveLayer
()];
if
(
gerber_image
)
{
int
tool
=
m_DCodeSelector
->
GetSelectedDCodeId
();
if
(
tool
!=
gerber_image
->
m_Selected_Tool
)
{
gerber_image
->
m_Selected_Tool
=
tool
;
DrawPanel
->
Refresh
();
}
}
}
/* Selects the active layer:
* - if a file is loaded, it is loaded in this layer
* _ this layer is displayed on top of other layers
*/
void
GERBVIEW_FRAME
::
OnSelectActiveLayer
(
wxCommandEvent
&
event
)
{
int
layer
=
getActiveLayer
();
setActiveLayer
(
event
.
GetSelection
()
);
if
(
layer
!=
getActiveLayer
()
)
DrawPanel
->
Refresh
();
}
/* Call preferred editor to show (and edit) the gerber source file
* loaded in the active layer
*/
void
GERBVIEW_FRAME
::
OnShowGerberSourceFile
(
wxCommandEvent
&
event
)
{
int
layer
=
getActiveLayer
();
GERBER_IMAGE
*
gerber_layer
=
g_GERBER_List
[
layer
];
if
(
gerber_layer
)
{
wxString
editorname
=
wxGetApp
().
GetEditorName
();
if
(
!
editorname
.
IsEmpty
()
)
{
wxFileName
fn
(
gerber_layer
->
m_FileName
);
ExecuteFile
(
this
,
editorname
,
QuoteFullPath
(
fn
)
);
}
else
{
wxMessageBox
(
_
(
"No editor defined. Please select one"
)
);
}
}
}
/* Function OnSelectDisplayMode: called to select display mode
* (fast display, or exact mode with stacked images or with transparency
*/
void
GERBVIEW_FRAME
::
OnSelectDisplayMode
(
wxCommandEvent
&
event
)
{
int
oldMode
=
GetDisplayMode
();
switch
(
event
.
GetId
()
)
{
case
ID_TB_OPTIONS_SHOW_GBR_MODE_0
:
SetDisplayMode
(
0
);
break
;
case
ID_TB_OPTIONS_SHOW_GBR_MODE_1
:
SetDisplayMode
(
1
);
break
;
case
ID_TB_OPTIONS_SHOW_GBR_MODE_2
:
SetDisplayMode
(
2
);
break
;
}
if
(
GetDisplayMode
()
!=
oldMode
)
DrawPanel
->
Refresh
();
}
void
GERBVIEW_FRAME
::
OnQuit
(
wxCommandEvent
&
event
)
{
Close
(
true
);
}
/**
* Function SetLanguage
* called on a language menu selection
* Update Layer manager title and tabs texts
*/
void
GERBVIEW_FRAME
::
SetLanguage
(
wxCommandEvent
&
event
)
{
EDA_DRAW_FRAME
::
SetLanguage
(
event
);
m_LayersManager
->
SetLayersManagerTabsText
();
wxAuiPaneInfo
&
pane_info
=
m_auimgr
.
GetPane
(
m_LayersManager
);
pane_info
.
Caption
(
_
(
"Visibles"
)
);
m_auimgr
.
Update
();
ReFillLayerWidget
();
}
gerbview/toolbars_gerber.cpp
View file @
8db19bbd
...
...
@@ -42,16 +42,16 @@ void GERBVIEW_FRAME::ReCreateHToolbar( void )
_
(
"Print layers"
)
);
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
_
(
"Zoom in"
),
s_Gerbview_Hokeys_Descr
,
HK_ZOOM_IN
,
false
);
msg
=
AddHotkeyName
(
_
(
"Zoom in"
),
s_Gerbview_Hokeys_Descr
,
HK_ZOOM_IN
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_IN
,
wxEmptyString
,
KiBitmap
(
zoom_in_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Zoom out"
),
s_Gerbview_Hokeys_Descr
,
HK_ZOOM_OUT
,
false
);
msg
=
AddHotkeyName
(
_
(
"Zoom out"
),
s_Gerbview_Hokeys_Descr
,
HK_ZOOM_OUT
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_OUT
,
wxEmptyString
,
KiBitmap
(
zoom_out_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Redraw view"
),
s_Gerbview_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
false
);
msg
=
AddHotkeyName
(
_
(
"Redraw view"
),
s_Gerbview_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_REDRAW
,
wxEmptyString
,
KiBitmap
(
zoom_redraw_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Zoom auto"
),
s_Gerbview_Hokeys_Descr
,
HK_ZOOM_AUTO
,
false
);
msg
=
AddHotkeyName
(
_
(
"Zoom auto"
),
s_Gerbview_Hokeys_Descr
,
HK_ZOOM_AUTO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_PAGE
,
wxEmptyString
,
KiBitmap
(
zoom_fit_in_page_xpm
),
msg
);
m_HToolBar
->
AddSeparator
();
...
...
include/hotkeys_basic.h
View file @
8db19bbd
...
...
@@ -14,7 +14,7 @@
class
EDA_DRAW_FRAME
;
/* Class to handle hotkey comm
n
ands. hotkeys have a default value
/* Class to handle hotkey commands. hotkeys have a default value
* This class allows the real key code changed by user(from a key code list file)
*/
class
Ki_HotkeyInfo
...
...
@@ -93,6 +93,20 @@ wxString ReturnKeyNameFromCommandId( Ki_HotkeyInfo** aList, int aCommandI
*/
int
ReturnKeyCodeFromKeyName
(
const
wxString
&
keyname
);
/* An helper enum for AddHotkeyName function
* In menus we can an a hot key, or an accelerator , or sometimes just a comment
* Hot keys can perform actions using the current mouse cursor position
* Accelerators performs the same action as the associated menu
* A comment is used in tool tips for some tools (zoom ..)
* to show the hot key that perfoms this action
*/
enum
HOTKEY_ACTION_TYPE
{
IS_HOTKEY
,
IS_ACCELERATOR
,
IS_COMMENT
};
/**
* Function AddHotkeyName
* Add the key name from the Command id value ( m_Idcommand member value)
...
...
@@ -105,7 +119,7 @@ int ReturnKeyCodeFromKeyName( const wxString& keyname );
*/
wxString
AddHotkeyName
(
const
wxString
&
aText
,
Ki_HotkeyInfo
**
aList
,
int
aCommandId
,
bool
aIsShortCut
=
true
);
HOTKEY_ACTION_TYPE
aShortCutType
=
IS_HOTKEY
);
/**
* Function AddHotkeyName
...
...
@@ -120,7 +134,7 @@ wxString AddHotkeyName( const wxString& aText, Ki_HotkeyInfo** aList,
wxString
AddHotkeyName
(
const
wxString
&
aText
,
struct
Ki_HotkeyInfoSectionDescriptor
*
aDescrList
,
int
aCommandId
,
bool
aIsShortCut
=
true
);
HOTKEY_ACTION_TYPE
aShortCutType
=
IS_HOTKEY
);
/**
* Function DisplayHotkeyList
...
...
pcbnew/class_netinfo.h
View file @
8db19bbd
/**
* @file class_netinfo.h
*/
/*
* Classes to handle info on nets
*/
#ifndef __CLASSES_NETINFO__
#define __CLASSES_NETINFO__
#include "class_netclass.h"
class
LINE_READER
;
class
EDA_DRAW_PANEL
;
class
EDA_DRAW_FRAME
;
class
NETINFO_ITEM
;
class
D_PAD
;
class
BOARD
;
class
BOARD_ITEM
;
/* Class RATSNEST_ITEM: describes a ratsnest line: a straight line connecting 2 pads */
/*****************************/
/* flags for a RATSNEST_ITEM */
/*****************************/
#define CH_VISIBLE 1
/* Visible */
#define CH_UNROUTABLE 2
/* Don't use autorouter. */
#define CH_ROUTE_REQ 4
/* Must be routed by the autorouter. */
#define CH_ACTIF 8
/* Not routed. */
#define LOCAL_RATSNEST_ITEM 0x8000
/* Line between two pads of a single module. */
class
RATSNEST_ITEM
{
private
:
int
m_NetCode
;
// netcode ( = 1.. n , 0 is the value used for not connected items)
public
:
int
m_Status
;
// State: see previous defines (CH_ ...)
D_PAD
*
m_PadStart
;
// pointer to the starting pad
D_PAD
*
m_PadEnd
;
// pointer to ending pad
int
m_Lenght
;
// length of the line (used in some calculations)
RATSNEST_ITEM
();
/**
* Function GetNet
* @return int - the net code.
*/
int
GetNet
()
const
{
return
m_NetCode
;
}
void
SetNet
(
int
aNetCode
)
{
m_NetCode
=
aNetCode
;
}
/**
* Function Draw
*/
void
Draw
(
EDA_DRAW_PANEL
*
panel
,
wxDC
*
DC
,
int
aDrawMode
,
const
wxPoint
&
offset
);
};
/***************************************************************/
/******************* class NETINFO *****************************/
/***************************************************************/
class
NETINFO_LIST
{
private
:
BOARD
*
m_Parent
;
std
::
vector
<
NETINFO_ITEM
*>
m_NetBuffer
;
// nets buffer list (name, design constraints ..
public
:
std
::
vector
<
D_PAD
*>
m_PadsFullList
;
// Entry for a sorted pad list (used in ratsnest
// calculations)
public
:
NETINFO_LIST
(
BOARD
*
aParent
);
~
NETINFO_LIST
();
/**
* Function GetItem
* @param aNetcode = netcode to identify a given NETINFO_ITEM
* @return a NETINFO_ITEM pointer to the selected NETINFO_ITEM by its
* netcode, or NULL if not found
*/
NETINFO_ITEM
*
GetNetItem
(
int
aNetcode
);
/**
* Function GetCount
* @return the number of nets ( always >= 1 )
* becuse the first net is the "not connected" net and always exists
*/
unsigned
GetCount
()
{
return
m_NetBuffer
.
size
();
}
/**
* Function Append
* adds \a aNewElement to the end of the list.
*/
void
AppendNet
(
NETINFO_ITEM
*
aNewElement
);
/**
* Function DeleteData
* delete the list of nets (and free memory)
*/
void
DeleteData
();
/**
* Function BuildListOfNets
* Build or rebuild the list of NETINFO_ITEM m_NetBuffer
* The list is sorted by names.
*/
void
BuildListOfNets
();
/**
* Function GetPadsCount
* @return the number of pads in board
*/
unsigned
GetPadsCount
()
{
return
m_PadsFullList
.
size
();
}
/**
* Function GetPad
* @return the pad idx from m_PadsFullList
*/
D_PAD
*
GetPad
(
unsigned
aIdx
)
{
if
(
aIdx
<
m_PadsFullList
.
size
()
)
return
m_PadsFullList
[
aIdx
];
else
return
NULL
;
}
private
:
/**
* Function Build_Pads_Full_List
* Create the pad list
* initialise:
* m_Pads (list of pads)
* set m_Status_Pcb = LISTE_PAD_OK;
* and clear for all pads in list the m_SubRatsnest member;
* clear m_Pcb->m_FullRatsnest
*/
void
Build_Pads_Full_List
();
};
/**
* Class NETINFO_ITEM
* handles the data for a net
*/
class
NETINFO_ITEM
{
private
:
int
m_NetCode
;
// this is a number equivalent to the net name
// Used for fast comparisons in ratsnest and DRC computations.
wxString
m_Netname
;
// Full net name like /mysheet/mysubsheet/vout
// used by eeschema
wxString
m_ShortNetname
;
// short net name, like vout from
// /mysheet/mysubsheet/vout
wxString
m_NetClassName
;
// Net Class name. if void this is equivalent
// to "default" (the first
// item of the net classes list
NETCLASS
*
m_NetClass
;
public
:
int
m_NbNodes
;
// Pads count for this net
int
m_NbLink
;
// Ratsnets count for this net
int
m_NbNoconn
;
// Ratsnets remaining to route count
int
m_Flag
;
// used in some calculations. Had no
// special meaning
std
::
vector
<
D_PAD
*>
m_ListPad
;
// List of pads connected to this net
unsigned
m_RatsnestStartIdx
;
/* Starting point of ratsnests of this
* net (included) in a general buffer of
* ratsnest (a vector<RATSNEST_ITEM*>
* buffer) */
unsigned
m_RatsnestEndIdx
;
// Ending point of ratsnests of this net
// (excluded) in this buffer
NETINFO_ITEM
(
BOARD_ITEM
*
aParent
);
~
NETINFO_ITEM
();
/**
* Function SetClass
* sets \a aNetclass into this NET
*/
void
SetClass
(
const
NETCLASS
*
aNetClass
)
{
m_NetClass
=
(
NETCLASS
*
)
aNetClass
;
if
(
aNetClass
)
m_NetClassName
=
aNetClass
->
GetName
();
else
m_NetClassName
=
NETCLASS
::
Default
;
}
NETCLASS
*
GetNetClass
()
{
return
m_NetClass
;
}
/**
* Function GetClassName
* returns the class name
*/
const
wxString
&
GetClassName
()
const
{
return
m_NetClassName
;
}
#if 1
/**
* Function GetTrackWidth
* returns the width of tracks used to route this net.
*/
int
GetTrackWidth
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetTrackWidth
();
}
/**
* Function GetViaSize
* returns the size of vias used to route this net
*/
int
GetViaSize
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetViaDiameter
();
}
/**
* Function GetMicroViaSize
* returns the size of vias used to route this net
*/
int
GetMicroViaSize
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetuViaDiameter
();
}
/**
* Function GetViaDrillSize
* returns the size of via drills used to route this net
*/
int
GetViaDrillSize
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetViaDrill
();
}
/**
* Function GetViaDrillSize
* returns the size of via drills used to route this net
*/
int
GetMicroViaDrillSize
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetuViaDrill
();
}
#if 0
/**
* Function GetViaMinSize
* returns the Minimum value for via sizes (used in DRC)
*/
int GetViaMinSize()
{
wxASSERT( m_NetClass );
return m_NetClass->GetViaMinSize();
}
#endif
/**
* Function GetClearance
* returns the clearance when routing near aBoardItem
*/
int
GetClearance
(
BOARD_ITEM
*
aBoardItem
)
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetClearance
();
}
#endif
/* Reading and writing data on files */
int
ReadDescr
(
LINE_READER
*
aReader
);
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd"
* format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool
Save
(
FILE
*
aFile
)
const
;
/**
* Function Draw
* @todo we actually could show a NET, simply show all the tracks and
* a pads or net name on pad and vias
*/
void
Draw
(
EDA_DRAW_PANEL
*
panel
,
wxDC
*
DC
,
int
aDrawMode
,
const
wxPoint
&
offset
);
/**
* Function GetNet
* @return int - the netcode
*/
int
GetNet
()
const
{
return
m_NetCode
;
}
void
SetNet
(
int
aNetCode
)
{
m_NetCode
=
aNetCode
;
}
int
GetNodesCount
()
const
{
return
m_ListPad
.
size
();
}
/**
* Function GetNetname
* @return const wxString * , a pointer to the full netname
*/
wxString
GetNetname
()
const
{
return
m_Netname
;
}
/**
* Function GetShortNetname
* @return const wxString * , a pointer to the short netname
*/
wxString
GetShortNetname
()
const
{
return
m_ShortNetname
;
}
/**
* Function SetNetname
* @param aNetname : the new netname
*/
void
SetNetname
(
const
wxString
&
aNetname
);
/**
* Function DisplayInfo
* has knowledge about the frame and how and where to put status information
* about this object into the frame's message panel.
* Is virtual from EDA_ITEM.
* @param frame A EDA_DRAW_FRAME in which to print status information.
*/
void
DisplayInfo
(
EDA_DRAW_FRAME
*
frame
);
};
/***********************************************************/
/* Description of a trace point for monitoring connections */
/***********************************************************/
#define START_ON_PAD 0x10
#define END_ON_PAD 0x20
#define START_ON_TRACK 0x40
#define END_ON_TRACK 0x80
/* Status bit (OR'ed bits) for class BOARD member .m_Status_Pcb */
enum
StatusPcbFlags
{
LISTE_PAD_OK
=
1
,
/* Pad list is Ok */
LISTE_RATSNEST_ITEM_OK
=
2
,
/* General Ratsnest is Ok */
RATSNEST_ITEM_LOCAL_OK
=
4
,
/* current MODULE ratsnest is Ok */
CONNEXION_OK
=
8
,
/* List of connections exists. */
NET_CODES_OK
=
0x10
,
/* Bit indicating that Netcode is OK,
* do not change net name. */
DO_NOT_SHOW_GENERAL_RASTNEST
=
0x20
/* Do not display the general
* ratsnest (used in module moves) */
};
#endif // __CLASSES_NETINFO__
/**
* @file class_netinfo.h
*/
/*
* Classes to handle info on nets
*/
#ifndef __CLASSES_NETINFO__
#define __CLASSES_NETINFO__
#include "class_netclass.h"
class
LINE_READER
;
class
EDA_DRAW_PANEL
;
class
EDA_DRAW_FRAME
;
class
NETINFO_ITEM
;
class
D_PAD
;
class
BOARD
;
class
BOARD_ITEM
;
/* Class RATSNEST_ITEM: describes a ratsnest line: a straight line connecting 2 pads */
/*****************************/
/* flags for a RATSNEST_ITEM */
/*****************************/
#define CH_VISIBLE 1
/* Visible */
#define CH_UNROUTABLE 2
/* Don't use autorouter. */
#define CH_ROUTE_REQ 4
/* Must be routed by the autorouter. */
#define CH_ACTIF 8
/* Not routed. */
#define LOCAL_RATSNEST_ITEM 0x8000
/* Line between two pads of a single module. */
class
RATSNEST_ITEM
{
private
:
int
m_NetCode
;
// netcode ( = 1.. n , 0 is the value used for not connected items)
public
:
int
m_Status
;
// State: see previous defines (CH_ ...)
D_PAD
*
m_PadStart
;
// pointer to the starting pad
D_PAD
*
m_PadEnd
;
// pointer to ending pad
int
m_Lenght
;
// length of the line (used in some calculations)
RATSNEST_ITEM
();
/**
* Function GetNet
* @return int - the net code.
*/
int
GetNet
()
const
{
return
m_NetCode
;
}
void
SetNet
(
int
aNetCode
)
{
m_NetCode
=
aNetCode
;
}
/**
* Function Draw
*/
void
Draw
(
EDA_DRAW_PANEL
*
panel
,
wxDC
*
DC
,
int
aDrawMode
,
const
wxPoint
&
offset
);
};
/***************************************************************/
/******************* class NETINFO *****************************/
/***************************************************************/
class
NETINFO_LIST
{
private
:
BOARD
*
m_Parent
;
std
::
vector
<
NETINFO_ITEM
*>
m_NetBuffer
;
// nets buffer list (name, design constraints ..
public
:
std
::
vector
<
D_PAD
*>
m_PadsFullList
;
// Entry for a sorted pad list (used in ratsnest
// calculations)
public
:
NETINFO_LIST
(
BOARD
*
aParent
);
~
NETINFO_LIST
();
/**
* Function GetItem
* @param aNetcode = netcode to identify a given NETINFO_ITEM
* @return a NETINFO_ITEM pointer to the selected NETINFO_ITEM by its
* netcode, or NULL if not found
*/
NETINFO_ITEM
*
GetNetItem
(
int
aNetcode
);
/**
* Function GetCount
* @return the number of nets ( always >= 1 )
* becuse the first net is the "not connected" net and always exists
*/
unsigned
GetCount
()
{
return
m_NetBuffer
.
size
();
}
/**
* Function Append
* adds \a aNewElement to the end of the list.
*/
void
AppendNet
(
NETINFO_ITEM
*
aNewElement
);
/**
* Function DeleteData
* delete the list of nets (and free memory)
*/
void
DeleteData
();
/**
* Function BuildListOfNets
* Build or rebuild the list of NETINFO_ITEM m_NetBuffer
* The list is sorted by names.
*/
void
BuildListOfNets
();
/**
* Function GetPadsCount
* @return the number of pads in board
*/
unsigned
GetPadsCount
()
{
return
m_PadsFullList
.
size
();
}
/**
* Function GetPad
* @return the pad idx from m_PadsFullList
*/
D_PAD
*
GetPad
(
unsigned
aIdx
)
{
if
(
aIdx
<
m_PadsFullList
.
size
()
)
return
m_PadsFullList
[
aIdx
];
else
return
NULL
;
}
private
:
/**
* Function Build_Pads_Full_List
* Create the pad list
* initialise:
* m_Pads (list of pads)
* set m_Status_Pcb = LISTE_PAD_OK;
* and clear for all pads in list the m_SubRatsnest member;
* clear m_Pcb->m_FullRatsnest
*/
void
Build_Pads_Full_List
();
};
/**
* Class NETINFO_ITEM
* handles the data for a net
*/
class
NETINFO_ITEM
{
private
:
int
m_NetCode
;
// this is a number equivalent to the net name
// Used for fast comparisons in ratsnest and DRC computations.
wxString
m_Netname
;
// Full net name like /mysheet/mysubsheet/vout
// used by eeschema
wxString
m_ShortNetname
;
// short net name, like vout from
// /mysheet/mysubsheet/vout
wxString
m_NetClassName
;
// Net Class name. if void this is equivalent
// to "default" (the first
// item of the net classes list
NETCLASS
*
m_NetClass
;
public
:
int
m_NbNodes
;
// Pads count for this net
int
m_NbLink
;
// Ratsnets count for this net
int
m_NbNoconn
;
// Ratsnets remaining to route count
int
m_Flag
;
// used in some calculations. Had no
// special meaning
std
::
vector
<
D_PAD
*>
m_ListPad
;
// List of pads connected to this net
unsigned
m_RatsnestStartIdx
;
/* Starting point of ratsnests of this
* net (included) in a general buffer of
* ratsnest (a vector<RATSNEST_ITEM*>
* buffer) */
unsigned
m_RatsnestEndIdx
;
// Ending point of ratsnests of this net
// (excluded) in this buffer
NETINFO_ITEM
(
BOARD_ITEM
*
aParent
);
~
NETINFO_ITEM
();
/**
* Function SetClass
* sets \a aNetclass into this NET
*/
void
SetClass
(
const
NETCLASS
*
aNetClass
)
{
m_NetClass
=
(
NETCLASS
*
)
aNetClass
;
if
(
aNetClass
)
m_NetClassName
=
aNetClass
->
GetName
();
else
m_NetClassName
=
NETCLASS
::
Default
;
}
NETCLASS
*
GetNetClass
()
{
return
m_NetClass
;
}
/**
* Function GetClassName
* returns the class name
*/
const
wxString
&
GetClassName
()
const
{
return
m_NetClassName
;
}
#if 1
/**
* Function GetTrackWidth
* returns the width of tracks used to route this net.
*/
int
GetTrackWidth
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetTrackWidth
();
}
/**
* Function GetViaSize
* returns the size of vias used to route this net
*/
int
GetViaSize
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetViaDiameter
();
}
/**
* Function GetMicroViaSize
* returns the size of vias used to route this net
*/
int
GetMicroViaSize
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetuViaDiameter
();
}
/**
* Function GetViaDrillSize
* returns the size of via drills used to route this net
*/
int
GetViaDrillSize
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetViaDrill
();
}
/**
* Function GetViaDrillSize
* returns the size of via drills used to route this net
*/
int
GetMicroViaDrillSize
()
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetuViaDrill
();
}
#if 0
/**
* Function GetViaMinSize
* returns the Minimum value for via sizes (used in DRC)
*/
int GetViaMinSize()
{
wxASSERT( m_NetClass );
return m_NetClass->GetViaMinSize();
}
#endif
/**
* Function GetClearance
* returns the clearance when routing near aBoardItem
*/
int
GetClearance
(
BOARD_ITEM
*
aBoardItem
)
{
wxASSERT
(
m_NetClass
);
return
m_NetClass
->
GetClearance
();
}
#endif
/* Reading and writing data on files */
int
ReadDescr
(
LINE_READER
*
aReader
);
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd"
* format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool
Save
(
FILE
*
aFile
)
const
;
/**
* Function Draw
* @todo we actually could show a NET, simply show all the tracks and
* a pads or net name on pad and vias
*/
void
Draw
(
EDA_DRAW_PANEL
*
panel
,
wxDC
*
DC
,
int
aDrawMode
,
const
wxPoint
&
offset
);
/**
* Function GetNet
* @return int - the netcode
*/
int
GetNet
()
const
{
return
m_NetCode
;
}
void
SetNet
(
int
aNetCode
)
{
m_NetCode
=
aNetCode
;
}
int
GetNodesCount
()
const
{
return
m_ListPad
.
size
();
}
/**
* Function GetNetname
* @return const wxString * , a pointer to the full netname
*/
wxString
GetNetname
()
const
{
return
m_Netname
;
}
/**
* Function GetShortNetname
* @return const wxString * , a pointer to the short netname
*/
wxString
GetShortNetname
()
const
{
return
m_ShortNetname
;
}
/**
* Function SetNetname
* @param aNetname : the new netname
*/
void
SetNetname
(
const
wxString
&
aNetname
);
/**
* Function DisplayInfo
* has knowledge about the frame and how and where to put status information
* about this object into the frame's message panel.
* Is virtual from EDA_ITEM.
* @param frame A EDA_DRAW_FRAME in which to print status information.
*/
void
DisplayInfo
(
EDA_DRAW_FRAME
*
frame
);
};
/***********************************************************/
/* Description of a trace point for monitoring connections */
/***********************************************************/
#define START_ON_PAD 0x10
#define END_ON_PAD 0x20
#define START_ON_TRACK 0x40
#define END_ON_TRACK 0x80
/* Status bit (OR'ed bits) for class BOARD member .m_Status_Pcb */
enum
StatusPcbFlags
{
LISTE_PAD_OK
=
1
,
/* Pad list is Ok */
LISTE_RATSNEST_ITEM_OK
=
2
,
/* General Ratsnest is Ok */
RATSNEST_ITEM_LOCAL_OK
=
4
,
/* current MODULE ratsnest is Ok */
CONNEXION_OK
=
8
,
/* List of connections exists. */
NET_CODES_OK
=
0x10
,
/* Bit indicating that Netcode is OK,
* do not change net name. */
DO_NOT_SHOW_GENERAL_RASTNEST
=
0x20
/* Do not display the general
* ratsnest (used in module moves) */
};
#endif // __CLASSES_NETINFO__
pcbnew/class_pcb_layer_widget.cpp
View file @
8db19bbd
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/******************************************************/
/* class_pcb_layer_widget.cpp - Pcbnew layers manager */
/******************************************************/
#include "fctsys.h"
#include "appl_wxstruct.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "wxPcbStruct.h"
#include "pcbstruct.h" // enum PCB_VISIBLE
#include "layer_widget.h"
#include "macros.h"
#include "pcbcommon.h"
#include "class_board.h"
#include "class_pcb_layer_widget.h"
#include "pcbnew.h"
#include "collectors.h"
#include "pcbnew_id.h"
/**
* Class PCB_LAYER_WIDGET
* is here to implement the abtract functions of LAYER_WIDGET so they
* may be tied into the PCB_EDIT_FRAME's data and so we can add a popup
* menu which is specific to PCBNEW's needs.
*/
PCB_LAYER_WIDGET
::
PCB_LAYER_WIDGET
(
PCB_EDIT_FRAME
*
aParent
,
wxWindow
*
aFocusOwner
,
int
aPointSize
)
:
LAYER_WIDGET
(
aParent
,
aFocusOwner
,
aPointSize
),
myframe
(
aParent
)
{
ReFillRender
();
// Update default tabs labels for gerbview
SetLayersManagerTabsText
(
);
//-----<Popup menu>-------------------------------------------------
// handle the popup menu over the layer window.
m_LayerScrolledWindow
->
Connect
(
wxEVT_RIGHT_DOWN
,
wxMouseEventHandler
(
PCB_LAYER_WIDGET
::
onRightDownLayers
),
NULL
,
this
);
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
// and not m_LayerScrolledWindow->Connect()
Connect
(
ID_SHOW_ALL_COPPERS
,
ID_SHOW_NO_COPPERS
,
wxEVT_COMMAND_MENU_SELECTED
,
wxCommandEventHandler
(
PCB_LAYER_WIDGET
::
onPopupSelection
),
NULL
,
this
);
// install the right click handler into each control at end of ReFill()
// using installRightLayerClickHandler
}
void
PCB_LAYER_WIDGET
::
installRightLayerClickHandler
()
{
int
rowCount
=
GetLayerRowCount
();
for
(
int
row
=
0
;
row
<
rowCount
;
++
row
)
{
for
(
int
col
=
0
;
col
<
LYR_COLUMN_COUNT
;
++
col
)
{
wxWindow
*
w
=
getLayerComp
(
row
,
col
);
w
->
Connect
(
wxEVT_RIGHT_DOWN
,
wxMouseEventHandler
(
PCB_LAYER_WIDGET
::
onRightDownLayers
),
NULL
,
this
);
}
}
}
void
PCB_LAYER_WIDGET
::
onRightDownLayers
(
wxMouseEvent
&
event
)
{
wxMenu
menu
;
// menu text is capitalized:
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_ALL_COPPERS
,
_
(
"Show All Copper Layers"
)
)
);
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_NO_COPPERS
,
_
(
"Hide All Copper Layers"
)
)
);
PopupMenu
(
&
menu
);
passOnFocus
();
}
void
PCB_LAYER_WIDGET
::
onPopupSelection
(
wxCommandEvent
&
event
)
{
int
rowCount
;
int
menuId
=
event
.
GetId
();
bool
visible
;
switch
(
menuId
)
{
case
ID_SHOW_ALL_COPPERS
:
visible
=
true
;
goto
L_change_coppers
;
case
ID_SHOW_NO_COPPERS
:
visible
=
false
;
L_change_coppers
:
int
lastCu
=
-
1
;
rowCount
=
GetLayerRowCount
();
for
(
int
row
=
rowCount
-
1
;
row
>=
0
;
--
row
)
{
wxCheckBox
*
cb
=
(
wxCheckBox
*
)
getLayerComp
(
row
,
3
);
int
layer
=
getDecodedId
(
cb
->
GetId
()
);
if
(
IsValidCopperLayerIndex
(
layer
)
)
{
lastCu
=
row
;
break
;
}
}
for
(
int
row
=
0
;
row
<
rowCount
;
++
row
)
{
wxCheckBox
*
cb
=
(
wxCheckBox
*
)
getLayerComp
(
row
,
3
);
int
layer
=
getDecodedId
(
cb
->
GetId
()
);
if
(
IsValidCopperLayerIndex
(
layer
)
)
{
cb
->
SetValue
(
visible
);
bool
isLastCopperLayer
=
(
row
==
lastCu
);
OnLayerVisible
(
layer
,
visible
,
isLastCopperLayer
);
if
(
isLastCopperLayer
)
break
;
}
}
break
;
}
}
/**
* Function SetLayersManagerTabsText
* Update the layer manager tabs labels
* Useful when changing Language or to set labels to a non default value
*/
void
PCB_LAYER_WIDGET
::
SetLayersManagerTabsText
(
)
{
m_notebook
->
SetPageText
(
0
,
_
(
"Layer"
)
);
m_notebook
->
SetPageText
(
1
,
_
(
"Render"
)
);
}
/**
* Function ReFillRender
* Rebuild Render for instance after the config is read
*/
void
PCB_LAYER_WIDGET
::
ReFillRender
()
{
BOARD
*
board
=
myframe
->
GetBoard
();
ClearRenderRows
();
// Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
// is changed before appending to the LAYER_WIDGET. This is an automatic variable
// not a static variable, change the color & state after copying from code to renderRows
// on the stack.
LAYER_WIDGET
::
ROW
renderRows
[
16
]
=
{
#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
// text id color tooltip checked
RR
(
_
(
"Through Via"
),
VIA_THROUGH_VISIBLE
,
WHITE
,
_
(
"Show through vias"
)
),
RR
(
_
(
"Bl/Buried Via"
),
VIA_BBLIND_VISIBLE
,
WHITE
,
_
(
"Show blind or buried vias"
)
),
RR
(
_
(
"Micro Via"
),
VIA_MICROVIA_VISIBLE
,
WHITE
,
_
(
"Show micro vias"
)
),
RR
(
_
(
"Ratsnest"
),
RATSNEST_VISIBLE
,
WHITE
,
_
(
"Show unconnected nets as a ratsnest"
)
),
RR
(
_
(
"Pads Front"
),
PAD_FR_VISIBLE
,
WHITE
,
_
(
"Show footprint pads on board's front"
)
),
RR
(
_
(
"Pads Back"
),
PAD_BK_VISIBLE
,
WHITE
,
_
(
"Show footprint pads on board's back"
)
),
RR
(
_
(
"Text Front"
),
MOD_TEXT_FR_VISIBLE
,
WHITE
,
_
(
"Show footprint text on board's back"
)
),
RR
(
_
(
"Text Back"
),
MOD_TEXT_BK_VISIBLE
,
WHITE
,
_
(
"Show footprint text on board's back"
)
),
RR
(
_
(
"Hidden Text"
),
MOD_TEXT_INVISIBLE
,
WHITE
,
_
(
"Show footprint text marked as invisible"
)
),
RR
(
_
(
"Anchors"
),
ANCHOR_VISIBLE
,
WHITE
,
_
(
"Show footprint and text origins as a cross"
)
),
RR
(
_
(
"Grid"
),
GRID_VISIBLE
,
WHITE
,
_
(
"Show the (x,y) grid dots"
)
),
RR
(
_
(
"No-Connects"
),
NO_CONNECTS_VISIBLE
,
-
1
,
_
(
"Show a marker on pads which have no net connected"
)
),
RR
(
_
(
"Modules Front"
),
MOD_FR_VISIBLE
,
-
1
,
_
(
"Show footprints that are on board's front"
)
),
RR
(
_
(
"Modules Back"
),
MOD_BK_VISIBLE
,
-
1
,
_
(
"Show footprints that are on board's back"
)
),
RR
(
_
(
"Values"
),
MOD_VALUES_VISIBLE
,
-
1
,
_
(
"Show footprint's values"
)
),
RR
(
_
(
"References"
),
MOD_REFERENCES_VISIBLE
,
-
1
,
_
(
"Show footprint's references"
)
),
};
for
(
unsigned
row
=
0
;
row
<
DIM
(
renderRows
);
++
row
)
{
if
(
renderRows
[
row
].
color
!=
-
1
)
// does this row show a color?
{
// this window frame must have an established BOARD, i.e. after SetBoard()
renderRows
[
row
].
color
=
board
->
GetVisibleElementColor
(
renderRows
[
row
].
id
);
}
renderRows
[
row
].
state
=
board
->
IsElementVisible
(
renderRows
[
row
].
id
);
}
AppendRenderRows
(
renderRows
,
DIM
(
renderRows
)
);
}
void
PCB_LAYER_WIDGET
::
ReFill
()
{
BOARD
*
brd
=
myframe
->
GetBoard
();
int
layer
;
int
enabledLayers
=
brd
->
GetEnabledLayers
();
// m_Layers->Freeze(); // no screen updates until done modifying
ClearLayerRows
();
// show all coppers first, with front on top, back on bottom, then technical layers
layer
=
LAYER_N_FRONT
;
if
(
enabledLayers
&
(
1
<<
layer
)
)
{
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
brd
->
GetLayerName
(
layer
),
layer
,
brd
->
GetLayerColor
(
layer
),
_
(
"Front copper layer"
),
true
)
);
}
for
(
layer
=
LAYER_N_FRONT
-
1
;
layer
>=
1
;
--
layer
)
{
if
(
enabledLayers
&
(
1
<<
layer
)
)
{
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
brd
->
GetLayerName
(
layer
),
layer
,
brd
->
GetLayerColor
(
layer
),
_
(
"An innner copper layer"
),
true
)
);
}
}
layer
=
LAYER_N_BACK
;
if
(
enabledLayers
&
(
1
<<
layer
)
)
{
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
brd
->
GetLayerName
(
layer
),
layer
,
brd
->
GetLayerColor
(
layer
),
_
(
"Back copper layer"
),
true
)
);
}
// technical layers are shown in this order:
static
const
struct
{
int
layerId
;
wxString
tooltip
;
}
techLayerSeq
[]
=
{
{
ADHESIVE_N_FRONT
,
_
(
"Adhesive on board's front"
)
},
{
ADHESIVE_N_BACK
,
_
(
"Adhesive on board's back"
)
},
{
SOLDERPASTE_N_FRONT
,
_
(
"Solder paste on board's front"
)},
{
SOLDERPASTE_N_BACK
,
_
(
"Solder paste on board's back"
)
},
{
SILKSCREEN_N_FRONT
,
_
(
"Silkscreen on board's front"
)
},
{
SILKSCREEN_N_BACK
,
_
(
"Silkscreen on board's back"
)
},
{
SOLDERMASK_N_FRONT
,
_
(
"Solder mask on board's front"
)
},
{
SOLDERMASK_N_BACK
,
_
(
"Solder mask on board's back"
)
},
{
DRAW_N
,
_
(
"Explanatory drawings"
)
},
{
COMMENT_N
,
_
(
"Explanatory comments"
)
},
{
ECO1_N
,
_
(
"TDB"
)
},
{
ECO2_N
,
_
(
"TBD"
)
},
{
EDGE_N
,
_
(
"Board's perimeter definition"
)
},
};
for
(
unsigned
i
=
0
;
i
<
DIM
(
techLayerSeq
);
++
i
)
{
layer
=
techLayerSeq
[
i
].
layerId
;
if
(
!
(
enabledLayers
&
(
1
<<
layer
))
)
continue
;
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
brd
->
GetLayerName
(
layer
),
layer
,
brd
->
GetLayerColor
(
layer
),
techLayerSeq
[
i
].
tooltip
,
true
)
);
}
installRightLayerClickHandler
();
// m_Layers->Thaw();
}
//-----<LAYER_WIDGET callbacks>-------------------------------------------
void
PCB_LAYER_WIDGET
::
OnLayerColorChange
(
int
aLayer
,
int
aColor
)
{
myframe
->
GetBoard
()
->
SetLayerColor
(
aLayer
,
aColor
);
myframe
->
ReCreateLayerBox
(
NULL
);
myframe
->
DrawPanel
->
Refresh
();
}
bool
PCB_LAYER_WIDGET
::
OnLayerSelect
(
int
aLayer
)
{
// the layer change from the PCB_LAYER_WIDGET can be denied by returning
// false from this function.
myframe
->
setActiveLayer
(
aLayer
,
false
);
if
(
DisplayOpt
.
ContrastModeDisplay
)
myframe
->
DrawPanel
->
Refresh
();
return
true
;
}
void
PCB_LAYER_WIDGET
::
OnLayerVisible
(
int
aLayer
,
bool
isVisible
,
bool
isFinal
)
{
BOARD
*
brd
=
myframe
->
GetBoard
();
int
visibleLayers
=
brd
->
GetVisibleLayers
();
if
(
isVisible
)
visibleLayers
|=
(
1
<<
aLayer
);
else
visibleLayers
&=
~
(
1
<<
aLayer
);
brd
->
SetVisibleLayers
(
visibleLayers
);
if
(
isFinal
)
myframe
->
DrawPanel
->
Refresh
();
}
void
PCB_LAYER_WIDGET
::
OnRenderColorChange
(
int
aId
,
int
aColor
)
{
myframe
->
GetBoard
()
->
SetVisibleElementColor
(
aId
,
aColor
);
myframe
->
DrawPanel
->
Refresh
();
}
void
PCB_LAYER_WIDGET
::
OnRenderEnable
(
int
aId
,
bool
isEnabled
)
{
BOARD
*
brd
=
myframe
->
GetBoard
();
/* @todo:
move:
GRID_VISIBLE, ? maybe not this one
into m_VisibleElements and get rid of globals.
*/
switch
(
aId
)
{
// see todo above, don't really want anything except IsElementVisible() here.
case
GRID_VISIBLE
:
// @todo, make read/write accessors for grid control so the write accessor can fire updates to
// grid state listeners. I think the grid state should be kept in the BOARD.
brd
->
SetElementVisibility
(
aId
,
isEnabled
);
// set visibilty flag also in list, and myframe->m_Draw_Grid
break
;
default
:
brd
->
SetElementVisibility
(
aId
,
isEnabled
);
}
myframe
->
DrawPanel
->
Refresh
();
}
//-----</LAYER_WIDGET callbacks>------------------------------------------
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gpisa-lab.inpg.fr
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/******************************************************/
/* class_pcb_layer_widget.cpp - Pcbnew layers manager */
/******************************************************/
#include "fctsys.h"
#include "appl_wxstruct.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "wxPcbStruct.h"
#include "pcbstruct.h" // enum PCB_VISIBLE
#include "layer_widget.h"
#include "macros.h"
#include "pcbcommon.h"
#include "class_board.h"
#include "class_pcb_layer_widget.h"
#include "pcbnew.h"
#include "collectors.h"
#include "pcbnew_id.h"
/**
* Class PCB_LAYER_WIDGET
* is here to implement the abtract functions of LAYER_WIDGET so they
* may be tied into the PCB_EDIT_FRAME's data and so we can add a popup
* menu which is specific to PCBNEW's needs.
*/
PCB_LAYER_WIDGET
::
PCB_LAYER_WIDGET
(
PCB_EDIT_FRAME
*
aParent
,
wxWindow
*
aFocusOwner
,
int
aPointSize
)
:
LAYER_WIDGET
(
aParent
,
aFocusOwner
,
aPointSize
),
myframe
(
aParent
)
{
ReFillRender
();
// Update default tabs labels for gerbview
SetLayersManagerTabsText
(
);
//-----<Popup menu>-------------------------------------------------
// handle the popup menu over the layer window.
m_LayerScrolledWindow
->
Connect
(
wxEVT_RIGHT_DOWN
,
wxMouseEventHandler
(
PCB_LAYER_WIDGET
::
onRightDownLayers
),
NULL
,
this
);
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
// and not m_LayerScrolledWindow->Connect()
Connect
(
ID_SHOW_ALL_COPPERS
,
ID_SHOW_NO_COPPERS
,
wxEVT_COMMAND_MENU_SELECTED
,
wxCommandEventHandler
(
PCB_LAYER_WIDGET
::
onPopupSelection
),
NULL
,
this
);
// install the right click handler into each control at end of ReFill()
// using installRightLayerClickHandler
}
void
PCB_LAYER_WIDGET
::
installRightLayerClickHandler
()
{
int
rowCount
=
GetLayerRowCount
();
for
(
int
row
=
0
;
row
<
rowCount
;
++
row
)
{
for
(
int
col
=
0
;
col
<
LYR_COLUMN_COUNT
;
++
col
)
{
wxWindow
*
w
=
getLayerComp
(
row
,
col
);
w
->
Connect
(
wxEVT_RIGHT_DOWN
,
wxMouseEventHandler
(
PCB_LAYER_WIDGET
::
onRightDownLayers
),
NULL
,
this
);
}
}
}
void
PCB_LAYER_WIDGET
::
onRightDownLayers
(
wxMouseEvent
&
event
)
{
wxMenu
menu
;
// menu text is capitalized:
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_ALL_COPPERS
,
_
(
"Show All Copper Layers"
)
)
);
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_NO_COPPERS
,
_
(
"Hide All Copper Layers"
)
)
);
PopupMenu
(
&
menu
);
passOnFocus
();
}
void
PCB_LAYER_WIDGET
::
onPopupSelection
(
wxCommandEvent
&
event
)
{
int
rowCount
;
int
menuId
=
event
.
GetId
();
bool
visible
;
switch
(
menuId
)
{
case
ID_SHOW_ALL_COPPERS
:
visible
=
true
;
goto
L_change_coppers
;
case
ID_SHOW_NO_COPPERS
:
visible
=
false
;
L_change_coppers
:
int
lastCu
=
-
1
;
rowCount
=
GetLayerRowCount
();
for
(
int
row
=
rowCount
-
1
;
row
>=
0
;
--
row
)
{
wxCheckBox
*
cb
=
(
wxCheckBox
*
)
getLayerComp
(
row
,
3
);
int
layer
=
getDecodedId
(
cb
->
GetId
()
);
if
(
IsValidCopperLayerIndex
(
layer
)
)
{
lastCu
=
row
;
break
;
}
}
for
(
int
row
=
0
;
row
<
rowCount
;
++
row
)
{
wxCheckBox
*
cb
=
(
wxCheckBox
*
)
getLayerComp
(
row
,
3
);
int
layer
=
getDecodedId
(
cb
->
GetId
()
);
if
(
IsValidCopperLayerIndex
(
layer
)
)
{
cb
->
SetValue
(
visible
);
bool
isLastCopperLayer
=
(
row
==
lastCu
);
OnLayerVisible
(
layer
,
visible
,
isLastCopperLayer
);
if
(
isLastCopperLayer
)
break
;
}
}
break
;
}
}
/**
* Function SetLayersManagerTabsText
* Update the layer manager tabs labels
* Useful when changing Language or to set labels to a non default value
*/
void
PCB_LAYER_WIDGET
::
SetLayersManagerTabsText
(
)
{
m_notebook
->
SetPageText
(
0
,
_
(
"Layer"
)
);
m_notebook
->
SetPageText
(
1
,
_
(
"Render"
)
);
}
/**
* Function ReFillRender
* Rebuild Render for instance after the config is read
*/
void
PCB_LAYER_WIDGET
::
ReFillRender
()
{
BOARD
*
board
=
myframe
->
GetBoard
();
ClearRenderRows
();
// Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
// is changed before appending to the LAYER_WIDGET. This is an automatic variable
// not a static variable, change the color & state after copying from code to renderRows
// on the stack.
LAYER_WIDGET
::
ROW
renderRows
[
16
]
=
{
#define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
// text id color tooltip checked
RR
(
_
(
"Through Via"
),
VIA_THROUGH_VISIBLE
,
WHITE
,
_
(
"Show through vias"
)
),
RR
(
_
(
"Bl/Buried Via"
),
VIA_BBLIND_VISIBLE
,
WHITE
,
_
(
"Show blind or buried vias"
)
),
RR
(
_
(
"Micro Via"
),
VIA_MICROVIA_VISIBLE
,
WHITE
,
_
(
"Show micro vias"
)
),
RR
(
_
(
"Ratsnest"
),
RATSNEST_VISIBLE
,
WHITE
,
_
(
"Show unconnected nets as a ratsnest"
)
),
RR
(
_
(
"Pads Front"
),
PAD_FR_VISIBLE
,
WHITE
,
_
(
"Show footprint pads on board's front"
)
),
RR
(
_
(
"Pads Back"
),
PAD_BK_VISIBLE
,
WHITE
,
_
(
"Show footprint pads on board's back"
)
),
RR
(
_
(
"Text Front"
),
MOD_TEXT_FR_VISIBLE
,
WHITE
,
_
(
"Show footprint text on board's back"
)
),
RR
(
_
(
"Text Back"
),
MOD_TEXT_BK_VISIBLE
,
WHITE
,
_
(
"Show footprint text on board's back"
)
),
RR
(
_
(
"Hidden Text"
),
MOD_TEXT_INVISIBLE
,
WHITE
,
_
(
"Show footprint text marked as invisible"
)
),
RR
(
_
(
"Anchors"
),
ANCHOR_VISIBLE
,
WHITE
,
_
(
"Show footprint and text origins as a cross"
)
),
RR
(
_
(
"Grid"
),
GRID_VISIBLE
,
WHITE
,
_
(
"Show the (x,y) grid dots"
)
),
RR
(
_
(
"No-Connects"
),
NO_CONNECTS_VISIBLE
,
-
1
,
_
(
"Show a marker on pads which have no net connected"
)
),
RR
(
_
(
"Modules Front"
),
MOD_FR_VISIBLE
,
-
1
,
_
(
"Show footprints that are on board's front"
)
),
RR
(
_
(
"Modules Back"
),
MOD_BK_VISIBLE
,
-
1
,
_
(
"Show footprints that are on board's back"
)
),
RR
(
_
(
"Values"
),
MOD_VALUES_VISIBLE
,
-
1
,
_
(
"Show footprint's values"
)
),
RR
(
_
(
"References"
),
MOD_REFERENCES_VISIBLE
,
-
1
,
_
(
"Show footprint's references"
)
),
};
for
(
unsigned
row
=
0
;
row
<
DIM
(
renderRows
);
++
row
)
{
if
(
renderRows
[
row
].
color
!=
-
1
)
// does this row show a color?
{
// this window frame must have an established BOARD, i.e. after SetBoard()
renderRows
[
row
].
color
=
board
->
GetVisibleElementColor
(
renderRows
[
row
].
id
);
}
renderRows
[
row
].
state
=
board
->
IsElementVisible
(
renderRows
[
row
].
id
);
}
AppendRenderRows
(
renderRows
,
DIM
(
renderRows
)
);
}
void
PCB_LAYER_WIDGET
::
ReFill
()
{
BOARD
*
brd
=
myframe
->
GetBoard
();
int
layer
;
int
enabledLayers
=
brd
->
GetEnabledLayers
();
// m_Layers->Freeze(); // no screen updates until done modifying
ClearLayerRows
();
// show all coppers first, with front on top, back on bottom, then technical layers
layer
=
LAYER_N_FRONT
;
if
(
enabledLayers
&
(
1
<<
layer
)
)
{
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
brd
->
GetLayerName
(
layer
),
layer
,
brd
->
GetLayerColor
(
layer
),
_
(
"Front copper layer"
),
true
)
);
}
for
(
layer
=
LAYER_N_FRONT
-
1
;
layer
>=
1
;
--
layer
)
{
if
(
enabledLayers
&
(
1
<<
layer
)
)
{
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
brd
->
GetLayerName
(
layer
),
layer
,
brd
->
GetLayerColor
(
layer
),
_
(
"An innner copper layer"
),
true
)
);
}
}
layer
=
LAYER_N_BACK
;
if
(
enabledLayers
&
(
1
<<
layer
)
)
{
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
brd
->
GetLayerName
(
layer
),
layer
,
brd
->
GetLayerColor
(
layer
),
_
(
"Back copper layer"
),
true
)
);
}
// technical layers are shown in this order:
static
const
struct
{
int
layerId
;
wxString
tooltip
;
}
techLayerSeq
[]
=
{
{
ADHESIVE_N_FRONT
,
_
(
"Adhesive on board's front"
)
},
{
ADHESIVE_N_BACK
,
_
(
"Adhesive on board's back"
)
},
{
SOLDERPASTE_N_FRONT
,
_
(
"Solder paste on board's front"
)},
{
SOLDERPASTE_N_BACK
,
_
(
"Solder paste on board's back"
)
},
{
SILKSCREEN_N_FRONT
,
_
(
"Silkscreen on board's front"
)
},
{
SILKSCREEN_N_BACK
,
_
(
"Silkscreen on board's back"
)
},
{
SOLDERMASK_N_FRONT
,
_
(
"Solder mask on board's front"
)
},
{
SOLDERMASK_N_BACK
,
_
(
"Solder mask on board's back"
)
},
{
DRAW_N
,
_
(
"Explanatory drawings"
)
},
{
COMMENT_N
,
_
(
"Explanatory comments"
)
},
{
ECO1_N
,
_
(
"TDB"
)
},
{
ECO2_N
,
_
(
"TBD"
)
},
{
EDGE_N
,
_
(
"Board's perimeter definition"
)
},
};
for
(
unsigned
i
=
0
;
i
<
DIM
(
techLayerSeq
);
++
i
)
{
layer
=
techLayerSeq
[
i
].
layerId
;
if
(
!
(
enabledLayers
&
(
1
<<
layer
))
)
continue
;
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
brd
->
GetLayerName
(
layer
),
layer
,
brd
->
GetLayerColor
(
layer
),
techLayerSeq
[
i
].
tooltip
,
true
)
);
}
installRightLayerClickHandler
();
// m_Layers->Thaw();
}
//-----<LAYER_WIDGET callbacks>-------------------------------------------
void
PCB_LAYER_WIDGET
::
OnLayerColorChange
(
int
aLayer
,
int
aColor
)
{
myframe
->
GetBoard
()
->
SetLayerColor
(
aLayer
,
aColor
);
myframe
->
ReCreateLayerBox
(
NULL
);
myframe
->
DrawPanel
->
Refresh
();
}
bool
PCB_LAYER_WIDGET
::
OnLayerSelect
(
int
aLayer
)
{
// the layer change from the PCB_LAYER_WIDGET can be denied by returning
// false from this function.
myframe
->
setActiveLayer
(
aLayer
,
false
);
if
(
DisplayOpt
.
ContrastModeDisplay
)
myframe
->
DrawPanel
->
Refresh
();
return
true
;
}
void
PCB_LAYER_WIDGET
::
OnLayerVisible
(
int
aLayer
,
bool
isVisible
,
bool
isFinal
)
{
BOARD
*
brd
=
myframe
->
GetBoard
();
int
visibleLayers
=
brd
->
GetVisibleLayers
();
if
(
isVisible
)
visibleLayers
|=
(
1
<<
aLayer
);
else
visibleLayers
&=
~
(
1
<<
aLayer
);
brd
->
SetVisibleLayers
(
visibleLayers
);
if
(
isFinal
)
myframe
->
DrawPanel
->
Refresh
();
}
void
PCB_LAYER_WIDGET
::
OnRenderColorChange
(
int
aId
,
int
aColor
)
{
myframe
->
GetBoard
()
->
SetVisibleElementColor
(
aId
,
aColor
);
myframe
->
DrawPanel
->
Refresh
();
}
void
PCB_LAYER_WIDGET
::
OnRenderEnable
(
int
aId
,
bool
isEnabled
)
{
BOARD
*
brd
=
myframe
->
GetBoard
();
/* @todo:
move:
GRID_VISIBLE, ? maybe not this one
into m_VisibleElements and get rid of globals.
*/
switch
(
aId
)
{
// see todo above, don't really want anything except IsElementVisible() here.
case
GRID_VISIBLE
:
// @todo, make read/write accessors for grid control so the write accessor can fire updates to
// grid state listeners. I think the grid state should be kept in the BOARD.
brd
->
SetElementVisibility
(
aId
,
isEnabled
);
// set visibilty flag also in list, and myframe->m_Draw_Grid
break
;
default
:
brd
->
SetElementVisibility
(
aId
,
isEnabled
);
}
myframe
->
DrawPanel
->
Refresh
();
}
//-----</LAYER_WIDGET callbacks>------------------------------------------
pcbnew/drc_marker_functions.cpp
View file @
8db19bbd
/*
* drc_marker_functions.cpp
*/
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Methods of class DRC to initialize drc markers with messages
* according to items and error ode
*/
#include "fctsys.h"
#include "common.h"
#include "pcbnew.h"
#include "class_board_design_settings.h"
#include "drc_stuff.h"
#include "class_pad.h"
#include "class_track.h"
#include "class_zone.h"
#include "class_marker_pcb.h"
MARKER_PCB
*
DRC
::
fillMarker
(
TRACK
*
aTrack
,
BOARD_ITEM
*
aItem
,
int
aErrorCode
,
MARKER_PCB
*
fillMe
)
{
wxString
textA
=
aTrack
->
GetSelectMenuText
();
wxString
textB
;
wxPoint
position
;
wxPoint
posB
;
if
(
aItem
)
// aItem might be NULL
{
textB
=
aItem
->
GetSelectMenuText
();
posB
=
aItem
->
GetPosition
();
if
(
aItem
->
Type
()
==
TYPE_PAD
)
position
=
aItem
->
GetPosition
();
else
if
(
aItem
->
Type
()
==
TYPE_VIA
)
position
=
aItem
->
GetPosition
();
else
if
(
aItem
->
Type
()
==
TYPE_TRACK
)
{
TRACK
*
track
=
(
TRACK
*
)
aItem
;
wxPoint
endPos
=
track
->
m_End
;
// either of aItem's start or end will be used for the marker position
// first assume start, then switch at end if needed. decision made on
// distance from end of aTrack.
position
=
track
->
m_Start
;
double
dToEnd
=
hypot
(
endPos
.
x
-
aTrack
->
m_End
.
x
,
endPos
.
y
-
aTrack
->
m_End
.
y
);
double
dToStart
=
hypot
(
position
.
x
-
aTrack
->
m_End
.
x
,
position
.
y
-
aTrack
->
m_End
.
y
);
if
(
dToEnd
<
dToStart
)
position
=
endPos
;
}
}
else
position
=
aTrack
->
GetPosition
();
if
(
fillMe
)
{
if
(
aItem
)
fillMe
->
SetData
(
aErrorCode
,
position
,
textA
,
aTrack
->
GetPosition
(),
textB
,
posB
);
else
fillMe
->
SetData
(
aErrorCode
,
position
,
textA
,
aTrack
->
GetPosition
()
);
}
else
{
if
(
aItem
)
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
position
,
textA
,
aTrack
->
GetPosition
(),
textB
,
posB
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
position
,
textA
,
aTrack
->
GetPosition
()
);
}
return
fillMe
;
}
MARKER_PCB
*
DRC
::
fillMarker
(
D_PAD
*
aPad
,
D_PAD
*
bPad
,
int
aErrorCode
,
MARKER_PCB
*
fillMe
)
{
wxString
textA
=
aPad
->
GetSelectMenuText
();
wxString
textB
=
bPad
->
GetSelectMenuText
();
wxPoint
posA
=
aPad
->
GetPosition
();
wxPoint
posB
=
bPad
->
GetPosition
();
if
(
fillMe
)
fillMe
->
SetData
(
aErrorCode
,
posA
,
textA
,
posA
,
textB
,
posB
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
posA
,
textA
,
posA
,
textB
,
posB
);
return
fillMe
;
}
MARKER_PCB
*
DRC
::
fillMarker
(
ZONE_CONTAINER
*
aArea
,
int
aErrorCode
,
MARKER_PCB
*
fillMe
)
{
wxString
textA
=
aArea
->
GetSelectMenuText
();
wxPoint
posA
=
aArea
->
GetPosition
();
if
(
fillMe
)
fillMe
->
SetData
(
aErrorCode
,
posA
,
textA
,
posA
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
posA
,
textA
,
posA
);
return
fillMe
;
}
MARKER_PCB
*
DRC
::
fillMarker
(
const
ZONE_CONTAINER
*
aArea
,
const
wxPoint
&
aPos
,
int
aErrorCode
,
MARKER_PCB
*
fillMe
)
{
wxString
textA
=
aArea
->
GetSelectMenuText
();
wxPoint
posA
=
aPos
;
if
(
fillMe
)
fillMe
->
SetData
(
aErrorCode
,
posA
,
textA
,
posA
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
posA
,
textA
,
posA
);
return
fillMe
;
}
MARKER_PCB
*
DRC
::
fillMarker
(
int
aErrorCode
,
const
wxString
&
aMessage
,
MARKER_PCB
*
fillMe
)
{
wxPoint
posA
;
// not displayed
if
(
fillMe
)
fillMe
->
SetData
(
aErrorCode
,
posA
,
aMessage
,
posA
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
posA
,
aMessage
,
posA
);
fillMe
->
SetShowNoCoordinate
();
return
fillMe
;
}
/*
* drc_marker_functions.cpp
*/
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2010 Dick Hollenbeck, dick@softplc.com
* Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Methods of class DRC to initialize drc markers with messages
* according to items and error ode
*/
#include "fctsys.h"
#include "common.h"
#include "pcbnew.h"
#include "class_board_design_settings.h"
#include "drc_stuff.h"
#include "class_pad.h"
#include "class_track.h"
#include "class_zone.h"
#include "class_marker_pcb.h"
MARKER_PCB
*
DRC
::
fillMarker
(
TRACK
*
aTrack
,
BOARD_ITEM
*
aItem
,
int
aErrorCode
,
MARKER_PCB
*
fillMe
)
{
wxString
textA
=
aTrack
->
GetSelectMenuText
();
wxString
textB
;
wxPoint
position
;
wxPoint
posB
;
if
(
aItem
)
// aItem might be NULL
{
textB
=
aItem
->
GetSelectMenuText
();
posB
=
aItem
->
GetPosition
();
if
(
aItem
->
Type
()
==
TYPE_PAD
)
position
=
aItem
->
GetPosition
();
else
if
(
aItem
->
Type
()
==
TYPE_VIA
)
position
=
aItem
->
GetPosition
();
else
if
(
aItem
->
Type
()
==
TYPE_TRACK
)
{
TRACK
*
track
=
(
TRACK
*
)
aItem
;
wxPoint
endPos
=
track
->
m_End
;
// either of aItem's start or end will be used for the marker position
// first assume start, then switch at end if needed. decision made on
// distance from end of aTrack.
position
=
track
->
m_Start
;
double
dToEnd
=
hypot
(
endPos
.
x
-
aTrack
->
m_End
.
x
,
endPos
.
y
-
aTrack
->
m_End
.
y
);
double
dToStart
=
hypot
(
position
.
x
-
aTrack
->
m_End
.
x
,
position
.
y
-
aTrack
->
m_End
.
y
);
if
(
dToEnd
<
dToStart
)
position
=
endPos
;
}
}
else
position
=
aTrack
->
GetPosition
();
if
(
fillMe
)
{
if
(
aItem
)
fillMe
->
SetData
(
aErrorCode
,
position
,
textA
,
aTrack
->
GetPosition
(),
textB
,
posB
);
else
fillMe
->
SetData
(
aErrorCode
,
position
,
textA
,
aTrack
->
GetPosition
()
);
}
else
{
if
(
aItem
)
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
position
,
textA
,
aTrack
->
GetPosition
(),
textB
,
posB
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
position
,
textA
,
aTrack
->
GetPosition
()
);
}
return
fillMe
;
}
MARKER_PCB
*
DRC
::
fillMarker
(
D_PAD
*
aPad
,
D_PAD
*
bPad
,
int
aErrorCode
,
MARKER_PCB
*
fillMe
)
{
wxString
textA
=
aPad
->
GetSelectMenuText
();
wxString
textB
=
bPad
->
GetSelectMenuText
();
wxPoint
posA
=
aPad
->
GetPosition
();
wxPoint
posB
=
bPad
->
GetPosition
();
if
(
fillMe
)
fillMe
->
SetData
(
aErrorCode
,
posA
,
textA
,
posA
,
textB
,
posB
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
posA
,
textA
,
posA
,
textB
,
posB
);
return
fillMe
;
}
MARKER_PCB
*
DRC
::
fillMarker
(
ZONE_CONTAINER
*
aArea
,
int
aErrorCode
,
MARKER_PCB
*
fillMe
)
{
wxString
textA
=
aArea
->
GetSelectMenuText
();
wxPoint
posA
=
aArea
->
GetPosition
();
if
(
fillMe
)
fillMe
->
SetData
(
aErrorCode
,
posA
,
textA
,
posA
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
posA
,
textA
,
posA
);
return
fillMe
;
}
MARKER_PCB
*
DRC
::
fillMarker
(
const
ZONE_CONTAINER
*
aArea
,
const
wxPoint
&
aPos
,
int
aErrorCode
,
MARKER_PCB
*
fillMe
)
{
wxString
textA
=
aArea
->
GetSelectMenuText
();
wxPoint
posA
=
aPos
;
if
(
fillMe
)
fillMe
->
SetData
(
aErrorCode
,
posA
,
textA
,
posA
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
posA
,
textA
,
posA
);
return
fillMe
;
}
MARKER_PCB
*
DRC
::
fillMarker
(
int
aErrorCode
,
const
wxString
&
aMessage
,
MARKER_PCB
*
fillMe
)
{
wxPoint
posA
;
// not displayed
if
(
fillMe
)
fillMe
->
SetData
(
aErrorCode
,
posA
,
aMessage
,
posA
);
else
fillMe
=
new
MARKER_PCB
(
aErrorCode
,
posA
,
aMessage
,
posA
);
fillMe
->
SetShowNoCoordinate
();
return
fillMe
;
}
pcbnew/menubar_pcbframe.cpp
View file @
8db19bbd
...
...
@@ -44,11 +44,11 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
filesMenu
->
Append
(
item
);
// Open
item
=
new
wxMenuItem
(
filesMenu
,
ID_LOAD_FILE
,
_
(
"&Open
\t
Ctrl+O"
),
_
(
"Delete current board and load new board"
)
);
SET_BITMAP
(
KiBitmap
(
open_document_xpm
)
);
filesMenu
->
Append
(
item
);
text
=
AddHotkeyName
(
_
(
"&Open"
),
g_Board_Editor_Hokeys_Descr
,
HK_LOAD_BOARD
);
AddMenuItem
(
filesMenu
,
ID_LOAD_FILE
,
text
,
_
(
"Delete current board and load new board"
),
KiBitmap
(
open_document_xpm
)
);
// Load Recent submenu
static
wxMenu
*
openRecentMenu
;
...
...
@@ -78,11 +78,11 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
filesMenu
->
AppendSeparator
();
// Save
item
=
new
wxMenuItem
(
filesMenu
,
ID_SAVE_BOARD
,
_
(
"&Save
\t
Ctrl+S"
),
_
(
"Save current board"
)
);
SET_BITMAP
(
KiBitmap
(
save_xpm
)
);
filesMenu
->
Append
(
item
);
text
=
AddHotkeyName
(
_
(
"&Save"
),
g_Board_Editor_Hokeys_Descr
,
HK_SAVE_BOARD
);
AddMenuItem
(
filesMenu
,
ID_SAVE_BOARD
,
text
,
_
(
"Save current board"
),
KiBitmap
(
save_xpm
)
);
// Save As
item
=
new
wxMenuItem
(
filesMenu
,
ID_SAVE_BOARD_AS
,
...
...
@@ -204,7 +204,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
// Print
item
=
new
wxMenuItem
(
filesMenu
,
wxID_PRINT
,
_
(
"&Print
\t
Ctrl+P
"
),
_
(
"&Print"
),
_
(
"Print board"
)
);
SET_BITMAP
(
KiBitmap
(
print_button_xpm
)
);
filesMenu
->
Append
(
item
);
...
...
@@ -336,20 +336,23 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
* for Zoom in and Zoom out sub menus
*/
// Zoom In
text
=
AddHotkeyName
(
_
(
"Zoom In"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ZOOM_IN
,
false
);
text
=
AddHotkeyName
(
_
(
"Zoom In"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ZOOM_IN
,
IS_ACCELERATOR
);
item
=
new
wxMenuItem
(
viewMenu
,
ID_ZOOM_IN
,
text
,
HELP_ZOOM_IN
,
wxITEM_NORMAL
);
SET_BITMAP
(
KiBitmap
(
zoom_in_xpm
)
);
viewMenu
->
Append
(
item
);
// Zoom Out
text
=
AddHotkeyName
(
_
(
"Zoom Out"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ZOOM_OUT
,
false
);
text
=
AddHotkeyName
(
_
(
"Zoom Out"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ZOOM_OUT
,
IS_ACCELERATOR
);
item
=
new
wxMenuItem
(
viewMenu
,
ID_ZOOM_OUT
,
text
,
HELP_ZOOM_OUT
,
wxITEM_NORMAL
);
SET_BITMAP
(
KiBitmap
(
zoom_out_xpm
)
);
viewMenu
->
Append
(
item
);
// Fit on Screen
text
=
AddHotkeyName
(
_
(
"Fit on Screen"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ZOOM_AUTO
);
text
=
AddHotkeyName
(
_
(
"Fit on Screen"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ZOOM_AUTO
);
item
=
new
wxMenuItem
(
viewMenu
,
ID_ZOOM_PAGE
,
text
,
HELP_ZOOM_FIT
,
wxITEM_NORMAL
);
SET_BITMAP
(
KiBitmap
(
zoom_fit_in_page_xpm
)
);
...
...
@@ -361,8 +364,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
text
=
AddHotkeyName
(
_
(
"Redraw"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ZOOM_REDRAW
);
item
=
new
wxMenuItem
(
viewMenu
,
ID_ZOOM_REDRAW
,
text
,
HELP_ZOOM_REDRAW
,
wxITEM_NORMAL
);
HELP_ZOOM_REDRAW
,
wxITEM_NORMAL
);
SET_BITMAP
(
KiBitmap
(
zoom_redraw_xpm
)
);
viewMenu
->
Append
(
item
);
viewMenu
->
AppendSeparator
();
...
...
@@ -387,7 +389,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
wxMenu
*
placeMenu
=
new
wxMenu
;
// Module
text
=
AddHotkeyName
(
_
(
"Module"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ADD_MODULE
,
false
);
text
=
AddHotkeyName
(
_
(
"Module"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ADD_MODULE
,
IS_ACCELERATOR
);
item
=
new
wxMenuItem
(
placeMenu
,
ID_PCB_MODULE_BUTT
,
text
,
_
(
"Add modules"
),
wxITEM_NORMAL
);
...
...
@@ -395,7 +397,7 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
placeMenu
->
Append
(
item
);
// Track
text
=
AddHotkeyName
(
_
(
"Track"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ADD_NEW_TRACK
,
false
);
text
=
AddHotkeyName
(
_
(
"Track"
),
g_Pcbnew_Editor_Hokeys_Descr
,
HK_ADD_NEW_TRACK
,
IS_ACCELERATOR
);
item
=
new
wxMenuItem
(
placeMenu
,
ID_TRACK_BUTT
,
text
,
_
(
"Add tracks and vias"
),
wxITEM_NORMAL
);
...
...
pcbnew/tool_modedit.cpp
View file @
8db19bbd
...
...
@@ -87,16 +87,16 @@ void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar()
_
(
"Print module"
)
);
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
_
(
"Zoom in"
),
g_Module_Editor_Hokeys_Descr
,
HK_ZOOM_IN
,
false
);
msg
=
AddHotkeyName
(
_
(
"Zoom in"
),
g_Module_Editor_Hokeys_Descr
,
HK_ZOOM_IN
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_IN
,
wxEmptyString
,
KiBitmap
(
zoom_in_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Zoom out"
),
g_Module_Editor_Hokeys_Descr
,
HK_ZOOM_OUT
,
false
);
msg
=
AddHotkeyName
(
_
(
"Zoom out"
),
g_Module_Editor_Hokeys_Descr
,
HK_ZOOM_OUT
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_OUT
,
wxEmptyString
,
KiBitmap
(
zoom_out_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Redraw view"
),
g_Module_Editor_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
false
);
msg
=
AddHotkeyName
(
_
(
"Redraw view"
),
g_Module_Editor_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_REDRAW
,
wxEmptyString
,
KiBitmap
(
zoom_redraw_xpm
),
msg
);
msg
=
AddHotkeyName
(
_
(
"Zoom auto"
),
g_Module_Editor_Hokeys_Descr
,
HK_ZOOM_AUTO
,
false
);
msg
=
AddHotkeyName
(
_
(
"Zoom auto"
),
g_Module_Editor_Hokeys_Descr
,
HK_ZOOM_AUTO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_PAGE
,
wxEmptyString
,
KiBitmap
(
zoom_fit_in_page_xpm
),
msg
);
m_HToolBar
->
AddSeparator
();
...
...
pcbnew/tool_pcb.cpp
View file @
8db19bbd
...
...
@@ -217,9 +217,9 @@ void PCB_EDIT_FRAME::ReCreateHToolbar()
#endif
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
HELP_UNDO
,
g_Board_Editor_Hokeys_Descr
,
HK_UNDO
,
false
);
msg
=
AddHotkeyName
(
HELP_UNDO
,
g_Board_Editor_Hokeys_Descr
,
HK_UNDO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
wxID_UNDO
,
wxEmptyString
,
KiBitmap
(
undo_xpm
),
HELP_UNDO
);
msg
=
AddHotkeyName
(
HELP_REDO
,
g_Board_Editor_Hokeys_Descr
,
HK_REDO
,
false
);
msg
=
AddHotkeyName
(
HELP_REDO
,
g_Board_Editor_Hokeys_Descr
,
HK_REDO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
wxID_REDO
,
wxEmptyString
,
KiBitmap
(
redo_xpm
),
HELP_REDO
);
m_HToolBar
->
AddSeparator
();
...
...
@@ -229,20 +229,20 @@ void PCB_EDIT_FRAME::ReCreateHToolbar()
_
(
"Plot (HPGL, PostScript, or GERBER format)"
)
);
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
HELP_ZOOM_IN
,
g_Board_Editor_Hokeys_Descr
,
HK_ZOOM_IN
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_IN
,
g_Board_Editor_Hokeys_Descr
,
HK_ZOOM_IN
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_IN
,
wxEmptyString
,
KiBitmap
(
zoom_in_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_OUT
,
g_Board_Editor_Hokeys_Descr
,
HK_ZOOM_OUT
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_OUT
,
g_Board_Editor_Hokeys_Descr
,
HK_ZOOM_OUT
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_OUT
,
wxEmptyString
,
KiBitmap
(
zoom_out_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_REDRAW
,
g_Board_Editor_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_REDRAW
,
g_Board_Editor_Hokeys_Descr
,
HK_ZOOM_REDRAW
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_REDRAW
,
wxEmptyString
,
KiBitmap
(
zoom_redraw_xpm
),
msg
);
msg
=
AddHotkeyName
(
HELP_ZOOM_FIT
,
g_Board_Editor_Hokeys_Descr
,
HK_ZOOM_AUTO
,
false
);
msg
=
AddHotkeyName
(
HELP_ZOOM_FIT
,
g_Board_Editor_Hokeys_Descr
,
HK_ZOOM_AUTO
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_ZOOM_PAGE
,
wxEmptyString
,
KiBitmap
(
zoom_fit_in_page_xpm
),
msg
);
m_HToolBar
->
AddSeparator
();
msg
=
AddHotkeyName
(
HELP_FIND
,
g_Board_Editor_Hokeys_Descr
,
HK_FIND_ITEM
,
false
);
msg
=
AddHotkeyName
(
HELP_FIND
,
g_Board_Editor_Hokeys_Descr
,
HK_FIND_ITEM
,
IS_COMMENT
);
m_HToolBar
->
AddTool
(
ID_FIND_ITEMS
,
wxEmptyString
,
KiBitmap
(
find_xpm
),
msg
);
m_HToolBar
->
AddSeparator
();
...
...
pcbnew/zones_convert_to_polygons_aux_functions.cpp
View file @
8db19bbd
/**
* @file zones_convert_to_polygons_aux_functions.cpp
*/
#include "fctsys.h"
#include "polygons_defs.h"
#include "PolyLine.h"
#include "wxPcbStruct.h"
#include "trigo.h"
#include "class_board.h"
#include "class_module.h"
#include "class_zone.h"
#include "pcbnew.h"
#include "zones.h"
/**
* Function BuildUnconnectedThermalStubsPolygonList
* Creates a set of polygons corresponding to stubs created by thermal shapes on pads
* which are not connected to a zone (dangling bridges)
* @param aCornerBuffer = a std::vector<CPolyPt> where to store polygons
* @param aPcb = the board.
* @param aZone = a pointer to the ZONE_CONTAINER to examine.
* @param aArcCorrection = a pointer to the ZONE_CONTAINER to examine.
* @param aRoundPadThermalRotation = the rotation in 1.0 degree for thermal stubs in round pads
*/
void
BuildUnconnectedThermalStubsPolygonList
(
std
::
vector
<
CPolyPt
>&
aCornerBuffer
,
BOARD
*
aPcb
,
ZONE_CONTAINER
*
aZone
,
double
aArcCorrection
,
int
aRoundPadThermalRotation
)
{
std
::
vector
<
wxPoint
>
corners_buffer
;
// a local polygon buffer to store one stub
corners_buffer
.
reserve
(
4
);
wxPoint
ptTest
[
4
];
int
zone_clearance
=
aZone
->
m_ZoneClearance
;
EDA_RECT
item_boundingbox
;
EDA_RECT
zone_boundingbox
=
aZone
->
GetBoundingBox
();
int
biggest_clearance
=
aPcb
->
GetBiggestClearanceValue
();
biggest_clearance
=
MAX
(
biggest_clearance
,
zone_clearance
);
zone_boundingbox
.
Inflate
(
biggest_clearance
);
// half size of the pen used to draw/plot zones outlines
int
pen_radius
=
aZone
->
m_ZoneMinThickness
/
2
;
// Calculate thermal bridge half width
int
thermbridgeWidth
=
aZone
->
m_ThermalReliefCopperBridgeValue
/
2
;
for
(
MODULE
*
module
=
aPcb
->
m_Modules
;
module
;
module
=
module
->
Next
()
)
{
for
(
D_PAD
*
pad
=
module
->
m_Pads
;
pad
!=
NULL
;
pad
=
pad
->
Next
()
)
{
// check
if
(
!
pad
->
IsOnLayer
(
aZone
->
GetLayer
()
)
)
continue
;
if
(
pad
->
GetNet
()
!=
aZone
->
GetNet
()
)
continue
;
item_boundingbox
=
pad
->
GetBoundingBox
();
item_boundingbox
.
Inflate
(
aZone
->
m_ThermalReliefGapValue
);
if
(
!
(
item_boundingbox
.
Intersects
(
zone_boundingbox
)
)
)
continue
;
// Thermal bridges are like a segment from a starting point inside the pad
// to an ending point outside the pad
wxPoint
startpoint
,
endpoint
;
endpoint
.
x
=
(
pad
->
m_Size
.
x
/
2
)
+
aZone
->
m_ThermalReliefGapValue
;
endpoint
.
y
=
(
pad
->
m_Size
.
y
/
2
)
+
aZone
->
m_ThermalReliefGapValue
;
int
copperThickness
=
aZone
->
m_ThermalReliefCopperBridgeValue
-
aZone
->
m_ZoneMinThickness
;
if
(
copperThickness
<
0
)
copperThickness
=
0
;
startpoint
.
x
=
min
(
pad
->
m_Size
.
x
,
copperThickness
);
startpoint
.
y
=
min
(
pad
->
m_Size
.
y
,
copperThickness
);
startpoint
.
x
/=
2
;
startpoint
.
y
/=
2
;
// This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg)
int
fAngle
=
pad
->
m_Orient
;
if
(
pad
->
m_PadShape
==
PAD_CIRCLE
)
{
endpoint
.
x
=
(
int
)
(
endpoint
.
x
*
aArcCorrection
);
endpoint
.
y
=
endpoint
.
x
;
fAngle
=
aRoundPadThermalRotation
;
}
// contour line width has to be taken into calculation to avoid "thermal stub bleed"
endpoint
.
x
+=
pen_radius
;
endpoint
.
y
+=
pen_radius
;
// compute north, south, west and east points for zone connection.
ptTest
[
0
]
=
wxPoint
(
0
,
endpoint
.
y
);
// lower point
ptTest
[
1
]
=
wxPoint
(
0
,
-
endpoint
.
y
);
// upper point
ptTest
[
2
]
=
wxPoint
(
endpoint
.
x
,
0
);
// right point
ptTest
[
3
]
=
wxPoint
(
-
endpoint
.
x
,
0
);
// left point
// Test all sides
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
// rotate point
RotatePoint
(
&
ptTest
[
i
],
fAngle
);
// translate point
ptTest
[
i
]
+=
pad
->
ReturnShapePos
();
if
(
aZone
->
HitTestFilledArea
(
ptTest
[
i
]
)
)
continue
;
corners_buffer
.
clear
();
// polygons are rectangles with width of copper bridge value
switch
(
i
)
{
case
0
:
// lower stub
corners_buffer
.
push_back
(
wxPoint
(
-
thermbridgeWidth
,
endpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
thermbridgeWidth
,
endpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
thermbridgeWidth
,
startpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
thermbridgeWidth
,
startpoint
.
y
)
);
break
;
case
1
:
// upper stub
corners_buffer
.
push_back
(
wxPoint
(
-
thermbridgeWidth
,
-
endpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
thermbridgeWidth
,
-
endpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
thermbridgeWidth
,
-
startpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
thermbridgeWidth
,
-
startpoint
.
y
)
);
break
;
case
2
:
// right stub
corners_buffer
.
push_back
(
wxPoint
(
endpoint
.
x
,
-
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
endpoint
.
x
,
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
startpoint
.
x
,
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
startpoint
.
x
,
-
thermbridgeWidth
)
);
break
;
case
3
:
// left stub
corners_buffer
.
push_back
(
wxPoint
(
-
endpoint
.
x
,
-
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
endpoint
.
x
,
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
startpoint
.
x
,
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
startpoint
.
x
,
-
thermbridgeWidth
)
);
break
;
}
// add computed polygon to list
for
(
unsigned
ic
=
0
;
ic
<
corners_buffer
.
size
();
ic
++
)
{
wxPoint
cpos
=
corners_buffer
[
ic
];
RotatePoint
(
&
cpos
,
fAngle
);
// Rotate according to module orientation
cpos
+=
pad
->
ReturnShapePos
();
// Shift origin to position
CPolyPt
corner
;
corner
.
x
=
cpos
.
x
;
corner
.
y
=
cpos
.
y
;
corner
.
end_contour
=
(
ic
<
(
corners_buffer
.
size
()
-
1
)
)
?
0
:
1
;
aCornerBuffer
.
push_back
(
corner
);
}
}
}
}
}
/**
* @file zones_convert_to_polygons_aux_functions.cpp
*/
#include "fctsys.h"
#include "polygons_defs.h"
#include "PolyLine.h"
#include "wxPcbStruct.h"
#include "trigo.h"
#include "class_board.h"
#include "class_module.h"
#include "class_zone.h"
#include "pcbnew.h"
#include "zones.h"
/**
* Function BuildUnconnectedThermalStubsPolygonList
* Creates a set of polygons corresponding to stubs created by thermal shapes on pads
* which are not connected to a zone (dangling bridges)
* @param aCornerBuffer = a std::vector<CPolyPt> where to store polygons
* @param aPcb = the board.
* @param aZone = a pointer to the ZONE_CONTAINER to examine.
* @param aArcCorrection = a pointer to the ZONE_CONTAINER to examine.
* @param aRoundPadThermalRotation = the rotation in 1.0 degree for thermal stubs in round pads
*/
void
BuildUnconnectedThermalStubsPolygonList
(
std
::
vector
<
CPolyPt
>&
aCornerBuffer
,
BOARD
*
aPcb
,
ZONE_CONTAINER
*
aZone
,
double
aArcCorrection
,
int
aRoundPadThermalRotation
)
{
std
::
vector
<
wxPoint
>
corners_buffer
;
// a local polygon buffer to store one stub
corners_buffer
.
reserve
(
4
);
wxPoint
ptTest
[
4
];
int
zone_clearance
=
aZone
->
m_ZoneClearance
;
EDA_RECT
item_boundingbox
;
EDA_RECT
zone_boundingbox
=
aZone
->
GetBoundingBox
();
int
biggest_clearance
=
aPcb
->
GetBiggestClearanceValue
();
biggest_clearance
=
MAX
(
biggest_clearance
,
zone_clearance
);
zone_boundingbox
.
Inflate
(
biggest_clearance
);
// half size of the pen used to draw/plot zones outlines
int
pen_radius
=
aZone
->
m_ZoneMinThickness
/
2
;
// Calculate thermal bridge half width
int
thermbridgeWidth
=
aZone
->
m_ThermalReliefCopperBridgeValue
/
2
;
for
(
MODULE
*
module
=
aPcb
->
m_Modules
;
module
;
module
=
module
->
Next
()
)
{
for
(
D_PAD
*
pad
=
module
->
m_Pads
;
pad
!=
NULL
;
pad
=
pad
->
Next
()
)
{
// check
if
(
!
pad
->
IsOnLayer
(
aZone
->
GetLayer
()
)
)
continue
;
if
(
pad
->
GetNet
()
!=
aZone
->
GetNet
()
)
continue
;
item_boundingbox
=
pad
->
GetBoundingBox
();
item_boundingbox
.
Inflate
(
aZone
->
m_ThermalReliefGapValue
);
if
(
!
(
item_boundingbox
.
Intersects
(
zone_boundingbox
)
)
)
continue
;
// Thermal bridges are like a segment from a starting point inside the pad
// to an ending point outside the pad
wxPoint
startpoint
,
endpoint
;
endpoint
.
x
=
(
pad
->
m_Size
.
x
/
2
)
+
aZone
->
m_ThermalReliefGapValue
;
endpoint
.
y
=
(
pad
->
m_Size
.
y
/
2
)
+
aZone
->
m_ThermalReliefGapValue
;
int
copperThickness
=
aZone
->
m_ThermalReliefCopperBridgeValue
-
aZone
->
m_ZoneMinThickness
;
if
(
copperThickness
<
0
)
copperThickness
=
0
;
startpoint
.
x
=
min
(
pad
->
m_Size
.
x
,
copperThickness
);
startpoint
.
y
=
min
(
pad
->
m_Size
.
y
,
copperThickness
);
startpoint
.
x
/=
2
;
startpoint
.
y
/=
2
;
// This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg)
int
fAngle
=
pad
->
m_Orient
;
if
(
pad
->
m_PadShape
==
PAD_CIRCLE
)
{
endpoint
.
x
=
(
int
)
(
endpoint
.
x
*
aArcCorrection
);
endpoint
.
y
=
endpoint
.
x
;
fAngle
=
aRoundPadThermalRotation
;
}
// contour line width has to be taken into calculation to avoid "thermal stub bleed"
endpoint
.
x
+=
pen_radius
;
endpoint
.
y
+=
pen_radius
;
// compute north, south, west and east points for zone connection.
ptTest
[
0
]
=
wxPoint
(
0
,
endpoint
.
y
);
// lower point
ptTest
[
1
]
=
wxPoint
(
0
,
-
endpoint
.
y
);
// upper point
ptTest
[
2
]
=
wxPoint
(
endpoint
.
x
,
0
);
// right point
ptTest
[
3
]
=
wxPoint
(
-
endpoint
.
x
,
0
);
// left point
// Test all sides
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
// rotate point
RotatePoint
(
&
ptTest
[
i
],
fAngle
);
// translate point
ptTest
[
i
]
+=
pad
->
ReturnShapePos
();
if
(
aZone
->
HitTestFilledArea
(
ptTest
[
i
]
)
)
continue
;
corners_buffer
.
clear
();
// polygons are rectangles with width of copper bridge value
switch
(
i
)
{
case
0
:
// lower stub
corners_buffer
.
push_back
(
wxPoint
(
-
thermbridgeWidth
,
endpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
thermbridgeWidth
,
endpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
thermbridgeWidth
,
startpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
thermbridgeWidth
,
startpoint
.
y
)
);
break
;
case
1
:
// upper stub
corners_buffer
.
push_back
(
wxPoint
(
-
thermbridgeWidth
,
-
endpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
thermbridgeWidth
,
-
endpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
thermbridgeWidth
,
-
startpoint
.
y
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
thermbridgeWidth
,
-
startpoint
.
y
)
);
break
;
case
2
:
// right stub
corners_buffer
.
push_back
(
wxPoint
(
endpoint
.
x
,
-
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
endpoint
.
x
,
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
startpoint
.
x
,
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
+
startpoint
.
x
,
-
thermbridgeWidth
)
);
break
;
case
3
:
// left stub
corners_buffer
.
push_back
(
wxPoint
(
-
endpoint
.
x
,
-
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
endpoint
.
x
,
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
startpoint
.
x
,
thermbridgeWidth
)
);
corners_buffer
.
push_back
(
wxPoint
(
-
startpoint
.
x
,
-
thermbridgeWidth
)
);
break
;
}
// add computed polygon to list
for
(
unsigned
ic
=
0
;
ic
<
corners_buffer
.
size
();
ic
++
)
{
wxPoint
cpos
=
corners_buffer
[
ic
];
RotatePoint
(
&
cpos
,
fAngle
);
// Rotate according to module orientation
cpos
+=
pad
->
ReturnShapePos
();
// Shift origin to position
CPolyPt
corner
;
corner
.
x
=
cpos
.
x
;
corner
.
y
=
cpos
.
y
;
corner
.
end_contour
=
(
ic
<
(
corners_buffer
.
size
()
-
1
)
)
?
0
:
1
;
aCornerBuffer
.
push_back
(
corner
);
}
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment