Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/atoidejouerbeta/ui/toolbar.py
diff options
context:
space:
mode:
Diffstat (limited to 'atoidejouerbeta/ui/toolbar.py')
-rw-r--r--atoidejouerbeta/ui/toolbar.py721
1 files changed, 721 insertions, 0 deletions
diff --git a/atoidejouerbeta/ui/toolbar.py b/atoidejouerbeta/ui/toolbar.py
new file mode 100644
index 0000000..8103319
--- /dev/null
+++ b/atoidejouerbeta/ui/toolbar.py
@@ -0,0 +1,721 @@
+
+# python import
+import logging, os, re, shutil
+# ...
+from functools import partial
+from gettext import gettext as _
+
+# gtk import
+import gtk, glib
+
+# sugar import
+from sugar.activity import activity
+
+# sugar import
+from sugar.graphics.toolbutton import ToolButton
+
+# atoidejouerbeta import
+from atoidejouerbeta.tools import config, storage
+from atoidejouerbeta.ui import screens
+
+# get application logger
+logger = logging.getLogger('atoidejouerbeta')
+
+
+def _clean_dir(dir_path):
+ # little check first
+ if os.path.exists(dir_path):
+ pass
+ # ???
+ else:
+ return
+ # ..
+ for _filename in os.listdir(dir_path):
+ # ..
+ _path = os.path.join(dir_path, _filename)
+ # little check
+ if os.path.isfile(_path):
+ os.remove(_path)
+ elif os.path.isdir(_path):
+ _clean_dir(_path)
+ else:
+ # ERRROR
+ logger.error('[toolbar] _clean_dir - path error: %s' % dir_path)
+ # remove dir at the end
+ os.removedirs(dir_path)
+
+
+def _cb_seq_new(widget, toolbar):
+ # get screen
+ _screen = toolbar.activity.get_current_screen()
+ # remove items from preview boxes
+ _screen.sequence_preview.clear()
+ # ..
+ _screen.notebook.current_sequence = None
+ # clear entry
+ toolbar._sequence_entry.set_text("")
+
+
+NON_ALPHA_NUM_PATTERN = re.compile('[\W_]+')
+
+
+def _cb_seq_name(entry):
+ # ensure good string
+ _str = NON_ALPHA_NUM_PATTERN.sub('-', entry.get_text())
+ # update entry
+ entry.set_text(_str)
+
+
+def _cb_seq_remove(widget, toolbar):
+ # get sequence name
+ _name = toolbar._sequence_entry.get_text()
+ # get screen
+ _screen = toolbar.activity.get_current_screen()
+ # type shortcut 'graphic' or 'sound'
+ _type = _screen.notebook._type
+ # little check
+ if _name.strip() == '':
+ # do nothing
+ pass
+ else:
+ # get sequence path
+ _seq_path = storage.get_sequence_path(_type, _name)
+ # remove dir
+ if os.path.exists(_seq_path):
+ # do clean
+ os.remove(_seq_path)
+ # and clear all at the end
+ _screen.sequence_preview.clear()
+ # clear entry
+ toolbar._sequence_entry.set_text("")
+ # update notebook
+ _screen.notebook._get_store_sequence()
+ # update focus
+ _screen.notebook.focus_current_seq()
+ # nothing to do
+ else:
+ pass
+
+
+def _cb_seq_save(widget, toolbar, remove=False):
+ storage.sequence_save(toolbar, remove=remove)
+ # get screen
+ _screen = toolbar.activity.get_current_screen()
+ # get sequence name
+ _name = toolbar._sequence_entry.get_text()
+ # update focus
+ _screen.notebook.focus_current_seq(name=_name)
+
+
+
+def _show_browser(toolbar, cls):
+ # next screen name
+ _screen_name = '%s_add' % toolbar.name
+ # do switch
+ toolbar._switch(_screen_name)
+ # get or create screen
+ _screen = toolbar.activity.get_screen(_screen_name)\
+ if toolbar.activity.has_screen(_screen_name)\
+ else cls(toolbar)
+ # update activity screens
+ toolbar.activity.set_current_screen(_screen_name, _screen)
+ # do show
+ _screen._show()
+ # update entry
+ _seq_name = _screen.notebook.current_sequence
+ if _seq_name is None:
+ pass
+ else:
+ # ..
+ toolbar._sequence_entry.set_text(_seq_name)
+ # pos
+ _current_pos = _screen.sequence_preview.get_current_pos()
+ # ..
+ if toolbar._frame_entry is None:
+ pass
+ else:
+ toolbar._frame_entry.set_text(str(_current_pos))
+
+
+def _cb_add(widget, toolbar):
+ # browser screen factory
+ if toolbar.name == 'graphics':
+ _show_browser(toolbar, screens.ScreenBrowserGraphics)
+ # ..
+ elif toolbar.name == 'sounds':
+ _show_browser(toolbar, screens.ScreenBrowserSounds)
+ # ??
+ else:
+ # ERROR
+ logger.error('[toolbar] _cb_add - unknown: %s' % toolbar.name)
+
+
+def _cb_remove(widget, toolbar):
+ # browser screen factory
+ if toolbar.name == 'graphics':
+ pass
+ # ..
+ elif toolbar.name == 'sounds':
+ pass
+ # ??
+ else:
+ # ERROR
+ logger.error('[toolbar] _cb_remove - name: %s' % toolbar.name)
+
+
+def _cb_frame_after(widget, toolbar):
+ if toolbar._frame_entry is None:
+ pass
+ else:
+ # get previous value
+ _value = int(toolbar._frame_entry.get_text())
+ # inc it
+ _update_frame_entry(widget, toolbar, _value + 1)
+ # update sequence file
+ _cb_seq_save(widget, toolbar)
+
+
+def _cb_frame_before(widget, toolbar):
+ if toolbar._frame_entry is None:
+ pass
+ else:
+ # get previous value
+ _value = int(toolbar._frame_entry.get_text())
+ # dec it
+ _update_frame_entry(widget, toolbar, _value - 1)
+ # update sequence file
+ _cb_seq_save(widget, toolbar)
+
+
+def _update_frame_entry(entry, toolbar, value):
+ # get screen
+ _screen = toolbar.activity.get_current_screen()
+ # get max value
+ _max = _screen.sequence_preview.number_of_items() - 1
+ # prepare value
+ _new_val = None
+ if value > _max:
+ _new_val = _max
+ elif value < 0:
+ _new_val = 0
+ # reset max just in case
+ else:
+ _new_val = value
+ # update entry
+ toolbar._frame_entry.set_text(str(_new_val))
+ # update sequence
+ _screen.sequence_preview.move_current(_new_val)
+
+
+def _cb_open(widget, toolbar):
+ pass
+
+
+def _cb_back(widget, toolbar):
+ # do switch
+ toolbar._switch(toolbar.name.replace('_add', ''))
+ # restore screen
+ toolbar.activity._change_screen(toolbar)
+ # get screen now
+ _screen = toolbar.activity.get_current_screen()
+ _screen.scene.refresh()
+
+
+def _cb_import(widget, toolbar):
+ # get the current sequence name
+ _sequence_name = toolbar._sequence_entry.get_text()
+ # get filenames
+ _screen = toolbar.activity.get_current_screen()
+ # shortcut
+ _filenames = _screen.sequence_preview.items
+ # add sequence to the story keys
+ if toolbar.story_keys.add_sequence(_sequence_name, _filenames):
+ # screen name factory
+ _screen_name = toolbar.name.replace('_add', '')
+ # get screen now
+ _screen = toolbar.activity.get_screen(_screen_name)
+ # add sequence to the timeline
+ _screen.timeline.add_sequence(_sequence_name)
+ # already added
+ else:
+ pass
+
+
+def _cb_play(widget, toolbar):
+ # replace play button
+ toolbar._replace_button('play', 'pause')
+ # trigger playing
+ toolbar.activity._thread.play()
+
+
+def _cb_pause(widget, toolbar):
+ # replace pause button
+ toolbar._replace_button('pause', 'play')
+ # trigger pausing
+ toolbar.activity._thread.pause()
+
+
+def _cb_stop(widget, toolbar):
+ # replace pause button - if playing
+ if toolbar._has_button('pause'):
+ # ..
+ toolbar._replace_button('pause', 'play')
+ else:
+ pass
+ # update main thread
+ toolbar.activity._thread.pause(stop=True)
+ # ..
+ toolbar.activity._thread.set_time()
+
+
+def _cb_view_fullscreen(widget, toolbar):
+ # replace fullscreen button with return button
+ toolbar._replace_button('view_fullscreen', 'view_return')
+ # ask_clear
+ toolbar.story_keys.ask_clear()
+ # get current screen
+ _screen = toolbar.activity.get_current_screen()
+ # enbale fullscreen
+ _screen.set_fullscreen(True)
+
+
+def _cb_view_return(widget, toolbar):
+ # remove return button with fullscreen button
+ toolbar._replace_button('view_return', 'view_fullscreen')
+ # ask_clear
+ toolbar.story_keys.ask_clear()
+ # get current screen
+ _screen = toolbar.activity.get_current_screen()
+ # disable fullscreen
+ _screen.set_fullscreen(False)
+
+
+def _cb_slider(widget, event, toolbar):
+ """action = 'press' or 'release'
+ """
+ # ...
+ if event.type == gtk.gdk.BUTTON_PRESS:
+ pass
+ elif event.type == gtk.gdk.BUTTON_RELEASE:
+ toolbar.activity._thread.set_time(time_=widget.get_value())
+ # ??
+ else:
+ pass
+
+
+def _cb_format_value(widget, value, toolbar):
+ """Format the slider value to display
+ """
+ # return formated value
+ return '%1d:%02d' % divmod(value, 60)
+
+TOOLBAR_INDEXES = ['activity', 'story', 'graphics', 'sounds', 'help']
+
+def _cb_help_back(widget, toolbar):
+ _previous = toolbar.activity._previous
+ # restore default tab
+ toolbar.activity._toolbox.set_current_toolbar(
+ TOOLBAR_INDEXES.index(_previous.replace('_add', '')))
+ # restore previous
+ toolbar.activity._change_screen(name=_previous)
+
+
+BUTTONS = {
+ 'add' : ['list-add', _cb_add],
+ 'back' : ['edit-undo', _cb_back],
+ 'backward' : ['media-seek-backward', None],
+ 'forward' : ['media-seek-forward', None],
+ 'frame_after' : ['go-right', _cb_frame_after],
+ 'frame_before' : ['go-left', _cb_frame_before],
+ 'frame_entry' : [None, None],
+ 'help_back' : ['edit-undo', _cb_help_back],
+ 'import' : ['insert-image', _cb_import],
+ 'open' : ['media', _cb_open],
+ 'pause' : ['media-playback-pause', _cb_pause],
+ 'play' : ['media-playback-start', _cb_play],
+ 'remove' : ['list-remove', _cb_remove],
+ 'separator' : [None, None],
+ 'seq_new' : ['document-generic', _cb_seq_new],
+ 'seq_name' : [None, _cb_seq_name],
+ 'seq_remove' : ['button_cancel', _cb_seq_remove],
+ 'seq_save' : ['dialog-apply', _cb_seq_save],
+ 'slider' : [None, _cb_slider],
+ 'stop' : ['media-playback-stop', _cb_stop],
+ 'view_fullscreen' : ['view-fullscreen', _cb_view_fullscreen],
+ 'view_return' : ['view-return', _cb_view_return],
+ }
+
+TOOLBARS = {
+ 'graphics' : [
+ ['stop', 'play', 'slider', # 'backward', 'forward'
+ 'separator',
+ 'add'],
+ []
+ ],
+ 'graphics_add' : [
+ ['seq_new', 'seq_name', 'seq_save', 'seq_remove',
+ # 'separator',
+ # 'add', 'remove',
+ # ''separator',
+ # 'frame_before', 'frame_entry', 'frame_after'
+ ],
+ ['import', 'back']
+ ],
+ 'sounds' : [
+ ['stop', 'play', 'slider', # 'backward', 'forward'
+ 'separator',
+ 'add'],
+ []
+ ],
+ 'sounds_add' : [
+ ['seq_new', 'seq_name', 'seq_save', 'seq_remove',
+ # 'separator',
+ # 'add', 'remove',
+ # ''separator',
+ # 'frame_before', 'frame_entry', 'frame_after'
+ ],
+ ['import', 'back']
+ ],
+ 'story' : [
+ ['stop', 'play', 'slider', # 'backward', 'forward'
+ 'separator',
+ 'view_fullscreen'],
+ []
+ ],
+ 'help' : [
+ [],
+ ['help_back']
+ ]
+ }
+
+TITLES = {
+ 'graphics' : {
+ 'toolbox': _('Graphic'),
+ 'buttons': {
+ # 'backward': _('Seek Backward'),
+ # 'forward': _('Seek Forward'),
+ 'pause': _('Pause Story'),
+ 'play': _('Play Story'),
+ 'slider': _('Progress Bar'),
+ 'stop': _('Stop Story'),
+ 'add': _('Add Graphic'),
+ }
+ },
+ 'graphics_add' : {
+ 'toolbox': None,
+ 'buttons': {
+ 'add': _('Add Graphic'),
+ 'back': _('Back'),
+ 'frame_after': _('Frame Before'),
+ 'frame_before': _('Frame After'),
+ 'frame_entry': None,
+ 'import': _('Import Sequence'),
+ 'remove': _('Remove Graphic'),
+ 'seq_new': _('New Sequence'),
+ 'seq_name': None,
+ 'seq_remove': _('Remove Sequence'),
+ 'seq_save': _('Save Sequence'),
+ }
+ },
+ 'sounds' : {
+ 'toolbox': _('Sound'),
+ 'buttons': {
+ # 'backward': _('Seek Backward'),
+ # 'forward': _('Seek Forward'),
+ 'pause': _('Pause Story'),
+ 'play': _('Play Story'),
+ 'slider': _('Progress Bar'),
+ 'stop': _('Stop Story'),
+ 'add': _('Add Sound'),
+ }
+ },
+ 'sounds_add' : {
+ 'toolbox': None,
+ 'buttons': {
+ 'add': _('Add Sound'),
+ 'back': _('Back'),
+ 'frame_after': _('Frame Before'),
+ 'frame_before': _('Frame After'),
+ 'frame_entry': None,
+ 'import': _('Import Sequence'),
+ 'remove': _('Remove Sound'),
+ 'seq_new': _('New Sound'),
+ 'seq_name': None,
+ 'seq_remove': _('Remove Sequence'),
+ 'seq_save': _('Save Sequence'),
+ }
+ },
+ 'story' : {
+ 'toolbox': _('Story'),
+ 'buttons': {
+ # 'open': _('Open Story'),
+ # 'backward': _('Seek Backward'),
+ # 'forward': _('Seek Forward'),
+ 'pause': _('Pause Story'),
+ 'play': _('Play Story'),
+ 'slider': _('Progress Bar'),
+ 'stop': _('Stop Story'),
+ 'view_fullscreen': _('Fullscreen'),
+ 'view_return': _('Default Screen'),
+ }
+ },
+ 'help' : {
+ 'toolbox': _('Help'),
+ 'buttons': {
+ 'help_back': _('Back')
+ }
+ }
+ }
+
+
+class Toolbar(gtk.Toolbar):
+
+ def __init__(self, activity, name='player'):
+ # init parent
+ gtk.Toolbar.__init__(self)
+ # keep the name
+ self.set_name(name)
+ # keep activity
+ self.activity = activity
+ # ..
+ if self.name == 'graphics'\
+ or self.name == 'story':
+ self.story_keys = self.activity.graphic_keys
+ else:
+ self.story_keys = self.activity.sound_keys
+ # adjustment
+ self._adjustment = None
+ self._number_of_keys = self.activity._number_of_keys
+ # keep components
+ self._sequence_entry = None
+ self._frame_entry = None
+ # init widget dict
+ self._button_dict = dict()
+ # init buttons
+ self._init_buttons()
+ # add tab in toolbox
+ _toolbox_name = TITLES[self.name]['toolbox']
+ if _toolbox_name is None:
+ pass
+ else:
+ _toolbox = self.activity.get_toolbox()
+ _toolbox.add_toolbar(_toolbox_name, self)
+ # connect focus event
+ self.connect('focus', self._on_focus)
+ # show
+ self.show()
+
+ def _switch(self, name):
+ # update toolbar
+ self._clear_buttons()
+ # switch name
+ self.set_name(name)
+ # reset
+ self._init_buttons()
+
+ def _clear_buttons(self):
+ # remove all
+ for _k in self._button_dict.keys():
+ self._remove_button(_k)
+ # remove separators
+ for _c in self.get_children():
+ # remove it
+ self.remove(_c)
+ # and destroy it
+ _c.destroy()
+
+ def _init_buttons(self):
+ # add buttons
+ _b_left, _b_right = TOOLBARS[self.name]
+ # place left buttons
+ for _b in _b_left:
+ # add button
+ self._add_button(_b)
+ # add expanded separator
+ _separator = gtk.SeparatorToolItem()
+ _separator.set_draw(False)
+ _separator.set_expand(True)
+ _separator.show()
+ self.add(_separator)
+ # place right buttons
+ for _b in _b_right:
+ # add button
+ self._add_button(_b)
+
+ def update_slider(self, time_, pause):
+ # get slider
+ _s = self.get_slider()
+ # slider stuff
+ if _s is None:
+ pass
+ else:
+ _s.set_value(time_)
+ # update pause status
+ if pause is True:
+ self._replace_button('pause', 'play')
+ else:
+ self._replace_button('play', 'pause')
+
+ def get_slider(self):
+ # little check
+ if 'slider' in self._button_dict:
+ _children = self._button_dict['slider'].get_children()
+ return None if len(_children) == 0 else _children[0]
+ else:
+ return None
+
+ def play(self):
+ # do pause
+ _cb_play(None, self)
+
+ def pause(self):
+ # do pause
+ _cb_pause(None, self)
+
+ def refresh(self, value):
+ # ...
+ if self._number_of_keys != self.activity._number_of_keys:
+ # update nb of keys
+ self._number_of_keys = self.activity._number_of_keys
+ # update adjustment
+ if hasattr(self._adjustment, 'set_upper'):
+ self._adjustment.set_upper(self._number_of_keys-1)
+ else:
+ self._adjustment.upper = self._number_of_keys-1
+ else:
+ pass
+ # get slider
+ _s = self.get_slider()
+ # slider stuff
+ if _s is None:
+ # just in case
+ value = 0
+ else:
+ # update value
+ _s.set_value(int(value))
+ # return _v to keep time value in thread
+ return value
+
+ def _on_focus(self, widget, direction):
+ if self.name in ['graphics_add', 'sounds_add']:
+ self._switch(self.name.replace('_add', ''))
+ else:
+ # update current screen
+ self.activity._change_screen(self)
+ if 'add' in self._button_dict:
+ # enable or disble add
+ _mode = config.Config().get('activity>mode')
+ _conf = config.Config().get('mode>%s' % _mode, type_=list)
+ # ..
+ self._button_dict['add'].set_sensitive('remove' in _conf)
+ else:
+ pass
+
+ def _has_button(self, button_id):
+ return button_id in self._button_dict
+
+ def _add_button(self, button_id, index=None):
+ # get button icon and cb
+ _icon, _cb = BUTTONS[button_id]
+ # manage separator
+ if button_id == 'separator':
+ _buton = gtk.SeparatorToolItem()
+ _buton.set_draw(True)
+ # manage slider
+ elif button_id == 'slider':
+ #
+ self._adjustment = gtk.Adjustment(0, 0, self._number_of_keys-1, 1)
+ # ..
+ _hscale = gtk.HScale(self._adjustment)
+ _hscale.set_draw_value(True)
+ _hscale.set_digits(False)
+ _hscale.set_update_policy(gtk.UPDATE_CONTINUOUS)
+ # manage cb
+ _hscale.connect('button-release-event', _cb, self)
+ _hscale.connect('format-value', _cb_format_value, self)
+ # show
+ _hscale.show()
+ # ..
+ _buton = gtk.ToolItem()
+ _buton.set_expand(True)
+ _buton.add(_hscale)
+ elif button_id == 'seq_name':
+ self._sequence_entry = gtk.Entry()
+ # show
+ self._sequence_entry.show()
+ # ..
+ self._sequence_entry.connect('changed', _cb)
+ # ..
+ _buton = gtk.ToolItem()
+ _buton.set_expand(True)
+ _buton.add(self._sequence_entry)
+ elif button_id == 'frame_entry':
+ # ...
+ self._frame_entry = gtk.Entry()
+ # ..
+ self._frame_entry.set_editable(False)
+ self._frame_entry.set_width_chars(2)
+ self._frame_entry.set_size_request(44, -1)
+ # set value
+ self._frame_entry.set_text('0')
+ # center text
+ self._frame_entry.set_alignment(1)
+ # show
+ self._frame_entry.show()
+ # ..
+ _buton = gtk.ToolItem()
+ _buton.add(self._frame_entry)
+ # standard button
+ elif button_id in BUTTONS:
+ # get tooltip
+ _tooltip = TITLES[self.name]['buttons'][button_id]
+ # set icon
+ _buton = ToolButton(_icon)
+ # set tooltip
+ _buton.set_tooltip(_tooltip)
+ # do connect
+ if _cb is None:
+ pass
+ else:
+ _buton.connect('clicked', _cb, self)
+ # ??
+ else:
+ # ERROR
+ logger.error('[toolbar] _add_button - ??: %s' % button_id)
+ return
+ # update the button dict
+ self._button_dict[button_id] = _buton
+ # add to the toolbar
+ if index is None:
+ self.add(_buton)
+ else:
+ self.insert(_buton, index)
+ # show it
+ _buton.show()
+
+ def _remove_button(self, button_id):
+ # little check
+ if button_id in self._button_dict:
+ # get button
+ _buton = self._button_dict.pop(button_id)
+ # do remove - do it safe
+ glib.idle_add(partial(self.remove, _buton))
+ # and destroy - safe
+ glib.idle_add(_buton.destroy)
+ # ??
+ else:
+ # ERROR
+ logger.error('[toolbar] _remove_button - unknown: %s' % button_id)
+
+ def _replace_button(self, button_id_out, button_id_in):
+ # little check
+ if button_id_out in self._button_dict:
+ # ...
+ _index = self.get_item_index(self._button_dict[button_id_out])
+ # do remove
+ self._remove_button(button_id_out)
+ # do it safe
+ glib.idle_add(partial(self._add_button, button_id_in, _index))
+ # ??
+ else:
+ pass