local-rendering.c 27.6 KB
Newer Older
Simon Wenner's avatar
Simon Wenner committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
 * Copyright (C) 2009 Simon Wenner <simon@wenner.ch>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <gtk/gtk.h>
#include <champlain/champlain.h>
22
#include <champlain/champlain-memphis-renderer.h>
Simon Wenner's avatar
Simon Wenner committed
23
#include <champlain-gtk/champlain-gtk.h>
24
#include <clutter-gtk/clutter-gtk.h>
25 26 27 28
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
Simon Wenner's avatar
Simon Wenner committed
29 30 31 32 33 34

#define N_COLS 2
#define COL_ID 0
#define COL_NAME 1

guint map_index = 0;
35
guint rules_index = 0;
Simon Wenner's avatar
Simon Wenner committed
36
static const char *maps[] = { "schaffhausen.osm", "las_palmas.osm" };
37
static const char *rules[] = { "default-rules.xml", "high-contrast.xml" };
Simon Wenner's avatar
Simon Wenner committed
38

39
static GtkWidget *window;
40
static GtkWidget *memphis_box, *memphis_net_box, *memphis_local_box;
41
static GtkWidget *rules_tree_view, *bg_button, *map_data_state_img;
42

43 44 45 46 47
static GtkWidget *rule_edit_window = NULL;
static GtkWidget *polycolor, *polyminz, *polymaxz;
static GtkWidget *linecolor, *linesize, *lineminz, *linemaxz;
static GtkWidget *bordercolor, *bordersize, *borderminz, *bordermaxz;
static GtkWidget *textcolor, *textsize, *textminz, *textmaxz;
48
static ChamplainMemphisRule *current_rule = NULL;
49

50 51
static ChamplainMapSource *tile_source = NULL;

Simon Wenner's avatar
Simon Wenner committed
52 53 54 55 56 57 58 59 60
/*
 * Terminate the main loop.
 */
static void
on_destroy (GtkWidget *widget, gpointer data)
{
  gtk_main_quit ();
}

61
static void color_gdk_to_clutter (const GdkColor *gdk_color,
62
                                  ClutterColor *clutter_color)
63 64 65 66 67 68 69 70
{
  clutter_color->red = CLAMP (((gdk_color->red / 65535.0) * 255), 0, 255);
  clutter_color->green = CLAMP (((gdk_color->green / 65535.0) * 255), 0, 255);
  clutter_color->blue = CLAMP (((gdk_color->blue / 65535.0) * 255), 0, 255);
  clutter_color->alpha = 255;
}

static void color_clutter_to_gdk (const ClutterColor *clutter_color,
71
                                  GdkColor *gdk_color)
72 73 74 75 76 77
{
  gdk_color->red = ((guint16) clutter_color->red) << 8;
  gdk_color->green = ((guint16) clutter_color->green) << 8;
  gdk_color->blue = ((guint16) clutter_color->blue) << 8;
}

78
static void
79
data_source_state_changed (ChamplainNetworkBboxTileSource *source,
80
                           GtkImage *image)
81
{
82 83 84 85 86
  gtk_image_clear (image);
  g_print ("NET DATA SOURCE STATE: done\n");
  g_signal_handlers_disconnect_by_func (source,
                                        data_source_state_changed,
                                        image);
87 88
}

Simon Wenner's avatar
Simon Wenner committed
89
static void
90
load_network_map_data (ChamplainNetworkBboxTileSource *source, ChamplainView *view)
Simon Wenner's avatar
Simon Wenner committed
91
{
92
  gdouble lat, lon;
93

94
  g_signal_connect (source, "data-loaded", G_CALLBACK (data_source_state_changed),
95
                    map_data_state_img);
96

97 98
  gtk_image_set_from_stock (GTK_IMAGE (map_data_state_img), GTK_STOCK_NETWORK, GTK_ICON_SIZE_BUTTON);
  g_print ("NET DATA SOURCE STATE: loading\n");
99
  g_object_get (G_OBJECT (view), "latitude", &lat, "longitude", &lon, NULL);
100

101
  champlain_network_bbox_tile_source_load_map_data (source,
102 103 104 105 106 107 108 109 110
      lon - 0.008, lat - 0.008, lon + 0.008, lat + 0.008);
}

