gschem
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gschem - gEDA Schematic Capture 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2011 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 #include <config.h> 00021 00022 #include <stdio.h> 00023 #include <math.h> 00024 00025 #include "gschem.h" 00026 00027 #ifdef HAVE_LIBDMALLOC 00028 #include <dmalloc.h> 00029 #endif 00030 00044 void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current) 00045 { 00046 int x1, y1, x2, y2; 00047 00048 if (o_current->line == NULL) { 00049 return; 00050 } 00051 00052 if (!o_line_visible (w_current, o_current->line, &x1, &y1, &x2, &y2)) { 00053 return; 00054 } 00055 00056 gschem_cairo_line (w_current, o_current->line_end, 00057 o_current->line_width, 00058 x1, y1, x2, y2); 00059 00060 gschem_cairo_set_source_color (w_current, 00061 o_drawing_color (w_current, o_current)); 00062 gschem_cairo_stroke (w_current, o_current->line_type, 00063 o_current->line_end, 00064 o_current->line_width, 00065 o_current->line_length, 00066 o_current->line_space); 00067 00068 if (o_current->selected && w_current->draw_grips) { 00069 o_line_draw_grips (w_current, o_current); 00070 } 00071 } 00072 00073 00078 void o_line_invalidate_rubber (GSCHEM_TOPLEVEL *w_current) 00079 { 00080 int x1, y1, x2, y2; 00081 00082 WORLDtoSCREEN (w_current, w_current->first_wx, w_current->first_wy, &x1, &y1); 00083 WORLDtoSCREEN (w_current, w_current->second_wx, w_current->second_wy, &x2, &y2); 00084 00085 o_invalidate_rect (w_current, x1, y1, x2, y2); 00086 } 00087 00099 void o_line_draw_place (GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current) 00100 { 00101 if (o_current->line == NULL) { 00102 return; 00103 } 00104 00105 gschem_cairo_line (w_current, END_NONE, 0, 00106 o_current->line->x[0] + dx, o_current->line->y[0] + dy, 00107 o_current->line->x[1] + dx, o_current->line->y[1] + dy); 00108 gschem_cairo_set_source_color (w_current, 00109 x_color_lookup_dark (o_current->color)); 00110 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, 0, -1, -1); 00111 } 00112 00129 void o_line_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) 00130 { 00131 /* init first_w[x|y], second_w[x|y] to describe line */ 00132 w_current->first_wx = w_current->second_wx = w_x; 00133 w_current->first_wy = w_current->second_wy = w_y; 00134 00135 o_line_invalidate_rubber (w_current); 00136 w_current->rubber_visible = 1; 00137 } 00138 00153 void o_line_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) 00154 { 00155 TOPLEVEL *toplevel = w_current->toplevel; 00156 OBJECT *new_obj; 00157 00158 g_assert( w_current->inside_action != 0 ); 00159 00160 /* Don't bother.. the real object is invalidated, its in the same place */ 00161 /* o_line_invalidate_rubber (w_current); */ 00162 w_current->rubber_visible = 0; 00163 00164 /* don't allow zero length lines */ 00165 if ( (w_current->first_wx == w_current->second_wx) && 00166 (w_current->first_wy == w_current->second_wy) ) { 00167 return; 00168 } 00169 00170 /* create the line object and draw it */ 00171 new_obj = o_line_new (toplevel, OBJ_LINE, GRAPHIC_COLOR, 00172 w_current->first_wx, w_current->first_wy, 00173 w_current->second_wx, w_current->second_wy); 00174 s_page_append (toplevel, toplevel->page_current, new_obj); 00175 00176 /* Call add-objects-hook */ 00177 g_run_hook_object (w_current, "%add-objects-hook", new_obj); 00178 00179 toplevel->page_current->CHANGED=1; 00180 o_undo_savestate(w_current, UNDO_ALL); 00181 } 00182 00196 void o_line_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) 00197 { 00198 int diff_x, diff_y; 00199 00200 g_assert( w_current->inside_action != 0 ); 00201 00202 if (w_current->rubber_visible) 00203 o_line_invalidate_rubber (w_current); 00204 00205 /* 00206 * The coordinates of the moving end of the line are updated. Its new 00207 * coordinates are in <B>w_x</B> and <B>w_y</B> parameters and saved to 00208 * <B>w_current->second_wx</B> and <B>w_current->second_wy</B> respectively. 00209 */ 00210 w_current->second_wx = w_x; 00211 w_current->second_wy = w_y; 00212 00213 /* if the control key was pressed then draw ortho lines */ 00214 if (w_current->CONTROLKEY) { 00215 diff_x = abs(w_current->second_wx - w_current->first_wx); 00216 diff_y = abs(w_current->second_wy - w_current->first_wy); 00217 00218 if (diff_x >= diff_y) { 00219 w_current->second_wy = w_current->first_wy; 00220 } else { 00221 w_current->second_wx = w_current->first_wx; 00222 } 00223 } 00224 00225 o_line_invalidate_rubber (w_current); 00226 w_current->rubber_visible = 1; 00227 } 00228 00238 void o_line_draw_rubber (GSCHEM_TOPLEVEL *w_current) 00239 { 00240 gschem_cairo_line (w_current, END_NONE, 0, 00241 w_current->first_wx, w_current->first_wy, 00242 w_current->second_wx, w_current->second_wy); 00243 00244 gschem_cairo_set_source_color (w_current, 00245 x_color_lookup_dark (SELECT_COLOR)); 00246 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, 0, -1, -1); 00247 } 00248 00258 void o_line_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current) 00259 { 00260 if (w_current->draw_grips == FALSE) 00261 return; 00262 00263 /* draw the grip on line end 1 */ 00264 o_grips_draw(w_current, o_current->line->x[0], o_current->line->y[0]); 00265 00266 /* draw the grip on line end 2 */ 00267 o_grips_draw(w_current, o_current->line->x[1], o_current->line->y[1]); 00268 } 00269 00270 00282 int o_line_visible (GSCHEM_TOPLEVEL *w_current, LINE *line, 00283 int *x1, int *y1, int *x2, int *y2) 00284 { 00285 *x1 = line->x[0]; *y1 = line->y[0]; 00286 *x2 = line->x[1]; *y2 = line->y[1]; 00287 00288 /* Do we want to skip clipping? */ 00289 if (!w_current->toplevel->object_clipping) 00290 return TRUE; 00291 00292 return WORLDclip_change (w_current, x1, y1, x2, y2); 00293 }