diff options
Diffstat (limited to 'atoidejouer/ui/screens/story.py')
-rw-r--r-- | atoidejouer/ui/screens/story.py | 486 |
1 files changed, 486 insertions, 0 deletions
diff --git a/atoidejouer/ui/screens/story.py b/atoidejouer/ui/screens/story.py new file mode 100644 index 0000000..fb9e1e9 --- /dev/null +++ b/atoidejouer/ui/screens/story.py @@ -0,0 +1,486 @@ +# python import +import logging +# .. +from gettext import gettext as _ + +# gtk import +import gtk + +# graphics import +from lib import graphics + +# atoidejouer import +from atoidejouer.db import story +from atoidejouer.tools import config, image, sound, storage + +# get application logger +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 + + +def _on_click(image, event, scene, key): + # get current screen + _screen = scene.toolbar.activity.get_current_screen() + # update panel + if hasattr(_screen, 'panel'): + _screen.panel.refresh() + else: + pass + + +class ScreenStory(graphics.Scene): + + def __init__(self, toolbar, height_offset=0, width_offset=0, + set_canvas=False, clear=False): + # .. + graphics.Scene.__init__(self) + self.background_color = "#ffffff" + # keep toolbar + self.toolbar = toolbar + # .. + self._set_canvas = set_canvas + self._clear = False + # init image dicts + self.__sizes = dict() + self.__graphics = dict() + self.__sounds = dict() + self.__dd_signals = dict() + # init fullscreen flag + self.fullscreen = False + self._fullscreen_changed = True + # screen size first + self._height_offset = height_offset + self._width_offset = width_offset + # .. + self._screen_height = None + self._screen_width = None + # ... + self._refresh_screen_size() + # 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 + # has changed + self._fullscreen_changed = True + # refresh + self.refresh() + + def _refresh_screen_size(self): + # keep some info + self._screen_height = gtk.gdk.screen_height() - self._height_offset + self._screen_width = gtk.gdk.screen_width() - self._width_offset + + def set_clear(self, clear): + self._clear = clear + + def _check_clear(self): + # need clear + if self._clear is True: + # hide previous + for _image in self.__graphics.values(): + _image.visible = False + del _image + # .. + self.__graphics = dict() + # .. + self.__sizes = dict() + # done + self._clear = False + return True + else: + return False + + def refresh(self, key=None): + # 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 + for _key in story.DB().get(story.Key(type='image', time=_time)): + # redraw only if necessary + if key is None or key.id == _k.id: + self.__refresh_image(key, _rate) + _currents.append(key.id) + # draw mask + _currents.append(self.__refresh_default('mask')) + # hide previous + for _id, _image in self.__graphics.items(): + if _id not in _currents: + _image.visible = False + self.queue_draw() + # show first + if self._fullscreen_changed is True: + # disable changed flag + self._fullscreen_changed = False + else: + pass + # refresh sounds if playing + if self.toolbar.activity._thread is None: + pass + elif self.toolbar.activity._thread._pause is False: + """ + # for each sound + for _n in self._get_keys('sounds').get_names(): + if sequence_name is None\ + or sequence_name == _n: + # do move + self.__refresh_sound(_n, _time) + else: + # just get code + _currents.append(self._get_current_code('sounds', _n, + _time)) + # using DB + for key in story.DB().get(story.Key(type='sound', time=_time)): + self.__refresh_sound(key) + """ + else: + # stop all + for _id, _sound in self.__sounds.items(): + if self.toolbar.activity._thread._time == 0: + _sound.stop() + else: + _sound.pause() + + def _update_w_h(self, key): + if key.id in self.__sizes: + pass + else: + # get file size + _c, _w, _h = image.get_image_info(key.media) + # .. + if (self.fullscreen is True\ + or self._screen_width < 1024)\ + and _w != 0: + _new_w = _w * self._screen_width / 1024 + _new_h = _h * _new_w / _w + else: + _new_w = _w + _new_h = _h + # update size + self.__sizes[key.id] = _new_w, _new_h, _w, _h + # return new values + return self.__sizes[key.id] + + def _reverse_x_y(self, size, position): + # .. + _w, _h = size + _x, _y = position + # .. + if self.fullscreen is True\ + or self._screen_width < 1024: + _scene_with = self._screen_width + _scene_height = 516 * _scene_with / 1024.0 + else: + _scene_with = 1024 + _scene_height = 516 + # update x + _a_x = _x - (self._screen_width - _w) / 2 + _a_x = int(_a_x * 100.0 / _scene_with) + # update y + _a_y = _y - (self._screen_height - _h - 88) / 2 + _a_y = int(_a_y * 100.0 / _scene_height) + # return it + 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 + _scene_height = 516 * _scene_with / 1024.0 + else: + _scene_with = 1024 + _scene_height = 516 + # update x + _new_x = ((self._screen_width - _new_w) / 2) + _new_x += int(_x * _scene_with / 100.0) + # update y + _new_y = ((self._screen_height - _new_h - 88) / 2) + _new_y += int(_y * _scene_height / 100.0) + # return it + return _new_x, _new_y + + def __get_scene_size(self): + # + if self.fullscreen is True\ + or self._screen_width < 1024: + _scene_with = self._screen_width + _scene_height = 516 * _scene_with / 1024.0 + else: + _scene_with = 1024 + _scene_height = 516 + # .. + return _scene_with, _scene_height + + def __refresh_default(self, default_name): + _code = '__%s' % default_name + # ensure current image + if _code in self.__graphics: + # .. + self.__graphics[_code].visible = True + else: + _filename = '%s_default' % default_name + _path = storage.get_image_path(_filename) + _key = story.Key(id=_code, media=_path, layer=0) + # .. + _align = (0, 0) + # get/update width and height + _size = self._update_w_h(_key) + # .. + self.__graphics[_key.id] =\ + self.__update_drawing_area(_key, _size, _align) + # and return displayed code + return _code + + def __get_transition_align(self, key, rate): + # get align + _x, _y = key.x, key.y + # get transition ratio + _ratio = time - int(time) + 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, type="image", 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: + # .. + _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 _code 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 + # .. + _image.visible = True + 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_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 + # image + _image = graphics.Image(key.media, 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) + # do add + self.add_child(_image) + # .. + return _image + + """ + def __stop_unused_sounds(self, key): + sounds = story.DB().get(story.Key(name=key.name, type='sound')) + # hide previous + for _k in keys: + if _k.id != current\ + and _k.id in self.__sounds: + self.__sounds[_k.id].pause() + else: + continue + + def __refresh_sound(self, sequence_name, frame): + # get sequence file codes + _seq_codes = self._get_keys('sounds').get_sequence_codes( + self.toolbar.name, sequence_name) + # get sequence filename + _current, _f_type, _k_type = self._get_keys('sounds').get_current( + sequence_name, frame) + # need current + if _current is None: + return self.__stop_unused_sounds(_seq_codes, None) + else: + pass + # current file code + _code = _seq_codes[_current] if _current in _seq_codes else None + # ensure current image + if _code in self.__sounds: + _s = self.__sounds[_code] + if _k_type is None: + _s.pause() + elif _k_type == 'key': + # reset + _s.seek(0) + # play + _s.play() + else: + _s.seek(frame) + _s.play() + else: + # create new + if _k_type is None: + pass + else: + # ... TODO manage start time + _code, _sound = self._prepare_sound(sequence_name, _current) + _sound.play() + # .. + self.__stop_unused_sounds(_seq_codes, _code) + + def _prepare_sound(self, sequence_name, current): + # get graphics path + _path = storage.get_sound_path(current) + # ensure/generate code + _filecode = key.random_str() + # update story key object + self._get_keys('sounds').set_code(self.toolbar.name, sequence_name, + current, _filecode) + # ... + _sound = sound.Player() + _sound.load(_path) + # update graphic dict + self.__sounds[_filecode] = _sound + # return image for futher use + return _filecode, _sound + """ + + def _show(self): + # first refresh + self.refresh() + # .. + self.show() + # update size request + self.set_size_request(self._screen_width, self._screen_height) + # update canvas + if self._set_canvas is True: + self.toolbar.activity.set_canvas(self) + else: + pass |