static void
load_rules_into_gui (ChamplainView *view)
{
  GList* ids, *ptr;
  GtkTreeModel *store;
  GtkTreeIter iter;
111 112
  GdkColor gdk_color;
  ClutterColor *clutter_color;
113
  ChamplainMemphisRenderer *renderer;
114

115 116
  renderer = CHAMPLAIN_MEMPHIS_RENDERER ( champlain_map_source_get_renderer (CHAMPLAIN_MAP_SOURCE (tile_source)));
  ids = champlain_memphis_renderer_get_rule_ids (renderer);
117

118
  clutter_color = champlain_memphis_renderer_get_background_color (renderer);
119 120

  color_clutter_to_gdk (clutter_color, &gdk_color);
121 122 123
  clutter_color_free (clutter_color);

  gtk_color_button_set_color (GTK_COLOR_BUTTON (bg_button), &gdk_color);
124 125 126 127 128 129 130 131 132 133 134 135 136

  store = gtk_tree_view_get_model (GTK_TREE_VIEW (rules_tree_view));
  gtk_list_store_clear (GTK_LIST_STORE (store));

  ptr = ids;
  while (ptr != NULL)
    {
      gtk_list_store_append (GTK_LIST_STORE (store), &iter);
      gtk_list_store_set (GTK_LIST_STORE (store), &iter, 0, ptr->data, -1);
      ptr = ptr->next;
    }

  g_list_free (ids);
137 138
}

139 140 141 142
static void
rule_window_close_cb (GtkWidget *widget, gpointer data)
{
  gtk_widget_destroy (rule_edit_window);
143 144
  memphis_rule_free (current_rule);
  current_rule = NULL;
145 146 147 148
  rule_edit_window = NULL;
}

static void
149
rule_apply_cb (GtkWidget *widget, ChamplainMemphisRenderer *renderer)
150
{
151
  ChamplainMemphisRule *rule = current_rule;
152 153
  GdkColor color;

154
  if (rule->polygon)
155 156
    {
      gtk_color_button_get_color (GTK_COLOR_BUTTON (polycolor), &color);
157 158 159 160 161
      rule->polygon->color_red = color.red >> 8;
      rule->polygon->color_green = color.green >> 8;
      rule->polygon->color_blue = color.blue >> 8;
      rule->polygon->z_min = gtk_spin_button_get_value (GTK_SPIN_BUTTON (polyminz));
      rule->polygon->z_max = gtk_spin_button_get_value (GTK_SPIN_BUTTON (polymaxz));
162
    }
163
  if (rule->line)
164 165
    {
      gtk_color_button_get_color (GTK_COLOR_BUTTON (linecolor), &color);
166 167 168 169 170 171
      rule->line->color_red = color.red >> 8;
      rule->line->color_green = color.green >> 8;
      rule->line->color_blue = color.blue >> 8;
      rule->line->size = gtk_spin_button_get_value (GTK_SPIN_BUTTON (linesize));
      rule->line->z_min = gtk_spin_button_get_value (GTK_SPIN_BUTTON (lineminz));
      rule->line->z_max = gtk_spin_button_get_value (GTK_SPIN_BUTTON (linemaxz));
172
    }
173
  if (rule->border)
174 175
    {
      gtk_color_button_get_color (GTK_COLOR_BUTTON (bordercolor), &color);
176 177 178 179 180 181
      rule->border->color_red = color.red >> 8;
      rule->border->color_green = color.green >> 8;
      rule->border->color_blue = color.blue >> 8;
      rule->border->size = gtk_spin_button_get_value (GTK_SPIN_BUTTON (bordersize));
      rule->border->z_min = gtk_spin_button_get_value (GTK_SPIN_BUTTON (borderminz));
      rule->border->z_max = gtk_spin_button_get_value (GTK_SPIN_BUTTON (bordermaxz));
182
    }
183
  if (rule->text)
184 185
    {
      gtk_color_button_get_color (GTK_COLOR_BUTTON (textcolor), &color);
186 187 188 189 190 191
      rule->text->color_red = color.red >> 8;
      rule->text->color_green = color.green >> 8;
      rule->text->color_blue = color.blue >> 8;
      rule->text->size = gtk_spin_button_get_value (GTK_SPIN_BUTTON (textsize));
      rule->text->z_min = gtk_spin_button_get_value (GTK_SPIN_BUTTON (textminz));
      rule->text->z_max = gtk_spin_button_get_value (GTK_SPIN_BUTTON (textmaxz));
192 193
    }

194
  champlain_memphis_renderer_set_rule (renderer, rule);
195 196 197
}

