#!/usr/bin/env python
# -*- coding: utf-8 -*-
-
-#This is a demonstration of the libchamplain python binding.
-#It will display a blue "pulsating" dot on a given position on the map
-#A old legend that this position is the bed of Pierlux. You will have to find out...
-
+"""This is a demonstration of the libchamplain python binding.
+It will display a blue "pulsating" dot on a given position on the map
+A old legend that this position is the bed of Pierlux. You will have
+to find out..."""
import champlain
import clutter
import cairo
POSITION = [45.528178, -73.563788]
SCREEN_SIZE = [640, 480]
-#The AnimatedMarker will extend the champlain.Marker class
class AnimatedMarker(champlain.Marker) :
+ """The AnimatedMarker will extend the champlain.Marker class"""
def __init__(self,color=None) :
champlain.Marker.__init__(self)
if not color :
color = MARKER_COLOR
- #Cairo definition of the inner marker
+ # Cairo definition of the inner marker
bg_in = clutter.CairoTexture(MARKER_SIZE, MARKER_SIZE)
cr_in = bg_in.cairo_create()
cr_in.set_source_rgb(0, 0, 0)
- cr_in.arc(MARKER_SIZE / 2.0, MARKER_SIZE / 2.0, MARKER_SIZE / 2.0, 0, 2 * math.pi)
+ cr_in.arc(MARKER_SIZE / 2.0, MARKER_SIZE / 2.0, MARKER_SIZE / 2.0,
+ 0, 2 * math.pi)
cr_in.close_path()
cr_in.set_source_rgba(*color)
cr_in.fill()
bg_in.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER)
bg_in.set_position(0, 0)
- #Cairo definition of the outside circle (that will be animated)
+ # Cairo definition of the outside circle (that will be animated)
bg_out = clutter.CairoTexture(2 * MARKER_SIZE, 2 * MARKER_SIZE)
cr_out = bg_out.cairo_create()
cr_out.set_source_rgb(0, 0, 0)
bg_out.set_position(0, 0)
bg_out.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER)
- #The timeline of our animation
+ # The timeline of our animation
self.timeline = clutter.Timeline()
self.timeline.set_duration(1000)
self.timeline.set_loop(True)
self.alpha = clutter.Alpha(self.timeline, clutter.EASE_OUT_SINE)
- #The "growing" behaviour
+ # The "growing" behaviour
self.grow_behaviour = clutter.BehaviourScale(0.5, 0.5, 2.0, 2.0)
self.grow_behaviour.set_alpha(self.alpha)
self.grow_behaviour.apply(bg_out)
- #The fade out behaviour
+ # The fade out behaviour
self.fade_behaviour = clutter.BehaviourOpacity(255, 0)
self.fade_behaviour.set_alpha(self.alpha)
self.fade_behaviour.apply(bg_out)
- #If you want the marked to be animated without calling start_animation
- #Uncomment the following line
+ # If you want the marked to be animated without calling start_animation
+ # Uncomment the following line
#self.timeline.start()
def stop_animation(self) :
def main() :
gobject.threads_init()
clutter.init()
- stage = clutter.stage_get_default()
+ stage = clutter.Stage(default=True)
actor = champlain.View()
layer = champlain.Layer()
marker = AnimatedMarker()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-import cluttergtk
+import cluttergtk # must be the first to be imported
import clutter
import champlain
-import gtk, gobject
-from twisted.internet import gtk2reactor
+import gtk
+import gobject
+from twisted.internet import gtk2reactor
gtk2reactor.install()
from twisted.internet import reactor
import twisted.web.client as httpclient
from BeautifulSoup import BeautifulSoup
-
BASE_URL = "http://en.wikipedia.org"
CAPITALS_URL = "%s/wiki/List_of_national_capitals" % BASE_URL
class Capitals:
-
-
- def __init__(self):
- self.win = gtk.Window()
- self.win.set_title("A Capital Idea")
-
- self.capital_uris = []
- self.markers = []
-
- # Create the map stuff
- self.map = champlain.View()
- self.embed = cluttergtk.Embed()
- self.embed.set_size_request(640, 480)
-
- self.map.set_property("scroll-mode", champlain.SCROLL_MODE_KINETIC)
- self.map.set_property("zoom-level", 3)
-
- self.layer = champlain.Layer()
- self.map.add_layer(self.layer)
-
- self.win.add(self.embed)
- self.win.connect("destroy", lambda w: reactor.stop())
-
- self.embed.realize()
- stage = self.embed.get_stage()
- self.map.set_size(640, 480)
- stage.add(self.map)
-
- self.win.show_all()
- self.map.center_on(0, 0)
-
- # Download the next map after the go-to animation has been completed
- self.map.connect('animation-completed::go-to', lambda w: gobject.timeout_add_seconds(1, self.download_capital))
-
- d = httpclient.getPage(CAPITALS_URL)
- d.addCallback(self.capitals_main_cb)
-
-
- def capitals_main_cb(self, data):
- """
- Called when the main page with all the capitals is downloaded.
- """
-
- soup = BeautifulSoup(data)
- table = soup.find("table", { "class" : "wikitable sortable" })
- for row in table.findAll("tr"):
- cell = row.find("td")
- if cell:
- link = cell.find("a")
- uri = str(link['href'])
- self.capital_uris.append(uri)
-
- self.download_capital()
-
-
- def capital_cb(self, data):
- """
- Called when the page of a capital is downloaded. The page is expected to have
- the coordinates of the capital.
- """
-
- soup = BeautifulSoup(data)
- heading = soup.find("h1", { "id" : "firstHeading" })
- if not heading:
- return
- name = heading.contents[0]
-
- geo = soup.find("span", { "class" : "geo" })
- if not geo:
- return
- latitude, longitude = geo.contents[0].split(";")
- latitude = float(latitude)
- longitude = float(longitude)
-
- # Keep only a few capitals at each iteration we remove a capital
- if len(self.markers) == 5:
- marker = self.markers[0]
- self.layer.remove(marker)
- self.markers.remove(marker)
-
- font = "Sans 15"
- white = clutter.Color(0xff, 0xff, 0xff, 0xff)
- orange = clutter.Color(0xf3, 0x94, 0x07, 0xbb)
- black = clutter.Color(0x00, 0x00, 0x00, 0xff)
-
- if self.markers:
- #Change the colour of the last marker's text
- last = self.markers.pop()
- self.layer.remove(last)
- marker = champlain.marker_new_with_text(last.name, font, black, orange)
- marker.set_position(last.get_property("latitude"), last.get_property("longitude"))
- self.markers.append(marker)
- self.layer.add(marker)
- marker.raise_top()
-
- marker = champlain.marker_new_with_text(name, font, white, orange)
- marker.set_position(latitude, longitude)
- marker.name = name
- self.markers.append(marker)
- self.layer.add(marker)
- marker.raise_top()
- self.map.go_to(latitude, longitude)
-
-
- def download_capital(self):
- if not self.capital_uris:
- # No more capitals to display
- return
- uri = self.capital_uris[0]
- self.capital_uris.remove(uri)
- d = httpclient.getPage(BASE_URL + uri)
- d.addCallback(self.capital_cb)
+ def __init__(self):
+ self.win = gtk.Window()
+ self.win.set_title("A Capital Idea")
+ self.win.connect("destroy", lambda w: reactor.stop())
+
+ self.capital_uris = []
+ self.markers = []
+
+ # Create the map stuff
+ self.map = champlain.View()
+ self.embed = cluttergtk.Embed()
+ self.embed.set_size_request(640, 480)
+
+ self.map.set_property("scroll-mode", champlain.SCROLL_MODE_KINETIC)
+ self.map.set_property("zoom-level", 3)
+
+ self.layer = champlain.Layer()
+ self.map.add_layer(self.layer)
+ self.win.add(self.embed)
+
+ self.embed.realize()
+ stage = self.embed.get_stage()
+ self.map.set_size(640, 480)
+ stage.add(self.map)
+
+ self.win.show_all()
+ self.map.center_on(0, 0)
+
+ # Download the next map after the go-to animation has been completed
+ self.map.connect('animation-completed::go-to', \
+ lambda w: gobject.timeout_add_seconds(1, self.download_capital))
+
+ d = httpclient.getPage(CAPITALS_URL)
+ d.addCallback(self.capitals_main_cb)
+
+ def capitals_main_cb(self, data):
+ """Called when the main page with all the capitals is downloaded."""
+ soup = BeautifulSoup(data)
+ table = soup.find("table", { "class" : "wikitable sortable" })
+ for row in table.findAll("tr"):
+ cell = row.find("td")
+ if cell:
+ link = cell.find("a")
+ uri = str(link['href'])
+ self.capital_uris.append(uri)
+ self.download_capital()
+
+ def capital_cb(self, data):
+ """Called when the page of a capital is downloaded. The page is
+ expected to have the coordinates of the capital."""
+ soup = BeautifulSoup(data)
+ heading = soup.find("h1", { "id" : "firstHeading" })
+ if not heading:
+ return
+ name = heading.contents[0]
+
+ geo = soup.find("span", { "class" : "geo" })
+ if not geo:
+ return
+ latitude, longitude = geo.contents[0].split(";")
+ latitude = float(latitude)
+ longitude = float(longitude)
+
+ # Keep only a few capitals at each iteration we remove a capital
+ if len(self.markers) == 5:
+ marker = self.markers[0]
+ self.layer.remove(marker)
+ self.markers.remove(marker)
+
+ font = "Sans 15"
+ white = clutter.Color(0xff, 0xff, 0xff, 0xff)
+ orange = clutter.Color(0xf3, 0x94, 0x07, 0xbb)
+ black = clutter.Color(0x00, 0x00, 0x00, 0xff)
+
+ if self.markers:
+ #Change the colour of the last marker's text
+ last = self.markers.pop()
+ self.layer.remove(last)
+ marker = champlain.marker_new_with_text(last.name, font, black, orange)
+ marker.set_position(last.get_property("latitude"), \
+ last.get_property("longitude"))
+ self.markers.append(marker)
+ self.layer.add(marker)
+ marker.raise_top()
+
+ marker = champlain.marker_new_with_text(name, font, white, orange)
+ marker.set_position(latitude, longitude)
+ marker.name = name
+ self.markers.append(marker)
+ self.layer.add(marker)
+ marker.raise_top()
+ self.map.go_to(latitude, longitude)
+
+ def download_capital(self):
+ if not self.capital_uris:
+ # No more capitals to display
+ return
+ uri = self.capital_uris[0]
+ self.capital_uris.remove(uri)
+ d = httpclient.getPage(BASE_URL + uri)
+ d.addCallback(self.capital_cb)
if __name__ == "__main__":
- gobject.threads_init()
- clutter.init()
- Capitals()
- reactor.run()
+ gobject.threads_init()
+ clutter.init()
+ Capitals()
+ reactor.run()
+++ /dev/null
-# -*- coding: utf-8 -*-
-import clutter
-import champlain
-
-class DemoMarkerLayer(champlain.Layer):
-
- def __init__(self):
- champlain.Layer.__init__(self)
-
- orange = clutter.Color(0xf3, 0x94, 0x07, 0xbb)
- white = clutter.Color(0xff, 0xff, 0xff, 0xff)
- black = clutter.Color(0x00, 0x00, 0x00, 0xff)
- marker = champlain.marker_new_with_text("Montréal", "Airmole 14", black, orange)
- marker.set_position(45.528178, -73.563788)
- self.add(marker)
-
- marker = champlain.marker_new_with_text("New York", "Sans 25", white, orange);
- marker.set_position(40.77, -73.98);
- self.add(marker)
-
- marker = champlain.marker_new_with_text("Saint-Tite-des-Caps", "Serif 12", black, orange);
- marker.set_position(47.130885, -70.764141);
- self.add(marker)
-
- self.hide()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-import cluttergtk
+import cluttergtk # must be the first to be imported
import clutter
import gobject
import gtk
from markers import create_marker_layer
class LauncherGTK:
+ def __init__(self):
+ self.window = gtk.Window()
+ self.window.set_border_width(10)
+ self.window.set_title("The world seen through the eyes of a Python")
+ self.window.connect("destroy", gtk.main_quit)
+
+ vbox = gtk.VBox(False, 12)
+
+ self.view = champlain.View()
+ self.view.set_property("scroll-mode", champlain.SCROLL_MODE_KINETIC)
+
+ self.layer = create_marker_layer(self.view)
+ self.view.add_layer(self.layer)
+
+ embed = cluttergtk.Embed()
+ embed.set_size_request(640, 480)
+
+ bbox = gtk.HBox(False, 6)
+ button = gtk.Button(stock=gtk.STOCK_ZOOM_IN)
+ button.connect("clicked", self.zoom_in)
+ bbox.add(button)
+
+ button = gtk.Button(stock=gtk.STOCK_ZOOM_OUT)
+ button.connect("clicked", self.zoom_out)
+ bbox.add(button)
+
+ button = gtk.ToggleButton(label="Markers")
+ button.connect("toggled", self.toggle_layer)
+ bbox.add(button)
+
+ combo = gtk.combo_box_new_text()
+ self.map_source_factory = champlain.map_source_factory_dup_default()
+ liststore = gtk.ListStore(str, str)
+ for source in self.map_source_factory.dup_list():
+ liststore.append([source.id, source.name])
+ combo.append_text(source.name)
+ combo.set_model(liststore)
+ combo.set_attributes(combo.get_cells()[0], text=1)
+ combo.set_active(0)
+ combo.connect("changed", self.map_source_changed)
+ bbox.add(combo)
+
+ self.spinbutton = gtk.SpinButton(gtk.Adjustment(lower=0, upper=20,
+ value=1, step_incr=1))
+ self.spinbutton.connect("changed", self.zoom_changed)
+ self.view.connect("notify::zoom-level", self.map_zoom_changed)
+ self.spinbutton.set_value(5)
+ bbox.add(self.spinbutton)
+
+ vbox.pack_start(bbox, expand=False, fill=False)
+ vbox.add(embed)
+
+ self.window.add(vbox)
+ # we need to realize the widget before we get the stage
+ embed.realize()
+
+ stage = embed.get_stage()
+ self.view.set_size(640, 480)
+ stage.add(self.view)
+
+ self.window.show_all()
+ self.view.center_on(45.466, -73.75)
+
+ def zoom_in(self, widget):
+ self.view.zoom_in()
+
+ def zoom_out(self, widget):
+ self.view.zoom_out()
+
+ def toggle_layer(self, widget):
+ if widget.get_active():
+ self.layer.animate_in_all_markers()
+ else:
+ self.layer.animate_out_all_markers()
+
+ def zoom_changed(self, widget):
+ self.view.set_property("zoom-level", self.spinbutton.get_value_as_int())
- def __init__(self):
- self.window = gtk.Window()
- self.window.set_border_width(10)
- self.window.set_title("The world seen through the eyes of a Python")
-
- self.window.connect("destroy", lambda w: gtk.main_quit)
-
- vbox = gtk.VBox(False, 12)
+ def map_source_changed(self, widget):
+ model = widget.get_model()
+ iter = widget.get_active_iter()
+ id = model.get_value(iter, 0)
+ source = self.map_source_factory.create(id);
+ self.view.set_property("map-source", source)
- self.view = champlain.View()
- self.view.set_property("scroll-mode", champlain.SCROLL_MODE_KINETIC)
-
- self.layer = create_marker_layer(self.view)
- self.view.add_layer(self.layer)
-
- embed = cluttergtk.Embed()
- embed.set_size_request(640, 480)
-
- bbox = gtk.HBox(False, 6)
- button = gtk.Button(stock=gtk.STOCK_ZOOM_IN)
- button.connect("clicked", self.zoom_in)
- bbox.add(button)
-
- button = gtk.Button(stock=gtk.STOCK_ZOOM_OUT)
- button.connect("clicked", self.zoom_out)
- bbox.add(button)
-
- button = gtk.ToggleButton(label="Markers")
- button.connect("toggled", self.toggle_layer)
- bbox.add(button)
-
- combo = gtk.combo_box_new_text()
- self.map_source_factory = champlain.map_source_factory_dup_default()
- liststore = gtk.ListStore(str, str)
- for source in self.map_source_factory.dup_list():
- liststore.append([source["id"], source["name"]])
- combo.append_text(source["name"])
- combo.set_model(liststore)
- combo.set_attributes(combo.get_cells()[0], text=1)
- combo.set_active(0)
- combo.connect("changed", self.map_source_changed)
- bbox.add(combo)
-
- self.spinbutton = gtk.SpinButton(gtk.Adjustment(lower=0, upper=20, value=1, step_incr=1))
- self.spinbutton.connect("changed", self.zoom_changed)
- self.view.connect("notify::zoom-level", self.map_zoom_changed)
- self.spinbutton.set_value(5)
- bbox.add(self.spinbutton)
-
- vbox.pack_start(bbox, expand=False, fill=False)
- vbox.add(embed)
-
- self.window.add(vbox)
- # we need to realize the widget before we get the stage
- embed.realize()
-
- stage = embed.get_stage()
- self.view.set_size(640, 480)
- stage.add(self.view)
-
- self.window.show_all()
- self.view.center_on(45.466, -73.75)
-
-
- def zoom_in(self, widget):
- self.view.zoom_in()
-
- def zoom_out(self, widget):
- self.view.zoom_out()
-
- def toggle_layer(self, widget):
- if widget.get_active():
- self.layer.animate_in_all_markers()
- #self.layer.show_all()
- else:
- self.layer.animate_out_all_markers()
- #self.layer.hide()
-
- def zoom_changed(self, widget):
- self.view.set_property("zoom-level", self.spinbutton.get_value_as_int())
-
- def map_source_changed(self, widget):
- model = widget.get_model()
- iter = widget.get_active_iter()
- id = model.get_value(iter, 0)
- source = self.map_source_factory.create(id);
- self.view.set_property("map-source", source)
-
- def map_zoom_changed(self, widget, value):
- self.spinbutton.set_value(self.view.get_property("zoom-level"))
+ def map_zoom_changed(self, widget, value):
+ self.spinbutton.set_value(self.view.get_property("zoom-level"))
if __name__ == "__main__":
- gobject.threads_init()
- clutter.init()
- LauncherGTK()
- gtk.main()
+ gobject.threads_init()
+ LauncherGTK()
+ gtk.main()
return button
def main():
-
# Create the map view
actor = champlain.View()
actor.set_size(640, 480)
layer = create_marker_layer(actor)
actor.add_layer(layer)
- stage = clutter.stage_get_default()
+ stage = clutter.Stage(default=True)
stage.set_size(640, 480)
stage.add(actor)
stage.add(buttons)
actor.set_size(640, 480)
actor.set_property('scroll-mode', champlain.SCROLL_MODE_KINETIC)
actor.set_property('zoom-level', 9)
- actor.center_on(45.466, -73.75)
# Create the buttons
buttons = clutter.Group()
button.connect('button-release-event', zoom_out, actor)
buttons.add(button)
- stage = clutter.stage_get_default()
+ stage = clutter.Stage(default=True)
stage.set_size(640, 480)
stage.add(actor)
stage.add(buttons)
# Connect to the click event
actor.set_reactive(True)
actor.connect('button-release-event', map_view_button_release_cb, actor)
+ actor.center_on(45.466, -73.75)
if __name__ == "__main__":