diff options
Diffstat (limited to 'atoidejouer/ui/panel/edit.py')
-rw-r--r-- | atoidejouer/ui/panel/edit.py | 642 |
1 files changed, 642 insertions, 0 deletions
diff --git a/atoidejouer/ui/panel/edit.py b/atoidejouer/ui/panel/edit.py new file mode 100644 index 0000000..7da08d4 --- /dev/null +++ b/atoidejouer/ui/panel/edit.py @@ -0,0 +1,642 @@ + +# python import +import logging, os +# .. +from functools import partial +from gettext import gettext as _ + +# gtk import +import gobject, gtk, glib + +# sugar import +from sugar.activity import activity + +# atoidejouer import +from atoidejouer.db import story +from atoidejouer.tools import config, image, storage, ui + +# get application logger +logger = logging.getLogger('atoidejouer') + + +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 _set_bg(widget): + # bg + widget.modify_bg(gtk.STATE_NORMAL, COLOR_GREY_WHITE) + widget.modify_bg(gtk.STATE_PRELIGHT, COLOR_GREY_WHITE) + widget.modify_bg(gtk.STATE_ACTIVE, COLOR_WHITE) + # fg + widget.modify_fg(gtk.STATE_NORMAL, COLOR_WHITE) + + +def _on_position_clicked(widget, panel, move, value): + # shortcut + _activity = panel.screen.toolbar.activity + if _activity._thread._pause is False\ + or panel.key is None: + pass + elif move == 'x': + panel.key.x += value + elif move == 'y': + panel.key.y += value + else: + raise Exception('[ui.panel] _on_position_clicked"\ + " - invalid position move: %s' % move) + # DB update + story.DB().update(panel.key) + # 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) + + +def _on_layout_clicked(widget, panel, move): + # shortcut + _activity = panel.screen.toolbar.activity + # get max + _layout_max = story.DB().get_layout_max() + # do nothing + if _activity._thread._pause is False\ + or panel.key is None: + return + # layout factory + elif move == 'move_up_up': + panel.key.layout = _layout_max + elif move == 'move_up': + panel.key.layout = panel.key.layout + 1\ + if panel.key.layout < _layout_max else _layout_max + elif move == 'move_down': + panel.key.layout = panel.key.layout - 1\ + if panel.key.layout > 0 else 0 + elif move == 'move_down_down': + panel.key.layout = 0 + else: + raise Exception('[ui.panel] _on_layout_clicked"\ + " - invalid layout move: %s' % move) + # DB update + story.DB().update(panel.key) + # update entry + panel.entry_layout.set_text(str(panel.key.layout)) + # 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() + + +def _on_duration_clicked(widget, panel, value): + # shortcut + _activity = panel.screen.toolbar.activity + _duration_max = story.DB().get_duration_max() + # do nothing + if _activity._thread._pause is False\ + or panel.key is None: + pass + 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 + story.DB().update(panel.key) + # update panel entries + panel.entry_duration.set_text( + '%1d:%02d' % divmod(panel.key.duration, 60)) + + +def _on_loop_click(toggle, panel, image): + # update image + _stock_id = 'repeat_grey' if toggle.get_active() is True else 'repeat' + image.set_from_file(storage.get_icon_path(_stock_id)) + # shortcut + _activity = panel.screen.toolbar.activity + # do nothing + if _activity._thread._pause is False\ + or panel.key is None: + return + else: + panel.key.loop = toggle.get_active() + # DB update + story.DB().update(panel.key) + + +def _get_next_time(panel, factor): + # get the current frame + _time = 0.0 if panel.screen.toolbar.activity._thread is None\ + else panel.screen.toolbar.activity._thread._time + # get rate + _rate = config.Config().get_rate_value() + # next time + _next = _time + factor * _rate + # get max + _max = panel.screen.toolbar.activity._number_of_keys - 1 + if _next < _max: + # ok! + return _next + else: + # return max + pause + return _max + + +def _get_previous_time(panel, factor): + # get the current frame + _time = 0.0 if panel.screen.toolbar.activity._thread is None\ + else panel.screen.toolbar.activity._thread._time + # get rate + _rate = config.Config().get_rate_value() + # previous time + _previous = _time - factor * _rate + # .. + if _previous < 0: + # return min + return 0 + else: + # ok + return _previous + + +def _on_key_press(widget, event, parent): + # .. + _keyval = event.keyval + _name = gtk.gdk.keyval_name(_keyval) + _mod = gtk.accelerator_get_label(_keyval, event.state) + # .. + if parent.screen != parent.screen.toolbar.activity.get_current_screen(): + return + # key factory + elif panel.screen.toolbar.name == 'edit': + # POSITION + if _name == 'Left' and _mod.startswith('Ctrl+'): # big left + _on_position_clicked(widget, parent, 'x', -10) + elif _name == 'Left': # left + _on_position_clicked(widget, parent, 'x', -1) + elif _name == 'Right' and _mod.startswith('Ctrl+'): # big right + _on_position_clicked(widget, parent, 'x', 10) + elif _name == 'Right': # right + _on_position_clicked(widget, parent, 'x', 1) + elif _name == 'Up' and _mod.startswith('Ctrl+'): # big top + _on_position_clicked(widget, parent, 'y', -10) + elif _name == 'Up': # top + _on_position_clicked(widget, parent, 'y', -1) + elif _name == 'Down' and _mod.startswith('Ctrl+'): # big bottom + _on_position_clicked(widget, parent, 'y', 10) + elif _name == 'Down': # bottom + _on_position_clicked(widget, parent, 'y', 1) + # LAYOUT + elif _name == 'Page_Up' and _mod.startswith('Ctrl+'): + _on_layout_clicked(widget, parent, 'move_up_up') + elif _name == 'Page_Up': + _on_layout_clicked(widget, parent, 'move_up') + elif _name == 'Page_Down' and _mod.startswith('Ctrl+'): + _on_layout_clicked(widget, parent, 'move_down_down') + elif _name == 'Page_Down': + _on_layout_clicked(widget, parent, 'move_down') + # TIME + elif _name == 'plus' and _mod.startswith('Ctrl+'): + _on_time_clicked(widget, parent, 10) + elif _name == 'plus': + _on_time_clicked(widget, parent, 1) + elif _name == 'minus' and _mod.startswith('Ctrl+'): + _on_time_clicked(widget, parent, -10) + elif _name == 'minus': + _on_time_clicked(widget, parent, -1) + # DELETE + elif _name == 'BackSpace': + _on_remove_key_clicked(widget, parent) + # IMAGE + # TODO ... + # IN EVERY CASE + 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() + else: + pass + # avoid propagation for rendering issue + widget.emit_stop_by_name('key-press-event') + + +class PanelEdit(gtk.Frame): + + def __init__(self, screen): + # init parent + gtk.Frame.__init__(self) + self.set_shadow_type(gtk.SHADOW_NONE) + # set screen + self.screen = screen + # key var + self.key = None + # get mode + self._mode = config.Config().get('activity>mode') + self._conf = config.Config().get('mode>%s' % self._mode, type_=list) + # ... + self.set_size_request(298, screen.scene._screen_height) + # do show + self.show() + # 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 + self.main_box.show() + # add it to the panel + self.add(self.main_box) + # .. + self.__init_handler() + # main vars + self.entry_layout = None + # .. + 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 + # add specific + self._frame_sound = None + self._add_frame_sound() + # add common + self._frame_time = None + self._frame_remove = None + self.add_frame_time() + self.add_frame_remove() + + def __init_handler(self): + _activity = self.screen.toolbar.activity + _handler_id = _activity._handler_id + if _handler_id: + _activity.disconnect(_handler_id) + _activity._handler_id = _activity.connect('key-press-event', + _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_x.set_text('') + self.entry_y.set_text('') + + def _get_pixbuf(self, graphic_name, dir_='graphics'): + # get the image path + _graphic_path = storage.get_image_path(graphic_name, dir_=dir_) + # return pix and path + return image.get_pixbuf(_graphic_path, 48, 36), _graphic_path + + def __refresh_image(self): + # hide frame sound + self._frame_sound.hide() + # shortcut + _activity = self.screen.toolbar.activity + # set layout value + self.entry_layout.set_text(str(self.key.layout)) + # 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_position.show() + + def __refresh_sound(self): + # hide frame image + self._frame_layout.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)) + # show frame sound + self._frame_sound.show() + + def refresh(self, key=None): + self.key = key + if not key: + """ + self._frame_layout.hide() + self._frame_position.hide() + self._frame_sound.hide() + self._frame_time.hide() + self._frame_remove.hide() + """ + self.show_all() + return self.clear() + elif key.type == 'image': + self.__refresh_image() + elif key.type == 'sound': + 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() + self._frame_remove.show() + + def __get_time_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) + return _button + + def add_frame_time(self): + # init frame + self._frame_time = gtk.Frame(label=_('Time')) + self._frame_time.set_border_width(1) + # do show + self._frame_time.show() + # do add + self.main_box.pack_start(self._frame_time, expand=False, fill=True) + # get over/under spin buttons + _time_box = gtk.HBox(homogeneous=False, spacing=4) + _time_box.set_border_width(4) + # before .. + _time_box.pack_start(self.__get_time_button('go_left', -10, + _('Play Before (10 Frames)')), expand=False, fill=True) + _time_box.pack_start(self.__get_time_button('go_left_small', -1, + _('Play Before (1 Frames)')), expand=False, fill=True) + # entry + self.time_entry = gtk.Entry() + # show + self.time_entry.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) + # add entry + _time_box.pack_start(self.time_entry, expand=True, fill=True) + # .. after + _time_box.pack_start(self.__get_time_button('go_right_small', 1, + _('Play After (1 Frames)')), expand=False, fill=True) + _time_box.pack_start(self.__get_time_button('go_right', 10, + _('Play After (10 Frames)')), expand=False, fill=True) + # do add + self._frame_time.add(_time_box) + + def add_frame_remove(self): + # init frame + self._frame_remove = gtk.Frame(label=_('Remove')) + self._frame_remove.set_border_width(1) + # do show + self._frame_remove.show() + # do add + self.main_box.pack_start(self._frame_remove, expand=False, fill=True) + # init container + _in_vbox = gtk.HBox(homogeneous=True, spacing=4) + _in_vbox.set_border_width(4) + # do add + self._frame_remove.add(_in_vbox) + # prepare remove sequence button + _rm_key_button = ui.get_button(label=_('Key'), + stock_id='remove_item', width=48, padding=(12, 0)) + _rm_key_button.set_tooltip_text(_('Remove Key')) + # set cb + _rm_key_button.connect('clicked', _on_remove_key_clicked, self) + # get remove image button + _in_vbox.pack_start(_rm_key_button, expand=False, fill=True) + + def __get_layout_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) + return _button + + def _add_frame_layout(self): + # init frame + self._frame_layout = gtk.Frame(label=_('Layout')) + self._frame_layout.set_border_width(1) + # do add + self.main_box.pack_start(self._frame_layout, 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) + # 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 to Bottom')), expand=False, fill=True) + _layer_box.pack_start(self.__get_layout_button('move_down', + _('Lower Layer')), expand=False, fill=True) + # entry + self.entry_layout = 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) + # add entry + _layer_box.pack_start(self.entry_layout, expand=False, fill=True) + # .. up + _layer_box.pack_start(self.__get_layout_button('move_up', + _('Raise Layer')), expand=False, fill=True) + _layer_box.pack_start(self.__get_layout_button('move_up_up', + _('Layer to Top')), expand=False, fill=True) + # add row sequence + _in_vbox.pack_start(_layer_box, expand=True, fill=True) + + def __get_position_button(self, name, move, value, tooltip_text): + # init button + _button = ui.get_button(stock_id=name) + _button.set_tooltip_text(tooltip_text) + _button.connect('clicked', _on_position_clicked, self, move, value) + return _button + + def _add_frame_position(self): + # init frame + self._frame_position = gtk.Frame(label=_('Position')) + self._frame_position.set_border_width(1) + # do add + self.main_box.pack_start(self._frame_position, expand=False, fill=True) + # _vbox + _in_vbox = gtk.VBox(homogeneous=False, spacing=4) + _in_vbox.set_border_width(4) + # first _row + _in_vbox.pack_start(self.__get_position_button('y_up_up', 'y', -10, + _('Move Up by 10%')), expand=False, fill=False) + # second _row + _in_vbox.pack_start(self.__get_position_button('y_up', 'y', -1, + _('Move Up by 1%')), expand=False, fill=False) + # third _row + _row3 = gtk.HBox(homogeneous=False, spacing=4) + _row3.pack_start(self.__get_position_button('x_left_left', 'x', -10, + _('Move Left by 10%')), expand=False, fill=True) + _row3.pack_start(self.__get_position_button('x_left', 'x', -1, + _('Move Left by 1%')), expand=False, fill=True) + # prepare middle box + _middle_box = gtk.VBox(homogeneous=True, spacing=4) + # get entries + _entry_box_x = ui.get_entry(label='X') + _entry_box_y = ui.get_entry(label='Y') + # update main vars + self.entry_x = _entry_box_x.get_children()[1] + self.entry_y = _entry_box_y.get_children()[1] + # add entries to the box + _middle_box.pack_start(_entry_box_x, expand=False, fill=True) + _middle_box.pack_start(_entry_box_y, expand=False, fill=True) + _middle_box.set_size_request(64, -1) + # add the box to the row + _row3.pack_start(_middle_box, expand=True, fill=True) + _row3.pack_start(self.__get_position_button('x_right', 'x', 1, + _('Move Right by 1%')), expand=False, fill=True) + _row3.pack_start(self.__get_position_button('x_right_right', 'x', 10, + _('Move Right by 10%')), expand=False, fill=True) + # and add the third row + _in_vbox.pack_start(_row3, expand=False, fill=False) + # fourth _row + _in_vbox.pack_start(self.__get_position_button('y_down', 'y', 1, + _('Move Down by 1%')), expand=False, fill=False) + # fifth _row + _in_vbox.pack_start(self.__get_position_button('y_down_down', 'y', 10, + _('Move Down by 10%')), expand=False, fill=False) + # 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() + # get img path + 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) + # create label + _label = gtk.Label(_('Repeat')) + _label.set_alignment(0, 0.5) + # add label + _loop_box.pack_start(_label, expand=True, fill=True) + # create checkbox + self.toggle_loop = gtk.ToggleButton() + # set tooltip + self.toggle_loop.set_tooltip_text(_('Loop (On/Off)')) + self.toggle_loop.add(_loop_box) + # set cb + self.toggle_loop.connect('toggled', _on_loop_click, self, + self.image_loop) + + def _add_frame_sound(self): + # init frame + self._frame_sound = gtk.Frame(label=_('Sound')) + 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) |