mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-22 12:20:37 +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:
parent
8377ab0e0d
commit
5d7ab083a3
2
Makefile
2
Makefile
@ -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
8
README
@ -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
1
TODO
@ -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
65
coord.c
@ -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
10
coord.h
@ -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
2
fpd.l
@ -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);
|
||||||
|
43
gui_inst.c
43
gui_inst.c
@ -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;
|
||||||
|
189
gui_tools.c
189
gui_tools.c
@ -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,7 +521,8 @@ 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;
|
||||||
do_move_to(&state, end);
|
if (!inst_do_move_to(selected_inst, inst_get_vec(end), state.anchor_i))
|
||||||
|
do_move_to(&state, end);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
gui_tools.h
11
gui_tools.h
@ -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);
|
||||||
|
@ -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
50
inst.c
@ -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
7
inst.h
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user