Ejemplo n.º 1
0
    def __init__(self,parent=None,save_path=None):
        self.save_path = save_path
        self.last_save_string = "Rhythm Desk"
        self.window = Toplevel(parent)
        if save_path:
            self.window.title(os.path.basename(save_path)+" Rhythm Editor Desk")
        else:
            self.window.title("Rhythm Editor Desk")
        self.rhythmletstack = []
        self.window.grid_columnconfigure(0,weight=0)
        self.window.grid_columnconfigure(1,weight=1)        
        self.window.grid_rowconfigure(0,weight=1)        
        self.tcontainer = Frame(self.window)
        self.tcontainer.grid(row=0,column=0,sticky=N+S+E+W)
        self.tvariable = ArrayVar(self.window)
        self.tvariable.set("-1,0","Rhythmlets")
        self.table = Table(self.tcontainer, rows=1,\
                           cols=1,titlerows=1,titlecols=0,roworigin=-1,\
                           colorigin=0,selectmode='browse',\
                           rowstretch='none',colstretch='all',\
                           variable=self.tvariable,drawmode='slow',\
                           state='disabled',colwidth=30)
        self.table.pack(side=LEFT,expand=1,fill='both')
        self.scrollbar = Scrollbar(self.tcontainer)
        self.scrollbar.pack(side=LEFT,fill=Y)
        self.scroll_callback = ScrollDummy(self.table)
        self.scrollbar.config(command=self.scroll_callback.yview)
        self.table.config(yscrollcommand=self.scrollbar.set)
        self.balloon = Balloon(self.window)
        self.r_buttons = Frame(self.window)
        self.r_buttons.grid(row=1,column=0,sticky=W)
        self.next_name = "A"
        self.second_op = -1
        self.canvas_op = -1

        def choose_second_op(event,s=self):
            row,col = s.table.index("@%i,%i"%(event.x,event.y)).split(",")
            row = int(row)
            s.second_op = row
            s.hilight_second_op()

        def calculate_meet(event,s=self):
            row,col = s.table.index("@%i,%i"%(event.x,event.y)).split(",")
            row = int(row)            
            if (0 <= s.second_op < len(s.rhythmletstack)) \
               and (0 <= row < len(s.rhythmletstack)):
                left = s.rhythmletstack[s.second_op]
                right = s.rhythmletstack[row]
                new_name = left[0]+" "*(max(utils.count_recurrences(left[0]," "))+1)\
                           + "&" + " "*(max(utils.count_recurrences(right[0]," "))+1)\
                           + right[0]
                idx = s.add_rhythmlet_var(new_name,left[1].____ref & right[1].____ref)
                s.second_op = idx
                s.hilight_second_op()

        def copy_by_mouse(event,s=self):
            row,col = s.table.index("@%i,%i"%(event.x,event.y)).split(",")
            row = int(row)
            if 0 <= row <= len(s.rhythmletstack):
                ob = s.rhythmletstack[row]
                new_name = ob[0] + "'"
                idx = s.add_rhythmlet_var(new_name,copy.deepcopy(ob[1].____ref))

        def copy_by_btn(event=None,s=self):
            row,col = s.table.index("active").split(",")
            row = int(row)
            if 0 <= row <= len(s.rhythmletstack):
                ob = s.rhythmletstack[row]
                new_name = ob[0] + "'"
                idx = s.add_rhythmlet_var(new_name,copy.deepcopy(ob[1].____ref))

        def calculate_join(event,s=self):
            row,col = s.table.index("@%i,%i"%(event.x,event.y)).split(",")
            row = int(row)            
            if (0 <= s.second_op < len(s.rhythmletstack)) \
               and (0 <= row < len(s.rhythmletstack)):
                left = s.rhythmletstack[s.second_op]
                right = s.rhythmletstack[row]
                new_name = left[0]+" "*(max(utils.count_recurrences(left[0]," "))+1)\
                           + "|" + " "*(max(utils.count_recurrences(right[0]," "))+1)\
                           + right[0]
                idx = s.add_rhythmlet_var(new_name,left[1].____ref | right[1].____ref)
                s.second_op = idx
                s.hilight_second_op()

        def new_rhythmlet(x=None,s=self):
            row = s.add_rhythmlet_var(s.get_next_name(),Rhythmlet())
            s.rename_rhythmlet_var(row)

        def rename_rhythmlet(x=None,s=self):
            row,col = s.table.index("active").split(",")
            row = int(row)
            s.rename_rhythmlet_var(row)

        def mouse_rename_rhythmlet(event,s=self):
            row,col = s.table.index("@%i,%i"%(event.x,event.y)).split(",")
            row = int(row)
            s.rename_rhythmlet_var(row)
            
        def del_rhythmlet(x=None,s=self):
            row,col = s.table.index("active").split(",")
            row = int(row)
            s.del_rhythmlet_var(row)
                    
        quicktix.add_balloon_button(self.__dict__,'new_btn','r_buttons','New',\
                                    new_rhythmlet,'Create a new rhythmlet.')
        quicktix.add_balloon_button(self.__dict__,'ren_btn','r_buttons','Rename',\
                                    rename_rhythmlet,\
                                    'Rename the currently selected rhythmlet.')
        quicktix.add_balloon_button(self.__dict__,'cpy_btn','r_buttons','Copy',\
                                    copy_by_btn,\
                                    'Create a copy of the currently selected rhythmlet')
        quicktix.add_balloon_button(self.__dict__,'del_btn','r_buttons','Delete',\
                                    del_rhythmlet,\
                                    'Deletes the currently selected rhythmlet. (Del)')
        
        
        def edit_rhythmlet(event,s=self):
            row,col = s.table.index("@%i,%i"%(event.x,event.y)).split(',')
            row = int(row)
            if row >= 0:
                RhythmletEditor(self.rhythmletstack[row][1],s.window,\
                                self.rhythmletstack[row][0]+" #"+str(row))

        def scroll_down(x=None,s=self):
            s.table.yview_scroll(1,"unit")
        def scroll_up(x=None,s=self):
            s.table.yview_scroll(-1,"unit")

        def pick_to_canvas(event,s=self):
            row,col = s.table.index("@%i,%i"%(event.x,event.y)).split(",")
            row = int(row)
            s.display_canvas(row)
            

        self.window.bind("<Button-4>",scroll_up)
        self.window.bind("<Button-5>",scroll_down)        

        self.table.bind("<Double-Button-1>",edit_rhythmlet)
        self.window.bind("<Delete>",del_rhythmlet)        
        self.table.bind("<Shift-Button-3>",mouse_rename_rhythmlet)
        self.table.bind("<Button-3>",choose_second_op)
        self.table.bind("<Button-2>",pick_to_canvas)
        self.table.bind("<Control-Button-2>", copy_by_mouse)
        self.table.bind("<Control-Button-1>",calculate_meet)
        self.table.bind("<Shift-Button-1>",calculate_join)                        
        self.fill_table()

        self.canvas = Canvas(self.window,width=300,height=300)
        self.canvas.grid(row=0,column=1,sticky=N+E+S+W)

        self.canvas_ids = []
        self.canvas_op = -1

        self.c_buttons = Frame(self.window)
        self.c_buttons.grid(row=1,column=1,sticky=W)

        def clear_canvas(x=None,s=self):
            s.canvas_ids = []
            s.update_canvas()

        def update_canvas(x=None,s=self):
            s.update_canvas()

        def to_canvas(x=None,s=self):
            row,col = s.table.index("active").split(",")
            row = int(row)
            s.display_canvas(row)

        def from_canvas(x=None,s=self):
            s.remove_canvas(s.canvas_op)

        quicktix.add_balloon_button(self.__dict__,"add_btn","c_buttons","← Add",\
                                    to_canvas,\
                                    "Add selected Rhythmlet to canvas.")
        quicktix.add_balloon_button(self.__dict__,"rmv_btn","c_buttons","Remove ↑",\
                                    from_canvas,\
                                    "Removes the selected canvas object from canvas."\
                                    " (Middle-Click)")
        quicktix.add_balloon_button(self.__dict__,"clr_btn","c_buttons","Clear",\
                                    clear_canvas,\
                                    "Clear all objects from canvas.")
        quicktix.add_balloon_button(self.__dict__,"upd_btn","c_buttons","Update",\
                                    update_canvas,\
                                    "Update shown relations on canvas.")

        def save_to_path(x=None,s=self):
            if s.save_path:
                path = str(s.save_path)
            else:
                path = ""
            i = inputbox("Rhytm Desk "+path,"Path = $"+path+"$")
            if i:
                s.save_to(i[0])

        quicktix.add_balloon_button(self.__dict__,"save_btn","c_buttons","Save",\
                                    save_to_path,\
                                    "Save the current rhythm desk.")
                

        def reconfigure(x=None,s=self):
            s.update_canvas()

        self.window.bind("<Configure>",reconfigure)

        def check_for_save(x=None,s=self):
            if s.to_string() != s.last_save_string:
                if s.save_path:
                    path = str(s.save_path)
                else:
                    path = ""
                if yesnobox("Rhythm Desk "+path,"Rhythm Desk has been changed.","",\
                            "Do you want to save now?"):
                    save_to_path(x,s)
            s.window.destroy()

        self.window.protocol("WM_DELETE_WINDOW",check_for_save)
        
        quicktix.min_win_size(self.window,600,400)
        quicktix.screencenter(self.window)
