Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/atoidejouerbeta/ui/preview.py
diff options
context:
space:
mode:
Diffstat (limited to 'atoidejouerbeta/ui/preview.py')
-rw-r--r--atoidejouerbeta/ui/preview.py608
1 files changed, 608 insertions, 0 deletions
diff --git a/atoidejouerbeta/ui/preview.py b/atoidejouerbeta/ui/preview.py
new file mode 100644
index 0000000..9da2df6
--- /dev/null
+++ b/atoidejouerbeta/ui/preview.py
@@ -0,0 +1,608 @@
+
+# python import
+import logging, os, threading, time
+# ..
+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')
+
+
+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 _cb_on_click(button, sequence_preview, filename):
+ # update current
+ sequence_preview.set_current(filename)
+ # udpate preview
+ sequence_preview.screen.item_preview.set_item(filename)
+ # get current item pos
+ _pos = sequence_preview
+ # get toolbar frame entry
+ if sequence_preview.screen.toolbar._frame_entry is None:
+ pass
+ else:
+ # get current
+ _current = str(sequence_preview.get_current_pos())
+ # update toolbar entry
+ sequence_preview.screen.toolbar._frame_entry.set_text(_current)
+
+
+def _cb_on_remove(sequence_preview, filename, button):
+ # set current first
+ sequence_preview.set_current(filename)
+ # udpate sequence preview
+ sequence_preview.remove_current()
+ # seq name
+ _seq_name = sequence_preview.screen.notebook.current_sequence
+ # ..
+ _keys = sequence_preview.screen.toolbar.activity.graphic_keys\
+ if sequence_preview.screen.toolbar.name == 'graphics_add'\
+ else sequence_preview.screen.toolbar.activity.sound_keys
+ # remove from keys
+ _keys.remove_filename_from_all(_seq_name, filename)
+ # update sequence file
+ storage.sequence_save(sequence_preview.screen.toolbar)
+
+
+def _cb_on_move(sequence_preview, move, button):
+ # ..
+ _current = sequence_preview.get_current_pos()
+ if move == 'left':
+ _current -= 1
+ else:
+ _current += 1
+ # get max value
+ _max = sequence_preview.number_of_items() - 1
+ # prepare value
+ _new_val = None
+ if _current > _max:
+ _current = _max
+ elif _current < 0:
+ _current = 0
+ # reset max just in case
+ else:
+ pass
+ # update entry
+ if sequence_preview.screen.toolbar._frame_entry is None:
+ pass
+ else:
+ sequence_preview.screen.toolbar._frame_entry.set_text(str(_current))
+ # update sequence
+ sequence_preview.move_current(_current)
+
+
+def _set_preview_buttom_bg(button):
+ # set color
+ button.modify_bg(gtk.STATE_NORMAL, COLOR_GREY_LIGHT)
+ button.modify_bg(gtk.STATE_PRELIGHT, COLOR_GREY_WHITE)
+ button.modify_bg(gtk.STATE_ACTIVE, COLOR_WHITE)
+
+
+def _add_simple_button(parent, icon_name, tooltip, cb):
+ # .. remove button
+ _button = gtk.Button()
+ _button.show()
+ _button.set_tooltip_text(tooltip) # _('Remove ') + filename
+ # cb
+ _button.connect('clicked', cb) # cb, self, filename
+ # add
+ parent.pack_start(_button, expand=False, fill=False)
+ # add a remove image here
+ _img = gtk.Image()
+ _img.show()
+ _button.add(_img)
+ _button.set_size_request(30, 30)
+ # ..
+ _set_preview_buttom_bg(_button)
+ # get pixbuff and update image
+ _path = storage.get_icon_path(icon_name)
+ _img.set_from_pixbuf(image.get_pixbuf(_path, 24, 24))
+
+class SequencePreview(gtk.Frame):
+
+ def __init__(self, screen, type_):
+ # keep type
+ self._type = type_
+ # specific frame name
+ _frame_name = _('Sequence Graphics') if self._type=='graphics'\
+ else _('Sequence Sounds')
+ # init parent
+ gtk.Frame.__init__(self, _frame_name)
+ self.set_border_width(2)
+ self.set_size_request(-1, 140)
+ # do show
+ self.show()
+ # keep the screen
+ self.screen = screen
+ self._current = None
+ # keep item list for the sequence
+ self.items = list()
+ # prepare scrolled window
+ self._scrolled_window = gtk.ScrolledWindow()
+ self._scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
+ self._scrolled_window.show()
+ # a box
+ _hbox = gtk.HBox(homogeneous=False, spacing=2)
+ _hbox.show()
+ self.add(_hbox)
+ # .. move left button
+ _add_simple_button(_hbox, 'go_left', _('Move Before'),
+ partial(_cb_on_move, self, 'left'))
+ # a box
+ self._scrolled_hbox = gtk.HBox(homogeneous=False, spacing=2)
+ self._scrolled_hbox.show()
+ # add box in viewport
+ self._scrolled_window.add_with_viewport(self._scrolled_hbox)
+ # add
+ _hbox.add(self._scrolled_window)
+ # .. move left button
+ _add_simple_button(_hbox, 'go_right', _('Move After'),
+ partial(_cb_on_move, self, 'right'))
+
+ def clear(self):
+ # ...
+ self._current = None
+ # keep item list for the sequence
+ self.items = list()
+ # remove graphics
+ _children = self._scrolled_hbox.get_children()
+ for _c in _children:
+ _c.destroy()
+ # remove image from preview
+ self.screen.item_preview.unset_item()
+ # add box in viewport
+ self._scrolled_window.add_with_viewport(self._scrolled_hbox)
+
+ def move_current(self, new_pos):
+ # get current pos
+ _current_pos = self.get_current_pos()
+ # little check
+ _filename = None
+ if _current_pos == new_pos:
+ return
+ # remove current
+ else:
+ # update list
+ _filename = self.items.pop(_current_pos)
+ self.items.insert(new_pos, _filename)
+ # ..
+ self._scrolled_hbox.reorder_child(self._current, new_pos)
+
+ def get_current_pos(self):
+ # get children
+ _children = self._scrolled_hbox.get_children()
+ # get button index
+ return _children.index(self._current)\
+ if self._current in _children else 0
+
+ def set_current(self, filename):
+ # get children
+ _children = self._scrolled_hbox.get_children()
+ # get new idx index
+ _index = self.items.index(filename)\
+ if filename in self.items else 1000
+ # little check
+ if _index < len(_children):
+ # update current
+ self._current = _children[_index]
+ # update preview
+ self.screen.item_preview.set_item(filename)
+ # update toolbar frame entry
+ if self.screen.toolbar._frame_entry is None:
+ pass
+ else:
+ self.screen.toolbar._frame_entry.set_text(str(_index))
+ # ??
+ else:
+ pass
+
+ def number_of_items(self):
+ return len(self._scrolled_hbox.get_children())
+
+ def __remove(self, index):
+ # update list
+ if index + 1 <= len(self.items):
+ self.items.pop(index)
+ # clear current
+ self._current.destroy()
+ self._current = None
+ # remove image from preview
+ self.screen.item_preview.unset_item()
+ else:
+ pass
+
+ def remove_current(self):
+ # get button index
+ _index = self.get_current_pos()
+ # do remove
+ self.__remove(_index)
+
+ def remove_item(self, item_name):
+ # get children
+ _children = self._scrolled_hbox.get_children()
+ # get button index
+ _index = _children.index(item_name)\
+ if item_name in _children else 0
+ # do remove
+ self.__remove(_index)
+
+ def add_item(self, filename, pos=None):
+ # ..
+ _item_box = gtk.HBox(homogeneous=False, spacing=2)
+ _item_box.show()
+ self._scrolled_hbox.pack_start(_item_box, expand=False, fill=False)
+ # prepare vbox item
+ _vbox = gtk.VBox(homogeneous=False, spacing=2)
+ _vbox.show()
+ _item_box.pack_start(_vbox, expand=False, fill=False)
+ # ...
+ # simple add
+ if filename in self.items:
+ pass
+ elif pos is None:
+ # update list
+ self.items.append(filename)
+ # add at pos
+ else:
+ # insert filename
+ self.items.insert(pos, filename)
+ # second pass .. reorder
+ self._scrolled_hbox.reorder_child(_vbox, pos)
+ # init event box to manage color
+ _item = gtk.Button()
+ _vbox.pack_start(_item, expand=False, fill=True)
+ # ..
+ _set_preview_buttom_bg(_item)
+ # set size
+ _item.set_size_request(96, 78)
+ # set relief
+ _item.set_relief(gtk.RELIEF_NONE)
+ # cb
+ _item.connect('clicked', _cb_on_click, self, filename)
+ # ..
+ _item.show()
+ # add a picture here
+ _item_img = gtk.Image()
+ _item_img.show()
+ _item.add(_item_img)
+ # get graphics path
+ if self._type == 'graphics':
+ _path = storage.get_image_path(filename)
+ elif self._type == 'sounds':
+ _path = storage.get_image_path('sound', dir_='data')
+ # ?? do nothing - TODO maybe log something
+ else:
+ _path = storage.get_image_path('blank', dir_='data')
+ # get pixbuff and update image
+ _item_img.set_from_pixbuf(image.get_pixbuf(_path, 96, 62))
+ # add label
+ _label = gtk.Label(filename)
+ # ...
+ _label.show()
+ # ...
+ _vbox.pack_start(_label, expand=False, fill=True)
+ # .. remove button
+ _add_simple_button(_item_box, 'less_small', _('Remove ') + filename,
+ partial(_cb_on_remove, self, filename))
+ # set current file nam eat the end
+ self.set_current(filename)
+
+
+class ItemPreview(gtk.VBox):
+
+ def __init__(self, screen, type_=None):
+ # init parent
+ gtk.VBox.__init__(self, homogeneous=False, spacing=0)
+ # keep screen and type
+ self.screen = screen
+ self._type = type_
+ # ..
+ self._screen_height = gtk.gdk.screen_height() - 140
+ self._screen_width = gtk.gdk.screen_width() - 360
+ # update size request
+ self.set_size_request(self._screen_width, self._screen_height)
+ # show self
+ self.show()
+
+ def unset_item(self):
+ for _c in self.get_children():
+ _c.destroy()
+
+ def __set_image(self, path):
+ # eventbox for the background
+ _ebox_image = gtk.EventBox()
+ _ebox_image.modify_bg(gtk.STATE_NORMAL, COLOR_WHITE)
+ _ebox_image.show()
+ # add a picture here
+ _image = gtk.Image()
+ # show
+ _image.show()
+ # ..
+ _ebox_image.add(_image)
+ # get pixbuff
+ _pixbuf = image.get_pixbuf(path, self._screen_width,
+ self._screen_height)
+ # set image
+ _image.set_from_pixbuf(_pixbuf)
+ # ...
+ self.pack_start(_ebox_image, expand=True, fill=True)
+
+ def __set_label(self, filename):
+ # eventbox for the background
+ _ebox_label = gtk.EventBox()
+ _ebox_label.modify_bg(gtk.STATE_NORMAL, COLOR_GREY_DARK)
+ _ebox_label.set_size_request(-1, 24)
+ _ebox_label.show()
+ # add label
+ _label = gtk.Label('<b>%s</b>' % filename)
+ _label.set_property('use-markup', True)
+ _ebox_label.modify_bg(gtk.STATE_NORMAL, COLOR_WHITE)
+ # ...
+ _label.show()
+ # ...
+ _ebox_label.add(_label)
+ # ...
+ self.pack_start(_ebox_label, expand=False, fill=True)
+
+ def set_item(self, filename):
+ # get path
+ if self._type == 'graphics':
+ _path = storage.get_image_path(filename)
+ elif self._type == 'sounds':
+ _path = storage.get_image_path('sound', dir_='data')
+ else:
+ _path = storage.get_image_path('blank', dir_='data')
+ # little check
+ if os.path.exists(_path):
+ # unset first
+ self.unset_item()
+ # ..
+ self.__set_image(_path)
+ # ..
+ self.__set_label(filename)
+ # OK
+ return True
+ else:
+ return False
+
+
+class ImagePreview(ItemPreview):
+
+ def __init__(self, screen):
+ # init parent
+ ItemPreview.__init__(self, screen, type_='graphics')
+
+
+def _on_stop(widget, sound_view, filename):
+ # update playing flag
+ sound_view.playing = False
+ # thread update
+ sound_view._thread.pause(stop=True)
+
+
+def _on_play_pause(widget, sound_view, filename):
+ # update playing flag
+ sound_view.playing = not sound_view.playing
+ # thread update
+ if sound_view.playing is True:
+ sound_view._thread.play()
+ else:
+ sound_view._thread.pause()
+
+
+def _cb_slider(widget, event, sound_view):
+ """action = 'press' or 'release'
+ """
+ # ...
+ if event.type == gtk.gdk.BUTTON_PRESS:
+ sound_view._thread._set_value = False
+ elif event.type == gtk.gdk.BUTTON_RELEASE:
+ # get time
+ _time = widget.get_value()
+ # udpate thread time
+ sound_view._thread._time = _time
+ sound_view._thread._set_value = True
+ # seek player
+ sound_view.player.seek(_time)
+ # ??
+ else:
+ pass
+
+
+def _cb_format_value(widget, value, sound_view):
+ """Format the slider value to display
+ """
+ # return formated value
+ return '%1d:%02d' % divmod(value, 60)
+
+
+class ThreadPlayer(threading.Thread):
+
+ def __init__(self, sound_view, rate=1):
+ # init parent
+ threading.Thread.__init__(self)
+ # main flag
+ self._die = False
+ self._pause = True
+ self._set_value = True
+ # main vars
+ self.sound_view = sound_view
+ self._rate = rate
+ self._time = 0
+ self._max = 0
+ # start right now
+ self.start()
+
+ def set_max(self, max_):
+ self._max = max_
+
+ def pause(self, stop=False):
+ self._pause = True
+ # ..
+ self.sound_view.switch_button()
+ # ..
+ if self.sound_view._adjustment is None:
+ return
+ # reset time on stop
+ elif stop is True:
+ # reset time
+ self._time = 0
+ # update slider
+ self.sound_view._adjustment.set_value(0)
+ # stop player
+ self.sound_view.player.stop()
+ # ..
+ self.sound_view._slider.set_property('sensitive', False)
+ else:
+ # pause player
+ self.sound_view.player.pause()
+
+ def play(self):
+ self._pause = False
+ # pause player
+ self.sound_view.player.play()
+ # seek player
+ self.sound_view.player.seek(self._time)
+ # ..
+ self.sound_view.switch_button()
+ # ..
+ self.sound_view._slider.set_property('sensitive', True)
+
+ def kill(self):
+ # stop player
+ self.sound_view.player.stop()
+ # ..
+ self._die = True
+
+ def run(self):
+ # ...
+ while self._die is False:
+ # ...
+ time.sleep(self._rate)
+ if self._time >= self._max:
+ self.pause(stop=True)
+ # do pause
+ elif self._pause is False:
+ # just in case
+ self._time += self._rate
+ # ...
+ if self.sound_view._adjustment is None:
+ pass
+ # ...
+ elif self._set_value is True:
+ self.sound_view._adjustment.set_value(self._time)
+ else:
+ pass
+ # .. do nothing
+ else:
+ pass
+
+class SoundPreview(ItemPreview):
+
+ def __init__(self, screen):
+ # init parent
+ ItemPreview.__init__(self, screen, type_='sounds')
+ # ..
+ self.playing = False
+ # ..
+ self.player = sound.Player()
+ # ..
+ self._adjustment = None
+ self._slider = None
+ self._button_play = None
+ self._thread = ThreadPlayer(self)
+
+ def switch_button(self):
+ # image stuff
+ _img = gtk.Image()
+ _img.show()
+ # ..
+ _stock_id = 'pause' if self.playing is True else 'play'
+ # update image
+ _img.set_from_file(storage.get_icon_path(_stock_id))
+ # update button
+ if self._button_play is None:
+ pass
+ else:
+ self._button_play.set_image(_img)
+
+ def unset_item(self):
+ # call parent
+ ItemPreview.unset_item(self)
+ # stop player
+ self.player.stop()
+
+ def __set_slider(self, filename):
+ # eventbox for the background
+ _ebox_player = gtk.EventBox()
+ _ebox_player.modify_bg(gtk.STATE_NORMAL, COLOR_WHITE)
+ _ebox_player.show()
+ # init player row
+ _hbox = gtk.HBox(homogeneous=False, spacing=12)
+ _hbox.set_border_width(8)
+ _hbox.set_size_request(-1, 64)
+ # ..
+ _hbox.show()
+ # ..
+ _ebox_player.add(_hbox)
+ # add button stop
+ _button_stop = ui.get_button(stock_id='stop')
+ # set cb
+ _button_stop.connect('clicked', _on_stop, self, filename)
+ _button_stop.modify_bg(gtk.STATE_NORMAL, COLOR_WHITE)
+ # ..
+ _hbox.pack_start(_button_stop, expand=False, fill=True)
+ # add button play
+ self._button_play = ui.get_button(stock_id='play')
+ # set cb
+ self._button_play.connect('clicked', _on_play_pause, self, filename)
+ self._button_play.modify_bg(gtk.STATE_NORMAL, COLOR_WHITE)
+ # ..
+ _hbox.pack_start(self._button_play, expand=False, fill=True)
+ # add slider
+ _timedelta = self.player.get_duration()
+ self._adjustment = gtk.Adjustment(0, 0, _timedelta.seconds, 1)
+ # udpate max
+ self._thread.set_max(_timedelta.seconds)
+ # ..
+ self._slider = gtk.HScale(self._adjustment)
+ self._slider.set_draw_value(True)
+ self._slider.set_digits(False)
+ self._slider.set_update_policy(gtk.UPDATE_CONTINUOUS)
+ self._slider.set_property('sensitive', False)
+ # manage cb
+ self._slider.connect('button-press-event', _cb_slider, self)
+ self._slider.connect('button-release-event', _cb_slider, self)
+ self._slider.connect('format-value', _cb_format_value, self)
+ # show
+ self._slider.show()
+ # ..
+ _hbox.pack_start(self._slider, expand=True, fill=True)
+ # ...
+ self.pack_start(_ebox_player, expand=False, fill=True)
+
+ def set_item(self, filename):
+ # call parent
+ if ItemPreview.set_item(self, filename):
+ # get sound path
+ _soundfile = storage.get_sound_path(filename)
+ # load player
+ self.player.load(_soundfile)
+ # add player
+ self.__set_slider(filename)
+ else:
+ pass