Ejemplo n.º 1
0
 def add_card_spark(self, card, start_pos, end_pos, size, dt=1.0, grow=False, dim=2):
     spark = Image(card._texture, pos=start_pos)
     spark._pos.set_transition(dt=dt, method="ease_in") #ease_out_back")
     spark.pos = end_pos
     spark.visible = anim.animate(1., 0., dt=dt, method="step")
     if grow: spark.scale = anim.animate(0.1, size, dt=dt, method="sine")
     else: spark.scale = anim.animate(1.5, size, dt=dt, method="sine")
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
Ejemplo n.º 2
0
    def __init__(self, pos=zero, is_opponent=False):
        super(StatusView,self).__init__(pos)
        self._toggled = False
        self._spacing = 10
        self._reveal_library = False
        self.color = (0.5, 0.5, 0.5)
        self.is_opponent = is_opponent
        #self._pos.set_transition(dt=0.1, method="linear")
        #symbols = ["life", "library", "hand", "graveyard", "exile"]
        symbols = ["life", "hand", "library", "graveyard", "exile"]
        self.symbols = dict([(symbol, cls(symbol)) for symbol, cls in zip(symbols, [Image, Image, Image, Image, Image])])
        for symbol in self.symbols.values():
            symbol.alpha = 0.8
        self.player_name = Label("", 11, halign="left", fontname = "Arial Bold", valign="center", shadow=False)
        #sizes = [20, 16, 14, 14, 14]
        sizes = [20, 14, 14, 14, 14]
        self.values = dict([(symbol, Label('', size, fontname = "Arial Bold", halign="center", valign="center", shadow=False)) for symbol, size in zip(symbols, sizes)])
        #for val in self.values.values():
        self.avatar = Image(pyglet.image.Texture.create(80,80))
        self.avatar.shaking = 0
        self.avatar.alpha = anim.animate(1., 1., dt=0.25)
        self.alpha = anim.animate(1., 1., dt=0.25)

        self.manapool = ManaPool(is_opponent)
        self.zone_view = ZoneView()
        self._library = LibraryImage(is_opponent)
        self.width, self.height = 145,135
Ejemplo n.º 3
0
 def add_star_spark(self, start_pos, end_pos, dt=1.0, color=None, start_size=0.2, end_size=2.0, dim=2):
     spark = Image('targeting', pos=start_pos)
     if color == None: spark.color = (1.0, 1.0, 1.0)
     elif isinstance(color, str):
         spark.color = self.COLORS.get(color)
     else: spark.color = color
     spark.visible = anim.animate(1., 0., dt=dt)
     spark.rotatez = anim.animate(15, -45, dt=dt, method="sine")
     spark.scale = anim.animate(start_size, end_size, dt=dt, method="sine")
     spark.alpha = anim.animate(1.0, 0., dt=dt)
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
Ejemplo n.º 4
0
 def add_spark(self, start_pos, end_pos, dt=1.0, color=None, grow=False, dim=2):
     spark = Image("glow", pos=start_pos)
     spark._pos.set_transition(dt=dt, method="ease_out_circ") #ease_out_back")
     spark.pos = end_pos
     if color == None: spark.color=(1.,1.,1.)
     elif isinstance(color, str):
         spark.color = self.COLORS.get(color)
     else: spark.color = color
     spark.visible = anim.animate(1., 0., dt=dt)
     if grow: spark.scale = anim.animate(0.5, 2.0, dt=dt, method="sine")
     else: spark.scale = anim.animate(2.0, 0.2, dt=dt, method="sine")
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
Ejemplo n.º 5
0
    def __init__(self, pos=zero, is_opponent=False):
        super(StatusView, self).__init__(pos)
        self._toggled = False
        self._spacing = 10
        self._reveal_library = False
        self.color = (0.5, 0.5, 0.5)
        self.is_opponent = is_opponent
        #self._pos.set_transition(dt=0.1, method="linear")
        #symbols = ["life", "library", "hand", "graveyard", "exile"]
        symbols = ["life", "hand", "library", "graveyard", "exile"]
        self.symbols = dict([(symbol, cls(symbol)) for symbol, cls in zip(
            symbols, [Image, Image, Image, Image, Image])])
        for symbol in self.symbols.values():
            symbol.alpha = 0.8
        self.player_name = Label("",
                                 11,
                                 halign="left",
                                 fontname="Arial Bold",
                                 valign="center",
                                 shadow=False)
        #sizes = [20, 16, 14, 14, 14]
        sizes = [20, 14, 14, 14, 14]
        self.values = dict([(symbol,
                             Label('',
                                   size,
                                   fontname="Arial Bold",
                                   halign="center",
                                   valign="center",
                                   shadow=False))
                            for symbol, size in zip(symbols, sizes)])
        #for val in self.values.values():
        self.avatar = Image(pyglet.image.Texture.create(80, 80))
        self.avatar.shaking = 0
        self.avatar.alpha = anim.animate(1., 1., dt=0.25)
        self.alpha = anim.animate(1., 1., dt=0.25)

        self.manapool = ManaPool(is_opponent)
        self.zone_view = ZoneView()
        self._library = LibraryImage(is_opponent)
        self.width, self.height = 145, 135
Ejemplo n.º 6
0
 def add_star_spark(self,
                    start_pos,
                    end_pos,
                    dt=1.0,
                    color=None,
                    start_size=0.2,
                    end_size=2.0,
                    dim=2):
     spark = Image('targeting', pos=start_pos)
     if color == None: spark.color = (1.0, 1.0, 1.0)
     elif isinstance(color, str):
         spark.color = self.COLORS.get(color)
     else:
         spark.color = color
     spark.visible = anim.animate(1., 0., dt=dt)
     spark.rotatez = anim.animate(15, -45, dt=dt, method="sine")
     spark.scale = anim.animate(start_size, end_size, dt=dt, method="sine")
     spark.alpha = anim.animate(1.0, 0., dt=dt)
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
Ejemplo n.º 7
0
 def add_spark(self,
               start_pos,
               end_pos,
               dt=1.0,
               color=None,
               grow=False,
               dim=2):
     spark = Image("glow", pos=start_pos)
     spark._pos.set_transition(dt=dt,
                               method="ease_out_circ")  #ease_out_back")
     spark.pos = end_pos
     if color == None: spark.color = (1., 1., 1.)
     elif isinstance(color, str):
         spark.color = self.COLORS.get(color)
     else:
         spark.color = color
     spark.visible = anim.animate(1., 0., dt=dt)
     if grow: spark.scale = anim.animate(0.5, 2.0, dt=dt, method="sine")
     else: spark.scale = anim.animate(2.0, 0.2, dt=dt, method="sine")
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
Ejemplo n.º 8
0
 def __init__(self, pos=zero):
     super(PhaseStatus, self).__init__(pos)
     self.visible = anim.constant(0)
     states = [('Untap', 'Untap'), ('Upkeep', 'Upkeep'), ('Draw', 'Draw'),
               ('Main1', 'Main 1'), ('BeginCombat', 'Beginning of combat'),
               ('Attack', 'Declare attackers'),
               ('Block', 'Declare blockers'), ('Damage', 'Combat damage'),
               ('EndCombat', 'End of combat'), ('Main2', 'Main 2'),
               ('EndStep', 'End Step'), ('Cleanup', 'Cleanup')]
     self.state_list = [s.lower() for s, t in states]
     self.grouping = [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0]
     self.state_map = dict([(key, (i, val))
                            for i, (key, val) in enumerate(states)])
     self.states = [Image(key) for key, val in states]
     self.state_labels = [
         Label(val, size=20, valign="center", shadow=False)
         for key, val in states
     ]
     self.state_text = None
     for state in self.states:
         state.visible = anim.constant(1.0)
         state.alpha = anim.animate(1.0,
                                    1.0,
                                    dt=0.5,
                                    method="ease_out_circ")  ##sine")
         state.scale = anim.animate(1.0, 1.0, dt=0.5, method="sine")
         state._pos.set_transition(dt=0.5, method="sine")
     for label in self.state_labels:
         label.scale = 0.8
         label._pos.y = anim.constant(
             -100)  # This is just a hack to hide it
     self.width = state.width
     self.current = 0
     self.select = False
     self.curr_player = None
     self.turn_label = Label("",
                             size=24,
                             halign="center",
                             valign="top",
                             shadow=False)
     self.render_after_transform = self.render_game
     self.set_stops()
