diff options
author | JCTutorius <charlie@tutorius-dev.(none)> | 2009-11-06 01:13:26 (GMT) |
---|---|---|
committer | JCTutorius <charlie@tutorius-dev.(none)> | 2009-11-06 01:13:26 (GMT) |
commit | 29aea8f7d71d5584e011a6955999e37efe6343f9 (patch) | |
tree | b2d59c925adf470d89f40458b5656219913bae31 /tutorius/viewer.py | |
parent | 7035c6e281332b1688c59877ac78516a0dd4635d (diff) | |
parent | 69e3f4598a8b1a4e3d20edcae524b05a8cc7f330 (diff) |
Merge branch 'master' of gitorious@git.sugarlabs.org:tutorius/mainlinelp458452
Diffstat (limited to 'tutorius/viewer.py')
-rw-r--r-- | tutorius/viewer.py | 119 |
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() |