# 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