Ejemplo n.º 9
0
 def add_card_spark(self,
                    card,
                    start_pos,
                    end_pos,
                    size,
                    dt=1.0,
                    grow=False,
                    dim=2):
     spark = Image(card._texture, pos=start_pos)
     spark._pos.set_transition(dt=dt, method="ease_in")  #ease_out_back")
     spark.pos = end_pos
     spark.visible = anim.animate(1., 0., dt=dt, method="step")
     if grow: spark.scale = anim.animate(0.1, size, dt=dt, method="sine")
     else: spark.scale = anim.animate(1.5, size, dt=dt, method="sine")
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
Ejemplo n.º 10
0
 def add_sparkle_star(self, start_pos, end_pos, dt=1.0, color=None, dim=2):
     if color == None: color = (1., 0.9, 0)
     elif isinstance(color, str): color = self.COLORS.get(color)
     else: color = color
     spark = Image('targeting', pos=start_pos)
     spark.visible = anim.animate(1., 0., dt=dt)
     spark.rotatez = anim.animate(15, -45, dt=dt, method="sine")
     spark.scale = anim.animate(0.2, 1.5, dt=dt, method="sine")
     spark.color = color
     spark.alpha = anim.animate(1.0, 0., dt=dt)
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
     dt = 0.75 * dt
     spark = Image('glow', pos=start_pos)
     spark._pos.set_transition(dt=dt, method="ease_out_circ")
     spark.pos = end_pos
     spark.color = color
     spark.visible = anim.animate(1., 0., dt=dt)
     spark.alpha = anim.animate(1.0, 0., dt=dt)
     spark.scale = anim.animate(0.5, 1.5, dt=dt, method="sine")
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
Ejemplo n.º 11
0
    def initUI(self):
        config = Foo.readConfig('options')
        self.timeOut = -1
        self.radio = False
        self.statusBar().showMessage('Ready')
        self.createMenu()
        self.setWindowTitle("Foo.cd")

        self.player = Player(Foo.readConfig('audio'))
        self.player.bus.connect('message::eos', self.stop)
        self.player.bus.connect('message::duration-changed',
                                self.onDurationChanged)

        self.tree = Tree(self, config['tree_order'])
        self.tree.addSongs.connect(self.addSongsFromTree)
        self.tree.customContextMenuRequested.connect(self.tmpTag)

        if not self.radio:
            self.table = Table(self, config)
            self.handlerATF = self.player.playbin.connect(
                "about-to-finish", self.onAboutToFinish)
            self.table.runAction.connect(self.tableAction)
        else:
            configRadio = Foo.readConfigRadios()
            self.table = TableRadio(self, configRadio)
            self.table.runAction.connect(self.tableAction)
            self.handlerT = self.player.bus.connect('message::tag',
                                                    self.table.onTag)

        self.playbackButtons = PlaybackButtons(None)
        self.playbackButtons.buttonPlay.clicked.connect(self.toggleSong)
        self.playbackButtons.buttonStop.clicked.connect(self.stop)
        self.playbackButtons.buttonPrev.clicked.connect(self.previous)
        self.playbackButtons.buttonNext.clicked.connect(self.next)

        self.volumeSlider = VolumeSlider(self)
        self.volumeSlider.sliderMoved.connect(self.player.setVolume)
        self.scrollSlider = ScrollSlider(self)
        self.scrollSlider.sliderPressed.connect(self.player.toggle)
        self.scrollSlider.sliderReleased.connect(self.player.toggle)
        self.scrollSlider.sliderMoved.connect(self.player.seek)

        self.pixmap = Image(self, config['cover_names'], config['extensions'])

        # Album cover connections
        self.tree.selectionModel().selectionChanged.connect(
            lambda: self.pixmap.onSelectionChanged(self.tree.getChildren()[0].
                                                   get('file', None)))
        self.table.selectionModel().selectionChanged.connect(
            lambda: self.pixmap.onSelectionChanged(self.table.getSelection().
                                                   get('file', None)))

        self.searchArea = SearchArea(self)
        self.searchArea.searchLine.returnPressed.connect(self.startSearch)

        self.playbackButtons.addWidget(self.volumeSlider)
        self.playbackButtons.addWidget(self.scrollSlider)

        splitterLeftRight = QtGui.QSplitter()
        self.splitterTopBottom = QtGui.QSplitter(Qt.Vertical, self)

        self.infoFrame = QtGui.QFrame()
        infoLayout = QtGui.QVBoxLayout()
        infoLayout.setContentsMargins(0, 0, 0, 0)
        infoLayout.addLayout(self.playbackButtons)
        infoLayout.addWidget(self.pixmap)
        self.infoFrame.setLayout(infoLayout)

        libLayout = QtGui.QVBoxLayout()
        libLayout.setContentsMargins(0, 0, 0, 0)
        libLayout.addWidget(self.tree)
        libLayout.addLayout(self.searchArea)
        libFrame = QtGui.QFrame()
        libFrame.setLayout(libLayout)

        self.splitterTopBottom.addWidget(self.table)
        self.splitterTopBottom.addWidget(self.infoFrame)
        self.splitterTopBottom.setStretchFactor(0, 1)
        #self.splitterTopBottom.setStretchFactor(1,0)

        splitterLeftRight.addWidget(libFrame)
        splitterLeftRight.addWidget(self.splitterTopBottom)
        splitterLeftRight.setStretchFactor(0, 2)
        splitterLeftRight.setStretchFactor(1, 3)

        mainLayout = QtGui.QGridLayout()
        mainLayout.setContentsMargins(4, 4, 4, 4)
        mainLayout.addWidget(splitterLeftRight)

        dummyWidget = QtGui.QWidget()
        dummyWidget.setLayout(mainLayout)
        self.setCentralWidget(dummyWidget)

        self.setTabOrder(self.tree, self.table)

        dictShortcuts = self.readConfig('shortcuts')
        modifier = dictShortcuts['modifier'] + '+'
        self.shortQuit = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['quit']), self,
            self.close)
        self.shortStop = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['stop']), self,
            self.stop)
        self.shortPlayPause = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['play_pause']), self,
            self.toggleSong)
        self.shortSongPrevious = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['previous']), self,
            self.previous)
        self.shortSongNext = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['next']), self,
            self.next)
        self.shortVolDown = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['volume_down']), self,
            self.volumeSlider.decr)
        self.shortVolUp = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['volume_up']), self,
            self.volumeSlider.incr)
        self.shortRadioMode = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['radio_mode']), self,
            self.toggleRadio)
        self.shortEqualizer = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['equalizer']), self,
            self.openEqualizer)

        thread = QtCore.QThread(self)
        thread.worker = WorkThreadPipe()
        thread.worker.moveToThread(thread)
        thread.started.connect(thread.worker.process)
        thread.worker.hotKey.connect(self.onHotKey)
        thread.worker.finished.connect(thread.quit)
        thread.worker.finished.connect(thread.worker.deleteLater)
        thread.finished.connect(thread.deleteLater)
        thread.start()

        self.show()
