1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
from gi.repository import GtkClutter, Clutter
5
GtkClutter.init([]) # Must be initialized before importing those:
6
from gi.repository import GObject, Gtk, Champlain, GtkChamplain
7
8
from markers import create_marker_layer
9
10
11
class LauncherGTK:
12
13
    def __init__(self):
14
        self.window = Gtk.Window()
15
        self.window.set_border_width(10)
16
        self.window.set_title("libchamplain Gtk+ demo (python introspection)")
17
        self.window.connect("destroy", Gtk.main_quit)
18
19
        vbox = Gtk.VBox(False, 10)
20
21
        embed = GtkChamplain.Embed()
22
23
        self.view = embed.get_view()
24
        self.view.set_reactive(True)
25
        self.view.connect('button-release-event', self.mouse_click_cb,
26
            self.view)
27
28
        self.view.set_property('kinetic-mode', True)
29
        self.view.set_property('zoom-level', 5)
30
31
        scale = Champlain.Scale()
32
        scale.connect_view(self.view)
33
        self.view.bin_layout_add(scale, Clutter.BinAlignment.START,
34
            Clutter.BinAlignment.END)
35
36
        license = self.view.get_license_actor()
37
        license.set_extra_text("Don't eat cereals with orange juice\nIt tastes bad")
38
39
        self.view.center_on(45.466, -73.75)
40
41
        self.layer = create_marker_layer(self.view)
42
        self.view.add_layer(self.layer)
43
        self.layer.hide_all_markers()
44
45
        self.path_layer = Champlain.PathLayer()
46
        # Cheap approx of Highway 10
47
        self.add_node(self.path_layer, 45.4095, -73.3197)
48
        self.add_node(self.path_layer, 45.4104, -73.2846)
49
        self.add_node(self.path_layer, 45.4178, -73.2239)
50
        self.add_node(self.path_layer, 45.4176, -73.2181)
51
        self.add_node(self.path_layer, 45.4151, -73.2126)
52
        self.add_node(self.path_layer, 45.4016, -73.1926)
53
        self.add_node(self.path_layer, 45.3994, -73.1877)
54
        self.add_node(self.path_layer, 45.4000, -73.1815)
55
        self.add_node(self.path_layer, 45.4151, -73.1218)
56
        self.view.add_layer(self.path_layer)
57
58
        embed.set_size_request(640, 480)
59
60
        bbox = Gtk.HBox(False, 10)
61
        button = Gtk.Button(stock=Gtk.STOCK_ZOOM_IN)
62
        button.connect("clicked", self.zoom_in)
63
        bbox.add(button)
64
65
        button = Gtk.Button(stock=Gtk.STOCK_ZOOM_OUT)
66
        button.connect("clicked", self.zoom_out)
67
        bbox.add(button)
68
69
        button = Gtk.ToggleButton(label="Markers")
70
        button.set_active(False)
71
        button.connect("toggled", self.toggle_layer)
72
        bbox.add(button)
73
74
        combo = Gtk.ComboBox()
75
        map_source_factory = Champlain.MapSourceFactory.dup_default()
76
        liststore = Gtk.ListStore(str, str)
77
        for source in map_source_factory.get_registered():
78
            liststore.append([source.get_id(), source.get_name()])
79
        combo.set_model(liststore)
80
        cell = Gtk.CellRendererText()
81
        combo.pack_start(cell, False)
82
        combo.add_attribute(cell, 'text', 1)
83
        combo.connect("changed", self.map_source_changed)
84
        combo.set_active(0)
85
        bbox.add(combo)
86
87
        self.spinbutton = Gtk.SpinButton.new_with_range(0, 20, 1)
88
        self.spinbutton.connect("changed", self.zoom_changed)
89
        self.view.connect("notify::zoom-level", self.map_zoom_changed)
90
        self.spinbutton.set_value(5)
91
        bbox.add(self.spinbutton)
92
93
        button = Gtk.Image()
94
        self.view.connect("notify::state", self.view_state_changed, button)
95
        bbox.pack_end(button, False, False, 0)
96
97
        vbox.pack_start(bbox, expand=False, fill=False, padding=0)
98
        vbox.add(embed)
99
100
        self.window.add(vbox)
101
102
        self.window.show_all()
103
    
104
    def add_node(self, path_layer, lat, lon):
105
        coord = Champlain.Coordinate.new_full(lat, lon)
106
        path_layer.add_node(coord)
107
108
    def zoom_in(self, widget):
109
        self.view.zoom_in()
110
111
    def zoom_out(self, widget):
112
        self.view.zoom_out()
113
114
    def toggle_layer(self, widget):
115
        if widget.get_active():
116
            self.path_layer.show()
117
            self.layer.animate_in_all_markers()
118
        else:
119
            self.path_layer.hide()
120
            self.layer.animate_out_all_markers()
121
122
    def mouse_click_cb(self, actor, event, view):
123
        x, y = event.x, event.y
124
        lat, lon = view.x_to_longitude(x), view.y_to_latitude(y)
125
        print "Mouse click at: %f %f" % (lon, lat)
126
        return True
127
128
    def zoom_changed(self, widget):
129
        self.view.set_property("zoom-level", self.spinbutton.get_value_as_int())
130
131
    def map_source_changed(self, widget):
132
        model = widget.get_model()
133
        iter = widget.get_active_iter()
134
        id = model.get_value(iter, 0)
135
        map_source_factory = Champlain.MapSourceFactory.dup_default()
136
        source = map_source_factory.create_cached_source(id);
137
        self.view.set_property("map-source", source)
138
139
    def map_zoom_changed(self, widget, value):
140
        self.spinbutton.set_value(self.view.get_property("zoom-level"))
141
142
    def view_state_changed(self, view, paramspec, image):
143
        state = view.get_state()
144
        if state == Champlain.State.LOADING:
145
            image.set_from_stock(Gtk.STOCK_NETWORK, Gtk.IconSize.BUTTON)
146
        else:
147
            image.clear()
148
149
150
if __name__ == "__main__":
151
    GObject.threads_init()
152
    LauncherGTK()
153
    Gtk.main()