1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-11-22 18:11:53 +02:00

- README: described use of semicolons

- README: added that loops can also execute zero times
- accept labels only at the beginning of a line
- rectangles and lines no longer use the bounding box for drawing (caused
  offset problems since we now correct for the line width)
- dist_rect and inside_rect no longer require their input pre-sorted
- pad instances now have their own structure and no longer abuse the bounding
  box to know the pad coordinates
- Makefile: use $(GEN) for fig2dev, to reduce chattiness
- when dragging a point, the symbol is now adjusted accordingly
- added moving of rects, pads, circles, and arcs
- added creation of pads 
- moved rotate_r from gui_inst.c to coord.c
- new function "theta" that combines most of the angle calculations
- save_pix_buf: y < 0 clipping changed width, not height



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5386 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-04 21:45:33 +00:00
parent 8377ab0e0d
commit 5d7ab083a3
12 changed files with 315 additions and 75 deletions

View File

@ -74,7 +74,7 @@ endif
# sed '/2 2 0 1 /{s//2 2 0 15 /;s/ 0 7 / 22 7 /;}' $< | \ # sed '/2 2 0 1 /{s//2 2 0 15 /;s/ 0 7 / 22 7 /;}' $< | \
.fig.xpm: .fig.xpm:
fig2dev -L xpm -Z 0.32 -S 4 $< | \ $(GEN) fig2dev -L xpm -Z 0.32 -S 4 $< | \
convert -crop 24x24+1+1 - - | \ convert -crop 24x24+1+1 - - | \
sed "s/*.*\[]/*xpm_`basename $@ .xpm`[]/" >$@ sed "s/*.*\[]/*xpm_`basename $@ .xpm`[]/" >$@

8
README
View File

@ -50,7 +50,8 @@ with existing designs when introduction future language features.
fped uses the C preprocessor for comments, conditional compilation, fped uses the C preprocessor for comments, conditional compilation,
and - to a limited extent - also macros. Long lines can be split by and - to a limited extent - also macros. Long lines can be split by
ending them with a backslash. ending them with a backslash. If multiple items need to be placed in a
single line, e.g., in a macro, they can be separated with semicolons.
Geometry model Geometry model
@ -279,7 +280,10 @@ and
loop n = 1, 3.5 loop n = 1, 3.5
both assign the values 1, 2, and 3 to the variable "n". both assign the values 1, 2, and 3 to the variable "n". The
following loop would not execute at all:
loop n = 1, 0
When a loop is executed, the objects contained in the body of the When a loop is executed, the objects contained in the body of the
enclosing frame are generated for each value of the variable. If enclosing frame are generated for each value of the variable. If

1
TODO
View File

@ -18,6 +18,7 @@ Style:
Bugs: Bugs:
- default silk width has no business being hard-coded in obj.c - default silk width has no business being hard-coded in obj.c
- after moving, arc sometimes wrap the wrong way
Code cleanup: Code cleanup:
- merge edit_unique with edit_name - merge edit_unique with edit_name

65
coord.c
View File