Ejemplo n.º 12
0
class Foo(QtGui.QMainWindow):
    def __init__(self):
        super(Foo, self).__init__()
        self.initUI()

    def initUI(self):
        config = Foo.readConfig('options')
        self.timeOut = -1
        self.radio = False
        self.statusBar().showMessage('Ready')
        self.createMenu()
        self.setWindowTitle("Foo.cd")

        self.player = Player(Foo.readConfig('audio'))
        self.player.bus.connect('message::eos', self.stop)
        self.player.bus.connect('message::duration-changed',
                                self.onDurationChanged)

        self.tree = Tree(self, config['tree_order'])
        self.tree.addSongs.connect(self.addSongsFromTree)
        self.tree.customContextMenuRequested.connect(self.tmpTag)

        if not self.radio:
            self.table = Table(self, config)
            self.handlerATF = self.player.playbin.connect(
                "about-to-finish", self.onAboutToFinish)
            self.table.runAction.connect(self.tableAction)
        else:
            configRadio = Foo.readConfigRadios()
            self.table = TableRadio(self, configRadio)
            self.table.runAction.connect(self.tableAction)
            self.handlerT = self.player.bus.connect('message::tag',
                                                    self.table.onTag)

        self.playbackButtons = PlaybackButtons(None)
        self.playbackButtons.buttonPlay.clicked.connect(self.toggleSong)
        self.playbackButtons.buttonStop.clicked.connect(self.stop)
        self.playbackButtons.buttonPrev.clicked.connect(self.previous)
        self.playbackButtons.buttonNext.clicked.connect(self.next)

        self.volumeSlider = VolumeSlider(self)
        self.volumeSlider.sliderMoved.connect(self.player.setVolume)
        self.scrollSlider = ScrollSlider(self)
        self.scrollSlider.sliderPressed.connect(self.player.toggle)
        self.scrollSlider.sliderReleased.connect(self.player.toggle)
        self.scrollSlider.sliderMoved.connect(self.player.seek)

        self.pixmap = Image(self, config['cover_names'], config['extensions'])

        # Album cover connections
        self.tree.selectionModel().selectionChanged.connect(
            lambda: self.pixmap.onSelectionChanged(self.tree.getChildren()[0].
                                                   get('file', None)))
        self.table.selectionModel().selectionChanged.connect(
            lambda: self.pixmap.onSelectionChanged(self.table.getSelection().
                                                   get('file', None)))

        self.searchArea = SearchArea(self)
        self.searchArea.searchLine.returnPressed.connect(self.startSearch)

        self.playbackButtons.addWidget(self.volumeSlider)
        self.playbackButtons.addWidget(self.scrollSlider)

        splitterLeftRight = QtGui.QSplitter()
        self.splitterTopBottom = QtGui.QSplitter(Qt.Vertical, self)

        self.infoFrame = QtGui.QFrame()
        infoLayout = QtGui.QVBoxLayout()
        infoLayout.setContentsMargins(0, 0, 0, 0)
        infoLayout.addLayout(self.playbackButtons)
        infoLayout.addWidget(self.pixmap)
        self.infoFrame.setLayout(infoLayout)

        libLayout = QtGui.QVBoxLayout()
        libLayout.setContentsMargins(0, 0, 0, 0)
        libLayout.addWidget(self.tree)
        libLayout.addLayout(self.searchArea)
        libFrame = QtGui.QFrame()
        libFrame.setLayout(libLayout)

        self.splitterTopBottom.addWidget(self.table)
        self.splitterTopBottom.addWidget(self.infoFrame)
        self.splitterTopBottom.setStretchFactor(0, 1)
        #self.splitterTopBottom.setStretchFactor(1,0)

        splitterLeftRight.addWidget(libFrame)
        splitterLeftRight.addWidget(self.splitterTopBottom)
        splitterLeftRight.setStretchFactor(0, 2)
        splitterLeftRight.setStretchFactor(1, 3)

        mainLayout = QtGui.QGridLayout()
        mainLayout.setContentsMargins(4, 4, 4, 4)
        mainLayout.addWidget(splitterLeftRight)

        dummyWidget = QtGui.QWidget()
        dummyWidget.setLayout(mainLayout)
        self.setCentralWidget(dummyWidget)

        self.setTabOrder(self.tree, self.table)

        dictShortcuts = self.readConfig('shortcuts')
        modifier = dictShortcuts['modifier'] + '+'
        self.shortQuit = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['quit']), self,
            self.close)
        self.shortStop = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['stop']), self,
            self.stop)
        self.shortPlayPause = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['play_pause']), self,
            self.toggleSong)
        self.shortSongPrevious = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['previous']), self,
            self.previous)
        self.shortSongNext = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['next']), self,
            self.next)
        self.shortVolDown = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['volume_down']), self,
            self.volumeSlider.decr)
        self.shortVolUp = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['volume_up']), self,
            self.volumeSlider.incr)
        self.shortRadioMode = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['radio_mode']), self,
            self.toggleRadio)
        self.shortEqualizer = QtGui.QShortcut(
            QtGui.QKeySequence(modifier + dictShortcuts['equalizer']), self,
            self.openEqualizer)

        thread = QtCore.QThread(self)
        thread.worker = WorkThreadPipe()
        thread.worker.moveToThread(thread)
        thread.started.connect(thread.worker.process)
        thread.worker.hotKey.connect(self.onHotKey)
        thread.worker.finished.connect(thread.quit)
        thread.worker.finished.connect(thread.worker.deleteLater)
        thread.finished.connect(thread.deleteLater)
        thread.start()

        self.show()

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_Alt:
            self.menuBar().setVisible(not self.menuBar().isVisible())
        else:
            QWidget.keyPressEvent(self, event)

    # Triggered by player end of stream event
    # or called by hand to stop the stream
    def stop(self, bus=None, msg=None):
        self.player.stop()
        self.scrollSlider.setValue(0)
        self.table.displayPlayToStop()
        self.stopStatusEmission('Ready')

    def previous(self):
        if self.table.playingId > 0:
            self.player.stop()
            self.table.playingId -= 1
            self.player.add(self.table.model().item(self.table.playingId,
                                                    0).data()['file'])
            self.player.play()

    def next(self):
        if self.table.model().rowCount() - 1 > self.table.playingId:
            self.player.stop()
            self.table.playingId += 1
            self.player.add(self.table.model().item(self.table.playingId,
                                                    0).data()['file'])
            self.player.play()

    def toggleSong(self):
        state = self.player.playbin.get_state(Gst.State.NULL)
        if state[1] == Gst.State.PLAYING:
            self.table.displayPlayToPause()
            self.player.toggle()

            status = self.statusBar().currentMessage().replace(
                'Playing', 'Paused')
            self.stopStatusEmission(status)
        else:
            self.table.displayPauseToPlay(self.table.playingId)
            self.player.toggle()
            #self.onDurationChanged(0,0)
            status = self.table.getStatus()
            self.setStatusEmission(status)

    # Triggered by player when a song starts
    def onDurationChanged(self, bus, msg):
        self.table.displayNext()
        print('Duration changed signal !')
        filename = self.table.model().item(self.table.playingId,
                                           0).data()['file'][7:]
        data = wave.getDBData(filename)
        wave.createImg(data)
        self.scrollSlider.setStyleSheet("border-image: url(./wave.png)")

    # Triggered by player at the end of a song
    def onAboutToFinish(self, bus):
        if self.table.model().rowCount() - 1 > self.table.playingId:
            print('About to finish !')
            self.table.playingId += 1
            self.player.add(self.table.model().item(self.table.playingId,
                                                    0).data()['file'])

    def addSongsFromTree(self, list, play):
        if not self.radio:
            i = self.table.model().rowCount()
            for l in list:
                self.table.addRow(l)
            self.table.resizeRowsToContents()
            if play:
                self.stop()
                self.player.add(list[0]['file'])
                self.player.play()
                self.table.displayStopToPlay(i)
                status = self.table.getStatus()
                self.setStatusEmission(status)

    def setStatusEmission(self, status):
        if self.timeOut > 0:
            GObject.source_remove(self.timeOut)
        self.timeOut = GObject.timeout_add(1000, self.update, status)

    def stopStatusEmission(self, status):
        if self.timeOut > 0:
            GObject.source_remove(self.timeOut)
        self.timeOut = GObject.timeout_add(0, self.update, status)
        self.timeOut = -1

    def update(self, status):
        print('.')
        try:
            duration_nanosecs = self.player.getDuration()
            duration = float(duration_nanosecs) / 1000000000
            self.scrollSlider.setRange(0, duration)

            nanosecs = self.player.getPosition()
            position = float(nanosecs) // 1000000000
            self.scrollSlider.setValue(position)
            m, s = divmod(position, 60)
            self.statusBar().showMessage(
                status.replace('%', "%02d:%02d" % (m, s)))
        except Exception as e:
            print(e)
            pass
        if 'Playing' in status:
            return True
        else:
            return False

    def tableAction(self, str):
        if str == 'stop':
            self.stop()
        elif str == 'play':
            if self.table.selectedIndexes():
                index = self.table.selectedIndexes()[0]
            else:
                index = self.table.model().index(
                    self.table.selectionModel().currentIndex().row(), 0)
            songURI = index.model().itemFromIndex(index).data()['file']

            self.player.stop()
            self.player.add(songURI)
            self.player.play()
            self.table.displayStopToPlay(index.row())
            status = self.table.getStatus()
            self.setStatusEmission(status)

    @staticmethod
    def readConfig(section):
        parser = RawConfigParser()
        if getattr(sys, 'frozen', False):
            # frozen
            parser.read(
                os.path.dirname(os.path.realpath(sys.executable)) + '/config')
        else:
            # unfrozen
            parser.read(
                os.path.dirname(os.path.realpath(__file__)) + '/config')

        return dict(parser.items(section))

    #Create menu bar
    def createMenu(self):
        self.menuBar()
        self.menuBar().setVisible(False)
        actionMenu = self.menuBar().addMenu('&Action')
        scanMusicFolderAction = QtGui.QAction('Scan Music Folder', self)
        showShortcutAction = QtGui.QAction('Show Shortcut', self)
        addFolderToLibraryAction = QtGui.QAction('Add Folder to Library', self)
        scanWaveformsAction = QtGui.QAction('Scan wave froms', self)
        #self.toggleRadioAction= QtGui.QAction('Switch to Radio mode',self)
        if not self.radio:
            self.toggleRadioAction = QtGui.QAction('Switch to Radio mode',
                                                   self)
        else:
            self.toggleRadioAction = QtGui.QAction('Switch to Library mode',
                                                   self)
        scanMusicFolderAction.triggered.connect(self.scanMusicFolder)
        actionMenu.addAction(scanMusicFolderAction)
        showShortcutAction.triggered.connect(self.showShortcut)
        actionMenu.addAction(showShortcutAction)
        addFolderToLibraryAction.triggered.connect(self.addFolderToLibrary)
        actionMenu.addAction(addFolderToLibraryAction)
        scanWaveformsAction.triggered.connect(self.scanWaveforms)
        actionMenu.addAction(scanWaveformsAction)
        self.toggleRadioAction.triggered.connect(self.toggleRadio)
        actionMenu.addAction(self.toggleRadioAction)

    # Menu Action 1
    def scanMusicFolder(self):
        thread = QtCore.QThread(self)
        thread.worker = WorkThread(
            Foo.readConfig('options')['music_folder'], False)
        thread.worker.moveToThread(thread)
        thread.started.connect(thread.worker.process)
        thread.worker.finished.connect(thread.quit)
        thread.worker.finished.connect(thread.worker.deleteLater)
        thread.finished.connect(thread.deleteLater)
        thread.finished.connect(self.tree.initUI)
        thread.start()

    # Menu Action 2
    def showShortcut(self):
        dictSC = Foo.readConfig('shortcuts')
        message = '''<b>''' + dictSC['modifier'] + '''+''' + dictSC[
            'stop'] + '''</b> : Stop<br/>''' + '''
		<b>''' + dictSC['modifier'] + '''+''' + dictSC['quit'] + '''</b> : Quit<br/>''' + '''
		<b>''' + dictSC['modifier'] + '''+''' + dictSC[
                'play_pause'] + '''</b> : Play/Pause    <br/>''' + '''
		<b>''' + dictSC['modifier'] + '''+''' + dictSC[
                    'previous'] + '''</b> : Previous<br/>''' + '''
		<b>''' + dictSC['modifier'] + '''+''' + dictSC['next'] + '''</b> : Next<br/>''' + '''
		<b>''' + dictSC['modifier'] + '''+''' + dictSC[
                        'volume_down'] + '''</b> : Volume down<br/>''' + '''
		<b>''' + dictSC['modifier'] + '''+''' + dictSC[
                            'volume_up'] + '''</b> : Volume up<br/>''' + '''
		<b>''' + dictSC['modifier'] + '''+''' + dictSC[
                                'radio_mode'] + '''</b> : Toggle radio mode<br/>''' + '''
		<b>''' + dictSC['modifier'] + '''+''' + dictSC[
                                    'equalizer'] + '''</b> : Equalizer<br/>'''
        print(len(self.findChildren(QtCore.QObject)))
        box = QMessageBox.about(self, 'About Shortcuts', message)
        print(len(self.findChildren(QtCore.QObject)))
        print('must delete')

    # Menu Action3
    # Must be subdirectory of music folder otherwise wont be rescanned
    def addFolderToLibrary(self):
        dir = QFileDialog.getExistingDirectory(
            None, "Open Directory",
            Foo.readConfig('options')['music_folder'], QFileDialog.ShowDirsOnly
            | QFileDialog.DontResolveSymlinks)
        thread = QtCore.QThread(self)
        thread.worker = WorkThread(dir, True)
        thread.worker.moveToThread(thread)
        thread.started.connect(thread.worker.process)
        thread.worker.finished.connect(thread.quit)
        thread.worker.finished.connect(thread.worker.deleteLater)
        thread.finished.connect(thread.deleteLater)
        thread.finished.connect(self.tree.initUI)
        thread.start()

    # Menu action 4
    def scanWaveforms(self):
        from wave import Wave
        thread = QtCore.QThread(self)
        thread.worker = Wave(Foo.readConfig('options')['music_folder'])
        thread.worker.moveToThread(thread)
        thread.started.connect(thread.worker.processScan)
        thread.worker.finished.connect(thread.quit)
        thread.worker.finished.connect(thread.worker.deleteLater)
        thread.finished.connect(thread.deleteLater)
        thread.finished.connect(self.tree.initUI)
        thread.start()

    # Menu Action5
    def toggleRadio(self):
        self.table.deleteLater()
        self.table.close()
        if not self.radio:
            configRadio = Foo.readConfig('radios')
            self.table = TableRadio(self.tree, configRadio)
            self.toggleRadioAction.setText('Switch to Library mode')
            self.radio = True
            self.player.playbin.disconnect(self.handlerATF)
            self.handlerT = self.player.bus.connect('message::tag',
                                                    self.table.onTag)
        else:
            config = Foo.readConfig('options')
            self.table = Table(self.tree, config)
            self.toggleRadioAction.setText('Switch to Radio mode')
            self.radio = False
            self.handlerATF = self.player.playbin.connect(
                "about-to-finish", self.onAboutToFinish)
            self.player.bus.disconnect(self.handlerT)

        self.splitterTopBottom.addWidget(self.table)
        # Since the frame is already attached to the splitter,
        # it only moves it to the new position
        self.splitterTopBottom.addWidget(self.infoFrame)
        self.table.runAction.connect(self.tableAction)
        self.setTabOrder(self.tree, self.table)
        self.splitterTopBottom.setStretchFactor(0, 10)
        #self.splitterTopBottom.setStretchFactor(3,1)

    @QtCore.pyqtSlot()
    def startSearch(self):
        input = self.searchArea.searchLine.text()

        db = thread.load()
        songList = []
        songGenerator = (Song(self.tree.comm, **dict) for dict in db)
        self.tree.model().removeRows(0, self.tree.model().rowCount())

        if self.searchArea.searchExact.isChecked():
            songList = [e for e in songGenerator if e.exactMatch(input)]
        elif self.searchArea.searchPrecise.isChecked():
            songList = [e for e in songGenerator if e.preciseMatch(input)]
        else:
            songList = [e for e in songGenerator if e.fuzzyMatch(input)]

        del db[:]
        songList.sort(key=self.tree.sortFunc)
        self.tree.populateTree(songList)

    @QtCore.pyqtSlot(str)
    def onHotKey(self, key):
        print('Hotkey was pressed', key)
        if key == 'quit':
            self.shortQuit.activated.emit()
        if key == 'stop':
            self.shortStop.activated.emit()
        if key == 'play_pause':
            self.shortPlayPause.activated.emit()
        if key == 'volume_up':
            self.shortVolUp.activated.emit()
        if key == 'volume_down':
            self.shortVolDown.activated.emit()
        if key == 'song_next':
            self.shortSongNext.activated.emit()
        if key == 'song_prev':
            self.shortSongPrev.activated.emit()
        if key == 'tree_up':
            if self.radio:
                self.table.keyPressEvent(
                    QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Up,
                                    Qt.KeyboardModifier(), ''))
            else:
                self.tree.keyPressEvent(
                    QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Up,
                                    Qt.KeyboardModifier(), ''))
        if key == 'tree_down':
            if self.radio:
                self.table.keyPressEvent(
                    QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Down,
                                    Qt.KeyboardModifier(), ''))
            else:
                self.tree.keyPressEvent(
                    QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Down,
                                    Qt.KeyboardModifier(), ''))
        if key == 'tree_left':
            if not self.radio:
                self.tree.keyPressEvent(
                    QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Left,
                                    Qt.KeyboardModifier(), ''))
        if key == 'tree_right':
            if not self.radio:
                self.tree.keyPressEvent(
                    QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Right,
                                    Qt.KeyboardModifier(), ''))
        if key == 'tree_validate':
            if self.radio:
                self.table.keyPressEvent(
                    QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Return,
                                    Qt.KeyboardModifier(), ''))
            else:
                self.tree.keyPressEvent(
                    QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Return,
                                    Qt.KeyboardModifier(), ''))
        if key == 'tree_append':
            if not self.radio:
                self.tree.keyPressEvent(
                    QtGui.QKeyEvent(
                        QtCore.QEvent.KeyPress, Qt.Key_Return,
                        Qt.KeyboardModifier(QtCore.Qt.ShiftModifier), ''))
        if key == 'radio_mode':
            self.shortRadioMode.activated.emit()

    def tmpTag(self, position):
        menu = QtGui.QMenu()
        tagging = QtGui.QAction('Tagging', self)
        replayGain = QtGui.QAction('ReplayGain', self)

        tagging.triggered.connect(self.openTagging)
        replayGain.triggered.connect(self.startReplayGain)
        menu.addAction(tagging)
        menu.addAction(replayGain)
        menu.exec_(self.tree.viewport().mapToGlobal(position))

    def startReplayGain(self):
        children = self.tree.getChildren()
        self.RG = ReplayGain([x['file'] for x in children])
        self.RG.exec_()

    def openTagging(self):
        children = self.tree.getChildren()
        #[7:] to drop the 'file://' appended for gstreamer
        retag = Retagging([x['file'][7:] for x in children])
        res = retag.exec_()
        if res:
            self.tree.initUI()
        print(res)

    def openEqualizer(self):
        from configparser import RawConfigParser
        equa = Equalizer(self, Foo.readConfig('audio'))
        equa.equalize.connect(self.applyEqua)
        if equa.exec_():
            parser = RawConfigParser()
            parser.read(
                os.path.dirname(os.path.realpath(__file__)) + '/config')
            parser['audio']['settings'] = str(equa.config)
            with open(
                    os.path.dirname(os.path.realpath(__file__)) + '/config',
                    'w') as configfile:
                parser.write(configfile)

    def applyEqua(self, band, value):
        print('receiving equa', str(band), value)
        if str(band) == 'band0' and value == 0:
            self.player.equalizer.set_property('band0', 0.01)
        else:
            self.player.equalizer.set_property(str(band), value)
