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:
parent
edb12b6e95
commit
85855ec5ac
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user