From 0d17137aaff76290b0f497bf10885620454f0a5a Mon Sep 17 00:00:00 2001 From: Sai Vineet Date: Wed, 04 Dec 2013 15:58:45 +0000 Subject: Export body positions in Physics Enhancement: Physics should let the user export the body positions for use in another activity like Chart, etc. --- diff --git a/activity.py b/activity.py index 9994dea..eef0e36 100644 --- a/activity.py +++ b/activity.py @@ -22,6 +22,8 @@ import os import gtk from gettext import gettext as _ import logging +import csv +import tempfile import pygame import sugargame @@ -36,6 +38,7 @@ 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 import tools import physics @@ -120,6 +123,12 @@ class PhysicsActivity(activity.Activity): self._insert_stop_play_button(toolbar_box.toolbar) + export_csv = ToolButton("document-save") + export_csv.set_tooltip(_("Export tracked objects to journal")) + export_csv.connect('clicked', self._export_csv_cb) + toolbar_box.toolbar.insert(export_csv, -1) + export_csv.show() + separator = gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) separator.show() @@ -203,8 +212,9 @@ class PhysicsActivity(activity.Activity): def clear_all_cb(self, button): clear_all_alert = ConfirmationAlert() - clear_all_alert.props.title=_('Are You Sure?') - clear_all_alert.props.msg = _('All you work will be discarded. This cannot be undone!') + clear_all_alert.props.title = _('Are You Sure?') + clear_all_alert.props.msg = \ + _('All you work will be discarded. This cannot be undone!') clear_all_alert.connect('response', self.clear_all_alert_cb) self.add_alert(clear_all_alert) @@ -216,6 +226,23 @@ class PhysicsActivity(activity.Activity): else: pass + def _export_csv_cb(self, button): + jobject = datastore.create() + jobject.metadata['title'] = _("Physics export") + jobject.metadata['mime_type'] = "text/csv" + + tmp_dir = os.path.join(self.get_activity_root(), 'instance') + fd, file_path = tempfile.mkstemp(dir=tmp_dir) + os.close(fd) + + data = self.game.full_pos_list + csvfile = open(file_path, "wb") + writer = csv.writer(csvfile) + writer.writerows(data) + jobject.set_file_path(os.path.abspath(csvfile.name)) + csvfile.close() + datastore.write(jobject) + def radioClicked(self, button): pygame.event.post(pygame.event.Event(pygame.USEREVENT, action=self.radioList[button])) diff --git a/icons/track.svg b/icons/track.svg new file mode 100644 index 0000000..16b2afc --- /dev/null +++ b/icons/track.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/physics.py b/physics.py index 253ff1b..64e4ae1 100644 --- a/physics.py +++ b/physics.py @@ -66,6 +66,9 @@ class PhysicsGame: self.loop = True self.pygame_started = False + self.full_pos_list = [] + self.tracked_bodies = [] + def switch_off_fake_pygame_cursor_cb(self, panel, event): self.show_fake_cursor = False @@ -131,6 +134,24 @@ class PhysicsGame: if self.world.run_physics: for body in self.world.world.GetBodyList(): if type(body.userData) == type({}): + if body.userData.has_key('track_index'): + trackdex = body.userData['track_index'] + + def round_to_3(n): + return math.ceil(n * 1000) / 1000.0 + + roundx = round_to_3(body.position.x) + roundy = round_to_3(body.position.y) + tupled_pos = (roundx, roundy) + posx = tupled_pos[0] + posy = tupled_pos[1] + try: + self.full_pos_list[trackdex].append(posx) + self.full_pos_list[trackdex].append(posy) + except: + self.full_pos_list.append([posx, posy]) + + if type(body.userData) == type({}): if body.userData.has_key('rollMotor'): diff = body.userData['rollMotor'] \ ['targetVelocity'] \ diff --git a/tools.py b/tools.py index 62aba05..d1af693 100644 --- a/tools.py +++ b/tools.py @@ -595,6 +595,36 @@ class DestroyTool(Tool): self.vertices = None +# Track tool +class TrackTool(Tool): + name = 'Track' + icon = 'track' + toolTip = _('Track Object') + toolAccelerator = _("r") + + def __init__(self, game): + Tool.__init__(self, game) + self.radius = 1 + + def handleToolEvent(self, event): + Tool.handleToolEvent(self, event) + + if pygame.mouse.get_pressed()[0]: + current_body = self.game.world.get_bodies_at_pos( + tuple_to_int(event.pos))[0] + if current_body: + point_pos = tuple_to_int(event.pos) + track_circle = self.game.world.add.ball(point_pos, self.radius, + dynamic=True, density=0.001, + restitution=0.16, friction=0.1) + track_circle.userData['track_index'] = len( + self.game.tracked_bodies) + + self.game.world.add.joint( + track_circle, current_body, point_pos, point_pos) + self.game.tracked_bodies.append(track_circle) + + def getAllTools(): return [MagicPenTool, CircleTool, @@ -605,6 +635,7 @@ def getAllTools(): MotorTool, PinTool, JointTool, + TrackTool, DestroyTool] allTools = getAllTools() -- cgit v0.9.1