Ejemplo n.º 13
0
	def initUI(self):
		config = Foo.readConfig('options')
		self.timeOut = -1
		self.radio = False
		self.statusBar().showMessage('Ready')
		self.createMenu()
		self.setWindowTitle("Foo.cd")
        
		self.player = Player(Foo.readConfig('audio'))
		self.player.bus.connect('message::eos', self.stop)
		self.player.bus.connect('message::duration-changed', self.onDurationChanged)
		   
		self.tree = Tree(self, config['tree_order'])
		self.tree.addSongs.connect(self.addSongsFromTree)
		self.tree.customContextMenuRequested.connect(self.tmpTag)
		
		if not self.radio:
			self.table=Table( self, config)
			self.handlerATF = self.player.playbin.connect("about-to-finish", self.onAboutToFinish)   
			self.table.runAction.connect(self.tableAction)
		else:
			configRadio = Foo.readConfigRadios()
			self.table=TableRadio( self, configRadio)
			self.table.runAction.connect(self.tableAction)
			self.handlerT = self.player.bus.connect('message::tag', self.table.onTag)
		
		self.playbackButtons = PlaybackButtons(None)
		self.playbackButtons.buttonPlay.clicked.connect(self.toggleSong)
		self.playbackButtons.buttonStop.clicked.connect(self.stop)
		self.playbackButtons.buttonPrev.clicked.connect(self.previous)
		self.playbackButtons.buttonNext.clicked.connect(self.next)
		
		self.volumeSlider = VolumeSlider(self)
		self.volumeSlider.sliderMoved.connect(self.player.setVolume)
		self.scrollSlider = ScrollSlider(self)
		self.scrollSlider.sliderPressed.connect(self.player.toggle)
		self.scrollSlider.sliderReleased.connect(self.player.toggle)
		self.scrollSlider.sliderMoved.connect(self.player.seek)

		self.pixmap = Image(self, config['cover_names'], config['extensions'])
		
		# Album cover connections
		self.tree.selectionModel().selectionChanged.connect(lambda: self.pixmap.onSelectionChanged(self.tree.getChildren()[0].get('file', None)))
		self.table.selectionModel().selectionChanged.connect(lambda:  self.pixmap.onSelectionChanged(self.table.getSelection().get('file', None)))
		
		self.searchArea = SearchArea(self)
		self.searchArea.searchLine.returnPressed.connect(self.startSearch)	
		
		self.playbackButtons.addWidget(self.volumeSlider)
		self.playbackButtons.addWidget(self.scrollSlider)
		
		splitterLeftRight = QtGui.QSplitter()
		self.splitterTopBottom = QtGui.QSplitter(Qt.Vertical, self)
		
		self.infoFrame = QtGui.QFrame()
		infoLayout = QtGui.QVBoxLayout()
		infoLayout.setContentsMargins(0,0,0,0)
		infoLayout.addLayout(self.playbackButtons)
		infoLayout.addWidget(self.pixmap)
		self.infoFrame.setLayout(infoLayout)
		
		libLayout = QtGui.QVBoxLayout()
		libLayout.setContentsMargins(0,0,0,0)
		libLayout.addWidget(self.tree)
		libLayout.addLayout(self.searchArea)
		libFrame = QtGui.QFrame()
		libFrame.setLayout(libLayout)
		
		self.splitterTopBottom.addWidget(self.table)
		self.splitterTopBottom.addWidget(self.infoFrame)
		self.splitterTopBottom.setStretchFactor(0,1)
		#self.splitterTopBottom.setStretchFactor(1,0)

		splitterLeftRight.addWidget(libFrame)
		splitterLeftRight.addWidget(self.splitterTopBottom)
		splitterLeftRight.setStretchFactor(0,2)
		splitterLeftRight.setStretchFactor(1,3)

		mainLayout = QtGui.QGridLayout()
		mainLayout.setContentsMargins(4, 4, 4, 4)
		mainLayout.addWidget(splitterLeftRight)
		
		dummyWidget = QtGui.QWidget()
		dummyWidget.setLayout(mainLayout)  
		self.setCentralWidget(dummyWidget)
		
		self.setTabOrder(self.tree, self.table)

		dictShortcuts = self.readConfig('shortcuts')
		modifier = dictShortcuts['modifier']+'+'
		self.shortQuit = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['quit']), self, self.close)
		self.shortStop = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['stop']), self, self.stop)
		self.shortPlayPause = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['play_pause']), self, self.toggleSong)
		self.shortSongPrevious = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['previous']), self, self.previous)
		self.shortSongNext = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['next']), self, self.next)
		self.shortVolDown = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['volume_down']), self, self.volumeSlider.decr)
		self.shortVolUp = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['volume_up']), self, self.volumeSlider.incr)
		self.shortRadioMode = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['radio_mode']), self, self.toggleRadio)
		self.shortEqualizer = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['equalizer']), self, self.openEqualizer)
		
		thread = QtCore.QThread(self)
		thread.worker = WorkThreadPipe()
		thread.worker.moveToThread(thread);
		thread.started.connect(thread.worker.process)
		thread.worker.hotKey.connect(self.onHotKey)
		thread.worker.finished.connect(thread.quit)
		thread.worker.finished.connect(thread.worker.deleteLater)
		thread.finished.connect(thread.deleteLater)
		thread.start()
			
		self.show()
