Exemple #1
0
    def __init_gui(self, glade):
        Common.connect_signals(glade, self)
        self.__main_window = glade.get_widget("mainWindow")
        groove_window = glade.get_widget("grooveWindow")
        tempo_window = glade.get_widget("tempoWindow")
        repeat_window = glade.get_widget("repeatWindow")
        repeat_end_window = glade.get_widget("repeatEndWindow")
        repeat_ending_window = glade.get_widget("repeatEndingWindow")
        self.__hbox8 = glade.get_widget("hbox8")
        self.__hbox7 = glade.get_widget("hbox7")
        # add event button
        self.__button17 = glade.get_widget("button17")
        # global groove and tempo buttons
        self.__togglebutton1 = glade.get_widget("togglebutton1")
        self.__togglebutton2 = glade.get_widget("togglebutton2")
        # global buttons
        self.__eventGroove = EventGroove(glade, self.__grooves)
        self.__eventTempo = EventTempo(glade)
        self.__triples.append([ self.__togglebutton1, groove_window, self.__eventGroove, None ])
        self.__triples.append([ self.__togglebutton2, tempo_window, self.__eventTempo, None ])
        # add event menu
        event_items = { Glob.A_GROOVE: "Groove change",
                      Glob.A_TEMPO: "Tempo change",
                      Glob.A_REPEAT: "Repeat",
                      Glob.A_REPEAT_ENDING: "RepeatEnding",
                      Glob.A_REPEAT_END: "RepeatEnd" }
        self.__addEventMenu = gtk.Menu()
        menu = self.__addEventMenu
        for key in Glob.EVENTS:
            item = gtk.MenuItem(event_items[key])
            item.connect_object("activate", self.__add_event, key)
            menu.append(item)
        menu.show_all()
        # for dynamic event creation
        self.__event_windows = { Glob.A_GROOVE: groove_window,
                              Glob.A_TEMPO: tempo_window,
                              Glob.A_REPEAT: repeat_window,
                              Glob.A_REPEAT_ENDING: repeat_ending_window,
                              Glob.A_REPEAT_END: repeat_end_window }

        self.__event_window_handlers = { Glob.A_GROOVE: self.__eventGroove, # reusing already existing object
                                      Glob.A_TEMPO: self.__eventTempo,
                                      Glob.A_REPEAT: EventRepeat(glade),
                                      Glob.A_REPEAT_ENDING: EventRepeatEnding(glade),
                                      Glob.A_REPEAT_END: EventRepeatEnd(glade) }
