Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS9
-rw-r--r--activity.py110
-rwxr-xr-xactivity/activity.info2
-rw-r--r--helpers.py36
-rw-r--r--physics.py12
-rwxr-xr-xsetup.py3
-rw-r--r--sugargame/canvas.py74
-rw-r--r--sugargame/event.py110
-rw-r--r--tools.py13
9 files changed, 215 insertions, 154 deletions
diff --git a/NEWS b/NEWS
index ba605f3..b6233c1 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@
ENHANCEMENTS:
* New translations
+* GTK3 conversion by Ignacio Rodriguez
13
@@ -26,3 +27,11 @@ ENHANCEMENTS:
BUG FIXES:
* Removed cjson dependency for elements
* pep8 cleanup (Sai Vineet)
+
+11.9
+
+* Removed cjson dependency for elements
+* Added option to joints to set collideConnected = False
+* Added clear_all (svineet)
+* Added tracking (svineet)
+* Added tracing (svineet)
diff --git a/activity.py b/activity.py
index e181092..d63574e 100644
--- a/activity.py
+++ b/activity.py
@@ -1,10 +1,11 @@
# Physics, a 2D Physics Playground for Kids
-# Copyright (C) 2008 Alex Levenson and Brian Jordan
-# Copyright (C) 2012 Daniel Francis
-# Copyright (C) 2012-13 Walter Bender
-# Copyright (C) 2013 Sai Vineet
-# Copyright (C) 2012-13 Sugar Labs
+# Copyright (C) 2008 Alex Levenson and Brian Jordan
+# Copyright (C) 2012 Daniel Francis
+# Copyright (C) 2012-14 Walter Bender
+# Copyright (C) 2013 Sai Vineet
+# Copyright (C) 2013-14 Ignacio Rodriguez
+# Copyright (C) 2012-13 Sugar Labs
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -20,29 +21,31 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import gtk
import csv
import tempfile
import json
-from gettext import gettext as _
import logging
+from gettext import gettext as _
import pygame
import sugargame
import sugargame.canvas
-from sugar.activity import activity
-from sugar.activity.widgets import ActivityToolbarButton
-from sugar.activity.widgets import StopButton
-from sugar.graphics.radiotoolbutton import RadioToolButton
-from sugar.graphics.toolbutton import ToolButton
-from sugar.graphics.alert import ConfirmationAlert
-from sugar.graphics.toolbarbox import ToolbarBox
-from sugar.graphics.toolbarbox import ToolbarButton
-from sugar.graphics.style import GRID_CELL_SIZE
-from sugar.datastore import datastore
-from sugar.graphics.icon import Icon
-from sugar.graphics import style
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GdkPixbuf
+
+from sugar3.activity import activity
+from sugar3.activity.widgets import ActivityToolbarButton
+from sugar3.activity.widgets import StopButton
+from sugar3.graphics.radiotoolbutton import RadioToolButton
+from sugar3.graphics.toolbutton import ToolButton
+from sugar3.graphics.alert import ConfirmationAlert
+from sugar3.graphics.toolbarbox import ToolbarBox
+from sugar3.graphics.toolbarbox import ToolbarButton
+from sugar3.graphics.style import GRID_CELL_SIZE
+from sugar3.datastore import datastore
+from sugar3.graphics.objectchooser import get_preview_pixbuf
import tools
import physics
@@ -52,8 +55,8 @@ class PhysicsActivity(activity.Activity):
def __init__(self, handle):
super(PhysicsActivity, self).__init__(handle)
self.metadata['mime_type'] = 'application/x-physics-activity'
- self.add_events(gtk.gdk.ALL_EVENTS_MASK |
- gtk.gdk.VISIBILITY_NOTIFY_MASK)
+ self.add_events(Gdk.EventMask.ALL_EVENTS_MASK |
+ Gdk.EventMask.VISIBILITY_NOTIFY_MASK)
self.connect('visibility-notify-event', self._focus_event)
self.connect('window-state-event', self._window_event)
@@ -64,8 +67,8 @@ class PhysicsActivity(activity.Activity):
self.build_toolbar()
self.set_canvas(self._canvas)
- gtk.gdk.screen_get_default().connect('size-changed',
- self.__configure_cb)
+ Gdk.Screen.get_default().connect('size-changed',
+ self.__configure_cb)
logging.debug(os.path.join(
activity.get_activity_root(), 'data', 'data'))
@@ -75,8 +78,8 @@ class PhysicsActivity(activity.Activity):
''' Screen size has changed '''
self.write_file(os.path.join(
activity.get_activity_root(), 'data', 'data'))
- pygame.display.set_mode((gtk.gdk.screen_width(),
- gtk.gdk.screen_height() - 2 * GRID_CELL_SIZE),
+ pygame.display.set_mode((Gdk.Screen.width(),
+ Gdk.Screen.height() - 2 * GRID_CELL_SIZE),
pygame.RESIZABLE)
self.read_file(os.path.join(
activity.get_activity_root(), 'data', 'data'))
@@ -90,18 +93,7 @@ class PhysicsActivity(activity.Activity):
def get_preview(self):
''' Custom preview code to get image from pygame. '''
- if self.preview:
- return self.preview
- surface = pygame.display.get_surface()
- width, height = surface.get_width(), surface.get_height()
- pixbuf = gtk.gdk.pixbuf_new_from_data(pygame.image.tostring(surface,
- 'RGB'),
- gtk.gdk.COLORSPACE_RGB, 0, 8,
- width, height,
- 3 * width)
- pixbuf = pixbuf.scale_simple(300, 225, gtk.gdk.INTERP_BILINEAR)
-
- preview_data = []
+ return self._canvas.get_preview()
def save_func(buf, data):
data.append(buf)
@@ -119,7 +111,7 @@ class PhysicsActivity(activity.Activity):
activity_button.show()
create_toolbar = ToolbarButton()
- create_toolbar.props.page = gtk.Toolbar()
+ create_toolbar.props.page = Gtk.Toolbar()
create_toolbar.props.icon_name = 'magicpen'
create_toolbar.props.label = _('Create')
toolbar_box.toolbar.insert(create_toolbar, -1)
@@ -127,7 +119,7 @@ class PhysicsActivity(activity.Activity):
self._insert_stop_play_button(toolbar_box.toolbar)
- separator = gtk.SeparatorToolItem()
+ separator = Gtk.SeparatorToolItem()
toolbar_box.toolbar.insert(separator, -1)
separator.show()
@@ -142,7 +134,7 @@ class PhysicsActivity(activity.Activity):
self._insert_clear_all_button(toolbar_box.toolbar)
- separator = gtk.SeparatorToolItem()
+ separator = Gtk.SeparatorToolItem()
separator.props.draw = False
separator.set_size_request(0, -1)
separator.set_expand(True)
@@ -153,7 +145,7 @@ class PhysicsActivity(activity.Activity):
toolbar_box.toolbar.insert(stop, -1)
stop.show()
- separator = gtk.SeparatorToolItem()
+ separator = Gtk.SeparatorToolItem()
activity_button.props.page.insert(separator, -1)
separator.show()
@@ -208,14 +200,13 @@ class PhysicsActivity(activity.Activity):
# Make + add the component buttons
self.radioList = {}
firstButton = None
- for c in tools.allTools:
- button = RadioToolButton(named_icon=c.icon)
- if firstButton:
- button.set_group(firstButton)
+ for i, c in enumerate(tools.allTools):
+ if i == 0:
+ button = RadioToolButton(group=None)
+ firstbutton = button
else:
- button.set_group(None)
- firstButton = button
-
+ button = RadioToolButton(group=firstbutton)
+ button.set_icon_name(c.icon)
button.set_tooltip(c.toolTip)
button.set_accelerator(c.toolAccelerator)
button.connect('clicked', self.radioClicked)
@@ -235,18 +226,17 @@ class PhysicsActivity(activity.Activity):
def _build_palette(self, tool):
if tool.palette_enabled:
if tool.palette_mode == tools.PALETTE_MODE_ICONS:
- vbox = gtk.VBox()
+ vbox = Gtk.VBox()
for settings in tool.palette_settings:
- hbox = gtk.HBox()
+ hbox = Gtk.HBox()
firstButton = None
for i in range(0, settings['icon_count']):
- button = RadioToolButton(
- named_icon=settings['icons'][i])
- if firstButton:
- button.set_group(firstButton)
+ if i == 0:
+ button = RadioToolButton(group=None)
+ firstbutton = button
else:
- button.set_group(None)
- firstButton = button
+ button = RadioToolButton(group=firstbutton)
+ button.set_icon_name(settings['icons'][i])
button.connect('clicked',
self._palette_icon_clicked,
tool.name,
@@ -271,7 +261,7 @@ class PhysicsActivity(activity.Activity):
def clear_trace_alert_cb(self, alert, response):
self.remove_alert(alert)
- if response is gtk.RESPONSE_OK:
+ if response is Gtk.ResponseType.OK:
self.game.full_pos_list = [[] for _ in self.game.full_pos_list]
self.game.tracked_bodies = 0
@@ -298,7 +288,7 @@ class PhysicsActivity(activity.Activity):
def clear_all_cb(self, button):
def clear_all_alert_cb(alert, response_id):
self.remove_alert(alert)
- if response_id is gtk.RESPONSE_OK:
+ if response_id is Gtk.ResponseType.OK:
pygame.event.post(pygame.event.Event(pygame.USEREVENT,
action='clear_all'))
if len(self.game.world.world.GetBodyList()) > 2:
@@ -320,7 +310,7 @@ class PhysicsActivity(activity.Activity):
if not self.game.pygame_started:
logging.debug('focus_event: pygame not yet initialized')
return
- if data.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED:
+ if data.state == Gdk.VisibilityState.FULLY_OBSCURED:
pygame.event.post(pygame.event.Event(pygame.USEREVENT,
action='focus_out'))
else:
@@ -366,6 +356,6 @@ class PhysicsActivity(activity.Activity):
def _window_event(self, window, event):
''' Send focus out event to pygame when switching to a desktop
view. '''
- if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
+ if event.changed_mask & Gdk.WindowState.ICONIFIED:
pygame.event.post(pygame.event.Event(pygame.USEREVENT,
action='focus_out'))
diff --git a/activity/activity.info b/activity/activity.info
index 8aa29a2..8e118f3 100755
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -4,6 +4,6 @@ summary = Prove Sir Isaac Newton right! Create real life simulations using diffe
bundle_id = org.laptop.physics
exec = sugar-activity activity.PhysicsActivity
icon = activity-physics
-activity_version = 13
+activity_version = 14
show_launcher = yes
mime_types = application/x-physics-activity;
diff --git a/helpers.py b/helpers.py
index 1d0d2fe..65b07cd 100644
--- a/helpers.py
+++ b/helpers.py
@@ -23,11 +23,13 @@
#==================================================================
import math
+
def distance(pt1, pt2):
"""Distance calculator, pt1 and pt2 are ordred pairs.
"""
return math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
+
def getAngle(pt1, pt2):
"""Returns angle between line segment pt1 -> pt2 and x axis, from -pi to pi.
"""
@@ -35,14 +37,18 @@ def getAngle(pt1, pt2):
ycomp = pt1[1] - pt2[1]
return math.atan2(ycomp, xcomp)
+
def constructTriangleFromLine(p1, p2):
- """Returns list of ordered pairs describing equilteral triangle around segment pt1 --> pt2.
+ """
+ Returns list of ordered pairs describing equilteral triangle around
+ segment pt1 --> pt2.
"""
halfHeightVector = (0.57735 * (p2[1] - p1[1]), 0.57735 * (p2[0] - p1[0]))
p3 = (p1[0] + halfHeightVector[0], p1[1] - halfHeightVector[1])
p4 = (p1[0] - halfHeightVector[0], p1[1] + halfHeightVector[1])
return [p2, p3, p4]
+
def polyArea(vertices):
"""Returns the area of a polygon.
"""
@@ -56,10 +62,10 @@ def polyArea(vertices):
q += 1
return A / 2.0
-
+
def insideTriangle(pt, triangle):
"""Returns true if pt is in triangle.
-
+
Some polygon magic, thanks to John W. Ratcliff on www.flipcode.com
"""
ax = triangle[2][0] - triangle[1][0]
@@ -77,9 +83,10 @@ def insideTriangle(pt, triangle):
aCROSSbp = ax * bpy - ay * bpx
cCROSSap = cx * apy - cy * apx
- bCROSScp = bx * cpy - by * cpx
+ bCROSScp = bx * cpy - by * cpx
return aCROSSbp >= 0.0 and bCROSScp >= 0.0 and cCROSSap >= 0.0
+
def polySnip(vertices, u, v, w, n):
EPSILON = 0.0000000001
@@ -92,7 +99,7 @@ def polySnip(vertices, u, v, w, n):
Cx = vertices[w][0]
Cy = vertices[w][1]
- if EPSILON > (((Bx-Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax))):
+ if EPSILON > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax))):
return False
for p in range(0, n):
@@ -112,7 +119,8 @@ def decomposePoly(vertices):
vertices = list(vertices)
n = len(vertices)
result = []
- if(n < 3): return [] # not a poly!
+ if(n < 3):
+ return [] # not a poly!
# Force counter-clockwise polygon
if 0 >= polyArea(vertices):
@@ -120,20 +128,23 @@ def decomposePoly(vertices):
# Remove nv-2 vertices, creating 1 triangle every time
nv = n
- count = 2 * nv # error detection
+ count = 2 * nv # error detection
v = nv - 1
while nv > 2:
count -= 1
if 0 >= count:
- return [] # Error -- probably bad polygon
+ return [] # Error -- probably bad polygon
# Three consecutive vertices
- u = v
- if nv <= u: u = 0 # previous
+ u = v
+ if nv <= u:
+ u = 0 # previous
v = u + 1
- if nv <= v: v = 0 # new v
+ if nv <= v:
+ v = 0 # new v
w = v + 1
- if nv <= w: w = 0 # next
+ if nv <= w:
+ w = 0 # next
if(polySnip(vertices, u, v, w, nv)):
@@ -147,6 +158,7 @@ def decomposePoly(vertices):
count = 2 * nv
return result
+
def tuple_to_int(tuple_input):
"""Cast tuple values to ints to avoid gtk+ and pygame's dislike of floats.
"""
diff --git a/physics.py b/physics.py
index c44f5ea..19b0688 100644
--- a/physics.py
+++ b/physics.py
@@ -27,7 +27,9 @@
import os
import sys
-import gtk
+
+from gi.repository import Gtk
+from gi.repository import Gdk
import pygame
from pygame.locals import *
@@ -105,8 +107,8 @@ class PhysicsGame:
self.switch_on_fake_pygame_cursor_cb)
self.canvas.connect('leave_notify_event',
self.switch_off_fake_pygame_cursor_cb)
- self.canvas.add_events(gtk.gdk.ENTER_NOTIFY_MASK
- | gtk.gdk.LEAVE_NOTIFY_MASK)
+ self.canvas.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK
+ | Gdk.EventMask.LEAVE_NOTIFY_MASK)
self.world = elements.Elements(self.screen.get_size())
self.world.renderer.set_surface(self.screen)
@@ -126,8 +128,8 @@ class PhysicsGame:
self.world.additional_vars['tracked_bodies']
while self.loop:
- while gtk.events_pending():
- gtk.main_iteration()
+ while Gtk.events_pending():
+ Gtk.main_iteration()
if not self.loop:
pygame.quit()
diff --git a/setup.py b/setup.py
index 6ed89aa..9a141b3 100755
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,3 @@
#!/usr/bin/env python
-from sugar.activity import bundlebuilder
+from sugar3.activity import bundlebuilder
bundlebuilder.start()
-
diff --git a/sugargame/canvas.py b/sugargame/canvas.py
index 980cb73..3976d5c 100644
--- a/sugargame/canvas.py
+++ b/sugargame/canvas.py
@@ -1,18 +1,19 @@
import os
-import gtk
-import gobject
+from gi.repository import Gtk
+from gi.repository import GObject
+from sugar3.activity.activity import PREVIEW_SIZE
import pygame
import event
CANVAS = None
-class PygameCanvas(gtk.EventBox):
-
+class PygameCanvas(Gtk.EventBox):
+
"""
mainwindow is the activity intself.
"""
def __init__(self, mainwindow, pointer_hint = True):
- gtk.EventBox.__init__(self)
+ GObject.GObject.__init__(self)
global CANVAS
assert CANVAS == None, "Only one PygameCanvas can be created, ever."
@@ -20,42 +21,77 @@ class PygameCanvas(gtk.EventBox):
# Initialize Events translator before widget gets "realized".
self.translator = event.Translator(mainwindow, self)
-
+
self._mainwindow = mainwindow
- self.set_flags(gtk.CAN_FOCUS)
-
- self._socket = gtk.Socket()
+ self.set_can_focus(True)
+
+ self._socket = Gtk.Socket()
self.add(self._socket)
+
+ self._initialized = False
+
self.show_all()
+ def get_preview(self):
+ """
+ Return preview of main surface
+ How to use in activity:
+ def get_preview(self):
+ return self.game_canvas.get_preview()
+ """
+
+ _tmp_dir = os.path.join(self._mainwindow.get_activity_root(),
+ 'tmp')
+ _file_path = os.path.join(_tmp_dir, 'preview.png')
+
+ width = PREVIEW_SIZE[0]
+ height = PREVIEW_SIZE[1]
+ _surface = pygame.transform.scale(self._screen, (width, height))
+ pygame.image.save(_surface, _file_path)
+
+ f = open(_file_path, 'r')
+ preview = f.read()
+ f.close()
+ os.remove(_file_path)
+
+ return preview
+
def run_pygame(self, main_fn):
- # Run the main loop after a short delay. The reason for the delay is that the
- # Sugar activity is not properly created until after its constructor returns.
- # If the Pygame main loop is called from the activity constructor, the
+ # Run the main loop after a short delay. The reason for the
+ # delay is that the Sugar activity is not properly created
+ # until after its constructor returns. If the Pygame main
+ # loop is called from the activity constructor, the
# constructor never returns and the activity freezes.
- gobject.idle_add(self._run_pygame_cb, main_fn)
+ GObject.idle_add(self._run_pygame_cb, main_fn)
def _run_pygame_cb(self, main_fn):
- assert pygame.display.get_surface() is None, "PygameCanvas.run_pygame can only be called once."
-
+ # PygameCanvas.run_pygame can only be called once
+ if self._initialized:
+ return
+
# Preinitialize Pygame with the X window ID.
- assert pygame.display.get_init() == False, "Pygame must not be initialized before calling PygameCanvas.run_pygame."
os.environ['SDL_WINDOWID'] = str(self._socket.get_id())
+ if pygame.display.get_surface() is not None:
+ pygame.display.quit()
pygame.init()
-
+
# Restore the default cursor.
- self._socket.window.set_cursor(None)
+ self._socket.props.window.set_cursor(None)
# Initialize the Pygame window.
r = self.get_allocation()
- pygame.display.set_mode((r.width, r.height), pygame.RESIZABLE)
+ # pygame.display.set_mode((r.width, r.height), pygame.RESIZABLE)
+ self._screen = pygame.display.set_mode((r.width, r.height),
+ pygame.RESIZABLE)
# Hook certain Pygame functions with GTK equivalents.
self.translator.hook_pygame()
# Run the Pygame main loop.
main_fn()
+
+ self._initialized = True
return False
def get_pygame_widget(self):
diff --git a/sugargame/event.py b/sugargame/event.py
index 2ee2bed..f6a69b9 100644
--- a/sugargame/event.py
+++ b/sugargame/event.py
@@ -1,8 +1,8 @@
-import gtk
-import gobject
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GObject
import pygame
import pygame.event
-import logging
class _MockEvent(object):
def __init__(self, keyval):
@@ -28,7 +28,7 @@ class Translator(object):
'KP_Right' : pygame.K_KP6,
}
-
+
mod_map = {
pygame.K_LALT: pygame.KMOD_LALT,
pygame.K_RALT: pygame.KMOD_RALT,
@@ -37,7 +37,7 @@ class Translator(object):
pygame.K_LSHIFT: pygame.KMOD_LSHIFT,
pygame.K_RSHIFT: pygame.KMOD_RSHIFT,
}
-
+
def __init__(self, mainwindow, inner_evb):
"""Initialise the Translator with the windows to which to listen"""
self._mainwindow = mainwindow
@@ -46,31 +46,34 @@ class Translator(object):
# Enable events
# (add instead of set here because the main window is already realized)
self._mainwindow.add_events(
- gtk.gdk.KEY_PRESS_MASK | \
- gtk.gdk.KEY_RELEASE_MASK \
+ Gdk.EventMask.KEY_PRESS_MASK | \
+ Gdk.EventMask.KEY_RELEASE_MASK | \
+ Gdk.EventMask.VISIBILITY_NOTIFY_MASK
)
-
+
self._inner_evb.set_events(
- gtk.gdk.POINTER_MOTION_MASK | \
- gtk.gdk.POINTER_MOTION_HINT_MASK | \
- gtk.gdk.BUTTON_MOTION_MASK | \
- gtk.gdk.BUTTON_PRESS_MASK | \
- gtk.gdk.BUTTON_RELEASE_MASK
+ Gdk.EventMask.POINTER_MOTION_MASK | \
+ Gdk.EventMask.POINTER_MOTION_HINT_MASK | \
+ Gdk.EventMask.BUTTON_MOTION_MASK | \
+ Gdk.EventMask.BUTTON_PRESS_MASK | \
+ Gdk.EventMask.BUTTON_RELEASE_MASK
)
- self._mainwindow.set_flags(gtk.CAN_FOCUS)
- self._inner_evb.set_flags(gtk.CAN_FOCUS)
-
+ self._mainwindow.set_can_focus(True)
+ self._inner_evb.set_can_focus(True)
+
# Callback functions to link the event systems
self._mainwindow.connect('unrealize', self._quit_cb)
+ self._mainwindow.connect('visibility_notify_event', self._visibility_cb)
self._inner_evb.connect('key_press_event', self._keydown_cb)
self._inner_evb.connect('key_release_event', self._keyup_cb)
self._inner_evb.connect('button_press_event', self._mousedown_cb)
self._inner_evb.connect('button_release_event', self._mouseup_cb)
self._inner_evb.connect('motion-notify-event', self._mousemove_cb)
- self._inner_evb.connect('expose-event', self._expose_cb)
+ self._inner_evb.connect('draw', self._draw_cb)
self._inner_evb.connect('configure-event', self._resize_cb)
-
+ self._inner_evb.connect('screen-changed', self._screen_changed_cb)
+
# Internal data
self.__stopped = False
self.__keystate = [0] * 323
@@ -87,8 +90,11 @@ class Translator(object):
pygame.key.set_repeat = self._set_repeat
pygame.mouse.get_pressed = self._get_mouse_pressed
pygame.mouse.get_pos = self._get_mouse_pos
-
- def _expose_cb(self, event, widget):
+
+ def update_display(self):
+ pygame.event.post(pygame.event.Event(pygame.VIDEOEXPOSE))
+
+ def _draw_cb(self, widget, event):
if pygame.display.get_init():
pygame.event.post(pygame.event.Event(pygame.VIDEOEXPOSE))
return True
@@ -99,12 +105,18 @@ class Translator(object):
pygame.event.post(evt)
return False # continue processing
+ def _screen_changed_cb(self, widget, previous_screen):
+ if pygame.display.get_init():
+ self.update_display()
+
def _quit_cb(self, data=None):
self.__stopped = True
- try:
- pygame.event.post(pygame.event.Event(pygame.QUIT))
- except pygame.error, e:
- logging.error('pygame already stopped? %s' % (e))
+ pygame.event.post(pygame.event.Event(pygame.QUIT))
+
+ def _visibility_cb(self, widget, event):
+ if pygame.display.get_init():
+ self.update_display()
+ return False
def _keydown_cb(self, widget, event):
key = event.keyval
@@ -115,9 +127,9 @@ class Translator(object):
self.__held_last_time[key] = pygame.time.get_ticks()
self.__held_time_left[key] = self.__repeat[0]
self.__held.add(key)
-
+
return self._keyevent(widget, event, pygame.KEYDOWN)
-
+
def _keyup_cb(self, widget, event):
key = event.keyval
if self.__repeat[0] is not None:
@@ -128,19 +140,19 @@ class Translator(object):
self.__held.discard(key)
return self._keyevent(widget, event, pygame.KEYUP)
-
+
def _keymods(self):
mod = 0
for key_val, mod_val in self.mod_map.iteritems():
mod |= self.__keystate[key_val] and mod_val
return mod
-
+
def _keyevent(self, widget, event, type):
- key = gtk.gdk.keyval_name(event.keyval)
+ key = Gdk.keyval_name(event.keyval)
if key is None:
# No idea what this key is.
return False
-
+
keycode = None
if key in self.key_trans:
keycode = self.key_trans[key]
@@ -153,19 +165,19 @@ class Translator(object):
self._mainwindow.view_source()
else:
print 'Key %s unrecognized' % key
-
+
if keycode is not None:
if type == pygame.KEYDOWN:
mod = self._keymods()
self.__keystate[keycode] = type == pygame.KEYDOWN
if type == pygame.KEYUP:
mod = self._keymods()
- ukey = unichr(gtk.gdk.keyval_to_unicode(event.keyval))
+ ukey = unichr(Gdk.keyval_to_unicode(event.keyval))
if ukey == '\000':
ukey = ''
evt = pygame.event.Event(type, key=keycode, unicode=ukey, mod=mod)
self._post(evt)
-
+
return True
def _get_pressed(self):
@@ -181,57 +193,57 @@ class Translator(object):
def _mouseup_cb(self, widget, event):
self.__button_state[event.button-1] = 0
return self._mouseevent(widget, event, pygame.MOUSEBUTTONUP)
-
+
def _mouseevent(self, widget, event, type):
evt = pygame.event.Event(type, button=event.button, pos=(event.x, event.y))
self._post(evt)
return True
-
+
def _mousemove_cb(self, widget, event):
# From http://www.learningpython.com/2006/07/25/writing-a-custom-widget-using-pygtk/
# if this is a hint, then let's get all the necessary
# information, if not it's all we need.
if event.is_hint:
- x, y, state = event.window.get_pointer()
+ win, x, y, state = event.window.get_device_position(event.device)
else:
x = event.x
y = event.y
- state = event.state
+ state = event.get_state()
rel = (x - self.__mouse_pos[0], y - self.__mouse_pos[1])
self.__mouse_pos = (x, y)
-
+
self.__button_state = [
- state & gtk.gdk.BUTTON1_MASK and 1 or 0,
- state & gtk.gdk.BUTTON2_MASK and 1 or 0,
- state & gtk.gdk.BUTTON3_MASK and 1 or 0,
+ state & Gdk.ModifierType.BUTTON1_MASK and 1 or 0,
+ state & Gdk.ModifierType.BUTTON2_MASK and 1 or 0,
+ state & Gdk.ModifierType.BUTTON3_MASK and 1 or 0,
]
-
+
evt = pygame.event.Event(pygame.MOUSEMOTION,
pos=self.__mouse_pos, rel=rel, buttons=self.__button_state)
self._post(evt)
return True
-
+
def _tick_cb(self):
cur_time = pygame.time.get_ticks()
for key in self.__held:
delta = cur_time - self.__held_last_time[key]
self.__held_last_time[key] = cur_time
-
+
self.__held_time_left[key] -= delta
if self.__held_time_left[key] <= 0:
self.__held_time_left[key] = self.__repeat[1]
self._keyevent(None, _MockEvent(key), pygame.KEYDOWN)
-
+
return True
-
+
def _set_repeat(self, delay=None, interval=None):
if delay is not None and self.__repeat[0] is None:
- self.__tick_id = gobject.timeout_add(10, self._tick_cb)
+ self.__tick_id = GObject.timeout_add(10, self._tick_cb)
elif delay is None and self.__repeat[0] is not None:
- gobject.source_remove(self.__tick_id)
+ GObject.source_remove(self.__tick_id)
self.__repeat = (delay, interval)
-
+
def _get_mouse_pos(self):
return self.__mouse_pos
diff --git a/tools.py b/tools.py
index 69f9c3b..1d0211f 100644
--- a/tools.py
+++ b/tools.py
@@ -21,16 +21,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-from shutil import copy
-import pygame
import json
+import math
import logging
+import pygame
+from shutil import copy
+from gettext import gettext as _
+
from pygame.locals import *
from helpers import *
-from gettext import gettext as _
-from sugar.activity import activity
-import gtk
-import math
+
+from sugar3.activity import activity
PALETTE_MODE_SLIDER_ICON = 0
PALETTE_MODE_ICONS = 1