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)
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)