Ejemplo n.º 14
0
class Foo(QtGui.QMainWindow):

	def __init__(self):
		super(Foo, self).__init__()
		self.initUI()
        
	def initUI(self):
		config = Foo.readConfig('options')
		self.timeOut = -1
		self.radio = False
		self.statusBar().showMessage('Ready')
		self.createMenu()
		self.setWindowTitle("Foo.cd")
        
		self.player = Player(Foo.readConfig('audio'))
		self.player.bus.connect('message::eos', self.stop)
		self.player.bus.connect('message::duration-changed', self.onDurationChanged)
		   
		self.tree = Tree(self, config['tree_order'])
		self.tree.addSongs.connect(self.addSongsFromTree)
		self.tree.customContextMenuRequested.connect(self.tmpTag)
		
		if not self.radio:
			self.table=Table( self, config)
			self.handlerATF = self.player.playbin.connect("about-to-finish", self.onAboutToFinish)   
			self.table.runAction.connect(self.tableAction)
		else:
			configRadio = Foo.readConfigRadios()
			self.table=TableRadio( self, configRadio)
			self.table.runAction.connect(self.tableAction)
			self.handlerT = self.player.bus.connect('message::tag', self.table.onTag)
		
		self.playbackButtons = PlaybackButtons(None)
		self.playbackButtons.buttonPlay.clicked.connect(self.toggleSong)
		self.playbackButtons.buttonStop.clicked.connect(self.stop)
		self.playbackButtons.buttonPrev.clicked.connect(self.previous)
		self.playbackButtons.buttonNext.clicked.connect(self.next)
		
		self.volumeSlider = VolumeSlider(self)
		self.volumeSlider.sliderMoved.connect(self.player.setVolume)
		self.scrollSlider = ScrollSlider(self)
		self.scrollSlider.sliderPressed.connect(self.player.toggle)
		self.scrollSlider.sliderReleased.connect(self.player.toggle)
		self.scrollSlider.sliderMoved.connect(self.player.seek)

		self.pixmap = Image(self, config['cover_names'], config['extensions'])
		
		# Album cover connections
		self.tree.selectionModel().selectionChanged.connect(lambda: self.pixmap.onSelectionChanged(self.tree.getChildren()[0].get('file', None)))
		self.table.selectionModel().selectionChanged.connect(lambda:  self.pixmap.onSelectionChanged(self.table.getSelection().get('file', None)))
		
		self.searchArea = SearchArea(self)
		self.searchArea.searchLine.returnPressed.connect(self.startSearch)	
		
		self.playbackButtons.addWidget(self.volumeSlider)
		self.playbackButtons.addWidget(self.scrollSlider)
		
		splitterLeftRight = QtGui.QSplitter()
		self.splitterTopBottom = QtGui.QSplitter(Qt.Vertical, self)
		
		self.infoFrame = QtGui.QFrame()
		infoLayout = QtGui.QVBoxLayout()
		infoLayout.setContentsMargins(0,0,0,0)
		infoLayout.addLayout(self.playbackButtons)
		infoLayout.addWidget(self.pixmap)
		self.infoFrame.setLayout(infoLayout)
		
		libLayout = QtGui.QVBoxLayout()
		libLayout.setContentsMargins(0,0,0,0)
		libLayout.addWidget(self.tree)
		libLayout.addLayout(self.searchArea)
		libFrame = QtGui.QFrame()
		libFrame.setLayout(libLayout)
		
		self.splitterTopBottom.addWidget(self.table)
		self.splitterTopBottom.addWidget(self.infoFrame)
		self.splitterTopBottom.setStretchFactor(0,1)
		#self.splitterTopBottom.setStretchFactor(1,0)

		splitterLeftRight.addWidget(libFrame)
		splitterLeftRight.addWidget(self.splitterTopBottom)
		splitterLeftRight.setStretchFactor(0,2)
		splitterLeftRight.setStretchFactor(1,3)

		mainLayout = QtGui.QGridLayout()
		mainLayout.setContentsMargins(4, 4, 4, 4)
		mainLayout.addWidget(splitterLeftRight)
		
		dummyWidget = QtGui.QWidget()
		dummyWidget.setLayout(mainLayout)  
		self.setCentralWidget(dummyWidget)
		
		self.setTabOrder(self.tree, self.table)

		dictShortcuts = self.readConfig('shortcuts')
		modifier = dictShortcuts['modifier']+'+'
		self.shortQuit = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['quit']), self, self.close)
		self.shortStop = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['stop']), self, self.stop)
		self.shortPlayPause = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['play_pause']), self, self.toggleSong)
		self.shortSongPrevious = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['previous']), self, self.previous)
		self.shortSongNext = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['next']), self, self.next)
		self.shortVolDown = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['volume_down']), self, self.volumeSlider.decr)
		self.shortVolUp = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['volume_up']), self, self.volumeSlider.incr)
		self.shortRadioMode = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['radio_mode']), self, self.toggleRadio)
		self.shortEqualizer = QtGui.QShortcut(QtGui.QKeySequence(modifier+dictShortcuts['equalizer']), self, self.openEqualizer)
		
		thread = QtCore.QThread(self)
		thread.worker = WorkThreadPipe()
		thread.worker.moveToThread(thread);
		thread.started.connect(thread.worker.process)
		thread.worker.hotKey.connect(self.onHotKey)
		thread.worker.finished.connect(thread.quit)
		thread.worker.finished.connect(thread.worker.deleteLater)
		thread.finished.connect(thread.deleteLater)
		thread.start()
			
		self.show()
	
	def keyReleaseEvent(self, event):
		if event.key() == Qt.Key_Alt:
			self.menuBar().setVisible(not self.menuBar().isVisible())
		else:
			QWidget.keyPressEvent(self, event)
		
	# Triggered by player end of stream event
	# or called by hand to stop the stream
	def stop(self, bus=None, msg=None):
		self.player.stop()
		self.scrollSlider.setValue(0)
		self.table.displayPlayToStop()
		self.stopStatusEmission('Ready')

	def previous(self):
		if self.table.playingId > 0:
			self.player.stop()
			self.table.playingId-=1
			self.player.add(self.table.model().item(self.table.playingId,0).data()['file'])
			self.player.play()
			
	def next(self):
		if self.table.model().rowCount()-1 > self.table.playingId:
			self.player.stop()
			self.table.playingId+=1
			self.player.add(self.table.model().item(self.table.playingId,0).data()['file'])
			self.player.play()
	
	def toggleSong(self):			
		state = self.player.playbin.get_state(Gst.State.NULL)
		if state[1] == Gst.State.PLAYING:
			self.table.displayPlayToPause()
			self.player.toggle()
			
			status = self.statusBar().currentMessage().replace('Playing', 'Paused')
			self.stopStatusEmission(status)	
		else:
			self.table.displayPauseToPlay(self.table.playingId)
			self.player.toggle()
			#self.onDurationChanged(0,0)
			status = self.table.getStatus()
			self.setStatusEmission(status)
			
	# Triggered by player when a song starts
	def onDurationChanged(self, bus, msg):
		self.table.displayNext()
		print('Duration changed signal !')
		filename = self.table.model().item(self.table.playingId,0).data()['file'][7:]
		data = wave.getDBData(filename)
		wave.createImg(data)
		self.scrollSlider.setStyleSheet("border-image: url(./wave.png)")
		

	# Triggered by player at the end of a song
	def onAboutToFinish(self, bus):
		if self.table.model().rowCount()-1 > self.table.playingId:
			print('About to finish !')
			self.table.playingId+=1
			self.player.add(self.table.model().item(self.table.playingId,0).data()['file'])

	def addSongsFromTree(self, list, play):
		if not self.radio:
			i = self.table.model().rowCount()
			for l in  list:
				self.table.addRow(l)
			self.table.resizeRowsToContents()
			if play:
				self.stop()
				self.player.add(list[0]['file'])
				self.player.play()
				self.table.displayStopToPlay(i)
				status = self.table.getStatus()
				self.setStatusEmission(status)
	
	def setStatusEmission(self, status):
		if self.timeOut > 0:
			GObject.source_remove(self.timeOut)
		self.timeOut =  GObject.timeout_add(1000, self.update, status)	
		
	def stopStatusEmission(self, status):
		if self.timeOut > 0:
			GObject.source_remove(self.timeOut)
		self.timeOut = GObject.timeout_add(0, self.update, status)
		self.timeOut=-1
	
	def update(self, status):
		print('.')
		try:
			duration_nanosecs = self.player.getDuration()
			duration = float(duration_nanosecs) / 1000000000
			self.scrollSlider.setRange(0, duration)
			
			nanosecs = self.player.getPosition()
			position = float(nanosecs) // 1000000000	
			self.scrollSlider.setValue(position)
			m, s = divmod(position, 60)
			self.statusBar().showMessage(status.replace('%',"%02d:%02d" % (m, s)))
		except Exception as e:
			print(e)
			pass	
		if 'Playing' in status:
			return True
		else:
			return False


	def tableAction(self, str):
		if str == 'stop':
			self.stop()
		elif str == 'play':
			if self.table.selectedIndexes():
				index = self.table.selectedIndexes()[0]
			else:
				index= self.table.model().index(self.table.selectionModel().currentIndex().row(),0)
			songURI = index.model().itemFromIndex(index).data()['file']
			
			self.player.stop()
			self.player.add(songURI)
			self.player.play()
			self.table.displayStopToPlay(index.row())
			status = self.table.getStatus()
			self.setStatusEmission(status)
			
	@staticmethod
	def readConfig(section):
		parser = RawConfigParser()
		if getattr(sys, 'frozen', False):
			# frozen
			parser.read(os.path.dirname(os.path.realpath(sys.executable))+'/config')
		else:
			# unfrozen
			parser.read(os.path.dirname(os.path.realpath(__file__))+'/config')
		
		return dict(parser.items(section))

	#Create menu bar
	def createMenu(self):
		self.menuBar()
		self.menuBar().setVisible(False)
		actionMenu = self.menuBar().addMenu('&Action')
		scanMusicFolderAction = QtGui.QAction('Scan Music Folder', self) 
		showShortcutAction = QtGui.QAction('Show Shortcut',self)
		addFolderToLibraryAction = QtGui.QAction('Add Folder to Library',self)
		scanWaveformsAction = QtGui.QAction('Scan wave froms',self)
		#self.toggleRadioAction= QtGui.QAction('Switch to Radio mode',self)
		if not self.radio: 
			self.toggleRadioAction= QtGui.QAction('Switch to Radio mode',self)
		else:
			self.toggleRadioAction= QtGui.QAction('Switch to Library mode',self)
		scanMusicFolderAction.triggered.connect(self.scanMusicFolder)
		actionMenu.addAction(scanMusicFolderAction)
		showShortcutAction.triggered.connect(self.showShortcut)
		actionMenu.addAction(showShortcutAction)
		addFolderToLibraryAction.triggered.connect(self.addFolderToLibrary)
		actionMenu.addAction(addFolderToLibraryAction)
		scanWaveformsAction.triggered.connect(self.scanWaveforms)
		actionMenu.addAction(scanWaveformsAction)
		self.toggleRadioAction.triggered.connect(self.toggleRadio)
		actionMenu.addAction(self.toggleRadioAction)
		
		
	# Menu Action 1
	def scanMusicFolder(self):
		thread = QtCore.QThread(self)
		thread.worker = WorkThread(Foo.readConfig('options')['music_folder'], False)
		thread.worker.moveToThread(thread)
		thread.started.connect(thread.worker.process)
		thread.worker.finished.connect(thread.quit)
		thread.worker.finished.connect(thread.worker.deleteLater)
		thread.finished.connect(thread.deleteLater)
		thread.finished.connect(self.tree.initUI)
		thread.start()
		
	# Menu Action 2
	def showShortcut(self):
		dictSC = Foo.readConfig('shortcuts')
		message = '''<b>'''+dictSC['modifier']+'''+'''+dictSC['stop']+'''</b> : Stop<br/>''' + '''
		<b>'''+dictSC['modifier']+'''+'''+dictSC['quit']+'''</b> : Quit<br/>''' + '''
		<b>'''+dictSC['modifier']+'''+'''+dictSC['play_pause']+'''</b> : Play/Pause    <br/>''' + '''
		<b>'''+dictSC['modifier']+'''+'''+dictSC['previous']+'''</b> : Previous<br/>''' + '''
		<b>'''+dictSC['modifier']+'''+'''+dictSC['next']+'''</b> : Next<br/>''' + '''
		<b>'''+dictSC['modifier']+'''+'''+dictSC['volume_down']+'''</b> : Volume down<br/>''' + '''
		<b>'''+dictSC['modifier']+'''+'''+dictSC['volume_up']+'''</b> : Volume up<br/>''' + '''
		<b>'''+dictSC['modifier']+'''+'''+dictSC['radio_mode']+'''</b> : Toggle radio mode<br/>''' + '''
		<b>'''+dictSC['modifier']+'''+'''+dictSC['equalizer']+'''</b> : Equalizer<br/>'''
		print(len(self.findChildren(QtCore.QObject)))
		box = QMessageBox.about(self, 'About Shortcuts',
		message)
		print(len(self.findChildren(QtCore.QObject)))
		print('must delete')

	# Menu Action3
	# Must be subdirectory of music folder otherwise wont be rescanned
	def addFolderToLibrary(self):
		dir = QFileDialog.getExistingDirectory(None,
				"Open Directory",
				Foo.readConfig('options')['music_folder'],
				QFileDialog.ShowDirsOnly
				| QFileDialog.DontResolveSymlinks)		
		thread = QtCore.QThread(self)
		thread.worker = WorkThread(dir, True)
		thread.worker.moveToThread(thread)
		thread.started.connect(thread.worker.process)
		thread.worker.finished.connect(thread.quit)
		thread.worker.finished.connect(thread.worker.deleteLater)
		thread.finished.connect(thread.deleteLater)
		thread.finished.connect(self.tree.initUI)
		thread.start()
		
	# Menu action 4
	def scanWaveforms(self):
		from wave import Wave
		thread = QtCore.QThread(self)
		thread.worker = Wave(Foo.readConfig('options')['music_folder'])
		thread.worker.moveToThread(thread)
		thread.started.connect(thread.worker.processScan)
		thread.worker.finished.connect(thread.quit)
		thread.worker.finished.connect(thread.worker.deleteLater)
		thread.finished.connect(thread.deleteLater)
		thread.finished.connect(self.tree.initUI)
		thread.start()
	
	# Menu Action5
	def toggleRadio(self):
		self.table.deleteLater()
		self.table.close()
		if not self.radio:
			configRadio = Foo.readConfig('radios')
			self.table=TableRadio(self.tree, configRadio)
			self.toggleRadioAction.setText('Switch to Library mode')
			self.radio=True
			self.player.playbin.disconnect(self.handlerATF)
			self.handlerT=self.player.bus.connect('message::tag', self.table.onTag)		
		else:
			config = Foo.readConfig('options')
			self.table=Table( self.tree, config)
			self.toggleRadioAction.setText('Switch to Radio mode')
			self.radio=False
			self.handlerATF = self.player.playbin.connect("about-to-finish",self.onAboutToFinish)
			self.player.bus.disconnect(self.handlerT)

		self.splitterTopBottom.addWidget(self.table)
		# Since the frame is already attached to the splitter, 
		# it only moves it to the new position
		self.splitterTopBottom.addWidget(self.infoFrame)
		self.table.runAction.connect(self.tableAction)
		self.setTabOrder(self.tree, self.table)
		self.splitterTopBottom.setStretchFactor(0,10)
		#self.splitterTopBottom.setStretchFactor(3,1)
		
	@QtCore.pyqtSlot()
	def startSearch(self):
		input = self.searchArea.searchLine.text()
		
		db = thread.load()
		songList = []
		songGenerator = (Song(self.tree.comm, **dict) for dict in db)
		self.tree.model().removeRows(0, self.tree.model().rowCount())
		
		if self.searchArea.searchExact.isChecked():
			songList = [ e for e in songGenerator if e.exactMatch(input) ]
		elif self.searchArea.searchPrecise.isChecked():
			songList = [ e for e in songGenerator if e.preciseMatch(input) ]
		else:
			songList = [ e for e in songGenerator if e.fuzzyMatch(input) ]	
		
		del db[:]
		songList.sort(key=self.tree.sortFunc)
		self.tree.populateTree(songList)
		
	@QtCore.pyqtSlot(str)
	def onHotKey(self, key):
		print('Hotkey was pressed', key)
		if key == 'quit':
			self.shortQuit.activated.emit()
		if key == 'stop':
			self.shortStop.activated.emit()
		if key == 'play_pause':
			self.shortPlayPause.activated.emit()
		if key == 'volume_up':
			self.shortVolUp.activated.emit()
		if key == 'volume_down':
			self.shortVolDown.activated.emit()
		if key == 'song_next':
			self.shortSongNext.activated.emit()
		if key == 'song_prev':
			self.shortSongPrev.activated.emit()
		if key == 'tree_up':
			if self.radio:
				self.table.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Up, Qt.KeyboardModifier(), ''))
			else:
				self.tree.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Up, Qt.KeyboardModifier(), ''))
		if key == 'tree_down':
			if self.radio:
				self.table.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Down, Qt.KeyboardModifier(), ''))
			else:
				self.tree.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Down, Qt.KeyboardModifier(), ''))
		if key == 'tree_left':
			if not self.radio:
				self.tree.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Left, Qt.KeyboardModifier(), ''))
		if key == 'tree_right':
			if not self.radio:
				self.tree.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Right, Qt.KeyboardModifier(), ''))
		if key == 'tree_validate':
			if self.radio:
				self.table.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Return, Qt.KeyboardModifier(), ''))
			else:
				self.tree.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Return, Qt.KeyboardModifier(), ''))
		if key == 'tree_append':
			if not self.radio:
				self.tree.keyPressEvent(QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_Return, Qt.KeyboardModifier(QtCore.Qt.ShiftModifier), ''))
		if key == 'radio_mode':
			self.shortRadioMode.activated.emit()

	def tmpTag(self, position):
		menu = QtGui.QMenu()
		tagging = QtGui.QAction('Tagging',self)
		replayGain = QtGui.QAction('ReplayGain',self)
		
		tagging.triggered.connect(self.openTagging)
		replayGain.triggered.connect(self.startReplayGain)
		menu.addAction(tagging)
		menu.addAction(replayGain)
		menu.exec_(self.tree.viewport().mapToGlobal(position))

	def startReplayGain(self):
		children = self.tree.getChildren()
		self.RG = ReplayGain([x['file'] for x in children])
		self.RG.exec_()
	
	def openTagging(self):
		children = self.tree.getChildren()
		#[7:] to drop the 'file://' appended for gstreamer
		retag = Retagging([x['file'][7:] for x in children])
		res = retag.exec_()
		if res:
			self.tree.initUI()
		print(res)
	
	def openEqualizer(self):
		from configparser import RawConfigParser
		equa = Equalizer(self, Foo.readConfig('audio'))
		equa.equalize.connect(self.applyEqua)
		if equa.exec_():
			parser = RawConfigParser()
			parser.read(os.path.dirname(os.path.realpath(__file__))+'/config')
			parser['audio']['settings']= str(equa.config)
			with open(os.path.dirname(os.path.realpath(__file__))+'/config', 'w') as configfile:
				parser.write(configfile)
		
	def applyEqua(self,band, value):
		print('receiving equa', str(band), value)
		if str(band) == 'band0' and value == 0:
			self.player.equalizer.set_property('band0', 0.01)
		else:
			self.player.equalizer.set_property(str(band), value)