GtkWidget *
198
gtk_memphis_prop_new (gint type, ChamplainMemphisRuleAttr *attr)
199 200 201 202 203 204
{
  GtkWidget *hbox, *cb, *sb1, *sb2, *sb3;
  GdkColor gcolor;

  hbox = gtk_hbox_new (FALSE, 0);

205 206 207
  gcolor.red = ((guint16) attr->color_red) << 8;
  gcolor.green = ((guint16) attr->color_green) << 8;
  gcolor.blue = ((guint16) attr->color_blue) << 8;
208 209 210 211 212 213
  cb = gtk_color_button_new_with_color (&gcolor);
  gtk_box_pack_start (GTK_BOX (hbox), cb, FALSE, FALSE, 0);

  if (type != 0)
    {
      sb1 = gtk_spin_button_new_with_range (0.0, 20.0, 0.1);
214
      gtk_spin_button_set_value (GTK_SPIN_BUTTON (sb1), attr->size);
215 216 217 218
      gtk_box_pack_start (GTK_BOX (hbox), sb1, FALSE, FALSE, 0);
    }

  sb2 = gtk_spin_button_new_with_range (12, 18, 1);
219
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (sb2), attr->z_min);
220 221
  gtk_box_pack_start (GTK_BOX (hbox), sb2, FALSE, FALSE, 0);
  sb3 = gtk_spin_button_new_with_range (12, 18, 1);
222
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (sb3), attr->z_max);
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
  gtk_box_pack_start (GTK_BOX (hbox), sb3, FALSE, FALSE, 0);

  if (type == 0)
    {
      polycolor = cb;
      polyminz = sb2;
      polymaxz = sb3;
    }
  else if (type == 1)
    {
      linecolor = cb;
      linesize = sb1;
      lineminz = sb2;
      linemaxz = sb3;
    }
  else if (type == 2)
    {
      bordercolor = cb;
      bordersize = sb1;
      borderminz = sb2;
      bordermaxz = sb3;
    }
  else
    {
      textcolor = cb;
      textsize = sb1;
      textminz = sb2;
      textmaxz = sb3;
    }
  return hbox;
}

static void
256 257
create_rule_edit_window (ChamplainMemphisRule *rule, gchar* id,
                         ChamplainMemphisRenderer *renderer)
258 259 260 261 262 263 264 265 266
{
  GtkWidget *label, *table, *props, *button;

  current_rule = rule;

  rule_edit_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_set_border_width (GTK_CONTAINER (rule_edit_window), 10);
  gtk_window_set_title (GTK_WINDOW (rule_edit_window), id);
  gtk_window_set_position (GTK_WINDOW (rule_edit_window),
267
                           GTK_WIN_POS_CENTER_ON_PARENT);
268
  gtk_window_set_transient_for (GTK_WINDOW (rule_edit_window),
269
                                GTK_WINDOW (window));
270
  g_signal_connect (G_OBJECT (rule_edit_window), "destroy",
271
                    G_CALLBACK (rule_window_close_cb), NULL);
272 273 274 275 276 277

  table = gtk_table_new (6, 2, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 8);
  gtk_table_set_row_spacings (GTK_TABLE (table), 8);
  label = gtk_label_new (NULL);

278
  if (rule->type == CHAMPLAIN_MEMPHIS_RULE_TYPE_WAY)
279
    gtk_label_set_markup (GTK_LABEL (label), "<b>Way properties</b>");
280
  else if (rule->type == CHAMPLAIN_MEMPHIS_RULE_TYPE_NODE)
281
    gtk_label_set_markup (GTK_LABEL (label), "<b>Node properties</b>");
282
  else if (rule->type == CHAMPLAIN_MEMPHIS_RULE_TYPE_RELATION)
283
    gtk_label_set_markup (GTK_LABEL (label), "<b>Relation properties</b>");
284
  else
285
    gtk_label_set_markup (GTK_LABEL (label), "<b>Unknown type</b>");
286 287 288

  gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 2, 0, 1);

289
  if (rule->polygon != NULL)
290 291 292
    {
      label = gtk_label_new ("Polygon: ");
      gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
293
      props = gtk_memphis_prop_new (0, rule->polygon);
294 295
      gtk_table_attach_defaults (GTK_TABLE (table), props, 1, 2, 1, 2);
    }
296
  if (rule->line != NULL)
297 298 299
    {
      label = gtk_label_new ("Line: ");
      gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
300
      props = gtk_memphis_prop_new (1, rule->line);
301 302
      gtk_table_attach_defaults (GTK_TABLE (table), props, 1, 2, 2, 3);
    }
303
  if (rule->border != NULL)
304 305 306
    {
      label = gtk_label_new ("Border: ");
      gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4);
307
      props = gtk_memphis_prop_new (2, rule->border);
308 309
      gtk_table_attach_defaults (GTK_TABLE (table), props, 1, 2, 3, 4);
    }
310
  if (rule->text != NULL)
311 312 313
    {
      label = gtk_label_new ("Text: ");
      gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 4, 5);
314
      props = gtk_memphis_prop_new (3, rule->text);
315 316 317 318 319 320 321 322
      gtk_table_attach_defaults (GTK_TABLE (table), props, 1, 2, 4, 5);
    }

  GtkWidget *vbox = gtk_hbox_new (TRUE, 0);

  button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
  g_signal_connect (G_OBJECT (button), "clicked",
323
                    G_CALLBACK (rule_window_close_cb), NULL);
