Mail Archives: geda-user/2015/10/14/20:41:27
X-Authentication-Warning: | delorie.com: mail set sender to geda-user-bounces using -f
|
X-Recipient: | geda-user AT delorie DOT com
|
To: | geda-user AT delorie DOT com
|
From: | Robert Drehmel <robert AT zoot DOT drehmel DOT com>
|
Subject: | [geda-user] Highlighting traces
|
Message-ID: | <561EF5FE.9070706@zoot.drehmel.com>
|
Date: | Thu, 15 Oct 2015 02:40:30 +0200
|
User-Agent: | Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101
|
| Thunderbird/38.3.0
|
MIME-Version: | 1.0
|
X-Provags-ID: | V03:K0:++lb+GGUy/yIEGWWmNENwSmA4HT4JWTNHjkl/s6ddQigRAjZTvf
|
| dX71OnrHAmhfckknnP1mFEwXcqJV3Jn3HNtEnUsDzYODR66Y017UIdR0VkJcEsktFFJ/GqQ
|
| 6fA7VIFmrC9DHFGofub/HNdb0NNWlm8DynqdAEYlzpp8a3KspVjoDLVmakbXStTSRcO4kAc
|
| db3fFWI97mk+Q1z5q1WLA==
|
X-UI-Out-Filterresults: | notjunk:1;V01:K0:+mPnuF2xCzs=:URUZij8K6KVgItFG419H0Q
|
| Vv06PPImvSbK4/H6pFUJ5J1GnvC4hxPicY0KmeC7viMI0SPhNh6Flu+ZdeBh0fnjsYovy/5He
|
| cDXFmzw7CyLeCj0av8OmI+qABYCIQ94ocWXjXzTta2/VI7wkR5U0gTr6174Wik1zUKyu1Wo1e
|
| nalYsZkghoviBX4XT6Ula0rZWDA5PlFZ6/irv/PsMAG2qYmqTDXNa2/HFCVefdfZOtyyWou59
|
| Y2ubez6dSk8lun7qUUQvvF0PmtdzzzGTT+o7ArcPPeI2NoKccpyunUCl2htSmcMvlgE0Xo8r4
|
| K2FKoUuK105O92pTYY0aU1NLfOlOEPb8fmx/8O9txFy9CmRkEx5Z5ol3tjoHYtqArwlH1YyDk
|
| eUlyOa0mvtJLsQtbzTqTEYQlYGJqattLuV8E6c8K0ezJZWtRKqScQkiMzqBfiU+uw8IzG++Cv
|
| YJ/i5edOQOt5kJdOhUXvjyQwZkJjvoKBrGXUnVtmokqDjBVJI0DzZ2lbCwvyDneT8lj/0AyjV
|
| sTN4ySa8R1hKLyPKFINv7sY7cfT0y3jfb1Cx57T6lHm83gPTwrC37MujuB5sC5Fc8dU7ORN2H
|
| QZ7N4bwuVuGo8sqSzepf3mshkpht/E2VtqsuPZtDh0sYtxsVvlrU6eJzDbYZzL1Tp8YkLFFBc
|
| 0BMV97O7BTg5wyVcxz81bJL98k+fs5cFTdzVqSdAQOmvDDFIYV9q9TAKypiux9ZPN3CA=
|
Reply-To: | geda-user AT delorie DOT com
|
This is a multi-part message in MIME format.
--------------000708030003070003020603
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit
Hi.
When (e.g.) routing 5mm power traces on a small grid, it's not always easy to hit the
point where the trace ended (which is the center of the semicircle at the end of the
line) to start the next line. If you have selected the line tool, finding the end of
the line can become guesswork as the cursor doesn't change shape like it does with the
select tool.
I want my traces to consist of lines and arcs that are perfectly connected and I want
to work as fast as possible.
Attached is a small patch that
- makes it possible to deactivate snapping to "some sensible point along a line".
(that's what a comment in the code says). This snapping algorithm gets in the way
sometimes so you have to slowly go over a line to find out where it really ends,
bouncing back and forth between the points of the small grid, the end of the line
and these "sensible points", which is wasting time. The command is
"Display(ToggleSnapOffGridLine)". It is still activated by default to avoid
violating POLA.
- more importantly, introduces a new command called "Display(ToggleHighlightOnPoint)"
that highlights all lines and arcs which have (end)points exactly on the position
where the cross hair is currently snapped to. It therefore helps finding the end
points of lines and arcs, but sometimes also shows redundant traces, traces that
aren't perfectly connected to each other, traces that don't end directly on the
center of a via but should, etc. It works with thin draw too and I tested it with
gtk and lesstif.
I use the second option mostly in conjunction with deactivating the first. Both commands
have been added to the menu by means of (g)pcb-menu.res.in and are available as command
line options as well.
Caveats:
- The HID API expects all HIDs to make a copy of the color string when setting a color.
- The function that lightens up a color could be improved.
- I used it for a while, but after porting it from my local fork, it probably needs
more testing.
Maybe someone else finds it useful.
Best regards,
Robert
--------------000708030003070003020603
Content-Type: text/x-patch;
name="pcb-onpoint.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="pcb-onpoint.diff"
diff --git a/src/action.c b/src/action.c
index 0be31ab..fd21d0e 100644
--- a/src/action.c
+++ b/src/action.c
@@ -198,6 +198,8 @@ typedef enum
F_ToggleRubberBandMode,
F_ToggleStartDirection,
F_ToggleSnapPin,
+ F_ToggleSnapOffGridLine,
+ F_ToggleHighlightOnPoint,
F_ToggleThindraw,
F_ToggleLockNames,
F_ToggleOnlyNames,
@@ -429,6 +431,8 @@ static FunctionType Functions[] = {
{"ToggleRubberBandMode", F_ToggleRubberBandMode},
{"ToggleStartDirection", F_ToggleStartDirection},
{"ToggleSnapPin", F_ToggleSnapPin},
+ {"ToggleSnapOffGridLine", F_ToggleSnapOffGridLine},
+ {"ToggleHighlightOnPoint", F_ToggleHighlightOnPoint},
{"ToggleThindraw", F_ToggleThindraw},
{"ToggleThindrawPoly", F_ToggleThindrawPoly},
{"ToggleLockNames", F_ToggleLockNames},
@@ -2492,7 +2496,8 @@ static const char display_syntax[] =
"Display(Grid|Redraw)\n"
"Display(CycleClip|CycleCrosshair|Toggle45Degree|ToggleStartDirection)\n"
"Display(ToggleGrid|ToggleRubberBandMode|ToggleUniqueNames)\n"
- "Display(ToggleMask|ToggleName|ToggleClearLine|ToggleFullPoly|ToggleSnapPin)\n"
+ "Display(ToggleMask|ToggleName|ToggleClearLine|ToggleFullPoly)\n"
+ "Display(ToggleSnapPin|ToggleSnapOffGridLine|ToggleHighlightOnPoint)\n"
"Display(ToggleThindraw|ToggleThindrawPoly|ToggleOrthoMove|ToggleLocalRef)\n"
"Display(ToggleCheckPlanes|ToggleShowDRC|ToggleAutoDRC)\n"
"Display(ToggleLiveRoute|LockNames|OnlyNames)\n"
@@ -2541,6 +2546,13 @@ match that of another element.
If set, pin centers and pad end points are treated as additional grid
points that the cursor can snap to.
+@item ToggleSnapOffGridLine
+If set, snap at some sensible point along a line.
+
+@item ToggleHighlightOnPoint
+If set, highlights lines and arcs when the crosshair is on one of their
+two (end) points.
+
@item ToggleLocalRef
If set, the mark is automatically set to the beginning of any move, so
you can see the relative distance you've moved.
@@ -2742,6 +2754,18 @@ ActionDisplay (int argc, char **argv, Coord childX, Coord childY)
notify_crosshair_change (true);
break;
+ case F_ToggleSnapOffGridLine:
+ notify_crosshair_change (false);
+ TOGGLE_FLAG (SNAPOFFGRIDLINEFLAG, PCB);
+ notify_crosshair_change (true);
+ break;
+
+ case F_ToggleHighlightOnPoint:
+ notify_crosshair_change (false);
+ TOGGLE_FLAG (HIGHLIGHTONPOINTFLAG, PCB);
+ notify_crosshair_change (true);
+ break;
+
case F_ToggleLocalRef:
TOGGLE_FLAG (LOCALREFFLAG, PCB);
break;
diff --git a/src/const.h b/src/const.h
index 3798251..d341854 100644
--- a/src/const.h
+++ b/src/const.h
@@ -268,9 +268,9 @@ If set, this object has been as physically connected by @code{FindConnection()}.
also pinout text for pins is vertical */
#define VISITFLAG 0x8000 /*!< marker to avoid re-visiting an object */
#define CONNECTEDFLAG 0x10000 /*!< flag like FOUND flag, but used to identify physically connected objects (not rats) */
+#define ONPOINTFLAG 0x20000 /*!< crosshair is on line point or arc point */
-
-#define NOCOPY_FLAGS (FOUNDFLAG | CONNECTEDFLAG)
+#define NOCOPY_FLAGS (FOUNDFLAG | CONNECTEDFLAG | ONPOINTFLAG)
/* ---------------------------------------------------------------------------
* PCB flags
@@ -327,10 +327,14 @@ Everything but names are locked, the mouse cannot select anything else.
New polygons are full polygons.
@item 0x200000
When set, element names are not drawn.
+@item 0x400000
+snap to certain off-grid points.
+@item 0x800000
+highlight lines and arcs when the crosshair is on one of their endpoints.
@end table
%end-doc */
-#define PCB_FLAGS 0x000fffff /* all used flags */
+#define PCB_FLAGS 0x00ffffff /* all used flags */
#define SHOWNUMBERFLAG 0x00000001
#define LOCALREFFLAG 0x00000002
@@ -354,6 +358,8 @@ When set, element names are not drawn.
#define ONLYNAMESFLAG 0x00080000
#define NEWFULLPOLYFLAG 0x00100000
#define HIDENAMESFLAG 0x00200000
+#define SNAPOFFGRIDLINEFLAG 0x00400000
+#define HIGHLIGHTONPOINTFLAG 0x00800000
/* ---------------------------------------------------------------------------
* object types
diff --git a/src/create.c b/src/create.c
index 5907a1f..8039a9c 100644
--- a/src/create.c
+++ b/src/create.c
@@ -177,6 +177,10 @@ CreateNewPCB (void)
SET_FLAG (UNIQUENAMEFLAG, ptr);
if (Settings.SnapPin)
SET_FLAG (SNAPPINFLAG, ptr);
+ if (Settings.SnapOffGridLine)
+ SET_FLAG (SNAPOFFGRIDLINEFLAG, ptr);
+ if (Settings.HighlightOnPoint)
+ SET_FLAG (HIGHLIGHTONPOINTFLAG, ptr);
if (Settings.ClearLine)
SET_FLAG (CLEARNEWFLAG, ptr);
if (Settings.FullPoly)
diff --git a/src/crosshair.c b/src/crosshair.c
index fb2ceca..bb7bd1d 100644
--- a/src/crosshair.c
+++ b/src/crosshair.c
@@ -36,10 +36,12 @@
#include <memory.h>
#include <math.h>
+#include <glib.h>
#include "global.h"
#include "hid_draw.h"
+#include "box.h"
#include "crosshair.h"
#include "data.h"
#include "draw.h"
@@ -47,6 +49,7 @@
#include "line.h"
#include "misc.h"
#include "mymem.h"
+#include "rtree.h"
#include "search.h"
#include "polygon.h"
@@ -789,6 +792,163 @@ RestoreCrosshair (void)
notify_mark_change (true);
}
+/*
+ * Below is the implementation of the "highlight on endpoint" functionality.
+ * This highlights lines and arcs when the crosshair is on of their (two)
+ * endpoints.
+ */
+struct onpoint_search_info {
+ CrosshairType *crosshair;
+ Coord X;
+ Coord Y;
+};
+
+static int
+onpoint_line_callback(const BoxType *box, void *cl)
+{
+ struct onpoint_search_info *info = (struct onpoint_search_info *)cl;
+ CrosshairType *crosshair = info->crosshair;
+ LineType *line = (LineType *)box;
+
+#ifdef DEBUG_ONPOINT
+ printf("X=%ld Y=%ld X1=%ld Y1=%ld X2=%ld Y2=%ld\n", info->X, info->Y,
+ line->Point1.X,
+ line->Point1.Y,
+ line->Point2.X,
+ line->Point2.Y);
+#endif
+ if ((line->Point1.X == info->X && line->Point1.Y == info->Y) ||
+ (line->Point2.X == info->X && line->Point2.Y == info->Y))
+ {
+ crosshair->onpoint_objs =
+ g_list_prepend(crosshair->onpoint_objs, line);
+ crosshair->onpoint_objs_types =
+ g_list_prepend(crosshair->onpoint_objs_types,
+ GINT_TO_POINTER(LINE_TYPE));
+ SET_FLAG(ONPOINTFLAG, (AnyObjectType *)line);
+ DrawLine(NULL, line);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static int
+onpoint_arc_callback(const BoxType *box, void *cl)
+{
+ struct onpoint_search_info *info = (struct onpoint_search_info *)cl;
+ CrosshairType *crosshair = info->crosshair;
+ ArcType *arc = (ArcType *)box;
+
+ if ((arc->Point1.X == info->X && arc->Point1.Y == info->Y) ||
+ (arc->Point2.X == info->X && arc->Point2.Y == info->Y))
+ {
+ crosshair->onpoint_objs =
+ g_list_prepend(crosshair->onpoint_objs, arc);
+ crosshair->onpoint_objs_types =
+ g_list_prepend(crosshair->onpoint_objs_types, GINT_TO_POINTER(ARC_TYPE));
+ SET_FLAG(ONPOINTFLAG, (AnyObjectType *)arc);
+ DrawArc(NULL, arc);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void DrawLineOrArc(int type, void *obj)
+{
+ switch (type)
+ {
+ case LINEPOINT_TYPE:
+ /* Attention: We can use a NULL pointer here for the layer,
+ * because it is not used in the DrawLine() function anyways.
+ * ATM DrawLine() only alls AddPart() internally, which invalidates
+ * the area specified by the line's bounding box.
+ */
+ DrawLine(NULL, (LineType *)obj);
+ break;
+ case ARCPOINT_TYPE:
+ /* See comment above */
+ DrawArc(NULL, (ArcType *)obj);
+ break;
+ }
+}
+
+/*
+ * Searches for lines or arcs which have points that are exactly
+ * at the given coordinates and adds them to the crosshair's
+ * object list along with their respective type.
+ */
+static void
+onpoint_work(CrosshairType *crosshair, Coord X, Coord Y)
+{
+ BoxType SearchBox = point_box(X, Y);
+ struct onpoint_search_info info;
+ int i;
+ GList *lobjs, *ltypes;
+ GList *old_onpoint_objs = crosshair->onpoint_objs;
+ GList *old_onpoint_objs_types = crosshair->onpoint_objs_types;
+ bool redraw = false;
+
+ crosshair->onpoint_objs = NULL;
+ crosshair->onpoint_objs_types = NULL;
+
+ info.crosshair = crosshair;
+ info.X = X;
+ info.Y = Y;
+
+ for (i = 0; i < max_copper_layer; i++)
+ {
+ LayerType *layer = &PCB->Data->Layer[i];
+ /* Only find points of arcs and lines on currently visible layers. */
+ if (!layer->On)
+ continue;
+ r_search(layer->line_tree, &SearchBox, NULL,
+ onpoint_line_callback, &info);
+ r_search(layer->arc_tree, &SearchBox, NULL,
+ onpoint_arc_callback, &info);
+ }
+
+ /* Undraw the old objects */
+ for (lobjs = old_onpoint_objs, ltypes = old_onpoint_objs_types;
+ lobjs != NULL;
+ lobjs = lobjs->next, ltypes = ltypes->next)
+ {
+ /* only remove and redraw those which aren't in the new list */
+ if (g_list_find(crosshair->onpoint_objs, lobjs->data) != NULL)
+ continue;
+
+ CLEAR_FLAG(ONPOINTFLAG, (AnyObjectType *)lobjs->data);
+ DrawLineOrArc(GPOINTER_TO_INT(ltypes->data), lobjs->data);
+ redraw = true;
+ }
+
+ /* draw the new objects */
+ for (lobjs = crosshair->onpoint_objs,
+ ltypes = crosshair->onpoint_objs_types;
+ lobjs != NULL;
+ lobjs = lobjs->next, ltypes = ltypes->next)
+ {
+ /* only draw those which aren't in the old list */
+ if (g_list_find(old_onpoint_objs, lobjs->data) != NULL)
+ continue;
+ DrawLineOrArc(GPOINTER_TO_INT(ltypes->data), lobjs->data);
+ redraw = true;
+ }
+
+ g_list_free(old_onpoint_objs);
+ g_list_free(old_onpoint_objs_types);
+
+ if (redraw)
+ {
+ Redraw();
+ }
+}
+
/*!
* \brief Returns the square of the given number.
*/
@@ -1088,7 +1248,11 @@ FitCrosshairIntoGrid (Coord X, Coord Y)
check_snap_object (&snap_data, pnt->X, pnt->Y, true);
}
- check_snap_offgrid_line (&snap_data, nearest_grid_x, nearest_grid_y);
+ /*
+ * Snap to offgrid points on lines.
+ */
+ if (TEST_FLAG (SNAPOFFGRIDLINEFLAG, PCB))
+ check_snap_offgrid_line (&snap_data, nearest_grid_x, nearest_grid_y);
ans = NO_TYPE;
if (TEST_FLAG (SNAPPINFLAG, PCB))
@@ -1107,6 +1271,9 @@ FitCrosshairIntoGrid (Coord X, Coord Y)
Crosshair.Y = snap_data.y;
}
+ if (TEST_FLAG (HIGHLIGHTONPOINTFLAG, PCB))
+ onpoint_work(&Crosshair, Crosshair.X, Crosshair.Y);
+
if (Settings.Mode == ARROW_MODE)
{
ans = SearchObjectByLocation (LINEPOINT_TYPE | ARCPOINT_TYPE,
@@ -1189,6 +1356,10 @@ InitCrosshair (void)
Crosshair.MaxX = PCB->MaxWidth;
Crosshair.MaxY = PCB->MaxHeight;
+ /* Initialize the onpoint data. */
+ Crosshair.onpoint_objs = NULL;
+ Crosshair.onpoint_objs_types = NULL;
+
/* clear the mark */
Marked.status = false;
}
diff --git a/src/draw.c b/src/draw.c
index 3ba4266..cf1127a 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -87,9 +87,31 @@ static void DrawEMark (ElementType *, Coord, Coord, bool);
static void DrawRats (const BoxType *);
static void
+LightenColor(const char *orig, char buf[8], double factor)
+{
+ unsigned int r, g, b;
+
+ if (orig[0] == '#')
+ {
+ sscanf(&orig[1], "%2x%2x%2x", &r, &g, &b);
+ r = MIN(255, r * factor);
+ g = MIN(255, g * factor);
+ b = MIN(255, b * factor);
+ }
+ else
+ {
+ r = 0xff;
+ g = 0xff;
+ b = 0xff;
+ }
+ snprintf(buf, sizeof("#XXXXXX"), "#%02x%02x%02x", r, g, b);
+}
+
+static void
set_object_color (AnyObjectType *obj, char *warn_color, char *selected_color,
char *connected_color, char *found_color, char *normal_color)
{
+ char buf[sizeof("#XXXXXX")];
char *color;
if (warn_color != NULL && TEST_FLAG (WARNFLAG, obj)) color = warn_color;
@@ -98,6 +120,13 @@ set_object_color (AnyObjectType *obj, char *warn_color, char *selected_color,
else if (found_color != NULL && TEST_FLAG (FOUNDFLAG, obj)) color = found_color;
else color = normal_color;
+ if (TEST_FLAG(ONPOINTFLAG, obj))
+ {
+ assert(color != NULL);
+ LightenColor(color, buf, 1.75);
+ color = buf;
+ }
+
gui->graphics->set_color (Output.fgGC, color);
}
diff --git a/src/flags.c b/src/flags.c
index 471d497..6f058c3 100644
--- a/src/flags.c
+++ b/src/flags.c
@@ -252,6 +252,8 @@ HID_Flag flags_flag_list[] = {
{"onlynames", FlagTESTFLAG, GINT_TO_POINTER (ONLYNAMESFLAG)},
{"newfullpoly", FlagTESTFLAG, GINT_TO_POINTER (NEWFULLPOLYFLAG)},
{"hidenames", FlagTESTFLAG, GINT_TO_POINTER (HIDENAMESFLAG)},
+ {"snapoffgridline", FlagTESTFLAG, GINT_TO_POINTER (SNAPOFFGRIDLINEFLAG)},
+ {"highlightonpoint", FlagTESTFLAG, GINT_TO_POINTER (HIGHLIGHTONPOINTFLAG)},
{"grid_units_mm", FlagUnitsMm, NULL},
{"grid_units_mil", FlagUnitsMil, NULL},
diff --git a/src/global.h b/src/global.h
index cf91f03..3deba02 100644
--- a/src/global.h
+++ b/src/global.h
@@ -717,6 +717,8 @@ typedef struct
PolygonType AttachedPolygon;
AttachedObjectType AttachedObject; /*!< Data of attached objects. */
enum crosshair_shape shape; /*!< Shape of Crosshair. */
+ GList *onpoint_objs; /* list of associated lines/arc */
+ GList *onpoint_objs_types; /* ..and a list of their respective types */
} CrosshairType;
typedef struct
@@ -823,6 +825,8 @@ typedef struct
FullPoly,
UniqueNames, /*!< Force unique names. */
SnapPin, /*!< Snap to pins and pads. */
+ SnapOffGridLine, /*!< Snap to certain off-grid points along a line. */
+ HighlightOnPoint, /*!< Highlight if crosshair is on endpoints. */
ShowBottomSide, /*!< Mirror output. */
SaveLastCommand, /*!< Save the last command entered by user. */
SaveInTMP, /*!< Always save data in /tmp. */
diff --git a/src/gpcb-menu.res.in b/src/gpcb-menu.res.in
index 4cea179..adeeb5d 100644
--- a/src/gpcb-menu.res.in
+++ b/src/gpcb-menu.res.in
@@ -202,6 +202,7 @@ MainMenu =
{"Auto swap line start angle" checked=swapstartdir Display(ToggleStartDirection)}
{"Orthogonal moves" checked=orthomove Display(ToggleOrthoMove)}
{"Crosshair snaps to pins and pads" checked=snappin Display(ToggleSnapPin)}
+ {"Crosshair snaps to off-grid points on lines" checked=snapoffgridline Display(ToggleSnapOffGridLine)}
{"Crosshair shows DRC clearance" checked=showdrc Display(ToggleShowDRC)}
{"Auto enforce DRC clearance" checked=autodrc Display(ToggleAutoDRC)}
{"Lock Names" checked=locknames Display(ToggleLockNames)}
@@ -214,6 +215,7 @@ MainMenu =
{"New lines, arcs clear polygons" checked=clearnew Display(ToggleClearLine)}
{"New polygons are full ones" checked=newfullpoly Display(ToggleFullPoly)}
{"Show autorouter trials" checked=liveroute Display(ToggleLiveRoute)}
+ {"Highlighting on line, arc points" checked=highlightonpoint Display(ToggleHighlightOnPoint)}
{"Thin draw" checked=thindraw Display(ToggleThindraw) a={"|" "<Key>|"}}
{"Thin draw poly" checked=thindrawpoly Display(ToggleThindrawPoly) a={"Ctrl-Shift-P" "Ctrl Shift<Key>p"}}
{"Check polygons" checked=checkplanes Display(ToggleCheckPlanes)}
diff --git a/src/hid/gtk/gtkhid-gdk.c b/src/hid/gtk/gtkhid-gdk.c
index 8857c65..a490b3d 100644
--- a/src/hid/gtk/gtkhid-gdk.c
+++ b/src/hid/gtk/gtkhid-gdk.c
@@ -113,6 +113,8 @@ ghid_destroy_gc (hidGC gc)
{
if (gc->gc)
g_object_unref (gc->gc);
+ if (gc->colorname != NULL)
+ g_free(gc->colorname);
g_free (gc);
}
@@ -123,7 +125,7 @@ ghid_make_gc (void)
rv = g_new0 (hid_gc_struct, 1);
rv->me_pointer = &ghid_hid;
- rv->colorname = Settings.BackgroundColor;
+ rv->colorname = g_strdup(Settings.BackgroundColor);
return rv;
}
@@ -378,7 +380,13 @@ ghid_set_color (hidGC gc, const char *name)
name = "magenta";
}
- gc->colorname = (char *) name;
+ if (name != gc->colorname)
+ {
+ if (gc->colorname != NULL)
+ g_free(gc->colorname);
+ gc->colorname = g_strdup(name);
+ }
+
if (!gc->gc)
return;
if (gport->colormap == 0)
diff --git a/src/hid/gtk/gtkhid-gl.c b/src/hid/gtk/gtkhid-gl.c
index c67fbd1..82fa9d0 100644
--- a/src/hid/gtk/gtkhid-gl.c
+++ b/src/hid/gtk/gtkhid-gl.c
@@ -85,7 +85,7 @@ typedef struct hid_gc_struct
{
HID *me_pointer;
- const char *colorname;
+ char *colorname;
double alpha_mult;
Coord width;
gint cap, join;
@@ -198,6 +198,8 @@ ghid_end_layer (void)
void
ghid_destroy_gc (hidGC gc)
{
+ if (gc->colorname != NULL)
+ g_free(gc->colorname);
g_free (gc);
}
@@ -208,7 +210,7 @@ ghid_make_gc (void)
rv = g_new0 (hid_gc_struct, 1);
rv->me_pointer = &ghid_hid;
- rv->colorname = Settings.BackgroundColor;
+ rv->colorname = g_strdup(Settings.BackgroundColor);
rv->alpha_mult = 1.0;
return rv;
}
@@ -470,7 +472,12 @@ set_gl_color_for_gc (hidGC gc)
void
ghid_set_color (hidGC gc, const char *name)
{
- gc->colorname = name;
+ if (name != gc->colorname)
+ {
+ if (gc->colorname != NULL)
+ g_free((void *)gc->colorname);
+ gc->colorname = g_strdup(name);
+ }
set_gl_color_for_gc (gc);
}
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 2cb3393..e96e1cf 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -50,7 +50,7 @@ typedef struct hid_gc_struct
{
HID *me_pointer;
Pixel color;
- const char *colorname;
+ char *colorname;
int width;
EndCapStyle cap;
char xor_set;
@@ -3063,12 +3063,15 @@ lesstif_make_gc (void)
hidGC rv = (hid_gc_struct *) malloc (sizeof (hid_gc_struct));
memset (rv, 0, sizeof (hid_gc_struct));
rv->me_pointer = &lesstif_hid;
+ rv->colorname = NULL;
return rv;
}
static void
lesstif_destroy_gc (hidGC gc)
{
+ if (gc->colorname != NULL)
+ g_free(gc->colorname);
free (gc);
}
@@ -3137,7 +3140,14 @@ lesstif_set_color (hidGC gc, const char *name)
return;
if (!name)
name = "red";
- gc->colorname = name;
+
+ if (name != gc->colorname)
+ {
+ if (gc->colorname != NULL)
+ g_free(gc->colorname);
+ gc->colorname = g_strdup(name);
+ }
+
if (strcmp (name, "erase") == 0)
{
gc->color = bgcolor;
diff --git a/src/main.c b/src/main.c
index ce95361..c25e21a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1474,6 +1474,27 @@ that the cursor can snap to.
BSET (SnapPin, 1, "snap-pin",
"If set, the cursor snaps to pads and pin centers"),
+/* %start-doc options "2 General GUI Options"
+@ftable @code
+@item --snap-offgrid-line
+If set, the cursor snaps at sensible points along a line
+@end ftable
+%end-doc
+*/
+ BSET (SnapOffGridLine, 1, "snap-offgrid-line",
+ "If set, the cursor snaps at sensible points along a line"),
+
+/* %start-doc options "2 General GUI Options"
+@ftable @code
+@item --highlight-on-point
+If set, highlights lines and arcs when the crosshair is on one of their
+two (end) points.
+@end ftable
+%end-doc
+*/
+ BSET (HighlightOnPoint, 0, "highlight-on-point",
+ "If set, highlights lines and arcs when the cursor is on their endpoints"),
+
/* %start-doc options "1 General Options"
@ftable @code
@item --save-last-command
diff --git a/src/pcb-menu.res.in b/src/pcb-menu.res.in
index e37bd7c..b188a96 100644
--- a/src/pcb-menu.res.in
+++ b/src/pcb-menu.res.in
@@ -191,6 +191,7 @@ MainMenu =
{"Auto swap line start angle" checked=swapstartdir Display(ToggleStartDirection)}
{"Orthogonal moves" checked=orthomove Display(ToggleOrthoMove)}
{"Crosshair snaps to pins and pads" checked=snappin Display(ToggleSnapPin)}
+ {"Crosshair snaps to off-grid points on lines" checked=snapoffgridline Display(ToggleSnapOffGridLine)}
{"Crosshair shows DRC clearance" checked=showdrc Display(ToggleShowDRC)}
{"Auto enforce DRC clearance" checked=autodrc Display(ToggleAutoDRC)}
-
@@ -200,6 +201,7 @@ MainMenu =
{"New lines, arcs clear polygons" checked=clearnew Display(ToggleClearLine)}
{"New polygons are full ones" checked=newfullpoly Display(ToggleFullPoly)}
{"Show autorouter trials" checked=liveroute Display(ToggleLiveRoute)}
+ {"Highlighting on line, arc points" checked=highlightonpoint Display(ToggleHighlightOnPoint)}
{"Thin draw" checked=thindraw Display(ToggleThindraw) a={"|" "<Key>|"}}
{"Thin draw poly" checked=thindrawpoly Display(ToggleThindrawPoly) a={"Ctrl-Shift-P" "Ctrl Shift<Key>p"}}
{"Check polygons" checked=checkplanes Display(ToggleCheckPlanes)}
diff --git a/src/strflags.c b/src/strflags.c
index 38ff104..aee280c 100644
--- a/src/strflags.c
+++ b/src/strflags.c
@@ -129,6 +129,8 @@ static FlagBitsType pcb_flagbits[] = {
{ LOCKNAMESFLAG, N ("locknames"), ALL_TYPES },
{ ONLYNAMESFLAG, N ("onlynames"), ALL_TYPES },
{ HIDENAMESFLAG, N ("hidenames"), ALL_TYPES },
+ { SNAPOFFGRIDLINEFLAG, N ("snapoffgridline"), ALL_TYPES },
+ { HIGHLIGHTONPOINTFLAG, N ("highlightonpoint"), ALL_TYPES }
};
#undef N
--------------000708030003070003020603--
- Raw text -