1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2020 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 * <B>stroke_points</B> is an array of points for the stroke
28 * footprints. The points of the stroke are displayed over the display
29 * area of the main window. They have to be erased when the stroke is
30 * translated and the sequence evaluated.
32 * Its size will never exceed <B>STROKE_MAX_POINTS</B> (the limit in
33 * number of points of a stroke provided by libstroke).
39 static GArray
*stroke_points
= NULL
;
42 /*! \brief Initializes the stroke interface.
43 * \par Function Description
44 * This is the initialization function for the stroke interface. It
45 * initializes the libstroke library and prepare an array of points
46 * for the mouse footprints.
48 * This function has to be called only once at application
49 * initialization before any use of the stroke interface.
54 g_return_if_fail (stroke_points
== NULL
);
58 stroke_points
= g_array_new (FALSE
,
60 sizeof (StrokePoint
));
63 /*! \brief Frees memory of the stroke interface.
64 * \par Function Description
65 * This function frees the memory used for the mouse footprint
66 * points. It terminates the use of the stroke interface.
71 g_return_if_fail (stroke_points
!= NULL
);
73 g_array_free (stroke_points
, TRUE
);
77 /*! \brief Records a new point for the stroke.
78 * \par Function Description
79 * This function adds the point (<B>x</B>,<B>y</B>) as a new point in
82 * The footprint is updated and the new point is drawn on the drawing area.
84 * \param [in] w_current The GschemToplevel object.
85 * \param [in] x The X coord of the new point.
86 * \param [in] Y The X coord of the new point.
89 x_stroke_record (GschemToplevel
*w_current
, gint x
, gint y
)
91 cairo_matrix_t user_to_device_matrix
;
92 double x0
, y0
, x1
, y1
;
93 GschemPageView
*view
= gschem_toplevel_get_current_page_view (w_current
);
94 g_return_if_fail (view
!= NULL
);
95 GschemPageGeometry
*geometry
= gschem_page_view_get_page_geometry (view
);
96 g_return_if_fail (geometry
!= NULL
);
98 g_assert (stroke_points
!= NULL
);
100 stroke_record (x
, y
);
102 if (stroke_points
->len
< STROKE_MAX_POINTS
) {
103 StrokePoint point
= { x
, y
};
105 g_array_append_val (stroke_points
, point
);
107 if (stroke_points
->len
== 1)
110 StrokePoint
*last_point
= &g_array_index (stroke_points
, StrokePoint
,
111 stroke_points
->len
- 2);
113 cairo_t
*cr
= gdk_cairo_create (gtk_widget_get_window (GTK_WIDGET(view
)));
114 COLOR
*color
= x_color_lookup (STROKE_COLOR
);
115 cairo_set_source_rgba (cr
,
121 cairo_set_matrix (cr
, gschem_page_geometry_get_world_to_screen_matrix (geometry
));
126 cairo_device_to_user (cr
, &x0
, &y0
);
127 cairo_device_to_user (cr
, &x1
, &y1
);
128 cairo_get_matrix (cr
, &user_to_device_matrix
);
130 cairo_identity_matrix (cr
);
132 cairo_matrix_transform_point (&user_to_device_matrix
, &x0
, &y0
);
133 cairo_matrix_transform_point (&user_to_device_matrix
, &x1
, &y1
);
135 cairo_move_to (cr
, x0
, y0
);
136 cairo_line_to (cr
, x1
, y1
);
144 /*! \brief Evaluates the stroke.
145 * \par Function Description
146 * This function transforms the stroke input so far in an action.
148 * It makes use of the guile procedure <B>eval-stroke</B> to evaluate
149 * the stroke sequence into a possible action. The mouse footprint is
150 * erased in this function.
152 * It returns 1 if the stroke has been successfully evaluated as an
153 * action. It returns 0 if libstroke failed to transform the stroke
154 * or there is no action attached to the stroke.
156 * \param [in] w_current The GschemToplevel object.
157 * \returns 1 on success, 0 otherwise.
160 x_stroke_translate_and_execute (GschemToplevel
*w_current
)
162 gchar sequence
[STROKE_MAX_SEQUENCE
];
164 int min_x
, min_y
, max_x
, max_y
;
167 g_assert (stroke_points
!= NULL
);
169 if (stroke_points
->len
== 0)
172 point
= &g_array_index (stroke_points
, StrokePoint
, 0);
173 min_x
= max_x
= point
->x
;
174 min_y
= max_y
= point
->y
;
176 for (i
= 1; i
< stroke_points
->len
; i
++) {
177 point
= &g_array_index (stroke_points
, StrokePoint
, i
);
178 min_x
= min (min_x
, point
->x
);
179 min_y
= min (min_y
, point
->y
);
180 max_x
= max (max_x
, point
->x
);
181 max_y
= max (max_y
, point
->y
);
184 o_invalidate_rect (w_current
, min_x
, min_y
, max_x
+ 1, max_y
+ 1);
186 /* resets length of array */
187 stroke_points
->len
= 0;
189 /* try evaluating stroke */
190 if (stroke_trans ((char*)&sequence
)) {
191 gchar
*guile_string
=
192 g_strdup_printf("(eval-stroke \"%s\")", sequence
);
195 scm_dynwind_begin (0);
196 scm_dynwind_unwind_handler (g_free
, guile_string
, SCM_F_WIND_EXPLICITLY
);
197 ret
= g_scm_c_eval_string_protected (guile_string
);
200 return (SCM_NFALSEP (ret
));