324 325
  button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
  g_signal_connect (G_OBJECT (button), "clicked",
326
                    G_CALLBACK (rule_apply_cb), renderer);
327 328 329 330 331 332 333 334 335 336
  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);

  GtkWidget *mainbox = gtk_vbox_new (FALSE, 0);
  gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (mainbox), vbox, FALSE, FALSE, 0);

  gtk_container_add (GTK_CONTAINER (rule_edit_window), mainbox);
  gtk_widget_show_all (rule_edit_window);
}

337 338 339
static void
zoom_to_map_data (GtkWidget *widget, ChamplainView *view)
{
340
  ChamplainMemphisRenderer *renderer;
341 342 343
  ChamplainBoundingBox *bbox;
  gdouble lat, lon;

344 345
  renderer = CHAMPLAIN_MEMPHIS_RENDERER ( champlain_map_source_get_renderer (CHAMPLAIN_MAP_SOURCE (tile_source)));
  g_object_get (G_OBJECT (renderer), "bounding-box", &bbox, NULL);
346 347 348 349
  champlain_bounding_box_get_center (bbox, &lat, &lon);

  champlain_view_center_on (CHAMPLAIN_VIEW(view), lat, lon);
  champlain_view_set_zoom_level (CHAMPLAIN_VIEW(view), 15);
Simon Wenner's avatar
Simon Wenner committed
350 351
}

352

353 354 355 356 357 358
static void
request_osm_data_cb (GtkWidget *widget, ChamplainView *view)
{
  gdouble lat, lon;
  g_object_get (G_OBJECT (view), "latitude", &lat, "longitude", &lon, NULL);

359
  if (g_strcmp0 (champlain_map_source_get_id (tile_source), "memphis-network") == 0)
360
    {
361 362
      ChamplainNetworkBboxTileSource *source = CHAMPLAIN_NETWORK_BBOX_TILE_SOURCE (tile_source);
      load_network_map_data (source, view);
363 364 365
    }
}

366 367 368
void
bg_color_set_cb (GtkColorButton *widget, ChamplainView *view)
{
369
  GdkColor gdk_color;
370

371
  gtk_color_button_get_color (widget, &gdk_color);
372

373
  if (strncmp (champlain_map_source_get_id (tile_source), "memphis", 7) == 0)
374
    {
375
      ChamplainMemphisRenderer *renderer;
376
      ClutterColor clutter_color;
377
      color_gdk_to_clutter (&gdk_color, &clutter_color);
378

379 380 381
      renderer = CHAMPLAIN_MEMPHIS_RENDERER ( champlain_map_source_get_renderer (CHAMPLAIN_MAP_SOURCE (tile_source)));

      champlain_memphis_renderer_set_background_color (renderer, &clutter_color);
382 383 384
    }
}

Simon Wenner's avatar
Simon Wenner committed
385 386 387 388 389 390 391
static void
map_source_changed (GtkWidget *widget, ChamplainView *view)
{
  gchar* id;
  ChamplainMapSource *source;
  GtkTreeIter iter;
  GtkTreeModel *model;
392
  ChamplainMemphisRenderer *renderer;
Simon Wenner's avatar
Simon Wenner committed
393 394 395 396 397 398 399 400 401 402

  if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter))
    return;

  model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));

  gtk_tree_model_get (model, &iter, COL_ID, &id, -1);

  ChamplainMapSourceFactory *factory = champlain_map_source_factory_dup_default ();
  source = champlain_map_source_factory_create (factory, id);
403
  renderer = CHAMPLAIN_MEMPHIS_RENDERER ( champlain_map_source_get_renderer (CHAMPLAIN_MAP_SOURCE (source)));
