1
0
mirror of git://projects.qi-hardware.com/ben-scans.git synced 2024-11-22 03:14:39 +02:00

Overlapping now has an OSD, too.

- solidify/overlap.c (BORDER, sx, sy), solidify/style.h (OVERLAP_BORDER):
  moved and renamed
- solidify/overlap.c (r_center, scroll_event): moved center radius
  calculation to separate function
- solidify/overlap.c (draw_image): renamed to draw_map
- solidify/overlap.c (draw_image): draw an on-screen display (OSD)
- solidify/level.c (expose_event, overlap): propagate OSD on/off switch
- solidify/overlap.c (osd_proximity, scroll_event, motion_notify_event,
  overlap): enable OSD when approaching the center circle or a diagonal
- solidify/overlap.c (scroll_event): reversed the direction of rotation
This commit is contained in:
Werner Almesberger 2010-09-24 02:47:34 -03:00
parent edb12b6e95
commit 85855ec5ac
2 changed files with 82 additions and 13 deletions

View File

@ -17,24 +17,34 @@
#include <limits.h>
#include <gtk/gtk.h>
#include "util.h"
#include "face.h"
#include "solid.h"
#include "style.h"
#include "overlap.h"
#define UNDEF_F HUGE_VAL
#define BORDER 10 /* pixels around the minimum drawing area */
static int has_osd;
static int sx(const struct solid *s)
{
return (s->a->sx > s->b->sx ? s->a->sx : s->b->sx)+2*BORDER;
return (s->a->sx > s->b->sx ? s->a->sx : s->b->sx)+2*OVERLAP_BORDER;
}
static int sy(const struct solid *s)
{
return (s->a->sy > s->b->sy ? s->a->sy : s->b->sy)+2*BORDER;
return (s->a->sy > s->b->sy ? s->a->sy : s->b->sy)+2*OVERLAP_BORDER;
}
static double r_center(const struct solid *s)
{
return hypot(sx(s), sy(s))/OVERLAP_CENTER_DIV;
}
@ -136,7 +146,7 @@ static void point(const struct solid *s, int x, int y, guchar *p)
}
static void draw_image(GtkWidget *widget, struct solid *s)
static void draw_map(GtkWidget *widget, struct solid *s)
{
guchar *rgbbuf, *p;
int x, y;
@ -158,6 +168,23 @@ static void draw_image(GtkWidget *widget, struct solid *s)
}
static void draw_image(GtkWidget *widget, struct solid *s, int osd)
{
int cx = sx(s)/2;
int cy = sy(s)/2;
int p;
draw_map(widget, s);
has_osd = osd;
if (!osd)
return;
draw_circle(widget->window, gc_osd, cx, cy, r_center(s));
p = r_center(s)/sqrt(2);
gdk_draw_line(widget->window, gc_osd, cx-p, cy-p, cx+p, cy+p);
gdk_draw_line(widget->window, gc_osd, cx-p, cy+p, cx+p, cy-p);
}
/*
* Rotate such that a point at distance "r" moves one unit. Rotate
* counter-clockwise for r > 1, clockwise for r < 0.
@ -200,6 +227,21 @@ static void shift(struct matrix *m, int dx, int dy, int dir)
}
static int osd_proximity(const struct solid *s, int dx, int dy)
{
double r = hypot(dx, dy);
double rc = r_center(s);
if (fabs(r-rc) < OSD_PROXIMITY)
return 1;
if (r > rc)
return 0;
if (abs(abs(dx)-abs(dy)) < OSD_PROXIMITY)
return 1;
return 0;
}
static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
gpointer data)
{
@ -208,7 +250,9 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
int dx = event->x-sx(s)/2;
int dy = event->y-sy(s)/2;
double r = hypot(dx, dy);
int center = r/hypot(sx(s), sy(s)) < 0.25;
double rc = r_center(s);
int center = r < rc;
int osd = osd_proximity(s, dx, dy);
if (r < 1)
return TRUE;
@ -217,15 +261,15 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
if (center)
shift(&s->a->m, dx, dy, 1);
else
rotate(&s->a->m, r);
draw_image(darea, s);
rotate(&s->a->m, -r);
draw_image(darea, s, osd);
break;
case GDK_SCROLL_DOWN:
if (center)
shift(&s->a->m, dx, dy, -1);
else
rotate(&s->a->m, -r);
draw_image(darea, s);
rotate(&s->a->m, r);
draw_image(darea, s, osd);
break;
default:
/* ignore */;
@ -237,11 +281,24 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
gpointer user_data)
{
draw_image(widget, user_data);
draw_image(widget, user_data, has_osd);
return TRUE;
}
static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
gpointer data)
{
struct solid *s = data;
int dx = event->x-sx(s)/2;
int dy = event->y-sy(s)/2;
int osd = osd_proximity(s, dx, dy);
if (osd != has_osd)
draw_image(widget, s, osd);
return FALSE;
}
void overlap(GtkWidget *canvas, struct solid *s)
{
@ -249,14 +306,24 @@ void overlap(GtkWidget *canvas, struct solid *s)
evbox = gtk_event_box_new();
darea = gtk_drawing_area_new();
gtk_widget_set_events(darea,
GDK_EXPOSE | GDK_KEY_PRESS_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
GDK_SCROLL |
GDK_POINTER_MOTION_MASK);
gtk_widget_set_size_request(darea, sx(s), sy(s));
gtk_container_add(GTK_CONTAINER(canvas), evbox);
gtk_container_add(GTK_CONTAINER(evbox), darea);
draw_image(darea, s);
draw_image(darea, s, 0);
g_signal_connect(G_OBJECT(evbox), "scroll-event",
G_CALLBACK(scroll_event), s);
g_signal_connect(G_OBJECT(darea), "expose-event",
G_CALLBACK(expose_event), s);
g_signal_connect(G_OBJECT(darea), "motion-notify-event",
G_CALLBACK(motion_notify_event), s);
}

View File

@ -19,8 +19,10 @@
extern GdkGC *gc_osd;
#define OSD_PROXIMITY 20
#define LEVEL_CENTER_DIV 5
#define OSD_PROXIMITY 20 /* pixels */
#define LEVEL_CENTER_DIV 5 /* fraction of diagonal */
#define OVERLAP_BORDER 10 /* pixels around min. drawing area */
#define OVERLAP_CENTER_DIV 5 /* fraction of diagonal */
void init_style(GdkDrawable *da);