@ -79,6 +79,54 @@ struct coord neg_vec(struct coord v)
} }
/* ----- point on circle --------------------------------------------------- */
struct coord rotate_r(struct coord c, unit_type r, double angle)
{
struct coord p;
angle = angle/180.0*M_PI;
p.x = c.x+r*cos(angle);
p.y = c.y+r*sin(angle);
return p;
}
double theta(struct coord c, struct coord p)
{
double a;
a = atan2(p.y-c.y, p.x-c.x)/M_PI*180.0;
if (a < 0)
a += 360.0;
return a;
}
/* ----- sorting coordinates ----------------------------------------------- */
void swap_coord(unit_type *a, unit_type *b)
{
unit_type tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void sort_coord(struct coord *min, struct coord *max)
{
if (min->x > max->x)
swap_coord(&min->x, &max->x);
if (min->y > max->y)
swap_coord(&min->y, &max->y);
}
/* ----- distance calculations --------------------------------------------- */ /* ----- distance calculations --------------------------------------------- */
@ -127,29 +175,30 @@ unit_type dist_line(struct coord p, struct coord a, struct coord b)
} }
unit_type dist_rect(struct coord p, struct coord min, struct coord max) unit_type dist_rect(struct coord p, struct coord a, struct coord b)
{ {
unit_type d_min, d; unit_type d_min, d;
d_min = dist_line_xy(p.x, p.y, min.x, min.y, max.x, min.y); d_min = dist_line_xy(p.x, p.y, a.x, a.y, b.x, a.y);
d = dist_line_xy(p.x, p.y, min.x, min.y, min.x, max.y); d = dist_line_xy(p.x, p.y, a.x, a.y, a.x, b.y);
if (d < d_min) if (d < d_min)
d_min = d; d_min = d;
d = dist_line_xy(p.x, p.y, min.x, max.y, max.x, max.y); d = dist_line_xy(p.x, p.y, a.x, b.y, b.x, b.y);
if (d < d_min) if (d < d_min)
d_min = d; d_min = d;
d = dist_line_xy(p.x, p.y, max.x, min.y, max.x, max.y); d = dist_line_xy(p.x, p.y, b.x, a.y, b.x, b.y);
if (d < d_min) if (d < d_min)
d_min = d; d_min = d;
return d_min; return d_min;
} }
int inside_rect(struct coord p, struct coord min, struct coord max) int inside_rect(struct coord p, struct coord a, struct coord b)
{ {
if (p.x < min.x || p.x > max.x) sort_coord(&a, &b);
if (p.x < a.x || p.x > b.x)
return 0; return 0;
if (p.y < min.y || p.y > max.y) if (p.y < a.y || p.y > b.y)
return 0; return 0;
return 1; return 1;
} }

10
coord.h
View File

@ -69,10 +69,16 @@ struct coord add_vec(struct coord a, struct coord b);
struct coord sub_vec(struct coord a, struct coord b); struct coord sub_vec(struct coord a, struct coord b);
struct coord neg_vec(struct coord v); struct coord neg_vec(struct coord v);
struct coord rotate_r(struct coord c, unit_type r, double angle);
double theta(struct coord c, struct coord p);
void swap_coord(unit_type *a, unit_type *b);
void sort_coord(struct coord *min, struct coord *max);
unit_type dist_point(struct coord a, struct coord b); unit_type dist_point(struct coord a, struct coord b);
unit_type dist_line(struct coord p, struct coord a, struct coord b); unit_type dist_line(struct coord p, struct coord a, struct coord b);
unit_type dist_rect(struct coord p, struct coord min, struct coord max); unit_type dist_rect(struct coord p, struct coord a, struct coord b);
int inside_rect(struct coord p, struct coord min, struct coord max); int inside_rect(struct coord p, struct coord a, struct coord b);
unit_type dist_circle(struct coord p, struct coord c, unit_type r); unit_type dist_circle(struct coord p, struct coord c, unit_type r);
#endif /* !COORD_H */ #endif /* !COORD_H */

2
fpd.l
View File

