1
0
mirror of git://projects.qi-hardware.com/ben-scans.git synced 2024-11-25 00:17:31 +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 <limits.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "util.h"
#include "face.h" #include "face.h"
#include "solid.h" #include "solid.h"
#include "style.h"
#include "overlap.h" #include "overlap.h"
#define UNDEF_F HUGE_VAL #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) 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) 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; guchar *rgbbuf, *p;
int x, y; 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 * Rotate such that a point at distance "r" moves one unit. Rotate
* counter-clockwise for r > 1, clockwise for r < 0. * 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, static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
gpointer data) gpointer data)
{ {
@ -208,7 +250,9 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
int dx = event->x-sx(s)/2; int dx = event->x-sx(s)/2;
int dy = event->y-sy(s)/2; int dy = event->y-sy(s)/2;
double r = hypot(dx, dy); 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) if (r < 1)
return TRUE; return TRUE;
@ -217,15 +261,15 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
if (center) if (center)
shift(&s->a->m, dx, dy, 1); shift(&s->a->m, dx, dy, 1);
else else
rotate(&s->a->m, r); rotate(&s->a->m, -r);
draw_image(darea, s); draw_image(darea, s, osd);
break; break;
case GDK_SCROLL_DOWN: case GDK_SCROLL_DOWN:
if (center) if (center)
shift(&s->a->m, dx, dy, -1); shift(&s->a->m, dx, dy, -1);
else else
rotate(&s->a->m, -r); rotate(&s->a->m, r);
draw_image(darea, s); draw_image(darea, s, osd);
break; break;
default: default:
/* ignore */; /* ignore */;
@ -237,11 +281,24 @@ static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
gpointer user_data) gpointer user_data)
{ {
draw_image(widget, user_data); draw_image(widget, user_data, has_osd);
return TRUE; 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) void overlap(GtkWidget *canvas, struct solid *s)
{ {
@ -249,14 +306,24 @@ void overlap(GtkWidget *canvas, struct solid *s)
evbox = gtk_event_box_new(); evbox = gtk_event_box_new();
darea = gtk_drawing_area_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_widget_set_size_request(darea, sx(s), sy(s));
gtk_container_add(GTK_CONTAINER(canvas), evbox); gtk_container_add(GTK_CONTAINER(canvas), evbox);
gtk_container_add(GTK_CONTAINER(evbox), darea); 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_signal_connect(G_OBJECT(evbox), "scroll-event",
G_CALLBACK(scroll_event), s); G_CALLBACK(scroll_event), s);
g_signal_connect(G_OBJECT(darea), "expose-event", g_signal_connect(G_OBJECT(darea), "expose-event",
G_CALLBACK(expose_event), s); 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; extern GdkGC *gc_osd;
#define OSD_PROXIMITY 20 #define OSD_PROXIMITY 20 /* pixels */
#define LEVEL_CENTER_DIV 5 #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); void init_style(GdkDrawable *da);