diff --git a/README b/README index f953c67..801bcd4 100644 --- a/README +++ b/README @@ -349,3 +349,4 @@ space reset user coordinates - zoom out (like mouse wheel backward) . cursor position to screen center (like middle click) * zoom and center to extents +# zoom and center to currently active frame instance diff --git a/gui_canvas.c b/gui_canvas.c index 5d7c277..fe5ffda 100644 --- a/gui_canvas.c +++ b/gui_canvas.c @@ -49,24 +49,24 @@ static void update_pos(struct coord pos) /* ----- coordinate system ------------------------------------------------- */ -static void center(void) +static void center(const struct bbox *this_bbox) { struct bbox bbox; - bbox = inst_get_bbox(); + bbox = this_bbox ? *this_bbox : inst_get_bbox(); ctx.center.x = (bbox.min.x+bbox.max.x)/2; ctx.center.y = (bbox.min.y+bbox.max.y)/2; } -static void auto_scale(void) +static void auto_scale(const struct bbox *this_bbox) { struct bbox bbox; unit_type h, w; int sx, sy; float aw, ah; - bbox = inst_get_bbox(); + bbox = this_bbox ? *this_bbox : inst_get_bbox(); aw = ctx.widget->allocation.width; ah = ctx.widget->allocation.height; h = bbox.max.x-bbox.min.x; @@ -236,9 +236,15 @@ static gboolean key_press_event(GtkWidget *widget, GdkEventKey *event, zoom_out(pos); break; case '*': - center(); - auto_scale(); + center(NULL); + auto_scale(NULL); redraw(); + break; + case '#': + center(&active_frame_bbox); + auto_scale(&active_frame_bbox); + redraw(); + break; case '.': ctx.center = pos; redraw(); @@ -293,8 +299,8 @@ static gboolean leave_notify_event(GtkWidget *widget, GdkEventCrossing *event, void init_canvas(void) { - center(); - auto_scale(); + center(NULL); + auto_scale(NULL); } diff --git a/gui_status.c b/gui_status.c index a618ae1..c26e4b6 100644 --- a/gui_status.c +++ b/gui_status.c @@ -310,7 +310,8 @@ static int expr_activate(GtkWidget *widget, const char *s, void *ctx) expr = try_parse_expr(s); if (!expr) return 0; - free_expr(*anchor); + if (*anchor) + free_expr(*anchor); *anchor = expr; entry_color(COLOR_EDIT_ASIS); return 1; diff --git a/inst.c b/inst.c index 80f562b..eae251a 100644 --- a/inst.c +++ b/inst.c @@ -62,6 +62,7 @@ enum inst_prio { struct inst *selected_inst = NULL; +struct bbox active_frame_bbox; static struct inst *curr_frame = NULL; static struct inst *insts[ip_n], **next_inst[ip_n]; @@ -224,6 +225,16 @@ static void propagate_bbox(const struct inst *inst) update_bbox(&curr_frame->bbox, inst->bbox.max); } + +static void grow_bbox_by_width(struct bbox *bbox, unit_type width) +{ + bbox->min.x -= width/2; + bbox->min.y -= width/2; + bbox->max.x += width/2; + bbox->max.y += width/2; +} + + static struct inst *add_inst(const struct inst_ops *ops, enum inst_prio prio, struct coord base) { @@ -331,6 +342,7 @@ int inst_line(struct obj *obj, struct coord a, struct coord b, unit_type width) inst->u.rect.end = b; inst->u.rect.width = width; update_bbox(&inst->bbox, b); + grow_bbox_by_width(&inst->bbox, width); propagate_bbox(inst); return 1; } @@ -371,6 +383,7 @@ int inst_rect(struct obj *obj, struct coord a, struct coord b, unit_type width) inst->u.rect.end = b; inst->u.rect.width = width; update_bbox(&inst->bbox, b); + grow_bbox_by_width(&inst->bbox, width); propagate_bbox(inst); return 1; } @@ -482,6 +495,7 @@ int inst_arc(struct obj *obj, struct coord center, struct coord start, inst->bbox.max.x = center.x+r; inst->bbox.min.y = center.y-r; inst->bbox.max.y = center.y+r; + grow_bbox_by_width(&inst->bbox, width); propagate_bbox(inst); return 1; } @@ -581,6 +595,8 @@ void inst_end_frame(const struct frame *frame) curr_frame = curr_frame->outer; if (curr_frame) propagate_bbox(inst); + if (inst->active && frame == active_frame) + active_frame_bbox = inst->bbox; } @@ -609,8 +625,10 @@ static void inst_free(struct inst *list[ip_n]) void inst_start(void) { + static struct bbox bbox_zero = { { 0, 0 }, { 0, 0 }}; enum inst_prio prio; + active_frame_bbox = bbox_zero; FOR_INST_PRIOS_UP(prio) { prev_insts[prio] = insts[prio]; insts[prio] = NULL; diff --git a/inst.h b/inst.h index a5fa1fb..6d7bf7c 100644 --- a/inst.h +++ b/inst.h @@ -71,6 +71,7 @@ struct inst { extern struct inst *selected_inst; +extern struct bbox active_frame_bbox; void inst_select_outside(void *item, void (*deselect)(void *item));