More stackup changes
[geda-pcb/pcjc2/v2.git] / src / set.c
blobd681e2fafbd166a8383982996f8061e665ea6ec4
1 /*!
2 * \file src/set.c
4 * \brief Routines to update widgets and global settings (except output
5 * window and dialogs).
7 * <hr>
9 * <h1><b>Copyright.</b></h1>\n
11 * PCB, interactive printed circuit board design
13 * Copyright (C) 1994,1995,1996 Thomas Nau
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * Contact addresses for paper mail and Email:
31 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
33 * Thomas.Nau@rz.uni-ulm.de
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
41 #include <math.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #ifdef HAVE_STRING_H
45 #include <string.h>
46 #endif
48 #include "global.h"
50 #include "action.h"
51 #include "buffer.h"
52 #include "compat.h"
53 #include "crosshair.h"
54 #include "data.h"
55 #include "draw.h"
56 #include "error.h"
57 #include "find.h"
58 #include "misc.h"
59 #include "move.h"
60 #include "set.h"
61 #include "undo.h"
62 #include "pcb-printf.h"
64 #ifdef HAVE_LIBDMALLOC
65 #include <dmalloc.h>
66 #endif
68 static int mode_position = 0;
69 static int mode_stack[MAX_MODESTACK_DEPTH];
71 /*!
72 * \brief Sets cursor grid with respect to grid offset values.
74 void
75 SetGrid (Coord Grid, bool align)
77 char *grid_string;
78 if (Grid >= 1 && Grid <= MAX_GRID)
80 if (align)
82 PCB->GridOffsetX = Crosshair.X % Grid;
83 PCB->GridOffsetY = Crosshair.Y % Grid;
85 PCB->Grid = Grid;
86 grid_string = pcb_g_strdup_printf ("%mr", Grid);
87 if (grid_string)
88 AttributePut (PCB, "PCB::grid::size", grid_string);
89 g_free (grid_string);
90 if (Settings.DrawGrid)
91 Redraw ();
95 /*!
96 * \brief Sets a new line thickness.
98 void
99 SetLineSize (Coord Size)
101 if (Size >= MIN_LINESIZE && Size <= MAX_LINESIZE)
103 Settings.LineThickness = Size;
104 if (TEST_FLAG (AUTODRCFLAG, PCB))
105 FitCrosshairIntoGrid (Crosshair.X, Crosshair.Y);
110 * \brief Sets a new via thickness.
112 void
113 SetViaSize (Coord Size, bool Force)
115 if (Force || (Size <= MAX_PINORVIASIZE &&
116 Size >= MIN_PINORVIASIZE &&
117 Size >= Settings.ViaDrillingHole + MIN_PINORVIACOPPER))
119 Settings.ViaThickness = Size;
124 * \brief Sets a new via drilling hole.
126 void
127 SetViaDrillingHole (Coord Size, bool Force)
129 if (Force || (Size <= MAX_PINORVIASIZE &&
130 Size >= MIN_PINORVIAHOLE &&
131 Size <= Settings.ViaThickness - MIN_PINORVIACOPPER))
133 Settings.ViaDrillingHole = Size;
137 void
138 pcb_use_route_style (RouteStyleType * rst)
140 Settings.LineThickness = rst->Thick;
141 Settings.ViaThickness = rst->Diameter;
142 Settings.ViaDrillingHole = rst->Hole;
143 Settings.Keepaway = rst->Keepaway;
147 * \brief Sets a keepaway width.
149 void
150 SetKeepawayWidth (Coord Width)
152 if (Width <= MAX_LINESIZE)
154 Settings.Keepaway = Width;
159 * \brief Sets a text scaling.
161 void
162 SetTextScale (int Scale)
164 if (Scale <= MAX_TEXTSCALE && Scale >= MIN_TEXTSCALE)
166 Settings.TextScale = Scale;
171 * \brief Sets or resets changed flag and redraws status.
173 void
174 SetChangedFlag (bool New)
176 if (PCB->Changed != New)
178 PCB->Changed = New;
184 * \brief Sets the crosshair range to the current buffer extents.
186 void
187 SetCrosshairRangeToBuffer (void)
189 if (Settings.Mode == PASTEBUFFER_MODE)
191 SetBufferBoundingBox (PASTEBUFFER);
192 SetCrosshairRange (PASTEBUFFER->X - PASTEBUFFER->BoundingBox.X1,
193 PASTEBUFFER->Y - PASTEBUFFER->BoundingBox.Y1,
194 PCB->MaxWidth -
195 (PASTEBUFFER->BoundingBox.X2 - PASTEBUFFER->X),
196 PCB->MaxHeight -
197 (PASTEBUFFER->BoundingBox.Y2 - PASTEBUFFER->Y));
202 * \brief Sets a new buffer number.
204 void
205 SetBufferNumber (int Number)
207 if (Number >= 0 && Number < MAX_BUFFER)
209 Settings.BufferNumber = Number;
211 /* do an update on the crosshair range */
212 SetCrosshairRangeToBuffer ();
217 * \brief Save mode.
219 void
220 SaveMode (void)
222 mode_stack[mode_position] = Settings.Mode;
223 if (mode_position < MAX_MODESTACK_DEPTH - 1)
224 mode_position++;
228 * \brief Restore mode.
230 void
231 RestoreMode (void)
233 if (mode_position == 0)
235 Message ("hace: underflow of restore mode\n");
236 return;
238 SetMode (mode_stack[--mode_position]);
243 * \brief Set a new mode and update X cursor.
245 * Protect the cursor while changing the mode.
247 * Perform some additional stuff depending on the new mode.
249 * Reset 'state' of attached objects.
251 void
252 SetMode (int Mode)
254 static bool recursing = false;
255 if (recursing)
256 return;
257 recursing = true;
258 notify_crosshair_change (false);
259 addedLines = 0;
260 Crosshair.AttachedObject.Type = NO_TYPE;
261 Crosshair.AttachedObject.State = STATE_FIRST;
262 Crosshair.AttachedPolygon.PointN = 0;
263 if (PCB->RatDraw)
265 if (Mode == ARC_MODE || Mode == RECTANGLE_MODE ||
266 Mode == VIA_MODE || Mode == POLYGON_MODE ||
267 Mode == POLYGONHOLE_MODE ||
268 Mode == TEXT_MODE || Mode == INSERTPOINT_MODE ||
269 Mode == THERMAL_MODE)
271 Message (_("That mode is NOT allowed when drawing ratlines!\n"));
272 Mode = NO_MODE;
275 if (Settings.Mode == LINE_MODE && Mode == ARC_MODE &&
276 Crosshair.AttachedLine.State != STATE_FIRST)
278 Crosshair.AttachedLine.State = STATE_FIRST;
279 Crosshair.AttachedBox.State = STATE_SECOND;
280 Crosshair.AttachedBox.Point1.X = Crosshair.AttachedBox.Point2.X =
281 Crosshair.AttachedLine.Point1.X;
282 Crosshair.AttachedBox.Point1.Y = Crosshair.AttachedBox.Point2.Y =
283 Crosshair.AttachedLine.Point1.Y;
284 AdjustAttachedObjects ();
286 else if (Settings.Mode == ARC_MODE && Mode == LINE_MODE &&
287 Crosshair.AttachedBox.State != STATE_FIRST)
289 Crosshair.AttachedBox.State = STATE_FIRST;
290 Crosshair.AttachedLine.State = STATE_SECOND;
291 Crosshair.AttachedLine.Point1.X = Crosshair.AttachedLine.Point2.X =
292 Crosshair.AttachedBox.Point1.X;
293 Crosshair.AttachedLine.Point1.Y = Crosshair.AttachedLine.Point2.Y =
294 Crosshair.AttachedBox.Point1.Y;
295 Settings.Mode = Mode;
296 AdjustAttachedObjects ();
298 /* Cancel rubberband move */
299 else if (Settings.Mode == MOVE_MODE)
300 MoveObjectAndRubberband (Crosshair.AttachedObject.Type,
301 Crosshair.AttachedObject.Ptr1,
302 Crosshair.AttachedObject.Ptr2,
303 Crosshair.AttachedObject.Ptr3,
304 0, 0);
305 else
307 if (Settings.Mode == ARC_MODE || Settings.Mode == LINE_MODE)
308 SetLocalRef (0, 0, false);
309 Crosshair.AttachedBox.State = STATE_FIRST;
310 Crosshair.AttachedLine.State = STATE_FIRST;
311 if (Mode == LINE_MODE && TEST_FLAG (AUTODRCFLAG, PCB))
313 if (ClearFlagOnAllObjects (true, CONNECTEDFLAG | FOUNDFLAG, true))
315 IncrementUndoSerialNumber ();
316 Draw ();
321 Settings.Mode = Mode;
323 if (Mode == PASTEBUFFER_MODE)
324 /* do an update on the crosshair range */
325 SetCrosshairRangeToBuffer ();
326 else
327 SetCrosshairRange (0, 0, PCB->MaxWidth, PCB->MaxHeight);
329 recursing = false;
331 /* force a crosshair grid update because the valid range
332 * may have changed
334 FitCrosshairIntoGrid (Crosshair.X, Crosshair.Y);
335 notify_crosshair_change (true);
339 * \brief Set route style.
341 void
342 SetRouteStyle (char *name)
344 char num[10];
346 STYLE_LOOP (PCB);
348 if (name && NSTRCMP (name, style->Name) == 0)
350 sprintf (num, "%d", n + 1);
351 hid_actionl ("RouteStyle", num, NULL);
352 break;
355 END_LOOP;
358 void
359 SetLocalRef (Coord X, Coord Y, bool Showing)
361 static _MarkType old;
362 static int count = 0;
364 if (Showing)
366 notify_mark_change (false);
367 if (count == 0)
368 old = Marked;
369 Marked.X = X;
370 Marked.Y = Y;
371 Marked.status = true;
372 count++;
373 notify_mark_change (true);
375 else if (count > 0)
377 notify_mark_change (false);
378 count = 0;
379 Marked = old;
380 notify_mark_change (true);