-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix "non responsive buttons" issue on the XO (#44)
Gtk+ events were not being handled in the application event loop, so we add a callback to check for and handle the events. Also ported to Sugargame v1.2 which solves some other problems. Tested on OLPC XO-4 with OLPC OS 13.2.9.
- Loading branch information
Showing
5 changed files
with
170 additions
and
136 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
__version__ = '1.1' | ||
__version__ = '1.2' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,86 @@ | ||
import os | ||
from gi.repository import Gtk | ||
from gi.repository import GObject | ||
from gi.repository import GLib | ||
from sugar3.activity.activity import PREVIEW_SIZE | ||
import pygame | ||
import event | ||
|
||
CANVAS = None | ||
|
||
|
||
class PygameCanvas(Gtk.EventBox): | ||
|
||
''' | ||
mainwindow is the activity intself. | ||
''' | ||
def __init__(self, mainwindow, pointer_hint = True): | ||
def __init__(self, activity, pointer_hint=True, | ||
main=None, modules=[pygame]): | ||
GObject.GObject.__init__(self) | ||
|
||
global CANVAS | ||
assert CANVAS == None, "Only one PygameCanvas can be created, ever." | ||
CANVAS = self | ||
|
||
# Initialize Events translator before widget gets "realized". | ||
self.translator = event.Translator(mainwindow, self) | ||
|
||
self._mainwindow = mainwindow | ||
self.translator = event.Translator(activity, self) | ||
|
||
self._activity = activity | ||
self._main = main | ||
self._modules = modules | ||
|
||
self.set_can_focus(True) | ||
|
||
self._socket = Gtk.Socket() | ||
self._socket.connect('realize', self._realize_cb) | ||
self.add(self._socket) | ||
|
||
self.show_all() | ||
|
||
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 | ||
# constructor never returns and the activity freezes. | ||
GObject.idle_add(self._run_pygame_cb, main_fn) | ||
def _realize_cb(self, widget): | ||
|
||
def _run_pygame_cb(self, main_fn): | ||
assert pygame.display.get_surface() is None, "PygameCanvas.run_pygame can only be called once." | ||
|
||
# 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()) | ||
pygame.init() | ||
os.environ['SDL_WINDOWID'] = str(widget.get_id()) | ||
for module in self._modules: | ||
module.init() | ||
|
||
# Restore the default cursor. | ||
self._socket.props.window.set_cursor(None) | ||
widget.props.window.set_cursor(None) | ||
|
||
# Initialize the Pygame window. | ||
# Confine the Pygame surface to the canvas size | ||
r = self.get_allocation() | ||
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() | ||
return False | ||
# Call the caller's main loop as an idle source | ||
if self._main: | ||
GLib.idle_add(self._main) | ||
|
||
def get_pygame_widget(self): | ||
return self._socket | ||
|
||
def get_preview(self): | ||
""" | ||
Return preview of main surface | ||
How to use in activity: | ||
def get_preview(self): | ||
return self.game_canvas.get_preview() | ||
""" | ||
|
||
if not hasattr(self, '_screen'): | ||
return None | ||
|
||
_tmp_dir = os.path.join(self._activity.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 |
Oops, something went wrong.