Index: trunk/src/crosshair.c =================================================================== --- trunk/src/crosshair.c (revision 32935) +++ trunk/src/crosshair.c (revision 32936) @@ -759,154 +759,6 @@ rnd_gui->notify_mark_change(rnd_gui, changes_complete); } - -/* - * Below is the implementation of the "highlight on endpoint" functionality. - * This highlights lines and arcs when the crosshair is on of their (two) - * endpoints. - */ -struct onpoint_search_info { - pcb_crosshair_t *crosshair; - rnd_coord_t X; - rnd_coord_t Y; -}; - -static rnd_r_dir_t onpoint_line_callback(const rnd_box_t * box, void *cl) -{ - struct onpoint_search_info *info = (struct onpoint_search_info *) cl; - pcb_crosshair_t *crosshair = info->crosshair; - pcb_line_t *line = (pcb_line_t *) box; - -#ifdef DEBUG_ONPOINT - printf("X=%ld Y=%ld X1=%ld Y1=%ld X2=%ld Y2=%ld\n", info->X, info->Y, - line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); -#endif - if ((line->Point1.X == info->X && line->Point1.Y == info->Y) || (line->Point2.X == info->X && line->Point2.Y == info->Y)) { - vtp0_append(&crosshair->onpoint_objs, line); - PCB_FLAG_SET(PCB_FLAG_ONPOINT, (pcb_any_obj_t *) line); - pcb_line_invalidate_draw(NULL, line); - return RND_R_DIR_FOUND_CONTINUE; - } - else - return RND_R_DIR_NOT_FOUND; -} - -#define close_enough(v1, v2) (coord_abs((v1)-(v2)) < 10) - -static rnd_r_dir_t onpoint_arc_callback(const rnd_box_t * box, void *cl) -{ - struct onpoint_search_info *info = (struct onpoint_search_info *) cl; - pcb_crosshair_t *crosshair = info->crosshair; - pcb_arc_t *arc = (pcb_arc_t *) box; - rnd_coord_t p1x, p1y, p2x, p2y; - - p1x = arc->X - arc->Width * cos(RND_TO_RADIANS(arc->StartAngle)); - p1y = arc->Y + arc->Height * sin(RND_TO_RADIANS(arc->StartAngle)); - p2x = arc->X - arc->Width * cos(RND_TO_RADIANS(arc->StartAngle + arc->Delta)); - p2y = arc->Y + arc->Height * sin(RND_TO_RADIANS(arc->StartAngle + arc->Delta)); - - /* printf("p1=%ld;%ld p2=%ld;%ld info=%ld;%ld\n", p1x, p1y, p2x, p2y, info->X, info->Y); */ - - if ((close_enough(p1x, info->X) && close_enough(p1y, info->Y)) || (close_enough(p2x, info->X) && close_enough(p2y, info->Y))) { - vtp0_append(&crosshair->onpoint_objs, arc); - PCB_FLAG_SET(PCB_FLAG_ONPOINT, (pcb_any_obj_t *) arc); - pcb_arc_invalidate_draw(NULL, arc); - return RND_R_DIR_FOUND_CONTINUE; - } - else - return RND_R_DIR_NOT_FOUND; -} - -static void draw_line_or_arc(pcb_any_obj_t *o) -{ - switch(o->type) { - case PCB_OBJ_LINE: pcb_line_invalidate_draw(o->parent.layer, (pcb_line_t *)o); break; - case PCB_OBJ_ARC: pcb_arc_invalidate_draw(o->parent.layer, (pcb_arc_t *)o); break; - break; - default: assert(!"draw_line_or_arc() expects line or arc point"); - } -} - - -#define op_swap(crosshair) \ -do { \ - vtp0_t __tmp__ = crosshair->onpoint_objs; \ - crosshair->onpoint_objs = crosshair->old_onpoint_objs; \ - crosshair->old_onpoint_objs = __tmp__; \ -} while(0) - -static void *onpoint_find(vtp0_t *vect, pcb_any_obj_t *obj_ptr) -{ - int i; - - for (i = 0; i < vect->used; i++) { - pcb_any_obj_t *op = vect->array[i]; - if (op == obj_ptr) - return op; - } - return NULL; -} - -/* - * Searches for lines or arcs which have points that are exactly - * at the given coordinates and adds them to the crosshair's - * object list along with their respective type. - */ -static void onpoint_work(pcb_crosshair_t * crosshair, rnd_coord_t X, rnd_coord_t Y) -{ - rnd_box_t SearchBox = rnd_point_box(X, Y); - struct onpoint_search_info info; - int i; - rnd_bool redraw = rnd_false; - - op_swap(crosshair); - - /* Do not truncate to 0 because that may free the array */ - vtp0_truncate(&crosshair->onpoint_objs, 1); - crosshair->onpoint_objs.used = 0; - - - info.crosshair = crosshair; - info.X = X; - info.Y = Y; - - for (i = 0; i < pcb_max_layer(PCB); i++) { - pcb_layer_t *layer = &PCB->Data->Layer[i]; - /* Only find points of arcs and lines on currently visible layers. */ - if (!layer->meta.real.vis) - continue; - rnd_r_search(layer->line_tree, &SearchBox, NULL, onpoint_line_callback, &info, NULL); - rnd_r_search(layer->arc_tree, &SearchBox, NULL, onpoint_arc_callback, &info, NULL); - } - - /* Undraw the old objects */ - for (i = 0; i < crosshair->old_onpoint_objs.used; i++) { - pcb_any_obj_t *op = crosshair->old_onpoint_objs.array[i]; - - /* only remove and redraw those which aren't in the new list */ - if (onpoint_find(&crosshair->onpoint_objs, op) != NULL) - continue; - - PCB_FLAG_CLEAR(PCB_FLAG_ONPOINT, op); - draw_line_or_arc(op); - redraw = rnd_true; - } - - /* draw the new objects */ - for (i = 0; i < crosshair->onpoint_objs.used; i++) { - pcb_any_obj_t *op = crosshair->onpoint_objs.array[i]; - - /* only draw those which aren't in the old list */ - if (onpoint_find(&crosshair->old_onpoint_objs, op) != NULL) - continue; - draw_line_or_arc(op); - redraw = rnd_true; - } - - if (redraw) - rnd_hid_redraw(PCB); -} - static double square(double x) { return x * x; @@ -1175,9 +1027,6 @@ PCB->hidlib.ch_x = pcb_crosshair.X = snap_data.x; PCB->hidlib.ch_y = pcb_crosshair.Y = snap_data.y; - if (conf_core.editor.highlight_on_point) - onpoint_work(&pcb_crosshair, pcb_crosshair.X, pcb_crosshair.Y); - if (newpos) rnd_event(hidlib, PCB_EVENT_CROSSHAIR_NEW_POS, NULL); @@ -1266,10 +1115,6 @@ */ void pcb_crosshair_init(void) { - /* Initialize the onpoint data. */ - memset(&pcb_crosshair.onpoint_objs, 0, sizeof(vtp0_t)); - memset(&pcb_crosshair.old_onpoint_objs, 0, sizeof(vtp0_t)); - /* clear the mark */ pcb_marked.status = rnd_false; Index: trunk/src_plugins/ch_onpoint/ch_onpoint.c =================================================================== --- trunk/src_plugins/ch_onpoint/ch_onpoint.c (revision 32935) +++ trunk/src_plugins/ch_onpoint/ch_onpoint.c (revision 32936) @@ -32,12 +32,176 @@ #include #include +#include +#include +#include "board.h" +#include "conf_core.h" +#include "crosshair.h" +#include "data.h" +#include "event.h" +static const char pcb_ch_onpoint_cookie[] = "ch_onpoint plugin"; + +/* + * Below is the implementation of the "highlight on endpoint" functionality. + * This highlights lines and arcs when the crosshair is on of their (two) + * endpoints. + */ +struct onpoint_search_info { + pcb_crosshair_t *crosshair; + rnd_coord_t X; + rnd_coord_t Y; +}; + +static rnd_r_dir_t onpoint_line_callback(const rnd_box_t * box, void *cl) +{ + struct onpoint_search_info *info = (struct onpoint_search_info *) cl; + pcb_crosshair_t *crosshair = info->crosshair; + pcb_line_t *line = (pcb_line_t *) box; + +#ifdef DEBUG_ONPOINT + printf("X=%ld Y=%ld X1=%ld Y1=%ld X2=%ld Y2=%ld\n", info->X, info->Y, + line->Point1.X, line->Point1.Y, line->Point2.X, line->Point2.Y); +#endif + if ((line->Point1.X == info->X && line->Point1.Y == info->Y) || (line->Point2.X == info->X && line->Point2.Y == info->Y)) { + vtp0_append(&crosshair->onpoint_objs, line); + PCB_FLAG_SET(PCB_FLAG_ONPOINT, (pcb_any_obj_t *) line); + pcb_line_invalidate_draw(NULL, line); + return RND_R_DIR_FOUND_CONTINUE; + } + else + return RND_R_DIR_NOT_FOUND; +} + +#define close_enough(v1, v2) (coord_abs((v1)-(v2)) < 10) + +static rnd_r_dir_t onpoint_arc_callback(const rnd_box_t * box, void *cl) +{ + struct onpoint_search_info *info = (struct onpoint_search_info *) cl; + pcb_crosshair_t *crosshair = info->crosshair; + pcb_arc_t *arc = (pcb_arc_t *) box; + rnd_coord_t p1x, p1y, p2x, p2y; + + p1x = arc->X - arc->Width * cos(RND_TO_RADIANS(arc->StartAngle)); + p1y = arc->Y + arc->Height * sin(RND_TO_RADIANS(arc->StartAngle)); + p2x = arc->X - arc->Width * cos(RND_TO_RADIANS(arc->StartAngle + arc->Delta)); + p2y = arc->Y + arc->Height * sin(RND_TO_RADIANS(arc->StartAngle + arc->Delta)); + + /* printf("p1=%ld;%ld p2=%ld;%ld info=%ld;%ld\n", p1x, p1y, p2x, p2y, info->X, info->Y); */ + + if ((close_enough(p1x, info->X) && close_enough(p1y, info->Y)) || (close_enough(p2x, info->X) && close_enough(p2y, info->Y))) { + vtp0_append(&crosshair->onpoint_objs, arc); + PCB_FLAG_SET(PCB_FLAG_ONPOINT, (pcb_any_obj_t *) arc); + pcb_arc_invalidate_draw(NULL, arc); + return RND_R_DIR_FOUND_CONTINUE; + } + else + return RND_R_DIR_NOT_FOUND; +} + +static void draw_line_or_arc(pcb_any_obj_t *o) +{ + switch(o->type) { + case PCB_OBJ_LINE: pcb_line_invalidate_draw(o->parent.layer, (pcb_line_t *)o); break; + case PCB_OBJ_ARC: pcb_arc_invalidate_draw(o->parent.layer, (pcb_arc_t *)o); break; + break; + default: assert(!"draw_line_or_arc() expects line or arc point"); + } +} + + +#define op_swap(crosshair) \ +do { \ + vtp0_t __tmp__ = crosshair->onpoint_objs; \ + crosshair->onpoint_objs = crosshair->old_onpoint_objs; \ + crosshair->old_onpoint_objs = __tmp__; \ +} while(0) + +static void *onpoint_find(vtp0_t *vect, pcb_any_obj_t *obj_ptr) +{ + int i; + + for (i = 0; i < vect->used; i++) { + pcb_any_obj_t *op = vect->array[i]; + if (op == obj_ptr) + return op; + } + return NULL; +} + +/* + * Searches for lines or arcs which have points that are exactly + * at the given coordinates and adds them to the crosshair's + * object list along with their respective type. + */ +static void onpoint_work(pcb_crosshair_t * crosshair, rnd_coord_t X, rnd_coord_t Y) +{ + rnd_box_t SearchBox = rnd_point_box(X, Y); + struct onpoint_search_info info; + int i; + rnd_bool redraw = rnd_false; + + op_swap(crosshair); + + /* Do not truncate to 0 because that may free the array */ + vtp0_truncate(&crosshair->onpoint_objs, 1); + crosshair->onpoint_objs.used = 0; + + + info.crosshair = crosshair; + info.X = X; + info.Y = Y; + + for (i = 0; i < pcb_max_layer(PCB); i++) { + pcb_layer_t *layer = &PCB->Data->Layer[i]; + /* Only find points of arcs and lines on currently visible layers. */ + if (!layer->meta.real.vis) + continue; + rnd_r_search(layer->line_tree, &SearchBox, NULL, onpoint_line_callback, &info, NULL); + rnd_r_search(layer->arc_tree, &SearchBox, NULL, onpoint_arc_callback, &info, NULL); + } + + /* Undraw the old objects */ + for (i = 0; i < crosshair->old_onpoint_objs.used; i++) { + pcb_any_obj_t *op = crosshair->old_onpoint_objs.array[i]; + + /* only remove and redraw those which aren't in the new list */ + if (onpoint_find(&crosshair->onpoint_objs, op) != NULL) + continue; + + PCB_FLAG_CLEAR(PCB_FLAG_ONPOINT, op); + draw_line_or_arc(op); + redraw = rnd_true; + } + + /* draw the new objects */ + for (i = 0; i < crosshair->onpoint_objs.used; i++) { + pcb_any_obj_t *op = crosshair->onpoint_objs.array[i]; + + /* only draw those which aren't in the old list */ + if (onpoint_find(&crosshair->old_onpoint_objs, op) != NULL) + continue; + draw_line_or_arc(op); + redraw = rnd_true; + } + + if (redraw) + rnd_hid_redraw(PCB); +} + +static void pcb_ch_onpoint(rnd_hidlib_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + rnd_trace("ch_onpoint %ml;%ml\n", pcb_crosshair.X, pcb_crosshair.Y); + if (conf_core.editor.highlight_on_point) + onpoint_work(&pcb_crosshair, pcb_crosshair.X, pcb_crosshair.Y); +} + int pplg_check_ver_ch_onpoint(int ver_needed) { return 0; } void pplg_uninit_ch_onpoint(void) { + rnd_event_unbind_allcookie(pcb_ch_onpoint_cookie); } int pplg_init_ch_onpoint(void) @@ -44,5 +208,11 @@ { RND_API_CHK_VER; + /* Initialize the onpoint data. */ + memset(&pcb_crosshair.onpoint_objs, 0, sizeof(vtp0_t)); + memset(&pcb_crosshair.old_onpoint_objs, 0, sizeof(vtp0_t)); + + rnd_event_bind(PCB_EVENT_CROSSHAIR_NEW_POS, pcb_ch_onpoint, NULL, pcb_ch_onpoint_cookie); + return 0; }