Simon Wenner's avatar
Simon Wenner committed
404 405 406

  if (source != NULL)
    {
407 408 409 410
      ChamplainMapSourceChain *source_chain;
      ChamplainMapSource *src;
      guint tile_size;

Simon Wenner's avatar
Simon Wenner committed
411
      if (g_strcmp0 (id, "memphis-local") == 0)
412
        {
413 414
          champlain_memphis_renderer_load_rules (renderer, rules[rules_index]);
          champlain_file_tile_source_load_map_data (CHAMPLAIN_FILE_TILE_SOURCE (source), maps[map_index]);
415 416 417 418 419 420
          gtk_widget_hide_all (memphis_box);
          gtk_widget_set_no_show_all (memphis_box, FALSE);
          gtk_widget_set_no_show_all (memphis_local_box, FALSE);
          gtk_widget_set_no_show_all (memphis_net_box, TRUE);
          gtk_widget_show_all (memphis_box);
        }
421
      else if (g_strcmp0 (id, "memphis-network") == 0)
422
        {
423 424
          champlain_memphis_renderer_load_rules (renderer, rules[rules_index]);
          load_network_map_data (CHAMPLAIN_NETWORK_BBOX_TILE_SOURCE (source), view);
425 426 427 428 429 430 431 432 433 434 435
          gtk_widget_hide_all (memphis_box);
          gtk_widget_set_no_show_all (memphis_box, FALSE);
          gtk_widget_set_no_show_all (memphis_local_box, TRUE);
          gtk_widget_set_no_show_all (memphis_net_box, FALSE);
          gtk_widget_show_all (memphis_box);
        }
      else
        {
          gtk_widget_hide_all (memphis_box);
          gtk_widget_set_no_show_all (memphis_box, TRUE);
        }
Simon Wenner's avatar
Simon Wenner committed
436

437 438 439 440
      tile_source = CHAMPLAIN_MAP_SOURCE(source);

      source_chain = champlain_map_source_chain_new ();

Jiří Techet's avatar
Jiří Techet committed
441
      tile_size = champlain_map_source_get_tile_size (tile_source);
442
      src = champlain_map_source_factory_create_error_source (factory, tile_size);
443

Jiří Techet's avatar
Jiří Techet committed
444 445
      champlain_map_source_chain_push (source_chain, src);
      champlain_map_source_chain_push (source_chain, tile_source);
446

447 448
      src = CHAMPLAIN_MAP_SOURCE(champlain_memory_cache_new_full (100));
      champlain_map_source_set_renderer (src, CHAMPLAIN_RENDERER (champlain_image_renderer_new ()));
449

Jiří Techet's avatar
Jiří Techet committed
450
      champlain_map_source_chain_push (source_chain, src);
451 452

      g_object_set (G_OBJECT (view), "map-source", source_chain, NULL);
453 454
      if (strncmp (id, "memphis", 7) == 0)
        load_rules_into_gui (view);
Simon Wenner's avatar
Simon Wenner committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
    }

  g_object_unref (factory);
}

static void
map_data_changed (GtkWidget *widget, ChamplainView *view)
{
  gint index;
  GtkTreeIter iter;
  GtkTreeModel *model;

  if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter))
    return;

  model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
  gtk_tree_model_get (model, &iter, 1, &index, -1);
472

Simon Wenner's avatar
Simon Wenner committed
473 474
  map_index = index;

475
  if (g_strcmp0 (champlain_map_source_get_id (tile_source), "memphis-local") == 0)
476
    champlain_file_tile_source_load_map_data (CHAMPLAIN_FILE_TILE_SOURCE (tile_source), maps[map_index]);
Simon Wenner's avatar
Simon Wenner committed
477 478
}

479 480 481 482 483 484 485 486 487 488 489 490 491
static void
rules_changed (GtkWidget *widget, ChamplainView *view)
{
  gchar* file;
  GtkTreeIter iter;
  GtkTreeModel *model;

  if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter))
    return;

  model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
  gtk_tree_model_get (model, &iter, 0, &file, -1);

492
  if (strncmp (champlain_map_source_get_id (tile_source), "memphis", 7) == 0)
493
    {
494 495 496 497
      ChamplainMemphisRenderer *renderer;

      renderer = CHAMPLAIN_MEMPHIS_RENDERER ( champlain_map_source_get_renderer (CHAMPLAIN_MAP_SOURCE (tile_source)));
      champlain_memphis_renderer_load_rules (renderer, file);
498 499
      load_rules_into_gui (view);
    }
500 501
}

Simon Wenner's avatar
Simon Wenner committed
502 503 504 505
static void
zoom_changed (GtkSpinButton *spinbutton,
              ChamplainView *view)
{
Jiří Techet's avatar
Jiří Techet committed
506
  gint zoom = gtk_spin_button_get_value_as_int (spinbutton);
507
  g_object_set (G_OBJECT(view), "zoom-level", zoom, NULL);
Simon Wenner's avatar
Simon Wenner committed
508 509 510 511 512 513 514 515
}

static void
map_zoom_changed (ChamplainView *view,
                  GParamSpec *gobject,
                  GtkSpinButton *spinbutton)
{
  gint zoom;
516
  g_object_get (G_OBJECT(view), "zoom-level", &zoom, NULL);
Jiří Techet's avatar
Jiří Techet committed
517
  gtk_spin_button_set_value (spinbutton, zoom);
Simon Wenner's avatar
Simon Wenner committed
518 519 520 521 522 523
}

