r5365 - developers/werner/fped
werner at docs.openmoko.org
werner at docs.openmoko.org
Sun Aug 2 07:17:40 CEST 2009
Author: werner
Date: 2009-08-02 07:17:39 +0200 (Sun, 02 Aug 2009)
New Revision: 5365
Modified:
developers/werner/fped/TODO
developers/werner/fped/gui_icons.c
developers/werner/fped/gui_inst.c
developers/werner/fped/inst.c
developers/werner/fped/inst.h
Log:
- implemented radio buttons for icon bar, but don't like them
- removed excessive paranoia in inst_get_bbox
- instances are now stacked by drawing/selection priority
- struct inst_ops is only used inside inst.c, moved it there
- no longer need "magic" VEC_EYE_R in gui_inst.c to give vectors selection
priority
- when selecting an arc now only consider the part drawn, not the whole circle
Modified: developers/werner/fped/TODO
===================================================================
--- developers/werner/fped/TODO 2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/TODO 2009-08-02 05:17:39 UTC (rev 5365)
@@ -16,13 +16,9 @@
- detect recursive evaluation (through variables)
- eliminate duplicate instances
-Bugs:
-- when selecting an arc only consider the part drawn, not the whole circle
-
Style:
-- stack elements (1): frames, pads, silk, vecs
-- stack elements (2): all unselected below all selected
-- stack elements (3): circle on top of vec
+- stack elements (2a): all inactive below all active
+- stack elements (2b): unselected below selected
- make column of entry field greedily consume all unallocated space
Code cleanup:
Modified: developers/werner/fped/gui_icons.c
===================================================================
--- developers/werner/fped/gui_icons.c 2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/gui_icons.c 2009-08-02 05:17:39 UTC (rev 5365)
@@ -28,8 +28,8 @@
#include "icons/vec.xpm"
-static GtkWidget *icon_button(GtkWidget *bar, GdkDrawable *drawable,
- char **xpm)
+static GtkToolItem *icon_button(GtkWidget *bar, GdkDrawable *drawable,
+ char **xpm, GtkToolItem *last)
{
GdkPixmap *pixmap;
GtkWidget *image;
@@ -38,19 +38,34 @@
pixmap = gdk_pixmap_create_from_xpm_d(drawable, NULL, NULL, xpm);
image = gtk_image_new_from_pixmap(pixmap, NULL);
+/*
+ * gtk_radio_tool_button_new_from_widget is *huge*. we try to do things in a
+ * more compact way.
+ */
+#if 0
+ if (last)
+ item = gtk_radio_tool_button_new_from_widget(
+ GTK_RADIO_TOOL_BUTTON(last));
+ else
+ item = gtk_radio_tool_button_new(NULL);
+ gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(item), image);
+#else
item = gtk_tool_item_new();
gtk_container_add(GTK_CONTAINER(item), image);
gtk_container_set_border_width(GTK_CONTAINER(item), 1);
+#endif
+
gtk_toolbar_insert(GTK_TOOLBAR(bar), item, -1);
- return NULL;
+ return item;
}
GtkWidget *gui_setup_icons(GdkDrawable *drawable)
{
GtkWidget *bar;
+ GtkToolItem *last;
bar = gtk_toolbar_new();
gtk_toolbar_set_style(GTK_TOOLBAR(bar), GTK_TOOLBAR_ICONS);
@@ -58,15 +73,15 @@
GTK_ORIENTATION_VERTICAL);
//gtk_container_set_border_width(GTK_CONTAINER(bar), 5);
- icon_button(bar, drawable, xpm_point);
- icon_button(bar, drawable, xpm_vec);
- icon_button(bar, drawable, xpm_frame);
- icon_button(bar, drawable, xpm_pad);
- icon_button(bar, drawable, xpm_line);
- icon_button(bar, drawable, xpm_rect);
- icon_button(bar, drawable, xpm_circ);
- icon_button(bar, drawable, xpm_arc);
- icon_button(bar, drawable, xpm_meas);
+ last = icon_button(bar, drawable, xpm_point, NULL);
+ last = icon_button(bar, drawable, xpm_vec, last);
+ last = icon_button(bar, drawable, xpm_frame, last);
+ last = icon_button(bar, drawable, xpm_pad, last);
+ last = icon_button(bar, drawable, xpm_line, last);
+ last = icon_button(bar, drawable, xpm_rect, last);
+ last = icon_button(bar, drawable, xpm_circ, last);
+ last = icon_button(bar, drawable, xpm_arc, last);
+ last = icon_button(bar, drawable, xpm_meas, last);
return bar;
}
Modified: developers/werner/fped/gui_inst.c
===================================================================
--- developers/werner/fped/gui_inst.c 2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/gui_inst.c 2009-08-02 05:17:39 UTC (rev 5365)
@@ -164,7 +164,7 @@
unit_type d;
d = dist_line(pos, self->bbox.min, self->bbox.max)/scale;
- return d > SELECT_R ? -1 : d+VEC_EYE_R;
+ return d > SELECT_R ? -1 : d;
}
@@ -187,7 +187,7 @@
unit_type d;
d = dist_rect(pos, self->bbox.min, self->bbox.max)/scale;
- return d > SELECT_R ? -1 : d+VEC_EYE_R;
+ return d > SELECT_R ? -1 : d;
}
@@ -211,9 +211,9 @@
unit_type d;
if (inside_rect(pos, self->bbox.min, self->bbox.max))
- return VEC_EYE_R;
+ return SELECT_R;
d = dist_rect(pos, self->bbox.min, self->bbox.max)/scale;
- return d > SELECT_R ? -1 : d+VEC_EYE_R;
+ return d > SELECT_R ? -1 : d;
}
@@ -233,12 +233,54 @@
/* ----- 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 d;
+ struct coord c = self->base;
+ struct coord p;
+ unit_type d_min, d;
+ double angle, a2;
- d = dist_circle(pos, self->base, self->u.arc.r)/scale;
- return d > SELECT_R ? -1 : d+VEC_EYE_R;
+ /* check endpoints */
+
+ p = rotate_r(c, self->u.arc.r, self->u.arc.a1);
+ d_min = hypot(pos.x-p.x, pos.y-p.y);
+
+ p = rotate_r(c, self->u.arc.r, self->u.arc.a2);
+ d = hypot(pos.x-p.x, pos.y-p.y);
+ if (d < d_min)
+ d_min = d;
+
+ if (d_min/scale <= SELECT_R)
+ return d;
+
+ /* distance from the circle containing the arc */
+
+ d = dist_circle(pos, c, self->u.arc.r)/scale;
+ if (d > SELECT_R)
+ return -1;
+ if (self->u.arc.a1 == self->u.arc.a2)
+ return d;
+
+ /* 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;
+ if (angle < 0)
+ angle += 180;
+ a2 = self->u.arc.a2;
+ if (a2 < self->u.arc.a1)
+ a2 += 180;
+ return angle >= self->u.arc.a1 && angle <= a2 ? d : -1;
}
@@ -283,7 +325,7 @@
a = add_vec(self->base, off);
b = add_vec(self->u.meas.end, off);
d = dist_line(pos, a, b)/scale;
- return d > SELECT_R ? -1 : d+VEC_EYE_R;
+ return d > SELECT_R ? -1 : d;
}
Modified: developers/werner/fped/inst.c
===================================================================
--- developers/werner/fped/inst.c 2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/inst.c 2009-08-02 05:17:39 UTC (rev 5365)
@@ -24,11 +24,48 @@
#include "inst.h"
+struct inst_ops {
+ void (*debug)(struct inst *self);
+ void (*save)(FILE *file, struct inst *self);
+ void (*draw)(struct inst *self, struct draw_ctx *ctx);
+ unit_type (*distance)(struct inst *self, struct coord pos,
+ unit_type scale);
+ void (*select)(struct inst *self);
+};
+
+enum inst_prio {
+ ip_frame, /* frames have their own selection */
+ ip_pad, /* pads also accept clicks inside */
+ ip_circ, /* circles don't overlap easily */
+ ip_arc, /* arc are like circles, just shorter */
+ ip_rect, /* rectangles have plenty of sides */
+ ip_meas, /* mesurements are like lines but set a bit apart */
+ ip_line, /* lines are easly overlapped by other things */
+ ip_vec, /* vectors only have the end point */
+ ip_n, /* number of priorities */
+};
+
+
+#define FOR_INST_PRIOS_UP(prio) \
+ for (prio = 0; prio != ip_n; prio++)
+
+#define FOR_INST_PRIOS_DOWN(prio) \
+ for (prio = ip_n-1; prio != (enum inst_prio) -1; prio--)
+
+#define FOR_INSTS_UP(prio, inst) \
+ FOR_INST_PRIOS_UP(prio) \
+ for (inst = insts[prio]; inst; inst = inst->next)
+
+#define FOR_INSTS_DOWN(prio, inst) \
+ FOR_INST_PRIOS_DOWN(prio) \
+ for (inst = insts[prio]; inst; inst = inst->next)
+
+
struct inst *curr_frame = NULL;
struct inst *selected_inst = NULL;
-static struct inst *insts = NULL, **next_inst;
-static struct inst *prev_insts;
+static struct inst *insts[ip_n], **next_inst[ip_n];
+static struct inst *prev_insts[ip_n];
static unsigned long active_set = 0;
@@ -86,27 +123,31 @@
int inst_select(const struct draw_ctx *ctx, struct coord pos)
{
+ enum inst_prio prio;
struct inst *inst;
int best_dist, dist;
deselect_outside();
- selected_inst = NULL;
edit_nothing();
- for (inst = insts; inst; inst = inst->next) {
- if (!inst->active || !inst->ops->distance)
- continue;
- dist = inst->ops->distance(inst, pos, ctx->scale);
- if (dist >= 0 && (!selected_inst || best_dist > dist)) {
- selected_inst = inst;
- best_dist = dist;
+ FOR_INST_PRIOS_DOWN(prio) {
+ selected_inst = NULL;
+ for (inst = insts[prio]; inst; inst = inst->next) {
+ if (!inst->active || !inst->ops->distance)
+ continue;
+ dist = inst->ops->distance(inst, pos, ctx->scale);
+ if (dist >= 0 && (!selected_inst || best_dist > dist)) {
+ selected_inst = inst;
+ best_dist = dist;
+ }
}
+ if (selected_inst) {
+ set_path(1);
+ if (selected_inst->ops->select)
+ selected_inst->ops->select(selected_inst);
+ return 1;
+ }
}
- if (selected_inst) {
- set_path(1);
- if (selected_inst->ops->select)
- selected_inst->ops->select(selected_inst);
- }
- return selected_inst != NULL;
+ return 0;
}
@@ -165,7 +206,8 @@
update_bbox(&curr_frame->bbox, inst->bbox.max);
}
-static struct inst *add_inst(const struct inst_ops *ops, struct coord base)
+static struct inst *add_inst(const struct inst_ops *ops, enum inst_prio prio,
+ struct coord base)
{
struct inst *inst;
@@ -176,8 +218,8 @@
inst->active = IS_ACTIVE;
inst->in_path = 0;
inst->next = NULL;
- *next_inst = inst;
- next_inst = &inst->next;
+ *next_inst[prio] = inst;
+ next_inst[prio] = &inst->next;
return inst;
}
@@ -227,7 +269,7 @@
{
struct inst *inst;
- inst = add_inst(&vec_ops, base);
+ inst = add_inst(&vec_ops, ip_vec, base);
inst->vec = vec;
inst->u.end = vec->pos;
update_bbox(&inst->bbox, vec->pos);
@@ -265,7 +307,7 @@
{
struct inst *inst;
- inst = add_inst(&line_ops, a);
+ inst = add_inst(&line_ops, ip_line, a);
inst->obj = obj;
inst->u.end = b;
update_bbox(&inst->bbox, b);
@@ -303,7 +345,7 @@
{
struct inst *inst;
- inst = add_inst(&rect_ops, a);
+ inst = add_inst(&rect_ops, ip_rect, a);
inst->obj = obj;
inst->u.end = b;
update_bbox(&inst->bbox, b);
@@ -355,7 +397,7 @@
{
struct inst *inst;
- inst = add_inst(&pad_ops, a);
+ inst = add_inst(&pad_ops, ip_pad, a);
inst->obj = obj;
inst->u.name = stralloc(name);
update_bbox(&inst->bbox, b);
@@ -399,7 +441,7 @@
struct inst *inst;
double r, a1, a2;
- inst = add_inst(&arc_ops, center);
+ inst = add_inst(&arc_ops, ip_arc, center);
inst->obj = obj;
r = hypot(start.x-center.x, start.y-center.y);
a1 = atan2(start.y-center.y, start.x-center.x)/M_PI*180.0;
@@ -452,7 +494,7 @@
{
struct inst *inst;
- inst = add_inst(&meas_ops, from);
+ inst = add_inst(&meas_ops, ip_meas, from);
inst->obj = obj;
inst->u.meas.end = to;
inst->u.meas.offset = offset;
@@ -499,7 +541,7 @@
{
struct inst *inst;
- inst = add_inst(&frame_ops, base);
+ inst = add_inst(&frame_ops, ip_frame, base);
inst->u.frame.ref = frame;
inst->active = active;
curr_frame = inst;
@@ -521,29 +563,33 @@
struct bbox inst_get_bbox(void)
{
- static struct bbox bbox_zero;
-
- return insts ? insts->bbox : bbox_zero;
+ return insts[ip_frame]->bbox;
}
-static void inst_free(struct inst *list)
+static void inst_free(struct inst *list[ip_n])
{
+ enum inst_prio prio;
struct inst *next;
- while (list) {
- next = list->next;
- free(list);
- list = next;
- }
+ FOR_INST_PRIOS_UP(prio)
+ while (list[prio]) {
+ next = list[prio]->next;
+ free(list[prio]);
+ list[prio] = next;
+ }
}
void inst_start(void)
{
- prev_insts = insts;
- insts = NULL;
- next_inst = &insts;
+ enum inst_prio prio;
+
+ FOR_INST_PRIOS_UP(prio) {
+ prev_insts[prio] = insts[prio];
+ insts[prio] = NULL;
+ next_inst[prio] = &insts[prio];
+ }
}
@@ -555,25 +601,30 @@
void inst_revert(void)
{
+ enum inst_prio prio;
+
inst_free(insts);
- insts = prev_insts;
+ FOR_INST_PRIOS_UP(prio)
+ insts[prio] = prev_insts[prio];
}
void inst_draw(struct draw_ctx *ctx)
{
- struct inst *walk;
+ enum inst_prio prio;
+ struct inst *inst;
- for (walk = insts; walk; walk = walk->next)
- if (walk->ops->draw)
- walk->ops->draw(walk, ctx);
+ FOR_INSTS_UP(prio, inst)
+ if (inst->ops->draw)
+ inst->ops->draw(inst, ctx);
}
void inst_debug(void)
{
- struct inst *walk;
+ enum inst_prio prio;
+ struct inst *inst;
- for (walk = insts; walk; walk = walk->next)
- walk->ops->debug(walk);
+ FOR_INSTS_UP(prio, inst)
+ inst->ops->debug(inst);
}
Modified: developers/werner/fped/inst.h
===================================================================
--- developers/werner/fped/inst.h 2009-08-01 23:12:30 UTC (rev 5364)
+++ developers/werner/fped/inst.h 2009-08-02 05:17:39 UTC (rev 5365)
@@ -34,18 +34,9 @@
struct coord max;
};
-struct inst;
+struct inst_ops;
struct draw_ctx;
-struct inst_ops {
- void (*debug)(struct inst *self);
- void (*save)(FILE *file, struct inst *self);
- void (*draw)(struct inst *self, struct draw_ctx *ctx);
- unit_type (*distance)(struct inst *self, struct coord pos,
- unit_type scale);
- void (*select)(struct inst *self);
-};
-
struct inst {
const struct inst_ops *ops;
struct coord base;
More information about the commitlog
mailing list