@ -93,7 +93,7 @@ SP [\t ]*
<INITIAL>"meas" { BEGIN(NOKEYWORD); <INITIAL>"meas" { BEGIN(NOKEYWORD);
return TOK_MEAS; } return TOK_MEAS; }
[a-zA-Z_][a-zA-Z_0-9]*: { *strchr(yytext, ':') = 0; <INITIAL>[a-zA-Z_][a-zA-Z_0-9]*: { *strchr(yytext, ':') = 0;
yylval.id = unique(yytext); yylval.id = unique(yytext);
return LABEL; } return LABEL; }
[a-zA-Z_][a-zA-Z_0-9]* { yylval.id = unique(yytext); [a-zA-Z_][a-zA-Z_0-9]* { yylval.id = unique(yytext);

View File

@ -176,7 +176,7 @@ unit_type gui_dist_line(struct inst *self, struct coord pos, unit_type scale)
r = self->u.rect.width/scale/2; r = self->u.rect.width/scale/2;
if (r < SELECT_R) if (r < SELECT_R)
r = SELECT_R; r = SELECT_R;
d = dist_line(pos, self->bbox.min, self->bbox.max)/scale; d = dist_line(pos, self->base, self->u.rect.end)/scale;
return d > r ? -1 : d; return d > r ? -1 : d;
} }
@ -203,21 +203,22 @@ unit_type gui_dist_rect(struct inst *self, struct coord pos, unit_type scale)
r = self->u.rect.width/scale/2; r = self->u.rect.width/scale/2;
if (r < SELECT_R) if (r < SELECT_R)
r = SELECT_R; r = SELECT_R;
d = dist_rect(pos, self->bbox.min, self->bbox.max)/scale; d = dist_rect(pos, self->base, self->u.rect.end)/scale;
return d > r ? -1 : d; return d > r ? -1 : d;
} }
void gui_draw_rect(struct inst *self, struct draw_ctx *ctx) void gui_draw_rect(struct inst *self, struct draw_ctx *ctx)
{ {
struct coord min = translate(ctx, self->bbox.min); struct coord min = translate(ctx, self->base);
struct coord max = translate(ctx, self->bbox.max); struct coord max = translate(ctx, self->u.rect.end);
GdkGC *gc; GdkGC *gc;
sort_coord(&min, &max);
gc = gc_obj[get_mode(self)]; gc = gc_obj[get_mode(self)];
set_width(gc, self->u.rect.width/ctx->scale); set_width(gc, self->u.rect.width/ctx->scale);
gdk_draw_rectangle(DA, gc, FALSE, gdk_draw_rectangle(DA, gc, FALSE,
min.x, max.y, max.x-min.x, min.y-max.y); min.x, min.y, max.x-min.x, max.y-min.y);
} }
@ -228,31 +229,32 @@ unit_type gui_dist_pad(struct inst *self, struct coord pos, unit_type scale)
{ {
unit_type d; unit_type d;
if (inside_rect(pos, self->bbox.min, self->bbox.max)) if (inside_rect(pos, self->base, self->u.pad.other))
return SELECT_R; return SELECT_R;
d = dist_rect(pos, self->bbox.min, self->bbox.max)/scale; d = dist_rect(pos, self->base, self->u.pad.other)/scale;
return d > SELECT_R ? -1 : d; return d > SELECT_R ? -1 : d;
} }
void gui_draw_pad(struct inst *self, struct draw_ctx *ctx) void gui_draw_pad(struct inst *self, struct draw_ctx *ctx)
{ {
struct coord min = translate(ctx, self->bbox.min); struct coord min = translate(ctx, self->base);
struct coord max = translate(ctx, self->bbox.max); struct coord max = translate(ctx, self->u.pad.other);
GdkGC *gc; GdkGC *gc;
struct coord c; struct coord c;
unit_type h, w; unit_type h, w;
gc = gc_pad[get_mode(self)]; gc = gc_pad[get_mode(self)];
sort_coord(&min, &max);
gdk_draw_rectangle(DA, gc, TRUE, gdk_draw_rectangle(DA, gc, TRUE,
min.x, max.y, max.x-min.x, min.y-max.y); min.x, min.y, max.x-min.x, max.y-min.y);
gc = gc_ptext[get_mode(self)]; gc = gc_ptext[get_mode(self)];
c = add_vec(min, max); c = add_vec(min, max);
h = min.y-max.y; h = max.y-min.y;
w = max.x-min.x; w = max.x-min.x;
render_text(DA, gc, c.x/2, c.y/2, w <= h*1.1 ? 0 : 90, self->u.name, render_text(DA, gc, c.x/2, c.y/2, w <= h*1.1 ? 0 : 90,
PAD_FONT, 0.5, 0.5, self->u.pad.name, PAD_FONT, 0.5, 0.5,
w-2*PAD_BORDER, h-2*PAD_BORDER); w-2*PAD_BORDER, h-2*PAD_BORDER);
} }
@ -260,17 +262,6 @@ void gui_draw_pad(struct inst *self, struct draw_ctx *ctx)
/* ----- arc --------------------------------------------------------------- */ /* ----- arc --------------------------------------------------------------- */
static struct coord rotate_r(struct coord center, unit_type r, double angle)
{
struct coord res;
angle = angle/180.0*M_PI;
res.x = center.x+r*cos(angle);
res.y = center.y+r*sin(angle);
return res;
}
unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale) unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale)
{ {
struct coord c = self->base; struct coord c = self->base;
@ -305,9 +296,7 @@ unit_type gui_dist_arc(struct inst *self, struct coord pos, unit_type scale)
/* see if we're close to the part that's actually drawn */ /* see if we're close to the part that's actually drawn */
angle = atan2(pos.y-c.y, pos.x-c.x)/M_PI*180.0; angle = theta(c, pos);
if (angle < 0)
angle += 180;
a2 = self->u.arc.a2; a2 = self->u.arc.a2;
if (a2 < self->u.arc.a1) if (a2 < self->u.arc.a1)
a2 += 180; a2 += 180;

View File

@ -65,7 +65,6 @@ static struct pix_buf *pix_buf;
static struct tool_ops vec_ops; static struct tool_ops vec_ops;
static struct tool_ops frame_ops; static struct tool_ops frame_ops;
static struct tool_ops pad_ops; static struct tool_ops pad_ops;
static struct tool_ops circ_ops;
static struct tool_ops meas_ops; static struct tool_ops meas_ops;
@ -101,6 +100,31 @@ static struct pix_buf *drag_new_line(struct draw_ctx *ctx,
} }
struct pix_buf *draw_move_line(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i)
{
struct coord from, to;
struct pix_buf *buf;
from = translate(ctx, inst->base);
to = translate(ctx, inst->u.rect.end);
pos = translate(ctx, pos);
switch (i) {
case 0:
from = pos;
break;
case 1:
to = pos;
break;
default:
abort();
}
buf = save_pix_buf(DA, from.x, from.y, to.x, to.y, 1);
gdk_draw_line(DA, gc_drag, from.x, from.y, to.x, to.y);
return buf;
}
static int end_new_line(struct draw_ctx *ctx, static int end_new_line(struct draw_ctx *ctx,
struct inst *from, struct inst *to) struct inst *from, struct inst *to)
{ {
@ -124,16 +148,6 @@ static struct tool_ops line_ops = {
/* ----- rect -------------------------------------------------------------- */ /* ----- rect -------------------------------------------------------------- */
static void swap_coord(unit_type *a, unit_type *b)
{
unit_type tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
static struct pix_buf *drag_new_rect(struct draw_ctx *ctx, static struct pix_buf *drag_new_rect(struct draw_ctx *ctx,
struct inst *from, struct coord to) struct inst *from, struct coord to)
{ {
@ -142,10 +156,7 @@ static struct pix_buf *drag_new_rect(struct draw_ctx *ctx,
pos = translate(ctx, inst_get_point(from)); pos = translate(ctx, inst_get_point(from));
to = translate(ctx, to); to = translate(ctx, to);
if (pos.x > to.x) sort_coord(&pos, &to);
swap_coord(&pos.x, &to.x);
if (pos.y > to.y)
swap_coord(&pos.y, &to.y);
buf = save_pix_buf(DA, pos.x, pos.y, to.x, to.y, 1); buf = save_pix_buf(DA, pos.x, pos.y, to.x, to.y, 1);
gdk_draw_rectangle(DA, gc_drag, FALSE, gdk_draw_rectangle(DA, gc_drag, FALSE,
pos.x, pos.y, to.x-pos.x, to.y-pos.y); pos.x, pos.y, to.x-pos.x, to.y-pos.y);
@ -153,6 +164,40 @@ static struct pix_buf *drag_new_rect(struct draw_ctx *ctx,
} }
static struct pix_buf *draw_move_rect_common(struct inst *inst,
struct coord other, struct draw_ctx *ctx, struct coord pos, int i)
{
struct coord min, max;
struct pix_buf *buf;
min = translate(ctx, inst->base);
max = translate(ctx, other);
pos = translate(ctx, pos);
switch (i) {
case 0:
min = pos;
break;
case 1:
max = pos;
break;
default:
abort();
}
sort_coord(&min, &max);
buf = save_pix_buf(DA, min.x, min.y, max.x, max.y, 1);
gdk_draw_rectangle(DA, gc_drag, FALSE,
min.x, min.y, max.x-min.x, max.y-min.y);
return buf;
}
struct pix_buf *draw_move_rect(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i)
{
return draw_move_rect_common(inst, inst->u.rect.end, ctx, pos, i);
}
static int end_new_rect(struct draw_ctx *ctx, static int end_new_rect(struct draw_ctx *ctx,
struct inst *from, struct inst *to) struct inst *from, struct inst *to)
{ {
@ -173,6 +218,36 @@ static struct tool_ops rect_ops = {
}; };
/* ----- pad --------------------------------------------------------------- */
static int end_new_pad(struct draw_ctx *ctx,
struct inst *from, struct inst *to)
{
struct obj *obj;
if (from == to)
return 0;
obj = new_obj(ot_pad, from);
obj->u.pad.other = inst_get_ref(to);
obj->u.pad.name = stralloc("?");
return 1;
}
struct pix_buf *draw_move_pad(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i)
{
return draw_move_rect_common(inst, inst->u.pad.other, ctx, pos, i);
}
static struct tool_ops pad_ops = {
.drag_new = drag_new_rect,
.end_new = end_new_pad,
};
/* ----- circ -------------------------------------------------------------- */ /* ----- circ -------------------------------------------------------------- */
@ -207,6 +282,83 @@ static int end_new_circ(struct draw_ctx *ctx,
} }
struct pix_buf *draw_move_arc(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i)
{
struct coord c, from, to;
double r, a1, a2;
struct pix_buf *buf;
c = translate(ctx, inst->base);
from =
translate(ctx, rotate_r(inst->base, inst->u.arc.r, inst->u.arc.a1));
to =
translate(ctx, rotate_r(inst->base, inst->u.arc.r, inst->u.arc.a2));
pos = translate(ctx, pos);
switch (i) {
case 0:
c = pos;
break;
case 1:
from = pos;
if (inst->obj->u.arc.start != inst->obj->u.arc.end)
break;
/* fall through */
case 2:
to = pos;
break;
default:
abort();
}
r = hypot(from.x-c.x, from.y-c.y);
/*
* the screen coordinate system is reversed with y growing downward,
* so we have to negate the angles.
*/
a1 = -theta(c, from);
a2 = -theta(c, to);
if (a2 < a1)
a2 += 360.0;
buf = save_pix_buf(DA, c.x-r, c.y-r, c.x+r, c.y+r, 1);
draw_arc(DA, gc_drag, FALSE, c.x, c.y, r, a1, a2);
return buf;
}
static void replace(struct vec **anchor, struct vec *new)
{
if (*anchor)
(*anchor)->n_refs--;
*anchor = new;
if (new)
new->n_refs++;
}
void do_move_to_arc(struct inst *inst, struct vec *vec, int i)
{
struct obj *obj = inst->obj;
int is_circle;
is_circle = obj->u.arc.start == obj->u.arc.end;
switch (i) {
case 0:
replace(&obj->base, vec);
break;
case 1:
replace(&obj->u.arc.start, vec);
if (!is_circle)
break;
/* fall through */
case 2:
replace(&obj->u.arc.end, vec);
break;
default:
abort();
}
}
static struct tool_ops circ_ops = { static struct tool_ops circ_ops = {
.drag_new = drag_new_circ, .drag_new = drag_new_circ,
.end_new = end_new_circ, .end_new = end_new_circ,
@ -274,7 +426,6 @@ static void do_move_to(struct drag_state *state, struct inst *curr)
if (old) if (old)
old->n_refs--; old->n_refs--;
*state->anchors[state->anchor_i] = inst_get_ref(curr); *state->anchors[state->anchor_i] = inst_get_ref(curr);
state->anchors_n = 0;
} }
@ -339,7 +490,8 @@ void tool_drag(struct draw_ctx *ctx, struct coord to)
if (pix_buf) if (pix_buf)
restore_pix_buf(pix_buf); restore_pix_buf(pix_buf);
tool_hover(ctx, to); tool_hover(ctx, to);
pix_buf = drag.new ? active_ops->drag_new(ctx, drag.new, to) : NULL; pix_buf = drag.new ? active_ops->drag_new(ctx, drag.new, to) :
inst_draw_move(selected_inst, ctx, to, drag.anchor_i);
} }
@ -369,6 +521,7 @@ int tool_end_drag(struct draw_ctx *ctx, struct coord to)
return ops->end_new(ctx, state.new, end); return ops->end_new(ctx, state.new, end);
if (!may_move_to(&state, end)) if (!may_move_to(&state, end))
return 0; return 0;
if (!inst_do_move_to(selected_inst, inst_get_vec(end), state.anchor_i))
do_move_to(&state, end); do_move_to(&state, end);
return 1; return 1;
} }

View File

@ -19,6 +19,17 @@
#include "inst.h" #include "inst.h"
struct pix_buf *draw_move_line(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i);
struct pix_buf *draw_move_rect(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i);
struct pix_buf *draw_move_pad(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i);
struct pix_buf *draw_move_arc(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i);
void do_move_to_arc(struct inst *inst, struct vec *vec, int i);
void tool_dehover(struct draw_ctx *ctx); void tool_dehover(struct draw_ctx *ctx);
void tool_hover(struct draw_ctx *ctx, struct coord pos); void tool_hover(struct draw_ctx *ctx, struct coord pos);
int tool_consider_drag(struct draw_ctx *ctx, struct coord pos); int tool_consider_drag(struct draw_ctx *ctx, struct coord pos);

View File

@ -79,7 +79,7 @@ struct pix_buf *save_pix_buf(GdkDrawable *da, int xa, int ya, int xb, int yb,
buf->x = 0; buf->x = 0;
} }
if (buf->y < 0) { if (buf->y < 0) {
w += buf->y; h += buf->y;
buf->y = 0; buf->y = 0;
} }
buf->buf = gdk_pixbuf_get_from_drawable(NULL, da, NULL, buf->buf = gdk_pixbuf_get_from_drawable(NULL, da, NULL,

50
inst.c
View File

@ -20,7 +20,7 @@
#include "expr.h" #include "expr.h"
#include "obj.h" #include "obj.h"
#include "gui_status.h" #include "gui_status.h"
#include "gui_status.h" #include "gui_tools.h"
#include "gui_inst.h" #include "gui_inst.h"
#include "inst.h" #include "inst.h"
@ -34,6 +34,10 @@ struct inst_ops {
unit_type scale); unit_type scale);
void (*select)(struct inst *self); void (*select)(struct inst *self);
int (*anchors)(struct inst *self, struct vec ***anchors); int (*anchors)(struct inst *self, struct vec ***anchors);
struct pix_buf *(*draw_move)(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i);
/* arcs need this special override */
void (*do_move_to)(struct inst *inst, struct vec *vec, int i);
}; };
enum inst_prio { enum inst_prio {
@ -269,9 +273,7 @@ static void rect_status(struct coord a, struct coord b, unit_type width)
if (!d.x && !d.y) if (!d.x && !d.y)
status_set_angle("a = 0 deg"); status_set_angle("a = 0 deg");
else { else {
angle = atan2(d.y, d.x)/M_PI*180.0; angle = theta(a, b);
if (angle < 0)
angle += 360;
status_set_angle("a = %3.1f deg", angle); status_set_angle("a = %3.1f deg", angle);
} }
status_set_r("r = %5.2f mm", hypot(units_to_mm(d.x), units_to_mm(d.y))); status_set_r("r = %5.2f mm", hypot(units_to_mm(d.x), units_to_mm(d.y)));
@ -432,6 +434,7 @@ static struct inst_ops line_ops = {
.distance = gui_dist_line, .distance = gui_dist_line,
.select = line_op_select, .select = line_op_select,
.anchors = line_op_anchors, .anchors = line_op_anchors,
.draw_move = draw_move_line,
}; };
@ -474,6 +477,7 @@ static struct inst_ops rect_ops = {
.distance = gui_dist_rect, .distance = gui_dist_rect,
.select = rect_op_select, .select = rect_op_select,
.anchors = line_op_anchors, .anchors = line_op_anchors,
.draw_move = draw_move_rect,
}; };
@ -498,8 +502,8 @@ int inst_rect(struct obj *obj, struct coord a, struct coord b, unit_type width)
static void pad_op_debug(struct inst *self) static void pad_op_debug(struct inst *self)
{ {
printf("pad \"%s\" %lg, %lg / %lg, %lg\n", self->u.name, printf("pad \"%s\" %lg, %lg / %lg, %lg\n", self->u.name,
units_to_mm(self->bbox.min.x), units_to_mm(self->bbox.min.y), units_to_mm(self->base.x), units_to_mm(self->base.y),
units_to_mm(self->bbox.max.x), units_to_mm(self->bbox.max.y)); units_to_mm(self->u.pad.other.x), units_to_mm(self->u.pad.other.y));
} }
@ -518,8 +522,8 @@ static int validate_pad_name(const char *s, void *ctx)
static void pad_op_select(struct inst *self) static void pad_op_select(struct inst *self)
{ {
status_set_type_entry("label ="); status_set_type_entry("label =");
status_set_name("%s", self->u.name); status_set_name("%s", self->u.pad.name);
rect_status(self->bbox.min, self->bbox.max, -1); rect_status(self->base, self->u.pad.other, -1);
edit_name(&self->obj->u.pad.name, validate_pad_name, NULL); edit_name(&self->obj->u.pad.name, validate_pad_name, NULL);
} }
@ -540,6 +544,7 @@ static struct inst_ops pad_ops = {
.distance = gui_dist_pad, .distance = gui_dist_pad,
.select = pad_op_select, .select = pad_op_select,
.anchors = pad_op_anchors, .anchors = pad_op_anchors,
.draw_move = draw_move_pad,
}; };
@ -549,7 +554,8 @@ int inst_pad(struct obj *obj, const char *name, struct coord a, struct coord b)
inst = add_inst(&pad_ops, ip_pad, a); inst = add_inst(&pad_ops, ip_pad, a);
inst->obj = obj; inst->obj = obj;
inst->u.name = stralloc(name); inst->u.pad.name = stralloc(name);
inst->u.pad.other = b;
update_bbox(&inst->bbox, b); update_bbox(&inst->bbox, b);
propagate_bbox(inst); propagate_bbox(inst);
return 1; return 1;
@ -597,6 +603,8 @@ static struct inst_ops arc_ops = {
.distance = gui_dist_arc, .distance = gui_dist_arc,
.select = arc_op_select, .select = arc_op_select,
.anchors = arc_op_anchors, .anchors = arc_op_anchors,
.draw_move = draw_move_arc,
.do_move_to = do_move_to_arc,
}; };
@ -609,13 +617,9 @@ int inst_arc(struct obj *obj, struct coord center, struct coord start,
inst = add_inst(&arc_ops, ip_arc, center); inst = add_inst(&arc_ops, ip_arc, center);
inst->obj = obj; inst->obj = obj;
r = hypot(start.x-center.x, start.y-center.y); r = hypot(start.x-center.x, start.y-center.y);
a1 = atan2(start.y-center.y, start.x-center.x)/M_PI*180.0;
a2 = atan2(end.y-center.y, end.x-center.x)/M_PI*180.0;
if (a1 < 0)
a1 += 360.0;
if (a2 < 0)
a2 += 360.0;
inst->u.arc.r = r; inst->u.arc.r = r;
a1 = theta(center, start);
a2 = theta(center, end);
inst->u.arc.a1 = a1; inst->u.arc.a1 = a1;
inst->u.arc.a2 = a2; inst->u.arc.a2 = a2;
inst->u.arc.width = width; inst->u.arc.width = width;
@ -834,6 +838,22 @@ void inst_draw(struct draw_ctx *ctx)
} }
struct pix_buf *inst_draw_move(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i)
{
return inst->ops->draw_move(inst, ctx, pos, i);
}
int inst_do_move_to(struct inst *inst, struct vec *vec, int i)
{
if (!inst->ops->do_move_to)
return 0;
inst->ops->do_move_to(inst, vec, i);
return 1;
}
void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on) void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on)
{ {
if (!inst->ops->hover) if (!inst->ops->hover)

7
inst.h
View File

@ -58,6 +58,10 @@ struct inst {
struct coord end; struct coord end;
unit_type width; unit_type width;
} rect; } rect;
struct {
const char *name;
struct coord other;
} pad;
struct { struct {
unit_type r; unit_type r;
double a1, a2; double a1, a2;
@ -109,6 +113,9 @@ void inst_commit(void);
void inst_revert(void); void inst_revert(void);
void inst_draw(struct draw_ctx *ctx); void inst_draw(struct draw_ctx *ctx);
struct pix_buf *inst_draw_move(struct inst *inst, struct draw_ctx *ctx,
struct coord pos, int i);
int inst_do_move_to(struct inst *inst, struct vec *vec, int i);
void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on); void inst_hover(struct inst *inst, struct draw_ctx *ctx, int on);
void inst_debug(void); void inst_debug(void);