Ejemplo n.º 15
0
class StatusView(Widget):
    alpha = anim.Animatable()
    def __init__(self, pos=zero, is_opponent=False):
        super(StatusView,self).__init__(pos)
        self._toggled = False
        self._spacing = 10
        self._reveal_library = False
        self.color = (0.5, 0.5, 0.5)
        self.is_opponent = is_opponent
        #self._pos.set_transition(dt=0.1, method="linear")
        #symbols = ["life", "library", "hand", "graveyard", "exile"]
        symbols = ["life", "hand", "library", "graveyard", "exile"]
        self.symbols = dict([(symbol, cls(symbol)) for symbol, cls in zip(symbols, [Image, Image, Image, Image, Image])])
        for symbol in self.symbols.values():
            symbol.alpha = 0.8
        self.player_name = Label("", 11, halign="left", fontname = "Arial Bold", valign="center", shadow=False)
        #sizes = [20, 16, 14, 14, 14]
        sizes = [20, 14, 14, 14, 14]
        self.values = dict([(symbol, Label('', size, fontname = "Arial Bold", halign="center", valign="center", shadow=False)) for symbol, size in zip(symbols, sizes)])
        #for val in self.values.values():
        self.avatar = Image(pyglet.image.Texture.create(80,80))
        self.avatar.shaking = 0
        self.avatar.alpha = anim.animate(1., 1., dt=0.25)
        self.alpha = anim.animate(1., 1., dt=0.25)

        self.manapool = ManaPool(is_opponent)
        self.zone_view = ZoneView()
        self._library = LibraryImage(is_opponent)
        self.width, self.height = 145,135
    #    self.layout()
    def resize(self, width, height):
        self.layout()
    #    offset = 5
    #    if self.is_opponent:
    #        pos = euclid.Vector3(offset, height-self.height-offset, 0)
    #    else:
    #        pos = euclid.Vector3(offset, offset, 0)
    #    self._pos.set(pos)
        self._orig_pos = self.pos
    def clear(self):
        self.symbols['life'].rotatey = anim.constant(0)
        status = self.values
        counters = ["life", "hand", "library", "graveyard", "exile"]
        for c in counters: status[c].set_text(0)
    def toggle(self):
        if not self._toggled: 
            x = self.width - self.values['life'].width-self._spacing*1.5
            self.pos += euclid.Vector3(-x, 0, 0)
        else: self.pos = self._orig_pos
        self._toggled = not self._toggled
    def toggle_library(self):
        self._reveal_library = not self._reveal_library
    def animate(self, status):
        symbol = self.symbols[status]
        symbol.scale = anim.animate(symbol.scale, 1.15*symbol.scale, dt=1.0, method=lambda t: anim.oscillate_n(t, 3))
    def handle_click(self, x, y):
        x -= self.pos.x
        y -= self.pos.y
        for status, item in self.symbols.items():
            sx, sy, sw, sh = item.pos.x, item.pos.y, item.width/2., item.height/2.
            if x > sx-sw and x < sx+sw and y >= sy-sh and y <= sy+sh:
                return status
        else:
            return (0 < x <= self.width and 0 < y <= self.height)
    def setup_player(self, player, color, avatar):
        self.player = player
        self.color = color
        self.avatar.img = avatar.get_texture()
        self.player_name.set_text(player.name)
        self.update_life()
        for zone in ["library", "hand", "graveyard", "exile"]:
            self.update_zone(getattr(player, zone))
    def new_turn(self, player):
        return
        life = self.symbols["life"]
        if self.player == player: life.rotatey = anim.animate(0,360,dt=5,method='linear',extend='repeat')
        else: life.rotatey = anim.constant(0)
    def pass_priority(self, player):
        alpha = 1.0 if self.player == player else 0.6
        self.alpha = self.avatar.alpha = alpha
    def animate_life(self, amount):
        symbol = self.symbols["life"]
        curr_scale = symbol._final_scale
        if amount > 0: final_scale = curr_scale*1.5
        else: final_scale = curr_scale*0.5
        symbol._scale = anim.animate(curr_scale, final_scale,dt=0.75, method="oscillate")
        symbol.alpha = anim.animate(symbol.alpha, 0.7,dt=0.75, method="oscillate")
        self.update_life()
    def update_life(self):
        status = self.values
        player = self.player
        counters = ["life"] #, "poison"]
        for c in counters: status[c].set_text(getattr(player, c))
    def update_zone(self, zone):
        val = len(zone)
        status = self.values[str(zone)]
        if val > 0:
        #    self.symbols[str(zone)].alpha = 0.8
            status.set_text(val)
        else:
        #    self.symbols[str(zone)].alpha = 0.4
            status.set_text('0')
        if str(zone) == "library": self._library.update(zone)
    def layout(self):
        life_img, life = self.symbols["life"], self.values["life"]
        life_img.alpha = anim.constant(0.3)
        life_img._final_scale = 0.25
        life_img._scale = anim.constant(life_img._final_scale)
        #life_img.visible = anim.constant(0)
        avatar = self.avatar
        spacing = self._spacing
        if self.is_opponent:
            x, y = spacing, life.height / 2.
        
            self.player_name.pos = euclid.Vector3(x, y, 0)
            self.manapool.pos = euclid.Vector3(self.width, 0, 0)
            x = self.width - life.width/2 - spacing
            life.pos = life_img.pos = euclid.Vector3(x, y, 0)
            
            for i, status in enumerate(["graveyard", "library", "hand"]):
                symbol, value = self.symbols[status], self.values[status]
                #symbol.scale = 0.3
                #symbol.pos = value.pos = euclid.Vector3(x, life.height+spacing+symbol.height/2+0.7*i*(symbol.height), 0)
                symbol.pos = value.pos = euclid.Vector3(x, life.height+spacing/2+symbol.height/2+i*(symbol.height), 0)
                
            library, lib = self._library, self.symbols["library"]
            library.scale = 0.5
            library.pos = euclid.Vector3(self.width, life.height+spacing/2+1.5*lib.height, 0)
            #status = "library"
            #library, value = self.symbols["library"], self.values["library"]
            #library.scale = 0.3
            #library.pos = value.pos = euclid.Vector3(spacing + library.width/2, life.height+library.height/2+spacing,0)
            avatar.pos = euclid.Vector3(spacing + avatar.width/2, life.height+avatar.height/2+spacing,0)
        else:
            x, y = spacing, self.height - life.height / 2.
        
            self.player_name.pos = euclid.Vector3(x, y, 0)
            self.manapool.pos = euclid.Vector3(self.width, self.height, 0)
            x = self.width - life.width/2 - spacing
            life.pos = life_img.pos = euclid.Vector3(x, y, 0)
            
            for i, status in enumerate(["graveyard", "library", "hand"][::-1]):
                symbol, value = self.symbols[status], self.values[status]
                #symbol.scale = 0.3
                #symbol.pos = value.pos = euclid.Vector3(x, self.height-life.height-symbol.height/2-0.7*i*(symbol.height), 0)
                symbol.pos = value.pos = euclid.Vector3(x, self.height-life.height-symbol.height/2-i*(symbol.height)-spacing/2, 0)
                
            library, lib = self._library, self.symbols["library"]
            library.scale = 0.5
            library.pos = euclid.Vector3(self.width, 1.5*lib.height, 0)
            #status = "library"
            #library, value = self.symbols["library"], self.values["library"]
            #library.scale = 0.3
            #library.pos = value.pos = euclid.Vector3(spacing + library.width/2, self.height-life.height-library.height/2-spacing,0)
            avatar.pos = euclid.Vector3(spacing + avatar.width/2, self.height-life.height-avatar.height/2-spacing,0)
            
    def render_after_transform(self):
        ac = self.color
        glColor4f(ac[0], ac[1], ac[2], self.alpha)
        life_height = self.values['life'].height
        h1, h2 = self.height - life_height, life_height
        if self.is_opponent: h1, h2 = h2, h1
        render_9_part("box4",
                      self.width, h1,
                      x=0, y=0)
        render_9_part("box4",
                      self.width, h2,
                      x=0, y=h1)
        
        self.avatar.render()
        self.player_name.render()
        for status in ["life", "library", "hand", "graveyard"]: #, "exile"]:
            symbol, value = self.symbols[status], self.values[status]
            symbol.render()
            value.render()
        self.manapool.render()
        self.zone_view.render()
        if self._reveal_library: self._library.render()
