--- trunk/src/map-tool.c 2009/08/04 19:27:39 45
+++ trunk/src/map-tool.c 2009/08/06 20:23:12 47
@@ -169,13 +169,16 @@
GMainLoop *loop;
} popup_context_t;
+/* draw shape */
+#define ARROW_BORDER 20
+#define CORNER_RADIUS 10
-#ifndef USE_HILDON
+#ifndef USE_MAEMO
#define POPUP_WIDTH 300
#define POPUP_HEIGHT 100
#else
-#define POPUP_WIDTH 600
-#define POPUP_HEIGHT 200
+#define POPUP_WIDTH 350
+#define POPUP_HEIGHT 120
#endif
static gboolean
@@ -242,6 +245,99 @@
shutdown_loop(context);
}
+static void popup_window_shape(GtkWidget *window, int tip_x, int tip_y) {
+ GdkBitmap *mask = gdk_pixmap_new(NULL, POPUP_WIDTH, POPUP_HEIGHT, 1);
+
+ GdkGC *gc = gdk_gc_new(mask);
+ GdkColormap *colormap;
+ GdkColor black;
+ GdkColor white;
+
+ /* get black/white color values */
+ colormap = gdk_colormap_get_system();
+ gdk_color_black(colormap, &black);
+ gdk_color_white(colormap, &white);
+
+ /* erase */
+ gdk_gc_set_foreground(gc, &black);
+ gdk_gc_set_background(gc, &white);
+
+ /* erase background */
+ gdk_draw_rectangle(mask, gc, TRUE, 0, 0, POPUP_WIDTH, POPUP_HEIGHT);
+
+ gdk_gc_set_foreground(gc, &white);
+ gdk_gc_set_background(gc, &black);
+
+ /* the tip is always above or below the "bubble" but never at its side */
+ guint tip_offset = (tip_y == 0)?ARROW_BORDER:0;
+
+ gdk_draw_rectangle(mask, gc, TRUE,
+ 0, tip_offset + CORNER_RADIUS,
+ POPUP_WIDTH,
+ POPUP_HEIGHT - 2*CORNER_RADIUS - ARROW_BORDER);
+
+ gdk_draw_rectangle(mask, gc, TRUE,
+ CORNER_RADIUS, tip_offset,
+ POPUP_WIDTH - 2*CORNER_RADIUS,
+ POPUP_HEIGHT - ARROW_BORDER);
+
+ int off[][2] = {
+ { CORNER_RADIUS, tip_offset + CORNER_RADIUS },
+ { POPUP_WIDTH - CORNER_RADIUS, tip_offset + CORNER_RADIUS },
+ { POPUP_WIDTH - CORNER_RADIUS,
+ POPUP_HEIGHT - CORNER_RADIUS - ARROW_BORDER + tip_offset},
+ { CORNER_RADIUS,
+ POPUP_HEIGHT - CORNER_RADIUS - ARROW_BORDER + tip_offset}};
+
+ int i;
+ for(i=0;i<4;i++) {
+ gdk_draw_arc(mask, gc, TRUE,
+ off[i][0]-CORNER_RADIUS, off[i][1]-CORNER_RADIUS,
+ 2*CORNER_RADIUS, 2*CORNER_RADIUS,
+ 0, 360*64);
+ }
+
+ GdkPoint points[3] = { {POPUP_WIDTH*1/3, POPUP_HEIGHT/2},
+ {POPUP_WIDTH*2/3, POPUP_HEIGHT/2},
+ {tip_x,tip_y} };
+ gdk_draw_polygon(mask, gc, TRUE, points, 3);
+
+
+ gdk_window_shape_combine_mask(window->window, mask, 0, 0);
+}
+
+/* create a left aligned label (normal ones are centered) */
+static GtkWidget *gtk_label_left_new(char *str) {
+ GtkWidget *label = gtk_label_new(str);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.f, .5f);
+ return label;
+}
+
+/* the small labels are actually only on maemo small */
+#ifdef USE_MAEMO
+#define MARKUP_SMALL "%s"
+GtkWidget *gtk_label_small_left_new(char *str) {
+ GtkWidget *label = gtk_label_new("");
+ char *markup = g_markup_printf_escaped(MARKUP_SMALL, str);
+ gtk_label_set_markup(GTK_LABEL(label), markup);
+ g_free(markup);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.f, .5f);
+ return label;
+}
+#define gtk_label_big_left_new(a) gtk_label_left_new(a)
+#else
+#define gtk_label_small_left_new(a) gtk_label_left_new(a)
+#define MARKUP_BIG "%s"
+GtkWidget *gtk_label_big_left_new(char *str) {
+ GtkWidget *label = gtk_label_new("");
+ char *markup = g_markup_printf_escaped(MARKUP_BIG, str);
+ gtk_label_set_markup(GTK_LABEL(label), markup);
+ g_free(markup);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.f, .5f);
+ return label;
+}
+#endif
+
void cache_popup(map_context_t *mcontext, cache_t *cache) {
popup_context_t pcontext;
pcontext.appdata = mcontext->appdata;
@@ -282,15 +378,7 @@
cache->pos.lat, cache->pos.lon,
&sx, &sy);
- printf("screen pos %d/%d\n", sx, sy);
-
gdk_window_get_origin(mcontext->widget->window, &x, &y);
- printf("window = %d/%d +%d+%d %d*%d\n", x, y,
- mcontext->widget->allocation.x,
- mcontext->widget->allocation.y,
- mcontext->widget->allocation.width,
- mcontext->widget->allocation.height
- );
gint ax = 0, ay = 0;
if(sx > mcontext->widget->allocation.width/2)
@@ -299,17 +387,77 @@
if(sy > mcontext->widget->allocation.height/2)
ay = POPUP_HEIGHT;
+#if !defined(USE_MAEMO) || (MAEMO_VERSION_MAJOR < 5)
+ GdkColor color;
+ gdk_color_parse("darkgray", &color);
+ gtk_widget_modify_bg(GTK_WIDGET(pcontext.window), GTK_STATE_NORMAL, &color);
+#endif
+
gtk_window_move(GTK_WINDOW(pcontext.window),
x + mcontext->widget->allocation.x + sx - ax,
y + mcontext->widget->allocation.y + sy - ay);
- /* a frame with a vscale inside */
- GtkWidget *frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
- gtk_container_add(GTK_CONTAINER(frame), gtk_label_new(cache->name));
- gtk_container_add(GTK_CONTAINER(pcontext.window), frame);
+ GtkWidget *alignment = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
+ CORNER_RADIUS/2 + (ay?0:ARROW_BORDER),
+ CORNER_RADIUS/2 + (ay?ARROW_BORDER:0),
+ CORNER_RADIUS, CORNER_RADIUS);
+
+ /* --- actual content ---- */
+ GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
+
+ if(cache->id) {
+ GtkWidget *ihbox = gtk_hbox_new(FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(ihbox),
+ icon_get_widget(ICON_CACHE_TYPE, cache->type),
+ FALSE, FALSE, 5);
+
+ gtk_box_pack_start_defaults(GTK_BOX(ihbox),
+ gtk_label_big_left_new(cache->id));
+
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), ihbox);
+ }
+
+ if(cache->name) {
+ GtkWidget *label = gtk_label_small_left_new(cache->name);
+ gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), label);
+ }
+
+ GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
+ if(cache->terrain) {
+ GtkWidget *ihbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(ihbox),
+ gtk_label_small_left_new(_("Terrain:")), FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(ihbox),
+ icon_get_widget(ICON_STARS, (int)(cache->terrain*2-2)),
+ FALSE, FALSE, 5);
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), ihbox);
+ }
+
+ if(cache->difficulty) {
+ GtkWidget *ihbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(ihbox),
+ gtk_label_small_left_new(_("Difficulty:")), FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(ihbox),
+ icon_get_widget(ICON_STARS, (int)(cache->difficulty*2-2)),
+ FALSE, FALSE, 5);
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), ihbox);
+ }
+
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+ gtk_container_add(GTK_CONTAINER(alignment), vbox);
+ /* ----------------------- */
+
+
+ gtk_container_add(GTK_CONTAINER(pcontext.window), alignment);
+ /* give window its shape */
+ popup_window_shape(pcontext.window, ax, ay);
+
gtk_widget_show_all(pcontext.window);
/* handle this popup until it's gone */
@@ -384,7 +532,7 @@
return 1000.0*km/m_per_pix;
}
-#define CLICK_FUZZ (16)
+#define CLICK_FUZZ (24)
static gboolean
on_map_button_press_event(GtkWidget *widget,