kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #21491
Re: eeschema field placement feature branch question
Thanks, Wayne.
I'm not sure if the original patch would apply anyway, it's been quite a while. Here's a new one. Not sure if you would want to merge it as a single patch (it's a bit long, about 2k lines), or if you'd rather I split it. I can split it into at least two patches: one to add the manual command, and one that ties it into placement so the labels move as you place parts. Let me know what you think about that.
As for the options - personally, I think the options in general really should be rearranged a bit _anyway_, and I've been considering poking the mailing list about that. I started a proof of concept branch for a more organized system a while ago but it didn't go very far as I ran out of time. I should have another stretch of development time starting in a few weeks, though. I could rearrange the options a bit for this patch, but I figured I should bring that up, since it wouldn't make much sense to rearrange them twice. Maybe we could just leave them as is for now, and rearrange them more thoughtfully a bit later?
My options idea was to make a more centralized configuration tool, the way most other EDA tools have, with a tree of categories, rather like this example from Altera Quartus: https://misc.c4757p.com/quartus_options.png . Personally I'd much rather that than the current situation with a whole bunch of specialized dialogs with like four options each. Any thoughts on /that/?
I don't think my code touches SCH_SHEET_PATH and SCH_SHEET_LIST, though I don't have a chance immediately to look through your branch and see whether mine will merge freely. It does touch SCH_SCREEN. I can look into that in a few days if you'd like.
On Wed, Dec 02, 2015 at 09:09:37AM -0500, Wayne Stambaugh wrote:
> Chris,
>
> I cannot find the original request for this patch. I do like the
> feature. Since I don't have the patch or a url to your branch, I cannot
> review the code. From the video, I have one minor suggestion. It looks
> like you added 3 new check boxes to the Eeschema options dialog which
> makes it even taller than it already is. Maybe it's time to add a third
> tab and move some of the controls in the "General Options" tab to a new
> tab. I'm not sure what to call the new tab and how to group the
> controls but it's something that should be done. Anyone else have any
> objections or comments about this feature?
>
> As for my Eeschema work, you can see what I've done so far at:
>
> https://github.com/stambaughw/kicad-eeschema-refactor
>
> If your code involves anything with SCH_SHEET_PATH and SCH_SHEET_LIST,
> there will be conflicts as these two objects are going away and their
> functionality moved into the SCH_SHEET object. I'm almost have this
> step completed. SCH_SCREENS is also going to be removed shortly. After
> that, I will rename SCH_SCREEN to SCH_SCHEMATIC and make SCH_SCREEN a
> separate object that is used only to store the current sheet display
> settings. The final step is to create a top level object (SCHEMATIC?)
> to act as a container for the entire schematic hierarchy any schematic
> settings (analogous to the BOARD object in Pcbnew).
>
> Cheers,
>
> Wayne
>
> On 12/1/2015 9:23 PM, Chris Pavlina wrote:
> > This is mostly directed at Wayne, since he's working on eeschema.
> >
> > I have a feature branch I worked on over the summer (back when the release was thought to be closer, and the eeschema rework farther) that implements a field (reference/value) autoplacement on symbols in eeschema. It moves and aligns the fields as you place parts to allow a minimum of manual placement, including some heuristics to avoid overlaps. I've found this to be a _major_ time saver when working on complicated schematics. A preview is here: https://www.youtube.com/watch?v=32FKnrKxe4Y
> >
> > Is there any willingness to include this? As far as I can tell, the eeschema work is already somewhat underway, though I don't know to what extent. I'll happily rework my code to fit into the new eeschema code, though it'd be really nice if I could see how the eeschema work is coming along and refactor my own code in parallel. I've been using this since I developed it in July, so it's pretty well tested, and I've kept that branch up to date with respect to the latest code. If accepted, I will happily maintain it through the transition to GAL as well.
> >
> > --
> > Chris
> >
> >
> > _______________________________________________
> > Mailing list: https://launchpad.net/~kicad-developers
> > Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
> > Unsubscribe : https://launchpad.net/~kicad-developers
> > More help : https://help.launchpad.net/ListHelp
> >
>
> _______________________________________________
> Mailing list: https://launchpad.net/~kicad-developers
> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~kicad-developers
> More help : https://help.launchpad.net/ListHelp
diff --git a/bitmaps_png/CMakeLists.txt b/bitmaps_png/CMakeLists.txt
index 7067585..1053e13 100644
--- a/bitmaps_png/CMakeLists.txt
+++ b/bitmaps_png/CMakeLists.txt
@@ -160,6 +160,7 @@ set( BMAPS_MID
auto_associe
auto_delete_track
auto_track_width
+ autoplace_fields
axis3d_back
axis3d_bottom
axis3d_front
diff --git a/bitmaps_png/cpp_26/autoplace_fields.cpp b/bitmaps_png/cpp_26/autoplace_fields.cpp
new file mode 100644
index 0000000..dda674b
--- /dev/null
+++ b/bitmaps_png/cpp_26/autoplace_fields.cpp
@@ -0,0 +1,79 @@
+
+/* Do not modify this file, it was automatically generated by the
+ * PNG2cpp CMake script, using a *.png file as input.
+ */
+
+#include <bitmaps.h>
+
+static const unsigned char png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+ 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c,
+ 0xce, 0x00, 0x00, 0x03, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xb5, 0x95, 0x5b, 0x4c, 0x1c,
+ 0x55, 0x18, 0xc7, 0x17, 0x86, 0x65, 0x59, 0x96, 0xe5, 0xb6, 0x96, 0x94, 0x70, 0x09, 0x5a, 0x1e,
+ 0xec, 0x83, 0x24, 0x0a, 0x18, 0xa5, 0xd4, 0x27, 0x6d, 0xc0, 0x5b, 0x63, 0x43, 0x13, 0x1a, 0x23,
+ 0xd1, 0x90, 0xa6, 0x11, 0x1e, 0x2a, 0x0f, 0x5a, 0x48, 0x37, 0xb0, 0x4b, 0x40, 0x36, 0x43, 0x9b,
+ 0x46, 0xc1, 0xe0, 0x72, 0xe9, 0x83, 0xc5, 0x18, 0x78, 0x30, 0x36, 0x28, 0x89, 0xed, 0x43, 0xfb,
+ 0xd2, 0x9a, 0x1a, 0x74, 0x37, 0x69, 0x6d, 0x61, 0x4b, 0x69, 0xa1, 0x5c, 0xbb, 0x4b, 0x8a, 0x54,
+ 0xd7, 0x86, 0x86, 0xfe, 0xfd, 0x9f, 0x99, 0xb3, 0x66, 0x84, 0x96, 0xd4, 0xb8, 0x7b, 0x92, 0x5f,
+ 0x32, 0x33, 0x67, 0xe6, 0xfc, 0xce, 0xf9, 0xbe, 0xef, 0x9c, 0x31, 0x99, 0xfe, 0x7b, 0xeb, 0x24,
+ 0x35, 0xc4, 0x4e, 0x86, 0xc9, 0x0b, 0xe4, 0x25, 0x79, 0x2d, 0x70, 0x93, 0x78, 0x53, 0x14, 0x9a,
+ 0x9f, 0x1c, 0x27, 0x0e, 0x02, 0xf2, 0x26, 0x29, 0x26, 0x5e, 0xc9, 0x6f, 0xa4, 0x2b, 0x56, 0xa2,
+ 0x44, 0x92, 0x21, 0x19, 0x20, 0x17, 0x63, 0x25, 0xda, 0x2f, 0xaf, 0x05, 0x2b, 0x64, 0x57, 0x34,
+ 0x44, 0x2d, 0x64, 0x51, 0x0a, 0xa7, 0x48, 0x8e, 0x41, 0xb4, 0x4b, 0xde, 0x47, 0xad, 0x7d, 0x40,
+ 0x3a, 0x0c, 0x83, 0x3e, 0x47, 0x3c, 0xc4, 0xfc, 0x24, 0x1f, 0xd7, 0x3f, 0xe6, 0xc5, 0x83, 0x86,
+ 0x44, 0x3b, 0x49, 0x25, 0x69, 0x95, 0x7d, 0x75, 0x52, 0x9a, 0x46, 0xbe, 0x94, 0xef, 0x08, 0xe9,
+ 0xeb, 0x86, 0x6f, 0xde, 0xdb, 0x38, 0x60, 0xd0, 0x6c, 0x36, 0x07, 0x12, 0x12, 0x12, 0x36, 0xc6,
+ 0xf7, 0x23, 0x59, 0xb6, 0x33, 0xe4, 0x27, 0xe2, 0x22, 0xb3, 0xb2, 0xef, 0x47, 0xd9, 0xd7, 0x5c,
+ 0x58, 0x58, 0x88, 0x92, 0x92, 0x12, 0x11, 0xbe, 0x33, 0x64, 0x9f, 0x7c, 0x3e, 0x46, 0xd6, 0x37,
+ 0x89, 0x28, 0x41, 0x5c, 0x5c, 0x1c, 0xd2, 0xd3, 0xd3, 0xbf, 0xe7, 0x7d, 0xa6, 0xa1, 0x6f, 0x9b,
+ 0x4c, 0xf2, 0xbb, 0x52, 0xf4, 0x17, 0xf9, 0x8e, 0x2c, 0xc9, 0x01, 0x4f, 0xcd, 0xce, 0xce, 0x62,
+ 0x6d, 0x6d, 0x0d, 0x79, 0x79, 0x79, 0x01, 0xf9, 0x8d, 0x42, 0xbe, 0x26, 0x67, 0x37, 0x89, 0xda,
+ 0xda, 0xda, 0x71, 0xe2, 0xc4, 0x67, 0xb0, 0xdb, 0xed, 0x48, 0x4a, 0x4a, 0xfa, 0x33, 0x39, 0x39,
+ 0xf9, 0xa0, 0xec, 0xeb, 0x26, 0x3e, 0xb9, 0x11, 0x45, 0xe8, 0x3e, 0x97, 0x4c, 0x4b, 0xd1, 0x57,
+ 0xe3, 0xe3, 0xe3, 0x58, 0x5d, 0x5d, 0x45, 0x76, 0x76, 0xf6, 0x04, 0xef, 0x2d, 0x64, 0x88, 0x7c,
+ 0x4b, 0x92, 0x36, 0x89, 0x3c, 0x1e, 0x15, 0xf7, 0xef, 0x03, 0x93, 0x93, 0x73, 0x38, 0x70, 0xa0,
+ 0x46, 0x5b, 0x1d, 0xa5, 0xa2, 0xba, 0x1e, 0x90, 0x57, 0x1f, 0x91, 0xbf, 0x48, 0xe8, 0x3e, 0x76,
+ 0x38, 0x1c, 0xc8, 0xcd, 0xcd, 0x15, 0xa1, 0x3b, 0x25, 0xee, 0xc9, 0x43, 0xf2, 0x2b, 0xf9, 0x39,
+ 0xf2, 0xf2, 0x4e, 0x72, 0x8c, 0x84, 0x3a, 0x3a, 0x54, 0x84, 0xc3, 0xe0, 0xcc, 0x80, 0xbb, 0x77,
+ 0x81, 0xd3, 0xa7, 0xcf, 0xa3, 0xa0, 0x60, 0x07, 0xe2, 0xe3, 0xe3, 0xd7, 0x53, 0x53, 0x53, 0x5b,
+ 0x65, 0x38, 0x8c, 0x4d, 0x94, 0xf5, 0xdb, 0xc4, 0x4a, 0x3e, 0x21, 0x47, 0x48, 0x3e, 0x79, 0x59,
+ 0x5e, 0x1f, 0x91, 0xcf, 0xf9, 0x34, 0x3f, 0xff, 0x35, 0x9b, 0xcd, 0xe6, 0x57, 0x14, 0xe5, 0xf7,
+ 0xf6, 0x76, 0x15, 0xf7, 0xee, 0xe9, 0x92, 0x50, 0x08, 0x58, 0x5a, 0x02, 0xa6, 0xa7, 0x1f, 0xc0,
+ 0xe3, 0xf1, 0x22, 0x23, 0xc3, 0x01, 0xca, 0x66, 0x58, 0x30, 0x25, 0x52, 0x62, 0x95, 0xe7, 0xdc,
+ 0x33, 0x4f, 0xb4, 0x21, 0x7a, 0x7b, 0x7b, 0x2b, 0xfb, 0xfa, 0xfa, 0x90, 0x92, 0x92, 0x82, 0xb6,
+ 0x36, 0x15, 0x2b, 0x2b, 0xc0, 0xf2, 0xb2, 0x2e, 0x99, 0x9f, 0x07, 0x6e, 0xdf, 0x06, 0x6e, 0xde,
+ 0x04, 0xc6, 0xc6, 0x42, 0xa8, 0xa9, 0x39, 0x0c, 0x16, 0xcc, 0x43, 0x4e, 0xec, 0x07, 0x7e, 0x3a,
+ 0x6f, 0x38, 0x0d, 0xbe, 0x79, 0xc4, 0x6a, 0xff, 0xdd, 0x86, 0x87, 0x87, 0x95, 0xc1, 0xc1, 0xc1,
+ 0x54, 0xe6, 0x23, 0xd4, 0xda, 0xaa, 0x6a, 0x92, 0x3b, 0x77, 0x80, 0x85, 0x05, 0x5d, 0x72, 0xeb,
+ 0x16, 0x70, 0xe3, 0x06, 0x30, 0x31, 0x01, 0x5c, 0xbd, 0x0a, 0x0c, 0x0d, 0x8d, 0xc1, 0x66, 0xb3,
+ 0x63, 0xf7, 0xee, 0x57, 0xe0, 0xf7, 0x4f, 0xe3, 0xe4, 0xc9, 0x51, 0x28, 0x4a, 0x02, 0x4a, 0x4b,
+ 0x4b, 0x7d, 0x69, 0x69, 0x69, 0x55, 0xf2, 0x48, 0x7a, 0x6a, 0x2b, 0x67, 0xd0, 0xed, 0x56, 0x11,
+ 0x0c, 0xea, 0x12, 0x56, 0x2b, 0xc3, 0xa6, 0x4b, 0x02, 0x01, 0xe0, 0xda, 0x35, 0xe0, 0xf2, 0x65,
+ 0x70, 0x70, 0x20, 0x33, 0x33, 0x0b, 0x4e, 0xe7, 0xa7, 0x98, 0x9a, 0x02, 0x7c, 0x3e, 0x70, 0x3b,
+ 0x6c, 0x83, 0x61, 0x75, 0x82, 0x3d, 0x5b, 0x8a, 0x5a, 0x5a, 0x54, 0x2c, 0x2e, 0x02, 0x73, 0x73,
+ 0xba, 0x44, 0x0c, 0x74, 0xfd, 0xba, 0x2e, 0xb9, 0x72, 0x05, 0xb8, 0x74, 0x29, 0x8c, 0x43, 0x87,
+ 0x5c, 0x2c, 0x0e, 0x05, 0x59, 0x59, 0xd9, 0x68, 0x6a, 0xfa, 0x02, 0x7b, 0xf7, 0x7e, 0xa8, 0x55,
+ 0x67, 0x63, 0x63, 0x23, 0x98, 0x86, 0x30, 0x81, 0x48, 0x05, 0x19, 0xdc, 0x28, 0x10, 0xb1, 0x4d,
+ 0x11, 0xa2, 0xe6, 0x66, 0x55, 0x93, 0xcc, 0xcc, 0xe8, 0x79, 0x11, 0x12, 0x6e, 0x0f, 0x4d, 0xd2,
+ 0xd5, 0x35, 0x82, 0x9c, 0x9c, 0xa7, 0x29, 0xc8, 0x42, 0x7d, 0x7d, 0x3d, 0xca, 0xca, 0xca, 0xc4,
+ 0xc6, 0xe6, 0xb3, 0x1c, 0xd4, 0xd6, 0xd6, 0x6a, 0x83, 0xf7, 0xf7, 0xf7, 0x5f, 0x24, 0x6f, 0x49,
+ 0x9e, 0xdf, 0x28, 0x7a, 0x43, 0x2e, 0x77, 0xd9, 0xe9, 0x54, 0xff, 0x91, 0x4c, 0x4e, 0xea, 0x92,
+ 0xd1, 0xd1, 0x00, 0xca, 0xcb, 0x2b, 0x99, 0x07, 0x05, 0x15, 0x15, 0x15, 0xe8, 0xe9, 0xe9, 0x89,
+ 0xcc, 0xf8, 0x02, 0x39, 0x27, 0xaf, 0x05, 0x53, 0x64, 0xe7, 0x63, 0xe3, 0xd5, 0xd0, 0xd0, 0xb0,
+ 0xa7, 0xae, 0xae, 0xce, 0x67, 0xb5, 0x5a, 0xd7, 0x8e, 0x1e, 0x55, 0xb5, 0xe4, 0x0b, 0x89, 0xdf,
+ 0xff, 0x07, 0x67, 0xee, 0x42, 0x62, 0xa2, 0x05, 0xe2, 0x1c, 0x73, 0xbb, 0xdd, 0x91, 0x01, 0x57,
+ 0x18, 0x9e, 0xc3, 0x2e, 0x97, 0x4b, 0xfb, 0x5d, 0x7b, 0xbd, 0xde, 0x1d, 0x62, 0xf6, 0x2c, 0xaa,
+ 0xc4, 0x2d, 0xab, 0x4e, 0xcc, 0x82, 0x2f, 0x1e, 0xb7, 0x58, 0x2c, 0xe1, 0xa6, 0x26, 0x55, 0x4b,
+ 0xbe, 0xd7, 0x3b, 0x82, 0xed, 0xdb, 0xf3, 0xc0, 0x23, 0x08, 0xd5, 0xd5, 0xd5, 0x30, 0xc4, 0x7d,
+ 0x84, 0xe4, 0xfe, 0xdf, 0x7f, 0x4c, 0xb0, 0xaa, 0xea, 0x7d, 0x14, 0x17, 0x97, 0x6b, 0x95, 0x53,
+ 0x54, 0x54, 0x84, 0xce, 0xce, 0xce, 0x88, 0x60, 0x8e, 0xec, 0x8b, 0xd6, 0xcf, 0x2c, 0x28, 0x04,
+ 0x22, 0xc1, 0x0c, 0x65, 0x44, 0xb0, 0x4e, 0xbc, 0x03, 0x03, 0x03, 0xf6, 0x68, 0xfe, 0x35, 0x17,
+ 0xb8, 0x8a, 0x5f, 0xba, 0xbb, 0xbb, 0x35, 0x09, 0xc3, 0xe5, 0x67, 0x48, 0x5f, 0x34, 0xc5, 0xa0,
+ 0x3d, 0x4b, 0xc1, 0x31, 0x12, 0x26, 0x2e, 0x26, 0xd9, 0x6c, 0x8a, 0x55, 0xe3, 0x2a, 0xde, 0x61,
+ 0xf9, 0x16, 0xc4, 0x62, 0xec, 0xbf, 0x01, 0x96, 0xa8, 0x5c, 0xe1, 0x12, 0x7e, 0x2a, 0x61, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+};
+
+const BITMAP_OPAQUE autoplace_fields_xpm[1] = {{ png, sizeof( png ), "autoplace_fields_xpm" }};
+
+//EOF
diff --git a/bitmaps_png/sources/autoplace_fields.svg b/bitmaps_png/sources/autoplace_fields.svg
new file mode 100644
index 0000000..a7f6728
--- /dev/null
+++ b/bitmaps_png/sources/autoplace_fields.svg
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="48"
+ width="48"
+ version="1.1"
+ viewBox="0 0 48 48"
+ id="svg2"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="autoplace_fields.svg">
+ <metadata
+ id="metadata151">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1676"
+ inkscape:window-height="994"
+ id="namedview149"
+ showgrid="false"
+ inkscape:zoom="6.9532167"
+ inkscape:cx="19.533569"
+ inkscape:cy="26.564532"
+ inkscape:window-x="0"
+ inkscape:window-y="54"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg2" />
+ <defs
+ id="defs4">
+ <linearGradient
+ id="a">
+ <stop
+ stop-color="#fff"
+ offset="0"
+ id="stop7" />
+ <stop
+ stop-color="#babaff"
+ offset="1"
+ id="stop9" />
+ </linearGradient>
+ <linearGradient
+ id="j"
+ y2="10.441"
+ xlink:href="#a"
+ gradientUnits="userSpaceOnUse"
+ x2="12.136"
+ gradientTransform="matrix(2.2734557,0,0,2.6193664,-58.250764,5.4148976)"
+ y1="1.9828"
+ x1="3.4673" />
+ <linearGradient
+ id="b"
+ y2="7.8438"
+ xlink:href="#a"
+ gradientUnits="userSpaceOnUse"
+ x2="12.922"
+ y1="6.0625"
+ x1="11.078"
+ gradientTransform="matrix(2.5619,0,0,2.3244,-58.266136,5.4148976)" />
+ <linearGradient
+ id="k"
+ y2="14.691"
+ gradientUnits="userSpaceOnUse"
+ x2="30.432"
+ gradientTransform="translate(6.3922,12.185)"
+ y1="12.338"
+ x1="28.079">
+ <stop
+ stop-color="#fcaf3e"
+ offset="0"
+ id="stop14" />
+ <stop
+ stop-color="#ce5c00"
+ offset="1"
+ id="stop16" />
+ </linearGradient>
+ <linearGradient
+ id="l"
+ y2="22.119"
+ gradientUnits="userSpaceOnUse"
+ x2="22.81"
+ gradientTransform="translate(6.3922,12.185)"
+ y1="21.481"
+ x1="23.448">
+ <stop
+ stop-color="#ce5c00"
+ offset="0"
+ id="stop19" />
+ <stop
+ stop-color="#ce5c00"
+ offset="1"
+ id="stop21" />
+ </linearGradient>
+ <linearGradient
+ id="m"
+ y2="32.714"
+ gradientUnits="userSpaceOnUse"
+ x2="25.485"
+ y1="34.39"
+ x1="26.379">
+ <stop
+ stop-color="#e9b96e"
+ offset="0"
+ id="stop24" />
+ <stop
+ stop-color="#fff"
+ offset="1"
+ id="stop26" />
+ </linearGradient>
+ <radialGradient
+ id="p"
+ gradientUnits="userSpaceOnUse"
+ cy="128"
+ cx="-138.84"
+ gradientTransform="matrix(.35473 -.34328 .35696 .34544 130.15 -71.026)"
+ r="9.1267">
+ <stop
+ stop-color="#f9a9a9"
+ offset="0"
+ id="stop29" />
+ <stop
+ stop-color="#ab5f5f"
+ offset="1"
+ id="stop31" />
+ </radialGradient>
+ <linearGradient
+ id="n"
+ y2="134.25"
+ gradientUnits="userSpaceOnUse"
+ x2="-158.75"
+ gradientTransform="matrix(.20949 -.20274 .20949 .20274 129.28 -31.999)"
+ y1="115.94"
+ x1="-158.75">
+ <stop
+ stop-color="#ddd"
+ offset="0"
+ id="stop34" />
+ <stop
+ stop-color="#fff"
+ offset=".34468"
+ id="stop36" />
+ <stop
+ stop-color="#737373"
+ offset=".72695"
+ id="stop38" />
+ <stop
+ stop-color="#bbb"
+ offset="1"
+ id="stop40" />
+ </linearGradient>
+ <linearGradient
+ id="o"
+ y2="10.441"
+ xlink:href="#a"
+ gradientUnits="userSpaceOnUse"
+ x2="12.136"
+ gradientTransform="matrix(2.246184,0,0,2.7037,-1.2081619,11.548735)"
+ y1="1.9828"
+ x1="3.4673" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#a"
+ id="linearGradient3479"
+ gradientUnits="userSpaceOnUse"
+ x1="11.078"
+ y1="6.0625"
+ x2="12.922"
+ y2="7.8438"
+ gradientTransform="matrix(2.531196,0,0,2.3993,-1.2229579,11.548735)" />
+ </defs>
+ <g
+ id="g4323">
+ <g
+ transform="matrix(2.531196,0,0,2.3993,-13.87883,-17.842265)"
+ id="g107"
+ style="fill:#9b9b9b">
+ <path
+ d="m 8,13.25 0,14 10.5,-7 -10.5,-7 z"
+ id="path109"
+ inkscape:connector-curvature="0"
+ style="fill-rule:evenodd" />
+ <rect
+ y="17.25"
+ width="1.9942"
+ x="6.0057998"
+ height="1"
+ id="rect111" />
+ <rect
+ y="22.25"
+ width="2"
+ x="6"
+ height="1"
+ id="rect113" />
+ <path
+ d="m 14.5,6.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+ transform="matrix(1.3333,0,0,1.3333,0.66664,11.583)"
+ id="path115"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="19.75"
+ width="2.4942"
+ x="19.506001"
+ height="1"
+ id="rect117" />
+ </g>
+ <rect
+ transform="matrix(-1.754568e-7,1,-1,-4.4663889e-8,0,0)"
+ height="2.5311959"
+ width="2.3993001"
+ y="-8.9018316"
+ x="16.347736"
+ id="rect119"
+ style="fill:#ffffff" />
+ <path
+ d="m 3.8394341,11.548735 0,33.591 26.5766399,-16.795 -26.5766399,-16.796 z"
+ id="path121"
+ inkscape:connector-curvature="0"
+ style="fill-rule:evenodd" />
+ <rect
+ y="21.146734"
+ width="2.5311959"
+ x="1.3082383"
+ height="2.3993001"
+ id="rect123" />
+ <rect
+ y="33.143135"
+ width="2.5311959"
+ x="1.3082383"
+ height="2.3993001"
+ id="rect125" />
+ <path
+ d="m 6.3853181,16.347735 0,23.993 20.2499999,-11.996 -20.2499999,-11.997 z"
+ id="path127"
+ style="fill:url(#o);fill-rule:evenodd"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 34.213624,28.344885 a 5.062338,4.79865 0 0 1 -10.124676,0 5.062338,4.79865 0 1 1 10.124676,0 z"
+ id="path129"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 31.68259,28.343835 a 2.531196,2.3993 0 0 1 -5.062392,0 2.531196,2.3993 0 1 1 5.062392,0 z"
+ id="path131"
+ style="fill:url(#linearGradient3479)"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="27.144733"
+ width="6.3132482"
+ x="32.962929"
+ height="2.3993001"
+ id="rect133" />
+ <path
+ d="m 22.49337,0.60054242 0,7.19799968 2.531196,2.3992999 2.531196,0 2.531196,-2.3992999 0,-7.19799968 -2.531196,0 0,7.19799968 -2.531196,0 0,-7.19799968 -2.53152,0 z"
+ id="path135"
+ inkscape:connector-curvature="0"
+ style="fill-rule:evenodd" />
+ <path
+ d="m 32.61729,0.60054242 5.062392,0 2.531196,2.39929998 0,2.3993 -2.531196,2.3992997 -2.531196,0 0,2.3992999 -2.53044,0 0,-4.7986996 5.062392,0 0,-2.3993 -5.06196,0 0,-2.39929998 z"
+ id="path147"
+ inkscape:connector-curvature="0"
+ style="fill-rule:evenodd" />
+ <path
+ d="m 15.393889,11.860171 6.40475,0 0,2.3244 -3.84285,6.990866 -2.5619,0 3.84285,-6.9732 -3.84285,0 0,-2.342995 z"
+ id="path75"
+ inkscape:connector-curvature="0"
+ style="fill-rule:evenodd" />
+ <path
+ d="m 39.731939,11.860171 0,2.3244 3.84285,0 0,1.1622 -3.84285,3.4866 0,2.3244 6.40475,0 0,-2.3244 -3.84285,0 3.84285,-3.4866 0,-2.3244 -1.28095,-1.179842 -5.1238,0.01767 z"
+ id="path77"
+ inkscape:connector-curvature="0"
+ style="fill-rule:evenodd" />
+ <path
+ d="m 32.046239,14.312413 0.01947,4.520958 1.261505,2.3244 3.84285,0 1.300395,-2.452242 0,-4.6488 -1.300395,-2.196488 -3.84285,0 -1.28095,2.452242 z"
+ id="path79"
+ inkscape:connector-curvature="0"
+ style="fill-rule:evenodd" />
+ <path
+ d="m 33.327189,15.346771 1.28095,-1.1622 1.28095,0 1.28095,1.1622 0,2.3244 -1.28095,1.1622 -1.28095,0 -1.28095,-1.1622 0,-2.3244 z"
+ id="path81"
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-rule:evenodd" />
+ <path
+ d="m 23.079589,11.860171 0,5.811 5.1238,0 0,3.4866 2.5619,0 0,-9.2976 -2.5619,0 0,3.4866 -2.5619,0 0,-3.4866 -2.5619,0 z"
+ id="path83"
+ inkscape:connector-curvature="0"
+ style="fill-rule:evenodd" />
+ </g>
+</svg>
diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt
index 462cd27..3079318 100644
--- a/eeschema/CMakeLists.txt
+++ b/eeschema/CMakeLists.txt
@@ -73,6 +73,7 @@ set( EESCHEMA_DLGS
)
set( EESCHEMA_SRCS
+ autoplace_fields.cpp
annotate.cpp
backanno.cpp
block.cpp
diff --git a/eeschema/autoplace_fields.cpp b/eeschema/autoplace_fields.cpp
new file mode 100644
index 0000000..001127a
--- /dev/null
+++ b/eeschema/autoplace_fields.cpp
@@ -0,0 +1,648 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Chris Pavlina <pavlina.chris@xxxxxxxxx>
+ * Copyright (C) 2015 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
+ */
+
+/******************************************************************************
+ * Field autoplacer: Tries to find an optimal place for component fields, and
+ * places them there. There are two modes: "auto"-autoplace, and "manual" autoplace.
+ * Auto mode is for when the process is run automatically, like when rotating parts,
+ * and it avoids doing things that would be helpful for the final positioning but
+ * annoying if they happened without permission.
+ * Short description of the process:
+ *
+ * 1. Compute the dimensions of the fields' bounding box ::ComputeFBoxSize
+ * 2. Determine which side the fields will go on. ::choose_side_for_fields
+ * 1. Sort the four sides in preference order,
+ * depending on the component's shape and
+ * orientation ::get_preferred_sides
+ * 2. If in manual mode, sift out the sides that would
+ * cause fields to overlap other items ::get_colliding_sides
+ * 3. If any remaining sides have zero pins there,
+ * choose the highest zero-pin side according to
+ * preference order.
+ * 4. If all sides have pins, choose the side with the
+ * fewest pins.
+ * 3. Compute the position of the fields' bounding box ::field_box_placement
+ * 4. In manual mode, shift the box vertically if possible
+ * to fit fields between adjacent wires ::fit_fields_between_wires
+ * 5. Move all fields to their final positions
+ * 1. Re-justify fields if options allow that ::justify_field
+ * 2. Round to a 50-mil grid coordinate if desired
+ */
+
+#include <schframe.h>
+#include <hotkeys_basic.h>
+#include <sch_component.h>
+#include <sch_line.h>
+#include <lib_pin.h>
+#include <class_drawpanel.h>
+#include <class_libentry.h>
+#include <eeschema_config.h>
+#include <kiface_i.h>
+#include <boost/foreach.hpp>
+#include <vector>
+#include <algorithm>
+
+#define FIELD_V_SPACING 100
+#define HPADDING 25
+#define VPADDING 50
+
+/**
+ * Function round_n
+ * Round up/down to the nearest multiple of n
+ */
+template<typename T> T round_n( const T& value, const T& n, bool aRoundUp )
+{
+ if( value % n )
+ return n * (value / n + (aRoundUp ? 1 : 0));
+ else
+ return value;
+}
+
+
+/**
+ * Function TO_HJUSTIFY
+ * Converts an integer to a horizontal justification; neg=L zero=C pos=R
+ */
+EDA_TEXT_HJUSTIFY_T TO_HJUSTIFY( int x )
+{
+ return static_cast<EDA_TEXT_HJUSTIFY_T>( x );
+}
+
+
+class AUTOPLACER
+{
+ SCH_SCREEN* m_screen;
+ SCH_COMPONENT* m_component;
+ std::vector<SCH_FIELD*> m_fields;
+ std::vector<SCH_ITEM*> m_colliders;
+ EDA_RECT m_comp_bbox;
+ wxSize m_fbox_size;
+ bool m_allow_rejustify, m_align_to_grid;
+ bool m_power_symbol;
+
+public:
+ typedef wxPoint SIDE;
+ static const SIDE SIDE_TOP, SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT;
+ enum COLLISION { COLLIDE_NONE, COLLIDE_OBJECTS, COLLIDE_H_WIRES };
+
+ struct SIDE_AND_NPINS
+ {
+ SIDE side;
+ unsigned pins;
+ };
+
+ struct SIDE_AND_COLL
+ {
+ SIDE side;
+ COLLISION collision;
+ };
+
+
+ AUTOPLACER( SCH_COMPONENT* aComponent, SCH_SCREEN* aScreen )
+ :m_screen( aScreen ), m_component( aComponent )
+ {
+ m_component->GetFields( m_fields, /* aVisibleOnly */ true );
+ Kiface().KifaceSettings()->Read( AUTOPLACE_JUSTIFY_KEY, &m_allow_rejustify, true );
+ Kiface().KifaceSettings()->Read( AUTOPLACE_ALIGN_KEY, &m_align_to_grid, false );
+
+ m_comp_bbox = m_component->GetBodyBoundingBox();
+ m_fbox_size = ComputeFBoxSize();
+
+ m_power_symbol = ! m_component->IsInNetlist();
+
+ if( aScreen )
+ get_possible_colliders( m_colliders );
+ }
+
+
+ /**
+ * Do the actual autoplacement.
+ * @param aManual - if true, use extra heuristics for smarter placement when manually
+ * called up.
+ */
+ void DoAutoplace( bool aManual )
+ {
+ SIDE field_side = choose_side_for_fields( aManual );
+ wxPoint fbox_pos = field_box_placement( field_side );
+ EDA_RECT field_box( fbox_pos, m_fbox_size );
+
+ if( aManual )
+ {
+ fbox_pos = fit_fields_between_wires( field_box, field_side );
+ field_box.SetOrigin( fbox_pos );
+ }
+
+ // Move the fields
+ for( int field_idx = 0; field_idx < m_fields.size(); ++field_idx )
+ {
+ SCH_FIELD* field = m_fields[field_idx];
+
+ if( m_allow_rejustify )
+ justify_field( field, field_side );
+
+ wxPoint pos(
+ field_horiz_placement( field, field_box ),
+ field_box.GetY() + (FIELD_V_SPACING * field_idx) );
+
+ if( m_align_to_grid )
+ {
+ pos.x = round_n( pos.x, 50, field_side.x >= 0 );
+ pos.y = round_n( pos.y, 50, field_side.y == 1 );
+ }
+
+ field->SetPosition( pos );
+ }
+ }
+
+
+protected:
+ /**
+ * Compute and return the size of the fields' bounding box.
+ */
+ wxSize ComputeFBoxSize()
+ {
+ int max_field_width = 0;
+ BOOST_FOREACH( SCH_FIELD* field, m_fields )
+ {
+ int field_width;
+
+ if( m_component->GetTransform().y1 )
+ {
+ field->SetOrientation( TEXT_ORIENT_VERT );
+ field_width = field->GetBoundingBox().GetHeight();
+ }
+ else
+ {
+ field->SetOrientation( TEXT_ORIENT_HORIZ );
+ field_width = field->GetBoundingBox().GetWidth();
+ }
+
+ max_field_width = std::max( max_field_width, field_width );
+ }
+
+ return wxSize( max_field_width, int( FIELD_V_SPACING * (m_fields.size() - 1) ) );
+ }
+
+
+ /**
+ * Function get_pin_side
+ * Return the side that a pin is on.
+ */
+ SIDE get_pin_side( LIB_PIN* aPin )
+ {
+ int pin_orient = aPin->PinDrawOrient( m_component->GetTransform() );
+ switch( pin_orient )
+ {
+ case PIN_RIGHT: return SIDE_LEFT;
+ case PIN_LEFT: return SIDE_RIGHT;
+ case PIN_UP: return SIDE_BOTTOM;
+ case PIN_DOWN: return SIDE_TOP;
+ default:
+ wxFAIL_MSG( "Invalid pin orientation" );
+ return SIDE_LEFT;
+ }
+ }
+
+
+ /**
+ * Function pins_on_side
+ * Count the number of pins on a side of the component.
+ */
+ unsigned pins_on_side( SIDE aSide )
+ {
+ unsigned pin_count = 0;
+
+ std::vector<LIB_PIN*> pins;
+ m_component->GetPins( pins );
+
+ BOOST_FOREACH( LIB_PIN* each_pin, pins )
+ {
+ if( !each_pin->IsVisible() && !m_power_symbol )
+ continue;
+ if( get_pin_side( each_pin ) == aSide )
+ ++pin_count;
+ }
+
+ return pin_count;
+ }
+
+
+ /**
+ * Function get_possible_colliders
+ * Populate a list of all drawing items that *may* collide with the fields. That is,
+ * all drawing items, including other fields, that are not the current component or
+ * its own fields.
+ */
+ void get_possible_colliders( std::vector<SCH_ITEM*>& aItems )
+ {
+ wxASSERT_MSG( m_screen, "get_possible_colliders() with null m_screen" );
+ for( SCH_ITEM* item = m_screen->GetDrawItems(); item; item = item->Next() )
+ {
+ if( SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( item ) )
+ {
+ if( comp == m_component ) continue;
+
+ std::vector<SCH_FIELD*> fields;
+ comp->GetFields( fields, /* aVisibleOnly */ true );
+ BOOST_FOREACH( SCH_FIELD* field, fields )
+ aItems.push_back( field );
+ }
+ aItems.push_back( item );
+ }
+ }
+
+
+ /**
+ * Function filtered_colliders
+ * Filter a list of possible colliders to include only those that actually collide
+ * with a given rectangle. Returns the new vector.
+ */
+ std::vector<SCH_ITEM*> filtered_colliders( const EDA_RECT& aRect )
+ {
+ std::vector<SCH_ITEM*> filtered;
+ BOOST_FOREACH( SCH_ITEM* item, m_colliders )
+ {
+ EDA_RECT item_box;
+ if( SCH_COMPONENT* item_comp = dynamic_cast<SCH_COMPONENT*>( item ) )
+ item_box = item_comp->GetBodyBoundingBox();
+ else
+ item_box = item->GetBoundingBox();
+
+ if( item_box.Intersects( aRect ) )
+ filtered.push_back( item );
+ }
+ return filtered;
+ }
+
+
+ /**
+ * Function get_preferred_sides
+ * Return a list with the preferred field sides for the component, in
+ * decreasing order of preference.
+ */
+ std::vector<SIDE_AND_NPINS> get_preferred_sides()
+ {
+ SIDE_AND_NPINS sides_init[] = {
+ { SIDE_RIGHT, pins_on_side( SIDE_RIGHT ) },
+ { SIDE_TOP, pins_on_side( SIDE_TOP ) },
+ { SIDE_LEFT, pins_on_side( SIDE_LEFT ) },
+ { SIDE_BOTTOM, pins_on_side( SIDE_BOTTOM ) },
+ };
+ std::vector<SIDE_AND_NPINS> sides( sides_init, sides_init + DIM( sides_init ) );
+
+ int orient = m_component->GetOrientation();
+ int orient_angle = orient & 0xff; // enum is a bitmask
+ bool h_mirrored = ( ( orient & CMP_MIRROR_X )
+ && ( orient_angle == CMP_ORIENT_0 || orient_angle == CMP_ORIENT_180 ) );
+ double w = double( m_comp_bbox.GetWidth() );
+ double h = double( m_comp_bbox.GetHeight() );
+
+ // The preferred-sides heuristics are a bit magical. These were determined mostly
+ // by trial and error.
+
+ if( m_power_symbol )
+ {
+ // For power symbols, we generally want the label at the top first.
+ switch( orient_angle )
+ {
+ case CMP_ORIENT_0:
+ std::swap( sides[0], sides[1] );
+ std::swap( sides[1], sides[3] );
+ // TOP, BOTTOM, RIGHT, LEFT
+ break;
+ case CMP_ORIENT_90:
+ std::swap( sides[0], sides[2] );
+ std::swap( sides[1], sides[2] );
+ // LEFT, RIGHT, TOP, BOTTOM
+ break;
+ case CMP_ORIENT_180:
+ std::swap( sides[0], sides[3] );
+ // BOTTOM, TOP, LEFT, RIGHT
+ break;
+ case CMP_ORIENT_270:
+ std::swap( sides[1], sides[2] );
+ // RIGHT, LEFT, TOP, BOTTOM
+ break;
+ }
+ }
+ else
+ {
+ // If the component is horizontally mirrored, swap left and right
+ if( h_mirrored )
+ {
+ std::swap( sides[0], sides[2] );
+ }
+
+ // If the component is very long or is a power symbol, swap H and V
+ if( w/h > 3.0 )
+ {
+ std::swap( sides[0], sides[1] );
+ std::swap( sides[1], sides[3] );
+ }
+ }
+
+ return sides;
+ }
+
+
+ /**
+ * Function get_colliding_sides
+ * Return a list of the sides where a field set would collide with another item.
+ */
+ std::vector<SIDE_AND_COLL> get_colliding_sides()
+ {
+ SIDE sides_init[] = { SIDE_RIGHT, SIDE_TOP, SIDE_LEFT, SIDE_BOTTOM };
+ std::vector<SIDE> sides( sides_init, sides_init + DIM( sides_init ) );
+ std::vector<SIDE_AND_COLL> colliding;
+
+ // Iterate over all sides and find the ones that collide
+ BOOST_FOREACH( SIDE side, sides )
+ {
+ EDA_RECT box( field_box_placement( side ), m_fbox_size );
+
+ COLLISION collision = COLLIDE_NONE;
+ BOOST_FOREACH( SCH_ITEM* collider, filtered_colliders( box ) )
+ {
+ SCH_LINE* line = dynamic_cast<SCH_LINE*>( collider );
+ if( line && !side.x )
+ {
+ wxPoint start = line->GetStartPoint(), end = line->GetEndPoint();
+ if( start.y == end.y && collision != COLLIDE_OBJECTS )
+ collision = COLLIDE_H_WIRES;
+ else
+ collision = COLLIDE_OBJECTS;
+ }
+ else
+ collision = COLLIDE_OBJECTS;
+ }
+
+ if( collision != COLLIDE_NONE )
+ colliding.push_back( (SIDE_AND_COLL){ side, collision } );
+ }
+
+ return colliding;
+ }
+
+
+ /**
+ * Function choose_side_filtered
+ * Choose a side for the fields, filtered on only one side collision type.
+ * Removes the sides matching the filter from the list.
+ */
+ SIDE_AND_NPINS choose_side_filtered( std::vector<SIDE_AND_NPINS>& aSides,
+ const std::vector<SIDE_AND_COLL>& aCollidingSides, COLLISION aCollision,
+ SIDE_AND_NPINS aLastSelection)
+ {
+ SIDE_AND_NPINS sel = aLastSelection;
+
+ std::vector<SIDE_AND_NPINS>::iterator it = aSides.begin();
+ while( it != aSides.end() )
+ {
+ bool collide = false;
+ BOOST_FOREACH( SIDE_AND_COLL collision, aCollidingSides )
+ {
+ if( collision.side == it->side && collision.collision == aCollision )
+ collide = true;
+ }
+ if( !collide )
+ ++it;
+ else
+ {
+ if( it->pins <= sel.pins )
+ {
+ sel.pins = it->pins;
+ sel.side = it->side;
+ }
+ it = aSides.erase( it );
+ }
+ }
+ return sel;
+ }
+
+
+ /**
+ * Function choose_side_for_fields
+ * Look where a component's pins are to pick a side to put the fields on
+ * @param aAvoidCollisions - if true, pick last the sides where the label will collide
+ * with other items.
+ */
+ SIDE choose_side_for_fields( bool aAvoidCollisions )
+ {
+ std::vector<SIDE_AND_NPINS> sides = get_preferred_sides();
+
+ std::reverse( sides.begin(), sides.end() );
+ SIDE_AND_NPINS side = { wxPoint( 1, 0 ), UINT_MAX };
+
+ if( aAvoidCollisions )
+ {
+ std::vector<SIDE_AND_COLL> colliding_sides = get_colliding_sides();
+ side = choose_side_filtered( sides, colliding_sides, COLLIDE_OBJECTS, side );
+ side = choose_side_filtered( sides, colliding_sides, COLLIDE_H_WIRES, side );
+ }
+
+ BOOST_REVERSE_FOREACH( SIDE_AND_NPINS& each_side, sides )
+ {
+ if( !each_side.pins ) return each_side.side;
+ }
+
+ BOOST_FOREACH( SIDE_AND_NPINS& each_side, sides )
+ {
+ if( each_side.pins <= side.pins )
+ {
+ side.pins = each_side.pins;
+ side.side = each_side.side;
+ }
+ }
+
+ return side.side;
+ }
+
+
+ /**
+ * Function justify_field
+ * Set the justification of a field based on the side it's supposed to be on, taking
+ * into account whether the field will be displayed with flipped justification due to
+ * mirroring.
+ */
+ void justify_field( SCH_FIELD* aField, SIDE aFieldSide )
+ {
+ // Justification is set twice to allow IsHorizJustifyFlipped() to work correctly.
+ aField->SetHorizJustify( TO_HJUSTIFY( -aFieldSide.x ) );
+ aField->SetHorizJustify( TO_HJUSTIFY( -aFieldSide.x *
+ ( aField->IsHorizJustifyFlipped() ? -1 : 1 ) ) );
+ aField->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
+ }
+
+
+ /**
+ * Function field_box_placement
+ * Returns the position of the field bounding box.
+ */
+ wxPoint field_box_placement( SIDE aFieldSide )
+ {
+ wxPoint fbox_center = m_comp_bbox.Centre();
+ int offs_x = ( m_comp_bbox.GetWidth() + m_fbox_size.GetWidth() ) / 2 + HPADDING;
+ int offs_y = ( m_comp_bbox.GetHeight() + m_fbox_size.GetHeight() ) / 2 + VPADDING;
+
+ fbox_center.x += aFieldSide.x * offs_x;
+ fbox_center.y += aFieldSide.y * offs_y;
+
+ wxPoint fbox_pos(
+ fbox_center.x - m_fbox_size.GetWidth() / 2,
+ fbox_center.y - m_fbox_size.GetHeight() / 2 );
+
+ return fbox_pos;
+ }
+
+
+ /**
+ * Function fit_fields_between_wires
+ * Shift a field box up or down a bit to make the fields fit between some wires.
+ * Returns the new position of the field bounding box.
+ */
+ wxPoint fit_fields_between_wires( const EDA_RECT& aBox, SIDE aSide )
+ {
+ if( aSide != SIDE_TOP && aSide != SIDE_BOTTOM )
+ return aBox.GetPosition();
+
+ std::vector<SCH_ITEM*> colliders = filtered_colliders( aBox );
+ if( colliders.empty() )
+ return aBox.GetPosition();
+
+ // Find the offset of the wires for proper positioning
+ int offset = 0;
+
+ BOOST_FOREACH( SCH_ITEM* item, colliders )
+ {
+ SCH_LINE* line = dynamic_cast<SCH_LINE*>( item );
+ if( !line )
+ return aBox.GetPosition();
+ wxPoint start = line->GetStartPoint(), end = line->GetEndPoint();
+ if( start.y != end.y )
+ return aBox.GetPosition();
+
+ int this_offset = (3 * FIELD_V_SPACING / 2) - ( start.y % FIELD_V_SPACING );
+ if( offset == 0 )
+ offset = this_offset;
+ else if( offset != this_offset )
+ return aBox.GetPosition();
+ }
+
+ if( aSide == SIDE_TOP )
+ offset = -offset;
+
+ wxPoint pos = aBox.GetPosition();
+ pos.y = round_n( pos.y - offset, FIELD_V_SPACING, aSide == SIDE_BOTTOM ) + offset;
+ return pos;
+ }
+
+
+ /**
+ * Function field_horiz_placement
+ * Place a field horizontally, taking into account the field width and
+ * justification.
+ *
+ * @param aField - the field to place.
+ * @param aFieldBox - box in which fields will be placed
+ *
+ * @return Correct field horizontal position
+ */
+ int field_horiz_placement( SCH_FIELD *aField, const EDA_RECT &aFieldBox )
+ {
+ int field_hjust;
+ int field_xcoord;
+
+ if( aField->IsHorizJustifyFlipped() )
+ field_hjust = -aField->GetHorizJustify();
+ else
+ field_hjust = aField->GetHorizJustify();
+
+ switch( field_hjust )
+ {
+ case GR_TEXT_HJUSTIFY_LEFT:
+ field_xcoord = aFieldBox.GetLeft();
+ break;
+ case GR_TEXT_HJUSTIFY_CENTER:
+ field_xcoord = aFieldBox.Centre().x;
+ break;
+ case GR_TEXT_HJUSTIFY_RIGHT:
+ field_xcoord = aFieldBox.GetRight();
+ break;
+ default:
+ wxFAIL_MSG( "Unexpected value for SCH_FIELD::GetHorizJustify()" );
+ field_xcoord = aFieldBox.Centre().x; // Most are centered
+ }
+
+ return field_xcoord;
+ }
+
+};
+
+const AUTOPLACER::SIDE AUTOPLACER::SIDE_TOP( 0, -1 );
+const AUTOPLACER::SIDE AUTOPLACER::SIDE_BOTTOM( 0, 1 );
+const AUTOPLACER::SIDE AUTOPLACER::SIDE_LEFT( -1, 0 );
+const AUTOPLACER::SIDE AUTOPLACER::SIDE_RIGHT( 1, 0 );
+
+
+void SCH_EDIT_FRAME::OnAutoplaceFields( wxCommandEvent& aEvent )
+{
+ SCH_SCREEN* screen = GetScreen();
+ SCH_ITEM* item = screen->GetCurItem();
+
+ // Get the item under cursor if we're not currently moving something
+ if( !item )
+ {
+ if( aEvent.GetInt() == 0 )
+ return;
+
+ EDA_HOTKEY_CLIENT_DATA& data = dynamic_cast<EDA_HOTKEY_CLIENT_DATA&>(
+ *aEvent.GetClientObject() );
+ item = LocateItem( data.GetPosition(), SCH_COLLECTOR::MovableItems, aEvent.GetInt() );
+ screen->SetCurItem( NULL );
+ if( !item || item->GetFlags() )
+ return;
+ }
+
+ SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( item );
+ if( !component )
+ return;
+
+ if( !component->IsNew() )
+ SaveCopyInUndoList( component, UR_CHANGED );
+
+ component->AutoplaceFields( screen, /* aManual */ true );
+
+ GetCanvas()->Refresh();
+ OnModify();
+}
+
+
+void SCH_COMPONENT::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual )
+{
+ if( aManual )
+ wxASSERT_MSG( aScreen, "A SCH_SCREEN pointer must be given for manual autoplacement" );
+ AUTOPLACER autoplacer( this, aScreen );
+ autoplacer.DoAutoplace( aManual );
+ m_fieldsAutoplaced = ( aManual? AUTOPLACED_MANUAL : AUTOPLACED_AUTO );
+}
diff --git a/eeschema/class_libentry.cpp b/eeschema/class_libentry.cpp
index 1d49ea3..755dcd8 100644
--- a/eeschema/class_libentry.cpp
+++ b/eeschema/class_libentry.cpp
@@ -1194,7 +1194,7 @@ const EDA_RECT LIB_PART::GetBodyBoundingBox( int aUnit, int aConvert ) const
if( item.m_Convert > 0 && ( ( aConvert > 0 ) && ( aConvert != item.m_Convert ) ) )
continue;
- if ( item.Type() == LIB_FIELD_T )
+ if( item.Type() == LIB_FIELD_T )
continue;
if( initialized )
diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp
index 4b9eabd..2e974e1 100644
--- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp
+++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp
@@ -158,6 +158,9 @@ void SCH_EDIT_FRAME::EditComponent( SCH_COMPONENT* aComponent )
// the QUASIMODAL macros here.
int ret = dlg->ShowQuasiModal();
+ if( m_autoplaceFields )
+ aComponent->AutoAutoplaceFields( GetScreen() );
+
m_canvas->SetIgnoreMouseEvents( false );
m_canvas->MoveCursorToCrossHair();
dlg->Destroy();
diff --git a/eeschema/dialogs/dialog_edit_one_field.cpp b/eeschema/dialogs/dialog_edit_one_field.cpp
index d3439da..b3cad30 100644
--- a/eeschema/dialogs/dialog_edit_one_field.cpp
+++ b/eeschema/dialogs/dialog_edit_one_field.cpp
@@ -298,6 +298,19 @@ void DIALOG_SCH_EDIT_ONE_FIELD::TransfertDataToField( bool aIncludeText )
m_field->SetItalic( ( m_TextShapeOpt->GetSelection() & 1 ) != 0 );
m_field->SetBold( ( m_TextShapeOpt->GetSelection() & 2 ) != 0 );
+
+ // Because field autoplace can change justification, check whether this has
+ // been changed, and clear the autoplace flag if so.
+ EDA_TEXT_HJUSTIFY_T old_hjust = m_field->GetHorizJustify();
+ EDA_TEXT_VJUSTIFY_T old_vjust = m_field->GetVertJustify();
+
+ if( old_hjust != m_textHjustify || old_vjust != m_textVjustify )
+ {
+ EDA_ITEM *parent = m_field->GetParent();
+ if( SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( parent ) )
+ component->ClearFieldsAutoplaced();
+ }
+
m_field->SetHorizJustify( m_textHjustify );
m_field->SetVertJustify( m_textVjustify );
}
diff --git a/eeschema/dialogs/dialog_eeschema_options.h b/eeschema/dialogs/dialog_eeschema_options.h
index df0c0bf..71d575b 100644
--- a/eeschema/dialogs/dialog_eeschema_options.h
+++ b/eeschema/dialogs/dialog_eeschema_options.h
@@ -441,6 +441,42 @@ public:
bool GetShowPageLimits( void ) { return m_checkPageLimits->GetValue(); }
/**
+ * Function
+ * Set the AutoplaceFields setting in the dialog
+ */
+ void SetAutoplaceFields( bool enable ) { m_checkAutoplaceFields->SetValue( enable ); }
+
+ /**
+ * Function
+ * Return the current AutoplaceFields setting from the dialog
+ */
+ bool GetAutoplaceFields() { return m_checkAutoplaceFields->GetValue(); }
+
+ /**
+ * Function
+ * Set the AutoplaceJustify setting in the dialog
+ */
+ void SetAutoplaceJustify( bool enable ) { m_checkAutoplaceJustify->SetValue( enable ); }
+
+ /**
+ * Function
+ * Return the current AutoplaceJustify setting from the dialog
+ */
+ bool GetAutoplaceJustify() { return m_checkAutoplaceJustify->GetValue(); }
+
+ /**
+ * Function
+ * Set the AutoplaceAlign setting in the dialog
+ */
+ void SetAutoplaceAlign( bool enable ) { m_checkAutoplaceAlign->SetValue( enable ); }
+
+ /**
+ * Function
+ * Return the current AutoplaceAlign setting from the dialog
+ */
+ bool GetAutoplaceAlign() { return m_checkAutoplaceAlign->GetValue(); }
+
+ /**
* Function SetTemplateFields
* Set the template field data in the dialog
*
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.cpp b/eeschema/dialogs/dialog_eeschema_options_base.cpp
index 56e1cf7..ef62650 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.cpp
+++ b/eeschema/dialogs/dialog_eeschema_options_base.cpp
@@ -214,6 +214,15 @@ DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wx
m_checkPageLimits = new wxCheckBox( m_panel1, wxID_ANY, _("Show page limi&ts"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_checkPageLimits, 0, wxALL|wxEXPAND, 3 );
+ m_checkAutoplaceFields = new wxCheckBox( m_panel1, wxID_ANY, _("Automatically place component fields"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkAutoplaceFields, 0, wxALL, 3 );
+
+ m_checkAutoplaceJustify = new wxCheckBox( m_panel1, wxID_ANY, _("Allow field autoplace to change justification"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkAutoplaceJustify, 0, wxALL, 3 );
+
+ m_checkAutoplaceAlign = new wxCheckBox( m_panel1, wxID_ANY, _("Always align autoplaced fields to the 50 mil grid"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer2->Add( m_checkAutoplaceAlign, 0, wxALL, 3 );
+
bSizer3->Add( bSizer2, 0, wxEXPAND, 0 );
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.fbp b/eeschema/dialogs/dialog_eeschema_options_base.fbp
index 9340f09..f270dfb 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.fbp
+++ b/eeschema/dialogs/dialog_eeschema_options_base.fbp
@@ -2873,7 +2873,7 @@
<property name="border">0</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="0">
+ <object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizer2</property>
<property name="orient">wxVERTICAL</property>
@@ -3663,6 +3663,270 @@
<event name="OnUpdateUI"></event>
</object>
</object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Automatically place component fields</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkAutoplaceFields</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Allow field autoplace to change justification</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkAutoplaceJustify</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">3</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="1">
+ <property name="BottomDockable">1</property>
+ <property name="LeftDockable">1</property>
+ <property name="RightDockable">1</property>
+ <property name="TopDockable">1</property>
+ <property name="aui_layer"></property>
+ <property name="aui_name"></property>
+ <property name="aui_position"></property>
+ <property name="aui_row"></property>
+ <property name="best_size"></property>
+ <property name="bg"></property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="checked">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default_pane">0</property>
+ <property name="dock">Dock</property>
+ <property name="dock_fixed">0</property>
+ <property name="docking">Left</property>
+ <property name="enabled">1</property>
+ <property name="fg"></property>
+ <property name="floatable">1</property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="label">Always align autoplaced fields to the 50 mil grid</property>
+ <property name="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="min_size"></property>
+ <property name="minimize_button">0</property>
+ <property name="minimum_size"></property>
+ <property name="moveable">1</property>
+ <property name="name">m_checkAutoplaceAlign</property>
+ <property name="pane_border">1</property>
+ <property name="pane_position"></property>
+ <property name="pane_size"></property>
+ <property name="permission">protected</property>
+ <property name="pin_button">1</property>
+ <property name="pos"></property>
+ <property name="resize">Resizable</property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="validator_data_type"></property>
+ <property name="validator_style">wxFILTER_NONE</property>
+ <property name="validator_type">wxDefaultValidator</property>
+ <property name="validator_variable"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></event>
+ <event name="OnCheckBox"></event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnKeyDown"></event>
+ <event name="OnKeyUp"></event>
+ <event name="OnKillFocus"></event>
+ <event name="OnLeaveWindow"></event>
+ <event name="OnLeftDClick"></event>
+ <event name="OnLeftDown"></event>
+ <event name="OnLeftUp"></event>
+ <event name="OnMiddleDClick"></event>
+ <event name="OnMiddleDown"></event>
+ <event name="OnMiddleUp"></event>
+ <event name="OnMotion"></event>
+ <event name="OnMouseEvents"></event>
+ <event name="OnMouseWheel"></event>
+ <event name="OnPaint"></event>
+ <event name="OnRightDClick"></event>
+ <event name="OnRightDown"></event>
+ <event name="OnRightUp"></event>
+ <event name="OnSetFocus"></event>
+ <event name="OnSize"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
</object>
</object>
</object>
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.h b/eeschema/dialogs/dialog_eeschema_options_base.h
index d09b2f9..b3f2dd2 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.h
+++ b/eeschema/dialogs/dialog_eeschema_options_base.h
@@ -109,6 +109,9 @@ class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM
wxCheckBox* m_checkAutoPan;
wxCheckBox* m_checkHVOrientation;
wxCheckBox* m_checkPageLimits;
+ wxCheckBox* m_checkAutoplaceFields;
+ wxCheckBox* m_checkAutoplaceJustify;
+ wxCheckBox* m_checkAutoplaceAlign;
wxPanel* m_panel2;
wxListView* templateFieldListCtrl;
wxStaticText* fieldNameLabel;
diff --git a/eeschema/edit_component_in_schematic.cpp b/eeschema/edit_component_in_schematic.cpp
index 3b9104a..c9294a5 100644
--- a/eeschema/edit_component_in_schematic.cpp
+++ b/eeschema/edit_component_in_schematic.cpp
@@ -137,6 +137,10 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField )
{
dlg.TransfertDataToField( /* aIncludeText = */ !( fieldNdx == VALUE && part->IsPower() ) );
OnModify();
+
+ if( m_autoplaceFields )
+ component->AutoAutoplaceFields( GetScreen() );
+
m_canvas->Refresh();
}
diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp
index 12c1598..1b585db 100644
--- a/eeschema/eeschema_config.cpp
+++ b/eeschema/eeschema_config.cpp
@@ -335,6 +335,9 @@ void SCH_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event )
dlg.SetEnableAutoPan( m_canvas->GetEnableAutoPan() );
dlg.SetEnableHVBusOrientation( GetForceHVLines() );
dlg.SetShowPageLimits( m_showPageLimits );
+ dlg.SetAutoplaceFields( m_autoplaceFields );
+ dlg.SetAutoplaceJustify( m_autoplaceJustify );
+ dlg.SetAutoplaceAlign( m_autoplaceAlign );
dlg.Layout();
dlg.Fit();
dlg.SetMinSize( dlg.GetSize() );
@@ -383,6 +386,9 @@ void SCH_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event )
m_canvas->SetEnableAutoPan( dlg.GetEnableAutoPan() );
SetForceHVLines( dlg.GetEnableHVBusOrientation() );
m_showPageLimits = dlg.GetShowPageLimits();
+ m_autoplaceFields = dlg.GetAutoplaceFields();
+ m_autoplaceJustify = dlg.GetAutoplaceJustify();
+ m_autoplaceAlign = dlg.GetAutoplaceAlign();
// Delete all template fieldnames and then restore them using the template field data from
// the options dialog
@@ -503,6 +509,9 @@ void SCH_EDIT_FRAME::SaveProjectSettings( bool aAskForSave )
}
+static const wxChar AutoplaceFieldsEntry[] = wxT( "AutoplaceFields" );
+static const wxChar AutoplaceJustifyEntry[] = AUTOPLACE_JUSTIFY_KEY;
+static const wxChar AutoplaceAlignEntry[] = AUTOPLACE_ALIGN_KEY;
static const wxChar DefaultBusWidthEntry[] = wxT( "DefaultBusWidth" );
static const wxChar DefaultDrawLineWidthEntry[] = wxT( "DefaultDrawLineWidth" );
static const wxChar ShowHiddenPinsEntry[] = wxT( "ShowHiddenPins" );
@@ -586,6 +595,9 @@ void SCH_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
SetDefaultLineThickness( aCfg->Read( DefaultDrawLineWidthEntry, DEFAULTDRAWLINETHICKNESS ) );
aCfg->Read( ShowHiddenPinsEntry, &m_showAllPins, false );
aCfg->Read( HorzVertLinesOnlyEntry, &m_forceHVLines, true );
+ aCfg->Read( AutoplaceFieldsEntry, &m_autoplaceFields, true );
+ aCfg->Read( AutoplaceJustifyEntry, &m_autoplaceJustify, true );
+ aCfg->Read( AutoplaceAlignEntry, &m_autoplaceAlign, false );
// Load print preview window session settings.
aCfg->Read( PreviewFramePositionXEntry, &tmp, -1 );
@@ -676,6 +688,9 @@ void SCH_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg )
aCfg->Write( DefaultDrawLineWidthEntry, (long) GetDefaultLineThickness() );
aCfg->Write( ShowHiddenPinsEntry, m_showAllPins );
aCfg->Write( HorzVertLinesOnlyEntry, GetForceHVLines() );
+ aCfg->Write( AutoplaceFieldsEntry, m_autoplaceFields );
+ aCfg->Write( AutoplaceJustifyEntry, m_autoplaceJustify );
+ aCfg->Write( AutoplaceAlignEntry, m_autoplaceAlign );
// Save print preview window session settings.
aCfg->Write( PreviewFramePositionXEntry, m_previewPosition.x );
diff --git a/eeschema/eeschema_config.h b/eeschema/eeschema_config.h
index e93160b..e82f5df 100644
--- a/eeschema/eeschema_config.h
+++ b/eeschema/eeschema_config.h
@@ -10,4 +10,8 @@
// a key to read write in user config the visibility of the rescue library dialog
#define RESCUE_NEVER_SHOW_KEY wxT("RescueNeverShow")
+// define autoplace key here to avoid having to take the long trip to get at the SCH_EDIT_FRAME
+#define AUTOPLACE_JUSTIFY_KEY wxT("AutoplaceJustify")
+#define AUTOPLACE_ALIGN_KEY wxT("AutoplaceAlign")
+
#endif // EESCHEMA_CONFIG_H
diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h
index ca8eeeb..2a7e903 100644
--- a/eeschema/eeschema_id.h
+++ b/eeschema/eeschema_id.h
@@ -168,6 +168,8 @@ enum id_eeschema_frm
ID_SCH_MOVE_ITEM,
ID_SCH_DRAG_ITEM,
+ ID_AUTOPLACE_FIELDS,
+
// Schematic editor commmands. These are command IDs that are generated by multiple
// events (menus, toolbar, context menu, etc.) that result in the same event handler.
ID_CANCEL_CURRENT_COMMAND,
diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp
index 8c8db7e..302a998 100644
--- a/eeschema/getpart.cpp
+++ b/eeschema/getpart.cpp
@@ -242,6 +242,10 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( wxDC* aDC,
SetMsgPanel( items );
component->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
component->SetFlags( IS_NEW );
+
+ if( m_autoplaceFields )
+ component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false );
+
PrepareMoveItem( (SCH_ITEM*) component, aDC );
return component;
@@ -268,29 +272,11 @@ void SCH_EDIT_FRAME::OrientComponent( COMPONENT_ORIENTATION_T aOrientation )
INSTALL_UNBUFFERED_DC( dc, m_canvas );
- // Erase the previous component in it's current orientation.
-
- m_canvas->CrossHairOff( &dc );
-
- if( component->GetFlags() )
- component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
- else
- {
- component->SetFlags( IS_MOVED ); // do not redraw the component
- m_canvas->RefreshDrawingRect( component->GetBoundingBox() );
- component->ClearFlags( IS_MOVED );
- }
-
component->SetOrientation( aOrientation );
- /* Redraw the component in the new position. */
- if( component->GetFlags() )
- component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
- else
- component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
-
m_canvas->CrossHairOn( &dc );
GetScreen()->TestDanglingEnds( m_canvas, &dc );
+ m_canvas->Refresh();
OnModify();
}
@@ -344,13 +330,11 @@ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent )
component->ClearFlags();
component->SetFlags( flags ); // Restore m_Flag modified by SetUnit()
- /* Redraw the component in the new position. */
- if( flags )
- component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode, g_GhostColor );
- else
- component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
+ if( m_autoplaceFields )
+ component->AutoAutoplaceFields( GetScreen() );
screen->TestDanglingEnds( m_canvas, &dc );
+ m_canvas->Refresh();
OnModify();
}
}
diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp
index 5994220..d31c392 100644
--- a/eeschema/hotkeys.cpp
+++ b/eeschema/hotkeys.cpp
@@ -219,6 +219,10 @@ static EDA_HOTKEY HkSaveLib( _HKI( "Save Library" ), HK_SAVE_LIB, 'S' + GR_KB_CT
static EDA_HOTKEY HkSaveSchematic( _HKI( "Save Schematic" ), HK_SAVE_SCH, 'S' + GR_KB_CTRL );
static EDA_HOTKEY HkLoadSchematic( _HKI( "Load Schematic" ), HK_LOAD_SCH, 'L' + GR_KB_CTRL );
+// Autoplace fields
+static EDA_HOTKEY HkAutoplaceFields( _HKI( "Autoplace Fields" ), HK_AUTOPLACE_FIELDS, 'O',
+ ID_AUTOPLACE_FIELDS );
+
// List of common hotkey descriptors
static EDA_HOTKEY* common_Hotkey_List[] =
{
@@ -292,6 +296,7 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
&HkAddGraphicPolyLine,
&HkAddGraphicText,
&HkLeaveSheet,
+ &HkAutoplaceFields,
&HkDeleteNode,
NULL
};
@@ -580,6 +585,7 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
case HK_ORIENT_NORMAL_COMPONENT: // Orient 0, no mirror (Component)
case HK_ROTATE: // Rotate schematic item.
case HK_EDIT_COMPONENT_WITH_LIBEDIT: // Call Libedit and load the current component
+ case HK_AUTOPLACE_FIELDS: // Autoplace all fields around component
{
// force a new item search on hot keys at current position,
// if there is no currently edited item,
diff --git a/eeschema/hotkeys.h b/eeschema/hotkeys.h
index afcebca..22f3f38 100644
--- a/eeschema/hotkeys.h
+++ b/eeschema/hotkeys.h
@@ -78,6 +78,7 @@ enum hotkey_id_commnand {
HK_LEFT_CLICK,
HK_LEFT_DCLICK,
HK_LEAVE_SHEET,
+ HK_AUTOPLACE_FIELDS,
HK_DELETE_NODE
};
diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp
index e4b221f..525e086 100644
--- a/eeschema/lib_pin.cpp
+++ b/eeschema/lib_pin.cpp
@@ -2012,7 +2012,7 @@ void LIB_PIN::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
}
-const EDA_RECT LIB_PIN::GetBoundingBox() const
+const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles ) const
{
LIB_PART* entry = (LIB_PART* ) m_Parent;
EDA_RECT bbox;
@@ -2023,6 +2023,8 @@ const EDA_RECT LIB_PIN::GetBoundingBox() const
bool showNum = m_number != 0;
int minsizeV = TARGET_PIN_RADIUS;
+ if( !aIncludeInvisibles && !IsVisible() )
+ showName = false;
if( entry )
{
diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h
index 6cf6801..f91ccdd 100644
--- a/eeschema/lib_pin.h
+++ b/eeschema/lib_pin.h
@@ -151,7 +151,15 @@ public:
bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
- const EDA_RECT GetBoundingBox() const; // Virtual
+ /* Cannot use a default parameter here as it will not be compatible with the virtual. */
+ const EDA_RECT GetBoundingBox() const { return GetBoundingBox( false ); }
+
+ /**
+ * Function GetBoundingBox
+ * @param aIncludeInvisibles - if false, do not include labels for invisible pins
+ * in the calculation.
+ */
+ const EDA_RECT GetBoundingBox( bool aIncludeInvisibles ) const;
/**
* Function PinEndPoint
diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp
index 442e241..526b562 100644
--- a/eeschema/onrightclick.cpp
+++ b/eeschema/onrightclick.cpp
@@ -394,6 +394,9 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS*
AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_CMP, msg, KiBitmap( delete_xpm ) );
}
+ msg = AddHotkeyName( _( "Autoplace Fields" ), g_Schematic_Hokeys_Descr, HK_AUTOPLACE_FIELDS );
+ AddMenuItem( PopMenu, ID_AUTOPLACE_FIELDS, msg, KiBitmap( autoplace_fields_xpm ) );
+
if( libEntry && !libEntry->GetDocFileName().IsEmpty() )
AddMenuItem( PopMenu, ID_POPUP_SCH_DISPLAYDOC_CMP, _( "Doc" ), KiBitmap( datasheet_xpm ) );
}
diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp
index 82694d8..91c906a 100644
--- a/eeschema/sch_component.cpp
+++ b/eeschema/sch_component.cpp
@@ -217,6 +217,7 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
}
m_isDangling = aComponent.m_isDangling;
+ m_fieldsAutoplaced = aComponent.m_fieldsAutoplaced;
}
@@ -660,6 +661,16 @@ SCH_FIELD* SCH_COMPONENT::GetField( int aFieldNdx ) const
}
+void SCH_COMPONENT::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly )
+{
+ BOOST_FOREACH( SCH_FIELD& each_field, m_Fields )
+ {
+ if( !aVisibleOnly || ( each_field.IsVisible() && !each_field.IsVoid() ) )
+ aVector.push_back( &each_field );
+ }
+}
+
+
SCH_FIELD* SCH_COMPONENT::AddField( const SCH_FIELD& aField )
{
int newNdx = m_Fields.size();
@@ -691,6 +702,17 @@ LIB_PIN* SCH_COMPONENT::GetPin( const wxString& number )
}
+void SCH_COMPONENT::GetPins( std::vector<LIB_PIN*>& aPinsList )
+{
+ if( PART_SPTR part = m_part.lock() )
+ {
+ part->GetPins( aPinsList, m_unit, m_convert );
+ }
+ else
+ wxFAIL_MSG( "Could not obtain PART_SPTR lock" );
+}
+
+
void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
{
wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T),
diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h
index 8984fc4..7d64546 100644
--- a/eeschema/sch_component.h
+++ b/eeschema/sch_component.h
@@ -64,6 +64,10 @@ class SCH_COMPONENT : public SCH_ITEM
{
friend class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC;
+public:
+ enum AUTOPLACED { AUTOPLACED_NO = 0, AUTOPLACED_AUTO, AUTOPLACED_MANUAL };
+private:
+
wxPoint m_Pos;
wxString m_part_name; ///< Name to look for in the library, i.e. "74LS00".
@@ -82,6 +86,8 @@ class SCH_COMPONENT : public SCH_ITEM
std::vector<bool> m_isDangling; ///< One isDangling per pin
+ AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement
+
/**
* A temporary sheet path is required to generate the correct reference designator string
* in complex heirarchies. Hopefully this is only a temporary hack to decouple schematic
@@ -100,8 +106,6 @@ class SCH_COMPONENT : public SCH_ITEM
void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
- EDA_RECT GetBodyBoundingBox() const;
-
public:
SCH_COMPONENT( const wxPoint& pos = wxPoint( 0, 0 ), SCH_ITEM* aParent = NULL );
@@ -255,6 +259,13 @@ public:
const EDA_RECT GetBoundingBox() const; // Virtual
+ /**
+ * Function GetBodyBoundingBox
+ * Return a bounding box for the component body but not the fields.
+ */
+ EDA_RECT GetBodyBoundingBox() const;
+
+
//-----<Fields>-----------------------------------------------------------
/**
@@ -266,6 +277,14 @@ public:
SCH_FIELD* GetField( int aFieldNdx ) const;
/**
+ * Function GetFields
+ * populates a std::vector with SCH_FIELDs.
+ * @param aVector - vector to populate.
+ * @param aVisibleOnly - if true, only get fields that are visible and contain text.
+ */
+ void GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly );
+
+ /**
* Function AddField
* adds a field to the component. The field is copied as it is put into
* the component.
@@ -284,9 +303,6 @@ public:
{
m_Fields = aFields; // vector copying, length is changed possibly
}
-
- //-----</Fields>----------------------------------------------------------
-
/**
* Function GetFieldCount
* returns the number of fields in this component.
@@ -294,6 +310,46 @@ public:
int GetFieldCount() const { return (int) m_Fields.size(); }
/**
+ * Function GetFieldsAutoplaced
+ * returns whether the fields are autoplaced.
+ */
+ AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; }
+
+ /**
+ * Function ClearFieldsAutoplaced
+ * Set fields autoplaced flag false.
+ */
+ void ClearFieldsAutoplaced() { m_fieldsAutoplaced = AUTOPLACED_NO; }
+
+ /**
+ * Function AutoplaceFields
+ * Automatically orient all the fields in the component.
+ * @param aScreen - the SCH_SCREEN associated with the current instance of the
+ * component. This can be NULL when aManual is false.
+ * @param aManual - True if the autoplace was manually initiated (e.g. by a hotkey
+ * or a menu item). Some more 'intelligent' routines will be used that would be
+ * annoying if done automatically during moves.
+ */
+ void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual );
+
+ /**
+ * Function AutoAutoplaceFields
+ * Autoplace fields only if correct to do so automatically. That is, do not
+ * autoplace if fields have been moved by hand.
+ * @param aScreen - the SCH_SCREEN associated with the current instance of the
+ * component.
+ */
+ void AutoAutoplaceFields( SCH_SCREEN* aScreen )
+ {
+ if( GetFieldsAutoplaced() )
+ AutoplaceFields( aScreen, GetFieldsAutoplaced() == AUTOPLACED_MANUAL );
+ }
+
+
+ //-----</Fields>----------------------------------------------------------
+
+
+ /**
* Function GetPin
* finds a component pin by number.
*
@@ -303,6 +359,12 @@ public:
LIB_PIN* GetPin( const wxString& number );
/**
+ * Function GetPins
+ * populate a vector with all the pins.
+ */
+ void GetPins( std::vector<LIB_PIN*>& aPinsList );
+
+ /**
* Virtual function, from the base class SCH_ITEM::Draw
*/
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp
index 46b8834..38cbe18 100644
--- a/eeschema/sch_field.cpp
+++ b/eeschema/sch_field.cpp
@@ -299,6 +299,23 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const
}
+bool SCH_FIELD::IsHorizJustifyFlipped() const
+{
+ wxPoint render_center = GetBoundingBox().Centre();
+ wxPoint pos = GetPosition();
+
+ switch( GetHorizJustify() )
+ {
+ case GR_TEXT_HJUSTIFY_LEFT:
+ return render_center.x < pos.x;
+ case GR_TEXT_HJUSTIFY_RIGHT:
+ return render_center.x > pos.x;
+ default:
+ return false;
+ }
+}
+
+
bool SCH_FIELD::Save( FILE* aFile ) const
{
char hjustify = 'C';
diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h
index 8b458bc..814876a 100644
--- a/eeschema/sch_field.h
+++ b/eeschema/sch_field.h
@@ -103,6 +103,13 @@ public:
const EDA_RECT GetBoundingBox() const; // Virtual
/**
+ * Function IsHorizJustifyFlipped
+ * Returns whether the field will be rendered with the horizontal justification
+ * inverted due to rotation or mirroring of the parent.
+ */
+ bool IsHorizJustifyFlipped() const;
+
+ /**
* Function IsVoid
* returns true if the field is either empty or holds "~".
*/
@@ -131,7 +138,7 @@ public:
*/
bool IsVisible() const
{
- return (m_Attributs & TEXT_NO_VISIBLE) == 0 ? true : false;
+ return !( m_Attributs & TEXT_NO_VISIBLE );
}
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp
index 927e44c..91bad6f 100644
--- a/eeschema/schedit.cpp
+++ b/eeschema/schedit.cpp
@@ -765,6 +765,13 @@ void SCH_EDIT_FRAME::PrepareMoveItem( SCH_ITEM* aItem, wxDC* aDC )
SetUndoItem( aItem );
}
+ if( aItem->Type() == SCH_FIELD_T && aItem->GetParent()->Type() == SCH_COMPONENT_T )
+ {
+ // Now that we're moving a field, they're no longer autoplaced.
+ SCH_COMPONENT *parent = dynamic_cast<SCH_COMPONENT*>( aItem->GetParent() );
+ parent->ClearFieldsAutoplaced();
+ }
+
aItem->SetFlags( IS_MOVED );
// For some items, moving the cursor to anchor is not good
@@ -826,14 +833,22 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
switch( item->Type() )
{
case SCH_COMPONENT_T:
- if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
- OrientComponent( CMP_ROTATE_CLOCKWISE );
- else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
- OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
- else
- wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );
+ {
+ SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( item );
+ if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
+ OrientComponent( CMP_ROTATE_CLOCKWISE );
+ else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
+ OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
+ else
+ wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );
- break;
+ if( m_autoplaceFields )
+ component->AutoAutoplaceFields( GetScreen() );
+
+ m_canvas->Refresh();
+
+ break;
+ }
case SCH_TEXT_T:
case SCH_LABEL_T:
@@ -846,6 +861,12 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
case SCH_FIELD_T:
m_canvas->MoveCursorToCrossHair();
RotateField( (SCH_FIELD*) item, &dc );
+ if( item->GetParent()->Type() == SCH_COMPONENT_T )
+ {
+ // Now that we're moving a field, they're no longer autoplaced.
+ SCH_COMPONENT *parent = dynamic_cast<SCH_COMPONENT*>( item->GetParent() );
+ parent->ClearFieldsAutoplaced();
+ }
break;
case SCH_BITMAP_T:
@@ -1126,16 +1147,24 @@ void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
switch( item->Type() )
{
case SCH_COMPONENT_T:
- if( aEvent.GetId() == ID_SCH_MIRROR_X )
- OrientComponent( CMP_MIRROR_X );
- else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
- OrientComponent( CMP_MIRROR_Y );
- else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL )
- OrientComponent( CMP_NORMAL );
- else
- wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) );
+ {
+ SCH_COMPONENT *component = dynamic_cast<SCH_COMPONENT*>( item );
+ if( aEvent.GetId() == ID_SCH_MIRROR_X )
+ OrientComponent( CMP_MIRROR_X );
+ else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
+ OrientComponent( CMP_MIRROR_Y );
+ else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL )
+ OrientComponent( CMP_NORMAL );
+ else
+ wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) );
+
+ if( m_autoplaceFields )
+ component->AutoAutoplaceFields( GetScreen() );
- break;
+ m_canvas->Refresh();
+
+ break;
+ }
case SCH_BITMAP_T:
if( aEvent.GetId() == ID_SCH_MIRROR_X )
diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp
index 2568576..22983ea 100644
--- a/eeschema/schframe.cpp
+++ b/eeschema/schframe.cpp
@@ -266,6 +266,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
EVT_TOOL( ID_BACKANNO_ITEMS, SCH_EDIT_FRAME::OnLoadCmpToFootprintLinkFile )
EVT_TOOL( ID_SCH_MOVE_ITEM, SCH_EDIT_FRAME::OnMoveItem )
+ EVT_TOOL( ID_AUTOPLACE_FIELDS, SCH_EDIT_FRAME::OnAutoplaceFields )
EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
@@ -1119,6 +1120,9 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event )
libeditFrame->LoadComponentAndSelectLib( entry, library );
}
}
+
+ GetScreen()->SchematicCleanUp( m_canvas, NULL );
+ m_canvas->Refresh();
}
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index 0db8ea8..f7309bc 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -146,6 +146,10 @@ private:
bool m_forceHVLines; ///< force H or V directions for wires, bus, line
+ bool m_autoplaceFields; ///< automatically place component fields
+ bool m_autoplaceJustify; ///< allow autoplace to change justification
+ bool m_autoplaceAlign; ///< align autoplaced fields to the grid
+
/// An index to the last find item in the found items list #m_foundItems.
int m_foundItemIndex;
@@ -765,6 +769,12 @@ public:
private:
/**
+ * Function OnAutoplaceFields
+ * handles the #ID_AUTOPLACE_FIELDS event.
+ */
+ void OnAutoplaceFields( wxCommandEvent& aEvent );
+
+ /**
* Function OnMoveItem
* handles the #ID_SCH_MOVE_ITEM event used to move schematic itams.
*/
diff --git a/include/bitmaps.h b/include/bitmaps.h
index c0711c8..67373b5 100644
--- a/include/bitmaps.h
+++ b/include/bitmaps.h
@@ -111,6 +111,7 @@ EXTERN_BITMAP( array_zone_xpm )
EXTERN_BITMAP( auto_associe_xpm )
EXTERN_BITMAP( auto_delete_track_xpm )
EXTERN_BITMAP( auto_track_width_xpm )
+EXTERN_BITMAP( autoplace_fields_xpm )
EXTERN_BITMAP( axis3d_back_xpm )
EXTERN_BITMAP( axis3d_bottom_xpm )
EXTERN_BITMAP( axis3d_front_xpm )
diff --git a/include/class_eda_rect.h b/include/class_eda_rect.h
index 57aa3a4..a38cc66 100644
--- a/include/class_eda_rect.h
+++ b/include/class_eda_rect.h
@@ -103,6 +103,7 @@ public:
int GetHeight() const { return m_Size.y; }
int GetRight() const { return m_Pos.x + m_Size.x; }
int GetLeft() const { return m_Pos.x; }
+ int GetTop() const { return m_Pos.y; }
int GetBottom() const { return m_Pos.y + m_Size.y; } // Y axis from top to bottom
void SetOrigin( const wxPoint& pos ) { m_Pos = pos; }
Follow ups
References