1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
27 #ifdef HAVE_LIBDMALLOC
31 static gboolean
o_find_test(GSCHEM_TOPLEVEL
*w_current
, OBJECT
*o_current
,
32 int w_x
, int w_y
, int w_slack
)
34 if (inside_region(o_current
->w_left
- w_slack
, o_current
->w_top
- w_slack
,
35 o_current
->w_right
+ w_slack
, o_current
->w_bottom
+ w_slack
,
37 o_shortest_distance(o_current
, w_x
, w_y
) < w_slack
) {
38 if (o_current
->selectable
&&
39 o_current
->type
!= OBJ_HEAD
&&
40 (o_current
->type
!= OBJ_TEXT
|| o_text_display_p(o_current
))) {
41 /* FIXME: should this switch be moved to o_select_object()? (Werner) */
42 /* FIXME: Move side effects out of this function. */
43 if (o_current
->type
== OBJ_NET
&& w_current
->net_selection_mode
) {
44 o_select_connected_nets(w_current
, o_current
);
46 o_select_object(w_current
, o_current
, SINGLE
, 0); /* 0 is count */
48 i_update_menus(w_current
);
56 struct find_object_context
{
57 GSCHEM_TOPLEVEL
*w_current
;
61 static enum visit_result
find_object_one(OBJECT
*o_current
, void *userdata
)
63 struct find_object_context
*ctx
= userdata
;
64 GSCHEM_TOPLEVEL
*w_current
= ctx
->w_current
;
65 TOPLEVEL
*toplevel
= w_current
->toplevel
;
66 PAGE
*page
= toplevel
->page_current
;
67 int w_x
= ctx
->w_x
, w_y
= ctx
->w_y
;
68 int w_slack
= WORLDabs(page
, w_current
->select_slack_pixels
);
70 if (o_current
== page
->object_lastfound
) {
71 return VISIT_RES_ABORT
;
74 if (o_find_test(w_current
, o_current
, w_x
, w_y
, w_slack
)) {
75 page
->object_lastfound
= o_current
;
76 return VISIT_RES_EARLY
;
82 /*! \todo Finish function documentation!!!
84 * \par Function Description
87 gboolean
o_find_object(GSCHEM_TOPLEVEL
*w_current
, int w_x
, int w_y
)
89 struct find_object_context ctx
= {
90 .w_current
= w_current
,
94 TOPLEVEL
*toplevel
= w_current
->toplevel
;
95 PAGE
*page
= toplevel
->page_current
;
96 enum visit_result found
;
98 /* Decide whether to iterate over all object or start at the last
99 found object. If there is more than one object below the
100 (w_x/w_y) position, this will select the next object below the
101 position point. You can change the selected object by clicking
102 at the same place multiple times. */
103 if (page
->object_lastfound
== NULL
) {
104 /* Start at the beginning of the page's object list. */
105 found
= s_visit_list(page
->object_head
, LIST_KIND_HEAD
,
106 &find_object_one
, &ctx
, VISIT_LINEAR
, 1);
108 /* Start at the next object after the last found one. */
109 found
= s_visit_list(page
->object_lastfound
, LIST_KIND_CDR
,
110 &find_object_one
, &ctx
, VISIT_LINEAR
, 1);
113 if (found
== VISIT_RES_EARLY
) {
118 printf("SEARCHING AGAIN\n");
121 if (page
->object_lastfound
!= NULL
) {
122 /* Cycle back to the head of the object list, up to object_lastfound. */
123 found
= s_visit_list(page
->object_head
, LIST_KIND_HEAD
,
124 &find_object_one
, &ctx
, VISIT_LINEAR
, 1);
125 if (found
== VISIT_RES_EARLY
) {
130 /* Didn't find anything; reset state. */
131 page
->object_lastfound
= NULL
;
133 /* deselect everything only if shift key isn't pressed and
134 the caller allows it */
135 if (!w_current
->SHIFTKEY
) {
136 o_select_unselect_all (w_current
);
139 i_update_menus(w_current
);
144 /*! \todo Finish function documentation!!!
146 * \par Function Description
149 gboolean
o_find_selected_object(GSCHEM_TOPLEVEL
*w_current
,
152 TOPLEVEL
*toplevel
= w_current
->toplevel
;
153 PAGE
*page
= toplevel
->page_current
;
154 OBJECT
*o_current
=NULL
;
158 w_slack
= WORLDabs(page
, w_current
->select_slack_pixels
);
160 s_current
= geda_list_get_glist(page
->selection_list
);
161 /* do first search */
162 while (s_current
!= NULL
) {
163 o_current
= s_current
->data
;
164 if (inside_region(o_current
->w_left
- w_slack
, o_current
->w_top
- w_slack
,
165 o_current
->w_right
+ w_slack
, o_current
->w_bottom
+ w_slack
,
169 printf("o_find_selected_object:\n");
170 printf("Object bounds:\n\tL: %i\tR: %i\n\tT: %i\tB: %i.\n",
171 o_current
->w_left
, o_current
->w_right
, o_current
->w_top
, o_current
->w_bottom
);
172 printf("Screen pointer at: (%i,%i)\n", w_x
, w_y
);
174 if (o_current
->selectable
&&
175 o_current
->type
!= OBJ_HEAD
&&
176 (o_current
->type
!= OBJ_TEXT
|| o_text_display_p(o_current
))) {
181 s_current
= g_list_next(s_current
);