Date:2010-09-24 07:47:34 (9 years 2 months ago)
Author:Werner Almesberger
Commit:85855ec5ac1ce49f6d46a81903f75eaaa8cf4584
Message: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
Files: solidify/overlap.c (8 diffs)
solidify/style.h (1 diff)

Change Details

solidify/overlap.c
1717#include <limits.h>
1818#include <gtk/gtk.h>
1919
20#include "util.h"
2021#include "face.h"
2122#include "solid.h"
23#include "style.h"
2224#include "overlap.h"
2325
2426
2527#define UNDEF_F HUGE_VAL
26#define BORDER 10 /* pixels around the minimum drawing area */
28
29
30static int has_osd;
2731
2832
2933static int sx(const struct solid *s)
3034{
31    return (s->a->sx > s->b->sx ? s->a->sx : s->b->sx)+2*BORDER;
35    return (s->a->sx > s->b->sx ? s->a->sx : s->b->sx)+2*OVERLAP_BORDER;
3236}
3337
3438
3539static int sy(const struct solid *s)
3640{
37    return (s->a->sy > s->b->sy ? s->a->sy : s->b->sy)+2*BORDER;
41    return (s->a->sy > s->b->sy ? s->a->sy : s->b->sy)+2*OVERLAP_BORDER;
42}
43
44
45static double r_center(const struct solid *s)
46{
47    return hypot(sx(s), sy(s))/OVERLAP_CENTER_DIV;
3848}
3949
4050
...... 
136146}
137147
138148
139static void draw_image(GtkWidget *widget, struct solid *s)
149static void draw_map(GtkWidget *widget, struct solid *s)
140150{
141151    guchar *rgbbuf, *p;
142152    int x, y;
...... 
158168}
159169
160170
171static void draw_image(GtkWidget *widget, struct solid *s, int osd)
172{
173    int cx = sx(s)/2;
174    int cy = sy(s)/2;
175    int p;
176
177    draw_map(widget, s);
178    has_osd = osd;
179    if (!osd)
180        return;
181    draw_circle(widget->window, gc_osd, cx, cy, r_center(s));
182    p = r_center(s)/sqrt(2);
183    gdk_draw_line(widget->window, gc_osd, cx-p, cy-p, cx+p, cy+p);
184    gdk_draw_line(widget->window, gc_osd, cx-p, cy+p, cx+p, cy-p);
185}
186
187
161188/*
162189 * Rotate such that a point at distance "r" moves one unit. Rotate
163190 * counter-clockwise for r > 1, clockwise for r < 0.
...... 
200227}
201228
202229
230static int osd_proximity(const struct solid *s, int dx, int dy)
231{
232    double r = hypot(dx, dy);
233    double rc = r_center(s);
234
235    if (fabs(r-rc) < OSD_PROXIMITY)
236        return 1;
237    if (r > rc)
238        return 0;
239    if (abs(abs(dx)-abs(dy)) < OSD_PROXIMITY)
240        return 1;
241    return 0;
242}
243
244
203245static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event,
204246    gpointer data)
205247{
...... 
208250    int dx = event->x-sx(s)/2;
209251    int dy = event->y-sy(s)/2;
210252    double r = hypot(dx, dy);
211    int center = r/hypot(sx(s), sy(s)) < 0.25;
253    double rc = r_center(s);
254    int center = r < rc;
255    int osd = osd_proximity(s, dx, dy);
212256
213257    if (r < 1)
214258        return TRUE;
...... 
217261        if (center)
218262            shift(&s->a->m, dx, dy, 1);
219263        else
220            rotate(&s->a->m, r);
221        draw_image(darea, s);
264            rotate(&s->a->m, -r);
265        draw_image(darea, s, osd);
222266        break;
223267    case GDK_SCROLL_DOWN:
224268        if (center)
225269            shift(&s->a->m, dx, dy, -1);
226270        else
227            rotate(&s->a->m, -r);
228        draw_image(darea, s);
271            rotate(&s->a->m, r);
272        draw_image(darea, s, osd);
229273        break;
230274    default:
231275        /* ignore */;
...... 
237281static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event,
238282    gpointer user_data)
239283{
240    draw_image(widget, user_data);
284    draw_image(widget, user_data, has_osd);
241285    return TRUE;
242286}
243287
244288
289static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
290    gpointer data)
291{
292    struct solid *s = data;
293    int dx = event->x-sx(s)/2;
294    int dy = event->y-sy(s)/2;
295    int osd = osd_proximity(s, dx, dy);
296
297    if (osd != has_osd)
298        draw_image(widget, s, osd);
299    return FALSE;
300}
301
245302
246303void overlap(GtkWidget *canvas, struct solid *s)
247304{
...... 
249306
250307    evbox = gtk_event_box_new();
251308    darea = gtk_drawing_area_new();
309
310    gtk_widget_set_events(darea,
311        GDK_EXPOSE | GDK_KEY_PRESS_MASK |
312        GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
313        GDK_SCROLL |
314        GDK_POINTER_MOTION_MASK);
315
252316    gtk_widget_set_size_request(darea, sx(s), sy(s));
253317    gtk_container_add(GTK_CONTAINER(canvas), evbox);
254318    gtk_container_add(GTK_CONTAINER(evbox), darea);
255319
256    draw_image(darea, s);
320    draw_image(darea, s, 0);
257321
258322    g_signal_connect(G_OBJECT(evbox), "scroll-event",
259323        G_CALLBACK(scroll_event), s);
260324    g_signal_connect(G_OBJECT(darea), "expose-event",
261325        G_CALLBACK(expose_event), s);
326    g_signal_connect(G_OBJECT(darea), "motion-notify-event",
327        G_CALLBACK(motion_notify_event), s);
328
262329}
solidify/style.h
1919extern GdkGC *gc_osd;
2020
2121
22#define OSD_PROXIMITY 20
23#define LEVEL_CENTER_DIV 5
22#define OSD_PROXIMITY 20 /* pixels */
23#define LEVEL_CENTER_DIV 5 /* fraction of diagonal */
24#define OVERLAP_BORDER 10 /* pixels around min. drawing area */
25#define OVERLAP_CENTER_DIV 5 /* fraction of diagonal */
2426
2527
2628void init_style(GdkDrawable *da);

Archive Download the corresponding diff file

Branches:
master



interactive