static void
zoom_in (GtkWidget *widget,
         ChamplainView *view)
{
Jiří Techet's avatar
Jiří Techet committed
524
  champlain_view_zoom_in (view);
Simon Wenner's avatar
Simon Wenner committed
525 526 527 528 529 530
}

static void
zoom_out (GtkWidget *widget,
          ChamplainView *view)
{
Jiří Techet's avatar
Jiří Techet committed
531
  champlain_view_zoom_out (view);
Simon Wenner's avatar
Simon Wenner committed
532 533 534 535 536 537 538 539 540 541 542 543 544
}

static void
build_source_combo_box (GtkComboBox *box)
{
  ChamplainMapSourceFactory *factory;
  GSList *sources, *iter;
  gint i = 0;
  GtkTreeStore *store;
  GtkTreeIter parent;
  GtkCellRenderer *cell;

  store = gtk_tree_store_new (N_COLS, G_TYPE_STRING, /* id */
545 546
                              G_TYPE_STRING, /* name */
                              -1);
Simon Wenner's avatar
Simon Wenner committed
547 548 549 550 551 552

  factory = champlain_map_source_factory_dup_default ();
  sources = champlain_map_source_factory_dup_list (factory);

  iter = sources;
  while (iter != NULL)
553 554
    {
      ChamplainMapSourceDesc *desc;
Simon Wenner's avatar
Simon Wenner committed
555

556
      desc = (ChamplainMapSourceDesc*) iter->data;
Simon Wenner's avatar
Simon Wenner committed
557

558 559 560
      gtk_tree_store_append (store, &parent, NULL);
      gtk_tree_store_set (store, &parent, COL_ID, desc->id,
                          COL_NAME, desc->name, -1);
Simon Wenner's avatar
Simon Wenner committed
561

562 563
      iter = g_slist_next (iter);
    }
Simon Wenner's avatar
Simon Wenner committed
564 565 566 567 568 569 570 571 572

  g_slist_free (sources);
  g_object_unref (factory);

  gtk_combo_box_set_model (box, GTK_TREE_MODEL (store));

  cell = gtk_cell_renderer_text_new ();
  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (box), cell, FALSE);
  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (box), cell,
573
                                  "text", COL_NAME, NULL);
Simon Wenner's avatar
Simon Wenner committed
574 575 576 577 578 579 580 581 582 583
}

static void
build_data_combo_box (GtkComboBox *box)
{
  GtkTreeStore *store;
  GtkTreeIter parent;
  GtkCellRenderer *cell;

  store = gtk_tree_store_new (2, G_TYPE_STRING, /* file name */
584
                              G_TYPE_INT, /* index */ -1);
Simon Wenner's avatar
Simon Wenner committed
585 586 587

  gtk_tree_store_append (store, &parent, NULL);
  gtk_tree_store_set (store, &parent, 0, maps[0],
588
                      1, 0, -1);
Simon Wenner's avatar
Simon Wenner committed
589 590 591

  gtk_tree_store_append (store, &parent, NULL);
  gtk_tree_store_set (store, &parent, 0, maps[1],
592
                      1, 1, -1);
Simon Wenner's avatar
Simon Wenner committed
593 594 595 596 597 598

  gtk_combo_box_set_model (box, GTK_TREE_MODEL (store));

  cell = gtk_cell_renderer_text_new ();
  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (box), cell, FALSE);
  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (box), cell,
599
                                  "text", 0, NULL);
Simon Wenner's avatar
Simon Wenner committed
600 601 602 603 604 605 606 607 608 609 610
}

static void
build_rules_combo_box (GtkComboBox *box)
{
  GtkTreeStore *store;
  GtkTreeIter parent;
  GtkCellRenderer *cell;

  store = gtk_tree_store_new (1, G_TYPE_STRING, /* file name */ -1);
  gtk_tree_store_append (store, &parent, NULL);
611
  gtk_tree_store_set (store, &parent, 0, rules[0], -1);
Simon Wenner's avatar
Simon Wenner committed
612

613 614
  gtk_tree_store_append (store, &parent, NULL);
  gtk_tree_store_set (store, &parent, 0, rules[1], -1);
Simon Wenner's avatar
Simon Wenner committed
615 616 617 618 619 620

  gtk_combo_box_set_model (box, GTK_TREE_MODEL (store));

  cell = gtk_cell_renderer_text_new ();
  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (box), cell, FALSE);
  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (box), cell,
621
                                  "text", 0, NULL);
Simon Wenner's avatar
Simon Wenner committed
622 623
}

624
void list_item_selected_cb (GtkTreeView *tree_view,
625 626 627
                            GtkTreePath *path,
                            GtkTreeViewColumn *column,
                            ChamplainView *view)
