Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tutorius/viewer.py
diff options
context:
space:
mode:
authorSimon Poirier <simpoir@gmail.com>2009-11-15 22:18:25 (GMT)
committer Simon Poirier <simpoir@gmail.com>2009-11-15 23:18:00 (GMT)
commit857aff7e1c1694a819c0dbc9b9103ef2206699e6 (patch)
tree49eef0c445efe1b98e6c22eccee6e09724d7994f /tutorius/viewer.py
parent05c177246d5b7a548395b2bb36faa90559c71943 (diff)
creator adt migration
Diffstat (limited to 'tutorius/viewer.py')
-rw-r--r--tutorius/viewer.py119
1 files changed, 61 insertions, 58 deletions
diff --git a/tutorius/viewer.py b/tutorius/viewer.py
index 272558e..56428e1 100644
--- a/tutorius/viewer.py
+++ b/tutorius/viewer.py
@@ -18,9 +18,7 @@ This module renders a widget containing a graphical representation
of a tutorial and acts as a creator proxy as it has some editing
functionality.
"""
-import sys
-
-import gtk, gtk.gdk
+import gtk
import cairo
from math import pi as PI
PI2 = PI/2
@@ -30,7 +28,6 @@ import rsvg
from sugar.bundle import activitybundle
from sugar.tutorius import addon
from sugar.graphics import icon
-from sugar.tutorius.filters import EventFilter
from sugar.tutorius.actions import Action
import os
@@ -66,7 +63,7 @@ class Viewer(object):
self.alloc = None
self.click_pos = None
self.drag_pos = None
- self.selection = []
+ self.selection = set()
self.win = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.win.set_size_request(400, 200)
@@ -81,7 +78,7 @@ class Viewer(object):
canvas = gtk.DrawingArea()
vbox.add_with_viewport(canvas)
canvas.set_app_paintable(True)
- canvas.connect_after("expose-event", self.on_viewer_expose, tutorial._states)
+ canvas.connect_after("expose-event", self.on_viewer_expose, tutorial)
canvas.add_events(gtk.gdk.BUTTON_PRESS_MASK \
|gtk.gdk.BUTTON_MOTION_MASK \
|gtk.gdk.BUTTON_RELEASE_MASK \
@@ -99,10 +96,13 @@ class Viewer(object):
canvas.set_size_request(2048, 180) # FIXME
def destroy(self):
+ """
+ Destroy ui resources associated with this object.
+ """
self.win.destroy()
- def _paint_state(self, ctx, states):
+ def _paint_state(self, ctx, tutorial):
"""
Paints a tutorius fsm state in a cairo context.
Final context state will be shifted by the size of the graphics.
@@ -111,17 +111,13 @@ class Viewer(object):
block_max_height = self.alloc.height
new_insert_point = None
- cur_state = 'INIT'
+ state_name = tutorial.INIT
# FIXME: get app when we have a model that supports it
cur_app = 'Calculate'
app_start = ctx.get_matrix()
- try:
- state = states[cur_state]
- except KeyError:
- state = None
- while state:
+ while state_name:
new_app = 'Calculate'
if new_app != cur_app:
ctx.save()
@@ -132,16 +128,17 @@ class Viewer(object):
ctx.translate(BLOCK_PADDING, 0)
cur_app = new_app
- action_list = state.get_action_list()
+ action_list = tutorial.get_action_dict(state_name).items()
if action_list:
- local_height = (block_max_height - BLOCK_PADDING)/len(action_list) - BLOCK_PADDING
+ local_height = (block_max_height - BLOCK_PADDING)\
+ / len(action_list) - BLOCK_PADDING
ctx.save()
- for action in action_list:
+ for action_name, action in action_list:
origin = tuple(ctx.get_matrix())[-2:]
if self.click_pos and \
self.click_pos[0]-BLOCK_WIDTH<origin[0] and \
self.drag_pos[0]>origin[0]:
- self.selection.append(action)
+ self.selection.add((action_name, action))
self.render_action(ctx, block_width, local_height, action)
ctx.translate(0, local_height+BLOCK_PADDING)
@@ -150,7 +147,7 @@ class Viewer(object):
# insertion cursor painting made from two opposed triangles
# joined by a line.
- if state.name == self._creator.get_insertion_point():
+ if state_name == self._creator.get_insertion_point():
ctx.save()
bp2 = BLOCK_PADDING/2
ctx.move_to(-bp2, 0)
@@ -170,36 +167,34 @@ class Viewer(object):
ctx.restore()
- event_list = state.get_event_filter_list()
+ event_list = tutorial.get_transition_dict(state_name).items()
if event_list:
- local_height = (block_max_height - BLOCK_PADDING)/len(event_list) - BLOCK_PADDING
+ local_height = (block_max_height - BLOCK_PADDING)\
+ /len(event_list) - BLOCK_PADDING
ctx.save()
- for event, next_state in event_list:
+ for transition_name, transition in event_list:
origin = tuple(ctx.get_matrix())[-2:]
if self.click_pos and \
self.click_pos[0]-BLOCK_WIDTH<origin[0] and \
self.drag_pos[0]>origin[0]:
- self.selection.append(event)
- self.render_event(ctx, block_width, local_height, event)
+ self.selection.add((transition_name, transition))
+ self.render_event(ctx, block_width, local_height,
+ event=transition[0])
ctx.translate(0, local_height+BLOCK_PADDING)
ctx.restore()
ctx.translate(BLOCK_WIDTH, 0)
- # FIXME point to next state in state, as it would highlight
- # the "happy path".
- cur_state = event_list[0][1]
-
if (not new_insert_point) and self.click_pos:
origin = tuple(ctx.get_matrix())[-2:]
if self.click_pos[0]<origin[0]:
- new_insert_point = state
+ new_insert_point = state_name
- if event_list:
- try:
- state = states[cur_state]
- except KeyError:
- break
+ if event_list and state_name != tutorial.END:
+ # TODO: use marked path, to avoid infinite loops on recursive
+ # tutorials.
+ next_states = tutorial.get_following_states_dict(state_name)
+ state_name = next_states.keys()[0]
yield True
else:
break
@@ -209,9 +204,9 @@ class Viewer(object):
if self.click_pos:
if not new_insert_point:
- new_insert_point = state
+ new_insert_point = state_name
- self._creator.set_insertion_point(new_insert_point.name)
+ self._creator.set_insertion_point(new_insert_point)
yield False
@@ -235,7 +230,7 @@ class Viewer(object):
def _render_app_hints(self, ctx, appname):
"""
- Fetches the icon of the app related to current states and renders it on a
+ Fetches the icon of the app related to current state and renders it on a
separator, between states.
"""
ctx.set_source_rgb(0.0, 0.0, 0.0)
@@ -248,11 +243,11 @@ class Viewer(object):
bundle_path = os.getenv("SUGAR_BUNDLE_PATH")
if bundle_path:
icon_path = activitybundle.ActivityBundle(bundle_path).get_icon()
- icon = rsvg.Handle(icon_path)
+ icon_rsvg = rsvg.Handle(icon_path)
ctx.save()
ctx.translate(-15, 0)
ctx.scale(0.5, 0.5)
- icon_surf = icon.render_cairo(ctx)
+ icon_rsvg.render_cairo(ctx)
ctx.restore()
@@ -278,9 +273,12 @@ class Viewer(object):
ctx.move_to(BLOCK_CORNERS, 0)
paint_border(inner_width, 0)
- ctx.arc(inner_width+BLOCK_CORNERS, BLOCK_CORNERS, BLOCK_CORNERS, -PI2, 0.0)
- ctx.arc(inner_width+BLOCK_CORNERS, inner_height+BLOCK_CORNERS, BLOCK_CORNERS, 0.0, PI2)
- ctx.arc(BLOCK_CORNERS, inner_height+BLOCK_CORNERS, BLOCK_CORNERS, PI2, PI)
+ ctx.arc(inner_width+BLOCK_CORNERS, BLOCK_CORNERS,
+ BLOCK_CORNERS, -PI2, 0.0)
+ ctx.arc(inner_width+BLOCK_CORNERS, inner_height+BLOCK_CORNERS,
+ BLOCK_CORNERS, 0.0, PI2)
+ ctx.arc(BLOCK_CORNERS, inner_height+BLOCK_CORNERS, BLOCK_CORNERS,
+ PI2, PI)
ctx.arc(BLOCK_CORNERS, BLOCK_CORNERS, BLOCK_CORNERS, -PI, -PI2)
ctx.set_source(tracing)
@@ -295,7 +293,7 @@ class Viewer(object):
ctx.save()
ctx.translate(BLOCK_INNER_PAD, BLOCK_INNER_PAD)
ctx.scale(0.5, 0.5)
- icon_surf = rsvg_icon.render_cairo(ctx)
+ rsvg_icon.render_cairo(ctx)
ctx.restore()
@@ -340,29 +338,30 @@ class Viewer(object):
addon_name = addon.get_name_from_type(type(event))
# TODO use icon pool
- icon_name = addon.get_addon_meta(addon_name)['icon']
- rsvg_icon = rsvg.Handle(icon.get_icon_file_name(icon_name))
- ctx.save()
- ctx.translate(BLOCK_INNER_PAD, BLOCK_INNER_PAD)
- ctx.scale(0.5, 0.5)
- icon_surf = rsvg_icon.render_cairo(ctx)
+ if addon_name:
+ icon_name = addon.get_addon_meta(addon_name)['icon']
+ rsvg_icon = rsvg.Handle(icon.get_icon_file_name(icon_name))
+ ctx.save()
+ ctx.translate(BLOCK_INNER_PAD, BLOCK_INNER_PAD)
+ ctx.scale(0.5, 0.5)
+ rsvg_icon.render_cairo(ctx)
- ctx.restore()
+ ctx.restore()
ctx.translate(BLOCK_INNER_PAD, (height-SNAP_HEIGHT)/2)
self._render_snapshot(ctx, event)
ctx.restore()
- def on_viewer_expose(self, widget, evt, states):
+ def on_viewer_expose(self, widget, evt, tutorial):
"""
Expose signal handler for the viewer's DrawingArea.
- This loops through states and renders every action and transition of
+ This loops through tutorial and renders every action and transition of
the "happy path".
@param widget: the gtk.DrawingArea on which to draw
@param evt: the gtk.gdk.Event containing an "expose" event
- @param states: a tutorius FiniteStateMachine object to paint
+ @param tutorial: a tutorius FiniteStateMachine object to paint
"""
ctx = widget.window.cairo_create()
self.alloc = widget.get_allocation()
@@ -378,9 +377,12 @@ class Viewer(object):
ctx.clip()
ctx.paint()
+ # padding internal to the widget, to draw the first half of the
+ # activity app hint (the icon)
+ ctx.translate(20, 0)
ctx.translate(BLOCK_PADDING, BLOCK_PADDING)
- painter = self._paint_state(ctx, states)
+ painter = self._paint_state(ctx, tutorial)
while painter.next(): pass
if self.click_pos and self.drag_pos:
@@ -400,7 +402,7 @@ class Viewer(object):
self.drag_pos = self.click_pos = evt.get_coords()
widget.queue_draw()
- self.selection = []
+ self.selection.clear()
def _on_drag(self, widget, evt):
self.drag_pos = evt.get_coords()
@@ -413,11 +415,12 @@ class Viewer(object):
def _on_key_press(self, widget, evt):
if evt.keyval == gtk.keysyms.BackSpace:
# remove selection
- for selected in self.selection:
- if isinstance(selected, EventFilter):
- self._creator.delete_state()
+ for name, obj in self.selection:
+ if isinstance(obj, Action):
+ self._creator.delete_action(name)
else:
- self._creator.delete_action(selected)
+ self._creator.delete_state()
+ self.selection.clear()
widget.queue_draw()