Print the desired object's description.
[geda-gaf/berndj.git] / gschem / src / o_find.c
blob81b79641ab9fd999aedc867ae451307d08e5dec8
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
20 #include <config.h>
22 #include <math.h>
23 #include <stdio.h>
25 #include "gschem.h"
27 #ifdef HAVE_LIBDMALLOC
28 #include <dmalloc.h>
29 #endif
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,
36 w_x, w_y) &&
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);
45 } else {
46 o_select_object(w_current, o_current, SINGLE, 0); /* 0 is count */
48 i_update_menus(w_current);
49 return TRUE;
53 return FALSE;
56 struct find_object_context {
57 GSCHEM_TOPLEVEL *w_current;
58 int w_x, w_y;
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;
79 return VISIT_RES_OK;
82 /*! \todo Finish function documentation!!!
83 * \brief
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,
91 .w_x = w_x,
92 .w_y = w_y,
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);
107 } else {
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) {
114 return TRUE;
117 if (GEDA_DEBUG) {
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) {
126 return TRUE;
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);
141 return FALSE;
144 /*! \todo Finish function documentation!!!
145 * \brief
146 * \par Function Description
149 gboolean o_find_selected_object(GSCHEM_TOPLEVEL *w_current,
150 int w_x, int w_y)
152 TOPLEVEL *toplevel = w_current->toplevel;
153 PAGE *page = toplevel->page_current;
154 OBJECT *o_current=NULL;
155 GList *s_current;
156 int w_slack;
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,
166 w_x, w_y)) {
168 if (GEDA_DEBUG) {
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))) {
177 return TRUE;
181 s_current = g_list_next(s_current);
184 return (FALSE);