628 629 630 631 632
{
  GtkTreeIter iter;
  GtkTreeModel *model;
  char *id;
  GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
633
  ChamplainMemphisRule *rule;
634 635 636 637

  if (rule_edit_window != NULL)
    return;

638 639
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
    {
640 641 642 643
      ChamplainMemphisRenderer *renderer;

      renderer = CHAMPLAIN_MEMPHIS_RENDERER ( champlain_map_source_get_renderer (CHAMPLAIN_MAP_SOURCE (tile_source)));

644
      gtk_tree_model_get (model, &iter, 0, &id, -1);
645

646
      rule = champlain_memphis_renderer_get_rule (renderer, id);
647

648
      if (rule != NULL)
649
        create_rule_edit_window (rule, id, renderer);
650

651 652
      g_free (id);
    }
653 654
}

Simon Wenner's avatar
Simon Wenner committed
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
int
main (int argc,
      char *argv[])
{
  GtkWidget *widget, *hbox, *bbox, *menubox, *button, *viewport, *label;
  ChamplainView *view;

  g_thread_init (NULL);
  gtk_clutter_init (&argc, &argv);

  /* create the main, top level, window */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  /* give the window a 10px wide border */
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);

  /* give it the title */
  gtk_window_set_title (GTK_WINDOW (window), "libchamplain Gtk+ demo");

  /* Connect the destroy event of the window with our on_destroy function
   * When the window is about to be destroyed we get a notificaiton and
   * stop the main GTK loop
   */
  g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (on_destroy),
679
                    NULL);
Simon Wenner's avatar
Simon Wenner committed
680 681 682

  hbox = gtk_hbox_new (FALSE, 10);
  menubox = gtk_vbox_new (FALSE, 10);
683 684 685 686 687 688
  memphis_box = gtk_vbox_new (FALSE, 10);
  gtk_widget_set_no_show_all (memphis_box, TRUE);
  memphis_net_box = gtk_hbox_new (FALSE, 10);
  gtk_widget_set_no_show_all (memphis_net_box, TRUE);
  memphis_local_box = gtk_hbox_new (FALSE, 10);
  gtk_widget_set_no_show_all (memphis_local_box, TRUE);
Simon Wenner's avatar
Simon Wenner committed
689 690 691 692 693

  widget = gtk_champlain_embed_new ();
  view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (widget));

  g_object_set (G_OBJECT (view), "scroll-mode", CHAMPLAIN_SCROLL_MODE_KINETIC,
694
                "zoom-level", 9, NULL);
Simon Wenner's avatar
Simon Wenner committed
695 696 697 698 699 700 701 702 703 704 705 706 707

  gtk_widget_set_size_request (widget, 640, 480);

  /* first line of buttons */
  bbox =  gtk_hbox_new (FALSE, 10);
  button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_IN);
  g_signal_connect (button, "clicked", G_CALLBACK (zoom_in), view);
  gtk_container_add (GTK_CONTAINER (bbox), button);

  button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_OUT);
  g_signal_connect (button, "clicked", G_CALLBACK (zoom_out), view);
  gtk_container_add (GTK_CONTAINER (bbox), button);

Jiří Techet's avatar
Jiří Techet committed
708
  button = gtk_spin_button_new_with_range (0, 20, 1);
Simon Wenner's avatar
Simon Wenner committed
709
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (button),
710
                             champlain_view_get_zoom_level (view));
Simon Wenner's avatar
Simon Wenner committed
711 712
  g_signal_connect (button, "changed", G_CALLBACK (zoom_changed), view);
  g_signal_connect (view, "notify::zoom-level", G_CALLBACK (map_zoom_changed),
713
                    button);
Simon Wenner's avatar
Simon Wenner committed
714 715 716 717 718 719 720 721 722 723 724
  gtk_container_add (GTK_CONTAINER (bbox), button);

  gtk_box_pack_start (GTK_BOX (menubox), bbox, FALSE, FALSE, 0);

  /* map source combo box */
  button = gtk_combo_box_new ();
  build_source_combo_box (GTK_COMBO_BOX (button));
  gtk_combo_box_set_active (GTK_COMBO_BOX (button), 0);
  g_signal_connect (button, "changed", G_CALLBACK (map_source_changed), view);
  gtk_box_pack_start (GTK_BOX (menubox), button, FALSE, FALSE, 0);

725
  /* Memphis options */
Simon Wenner's avatar
Simon Wenner committed
726 727
  label = gtk_label_new (NULL);
  gtk_label_set_markup (GTK_LABEL (label), "<b>Memphis Rendering Options</b>");
728
  gtk_box_pack_start (GTK_BOX (memphis_box), label, FALSE, FALSE, 0);
729

730
  /* local source panel */
