Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/atoidejouerbeta/story/keys.py
diff options
context:
space:
mode:
Diffstat (limited to 'atoidejouerbeta/story/keys.py')
-rw-r--r--atoidejouerbeta/story/keys.py692
1 files changed, 692 insertions, 0 deletions
diff --git a/atoidejouerbeta/story/keys.py b/atoidejouerbeta/story/keys.py
new file mode 100644
index 0000000..90f03bb
--- /dev/null
+++ b/atoidejouerbeta/story/keys.py
@@ -0,0 +1,692 @@
+
+# python import
+import json, logging, os
+# ..
+from functools import partial
+from gettext import gettext as _
+
+# gtk import
+import gobject, gtk, glib
+
+# sugar import
+from sugar.activity import activity
+
+# atoidejouerbeta import
+from atoidejouerbeta.tools import image, sound, storage, ui
+
+# get application logger
+logger = logging.getLogger('atoidejouerbeta')
+
+
+class StoryKeys(object):
+
+ def __init__(self, type_, activity_):
+ # keep type
+ self._type = type_
+ # ..
+ self._activity = activity_
+ # ..
+ self.clear()
+
+ def clear(self):
+ # ..
+ self._names = list()
+ self.__codes = {
+ 'graphics': dict(),
+ 'sounds': dict(),
+ 'story': dict(),
+ }
+ self.__clear = {
+ 'graphics': False,
+ 'sounds': False,
+ 'story': False,
+ }
+ #
+ self._keys = dict()
+
+ def loads(self, data, clear=True):
+ # parse json data
+ _data_dict = json.loads(data)
+ # ..
+ if self._type == 'graphics':
+ # ..
+ _tmp_names = _data_dict['graphic_names']
+ _tmp_keys = _data_dict['graphic_keys']
+ # ..
+ elif self._type == 'sounds':
+ # ..
+ _tmp_names = _data_dict['sound_names']
+ _tmp_keys = _data_dict['sound_keys']
+ # ??
+ else:
+ return
+ # reset keys
+ if clear is True:
+ self.clear()
+ else:
+ pass
+ # set names
+ _exist_list = list()
+ for _n in _tmp_names:
+ if _n in self._names:
+ _exist_list.append(_n)
+ else:
+ self._names.append(_n)
+ # ensure keys
+ for _seq_name, _seq_dict in _tmp_keys.items():
+ # get seq_path for check
+ _seq_path = storage.get_sequence_path(self._type, _seq_name)
+ # little check
+ if _seq_name in self._keys:
+ continue
+ # check path
+ elif os.path.exists(_seq_path):
+ # init seq dict copy
+ _tmp_seq_dict = dict()
+ # work on seq dict copy
+ for _frame_name, _frame_dict in _seq_dict.items():
+ # seq dict copy update
+ _tmp_seq_dict[float(_frame_name)] = _frame_dict
+ # update main dict
+ self._keys[_seq_name] = _tmp_seq_dict
+ # sequence does not exist
+ else:
+ if _seq_name in self._names:
+ self._names.remove(_seq_name)
+ else:
+ pass
+ # ..
+ return _exist_list
+
+ def add_sequence(self, sequence_name, filenames):
+ # TODO ensure valid name
+ if sequence_name in self._names:
+ return False
+ else:
+ # add name to the registry
+ self._names.append(sequence_name)
+ # init seq dict
+ _seq_dict = dict()
+ # update dict
+ for _i, _f in enumerate(filenames):
+ _seq_dict[_f] = {
+ '__align': [0, 0],
+ '__duration': 0,
+ '__loop': False,
+ '__file_type': None,
+ '__key_type': None
+ }
+ # udpate main dict
+ self._keys[sequence_name] = {
+ 0: _seq_dict
+ }
+ # ok
+ return True
+
+ def remove_sequence(self, sequence_name):
+ # little check
+ if sequence_name in self._names:
+ self._names.remove(sequence_name)
+ del self._keys[sequence_name]
+ # ??
+ else:
+ pass
+
+ def ask_clear(self):
+ # ...
+ self.__clear = {
+ 'graphics': True,
+ 'sounds': True,
+ 'story': True,
+ }
+
+ def get_clear(self, screen):
+ return self.__clear[screen]
+
+ def set_clear(self, screen, flag):
+ self.__clear[screen] = flag
+
+ def set_layout(self, sequence_name, layout):
+ # little check
+ if sequence_name in self._names:
+ _current = self._names.index(sequence_name)
+ # little check
+ if _current == layout:
+ # do nothing
+ pass
+ else:
+ # ...
+ self._names.remove(sequence_name)
+ # ...
+ self._names.insert(layout, sequence_name)
+ # nothing to do
+ else:
+ pass
+
+ def get_layout(self, sequence_name):
+ if sequence_name in self._names:
+ return self._names.index(sequence_name)
+ else:
+ return -1
+
+ def get_max_layout(self):
+ return len(self._names) - 1
+
+ def set_code(self, screen, sequence_name, filename, _code):
+ # ..
+ if sequence_name in self.__codes[screen]:
+ pass
+ else:
+ self.__codes[screen][sequence_name] = dict()
+ # ..
+ self.__codes[screen][sequence_name][filename] = _code
+
+ def get_code(self, screen, sequence_name, filename):
+ # ..
+ if sequence_name in self.__codes[screen]:
+ # ..
+ if filename in self.__codes[screen][sequence_name]:
+ return self.__codes[screen][sequence_name][filename]
+ # ??
+ else:
+ return None
+ # ??
+ else:
+ return None
+
+ def get_sequence_codes(self, screen, sequence_name):
+ # ..
+ if sequence_name in self.__codes[screen]:
+ return self.__codes[screen][sequence_name]
+ else:
+ return dict()
+
+ def get_names(self, mask=False):
+ # .. add mask
+ if mask is True:
+ yield 'background_default'
+ else:
+ pass
+ for _n in self._names:
+ yield _n
+ # .. add mask
+ if mask is True:
+ yield 'mask_default'
+ else:
+ pass
+
+ def get_frame_dict(self, sequence_name, frame):
+ # little check
+ if sequence_name in self._names:
+ # ..
+ _seq_dict = self._keys[sequence_name]
+ # little check
+ if frame in _seq_dict:
+ # get frame dict
+ return _seq_dict[frame]
+ else:
+ return None
+ else:
+ return None
+
+ def set_frame(self, sequence_name, previous_frame, new_frame):
+ # little check
+ if sequence_name in self._names:
+ # ..
+ _seq_dict = self._keys[sequence_name]
+ # little check
+ if previous_frame in _seq_dict:
+ # set frame dict from previous
+ _seq_dict[new_frame] = _seq_dict[previous_frame]
+ # clear main dict
+ del _seq_dict[previous_frame]
+ else:
+ pass
+ else:
+ pass
+
+ def get_max_frame(self):
+ # ...
+ _tmp_set = set()
+ # ...
+ for _seq_dict in self._keys.values():
+ # udpate set
+ _tmp_set = _tmp_set.union(_seq_dict.keys())
+ # order list
+ _tmp_list = list(_tmp_set)
+ _tmp_list.sort()
+ # return max
+ if len(_tmp_list) == 0:
+ return 0
+ else:
+ return _tmp_list[-1]
+
+ def set_filename_dict(self, sequence_name, frame, filename, dict_=None):
+ # ensure default dict
+ if dict_ is None:
+ dict_ = {
+ '__align': [0, 0],
+ '__duration': 0,
+ '__loop': False,
+ '__file_type': None,
+ '__key_type': None
+ }
+ else:
+ pass
+ # ensure frame dict
+ _frame_dict = self.get_frame_dict(sequence_name, frame)
+ if _frame_dict is None:
+ self._keys[sequence_name][frame] = dict()
+ else:
+ pass
+ # update the main dict
+ self._keys[sequence_name][frame][filename] = dict_
+
+ def get_filename_dict(self, sequence_name, frame, filename):
+ # little check
+ if sequence_name in self._names:
+ # ..
+ _seq_dict = self._keys[sequence_name]
+ # little check
+ if frame in _seq_dict:
+ # get frame dict
+ _frame_dict = _seq_dict[frame]
+ # little check
+ if filename in _frame_dict:
+ # return filename dict
+ return _frame_dict[filename]
+ else:
+ return None
+ else:
+ return None
+ else:
+ return None
+
+ def remove_filename(self, sequence_name, frame, filename):
+ # .. get the dict
+ _f_dict = self.get_filename_dict(sequence_name, frame, filename)
+ # little check
+ if _f_dict is None:
+ return
+ # do remove
+ else:
+ del self._keys[sequence_name][frame][filename]
+
+ def remove_filename_from_all(self, sequence_name, filename):
+ # little check
+ if sequence_name in self._names:
+ for _frame in range(self.get_max_frame()):
+ self.remove_filename(sequence_name, _frame, filename)
+ # ..
+ else:
+ pass
+
+ def set_align(self, sequence_name, frame, filename, align):
+ # .. get the dict
+ _f_dict = self.get_filename_dict(sequence_name, frame, filename)
+ # little check
+ if _f_dict is None:
+ return
+ else:
+ self._keys[sequence_name][frame][filename]['__align'] = align
+
+ def get_previous_align(self, sequence_name, frame):
+ # prepare inversed range
+ _range = range(frame)
+ _range.reverse()
+ # try one by one
+ for _f in _range:
+ # get frame dict
+ _frame_dict = self.get_frame_dict(sequence_name, _f)
+ # get frame values
+ _frame_values = [] if _frame_dict is None else _frame_dict.values()
+ # find first valid key
+ for _f_dict in _frame_values:
+ # little check
+ if _f_dict['__key_type'] != 'key':
+ continue
+ elif '__align' in _f_dict:
+ return _f_dict['__align']
+ else:
+ return [0, 0]
+ # default
+ return [0, 0]
+
+ def get_align(self, sequence_name, frame, filename):
+ # .. get the dict
+ _f_dict = self.get_filename_dict(sequence_name, frame, filename)
+ # little check
+ if _f_dict is None:
+ return [0, 0]
+ else:
+ # ensure default
+ if '__align' in _f_dict:
+ return _f_dict['__align']
+ else:
+ # set default
+ _f_dict['__align'] = [0, 0]
+ # return default
+ return [0, 0]
+
+ def get_next_align(self, sequence_name, frame, filename,
+ use_transition=False):
+ # prepare inversed range
+ _range = range(frame + 1, self.get_max_frame() + 1)
+ # try one by one
+ for _f in _range:
+ # get frame dict
+ _frame_dict = self.get_frame_dict(sequence_name, _f)
+ # get frame values
+ _frame_values = [] if _frame_dict is None else _frame_dict.values()
+ if _frame_dict is None:
+ continue
+ else:
+ # find first valid key
+ for _f_name, _f_dict in _frame_dict.items():
+ # little check
+ if use_transition is False\
+ and _f_dict['__key_type'] != 'key':
+ continue
+ elif '__align' in _f_dict\
+ and _f_dict['__key_type'] in ['key', 'transition']:
+ # works on the same file only
+ if _f_name == filename:
+ return _f_dict['__align']
+ else:
+ return None, None
+ else:
+ continue
+ # default
+ return None, None
+
+ def inc_position(self, sequence_name, frame, filename, move, value):
+ # get align first
+ _x, _y = self.get_align(sequence_name, frame, filename)
+ # inc
+ if move == 'x':
+ _x += value
+ elif move == 'y':
+ _y += value
+ else:
+ # ??
+ return
+ # update
+ self.set_align(sequence_name, frame, filename, (_x, _y))
+ # return current pos
+ return _x, _y
+
+ def set_duration(self, sequence_name, frame, filename, duration):
+ # .. get the dict
+ _f_dict = self.get_filename_dict(sequence_name, frame, filename)
+ # little check
+ if _f_dict is None:
+ return
+ else:
+ self._keys[sequence_name][frame][filename]['__duration'] = duration
+
+ def get_duration(self, sequence_name, frame, filename):
+ # .. get the dict
+ _f_dict = self.get_filename_dict(sequence_name, frame, filename)
+ # little check
+ if _f_dict is None:
+ return 0
+ else:
+ # ensure default
+ if '__duration' in _f_dict:
+ return _f_dict['__duration']
+ else:
+ # set default
+ _f_dict['__duration'] = 0
+ # return default
+ return 0
+
+ def inc_duration(self, sequence_name, frame, filename, value):
+ # get duration first
+ _d = self.get_duration(sequence_name, frame, filename)
+ # inc
+ _d += value
+ # TODO max is max_ or next key
+ # get max frame
+ _max_frame = self._activity._number_of_keys - frame
+ # ensure value
+ if _d < 0:
+ _d = 0
+ elif _d >= _max_frame:
+ _d = _max_frame - 1
+ else:
+ pass
+ # update
+ self.set_duration(sequence_name, frame, filename, _d)
+ # return current pos
+ return _d
+
+ def set_loop(self, sequence_name, frame, filename, loop):
+ # .. get the dict
+ _f_dict = self.get_filename_dict(sequence_name, frame, filename)
+ # little check
+ if _f_dict is None:
+ return
+ else:
+ self._keys[sequence_name][frame][filename]['__loop'] = loop
+
+ def get_loop(self, sequence_name, frame, filename):
+ # .. get the dict
+ _f_dict = self.get_filename_dict(sequence_name, frame, filename)
+ # little check
+ if _f_dict is None:
+ return False
+ # ensure default
+ else:
+ if '__loop' in _f_dict:
+ return _f_dict['__loop']
+ else:
+ # set default
+ _f_dict['__loop'] = False
+ # return default
+ return False
+
+ def set_current(self, sequence_name, frame, filename, file_type='lib',
+ key_type='key'):
+ """
+ file_type lib or jnl
+ key_type key or transition
+ """
+ # get the dict
+ _filename_dict = self.get_filename_dict(sequence_name, frame, filename)
+ # ensure filename dict
+ if _filename_dict is None:
+ self.set_filename_dict(sequence_name, frame, filename)
+ else:
+ pass
+ # get the dict
+ _frame_dict = self.get_frame_dict(sequence_name, frame)
+ # little check
+ if _frame_dict is None:
+ pass
+ else:
+ # set current
+ for _f, _d in _frame_dict.items():
+ # key type or none
+ _ft = key_type if _f == filename else None
+ # update
+ self._keys[sequence_name][frame][_f]['__file_type'] = _ft
+ # key type or none
+ _kt = key_type if _f == filename else None
+ # update
+ self._keys[sequence_name][frame][_f]['__key_type'] = _kt
+
+ def get_current(self, sequence_name, frame):
+ # get the dict
+ _f_dict = self.get_frame_dict(sequence_name, frame)
+ # little check
+ if _f_dict is None:
+ return None, None, None
+ else:
+ for _f, _d in _f_dict.items():
+ if _d['__key_type'] is None:
+ continue
+ else:
+ return _f, _d['__file_type'], _d['__key_type']
+ # default
+ return None, None, None
+
+ def _refresh_graphic_keys(self, sequence_name):
+ # little check
+ if sequence_name in self._keys:
+ # next dict for transition check
+ _next_list = list()
+ _range = list()
+ _filenames = list()
+ # update next dict
+ for _frame, _filename_dict in self._keys[sequence_name].items():
+ for _filename, _dict in _filename_dict.items():
+ if _filename is None or _dict['__key_type'] != 'key':
+ # invalidate previous
+ self._keys[sequence_name][_frame][_filename] = {
+ '__align': [0, 0],
+ '__duration': 0,
+ '__loop': False,
+ '__file_type': None,
+ '__key_type': None
+ }
+ else:
+ # small update for transition management
+ _tr_frame = (_frame + 1) if len(_range) == 0 else _frame
+ # update current range
+ _range.append(_tr_frame)
+ _filenames.append((_filename, _dict['__file_type']))
+ # ..
+ if len(_range) == 2:
+ _next_list.append((_range, _filenames))
+ _range = list()
+ _filenames = list()
+ else:
+ continue
+ # set transition
+ for _range, _filenames in _next_list:
+ # get first align
+ _first_filename, _first_filetype = _filenames[0]
+ _first_x, _first_y = self.get_align(sequence_name, _range[0]-1,
+ _first_filename)
+ # get last align
+ _last_filename, _last_filetype = _filenames[1]
+ _last_x, _last_y = self.get_align(sequence_name, _range[1],
+ _last_filename)
+ # compute steps
+ _inc_x = float(_last_x - _first_x)
+ _inc_x /= (_range[1] - _range[0] + 1)
+ _inc_y = float(_last_y - _first_y)
+ _inc_y /= (_range[1] - _range[0] + 1)
+ # init new position values
+ _new_x = _first_x
+ _new_y = _first_y
+ for _i in range(*_range):
+ # compute filename and file type
+ if _i < ((_range[1] - _range[0]) / 2):
+ _f = _first_filename
+ _t = _first_filetype
+ else:
+ #_f = _last_filename
+ #_t = _last_filetype
+ _f = _first_filename
+ _t = _first_filename
+ # set transition
+ self.set_current(sequence_name, _i, _f, file_type=_t,
+ key_type='transition')
+ # compute align
+ _new_x += _inc_x
+ _new_y += _inc_y
+ # update align
+ self.set_align(sequence_name, _i, _f, (_new_x, _new_y))
+ else:
+ pass
+
+ def _refresh_sound_keys(self, sequence_name):
+ # shortcut
+ _max = self._activity._number_of_keys
+ # little check
+ if sequence_name in self._keys:
+ # next dict for transition check
+ _durations = list()
+ _loops = list()
+ # update next dict
+ for _frame, _filename_dict in self._keys[sequence_name].items():
+ for _filename, _dict in _filename_dict.items():
+ if _filename is None or _dict['__key_type'] != 'key':
+ # invalidate previous
+ self._keys[sequence_name][_frame][_filename] = {
+ '__align': [0, 0],
+ '__duration': 0,
+ '__loop': False,
+ '__file_type': None,
+ '__key_type': None
+ }
+ else:
+ if _dict['__loop'] is True:
+ _loops.append((_frame, _filename, _dict['__file_type']))
+ elif _dict['__duration'] != None:
+ _durations.append((_frame, _filename,
+ _dict['__file_type'], _dict['__duration']))
+ else:
+ continue
+ # set transition for loop keys
+ for _frame, _f, _f_type in _loops:
+ # little check
+ _t_start = _frame + 1
+ # ..
+ if _t_start >= _max:
+ continue
+ else:
+ pass
+ # ..
+ for _i in range(_t_start, _max+1):
+ # set transition
+ self.set_current(sequence_name, _i, _f,
+ file_type=_f_type, key_type='transition')
+ # set transition for loop keys
+ for _frame, _f, _f_type, _d in _durations:
+ # little check
+ _t_start = _frame + 1
+ _t_end = _t_start + _d
+ # ..
+ if _t_start >= _max:
+ continue
+ elif _t_end > _max:
+ _t_end = _max+1
+ else:
+ pass
+ # ..
+ if _t_start > _t_end:
+ continue
+ else:
+ pass
+ # ..
+ for _i in range(_t_start, _t_end):
+ _f_dict = self.get_filename_dict(sequence_name, _i, _f)
+ # update
+ _kt = None if _f_dict is None else _f_dict['__key_type']
+ # ..
+ if _kt is None:
+ # set transition
+ self.set_current(sequence_name, _i, _f,
+ file_type=_f_type, key_type='transition')
+
+ def check_sequences(self):
+ # sequence check
+ _s_to_remove = list()
+ for _s_name in self._names:
+ _path = storage.get_sequence_path(self._type, _s_name)
+ if os.path.exists(_path):
+ continue
+ else:
+ _s_to_remove.append(_s_name)
+ # ..
+ for _s_name in _s_to_remove:
+ self.remove_sequence(_s_name)
+
+ def refresh(self, sequence_name):
+ # ..
+ if self._type == 'graphics':
+ self._refresh_graphic_keys(sequence_name)
+ else:
+ self._refresh_sound_keys(sequence_name)