Ejemplo n.º 2
0
    def __init__(self,parent=None,path="",workspace=None):
        self.window = Toplevel(parent)
        self.workspace = workspace
        self.name = os.path.basename(path)+' Song Editor'
        self.path = path
        self.saved_data = ""
        self.line_type = ""
        self.table_data = {}
        self.current_table_data = []
        self.table_scroll = {}
        self.table_colwidth = 36
        self.colon_depth = 0
        self.window.title(self.name)
        self.window.grid_columnconfigure(0,weight=1)
        self.window.grid_rowconfigure(0,weight=1)
        self.text = ScrolledText(self.window)
        self.text.grid(row=0,column=0,sticky=N+E+S+W)
        self.text.subwidget("text").configure(foreground="cyan",\
                                              background="#000000",\
                                              font="courier 12",\
                                              insertbackground="#FFFFFF",\
                                              undo=1,autoseparators=1)
        self.balloon = Balloon(self.window)
        self.tcontainer = Frame(self.window)
        self.tcontainer.grid(row=0,column=1,rowspan=2,sticky=N+S+E+W)
        self.tvariable = ArrayVar(self.window)
        self.table = Table(self.tcontainer, rows=1,\
                           cols=1,titlerows=0,titlecols=0,roworigin=-1,\
                           colorigin=0,selectmode='browse',\
                           rowstretch='none',colstretch='all',\
                           variable=self.tvariable,drawmode='slow',\
                           state='disabled',colwidth=self.table_colwidth,\
                           font="courier 12",background="#222222",\
                           foreground="yellow",\
                           anchor=W)
        self.table.pack(side=LEFT,expand=1,fill='both')
        self.scrollbar = Scrollbar(self.tcontainer)
        self.scrollbar.pack(side=LEFT,fill=Y)
        self.scroll_callback = ScrollDummy(self.table)
        self.scrollbar.config(command=self.scroll_callback.yview)
        self.table.config(yscrollcommand=self.scrollbar.set)
        def scroll_table_up(x=None,s=self):
            s.table.yview_scroll(-1,"unit")
        def scroll_table_down(x=None,s=self):
            s.table.yview_scroll(1,"unit")
        self.table.bind("<Button-4>",scroll_table_up)
        self.table.bind("<Button-5>",scroll_table_down)
        self.table.tag_configure("heading",background="#000000",\
                                 foreground="#FF00FF",font="courier 12 bold")
        self.table.tag_cell("heading","-1,0")

        self.time_canvas = Canvas(self.window,height=120,background="#000000")
        self.time_canvas.grid(row=1,column=0,sticky=E+W+N)

        self.time_container = Frame(self.window)
        self.time_container.grid(row=2,column=0,sticky=W)

        self.time_container2 = Frame(self.time_container)
        self.time_container2.pack(side=RIGHT)

        self.table_row = None

        for i in range(1,5):
            def set_offset_to(x=None,s=self,txt=str(i)):
                s.time_offset.delete(0,END)
                s.time_offset.insert(END,txt)
            quicktix.add_balloon_button(self.__dict__,"btn_off"+str(i),\
                                        "time_container2",str(i),\
                                        set_offset_to,\
                                        "Set += time offset entry to "+str(i))

                                        
        self.time_offset = Entry(self.time_container,width=4,justify=RIGHT)
        self.time_offset.pack(side=RIGHT)
        self.time_offset.insert(END,"4")
        
        self.tolabel = Label(self.time_container,text="+=")
        self.tolabel.pack(side=RIGHT)

        self.time = Entry(self.time_container,width=4,justify=RIGHT)
        self.time.pack(side=RIGHT)
        self.time.insert(END,"0")

        self.time_canvas_factor = 1.0
        self.time_canvas_data = {}
        self.time_canvas_drag_txt = None
        self.time_canvas_drag_bbox = None


        self.tlabel = Label(self.time_container,text="@")
        self.tlabel.pack(side=RIGHT)

        for i in range(16)[-1::-1]:
            def set_time_to(x=None,s=self,txt=str(i)):
                s.time.delete(0, END)
                s.time.insert(END,txt)
            quicktix.add_balloon_button(self.__dict__, "btn_at"+str(i),\
                                        "time_container",str(i),\
                                        set_time_to,\
                                        "Set @ time entry to "+str(i))

        self.line_starts = Frame(self.window)
        self.line_starts.grid(row=3,column=0,columnspan=2,sticky=W)

        for txt in ["grammar=","length*=","bpm=","initial=","things=",\
                    "rhythms=","depth=","postprocess=",":","::",":::",\
                    "::::","taxa="]:
            txt2 = " "*(10-len(txt)) + txt
            txt2 = txt2.replace("="," = ")
            if txt.startswith(':'):
                txt2 = txt+" "
            def add_to_text(x=None,s=self,txt=txt2):
                line = int(s.text.subwidget("text").index("insert").split(".")[0])
                lastline = int(s.text.subwidget("text").index(END).split(".")[0])
                if line == lastline:
                    s.text.subwidget("text").insert("insert lineend","\n"+txt+"\n")
                else:
                    s.text.subwidget("text").insert("insert lineend","\n"+txt)
                s.text.subwidget("text").mark_set("insert","%i.%i"%(line+1,len(txt)))
                s.colorize_text_widget()
                s.text.subwidget("text").focus_set()
                
            quicktix.add_balloon_button(self.__dict__, "btn_txt"+txt,\
                                        "line_starts",txt,\
                                        add_to_text,\
                                        "Add "+txt+" line after insert line.")

        def add_lot_of_text(x=None,s=self):
            txt = """  grammar = g_2010
  initial = 
      bpm = 
  length* = 
  rhythms = 
   things = """
            line = int(s.text.subwidget("text").index("insert").split(".")[0])
            lastline = int(s.text.subwidget("text").index(END).split(".")[0])
            if line == lastline:
                s.text.subwidget("text").insert("insert lineend","\n"+txt+"\n")
            else:
                s.text.subwidget("text").insert("insert lineend","\n"+txt)
            s.text.subwidget("text").mark_set("insert","%i.%i"%(line+1,len(txt)))
            s.colorize_text_widget()
            s.text.subwidget("text").focus_set()
                
        quicktix.add_balloon_button(self.__dict__, "btn_txtlot",\
                                        "line_starts","...",\
                                        add_lot_of_text,\
                                        "Add common stuff...")

            

        self.right_buttons = Frame(self.window)
        self.right_buttons.grid(row=2,column=1,sticky=E)

        def save_cmd(x=None,s=self):
            s.save_to()
        
        def upd_cmd(x=None,s=self):
            if s.workspace != None:
                s.workspace.update_directory()
            s.prepare_table_data()
            s.table_update()
            s.colorize_text_widget()

        def close_handler(x=None,s=self):
            if s.to_string() != s.saved_data:
                if yesnobox(self.name,"The song has been changed.",\
                            "","Do you want to save it now?"):
                    s.save_to()
            s.window.destroy()

        self.window.protocol("WM_DELETE_WINDOW",close_handler)
        self.window.bind("<Control-s>",save_cmd)

        def undo_cmd(x=None,s=self):
            s.text.subwidget("text").edit_undo()
            s.colorize_text_widget()
            s.table_update()

        def redo_cmd(x=None,s=self):
            s.text.subwidget("text").edit_redo()
            s.colorize_text_widget()
            s.table_update()

        quicktix.add_balloon_button(self.__dict__,"btn_undo","right_buttons",\
                                    "Undo", undo_cmd,\
                                    "Undo the last edit action.")

        quicktix.add_balloon_button(self.__dict__,"btn_redo","right_buttons",\
                                    "Redo", redo_cmd,\
                                    "Redo the last undone edit action.")



        quicktix.add_balloon_button(self.__dict__,"btn_update","right_buttons",\
                                    "Update", upd_cmd,\
                                "Update the table and the text colorization. (F5)")
        quicktix.add_balloon_button(self.__dict__,"btn_save","right_buttons",\
                                    "Save", save_cmd,"Save the current file.",)

        self.window.bind("<F5>",upd_cmd)

        self.b1_start_position = END

        def tbl_update(x=None,s=self):
            idx = s.text.subwidget("text").index("@%i,%i"%(x.x,x.y))
            s.text.subwidget("text").mark_set("insert",idx)
            ranges = s.text.subwidget("text").tag_ranges(SEL)
            if ranges:
                start = s.text.subwidget("text").index(ranges[0])
                end = s.text.subwidget("text").index(ranges[1])
                s.text.subwidget("text").tag_remove(SEL,start,end)
            s.text.subwidget("text").tag_add(SEL,idx,idx)
            s.b1_start_position = idx
            s.text.subwidget("text").focus_set()
            s.table_update()
            return "break"

        def tbl_drag(x=None,s=self):
            idx = s.text.subwidget("text").index("@%i,%i"%(x.x,x.y))
            s.text.subwidget("text").mark_set("insert",idx)
            ranges = s.text.subwidget("text").tag_ranges(SEL)

            if ranges:
                start = s.text.subwidget("text").index(ranges[0])
                end = s.text.subwidget("text").index(ranges[1])
                s.text.subwidget("text").tag_remove(SEL,start,end)
            s.text.subwidget("text").tag_add(SEL,s.b1_start_position,idx)
            s.text.subwidget("text").tag_add(SEL,idx,s.b1_start_position)           
            return "break"

        def tbl_select_dbl(x=None,s=self):
            s.select_current_fragment()
            return "break"

        def tbl_select_trp(x=None,s=self):
            s.select_current_values()
            return "break"

        self.text.subwidget("text").bind("<Button-1>",tbl_update)
        self.text.subwidget("text").bind("<Double-Button-1>",tbl_select_dbl)
        self.text.subwidget("text").bind("<Triple-Button-1>",tbl_select_trp)
        self.text.subwidget("text").bind("<B1-Motion>",tbl_drag)

        def refresh_table(x=None,s=self):
            s.table_update()

        for key in ["<Left>","<Right>","<Up>","<Down>","<Return>","<Prior>","<Next>"]:
            self.text.subwidget("text").bind(key,refresh_table)


        def refocus_text(x=None,s=self):
            s.table_row = int(s.table.index("@%i,%i"%(x.x,x.y)).split(",")[0])
            s.text.subwidget("text").focus_set()

        def insert_text(x=None,s=self):
            s.table_row = int(s.table.index("@%i,%i"%(x.x,x.y)).split(",")[0])
            s.table_text()

        def open_in_editor(x=None,s=self):
            s.table_row = int(s.table.index("@%i,%i"%(x.x,x.y)).split(",")[0])
            s.do_edit(s.table_row)

        self.table.bind("<Button-1>",refocus_text)
        self.table.bind("<Double-Button-1>",refocus_text)
        self.table.bind("<Triple-Button-1>",refocus_text)

        self.table.bind("<Double-Button-1>",insert_text)
        self.table.bind("<Triple-Button-1>",insert_text)
        self.table.bind("<Double-Button-3>",open_in_editor)

        self.prepare_table_data()


        self.colorize_text_widget()
        self.text.subwidget("text").focus_set()
        quicktix.min_win_size(self.window,700,680)
        screencenter(self.window)