Ejemplo n.º 16
0
 def add_sparkle_star(self, start_pos, end_pos, dt=1.0, color=None, dim=2):
     if color == None: color = (1., 0.9, 0)
     elif isinstance(color, str): color = self.COLORS.get(color)
     else: color = color
     spark = Image('targeting', pos=start_pos)
     spark.visible = anim.animate(1., 0., dt=dt)
     spark.rotatez = anim.animate(15, -45, dt=dt, method="sine")
     spark.scale = anim.animate(0.2, 1.5, dt=dt, method="sine")
     spark.color = color
     spark.alpha = anim.animate(1.0, 0., dt=dt)
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
     dt = 0.75*dt
     spark = Image('glow', pos=start_pos)
     spark._pos.set_transition(dt=dt, method="ease_out_circ")
     spark.pos = end_pos
     spark.color = color
     spark.visible = anim.animate(1., 0., dt=dt)
     spark.alpha = anim.animate(1.0, 0., dt=dt)
     spark.scale = anim.animate(0.5, 1.5, dt=dt, method="sine")
     if dim == 2: self.active_sparks.append(spark)
     else: self.active_sparks_3d.append(spark)
Ejemplo n.º 17
0
class StatusView(Widget):
    alpha = anim.Animatable()

    def __init__(self, pos=zero, is_opponent=False):
        super(StatusView, self).__init__(pos)
        self._toggled = False
        self._spacing = 10
        self._reveal_library = False
        self.color = (0.5, 0.5, 0.5)
        self.is_opponent = is_opponent
        #self._pos.set_transition(dt=0.1, method="linear")
        #symbols = ["life", "library", "hand", "graveyard", "exile"]
        symbols = ["life", "hand", "library", "graveyard", "exile"]
        self.symbols = dict([(symbol, cls(symbol)) for symbol, cls in zip(
            symbols, [Image, Image, Image, Image, Image])])
        for symbol in self.symbols.values():
            symbol.alpha = 0.8
        self.player_name = Label("",
                                 11,
                                 halign="left",
                                 fontname="Arial Bold",
                                 valign="center",
                                 shadow=False)
        #sizes = [20, 16, 14, 14, 14]
        sizes = [20, 14, 14, 14, 14]
        self.values = dict([(symbol,
                             Label('',
                                   size,
                                   fontname="Arial Bold",
                                   halign="center",
                                   valign="center",
                                   shadow=False))
                            for symbol, size in zip(symbols, sizes)])
        #for val in self.values.values():
        self.avatar = Image(pyglet.image.Texture.create(80, 80))
        self.avatar.shaking = 0
        self.avatar.alpha = anim.animate(1., 1., dt=0.25)
        self.alpha = anim.animate(1., 1., dt=0.25)

        self.manapool = ManaPool(is_opponent)
        self.zone_view = ZoneView()
        self._library = LibraryImage(is_opponent)
        self.width, self.height = 145, 135

    #    self.layout()
    def resize(self, width, height):
        self.layout()
        #    offset = 5
        #    if self.is_opponent:
        #        pos = euclid.Vector3(offset, height-self.height-offset, 0)
        #    else:
        #        pos = euclid.Vector3(offset, offset, 0)
        #    self._pos.set(pos)
        self._orig_pos = self.pos

    def clear(self):
        self.symbols['life'].rotatey = anim.constant(0)
        status = self.values
        counters = ["life", "hand", "library", "graveyard", "exile"]
        for c in counters:
            status[c].set_text(0)

    def toggle(self):
        if not self._toggled:
            x = self.width - self.values['life'].width - self._spacing * 1.5
            self.pos += euclid.Vector3(-x, 0, 0)
        else:
            self.pos = self._orig_pos
        self._toggled = not self._toggled

    def toggle_library(self):
        self._reveal_library = not self._reveal_library

    def animate(self, status):
        symbol = self.symbols[status]
        symbol.scale = anim.animate(symbol.scale,
                                    1.15 * symbol.scale,
                                    dt=1.0,
                                    method=lambda t: anim.oscillate_n(t, 3))

    def handle_click(self, x, y):
        x -= self.pos.x
        y -= self.pos.y
        for status, item in self.symbols.items():
            sx, sy, sw, sh = item.pos.x, item.pos.y, item.width / 2., item.height / 2.
            if x > sx - sw and x < sx + sw and y >= sy - sh and y <= sy + sh:
                return status
        else:
            return (0 < x <= self.width and 0 < y <= self.height)

    def setup_player(self, player, color, avatar):
        self.player = player
        self.color = color
        self.avatar.img = avatar.get_texture()
        self.player_name.set_text(player.name)
        self.update_life()
        for zone in ["library", "hand", "graveyard", "exile"]:
            self.update_zone(getattr(player, zone))

    def new_turn(self, player):
        return
        life = self.symbols["life"]
        if self.player == player:
            life.rotatey = anim.animate(0,
                                        360,
                                        dt=5,
                                        method='linear',
                                        extend='repeat')
        else:
            life.rotatey = anim.constant(0)

    def pass_priority(self, player):
        alpha = 1.0 if self.player == player else 0.6
        self.alpha = self.avatar.alpha = alpha

    def animate_life(self, amount):
        symbol = self.symbols["life"]
        curr_scale = symbol._final_scale
        if amount > 0: final_scale = curr_scale * 1.5
        else: final_scale = curr_scale * 0.5
        symbol._scale = anim.animate(curr_scale,
                                     final_scale,
                                     dt=0.75,
                                     method="oscillate")
        symbol.alpha = anim.animate(symbol.alpha,
                                    0.7,
                                    dt=0.75,
                                    method="oscillate")
        self.update_life()

    def update_life(self):
        status = self.values
        player = self.player
        counters = ["life"]  #, "poison"]
        for c in counters:
            status[c].set_text(getattr(player, c))

    def update_zone(self, zone):
        val = len(zone)
        status = self.values[str(zone)]
        if val > 0:
            #    self.symbols[str(zone)].alpha = 0.8
            status.set_text(val)
        else:
            #    self.symbols[str(zone)].alpha = 0.4
            status.set_text('0')
        if str(zone) == "library": self._library.update(zone)

    def layout(self):
        life_img, life = self.symbols["life"], self.values["life"]
        life_img.alpha = anim.constant(0.3)
        life_img._final_scale = 0.25
        life_img._scale = anim.constant(life_img._final_scale)
        #life_img.visible = anim.constant(0)
        avatar = self.avatar
        spacing = self._spacing
        if self.is_opponent:
            x, y = spacing, life.height / 2.

            self.player_name.pos = euclid.Vector3(x, y, 0)
            self.manapool.pos = euclid.Vector3(self.width, 0, 0)
            x = self.width - life.width / 2 - spacing
            life.pos = life_img.pos = euclid.Vector3(x, y, 0)

            for i, status in enumerate(["graveyard", "library", "hand"]):
                symbol, value = self.symbols[status], self.values[status]
                #symbol.scale = 0.3
                #symbol.pos = value.pos = euclid.Vector3(x, life.height+spacing+symbol.height/2+0.7*i*(symbol.height), 0)
                symbol.pos = value.pos = euclid.Vector3(
                    x, life.height + spacing / 2 + symbol.height / 2 + i *
                    (symbol.height), 0)

            library, lib = self._library, self.symbols["library"]
            library.scale = 0.5
            library.pos = euclid.Vector3(
                self.width, life.height + spacing / 2 + 1.5 * lib.height, 0)
            #status = "library"
            #library, value = self.symbols["library"], self.values["library"]
            #library.scale = 0.3
            #library.pos = value.pos = euclid.Vector3(spacing + library.width/2, life.height+library.height/2+spacing,0)
            avatar.pos = euclid.Vector3(
                spacing + avatar.width / 2,
                life.height + avatar.height / 2 + spacing, 0)
        else:
            x, y = spacing, self.height - life.height / 2.

            self.player_name.pos = euclid.Vector3(x, y, 0)
            self.manapool.pos = euclid.Vector3(self.width, self.height, 0)
            x = self.width - life.width / 2 - spacing
            life.pos = life_img.pos = euclid.Vector3(x, y, 0)

            for i, status in enumerate(["graveyard", "library", "hand"][::-1]):
                symbol, value = self.symbols[status], self.values[status]
                #symbol.scale = 0.3
                #symbol.pos = value.pos = euclid.Vector3(x, self.height-life.height-symbol.height/2-0.7*i*(symbol.height), 0)
                symbol.pos = value.pos = euclid.Vector3(
                    x, self.height - life.height - symbol.height / 2 - i *
                    (symbol.height) - spacing / 2, 0)

            library, lib = self._library, self.symbols["library"]
            library.scale = 0.5
            library.pos = euclid.Vector3(self.width, 1.5 * lib.height, 0)
            #status = "library"
            #library, value = self.symbols["library"], self.values["library"]
            #library.scale = 0.3
            #library.pos = value.pos = euclid.Vector3(spacing + library.width/2, self.height-life.height-library.height/2-spacing,0)
            avatar.pos = euclid.Vector3(
                spacing + avatar.width / 2,
                self.height - life.height - avatar.height / 2 - spacing, 0)

    def render_after_transform(self):
        ac = self.color
        glColor4f(ac[0], ac[1], ac[2], self.alpha)
        life_height = self.values['life'].height
        h1, h2 = self.height - life_height, life_height
        if self.is_opponent: h1, h2 = h2, h1
        render_9_part("box4", self.width, h1, x=0, y=0)
        render_9_part("box4", self.width, h2, x=0, y=h1)

        self.avatar.render()
        self.player_name.render()
        for status in ["life", "library", "hand", "graveyard"]:  #, "exile"]:
            symbol, value = self.symbols[status], self.values[status]
            symbol.render()
            value.render()
        self.manapool.render()
        self.zone_view.render()
        if self._reveal_library: self._library.render()