From 3b73098c9dcc69c759a5d23f7aa47482d89443f7 Mon Sep 17 00:00:00 2001 From: Florent Pigout Date: Sun, 16 Oct 2011 23:46:49 +0000 Subject: permits to add remove image or audio items to the scene --- diff --git a/atoidejouer/db/story.py b/atoidejouer/db/story.py index a0392c7..d386563 100644 --- a/atoidejouer/db/story.py +++ b/atoidejouer/db/story.py @@ -13,34 +13,49 @@ from atoidejouer.tools import storage class Key(object): - def __init__(self, id=None, name=None, type=None, media=None, **kargs): + def __init__(self, id=None, name=None, mime_type=None, timestamp=None, **kargs): """ """ - self.id, self.name, self.type, self.media = id, name, type, media + self.id, self.name, self.mime_type, self.timestamp = id, name, mime_type, timestamp # ensure value if select row returns None value - for arg in ['time', 'layer', 'x', 'y', 'duration', 'loop']: + for arg in ['time', 'layer', 'x', 'y', 'duration', 'loop', 'path']: setattr(self, arg, kargs[arg] if arg in kargs and kargs[arg] else 0) + def get_path(self): + if self.path == 0: + _ds_obj = None + for _ds_obj in storage.journal_query({ + 'mime_type': self.mime_type, + 'timestamp': self.timestamp, + 'title': self.name + }): + break + self.path = _ds_obj.file_path if _ds_obj else 0 + return self.path + + def set_path(self, path): + self.path = path + def __repr__(self): - return "%s|name=%s|type=%s|media=%s|time=%s|layer=%s|"\ + return "%s|name=%s|mime_type=%s|timestamp=%s|time=%s|layer=%s|"\ "x=%s|y=%s|dur=%s|loop=%s"\ - % (self.id, self.name, self.type, self.media, + % (self.id, self.name, self.mime_type, self.timestamp, self.time, self.layer, self.x, self.y, self.duration, self.loop) def __cmp__(self, other): return cmp( - (self.name, self.type, self.media, self.time, self.layer), - (other.name, other.type, self.media, other.time, other.layer) + (self.name, self.mime_type, self.timestamp, self.time, self.layer), + (other.name, other.mime_type, self.timestamp, other.time, other.layer) ) def create(self): return "create table story("\ "id integer primary key autoincrement not null,"\ "name text,"\ - "type text,"\ - "media text,"\ + "mime_type text,"\ + "timestamp text,"\ "time integer,"\ "layer integer,"\ "x integer,"\ @@ -52,7 +67,7 @@ class Key(object): def insert(self): columns = list() values = list() - for c in ['name', 'type', 'media', 'time', 'layer']: + for c in ['name', 'mime_type', 'timestamp', 'time', 'layer']: v = getattr(self, c) if v and v != -1: columns.append(c) @@ -62,9 +77,9 @@ class Key(object): ",".join(values) ) - def _params(self, crit, joiner=" "): + def _params(self, crit, joiner=" and "): values = list() - for c in ['name', 'type', 'time', 'layer', 'media']: + for c in ['name', 'mime_type', 'time', 'layer', 'timestamp']: v = getattr(self, c) if v and v != -1: v = v if v in ['time', 'layer'] else "'%s'" % v @@ -150,6 +165,10 @@ class DB(object): yield obj cur.close() + def one(self, obj): + for one in self.get(obj): + return one + def get_layout_max(self): return 10 diff --git a/atoidejouer/tools/storage.py b/atoidejouer/tools/storage.py index 2dad46b..a0d7437 100644 --- a/atoidejouer/tools/storage.py +++ b/atoidejouer/tools/storage.py @@ -252,6 +252,9 @@ def journal_query(query): # find in ds _results, _count = datastore.find(query, sorting='timestamp') for _r in _results: + if 'title' in query\ + and query['title'] != str(_r.metadata['title']): + continue yield _r @@ -270,13 +273,11 @@ def list_info_from_journal(mime_type=None): _titles = {} # return infos for _o in journal_query({'mime_type': mime_type}): - # get meta - _m = _o.get_metadata() # get title - _t = _m['title'] + _t = _o.metadata['title'] # ensure description - _d = _m['description'] if 'description' in _m else '' - _p = _m['preview'] if 'preview' in _m else None + _d = _o.metadata['description'] if 'description' in _o.metadata else '' + _p = _o.metadata['preview'] if 'preview' in _o.metadata else None # little check if _t in _titles: # udpate reg @@ -288,11 +289,13 @@ def list_info_from_journal(mime_type=None): _titles[_t] = 1 # ensure info yield { - 'activity_id' : _m['activity_id'], + 'activity_id' : _o.metadata['activity_id'], 'description' : _d, - 'timestamp' : _m['timestamp'], + 'timestamp' : _o.metadata['timestamp'], 'preview' : _p, 'title' : _t, + 'file_path' : _o.file_path, + 'mime_type' : mime_type } @@ -302,7 +305,7 @@ def list_files_from_journal(activity_name=None, mime_type=None): # return paths for _o in _objs: # TODO open the files - yield _o.get_file_path() + yield _o.file_path() def get_path_from_journal(timestamp, mime_type): diff --git a/atoidejouer/ui/panel/notebook.py b/atoidejouer/ui/panel/notebook.py index 63e1be3..f67abfc 100644 --- a/atoidejouer/ui/panel/notebook.py +++ b/atoidejouer/ui/panel/notebook.py @@ -12,6 +12,7 @@ import gobject, gtk, glib from sugar.activity import activity # atoidejouer import +from atoidejouer.db import story from atoidejouer.tools import image, storage, ui from atoidejouer.ui.panel import PanelEdit @@ -53,15 +54,10 @@ def _cb_swicth_page(widget, page, page_num, notebook): def _cb_cursor_changed(treeview, notebook, type_): - pass - """ # get the current cursor and path _path, _column = treeview.get_cursor() - # DEBUG if _column is None: return - else: - pass # get model _model = treeview.get_model() # get resource info @@ -70,76 +66,44 @@ def _cb_cursor_changed(treeview, notebook, type_): _iter = _model.get_iter(_path) # update current if type_ in ['graphics', 'sounds']: - # get value - _filename = _model.get_value(_iter, 1) - # udpate preview - notebook.screen.item_preview.set_item(filename=_filename) - # update current - notebook.current_item = _filename - # update current - elif type_ == 'journal': - # get value - _pixbuf = _model.get_value(_iter, 0) - _filename = _model.get_value(_iter, 1) - _metadata = _model.get_value(_iter, 3) - # copy journal item to library to work on it - if notebook._type == 'graphics': - storage.png_from_pixbuf(_filename, _metadata['timestamp']) - # .. - notebook._get_store_graphic() - # for sound - else: - # get source path - _src_path = storage.get_path_from_journal(_metadata['timestamp'], - 'audio/ogg') - # get dst path - _dst_path = storage.get_sound_path(_filename) - # copy - shutil.copy(_src_path, _dst_path) - # .. - notebook._get_store_sound() - # udpate preview - notebook.screen.item_preview.set_item(filename=_filename) - # update current - notebook.current_item = _filename - elif type_ == 'sequence': - # clear sequence preview - notebook.screen.sequence_preview.clear() - # get value - _sequence_path = _model.get_value(_iter, 2) - # update sequence .. - _fnames = storage.get_sequence_items(_sequence_path) - for _f in _fnames: - notebook.screen.sequence_preview.add_item(_f.strip()) - # get sequence name - _sequence_name = _model.get_value(_iter, 1) - # get toolbar sequence entry - _entry = notebook.screen.toolbar._sequence_entry - # update toolbar entry - _entry.set_text(_sequence_name) - # update current - notebook.current_sequence = _sequence_name - # .. - notebook.update_store_sequence() - """ - """ - # .. add action - add column as no title - if _column.get_title() is None: - # get graphic name - _item_name = notebook.current_item - _sequence_name = notebook.current_sequence - if _sequence_name is None\ - or _sequence_name.strip() == ''\ - or _item_name is None: - pass + # shorcut + _activity = notebook.screen.toolbar.activity + # prepare key + _name = _model.get_value(_iter, 1) + _info = _model.get_value(_iter, 2) + _kargs = { + 'name': _name, + 'mime_type': str(_info['mime_type']), + 'timestamp': str(_info['timestamp']), + 'time': _activity._thread._time, + 'layout': story.DB().get_layout_max(), + 'x': 0, + 'y': 0, + 'duration': 0, + 'loop': 0, + 'path': _info['file_path'] + } + # do add + story.DB().add(story.Key(**_kargs)) + # reload key + _key = story.DB().one( + story.Key( + timestamp=str(_info['timestamp']), + mime_type=str(_info['mime_type']), + ) + ) + if _key is None: + raise Exception('[ui.panel.notebook] on_click - key not found: %s'\ + % str(_info['timestamp'])) + # set path for next use + _key.set_path(_info['file_path']) + # TODO refresh panel graphics or sounds + logger.debug('[ui.panel.notebook] on_clicked - _kargs: %s' % _kargs) + # udpate scene or panel_sound + if type_ == 'graphics': + notebook.screen.scene.refresh() else: - # udpate sequence preview - notebook.screen.sequence_preview.add_item(_item_name) - # update sequence file - storage.sequence_save(notebook.screen.toolbar) - else: - pass - """ + notebook.screen.panel_sound.refresh() def __remove_filename_from_sequence(type_, sequence, filename): @@ -275,97 +239,6 @@ class PanelNotebook(gtk.Frame): # return it return _button, _label - """ - def _get_store_graphic(self): - # init/reset store - if self._store_graphic is None: - self._store_graphic = gtk.ListStore( - gtk.gdk.Pixbuf, - gobject.TYPE_STRING, - gtk.gdk.Pixbuf, - gobject.TYPE_PYOBJECT - ) - else: - self._store_graphic.clear() - # .. - _add_path = storage.get_icon_path('more_small') - # .. - _graphic_dir = os.path.join(activity.get_activity_root(), 'data', - 'graphics') - # .. - for _filename in os.listdir(_graphic_dir): - # .. - _path = os.path.join(_graphic_dir, _filename) - # little check - if os.path.isfile(_path): - # check name - try: - _filename, _ext = os.path.splitext(_filename) - # check ext - if _ext in ['.png']: - pass - else: - continue - except Exception, e: - # TODO log something - continue - # .. - _pixbuf = image.get_pixbuf(_path, 64, 48) - _pix_a = image.get_pixbuf(_add_path, 24, 24) - # do update - self._store_graphic.append([_pixbuf, _filename, _pix_a, _path]) - else: - continue - # return the store - return self._store_graphic - """ - - """ - def _get_store_sound(self): - # init/reset store - if self._store_sound is None: - self._store_sound = gtk.ListStore( - gtk.gdk.Pixbuf, - gobject.TYPE_STRING, - gtk.gdk.Pixbuf, - gobject.TYPE_PYOBJECT - ) - else: - self._store_sound.clear() - # prepare icon path - _pix_path = storage.get_image_path('sound', dir_='data') - _add_path = storage.get_icon_path('more_small') - # .. - _sound_dir = os.path.join(activity.get_activity_root(), 'data', - 'sounds') - # .. - for _filename in os.listdir(_sound_dir): - # .. - _path = os.path.join(_sound_dir, _filename) - # little check - if os.path.isfile(_path): - # check name - try: - _filename, _ext = os.path.splitext(_filename) - # check ext - if _ext in ['.ogg']: - pass - else: - continue - except Exception, e: - # TODO log something - continue - # .. - _pixbuf = image.get_pixbuf(_pix_path, 64, 48) - _pix_a = image.get_pixbuf(_add_path, 24, 24) - # do update - self._store_sound.append([_pixbuf, _filename, _pix_a, _path]) - else: - continue - # return the store - return self._store_sound - """ - def update_store(self, type_): _store = self._store_graphic if type_ == 'graphics'\ else self._store_sound @@ -374,7 +247,7 @@ class PanelNotebook(gtk.Frame): _store = gtk.ListStore( gtk.gdk.Pixbuf, gobject.TYPE_STRING, - gtk.gdk.Pixbuf, + # gtk.gdk.Pixbuf, gobject.TYPE_PYOBJECT ) else: @@ -386,25 +259,20 @@ class PanelNotebook(gtk.Frame): # mime type factory _mime_type = 'image/png' if type_=='graphics' else 'audio/ogg' # update store - for _i in storage.list_info_from_journal(mime_type=_mime_type): + for _info in storage.list_info_from_journal(mime_type=_mime_type): # DEBUG - logger.debug('[ui.panel.notebook] update_store - title: %s' % _i['title']) - if _i['preview'] is None: + logger.debug('[ui.panel.notebook] update_store - title: %s' % _info['title']) + if _info['preview'] is None or type_ == 'sounds': _pixbuf = image.get_pixbuf(_default_pix_path, 64, 48) else: # prepare preview - _pixbuf = storage.get_pixbuf_from_data(_i['preview'], - size=(64, 48)) + _pixbuf = storage.get_pixbuf_from_data( + _info['preview'], size=(64, 48)) # .. _add_path = storage.get_icon_path('more_small') - _pix_a = image.get_pixbuf(_add_path, 24, 24) - # store info - _store_info = { - 'activity_id':_i['activity_id'], - 'timestamp': _i['timestamp'] - } + # _pix_a = image.get_pixbuf(_add_path, 24, 24) # do update - _row = [_pixbuf, _i['title'], _pix_a, _store_info] + _row = [_pixbuf, _info['title'], _info] # , _pix_a, _info] _store.append(_row) # .. return _store @@ -431,13 +299,14 @@ class PanelNotebook(gtk.Frame): _col_description.add_attribute(_cell_text, 'text', 1) _col_description.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) _col_description.set_fixed_width(220) - # .. + """ _cell_add = gtk.CellRendererPixbuf() _cell_add.set_property('height', 48) _col_add.pack_start(_cell_add, expand=False) _col_add.add_attribute(_cell_add, 'pixbuf', 2) _col_add.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) _col_add.set_fixed_width(28) + """ # update store _store = self.update_store(type_) # ensure sorting @@ -452,7 +321,7 @@ class PanelNotebook(gtk.Frame): # add columns _treeview.append_column(_col_preview) _treeview.append_column(_col_description) - _treeview.append_column(_col_add) + # _treeview.append_column(_col_add) # .. _scrolled_win.add(_treeview) # return it diff --git a/atoidejouer/ui/panel/sound.py b/atoidejouer/ui/panel/sound.py index 2a76332..27a2062 100644 --- a/atoidejouer/ui/panel/sound.py +++ b/atoidejouer/ui/panel/sound.py @@ -22,15 +22,16 @@ COLOR_GREY_WHITE = ui.get_color(0.85, 0.85, 0.85) COLOR_WHITE = ui.get_color(1.0, 1.0, 1.0) -def _cb_on_click(button, panel_sound, key): +def _cb_on_click(button, panel_sound, key, event): pass - # TODO - update edit panel def _cb_on_remove(panel_sound, key, button): - # udpate DB + # remove image on right click story.DB()._del(key) + panel_sound.refresh() # TODO - update edit panel + panel_sound.screen.panel_edit.refresh() def _set_bg(widget): @@ -69,6 +70,8 @@ class PanelSound(gtk.Frame): self.set_size_request(-1, 140) # do show self.show() + # keep the screen + self.screen = screen # keep item list for the sequence self.keys = list() self._current = None @@ -152,7 +155,7 @@ class PanelSound(gtk.Frame): # do remove self.__remove(_index) - def add_key(self, key): + def add_key(self, key, pos=None): # .. _item_box = gtk.HBox(homogeneous=False, spacing=2) _item_box.show() @@ -176,6 +179,7 @@ class PanelSound(gtk.Frame): _set_bg(_item) _item.set_size_request(96, 78) _item.set_relief(gtk.RELIEF_NONE) + _item.add_events(gtk.gdk.BUTTON_PRESS_MASK) _item.connect('clicked', _cb_on_click, self, key) _item.show() # add a picture here @@ -195,4 +199,10 @@ class PanelSound(gtk.Frame): partial(_cb_on_remove, self, key)) def refresh(self): - pass + self.clear() + # get the current frame + _time = 0.0 if self.screen.toolbar.activity._thread is None\ + else self.screen.toolbar.activity._thread._time + # get the current rate + for _k in story.DB().get(story.Key(mime_type='audio/ogg', time=_time)): + self.add_key(_k) diff --git a/atoidejouer/ui/screens/story.py b/atoidejouer/ui/screens/story.py index fb9e1e9..5c4d7b1 100644 --- a/atoidejouer/ui/screens/story.py +++ b/atoidejouer/ui/screens/story.py @@ -42,6 +42,10 @@ def _on_drag_finish(image, event, scene, key, image_size): def _on_click(image, event, scene, key): # get current screen _screen = scene.toolbar.activity.get_current_screen() + # remove image on right click + if event.button == 3: + story.DB()._del(key) + scene.refresh() # update panel if hasattr(_screen, 'panel'): _screen.panel.refresh() @@ -147,11 +151,11 @@ class ScreenStory(graphics.Scene): _time)) """ # using DB - for _key in story.DB().get(story.Key(type='image', time=_time)): + for _k in story.DB().get(story.Key(mime_type='image/png', time=_time)): # redraw only if necessary if key is None or key.id == _k.id: - self.__refresh_image(key, _rate) - _currents.append(key.id) + self.__refresh_image(_k, _rate) + _currents.append(_k.id) # draw mask _currents.append(self.__refresh_default('mask')) # hide previous @@ -181,7 +185,7 @@ class ScreenStory(graphics.Scene): _currents.append(self._get_current_code('sounds', _n, _time)) # using DB - for key in story.DB().get(story.Key(type='sound', time=_time)): + for key in story.DB().get(story.Key(mime_type='audio/ogg', time=_time)): self.__refresh_sound(key) """ else: @@ -197,7 +201,7 @@ class ScreenStory(graphics.Scene): pass else: # get file size - _c, _w, _h = image.get_image_info(key.media) + _c, _w, _h = image.get_image_info(key.get_path()) # .. if (self.fullscreen is True\ or self._screen_width < 1024)\ @@ -275,7 +279,7 @@ class ScreenStory(graphics.Scene): else: _filename = '%s_default' % default_name _path = storage.get_image_path(_filename) - _key = story.Key(id=_code, media=_path, layer=0) + _key = story.Key(id=_code, path=_path, layer=0) # .. _align = (0, 0) # get/update width and height @@ -289,8 +293,11 @@ class ScreenStory(graphics.Scene): def __get_transition_align(self, key, rate): # get align _x, _y = key.x, key.y + # get the current frame + _time = 0.0 if self.toolbar.activity._thread is None\ + else self.toolbar.activity._thread._time # get transition ratio - _ratio = time - int(time) + _ratio = _time - int(_time) if _ratio < rate: return _x, _y else: @@ -298,7 +305,7 @@ class ScreenStory(graphics.Scene): _next_x, _next_y = self._get_keys('graphics').get_next_align( sequence_name, int(time), filename, use_transition=True) """ - _next_key = story.Key(name=key.name, type="image", time=(key.time+1), + _next_key = story.Key(name=key.name, mime_type="image/png", time=(key.time+1), layer=key.layer) _next_key = story.DB().get(_next_key) _next_x, _next_y = _next_key.x, _next_key.y @@ -350,7 +357,7 @@ class ScreenStory(graphics.Scene): # get z_order _image.z_order = key.layer # disconnect - if _code in self.__dd_signals: + if key.id in self.__dd_signals: _image.disconnect(self.__dd_signals[key.id]) else: pass @@ -388,7 +395,7 @@ class ScreenStory(graphics.Scene): else: _scale = float(_new_w)/_w # image - _image = graphics.Image(key.media, x=_x, y=_y, scale_x=_scale, + _image = graphics.Image(key.get_path(), x=_x, y=_y, scale_x=_scale, scale_y=_scale, z_order=key.layer, draggable=draggable) # connect drag if self._set_canvas is True\ @@ -408,7 +415,7 @@ class ScreenStory(graphics.Scene): """ def __stop_unused_sounds(self, key): - sounds = story.DB().get(story.Key(name=key.name, type='sound')) + sounds = story.DB().get(story.Key(name=key.name, mime_type='audio/ogg')) # hide previous for _k in keys: if _k.id != current\ diff --git a/static/ext/db/blank b/static/ext/db/blank new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/static/ext/db/blank -- cgit v0.9.1