From 425966641affcc8916c787c98b08e6eead399110 Mon Sep 17 00:00:00 2001 From: Florent Pigout Date: Mon, 17 Oct 2011 12:50:52 +0000 Subject: restore edit position, etc.. features on selected item --- diff --git a/atoidejouer/db/story.py b/atoidejouer/db/story.py index d386563..476b610 100644 --- a/atoidejouer/db/story.py +++ b/atoidejouer/db/story.py @@ -8,28 +8,76 @@ logger = logging.getLogger('atoidejouer') import sqlite3; # atoidejouer import -from atoidejouer.tools import storage +from atoidejouer.tools import image, storage + + +WHERE_COLS = [ + 'id', + 'title', + 'mime_type', + 'time', + 'timestamp' + ] + +SET_COLS = [ + 'layer', + 'x', + 'y', + 'duration', + 'loop' + ] + +INSERT_COLS = [ + 'title', + 'mime_type', + 'time', + 'layer', + 'timestamp', + 'x', + 'y', + 'duration', + 'loop' + ] + +NUMERIC_COLS = [ + 'time', + 'layer', + 'x', + 'y', + 'duration', + 'loop' + ] class Key(object): - def __init__(self, id=None, name=None, mime_type=None, timestamp=None, **kargs): - """ - """ - self.id, self.name, self.mime_type, self.timestamp = id, name, mime_type, timestamp + def __init__(self, id=None, title=None, mime_type=None, timestamp=None, **kargs): + self.id, self.title, self.mime_type, self.timestamp = id, title, mime_type, timestamp # ensure value if select row returns None value 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_obj(self): + for _ds_obj in storage.journal_query({ + 'mime_type': self.mime_type, + 'title': self.title + }): + return _ds_obj + + def get_preview(self): + if self.mime_type == 'image/png': + _ds_obj = self._get_obj() + return storage.get_pixbuf_from_data( + _ds_obj.metadata['preview'], + size=(64, 48) + ) + else: + _path = storage.get_image_path('sound', dir_='data') + return image.get_pixbuf(_path, 64, 48) + 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 + _ds_obj = self._get_obj() self.path = _ds_obj.file_path if _ds_obj else 0 return self.path @@ -37,23 +85,23 @@ class Key(object): self.path = path def __repr__(self): - 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.mime_type, self.timestamp, + return "%s|title=%s|mime_type=%s|timestamp=%s|time=%s|layer=%s|"\ + "x=%s|y=%s|duration=%s|loop=%s"\ + % (self.id, self.title, 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.mime_type, self.timestamp, self.time, self.layer), - (other.name, other.mime_type, self.timestamp, other.time, other.layer) + (self.title, self.mime_type, self.timestamp, self.time, self.layer), + (other.title, 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,"\ + "title text,"\ "mime_type text,"\ "timestamp text,"\ "time integer,"\ @@ -67,34 +115,36 @@ class Key(object): def insert(self): columns = list() values = list() - for c in ['name', 'mime_type', 'timestamp', 'time', 'layer']: + for c in INSERT_COLS: v = getattr(self, c) - if v and v != -1: + if v is not None and v != -1: columns.append(c) - values.append(str(v) if c in ['time', 'layer'] else "'%s'" % v) + values.append(str(v) if c in NUMERIC_COLS else "'%s'" % v) return "insert into story (%s) values (%s)" % ( ",".join(columns), ",".join(values) ) - def _params(self, crit, joiner=" and "): + def _params(self, crit): values = list() - for c in ['name', 'mime_type', 'time', 'layer', 'timestamp']: + joiner = ' and ' if crit == 'where' else ', ' + cols = WHERE_COLS if crit == 'where' else SET_COLS + for c in cols: v = getattr(self, c) - if v and v != -1: - v = v if v in ['time', 'layer'] else "'%s'" % v + if v is not None and v != -1: + v = str(v) if c in NUMERIC_COLS else "'%s'" % v values.append("%s=%s" % (c, v)) return "%s %s" % (crit, joiner.join(values)) def where(self): """Prepares simple where query according OO parameters. """ - return self._params("where") + return self._params('where') def set(self): """Prepares simple where query according OO parameters. """ - return self._params("set", joiner=",") + return self._params('set') def select(self): """Prepares simple select query according OO parameters. @@ -151,15 +201,21 @@ class DB(object): yield self.obj(**row) row = cur.fetchone() - def all(self): + def _all(self, query=None): cur = self.con.cursor() - cur.execute("select * from story") + query = "select * from %s" % self.name\ + if query is None\ + else query + cur.execute(query) for obj in self._fetch(cur): yield obj cur.close() def get(self, obj): cur = self.con.cursor() + # DEBUG + # logger.debug('[db.story] get - query: %s' % obj.select()) + # DEBUG cur.execute(obj.select()) for obj in self._fetch(cur): yield obj @@ -169,11 +225,12 @@ class DB(object): for one in self.get(obj): return one - def get_layout_max(self): - return 10 - - def get_duration_max(self): - return 10 + def get_max(self, max_): + query = "select %(max_)s from %(name)s order by -%(max_)s"\ + % {'name': self.name, 'max_': max_} + for obj in self._all(query=query): + return getattr(obj, max_) + return 0 def update(self, obj): cur = self.con.cursor() diff --git a/atoidejouer/tools/image.py b/atoidejouer/tools/image.py index f5ff573..c2d966c 100644 --- a/atoidejouer/tools/image.py +++ b/atoidejouer/tools/image.py @@ -63,9 +63,6 @@ def compute_width_height(width, height, max_width, max_height, use_max=False): # compute ratio _ratio_scr = max_width / float(max_height) _ratio_img = width / float(height) - # DEBUG - logger.debug('[tools.image] compute_width_height - r_src/r_img: %s/%s' % (_ratio_scr, _ratio_img)) - # .. if width > max_width\ or height > max_height: if _ratio_img > _ratio_scr: @@ -77,14 +74,9 @@ def compute_width_height(width, height, max_width, max_height, use_max=False): else: width = max_width height = max_height - # DEBUG - logger.debug('[tools.image] compute_width_height - w/h: %s/%s' % (width, height)) - logger.debug('[tools.image] compute_width_height - max_w/max_h: %s/%s' % (max_width, max_height)) return width, height - # .. elif use_max is True: return max_width, max_height - # .. else: return width, height diff --git a/atoidejouer/tools/storage.py b/atoidejouer/tools/storage.py index a0d7437..4c44289 100644 --- a/atoidejouer/tools/storage.py +++ b/atoidejouer/tools/storage.py @@ -89,8 +89,6 @@ def get_pixbuf_from_data(data, image_type=None, size=None): _loader = gtk.gdk.PixbufLoader(image_type=image_type) else: _loader = gtk.gdk.PixbufLoader() - # DEBUG - logger.debug('[tools.storage] get_pixbuf_from_data - size: %s/%s' % size) # size check if size is None: pass @@ -370,8 +368,6 @@ def __get_preview(file_path): """Creates preview from file path for ds metadata. cf.: http://en.flossmanuals.net/make-your-own-sugar-activities/fun-with-the-journal """ - # DEBUG - logger.debug('[tools.storage] __get_preview - file_path: %s' % file_path) # avoid inter-dependance loop from atoidejouer.tools import image # prepare pixbuf diff --git a/atoidejouer/ui/panel/edit.py b/atoidejouer/ui/panel/edit.py index 7da08d4..b2cacee 100644 --- a/atoidejouer/ui/panel/edit.py +++ b/atoidejouer/ui/panel/edit.py @@ -48,94 +48,61 @@ def _on_position_clicked(widget, panel, move, value): raise Exception('[ui.panel] _on_position_clicked"\ " - invalid position move: %s' % move) # DB update - story.DB().update(panel.key) + rowcount = story.DB().update(panel.key) + # DEBUG + logger.debug('[ui.panel.edit] _on_position_clicked - rowcount: %s' % rowcount) # update panel entries panel.entry_x.set_text(str(panel.key.x)) panel.entry_y.set_text(str(-panel.key.y)) # refresh scene - panel.screen.scene.refresh(key=panel.key) + panel.screen.scene.refresh() -def _on_layout_clicked(widget, panel, move): +def _on_layer_clicked(widget, panel, move): # shortcut _activity = panel.screen.toolbar.activity # get max - _layout_max = story.DB().get_layout_max() + _layer_max = story.DB().get_max('layer') # do nothing if _activity._thread._pause is False\ or panel.key is None: return - # layout factory + # layer factory elif move == 'move_up_up': - panel.key.layout = _layout_max + panel.key.layer = _layer_max elif move == 'move_up': - panel.key.layout = panel.key.layout + 1\ - if panel.key.layout < _layout_max else _layout_max + panel.key.layer = panel.key.layer + 1\ + if panel.key.layer <= _layer_max else _layer_max elif move == 'move_down': - panel.key.layout = panel.key.layout - 1\ - if panel.key.layout > 0 else 0 + panel.key.layer = panel.key.layer - 1\ + if panel.key.layer > 0 else 0 elif move == 'move_down_down': - panel.key.layout = 0 + panel.key.layer = 0 else: - raise Exception('[ui.panel] _on_layout_clicked"\ - " - invalid layout move: %s' % move) + raise Exception('[ui.panel] _on_layer_clicked"\ + " - invalid layer move: %s' % move) # DB update - story.DB().update(panel.key) + rowcount = story.DB().update(panel.key) + # DEBUG + # logger.debug('[ui.screen.story] _on_layer_clicked - key: %s' % panel.key) + # logger.debug('[ui.screen.story] _on_layer_clicked - rowcount: %s' % rowcount) + # DEBUG # update entry - panel.entry_layout.set_text(str(panel.key.layout)) + panel.entry_layer.set_text(str(panel.key.layer)) # refresh scene - panel.screen.scene.refresh() - - -def _on_time_clicked(widget, panel, value): - # shortcut - _activity = panel.screen.toolbar.activity - # little check - if _activity._thread._pause is False\ - or panel.key is None: - return - else: - _time = _activity._thread._time - # time factory - _time += value - panel.key.time = 0 if _time < 0 else _time - # DB update - story.DB().update(panel.key) - # entry update - panel.time_entry.set_text('%1d:%02d' % divmod(_time, 60)) - # update thread time - _activity._thread.set_time(time_=_time) - - -def _on_remove_key_clicked(widget, panel): - # shortcut - _activity = panel.screen.toolbar.activity - if _activity._thread._pause is False\ - or panel.key is None: - return - else: - # delete - story.DB()._del(panel.key) - # empty key - panel.key = None - # refresh scene - panel.screen.scene.refresh() - # and reset panel - panel.refresh() + panel.screen.refresh(key=panel.key) def _on_duration_clicked(widget, panel, value): # shortcut _activity = panel.screen.toolbar.activity - _duration_max = story.DB().get_duration_max() + _duration_max = story.DB().get_max('duration') # do nothing if _activity._thread._pause is False\ or panel.key is None: - pass + return elif panel.key.duration + value < 0: panel.key.duration = 0 - elif panel.key.duration + value > _duration_max: - panel.key.duration = _duration_max else: panel.key.duration += value # DB update @@ -196,6 +163,21 @@ def _get_previous_time(panel, factor): return _previous +def _on_remove_key_clicked(widget, panel): + # shortcut + _activity = panel.screen.toolbar.activity + if _activity._thread._pause is False\ + or panel.key is None: + return + else: + # delete + story.DB()._del(panel.key) + # empty key + panel.key = None + # refresh screen + panel.screen.refresh() + + def _on_key_press(widget, event, parent): # .. _keyval = event.keyval @@ -205,7 +187,7 @@ def _on_key_press(widget, event, parent): if parent.screen != parent.screen.toolbar.activity.get_current_screen(): return # key factory - elif panel.screen.toolbar.name == 'edit': + elif parent.screen.toolbar.name == 'edit': # POSITION if _name == 'Left' and _mod.startswith('Ctrl+'): # big left _on_position_clicked(widget, parent, 'x', -10) @@ -225,22 +207,22 @@ def _on_key_press(widget, event, parent): _on_position_clicked(widget, parent, 'y', 1) # LAYOUT elif _name == 'Page_Up' and _mod.startswith('Ctrl+'): - _on_layout_clicked(widget, parent, 'move_up_up') + _on_layer_clicked(widget, parent, 'move_up_up') elif _name == 'Page_Up': - _on_layout_clicked(widget, parent, 'move_up') + _on_layer_clicked(widget, parent, 'move_up') elif _name == 'Page_Down' and _mod.startswith('Ctrl+'): - _on_layout_clicked(widget, parent, 'move_down_down') + _on_layer_clicked(widget, parent, 'move_down_down') elif _name == 'Page_Down': - _on_layout_clicked(widget, parent, 'move_down') + _on_layer_clicked(widget, parent, 'move_down') # TIME elif _name == 'plus' and _mod.startswith('Ctrl+'): - _on_time_clicked(widget, parent, 10) + _on_duration_clicked(widget, parent, 10) elif _name == 'plus': - _on_time_clicked(widget, parent, 1) + _on_duration_clicked(widget, parent, 1) elif _name == 'minus' and _mod.startswith('Ctrl+'): - _on_time_clicked(widget, parent, -10) + _on_duration_clicked(widget, parent, -10) elif _name == 'minus': - _on_time_clicked(widget, parent, -1) + _on_duration_clicked(widget, parent, -1) # DELETE elif _name == 'BackSpace': _on_remove_key_clicked(widget, parent) @@ -250,24 +232,17 @@ def _on_key_press(widget, event, parent): if parent.screen.toolbar.name in ['edit', 'story']: # shortcut _thread = parent.screen.toolbar.activity._thread - # .. if _name == 'space': # play right - # _time = _get_next_time(parent, 1) - # _thread.set_time(time_=_time, pause=True) elif _name == 'space' and _mod.startswith('Ctrl+'): # play left - # _time = _get_previous_time(parent, 1) - # _thread.set_time(time_=_time, pause=True) # PLAY elif _name == 'Return': - # .. if _thread._pause is True: parent.screen.toolbar.play() _thread.play() - # .. else: parent.screen.toolbar.pause() _thread.pause() @@ -297,8 +272,6 @@ class PanelEdit(gtk.Frame): # init vars self._store = None self.sequence_name = None - # .. - self.time_entry = None # add vbox to the panel for sub frames self.main_box = gtk.VBox(homogeneous=False, spacing=0) # do show @@ -308,27 +281,31 @@ class PanelEdit(gtk.Frame): # .. self.__init_handler() # main vars - self.entry_layout = None - # .. + # title + self._frame_title = None + self._title_image = None + self._title_label = None + self._add_frame_title() + # add specific + self.entry_layer = None + self._frame_layer = None + self._add_frame_layer() self.entry_x = None self.entry_y = None - # add specific - self._frame_layout = None self._frame_position = None - self._add_frame_layout() self._add_frame_position() # init sound fields - self.entry_duration = None self.toggle_loop = None - self.image_loop = None + self._image_loop = None # add specific self._frame_sound = None self._add_frame_sound() # add common - self._frame_time = None + self.entry_duration = None + self._frame_duration = None self._frame_remove = None - self.add_frame_time() - self.add_frame_remove() + self._add_frame_duration() + self._add_frame_remove() def __init_handler(self): _activity = self.screen.toolbar.activity @@ -339,13 +316,11 @@ class PanelEdit(gtk.Frame): _on_key_press, self) def clear(self): - self.time_entry.set_text('') - self.entry_duration.set_text('') - self.toggle_loop.set_active(False) - # .. - self.entry_layout.set_text('') + self.entry_layer.set_text('') self.entry_x.set_text('') self.entry_y.set_text('') + self.entry_duration.set_text('') + self.toggle_loop.set_active(False) def _get_pixbuf(self, graphic_name, dir_='graphics'): # get the image path @@ -358,95 +333,99 @@ class PanelEdit(gtk.Frame): self._frame_sound.hide() # shortcut _activity = self.screen.toolbar.activity - # set layout value - self.entry_layout.set_text(str(self.key.layout)) + # set layer value + self.entry_layer.set_text(str(self.key.layer)) # set x value self.entry_x.set_text(str(self.key.x)) # set y value self.entry_y.set_text(str(-self.key.y)) # hide frame image - self._frame_layout.show() + self._frame_layer.show() self._frame_position.show() def __refresh_sound(self): # hide frame image - self._frame_layout.hide() + self._frame_layer.hide() self._frame_position.hide() - # update duration value - self.entry_duration.set_text('%1d:%02d' % divmod(self.key.duration, 60)) # update loop value self.toggle_loop.set_active(self.key.loop==1) # update image _stock_id = 'repeat_grey' if self.key.loop==1 else 'repeat' - self.image_loop.set_from_file(storage.get_icon_path(_stock_id)) + self._image_loop.set_from_file(storage.get_icon_path(_stock_id)) # show frame sound self._frame_sound.show() def refresh(self, key=None): + # DEBUG + logger.debug('[ui.panel.edit] refresh - key: %s' % key) + # DEBUG self.key = key if not key: - """ - self._frame_layout.hide() + self._frame_title.hide() + self._frame_layer.hide() self._frame_position.hide() self._frame_sound.hide() - self._frame_time.hide() + self._frame_duration.hide() self._frame_remove.hide() - """ - self.show_all() return self.clear() - elif key.type == 'image': + elif key.mime_type == 'image/png': self.__refresh_image() - elif key.type == 'sound': + elif key.mime_type == 'audio/ogg': self.__refresh_sound() else: raise Exception('[ui.panel] refresh - invalid key: %s' % key) - # update common time value - self.time_entry.set_text( - '%1d:%02d' % divmod(key.time, 60)) - self._frame_time.show() + # update title image + self._title_image.set_from_pixbuf(key.get_preview()) + # udpate title label + self._title_label.set_text(key.title) + self._frame_title.show() + # update common duration value + self.entry_duration.set_text( + '%1d:%02d' % divmod(key.duration, 60)) + self._frame_duration.show() self._frame_remove.show() - def __get_time_button(self, name, value, tooltip_text): + def __get_duration_button(self, name, value, tooltip_text): _button = ui.get_button(stock_id=name) _button.set_tooltip_text(tooltip_text) - _button.connect('clicked', _on_time_clicked, self, value) + _button.connect('clicked', _on_duration_clicked, self, value) return _button - def add_frame_time(self): + def _add_frame_duration(self): # init frame - self._frame_time = gtk.Frame(label=_('Time')) - self._frame_time.set_border_width(1) + self._frame_duration = gtk.Frame(label=_('Duration')) + self._frame_duration.set_border_width(1) # do show - self._frame_time.show() + self._frame_duration.show() # do add - self.main_box.pack_start(self._frame_time, expand=False, fill=True) + self.main_box.pack_start(self._frame_duration, expand=False, fill=True) # get over/under spin buttons - _time_box = gtk.HBox(homogeneous=False, spacing=4) - _time_box.set_border_width(4) + _duration_box = gtk.HBox(homogeneous=False, spacing=4) + _duration_box.set_border_width(4) # before .. - _time_box.pack_start(self.__get_time_button('go_left', -10, + _duration_box.pack_start(self.__get_duration_button('go_left', -10, _('Play Before (10 Frames)')), expand=False, fill=True) - _time_box.pack_start(self.__get_time_button('go_left_small', -1, + _duration_box.pack_start(self.__get_duration_button('go_left_small', -1, _('Play Before (1 Frames)')), expand=False, fill=True) # entry - self.time_entry = gtk.Entry() + self.entry_duration = gtk.Entry() # show - self.time_entry.show() + self.entry_duration.show() # set value - should be a string - self.time_entry.set_text('') - self.time_entry.set_alignment(1) - self.time_entry.set_property('editable', False) + self.entry_duration.set_text('') + self.entry_duration.set_alignment(1) + self.entry_duration.set_property('editable', False) # add entry - _time_box.pack_start(self.time_entry, expand=True, fill=True) + _duration_box.pack_start(self.entry_duration, expand=True, fill=True) # .. after - _time_box.pack_start(self.__get_time_button('go_right_small', 1, + _duration_box.pack_start(self.__get_duration_button('go_right_small', 1, _('Play After (1 Frames)')), expand=False, fill=True) - _time_box.pack_start(self.__get_time_button('go_right', 10, + _duration_box.pack_start(self.__get_duration_button('go_right', 10, _('Play After (10 Frames)')), expand=False, fill=True) # do add - self._frame_time.add(_time_box) + self._frame_duration.add(_duration_box) - def add_frame_remove(self): + def _add_frame_remove(self): # init frame self._frame_remove = gtk.Frame(label=_('Remove')) self._frame_remove.set_border_width(1) @@ -468,42 +447,65 @@ class PanelEdit(gtk.Frame): # get remove image button _in_vbox.pack_start(_rm_key_button, expand=False, fill=True) - def __get_layout_button(self, name, tooltip_text): + def _add_frame_title(self): + # init frame + self._frame_title = gtk.Frame(label=_('Title')) + self._frame_title.set_border_width(1) + # do add + self.main_box.pack_start(self._frame_title, expand=False, fill=True) + # vbox for the fram + _in_hbox = gtk.HBox(homogeneous=False, spacing=4) + _in_hbox.set_border_width(4) + # do add + self._frame_title.add(_in_hbox) + # create image + self._title_image = gtk.Image() + # get img path + self._title_image.set_from_file(storage.get_icon_path('repeat')) + self._title_image.set_size_request(48, -1) + # add duration box + _in_hbox.pack_start(self._title_image, expand=False, fill=True) + # create label + self._title_label = gtk.Label() + self._title_label.set_alignment(0, 0.5) + # add duration box + _in_hbox.pack_start(self._title_label, expand=False, fill=True) + + def __get_layer_button(self, name, tooltip_text): _button = ui.get_button(stock_id=name) _button.set_tooltip_text(tooltip_text) - _button.connect('clicked', _on_layout_clicked, self, name) + _button.connect('clicked', _on_layer_clicked, self, name) return _button - def _add_frame_layout(self): + def _add_frame_layer(self): # init frame - self._frame_layout = gtk.Frame(label=_('Layout')) - self._frame_layout.set_border_width(1) + self._frame_layer = gtk.Frame(label=_('Layer')) + self._frame_layer.set_border_width(1) # do add - self.main_box.pack_start(self._frame_layout, expand=False, fill=True) + self.main_box.pack_start(self._frame_layer, expand=False, fill=True) # vbox for the frame _in_vbox = gtk.VBox(homogeneous=False, spacing=4) _in_vbox.set_border_width(4) # do add - self._frame_layout.add(_in_vbox) + self._frame_layer.add(_in_vbox) # get over/under spin buttons _layer_box = gtk.HBox(homogeneous=True, spacing=4) # down .. - _layer_box.pack_start(self.__get_layout_button('move_down_down', + _layer_box.pack_start(self.__get_layer_button('move_down_down', _('Layer to Bottom')), expand=False, fill=True) - _layer_box.pack_start(self.__get_layout_button('move_down', + _layer_box.pack_start(self.__get_layer_button('move_down', _('Lower Layer')), expand=False, fill=True) # entry - self.entry_layout = gtk.Entry() + self.entry_layer = gtk.Entry() # set value - should be a string - self.entry_layout.set_text("") - self.entry_layout.set_alignment(1) - self.entry_layout.set_property('editable', False) + self.entry_layer.set_alignment(1) + self.entry_layer.set_property('editable', False) # add entry - _layer_box.pack_start(self.entry_layout, expand=False, fill=True) + _layer_box.pack_start(self.entry_layer, expand=False, fill=True) # .. up - _layer_box.pack_start(self.__get_layout_button('move_up', + _layer_box.pack_start(self.__get_layer_button('move_up', _('Raise Layer')), expand=False, fill=True) - _layer_box.pack_start(self.__get_layout_button('move_up_up', + _layer_box.pack_start(self.__get_layer_button('move_up_up', _('Layer to Top')), expand=False, fill=True) # add row sequence _in_vbox.pack_start(_layer_box, expand=True, fill=True) @@ -565,51 +567,16 @@ class PanelEdit(gtk.Frame): # put it in self._frame_position.add(_in_vbox) - def _get_time(self, value): - """Format the time value to display - """ - return '%1d:%02d' % divmod(value, 60) - - def __get_duration_button(self, name, value, tooltip_text): - _button = ui.get_button(stock_id=name) - _button.set_tooltip_text(tooltip_text) - _button.connect('clicked', _on_duration_clicked, self, value) - return _button - - def _get_duration_box(self): - # get less/more spin buttons - _duration_box = gtk.HBox(homogeneous=True, spacing=4) - # down .. - _duration_box.pack_start(self.__get_duration_button('less', -10, - _('Duration -10s')), expand=False, fill=True) - _duration_box.pack_start(self.__get_duration_button('less_small', -1, - _('Duration -1s')), expand=False, fill=True) - # entry - self.entry_duration = gtk.Entry() - # set value - should be a string - self.entry_duration.set_text('') # self._get_time(0) - self.entry_duration.set_alignment(1) - self.entry_duration.set_property('editable', False) - self.entry_duration.set_size_request(64, -1) - # add entry - _duration_box.pack_start(self.entry_duration, expand=False, fill=True) - _duration_box.pack_start(self.__get_duration_button('more_small', 1, - _('Duration +1s')), expand=False, fill=True) - _duration_box.pack_start(self.__get_duration_button('more', 10, - _('Duration +10s')), expand=False, fill=True) - # return it - return _duration_box - def _init_loop_box(self): # init row _loop_box = gtk.HBox(homogeneous=False, spacing=4) # create image - self.image_loop = gtk.Image() + self._image_loop = gtk.Image() # get img path - self.image_loop.set_from_file(storage.get_icon_path('repeat')) - self.image_loop.set_size_request(48, -1) + self._image_loop.set_from_file(storage.get_icon_path('repeat')) + self._image_loop.set_size_request(48, -1) # add image - _loop_box.pack_start(self.image_loop, expand=False, fill=True) + _loop_box.pack_start(self._image_loop, expand=False, fill=True) # create label _label = gtk.Label(_('Repeat')) _label.set_alignment(0, 0.5) @@ -622,7 +589,7 @@ class PanelEdit(gtk.Frame): self.toggle_loop.add(_loop_box) # set cb self.toggle_loop.connect('toggled', _on_loop_click, self, - self.image_loop) + self._image_loop) def _add_frame_sound(self): # init frame @@ -630,13 +597,6 @@ class PanelEdit(gtk.Frame): self._frame_sound.set_border_width(1) # do add self.main_box.pack_start(self._frame_sound, expand=False, fill=True) - # vbox for the fram - _in_vbox = gtk.VBox(homogeneous=False, spacing=4) - _in_vbox.set_border_width(4) - # do add - self._frame_sound.add(_in_vbox) - # add duration box - _in_vbox.pack_start(self._get_duration_box(), expand=False, fill=True) # add loop button self._init_loop_box() - _in_vbox.pack_start(self.toggle_loop, expand=False, fill=True) + self._frame_sound.add(self.toggle_loop) diff --git a/atoidejouer/ui/panel/notebook.py b/atoidejouer/ui/panel/notebook.py index f67abfc..346e2f9 100644 --- a/atoidejouer/ui/panel/notebook.py +++ b/atoidejouer/ui/panel/notebook.py @@ -36,158 +36,57 @@ def _set_bg(widget): def _cb_swicth_page(widget, page, page_num, notebook): - """ - if page_num == 1: - notebook.remove_button.show() - else: - notebook.remove_button.hide() - notebook.remove_label.hide() - """ # get current child _child = widget.get_nth_page(page_num) # get current label _label = widget.get_tab_label(_child) # force white - # glib.idle_add(partial(_label.modify_fg, gtk.STATE_NORMAL, COLOR_WHITE)) - # _label.modify_fg(gtk.STATE_NORMAL, COLOR_WHITE) _set_bg(_label) -def _cb_cursor_changed(treeview, notebook, type_): +def _cb_cursor_changed(treeview, notebook): # get the current cursor and path _path, _column = treeview.get_cursor() if _column is None: return # get model _model = treeview.get_model() - # get resource info - _info = _model # get iter _iter = _model.get_iter(_path) - # update current - if type_ in ['graphics', 'sounds']: - # 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']), - ) + # shorcut + _activity = notebook.screen.toolbar.activity + # prepare key + _title = _model.get_value(_iter, 1) + _info = _model.get_value(_iter, 2) + _kargs = { + 'title': _title, + 'mime_type': str(_info['mime_type']), + 'timestamp': str(_info['timestamp']), + 'time': _activity._thread._time, + 'layer': story.DB().get_max('layer'), + 'x': 0, + 'y': 0, + 'duration': 0, + 'loop': 0, + 'path': _info['file_path'] + } + # do add + story.DB().add(story.Key(**_kargs)) + # reload key to retrieve db id + _key = story.DB().one( + story.Key( + title=_title, + 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: - notebook.screen.panel_sound.refresh() - - -def __remove_filename_from_sequence(type_, sequence, filename): - pass - """ - # little check - if filename.strip() == '': - # do nothing - return True - else: - # get sequence path - _seq_path = storage.get_sequence_path(type_, sequence) - # get current names - _fnames = storage.get_sequence_items(_seq_path) - # has remaining files - if filename in _fnames: - _fnames.remove(filename) - else: - return True - # .. - if len(_fnames) == 0: - os.remove(_seq_path) - return False - else: - # open file - _file = open(_seq_path, 'wb') - # update - for _f in _fnames: - _file.write('%s\n' % _f) - # close - _file.close() - # .. - return True - """ - - -def _on_button_click(button, notebook): - pass - """ - # get file path - if notebook._type == 'graphics': - _path = storage.get_image_path(notebook.current_item) - elif notebook._type == 'sounds': - _path = storage.get_sound_path(notebook.current_item) - # do nothing - else: - return - # remove file - os.remove(_path) - # shortcuts - _screen = notebook.screen - _toolbar = _screen.toolbar - _activity = _toolbar.activity - # .. - _keys = _activity.graphic_keys\ - if _toolbar.name == 'graphics_add'\ - else _activity.sound_keys - # .. - _type = 'graphics' if _toolbar.name == 'graphics_add' else 'sounds' - # prepare seq path - _seq_dir = os.path.join(activity.get_activity_root(), 'data', - 'sequences', _type) - # get sequence names - for _seq_name in os.listdir(_seq_dir): - # get sequence name from corresponding file name - _seq_name = _seq_name.replace('.seq', '') - # remove from file system - if __remove_filename_from_sequence(_type, _seq_name, - notebook.current_item) is True: - # remove from keys - _keys.remove_filename_from_all(_seq_name, notebook.current_item) - # remove the entire sequence - else: - # from keys - _keys.remove_sequence(_seq_name) - # .. - notebook._get_store_sequence() - # remove item in treview - notebook.remove_current_row() - # remove current sequence - _screen.sequence_preview.remove_item(notebook.current_item) - # avoid current - notebook.current_item = None - """ + ) + 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']) + # udpate all + notebook.screen.refresh(key=_key) class PanelNotebook(gtk.Frame): @@ -213,31 +112,6 @@ class PanelNotebook(gtk.Frame): self.add(_main_box) # and the notebook _main_box.pack_start(self._get_notebook(), expand=True, fill=True) - """ - # init remove button and label - self.remove_button, self.remove_label = self._get_remove_button() - # .. - _main_box.pack_start(self.remove_button, expand=False, fill=True) - _main_box.pack_start(self.remove_label, expand=False, fill=True) - """ - - def _get_remove_button(self): - # init button - _button = ui.get_button(label=_('Remove Item from Disk'), - stock_id='delete', width=48, padding=(5, 0)) - _button.set_border_width(2) - _button.hide() - # set cb - _button.connect('clicked', _on_button_click, self) - # init - _label = gtk.Label() - # set markup - _label.set_use_markup(True) - # align - _label.set_padding(5, 5) - _label.set_alignment(0, 0.5) - # return it - return _button, _label def update_store(self, type_): _store = self._store_graphic if type_ == 'graphics'\ @@ -260,8 +134,6 @@ class PanelNotebook(gtk.Frame): _mime_type = 'image/png' if type_=='graphics' else 'audio/ogg' # update store for _info in storage.list_info_from_journal(mime_type=_mime_type): - # DEBUG - 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: @@ -315,7 +187,7 @@ class PanelNotebook(gtk.Frame): _treeview = gtk.TreeView(_store) _treeview.set_reorderable(False) # cb - _treeview.connect('cursor-changed', _cb_cursor_changed, self, type_) + _treeview.connect('cursor-changed', _cb_cursor_changed, self) # show it _treeview.show() # add columns diff --git a/atoidejouer/ui/panel/sound.py b/atoidejouer/ui/panel/sound.py index 27a2062..406cc32 100644 --- a/atoidejouer/ui/panel/sound.py +++ b/atoidejouer/ui/panel/sound.py @@ -16,21 +16,24 @@ from atoidejouer.tools import image, sound, storage, ui logger = logging.getLogger('atoidejouer') +LABEL_MAX_LENGHT = 12 + COLOR_GREY_DARK = ui.get_color(0.5, 0.5, 0.5) COLOR_GREY_LIGHT = ui.get_color(0.75, 0.75, 0.75) 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, event): - pass +def _cb_on_click(button, panel_sound, key): + # update edit panel + panel_sound.screen.panel_edit.refresh(key=key) def _cb_on_remove(panel_sound, key, button): # remove image on right click story.DB()._del(key) panel_sound.refresh() - # TODO - update edit panel + # update edit panel panel_sound.screen.panel_edit.refresh() @@ -44,9 +47,9 @@ def _add_simple_button(parent, icon_name, tooltip, cb): # .. remove button _button = gtk.Button() _button.show() - _button.set_tooltip_text(tooltip) # _('Remove ') + filename + _button.set_tooltip_text(tooltip) # cb - _button.connect('clicked', cb) # cb, self, filename + _button.connect('clicked', cb) # add parent.pack_start(_button, expand=False, fill=False) # add a remove image here @@ -156,7 +159,6 @@ class PanelSound(gtk.Frame): self.__remove(_index) def add_key(self, key, pos=None): - # .. _item_box = gtk.HBox(homogeneous=False, spacing=2) _item_box.show() self._scrolled_hbox.pack_start(_item_box, expand=False, fill=False) @@ -189,13 +191,16 @@ class PanelSound(gtk.Frame): # get pixbuff and update image _path = storage.get_image_path('sound', dir_='data') _item_img.set_from_pixbuf(image.get_pixbuf(_path, 96, 62)) + # manage label max length + _title = key.title + _title = _title[:len(_title) - LABEL_MAX_LENGHT]\ + if len(_title) > LABEL_MAX_LENGHT else _title # add label - _label = gtk.Label(key.name) + _label = gtk.Label(_title) _label.show() - # ... _vbox.pack_start(_label, expand=False, fill=True) # remove button - _add_simple_button(_item_box, 'less_small', _('Remove ') + key.name, + _add_simple_button(_item_box, 'less_small', _('Remove ') + key.title, partial(_cb_on_remove, self, key)) def refresh(self): diff --git a/atoidejouer/ui/screens/edit.py b/atoidejouer/ui/screens/edit.py index 1d28baf..fa63bb7 100644 --- a/atoidejouer/ui/screens/edit.py +++ b/atoidejouer/ui/screens/edit.py @@ -53,12 +53,12 @@ class ScreenEdit(gtk.HBox): self.panel_edit = PanelNotebook(self) # PanelEdit(self) self.pack_start(self.panel_edit, expand=False, fill=False) - def _show(self): - # show self - self.show_all() - # refresh all + def refresh(self, key=None): self.scene.refresh() self.panel_sound.refresh() - self.panel_edit.refresh() - # update toolbar + self.panel_edit.refresh(key=key) + + def _show(self): + self.show_all() + self.refresh() self.toolbar.activity.set_canvas(self) diff --git a/atoidejouer/ui/screens/story.py b/atoidejouer/ui/screens/story.py index 5c4d7b1..9086410 100644 --- a/atoidejouer/ui/screens/story.py +++ b/atoidejouer/ui/screens/story.py @@ -19,38 +19,25 @@ logger = logging.getLogger('atoidejouer') def _on_drag_finish(image, event, scene, key, image_size): # get align values - _a_x, _a_y = scene._reverse_x_y(image_size, (image.x, image.y)) - # shortcut - # story_keys = scene._get_keys('graphics') - # update keys - # story_keys.set_align(sequence_name, frame, filename, - # (_a_x, _a_y)) - # update transitions - # story_keys.refresh(sequence_name) - # story_keys.ask_clear() - # refresh scene with rounded values - scene.refresh(key=key) - # get current screen - _screen = scene.toolbar.activity.get_current_screen() - # update position in panel - if hasattr(_screen, 'panel'): - _screen.panel.refresh() - else: - pass + key.x, key.y = scene._reverse_x_y(image_size, (image.x, image.y)) + # do update + rowcount = story.DB().update(key) + # DEBUG + # logger.debug('[ui.screen.story] _on_drag_finish - key: %s' % key) + # logger.debug('[ui.screen.story] _on_drag_finish - rowcount: %s' % rowcount) + # DEBUG + # refresh + scene.toolbar.activity.get_current_screen().refresh(key=key) 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() - else: - pass + # invalidate key + key = None + # refresh + scene.toolbar.activity.get_current_screen().refresh(key=key) class ScreenStory(graphics.Scene): @@ -84,15 +71,6 @@ class ScreenStory(graphics.Scene): # and show self._show() - """ - def _get_keys(self, type_): - # .. - if type_ == 'graphics': - return self.toolbar.activity.graphic_keys - else: - return self.toolbar.activity.sound_keys - """ - def set_fullscreen(self, fullscreen): # update fullscreen flag self.fullscreen = fullscreen @@ -126,35 +104,18 @@ class ScreenStory(graphics.Scene): else: return False - def refresh(self, key=None): + def refresh(self): + # ensure valid screen size + self._refresh_screen_size() # get the current frame _time = 0.0 if self.toolbar.activity._thread is None\ else self.toolbar.activity._thread._time # get the current rate _rate = config.Config().get_rate_value() - # clear ?? - # self._check_clear() - # .. - self._refresh_screen_size() - # .. - _currents = list() - """ - # for each images - for _n in self._get_keys('graphics').get_names(): - if sequence_name is None\ - or sequence_name == _n: - # do move - _currents.append(self.__refresh_image(_n, _time, _rate)) - else: - # just get code - _currents.append(self._get_current_code('graphics', _n, - _time)) - """ # using DB + _currents = list() 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(_k, _rate) + self.__refresh_image(_k, _rate) _currents.append(_k.id) # draw mask _currents.append(self.__refresh_default('mask')) @@ -238,10 +199,8 @@ class ScreenStory(graphics.Scene): return _a_x, _a_y def _update_x_y(self, size, align): - # .. _new_w, _new_h, _w, _h = size _x, _y = align - # if self.fullscreen is True\ or self._screen_width < 1024: _scene_with = self._screen_width @@ -301,116 +260,74 @@ class ScreenStory(graphics.Scene): if _ratio < rate: return _x, _y else: - """ - _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, mime_type="image/png", time=(key.time+1), - layer=key.layer) + _next_key = story.Key(title=key.title, 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 _next_x = _x if _next_x is None else _x + (_next_x - _x) * _ratio _next_y = _y if _next_y is None else _y + (_next_y - _y) * _ratio return _next_x, _next_y - """ - def _get_current_code(self, type_, sequence_name, time): - # get sequence filename - _current, _f_type, _k_type = self._get_keys(type_).get_current( - sequence_name, int(time)) - # need current - if _current is None: - return None - else: - pass - # get sequence file codes - return self._get_keys(type_).get_code( - self.toolbar.name, sequence_name, _current) - """ - def __refresh_image(self, key, rate): - """ - # get sequence filename - _current, _f_type, _k_type = self._get_keys('graphics').get_current( - sequence_name, int(time)) - # need current - if _current is None: - return None - else: - pass - # get sequence file codes - _code = self._get_keys('graphics').get_code( - self.toolbar.name, sequence_name, _current) - # current file code - _code = key.random_str() if _code is None else _code - """ # get/update width and height _size = self._update_w_h(key) # get align _align = self.__get_transition_align(key, rate) # ensure current image if key.id in self.__graphics: - # .. + # DEBUG + logger.debug('[ui.screen.story] __refresh_image - key: %s' % key) + # DEBUG _image = self.__graphics[key.id] # update x, y _image.x, _image.y = self._update_x_y(_size, _align) # get z_order _image.z_order = key.layer - # disconnect - if key.id in self.__dd_signals: - _image.disconnect(self.__dd_signals[key.id]) - else: - pass # scale _new_w, _new_h, _w, _h = _size - # re-connect - _h_id = _image.connect('on-drag-finish', _on_drag_finish, self, - key, (_new_w, _new_h)) - # .. - self.__dd_signals[key.id] = _h_id - # .. + # set visibility _image.visible = True + # refresh signals + self.__update_image_signals(key, _image, (_new_w, _new_h)) else: # draggable for edit only _draggable = self._set_canvas is False\ and config.Config().use_dnd() is True - # .. _image = self.__update_drawing_area(key, _size, _align, draggable=_draggable) - # .. self.__graphics[key.id] = _image - """ - self._get_keys('graphics').set_code(self.toolbar.name, sequence_name, - _current, _code) - """ + + def __update_image_signals(self, key, image, size): + # remove existing handlers + if key.id in self.__dd_signals: + _h_id_drag, _h_id_click = self.__dd_signals[key.id] + image.disconnect(_h_id_drag) + image.disconnect(_h_id_click) + # connect + _h_id_drag = image.connect('on-drag-finish', _on_drag_finish, self, + key, size) + _h_id_click = image.connect('on-click', _on_click, self, key) + # update signal dict + self.__dd_signals[key.id] = (_h_id_drag, _h_id_click) def __update_drawing_area(self, key, size, align, draggable=False): # update x, y _x, _y = self._update_x_y(size, align) - # scale _new_w, _new_h, _w, _h = size - # .. if _w is None or _w == 0: _scale = 1 else: _scale = float(_new_w)/_w + # DEBUG + logger.debug('[ui.screen.story] __update_drawing_area - key: %s' % key) + # DEBUG # image _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\ - or config.Config().use_dnd() is False\ - or self.toolbar.name != 'graphics': - pass - else: - _h_id = _image.connect('on-drag-finish', _on_drag_finish, self, - key, (_new_w, _new_h)) - self.__dd_signals[key.id] = _h_id - # connect on click - _image.connect('on-click', _on_click, self, key) + # refresh signals + self.__update_image_signals(key, _image, (_new_w, _new_h)) # do add self.add_child(_image) - # .. return _image """ -- cgit v0.9.1