Simon Wenner's avatar
Simon Wenner committed
731 732 733 734
  button = gtk_combo_box_new ();
  build_data_combo_box (GTK_COMBO_BOX (button));
  gtk_combo_box_set_active (GTK_COMBO_BOX (button), 0);
  g_signal_connect (button, "changed", G_CALLBACK (map_data_changed), view);
735
  gtk_box_pack_start (GTK_BOX (memphis_local_box), button, FALSE, FALSE, 0);
736 737 738

  button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_FIT);
  g_signal_connect (button, "clicked", G_CALLBACK (zoom_to_map_data), view);
739
  gtk_container_add (GTK_CONTAINER (memphis_local_box), button);
740

741
  gtk_box_pack_start (GTK_BOX (memphis_box), memphis_local_box, FALSE, FALSE, 0);
Simon Wenner's avatar
Simon Wenner committed
742

743 744 745 746 747
  /* network source panel */
  button = gtk_button_new_with_label ("Request OSM data");
  g_signal_connect (button, "clicked", G_CALLBACK (request_osm_data_cb), view);
  gtk_box_pack_start (GTK_BOX (memphis_net_box), button, FALSE, FALSE, 0);

748 749 750
  map_data_state_img = gtk_image_new ();
  gtk_box_pack_start (GTK_BOX (memphis_net_box), map_data_state_img, FALSE, FALSE, 0);

751 752 753
  gtk_box_pack_start (GTK_BOX (memphis_box), memphis_net_box, FALSE, FALSE, 0);

  /* rules chooser */
Simon Wenner's avatar
Simon Wenner committed
754 755 756
  button = gtk_combo_box_new ();
  build_rules_combo_box (GTK_COMBO_BOX (button));
  gtk_combo_box_set_active (GTK_COMBO_BOX (button), 0);
757
  g_signal_connect (button, "changed", G_CALLBACK (rules_changed), view);
758 759 760 761 762 763 764 765
  gtk_box_pack_start (GTK_BOX (memphis_box), button, FALSE, FALSE, 0);

  /* bg chooser */
  bbox =  gtk_hbox_new (FALSE, 10);

  label = gtk_label_new (NULL);
  gtk_label_set_markup (GTK_LABEL (label), "Background color");
  gtk_box_pack_start (GTK_BOX (bbox), label, FALSE, FALSE, 0);
766

767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
  bg_button = gtk_color_button_new ();
  gtk_color_button_set_title (GTK_COLOR_BUTTON (bg_button), "Background");
  g_signal_connect (bg_button, "color-set", G_CALLBACK (bg_color_set_cb), view);
  gtk_box_pack_start (GTK_BOX (bbox), bg_button, FALSE, FALSE, 0);

  gtk_box_pack_start (GTK_BOX (memphis_box), bbox, FALSE, FALSE, 0);

  /* rules list */
  label = gtk_label_new ("Rules");
  bbox =  gtk_hbox_new (FALSE, 10);
  gtk_box_pack_start (GTK_BOX (bbox), label, FALSE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (memphis_box), bbox, FALSE, FALSE, 0);

  GtkListStore *store;
  GtkWidget *tree_view, *scrolled;
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;

  store = gtk_list_store_new (1, G_TYPE_STRING);

  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
  rules_tree_view = tree_view;
  g_object_unref (store);
  renderer = gtk_cell_renderer_text_new ();

  column = gtk_tree_view_column_new_with_attributes (NULL, renderer, "text", 0, NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE);

796
  gtk_tree_view_get_selection (GTK_TREE_VIEW(tree_view));
Jiří Techet's avatar
Jiří Techet committed
797
  g_signal_connect (tree_view, "row-activated", G_CALLBACK(list_item_selected_cb), view);
798

799 800
  scrolled = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
801
                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
802 803 804 805
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrolled), tree_view);

  gtk_box_pack_start (GTK_BOX (memphis_box), scrolled, TRUE, TRUE, 0);
  gtk_box_pack_start (GTK_BOX (menubox), memphis_box, TRUE, TRUE, 0);
806

Simon Wenner's avatar
Simon Wenner committed
807
  /* viewport */
808
  viewport = gtk_frame_new (NULL);
Simon Wenner's avatar
Simon Wenner committed
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
  gtk_container_add (GTK_CONTAINER (viewport), widget);

  gtk_box_pack_end (GTK_BOX (hbox), menubox, FALSE, FALSE, 0);
  gtk_container_add (GTK_CONTAINER (hbox), viewport);

  /* and insert it into the main window  */
  gtk_container_add (GTK_CONTAINER (window), hbox);

  /* make sure that everything, window and label, are visible */
  gtk_widget_show_all (window);
  champlain_view_center_on (CHAMPLAIN_VIEW(view), 28.13476, -15.43814);
  /* start the main loop */
  gtk_main ();

  return 0;
}