Exemple #2
0
class EventsBar(object):

    def __init__(self, glade, song, gui, grooves):
        self.__song = song
        # triple = [ button, window, handler, event ]
        self.__triples = []
        # triple which window is currently active
        self.__toggled_triple = None
        # toggleWindowClose workaround
        self.__toggle_window_close_recursive = False
        # original label on toggle button just before opening the window
        self.__toggled_button_label = None
        # event which is being edited in the toggleWindow    
        self.__curr_event = None
        self.__grooves = grooves
        self.__gui = gui
        self.__init_gui(glade)

    def move_event_backwards_callback(self, widget):
        """ Move events button and it's window to the left. """
        box = self.__hbox8
        index = box.child_get_property(self.__toggled_triple[0], "position")
        if index > 0:
            # move event in the model
            barNum = self.__gui.get_current_bar_number()
            self.__song.get_data().get_bar_info(barNum).move_event_backwards(self.__curr_event)
            # move the button and its window
            box.reorder_child(self.__toggled_triple[0], index - 1)
            gobject.idle_add(self.__move_window_underneath, self.__toggled_triple[1], self.__toggled_triple[0])
            # we could have moved the tempo event to the beginning -> became the global tempo
            self.__refresh_globals()

    def move_event_forwards_callback(self, widget):
        """ Move events button and it's window to the right. """
        box = self.__hbox8
        index = box.child_get_property(self.__toggled_triple[0], "position")
        if index < len(box.get_children()) - 1:
            # move event in the model
            barNum = self.__gui.get_current_bar_number()
            self.__song.get_data().get_bar_info(barNum).move_event_forwards(self.__curr_event)
            # move the button and its window
            box.reorder_child(self.__toggled_triple[0], index + 1)
            gobject.idle_add(self.__move_window_underneath, self.__toggled_triple[1], self.__toggled_triple[0])
            # the global tempo or the global groove could have been changed
            self.__refresh_globals()

    def remove_event_callback(self, widget):
        """ Remove the event from event bar. """
        # remove event from the model
        barNum = self.__gui.get_current_bar_number()
        self.__song.get_data().get_bar_info(barNum).remove_event(self.__curr_event)
        # remove the window from the triples list
        self.__remove_from_triples(self.__toggled_triple[0])
        # remove button and close the window
        self.__hbox8.remove(self.__toggled_triple[0])
        self.__toggle_window_close() # deletes the self.__toggled_triple
        self.__refresh_globals()
        self.__gui.refresh_current_field() # repetition

    def add_event_clicked_callback(self, button):
        """ Add event button pressed. """
        menu = self.__addEventMenu
        x, y = self.__get_widget_xy_position(button, menu)
        self.__toggle_window_close()
        event = gtk.get_current_event()
        menu.popup(None, None, lambda menu: (x, y, True), event.button, event.time)

    def toggle_button_clicked_callback(self, button, event=None):
        """ User clicked on toggle button (global button or event button). """
        if button.get_active():
            # button is pressed in
            if self.__toggled_triple:
                # some other button is toggled
                self.__toggle_window_close()
            for triple in self.__triples:
                if triple[0] is button: break
            self.__toggled_button_label = button.get_label()
            if button is self.__togglebutton1:
                self.__curr_event = self.__song.get_data().get_bar_info(0).get_groove()
            elif button is self.__togglebutton2:
                self.__curr_event = self.__song.get_data().get_bar_info(0).get_tempo()
            else:
                self.__curr_event = event
            self.__move_window_underneath(triple[1], button)
            triple[2].init_window(button, self.__curr_event)
            triple[1].show()
            self.__toggled_triple = triple
        else:
            # button is released
            self.__toggle_window_close()

    def toggle_window_expose_event_callback(self, widget, event):
        self.__draw_window_border(widget)
        return False

    def toggle_window_cancel_callback(self, widget):
        """ Toggle window cancel button clicked. """
        self.__toggle_window_close(True)

    def toggle_window_ok_callback(self, widget, *args):
        """ Toggle window OK button clicked. """
        # we didn't touch the settings, don't set label
        newEvent = self.__toggled_triple[2].get_new_event()
        button = self.__toggled_triple[0]
        if not newEvent:
            self.__toggle_window_close(True)
        else:
            self.__toggle_window_close(False)
            if button in [self.__togglebutton1, self.__togglebutton2]:
                if not self.__curr_event: self.__song.get_data().get_bar_info(0).add_event(newEvent)
                else: self.__song.get_data().get_bar_info(0).replace_event(self.__curr_event, newEvent)
            else:
                barNum = self.__gui.get_current_bar_number()
                self.__song.get_data().get_bar_info(barNum).replace_event(self.__curr_event, newEvent)
            self.refresh_all() # global groove or global tempo could have been changed

    def main_window_configure_event_callback(self, widget, event):
        """ Everytime the main window is moved or resised, move the toggle window with it. """
        if self.__toggled_triple:
            self.__move_window_underneath(self.__toggled_triple[1], self.__toggled_triple[0])
        return False

    def toggle_window_key_pressed_event_callback(self, widget, event):
        """ If the Escape was pressed, close the toggle window. """
        key = event.keyval
        if key == gtk.keysyms.Escape:
            self.__toggle_window_close(True)
            return True

    def refresh_all(self):
        """ Refresh global buttons Select groove, Select tempo and event buttons. """
        self.__refresh_globals()
        self.__refresh_events_bar()

    def grab_focus(self):
        """ First event button or Add event button takes focus. """
        if len(self.__triples) > 0:
            self.__triples[0][0].grab_focus()
        else:
            self.__button17.grab_focus()

    def hide(self):
        self.__hbox7.hide()

    def show(self):
        self.__hbox7.show()

    def __init_gui(self, glade):
        Common.connect_signals(glade, self)
        self.__main_window = glade.get_widget("mainWindow")
        groove_window = glade.get_widget("grooveWindow")
        tempo_window = glade.get_widget("tempoWindow")
        repeat_window = glade.get_widget("repeatWindow")
        repeat_end_window = glade.get_widget("repeatEndWindow")
        repeat_ending_window = glade.get_widget("repeatEndingWindow")
        self.__hbox8 = glade.get_widget("hbox8")
        self.__hbox7 = glade.get_widget("hbox7")
        # add event button
        self.__button17 = glade.get_widget("button17")
        # global groove and tempo buttons
        self.__togglebutton1 = glade.get_widget("togglebutton1")
        self.__togglebutton2 = glade.get_widget("togglebutton2")
        # global buttons
        self.__eventGroove = EventGroove(glade, self.__grooves)
        self.__eventTempo = EventTempo(glade)
        self.__triples.append([ self.__togglebutton1, groove_window, self.__eventGroove, None ])
        self.__triples.append([ self.__togglebutton2, tempo_window, self.__eventTempo, None ])
        # add event menu
        event_items = { Glob.A_GROOVE: "Groove change",
                      Glob.A_TEMPO: "Tempo change",
                      Glob.A_REPEAT: "Repeat",
                      Glob.A_REPEAT_ENDING: "RepeatEnding",
                      Glob.A_REPEAT_END: "RepeatEnd" }
        self.__addEventMenu = gtk.Menu()
        menu = self.__addEventMenu
        for key in Glob.EVENTS:
            item = gtk.MenuItem(event_items[key])
            item.connect_object("activate", self.__add_event, key)
            menu.append(item)
        menu.show_all()
        # for dynamic event creation
        self.__event_windows = { Glob.A_GROOVE: groove_window,
                              Glob.A_TEMPO: tempo_window,
                              Glob.A_REPEAT: repeat_window,
                              Glob.A_REPEAT_ENDING: repeat_ending_window,
                              Glob.A_REPEAT_END: repeat_end_window }

        self.__event_window_handlers = { Glob.A_GROOVE: self.__eventGroove, # reusing already existing object
                                      Glob.A_TEMPO: self.__eventTempo,
                                      Glob.A_REPEAT: EventRepeat(glade),
                                      Glob.A_REPEAT_ENDING: EventRepeatEnding(glade),
                                      Glob.A_REPEAT_END: EventRepeatEnd(glade) }

    def __refresh_events_bar(self):
        """ Refresh events bar """
        if self.__gui.is_cursor_on_bar_chords(): return
        barNum = self.__gui.get_current_bar_number()
        box = self.__hbox8
        children = box.get_children()
        # remove widgets from triples and events bar
        for child in children:
            self.__remove_from_triples(child)
            box.remove(child)
        # recreate event buttons
        events = self.__song.get_data().get_bar_info(barNum).get_events()
        for event in events:
            title = event[0]
            button = gtk.ToggleButton()
            window = self.__event_windows[title]
            handler = self.__event_window_handlers[title]
            self.__triples.append([button, window, handler, event])
            handler.set_label_from_event(button, event)
            button.connect("clicked", self.toggle_button_clicked_callback, event)
            box.pack_start(button, False, False, 0)
            button.show()

    def __add_event(self, key):
        """ Add selected event and open its window """
        barNum = self.__gui.get_current_bar_number()
        event = BarInfo.create_event(key)
        self.__song.get_data().get_bar_info(barNum).add_event(event)
        self.refresh_all()
        self.__gui.refresh_current_field() # repetition
        # open the new event window
        for triple in self.__triples:
            if triple[3] is event:
                gobject.idle_add(triple[0].clicked)
                break

    def __remove_from_triples(self, button):
        for triple in self.__triples:
            if triple[0] is button: break
        if triple[0] is button:
            self.__triples.remove(triple)

    def __move_window_underneath(self, gtkwindow, widget):
        """ Move window to appear directly under the toggled button """
        rect = widget.get_allocation()
        rect2 = self.__main_window.get_allocation() # (0, 0, 1100, 700)

        # black magic to get the correct values into rect3 
        gtkwindow.realize()
        gtkwindow.window.get_root_origin()

        rect3 = gtkwindow.get_allocation()

        # this has a side effect that x, y on the following line are set properly
        x1, y1 = self.__main_window.window.get_root_origin() # decoration window  @UnusedVariable
        x, y = self.__main_window.window.get_origin() # our window

        wx = min(x + rect.x, x + rect2.width - rect3.width)
        wy = y + rect.y + rect.height

        gtkwindow.move(wx, wy)

    def __get_widget_xy_position(self, widget, gtkwindow):
        #""" Move window to appear directly under the toggle button """
        rect = widget.get_allocation()
        rect2 = self.__main_window.get_allocation() # (0, 0, 1100, 700)

        # black magic to get the correct values into rect3 
        gtkwindow.realize()
        gtkwindow.window.get_root_origin()

        rect3 = gtkwindow.get_allocation()

        # this has a side effect that x, y on the following line are set properly
        x1, y1 = self.__main_window.window.get_root_origin() # decoration window  @UnusedVariable
        x, y = self.__main_window.window.get_origin() # our window

        wx = min(x + rect.x, x + rect2.width - rect3.width)
        wy = y + rect.y #+ rect.height

        return (wx, wy)

    def __draw_window_border(self, widget):
        """ toggle windows have no decoration, we draw the border ourselvtoggleWindowClose(es """
        window = widget.bin_window
        g = window.get_geometry()
        width = g[2]
        height = g[3]
        gc = window.new_gc()
        brown = widget.get_colormap().alloc_color('#AAAAA3')
        gc.set_foreground(brown)
        window.draw_rectangle(gc, False, 0, 0, width - 1, height - 1)

    def __toggle_window_close(self, restoreLabel=True):
        """ Close toggle window """
        if self.__toggle_window_close_recursive: return
        if self.__toggled_triple:
            if restoreLabel: self.__toggled_triple[0].set_label(self.__toggled_button_label)
            self.__toggled_triple[1].hide()
            # this will invoke on_togglebutton_clicked and then this method recursive again!
            self.__toggle_window_close_recursive = True
            self.__toggled_triple[0].set_active(False)
            self.__toggle_window_close_recursive = False
            self.__toggled_triple = None

    def __refresh_globals(self):
        """ Sets the global groove and global tempo labels """
        if self.__gui.get_current_bar_number() == 0:
            groove = self.__song.get_data().get_bar_info(0).get_groove()
            self.__eventGroove.set_label_from_event(self.__togglebutton1, groove)
            tempo = self.__song.get_data().get_bar_info(0).get_tempo()
            self.__eventTempo.set_label_from_event(self.__togglebutton2, tempo)