diff options
author | Manuel QuiƱones <manuq@laptop.org> | 2012-04-03 23:41:50 (GMT) |
---|---|---|
committer | Manuel QuiƱones <manuq@laptop.org> | 2012-04-03 23:41:50 (GMT) |
commit | 3f85ef148c482039d3ce681ae1cca7f0c6492ab6 (patch) | |
tree | 60094b282ecda30ec9becfbb86a8dcc39a0b62e8 | |
parent | cb95a34f0369a4f438d0358953a2ffac4bd765b4 (diff) | |
parent | 05d854454008aa2809fcc9e7f3d9c4a57507b2ab (diff) |
Merge branch 'master' of git.sugarlabs.org:ingeniummachina/mainline
-rw-r--r-- | activity.py | 4 | ||||
-rw-r--r-- | editmap.py | 47 | ||||
-rw-r--r-- | icons/question.svg | 14 | ||||
-rw-r--r-- | mapnav.py | 7 | ||||
-rw-r--r-- | model.py | 23 | ||||
-rw-r--r-- | questions.py | 113 |
6 files changed, 155 insertions, 53 deletions
diff --git a/activity.py b/activity.py index c75cbc6..b0fa8cd 100644 --- a/activity.py +++ b/activity.py @@ -230,7 +230,7 @@ class IngeniumMachinaActivity(activity.Activity): not self.resources_maps_connected: logging.error('Connecting signal resource_updated') self.collect_resources_win.connect('resource_updated', - self.edit_map_win.load_resources) + self.edit_map_win.load_resources_and_questions) self.main_notebook.set_current_page(button.page) self.action = EDIT_RESOURCES_ACTION @@ -244,7 +244,7 @@ class IngeniumMachinaActivity(activity.Activity): not self.resources_maps_connected: logging.error('Connecting signal resource_updated') self.collect_resources_win.connect('resource_updated', - self.edit_map_win.load_resources) + self.edit_map_win.load_resources_and_questions) # Try connect with the playing map if self.edit_descriptions_win is not None and not \ @@ -54,13 +54,15 @@ class EditMapWin(gtk.HBox): rigth_vbox.pack_start(notebook, True, True) # resources - # store: title, pxb, image_file_name, id_resource - self._resources_store = gtk.ListStore(str, gtk.gdk.Pixbuf, str, str) + # store: title, pxb, image_file_name, id_resource/id_question, type + # type: question or resource + self._resources_store = gtk.ListStore(str, gtk.gdk.Pixbuf, str, str, + str) self._resources_store.set_sort_column_id(0, gtk.SORT_ASCENDING) self.resources_iconview = gtk.IconView(self._resources_store) self.resources_iconview.set_text_column(0) self.resources_iconview.set_pixbuf_column(1) - self.load_resources() + self.load_resources_and_questions() self.resources_iconview.connect('item-activated', self.__resource_iconview_activated_cb) @@ -77,7 +79,7 @@ class EditMapWin(gtk.HBox): scrolled1 = gtk.ScrolledWindow() scrolled1.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) scrolled1.add_with_viewport(self.resources_iconview) - notebook.append_page(scrolled1, gtk.Label(_('Resources'))) + notebook.append_page(scrolled1, gtk.Label(_('Resources & ?'))) scrolled2 = gtk.ScrolledWindow() scrolled2.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) scrolled2.add_with_viewport(self.furniture_iconview) @@ -108,7 +110,7 @@ class EditMapWin(gtk.HBox): room_name = self.game_map.get_room_name(room_key) self.room_name_entry.set_text(room_name) - def load_resources(self, origin=None): + def load_resources_and_questions(self, origin=None): logging.error('Loading resources') self._resources_store.clear() for resource in self.model.data['resources']: @@ -124,7 +126,22 @@ class EditMapWin(gtk.HBox): pxb = gtk.gdk.pixbuf_new_from_file_at_size(image_file_name, 100, 100) self._resources_store.append([title, pxb, image_file_name, - id_resource]) + id_resource, 'resource']) + logging.error('Loading questions') + for question in self.model.data['questions']: + text = question['question'] + if question['type'] == self.model.QUESTION_TYPE_GRAPHIC: + image_file_name = question['file_image'] + else: + image_file_name = './icons/question.svg' + + id_question = question['id_question'] + logging.error('Adding %s %s %s', text, image_file_name, + id_question) + pxb = gtk.gdk.pixbuf_new_from_file_at_size(image_file_name, 100, + 100) + self._resources_store.append([text, pxb, image_file_name, + id_question, 'question']) def load_furniture(self): images_path = os.path.join(activity.get_bundle_path(), @@ -146,18 +163,21 @@ class EditMapWin(gtk.HBox): def __resource_iconview_activated_cb(self, widget, item): model = widget.get_model() image_file_name = model[item][2] - id_resource = model[item][3] - self._add_image(image_file_name, id_resource) + id_object = model[item][3] + type_object = model[item][4] + self._add_image(image_file_name, id_object, type_object) - def _add_image(self, image_file_name, id_resource=None): + def _add_image(self, image_file_name, id_object=None, type_object=None): logging.error('Image %s selected', image_file_name) x = self.nav_view.x y = self.nav_view.y direction = self.nav_view.direction wall_object = {'image_file_name': image_file_name, 'wall_x': 50.0, 'wall_y': 50.0, 'wall_scale': 0.2} - if id_resource is not None: - wall_object['id_resource'] = id_resource + if id_object is not None: + wall_object['id_object'] = id_object + if type_object is not None: + wall_object['type_object'] = type_object self.game_map.add_object_to_wall(x, y, direction, wall_object) self.nav_view.update_wall_info(x, y, direction) self.nav_view.grab_focus() @@ -170,8 +190,9 @@ class EditMapWin(gtk.HBox): if self.resources_iconview.is_focus(): item = self.resources_iconview.get_selected_items()[0][0] image_file_name = self._resources_store[item][2] - id_resource = self._resources_store[item][3] - self._add_image(image_file_name, id_resource) + id_object = self._resources_store[item][3] + type_object = self._resources_store[item][4] + self._add_image(image_file_name, id_object, type_object) def remove_selected_object(self): self.nav_view.remove_selected_object() diff --git a/icons/question.svg b/icons/question.svg new file mode 100644 index 0000000..f6c92bf --- /dev/null +++ b/icons/question.svg @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="55px" height="55px"> + <path + style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linejoin:round" + d="M 48,28 A 20,20 0 1 1 8,28 A 20,20 0 1 1 48,28 z"/> + <path + style="fill:none;stroke:#ffffff;stroke-width:6;stroke-linecap:round;stroke-linejoin:round" + d="M 22,20 C 22,20 25,17 29,17 C 33,17 36,19 36,23 C 36,27 31,29 28,29 L 28,32" /> + <path + style="fill:#ffffff" + d="M 25,40 + a 3,3 0 1 1 6,0 + a 3,3 0 1 1 -6,0 z" /> +</svg> @@ -41,6 +41,8 @@ class MapNavView(gtk.DrawingArea): ([gobject.TYPE_INT, gobject.TYPE_INT, gobject.TYPE_STRING])), 'resource-clicked': (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, ([gobject.TYPE_STRING])), + 'question-clicked': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_STRING]))} MODE_PLAY = 0 @@ -145,7 +147,10 @@ class MapNavView(gtk.DrawingArea): self.update_wall_info(self.x, self.y, self.direction) else: # in play mode trigger event - self.emit('resource-clicked', wall_object['id_resource']) + if wall_object['type_object'] == 'resource': + self.emit('resource-clicked', wall_object['id_object']) + if wall_object['type_object'] == 'question': + self.emit('question-clicked', wall_object['id_object']) if self.view_mode == self.MODE_EDIT: # check resize @@ -8,6 +8,9 @@ import zipfile class GameModel: + QUESTION_TYPE_TEXT = 'TEXT' + QUESTION_TYPE_GRAPHIC = 'GRAPHIC' + def __init__(self): self.data = {} self.data['questions'] = [] @@ -27,6 +30,7 @@ class GameModel: 'file_text' = ''} """ self.data['last_resource_id'] = 0 + self.data['last_question_id'] = 0 self.data['map_data'] = None @@ -34,6 +38,10 @@ class GameModel: self.data['last_resource_id'] = self.data['last_resource_id'] + 1 return self.data['last_resource_id'] + def get_new_question_id(self): + self.data['last_question_id'] = self.data['last_question_id'] + 1 + return self.data['last_question_id'] + def get_resource(self, id_resource): for resource in self.data['resources']: if resource['id_resource'] == int(id_resource): @@ -41,6 +49,13 @@ class GameModel: logging.error('ERROR: resource %s not found', id_resource) return None + def get_question(self, id_question): + for question in self.data['questions']: + if question['id_question'] == int(id_question): + return question + logging.error('ERROR: question %s not found', id_question) + return None + def write(self, file_name): instance_path = os.path.join(activity.get_activity_root(), 'instance') @@ -64,6 +79,14 @@ class GameModel: z.write(resource['file_text'], os.path.join('resources', os.path.basename(resource['file_text']))) + for question in self.data['questions']: + if question['type'] == self.QUESTION_TYPE_GRAPHIC: + z.write(question['file_image'], os.path.join('resources', + os.path.basename(question['file_image']))) + z.write(question['file_image_reply'], + os.path.join('resources', + os.path.basename(question['file_image_reply']))) + z.close() def read(self, file_name): diff --git a/questions.py b/questions.py index 81d9741..385dd99 100644 --- a/questions.py +++ b/questions.py @@ -90,6 +90,12 @@ class DrawReplyArea(gtk.DrawingArea): self.draw_brush(widget, x, y) return True + def write_reply_png(self, file_path): + self.reply_surface.write_to_png(file_path) + + def read_reply_png(self, file_path): + self.reply_surface = self.reply_surface.create_from_png(file_path) + class PrepareQuestionsWin(gtk.HBox): @@ -114,7 +120,8 @@ class PrepareQuestionsWin(gtk.HBox): self.quest_listview.set_size_request(width, -1) self.quest_listview.connect('cursor-changed', self.select_question) - self.treemodel = gtk.ListStore(gobject.TYPE_STRING) + self.treemodel = gtk.ListStore(gobject.TYPE_STRING, + gobject.TYPE_STRING) self.quest_listview.set_model(self.treemodel) renderer = gtk.CellRendererText() renderer.set_property('wrap-mode', gtk.WRAP_WORD) @@ -139,14 +146,19 @@ class PrepareQuestionsWin(gtk.HBox): hbox_row.pack_start(self.question_entry, True, padding=5) vbox.pack_start(hbox_row, False, padding=5) - notebook = gtk.Notebook() - vbox.pack_start(notebook, True) + self.notebook = gtk.Notebook() + vbox.pack_start(self.notebook, True) self.vbox_edit = gtk.VBox() - notebook.set_show_tabs(True) - notebook.append_page(self.vbox_edit, gtk.Label(_('Text reply'))) + self.notebook.set_show_tabs(True) + self.questions_types = [] + + self.notebook.append_page(self.vbox_edit, gtk.Label(_('Text reply'))) + self.questions_types.append(self.model.QUESTION_TYPE_TEXT) vbox_graph_replies = gtk.VBox() - notebook.append_page(vbox_graph_replies, gtk.Label(_('Graph reply'))) + self.notebook.append_page(vbox_graph_replies, + gtk.Label(_('Graph reply'))) + self.questions_types.append(self.model.QUESTION_TYPE_GRAPHIC) # text reply controls hbox_buttons = gtk.HBox() @@ -178,7 +190,7 @@ class PrepareQuestionsWin(gtk.HBox): self._load_treemodel() self.show_all() self._modified_data = False - self._selected_key = None + self._selected_key = self.model.get_new_question_id() def __load_image_cb(self, button): try: @@ -202,13 +214,17 @@ class PrepareQuestionsWin(gtk.HBox): del chooser def __load_image(self, file_path): + if self.draw_reply_area is not None: + self.scrollwin.remove(self.scrollwin.get_children()[0]) + self.draw_reply_area = None self.draw_reply_area = DrawReplyArea(file_path) self.scrollwin.add_with_viewport(self.draw_reply_area) # copy to resources directory self.model.check_resources_directory() resource_path = os.path.join(activity.get_activity_root(), 'instance', 'resources') - shutil.copy(file_path, resource_path) + if not file_path.startswith(resource_path): + shutil.copy(file_path, resource_path) self._image_resource_path = os.path.join(resource_path, os.path.basename(file_path)) self._modified_data = True @@ -221,7 +237,8 @@ class PrepareQuestionsWin(gtk.HBox): logging.error('loading treemodel') for question in self.model.data['questions']: logging.error('adding question %s', question) - self.treemodel.append([question['question']]) + self.treemodel.append([question['question'], + question['id_question']]) def __add_reply_cb(self, button): self._add_reply_entry(reply_ok=len(self.replies_entries) == 0) @@ -242,40 +259,58 @@ class PrepareQuestionsWin(gtk.HBox): hbox_row.pack_start(icon, False, padding=5) hbox_row.show_all() self.replies_entries.append(reply_entry) - self.vbox_edit.replies.append(hbox_row, False) + self.vbox_edit.replies.append(hbox_row) def select_question(self, treeview): treestore, coldex = treeview.get_selection().get_selected() - logging.debug('selected question %s', treestore.get_value(coldex, 0)) + logging.debug('selected question %s', treestore.get_value(coldex, 1)) if self._modified_data: # update data self._update_model(self._selected_key) - self._selected_key = treestore.get_value(coldex, 0) + self._selected_key = treestore.get_value(coldex, 1) self._display_model(self._selected_key) def _update_model(self, key): - question = self._get_question(key) + question = self.model.get_question(key) new_entry = False if question == None: question = {} new_entry = True replies = [] - for reply_entry in self.replies_entries: - if reply_entry.get_text() != '': - reply = {} - reply['text'] = reply_entry.get_text() - reply['valid'] = len(replies) == 0 # The first is the valid - replies.append(reply) + + question_type = self.questions_types[self.notebook.get_current_page()] + question = {'question': self.question_entry.get_text(), - 'type': 'TEXT', - 'replies': replies} + 'type': question_type, + 'id_question': key} + + if question_type == self.model.QUESTION_TYPE_TEXT: + for reply_entry in self.replies_entries: + if reply_entry.get_text() != '': + reply = {} + reply['text'] = reply_entry.get_text() + # The first is the valid + reply['valid'] = len(replies) == 0 + replies.append(reply) + question['replies'] = replies + + if question_type == self.model.QUESTION_TYPE_GRAPHIC: + question['file_image'] = self._image_resource_path + # save painted image + resource_path = os.path.join(activity.get_activity_root(), + 'instance', 'resources') + reply_file_name = os.path.join(resource_path, + 'reply_image_%s.png' % key) + self.draw_reply_area.write_reply_png(reply_file_name) + question['file_image_reply'] = reply_file_name + if new_entry: self.model.data['questions'].append(question) - self.treemodel.append([self.question_entry.get_text()]) + self.treemodel.append([self.question_entry.get_text(), key]) self._modified_data = False def _display_model(self, key): - question = self._get_question(key) + question = self.model.get_question(key) self._display_question(question) def _display_question(self, question, display_empty_entries=False): @@ -284,24 +319,27 @@ class PrepareQuestionsWin(gtk.HBox): for hbox in self.vbox_edit.replies: self.vbox_edit.remove(hbox) self.vbox_edit.replies = [] - # add news - for reply in question['replies']: - if display_empty_entries or reply['text'] != '': - self._add_reply_entry(reply_ok=reply['valid'], - text=reply['text']) + question_type = question['type'] + if question_type == self.model.QUESTION_TYPE_TEXT: + self.notebook.set_current_page(0) + # add replies + for reply in question['replies']: + if display_empty_entries or reply['text'] != '': + self._add_reply_entry(reply_ok=reply['valid'], + text=reply['text']) + + if question_type == self.model.QUESTION_TYPE_GRAPHIC: + self.notebook.set_current_page(1) + # show graph + self.__load_image(question['file_image']) + self.draw_reply_area.read_reply_png(question['file_image_reply']) self._modified_data = False - def _get_question(self, key): - for question in self.model.data['questions']: - if question['question'] == key: - return question - return None - def del_question(self): logging.debug('del question') if self._selected_key is not None: logging.debug('select key %s', self._selected_key) - self.model.data['questions'].remove(self._get_question( + self.model.data['questions'].remove(self.model.get_question( self._selected_key)) self.treemodel.remove( self.quest_listview.get_selection()) @@ -313,10 +351,11 @@ class PrepareQuestionsWin(gtk.HBox): # update data self._update_model(self._selected_key) - self._selected_key = None + self._selected_key = self.model.get_new_question_id() question = {'question': '', - 'type': 'TEXT', + 'type': self.model.QUESTION_TYPE_TEXT, 'replies': [{'text':'', 'valid':True}, {'text':'', 'valid':False}]} + self._display_question(question, display_empty_entries=True) |