mirror of
git://projects.qi-hardware.com/ben-scans.git
synced 2024-11-21 21:33:11 +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:
parent
edb12b6e95
commit
85855ec5ac
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user