import gtk import time import math from copy import deepcopy from Musicpainter import * _showGraphcisEvent = False class Canvas(gtk.DrawingArea): def __init__(self, wid, hei, platform, mp): self.main = mp self.platform = platform self.width, self.height = wid, hei self.init_data() self.init_graphics() gtk.DrawingArea.__init__(self) self.set_size_request(self.width, self.height) # Event signals self.connect("expose_event", self.expose_event) self.connect("configure_event", self.configure_event) self.connect("enter_notify_event", self.enter_notify_event) self.connect("leave_notify_event", self.leave_notify_event) self.connect("motion_notify_event", self.motion_notify_event) self.connect("button_press_event", self.button_press_event) self.connect("button_release_event", self.button_release_event) self.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.LEAVE_NOTIFY_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK) def zeros(self, n1, n2): array = [[0 for i in range(n2)] for j in range(n1)] return array def init_data(self): self.ready = 0 self.button_highlight = -1 if self.platform == "sugar-xo": self.btns = ["Explore", "Load", "Clear"] else: self.btns = ["Explore", "Load", "Save", "Clear", "Quit"] self.dblclick_state = 0 self.fix_button = 0 self.just_clean = 0 self.last_gx_key = -1 self.last_gx, self.last_gy = -1, -1 self.start_drag_gx, self.start_drag_gy = -1, -1 self.rec_gx, self.rec_gy = -1, -1 self.ngrid_h = 64 self.ngrid_v = 18 self.drag_state = 0 self.last_hgx = -1 self.cursor_x = -1 (self.tsx, self.tsy) = (-1, -1) (self.tgx, self.tgy) = (-1, -1) self.mask = self.zeros(self.ngrid_h, self.ngrid_v) self.mask_buf = self.zeros(self.ngrid_h, self.ngrid_v) self.umask = self.zeros(self.ngrid_h, self.ngrid_v) def init_graphics(self): self.cx = (int)(0.09 * self.width) self.cy = 16 self.btn_h = 42 # print str(self.width) + "," + str(self.height) vh = 1.0 * (self.width - 1.33 * self.cx) / self.ngrid_h self.gridw = (int)(vh) vv = 1.0 * (self.height - self.cy - self.cy) / self.ngrid_v self.gridh = (int)(vv) # if self.platform == "sugar-xo": # self.gridh = 30 # self.gridw = 16 # else: # "windows-1024", default # self.gridh = 22 # self.gridw = 14 self.blue = gtk.gdk.Color(0,1280,57600) self.green = gtk.gdk.Color(9728,38912,4608) self.red = gtk.gdk.Color(65535,15000,15000) self.yellow = gtk.gdk.Color(64000, 65000, 500) self.purple = gtk.gdk.color_parse('purple') self.orange = gtk.gdk.color_parse('orange') self.lblue = gtk.gdk.Color(0, 65535, 65535) self.grass = gtk.gdk.Color(41728, 63744, 512) self.color_list = [self.red,self.orange,self.yellow,self.grass,self.green,self.lblue,self.blue,self.purple] def expose_event(self, widget, event): cr = self.pixmap.cairo_create() # set a clip region for the expose event x , y, width, height = event.area cr.rectangle(x, y, width, height) cr.clip() self.draw_canvas(cr) self.draw_score(cr) self.draw_buttons(cr) self.widget = widget self.ready = 1 widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, x, y, x, y, width, height) return False # ===================================================================================================================================================== def configure_event(self, widget, event): x, y, width, height = widget.get_allocation() # print "configure_event width = " + str(width) + ", height = " + str(height) self.pixmap = gtk.gdk.Pixmap(widget.window, width, height) return True def enter_notify_event(self, widget, event): # print "canvas.enter" self.main.cursor_area = 2 self.main.grab_focus() def leave_notify_event(self, widget, event): # print "canvas.leave" if self.main.cursor_area == 2: self.main.cursor_area = 0 if self.main.toolbar.toolsel == 1: return self.clear_grid_cursor(widget, self.main.toolbar.toolsel) (self.last_gx, self.last_gy) = (-1, -1) def button_press_event(self, widget, event): # print "canvas.mouse_btn_press (%d,%d)" % (event.x, event.y) self.fix_button = self.fix_button + 1 if self.fix_button != 1: return if event.button == 1: gx, gy = self.within_score(event.x, event.y) #print "gx,gy = (%d,%d)" % (gx, gy) toolbar = self.main.toolbar score = self.main.score if gx!=-1: # if the cursor is within the score area if toolbar.toolsel == 1: if self.dblclick_state == 2 and self.last_drag_gx == gx and self.last_drag_gy == gy: self.dblclick_state = 3 else: self.dblclick_state = 1 (self.last_drag_gx, self.last_drag_gy) = (gx, gy) if toolbar.toolsel == 2 or toolbar.toolsel == 3 or toolbar.toolsel == 4: if score.select_state == 1: score.de_selection() self.draw_deselection() if self.is_rec() and self.cursor_x != -1 and toolbar.toolsel == 2: gx = self.cursor_x self.rec_gx = gx self.rec_gy = gy self.draw_cell(widget, gx, gy, True) else: self.draw_cell(widget, gx, gy) self.just_clean = 0 elif toolbar.toolsel == 1: # region-selecting mode (self.start_drag_gx, self.start_drag_gy) = (gx, gy) if score.select_state == 1: if self.is_cursor_on_selection(gx, gy): score.drag = deepcopy(score.sel) score.dcut = deepcopy(score.scut) self.drag_state = 1 else: if self.main.press_ctrl == 0: # if has current selection but not in union mode, de-select first score.de_selection() self.draw_deselection() self.draw_grid_cursor(widget, gx, gy, toolbar.toolsel) else: self.draw_grid_cursor(widget, gx, gy, toolbar.toolsel) elif toolbar.toolsel <= 0: # f or p if toolbar.toolsel == 0 and toolbar.fstate != 0 or toolbar.toolsel == -1 and toolbar.pstate != 0: # region_mode (self.start_drag_gx, self.start_drag_gy) = (gx, gy) self.draw_grid_cursor(widget, gx, gy, toolbar.toolsel) else: v = self.adjust_volume(gx, gy, toolbar.toolsel) if v != -1: self.main.score.drag_on_vol(self.main.csound, toolbar.toolsel, toolbar.colorsel, gy, v) else: t = self.is_on_button(event.x, event.y) if self.platform == "sugar-xo" and t == 2: t = 3 # if t == 0: # Play # self.main.score.play_music(self.main.csound) # elif t == 1: # Stop # self.main.score.stop_music(self.main.csound) if t == 0: # Explore browser = self.main.browser if browser.flag == 0: self.main.bricksarea.change_into_browser() self.fix_button = 0 self.main.author_box.set_active(0) self.main.type_box.set_active(0) self.main.scale_box.set_active(0) browser.flag = 3 elif t == 1: # Load if score.select_state == 1: score.de_selection() self.draw_deselection() browser = self.main.browser if browser.flag == 0: self.main.bricksarea.change_into_browser() self.fix_button = 0 self.main.author_box.set_active(1) self.main.type_box.set_active(0) self.main.scale_box.set_active(0) browser.flag = 3 elif t == 2: # Save self.save_file() elif t == 3: # Clear self.main.score.filename = "" self.main.score.note = "" self.main.score.title = "" self.main.score.description = "" self.main.score.clear_score() cr = self.pixmap.cairo_create() self.draw_canvas(cr) self.draw_buttons(cr) self.draw_score(cr) widget = self.widget widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) elif t == 4: # Quit if self.main.bricksarea.brick_added: flag = False for i in range(self.main.score.work_bricks_cnt): # print self.main.score.work_bricks[i].is_blank if self.main.score.work_bricks[i].is_blank == 0: flag = True break if flag: if self.platform == "sugar-xo": self.main.window.set_canvas(self.main.msg1_layout) else: self.main.window.remove(self.main.layout) self.main.window.add(self.main.msg1_layout) self.main.now_layout = self.main.msg1_layout self.main.window.show_all() self.fix_button = 0 else: self.main.destroy0(widget) else: self.main.destroy0(widget) return True def save_file(self): score = self.main.score if score.select_state == 1: score.de_selection() self.draw_deselection() if self.main.score.filename == "": self.main.score.filename = self.main.username + "_0_" + str(self.main.score.scale_mode) + "_piece" + str(random.randint(0, 999999)) + ".mps" if self.main.save_as: self.main.save_as = False self.main.sbutton2.set_no_show_all(False) self.main.sbutton2.show() else: [a, ty, s] = self.main.browser.get_file_info(self.main.score.filename) if a != self.main.username: self.main.score.note = "Based on " + self.main.score.filename+ " - " + self.main.score.note self.main.score.filename = self.main.username + "_0_" + str(self.main.score.scale_mode) + "_piece" + str(random.randint(0, 999999)) + ".mps" if not self.main.save_as: self.main.save_as = True self.main.sbutton2.set_no_show_all(True) self.main.sbutton2.hide() else: if self.main.save_as: self.main.save_as = False self.main.sbutton2.set_no_show_all(False) self.main.sbutton2.show() if self.platform == "sugar-xo": self.main.window.set_canvas(self.main.msg2_layout) else: self.main.window.remove(self.main.layout) self.main.window.add(self.main.msg2_layout) self.main.mlabel3.set_text("Author: " + self.main.username) self.main.mlabel4.set_text("Scale: " + self.main.score.scale_list[self.main.score.scale_mode]) self.main.mlabel5.set_text("Filename: " + self.main.score.filename) self.main.entry2.set_text(self.main.score.title) self.main.entry3.set_text(self.main.score.description) self.main.entry4.set_text(self.main.score.note) self.main.window.show_all() self.main.key_lock = 1 self.fix_button = 0 def canvas_load_score(self, filename): #if self.main.score.is_edited: #self.main.window.remove(self.main.layout) #self.main.window.add(self.main.msg1_layout) #self.main.mlabel1.set_text("Do you want to save") #self.main.mlabel2.set_text("your current work?") #self.main.window.show_all() #self.load_pending = filename #return self.main.score.read_mpscore(filename) self.update_top() cr = self.pixmap.cairo_create() self.draw_canvas(cr) self.draw_buttons(cr) self.draw_score(cr) widget = self.widget widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) self.main.score.is_edited = False self.main.window.set_title("Music Painter - " + self.main.username) #self.main.window.show_all() def canvas_load_journal(self, filename): try: self.main.score.read_journal(filename) except: print "read journal exception caught" #print "update top" self.update_top() cr = self.pixmap.cairo_create() self.draw_canvas(cr) self.draw_buttons(cr) self.draw_score(cr) widget = self.widget widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) self.main.score.is_edited = False self.main.window.set_title("Music Painter - " + self.main.username) #self.main.window.show_all() def button_release_event(self, widget, event): # print "canvas.mouse_btn_release (%d,%d)" % (event.x, event.y) self.fix_button = 0 self.just_clean = 0 self.rec_gx = self.rec_gy = -1 toolbar = self.main.toolbar if toolbar.toolsel==1: # region-selecting mode gx, gy = self.within_score(event.x, event.y) if self.dblclick_state == 1 and gx == self.start_drag_gx and gy == self.start_drag_gy: if self.drag_state == 1: self.drag_state = 0 else: self.do_select_region(self.start_drag_gx, self.start_drag_gy, self.last_gx, self.last_gy, 1) self.draw_grid_cursor(widget, -1, -1, toolbar.toolsel) self.dblclick_state = 2 (self.last_drag_gx, self.last_drag_gy) = (gx, gy) elif self.dblclick_state == 3 and gx == self.start_drag_gx and gy == self.start_drag_gy: if self.drag_state == 1: self.drag_state = 0 self.draw_grid_cursor(widget, -1, -1, toolbar.toolsel) cr = self.pixmap.cairo_create() self.do_select_same_color(widget, cr, gx, gy) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) self.dblclick_state = 0 else: self.dblclick_state = 0 if self.drag_state == 1: self.drag_state = 0 bricka = self.main.bricksarea score = self.main.score t = bricka.is_on_brick(event.x, event.y - self.main.canvas_height) if t != -1 and t != bricka.bricks_cnt: score.bricks[t].dump_score(score.drag, score.dcut, score.scale_mode, score.key_shift) score.bricks[t].sval = self.main.toolbar.sval score.bricks[t].filename = "" bricka.draw_scores() else: self.do_select_region(self.start_drag_gx, self.start_drag_gy, self.last_gx, self.last_gy, 1) self.draw_grid_cursor(widget, -1, -1, toolbar.toolsel) (self.start_drag_gx, self.start_drag_gy) = (-1, -1) elif toolbar.toolsel == -1 and toolbar.pstate != 0 or toolbar.toolsel == 0 and toolbar.fstate != 0: if toolbar.toolsel == -1 and toolbar.pstate == 1: mode = 0 elif toolbar.toolsel == -1 and toolbar.pstate == 2: mode = 2 elif toolbar.toolsel == 0 and toolbar.fstate == 1: mode = 1 elif toolbar.toolsel == 0 and toolbar.fstate == 2: mode = 3 self.draw_grid_cursor(widget, -1, -1, 1) self.adjust_volume_in_selected_region(self.start_drag_gx, self.start_drag_gy, self.last_gx, self.last_gy, mode) (self.start_drag_gx, self.start_drag_gy) = (-1, -1) self.main.score.drag_off(self.main.csound, toolbar.toolsel, toolbar.colorsel) # note_off return def is_rec(self): return (self.main.score.play_state != -2 and self.main.toolbar.record == 1) def motion_notify_event(self, widget, event): if self.ready == 0: return if event.is_hint: x, y, state = event.window.get_pointer() else: x, y = event.x, event.y state = event.state if state & gtk.gdk.BUTTON1_MASK: gx, gy = self.within_score(event.x, event.y) toolbar = self.main.toolbar if gx!=-1 and (toolbar.toolsel == 2 or toolbar.toolsel == 3): if self.is_rec() == 1 and self.cursor_x != -1 and toolbar.toolsel == 2: gx = self.cursor_x if self.rec_gx == gx and self.rec_gy != gy: self.erase_cell(widget, gx, self.rec_gy) self.draw_cell(widget, gx, gy, True) self.rec_gx = gx self.rec_gy = gy elif not (gx == self.last_drag_gx and gy == self.last_drag_gy): self.draw_cell(widget, gx, gy) (self.last_drag_gx, self.last_drag_gy) = (gx, gy) if gx!=-1 and (toolbar.toolsel == -1 and toolbar.pstate == 0 or toolbar.toolsel == 0 and toolbar.fstate == 0) and not (gx == self.last_drag_gx and gy == self.last_drag_gy): v = self.adjust_volume(gx, gy, toolbar.toolsel) if v != -1: self.main.score.drag_on_vol(self.main.csound, toolbar.toolsel, toolbar.colorsel, gy, v) (self.last_drag_gx, self.last_drag_gy) = (gx, gy) if self.drag_state == 1: if (self.dblclick_state == 1 or self.dblclick_state == 3) and (self.start_drag_gx != gx or self.start_drag_gy != gy): self.dblclick_state = 0 bricka = self.main.bricksarea score = self.main.score if bricka.active_group != 0 and bricka.is_on_brickarea(event.x, event.y - self.main.canvas_height): bricka.change_active_group(0) t = bricka.is_on_brick(event.x, event.y - self.main.canvas_height) # drag seleted brick to bricks_area if t != -1 and t != bricka.bricks_cnt: t2 = bricka.brick_highlight bricka.brick_highlight = t if t2 != -1 and t2 != t: bricka.draw_1_score(t2) if t2 != t: bricka.draw_1_score_b(t, self.main.score.drag, self.main.score.dcut) elif bricka.brick_highlight != -1: # cursor leave bricks_area t2 = bricka.brick_highlight bricka.brick_highlight = -1 bricka.draw_1_score(t2) if t != -1 and t != bricka.bricks_cnt: if not (gx == self.start_drag_gx and gy == self.start_drag_gy): self.move_selection(self.start_drag_gx, self.start_drag_gy, self.start_drag_gx, self.start_drag_gy) (self.last_gx, self.last_gy) = (self.start_drag_gx, self.start_drag_gy) else: gx, gy = self.xy2gridxy(event.x, event.y) if not (gx == self.last_gx and gy == self.last_gy): self.move_selection(self.start_drag_gx, self.start_drag_gy, gx, gy) (self.last_gx, self.last_gy) = (gx, gy) else: gx, gy = self.within_score(event.x, event.y) out = False if self.is_rec() and self.cursor_x != -1 and self.main.toolbar.toolsel == 2: gx = self.cursor_x if gx < 0 or gx >= self.ngrid_h or gy < 0 or gy >= self.ngrid_v: out = True if (self.dblclick_state == 1 or self.dblclick_state == 3) and (self.start_drag_gx != gx or self.start_drag_gy != gy): self.dblclick_state = 0 if not (gx == self.last_gx and gy == self.last_gy) and not out: toolbar = self.main.toolbar if toolbar.toolsel == -1 and toolbar.pstate != 0 or toolbar.toolsel == 0 and toolbar.fstate != 0: self.draw_grid_cursor(widget, gx, gy, 1) else: self.draw_grid_cursor(widget, gx, gy, self.main.toolbar.toolsel) (self.last_gx, self.last_gy) = (gx, gy) t = self.is_on_button(event.x, event.y) if t != self.button_highlight and (self.button_highlight != -1 or t != -1): # t2 = self.button_highlight self.button_highlight = t cr = self.pixmap.cairo_create() widget = self.widget self.draw_buttons(cr) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.cx, self.height) return True # ===================================================================================================================================================== def is_on_button(self, x, y): if x < 12 or x >= self.cx - 12: return -1 for i in range(7): if y >= self.cy + i*self.btn_h and y < self.cy + i*self.btn_h + self.btn_h - 8: return i return -1 def draw_buttons(self, cr): cr.set_font_size(18) for i in range(len(self.btns)): (x0, y0) = (12, self.cy + i * self.btn_h) (x1, y1) = (self.cx-12, self.cy + i * self.btn_h + self.btn_h - 8) self.main.bricksarea.draw_curvy_rectangle(cr, x0, y0, x1, y1, 4, (self.button_highlight == i)) xb, yb, wid, hei = cr.text_extents(self.btns[i])[:4] cr.set_source_rgb(0.4, 0.4, 0.4) cr.move_to( (x0+x1)/2 - wid/2 - xb, (y0+y1)/2 - hei/2 - yb) cr.show_text(self.btns[i]) def move_selection(self, sx, sy, gx, gy): dx = gx - sx dy = gy - sy score = self.main.score score.copy_drag_2_sel(dx, dy) self.update_top() return def is_cursor_on_selection(self, gx, gy): for i in range(8): if self.main.score.sel[i][gx][gy] != 0: return True return False def draw_deselection(self): # print "draw_deselection" cr = self.pixmap.cairo_create() score = self.main.score self.draw_note_buf = list() for i in range(self.ngrid_h): for j in range(self.ngrid_v): f = 0 for k in range(8): if score.bsel[k][i][j] != 0: # finish de-selection f = 1 if f == 1: self.draw_grid(self.widget, cr, i, j, score.top[i][j], 0, 1) self.execute_draw_buf(cr) self.widget.window.draw_drawable(self.widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) def max(self, a, b): if a > b: return a return b def select_all(self): score = self.main.score flag = 0 for i in range(self.ngrid_h): for j in range(self.ngrid_v): for k in range(8): # de-selection if score.sel[k][i][j] != 0: score.map[k][i][j] = max(score.map[k][i][j], score.sel[k][i][j]) score.cut[k][i][j] = score.scut[k][i][j] score.sel[k][i][j] = 0 score.scut[k][i][j] = 0 for i in range(self.ngrid_h): #select-all for j in range(self.ngrid_v): for k in range(8): if score.map[k][i][j] != 0: score.sel[k][i][j] = score.map[k][i][j] score.scut[k][i][j] = score.cut[k][i][j] score.map[k][i][j] = 0 score.cut[k][i][j] = 0 flag = 1 if flag == 1: # print "re_draw" score.select_state = 1 cr = self.pixmap.cairo_create() self.draw_score(cr) self.widget.window.draw_drawable(self.widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) def do_select_same_color(self, widget, cr, sx, sy): score = self.main.score t = score.top[sx][sy] if t == -1: return flag = 0 for i in range(self.ngrid_h): for j in range(self.ngrid_v): if score.map[t][i][j] != 0: flag = 1 score.sel[t][i][j] = score.map[t][i][j] score.scut[t][i][j] = score.cut[t][i][j] score.map[t][i][j] = 0 score.cut[t][i][j] = 0 for i in range(self.ngrid_h): for j in range(self.ngrid_v): if score.sel[t][i][j] != 0 and (i == 0 or score.sel[t][i-1][j] == 0 or score.scut[t][i-1][j] == 1): self.draw_selected_grid(widget, cr, i, j, t) if flag == 1: score.select_state = 1 def do_select_region(self, sx, sy, gx, gy, release = 0): if sx == -1 or gy == -1: # if cursor is out of bound, return return (sx, sy, gx, gy) = self.switch_order(sx, sy, gx, gy) score = self.main.score flag = 0 if release == 1: # move region from map to sel for i in range(gx-sx+1): for j in range(gy-sy+1): for k in range(8): # to do: select specific color if score.map[k][sx+i][sy+j] != 0 and (sx+i == 0 or score.map[k][sx+i-1][sy+j] == 0 or score.cut[k][sx+i-1][sy+j] == 1): len = 1 while score.cut[k][sx+i+len-1][sy+j] == 0 and (sx+i+len) < score.ngrid_h and score.map[k][sx+i+len][sy+j] != 0: len = len + 1 if sx+i+len-1 <= gx: flag = 1 for l in range(len): score.sel[k][sx+i+l][sy+j] = score.map[k][sx+i+l][sy+j] score.scut[k][sx+i+l][sy+j] = score.cut[k][sx+i+l][sy+j] score.map[k][sx+i+l][sy+j] = 0 score.cut[k][sx+i+l][sy+j] = 0 if flag == 1: score.select_state = 1 def adjust_volume_in_selected_region(self, sx, sy, gx, gy, mode): # 0: p 1: f 2: dim 3: cresc if sx == -1 or gy == -1: # if cursor is out of bound, return return (sx, sy, gx, gy) = self.switch_order(sx, sy, gx, gy) score = self.main.score lx = -1 cnt = 0 for i in range(gx-sx+1): for j in range(gy-sy+1): for k in range(8): if score.map[k][sx+i][sy+j] != 0 and (sx+i == 0 or score.map[k][sx+i-1][sy+j] == 0 or score.cut[k][sx+i-1][sy+j] == 1): if lx != i: lx = i cnt = cnt + 1 # count how many note are there in the area (notes play at the same time will be counted once only) lx = -1 cnt2 = 0 if cnt == 0: return cr = self.pixmap.cairo_create() widget = self.widget for i in range(gx-sx+1): for j in range(gy-sy+1): f = 0 for k in range(8): if score.map[k][sx+i][sy+j] != 0 and (sx+i == 0 or score.map[k][sx+i-1][sy+j] == 0 or score.cut[k][sx+i-1][sy+j] == 1): f = 1 if lx != i: lx = i cnt2 = cnt2 + 1 # count how many note are there in the area (notes play at the same time will be counted once only) if mode == 0: score.map[k][sx+i][sy+j] = score.map[k][sx+i][sy+j] * 0.88 elif mode == 1: score.map[k][sx+i][sy+j] = score.map[k][sx+i][sy+j] * 1.15 elif mode == 2: score.map[k][sx+i][sy+j] = score.map[k][sx+i][sy+j] * (1.0 - 0.3 * (cnt2-1) / (cnt-1)) elif mode == 3: score.map[k][sx+i][sy+j] = score.map[k][sx+i][sy+j] * (1.0 + 0.4 * (cnt2-1) / (cnt-1)) if score.map[k][sx+i][sy+j] >= 3: score.map[k][sx+i][sy+j] = 3 elif score.map[k][sx+i][sy+j] <= 0.2: score.map[k][sx+i][sy+j] = 0.2 if f == 1: c = score.top[sx+i][sy+j] self.draw_grid(widget, cr, sx+i, sy+j, c, 0) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) def get_first_color(self, gx, gy): c = self.main.toolbar.colorsel if self.main.score.map[c][gx][gy] != 0 or self.main.score.sel[c][gx][gy] != 0: return c for i in range(8): if self.main.score.map[i][gx][gy] != 0 or self.main.score.sel[i][gx][gy] != 0: return i return -1 def get_top_color_detail(self, gx, gy, sel): c = self.main.toolbar.colorsel if sel[c][gx][gy] != 0: return (c, 1) elif self.main.score.map[c][gx][gy] != 0: return (c, 0) for i in range(8): if sel[i][gx][gy] != 0: return (i, 1) elif self.main.score.map[i][gx][gy] != 0: return (i, 0) return (-1, -1) def update_top(self): score = self.main.score #score.top_buf = copy(score.top) for i in range(self.ngrid_h): for j in range(self.ngrid_v): score.top_buf[i][j] = score.top[i][j] score.top[i][j] = self.get_first_color(i, j) for i in range(self.ngrid_h): for j in range(self.ngrid_v): if score.top_buf[i][j] != score.top[i][j] and score.top[i][j] == -1: if i!=0 and score.top[i-1][j] != -1 and score.top_buf[i-1][j] == score.top[i-1][j]: score.top_buf[i-1][j] = -99 # force redraw if _showGraphcisEvent: print "force redraw (%d,%d)" % (i-1,j) if i+1 < self.ngrid_h and score.top[i+1][j] != -1 and score.top_buf[i+1][j] == score.top[i+1][j]: score.top_buf[i+1][j] = -99 if _showGraphcisEvent: print "force redraw (%d,%d)" % (i+1,j) if score.top[i][j] != -1 and score.top_buf[i][j] == score.top[i][j]: (c_A, is_sel_A) = self.get_top_color_detail(i, j, score.bsel) (c_B, is_sel_B) = self.get_top_color_detail(i, j, score.sel) if _showGraphcisEvent: print "top_color detail -> %d,%d %d,%d" % (c_A, is_sel_A, c_B, is_sel_B) if not (is_sel_A == is_sel_B and c_A == c_B): score.top_buf[i][j] = -99 if _showGraphcisEvent: print "force redraw (%d,%d)" % (i,j) # if score. cr = self.pixmap.cairo_create() widget = self.widget #for i in range(self.ngrid_h): #for j in range(self.ngrid_v): #if score.top[i][j] != score.top_buf[i][j]: #self.clean_cursor_mode(cr, i, j) self.umask = self.zeros(self.ngrid_h, self.ngrid_v) self.draw_note_buf = list() c = self.get_rev_color_list() c.insert(0, -1) sx = sy = ex = ey = -1 # print c for k in range(len(c)): for i in range(self.ngrid_h): for j in range(self.ngrid_v): if score.top[i][j] != score.top_buf[i][j]: if sx == -1 or i < sx: # maintain a minimum region (sx,sy)-(ex,ey) to be updated sx = i if ex == -1 or i > ex: ex = i if sy == -1 or j < sy: sy = j if ey == -1 or j > ey: ey = j if self.main.score.top[i][j] == c[k]: # print "draw (%d,%d,%d)"%(i,j,c[k]) if c[k] == -1: self.clear_note(cr, i, j, 1, 0, 1) else: self.draw_grid(widget, cr, i, j, score.top[i][j], (score.sel[c[k]][i][j] != 0), 1) # draw_note buffer mode self.execute_draw_buf(cr) #self.draw_canvas(cr) #self.draw_score(cr) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx+sx*self.gridw-1, self.cy+sy*self.gridh, self.cx+sx*self.gridw-1, self.cy+sy*self.gridh, (ex-sx+1)*self.gridw+2, (ey-sy+1)*self.gridh) #widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) def update_top_all(self): for i in range(self.ngrid_h): for j in range(self.ngrid_v): self.main.score.top[i][j] = self.get_first_color(i, j) cr = self.pixmap.cairo_create() self.draw_canvas(cr) self.draw_score(cr) widget = self.widget widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) def highlight_grid(self, erase_mode = False): if self.main.score.play_state != -1: return cr = self.pixmap.cairo_create() fa = False fb = False gx = (int)((self.main.score.currentTime - self.main.score.startSessionTime + self.main.score.score_start_time) / self.main.score.grid_tdiv) self.cursor_x = gx if (not erase_mode) and self.last_hgx == gx: return if gx < 0: return elif gx >= self.ngrid_h and not erase_mode: self.highlight_grid(True) self.last_hgx = -1 if self.main.toolbar.loop == 0: self.main.score.play_state = -2 self.main.toolbar.update() else: self.main.score.play_music(self.main.csound) # print "stop" return self.last_hgx = gx if gx != 0 and gx-1 < self.ngrid_h: fa = True if gx < self.ngrid_h: fb = True if not fa and not fb: if erase_mode: return self.last_hgx = -1 if self.main.toolbar.loop == 0: self.main.score.play_state = -2 self.main.toolbar.update() else: self.main.score.play_music(self.main.csound) return for j in range(self.ngrid_v): # original code, commented out by wuhsi, 03/03/2010 # if fa and self.main.score.top[gx-1][j] != -1 and (self.main.score.select_state == 0 or self.main.score.sel[self.main.score.top[gx-1][j]][gx-1][j] != 0): # self.draw_grid(self.widget, cr, gx-1, j, self.main.score.top[gx-1][j]) # if fb and self.main.score.top[gx][j] != -1 and (self.main.score.select_state == 0 or self.main.score.sel[self.main.score.top[gx][j]][gx][j] != 0): # if erase_mode: # self.draw_grid(self.widget, cr, gx, j, self.main.score.top[gx][j]) # else: # self.draw_grid(self.widget, cr, gx, j, -1) if fa: if self.main.score.top[gx-1][j] != -1: self.draw_grid(self.widget, cr, gx-1, j, self.main.score.top[gx-1][j]) else: self.clear_note(cr, gx-1, j, 1) if fb: if erase_mode: if self.main.score.top[gx][j] != -1: self.draw_grid(self.widget, cr, gx, j, self.main.score.top[gx][j]) else: self.clear_note(cr, gx, j, 1) else: self.draw_grid(self.widget, cr, gx, j, -1) sy = 0 ey = self.ngrid_v-1 if fa and fb: sx = gx-1 ex = gx elif fa: sx = gx-1 ex = gx-1 elif fb: sx = gx ex = gx self.widget.window.draw_drawable(self.widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx+sx*self.gridw-1, self.cy+sy*self.gridh, self.cx+sx*self.gridw-1, self.cy+sy*self.gridh, (ex-sx+1)*self.gridw+2, (ey-sy+1)*self.gridh) # self.widget.window.draw_drawable(self.widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) # print "score time = %.2f, score_end_time = %.2f" % (self.main.score.currentTime - self.main.score.startSessionTime, self.main.score.score_end_time) if not self.main.toolbar.from_start and not erase_mode and (self.main.score.currentTime - self.main.score.startSessionTime) > self.main.score.score_end_time: # print "call highlight_grid erase mode" self.highlight_grid(True) if self.main.toolbar.loop == 0: self.main.score.play_state = -2 self.main.toolbar.update() else: self.main.score.play_music(self.main.csound) return if gx < 0 or gx >= self.ngrid_h: return if self.rec_gx != -1 and self.rec_gy != -1: # writing notes in metro mode if gx != self.rec_gx and self.main.toolbar.colorsel != 7: self.draw_cell(self.widget, gx, self.rec_gy, True) self.rec_gx = gx elif self.is_rec() and self.last_gy != -1 and self.main.toolbar.toolsel == 2 and gx != self.last_gx: self.draw_grid_cursor(self.widget, gx, self.last_gy, self.main.toolbar.toolsel) self.last_gx = gx if self.is_rec() and self.last_gx_key != gx: # on timeline moved, write note if keyboard is pressed if self.main.toolbar.colorsel != 7: for i in range(self.ngrid_v): if self.main.score.keyon[i] != 0: self.paint_cell(self.widget, gx, i) self.last_gx_key = gx def write_note_keyboard(self, gy): if self.is_rec(): self.paint_cell(self.widget, self.last_gx_key, gy) def clear_note(self, cr, gx, gy, len, erase = 0, buf = 0): # given a cairo_context and the location of note, draw the area with white / bg color if buf == 1: self.draw_note_buf.append([gx,gy,len,1,erase,-1,-1]) return if _showGraphcisEvent: print "clean (%d, %d, %d)" % (gx, gy, len) x0, y0 = self.cx+gx*self.gridw, self.cy+gy*self.gridh+2 x1, y1 = x0+self.gridw*len, y0+self.gridh-4 gradient_change = self.set_gradient(self.set_cycle(),self.set_offset(),self.ngrid_v-gy-1) if erase == 1: cr.set_source_rgba(1, 1, 1, 0.7) cr.rectangle(x0, y0, x1-x0, y1-y0) else: #cr.set_source_rgb(0.93, 0.86, 0.72) cr.set_source_rgb(1.0-gradient_change, 0.95-gradient_change, 0.80-gradient_change) cr.rectangle(x0-1, y0-1, x1-x0+2, y1-y0+2) cr.fill() def draw_note(self, cr, gx, gy, len, c, v, sel = 0, buf = 0): # given a cairo_context and the location of note, draw the note (frame and color) if buf == 1: self.draw_note_buf.append([gx,gy,len,0,c,sel,v]) return if _showGraphcisEvent: print "draw (%d, %d, %d) sel = %d" % (gx, gy, len, sel) x0, y0 = self.cx+gx*self.gridw, self.cy+gy*self.gridh+2 x1, y1 = x0+self.gridw*len, y0+self.gridh-4 r = self.gridw/2 for i in range(len): self.umask[gx+i][gy] = 1 self.set_color(cr, c, v) # cr.set_source_color(self.color_list[c]) cr.move_to(x0, y0 + r) cr.curve_to(x0, y0, x0, y0, x0+r, y0) cr.line_to(x1-r, y0) cr.curve_to(x1, y0, x1, y0, x1, y0+r) cr.line_to(x1, y1-r) cr.curve_to(x1, y1, x1, y1, x1-r, y1) cr.line_to(x0+r, y1) cr.curve_to(x0, y1, x0, y1, x0, y1-r) cr.close_path() cr.fill_preserve() cr.set_line_width(1) cr.set_source_rgb(0, 0, 0) if sel == 1: dashes = [6.0, 3.0] cr.set_dash(dashes, 0.0) else: dashes = [] cr.set_dash(dashes, 0.0) cr.stroke() def erase_grid(self, widget, cr, gx, gy): self.clear_note(cr, gx, gy, 1) #widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) def clear_grid_cursor(self, widget, tsel): gradient_change = self.set_gradient(self.set_cycle(),self.set_offset(),self.ngrid_v-self.last_gy-1) cr = self.pixmap.cairo_create() if self.last_gx != -1 and self.last_gy != -1: if tsel != 4: if self.main.score.top[self.last_gx][self.last_gy] == -1: cr.set_source_rgb(1.0-gradient_change, 0.95-gradient_change, 0.80-gradient_change) #cr.set_source_rgb(0.93, 0.86, 0.72) cr.rectangle(self.cx+self.last_gx*self.gridw+1, self.cy+self.last_gy*self.gridh+2-1, self.gridw-2, self.gridh-4+2) cr.fill() else: self.draw_grid(widget, cr, self.last_gx, self.last_gy, self.main.score.top[self.last_gx][self.last_gy]) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) def clean_cursor_mode(self, cr, gx, gy): # this has been added: gradient_change = self.set_gradient(self.set_cycle(),self.set_offset(),self.ngrid_v-gy-1) if gy >= self.ngrid_v: return if self.main.score.top[gx][gy] == -1: #cr.set_source_rgb(0.93, 0.86, 0.72) cr.set_source_rgb(1.0-gradient_change, 0.95-gradient_change, 0.80-gradient_change) cr.rectangle(self.cx+gx*self.gridw, self.cy+gy*self.gridh+2-1, self.gridw, self.gridh-4+2) cr.fill() else: self.draw_grid(self.widget, cr, gx, gy, self.main.score.top[gx][gy]) if self.is_rec() and gx == self.cursor_x: self.draw_grid(self.widget, cr, gx, gy, -1) def draw_cursor_white(self, cr, gx, gy): cr.set_source_rgba(1, 1, 1, 0.6) cr.rectangle(self.cx+gx*self.gridw, self.cy+gy*self.gridh+2-1, self.gridw, self.gridh-4+2) cr.fill() def draw_grid_cursor(self, widget, gx, gy, tsel): # print "(%d,%d) (%d,%d)" % (self.last_gx, self.last_gy, gx, gy) x0, y0 = self.cx+gx*self.gridw, self.cy+gy*self.gridh+2 x1, y1 = x0+self.gridw, y0+self.gridh-4 lx = self.last_gx ly = self.last_gy sdx = self.start_drag_gx sdy = self.start_drag_gy cr = self.pixmap.cairo_create() if self.last_gx != -1: # erase old cursor if tsel == 2 or tsel == 3: self.clean_cursor_mode(cr, self.last_gx, self.last_gy) elif tsel == 4: if self.main.score.top[self.last_gx][self.last_gy] != -1: # cut mode self.draw_grid(widget, cr, self.last_gx, self.last_gy, self.main.score.top[self.last_gx][self.last_gy]) # added by wuhsi 0303 2010 elif not (tsel == 1 and sdx != -1): self.clean_cursor_mode(cr, self.last_gx, self.last_gy) # elif tsel == 1: # if self.start_drag_gx != -1: # self.clean_selection_frame(cr, self.start_drag_gx, self.start_drag_gy, self.last_gx, self.last_gy) if gx != -1: # draw new cursor if tsel == 4: if gx+1 < self.ngrid_h and self.main.score.top[gx][gy] != -1 and self.main.score.top[gx][gy] == self.main.score.top[gx+1][gy]: cr.set_source_rgb(0.2, 0.2, 0.2) cr.rectangle(x1, y0-1, 2, y1-y0+2) cr.fill() elif tsel == 2 or tsel == 3: if tsel == 3: cr.set_source_rgba(1, 1, 1, 0.8) else: c1, c2, c3 = self.main.toolbar.get_color_attr(self.main.toolbar.colorsel) cr.set_source_rgba(c1, c2, c3, 0.8) cr.rectangle(x0+1, y0-1, x1-x0-2, y1-y0+2) cr.fill() elif tsel == 1 and sdx != -1: self.draw_selection_frame(cr, sdx, sdy, gx, gy) else: cr.set_source_rgba(1, 1, 1, 0.8) cr.rectangle(x0+1, y0-1, x1-x0-2, y1-y0+2) cr.fill() else: self.mask_buf = self.zeros(self.ngrid_h, self.ngrid_v) if tsel == 1 and sdx != -1: self.draw_selection_dif(cr) if tsel == 1 and self.start_drag_gx != -1: # sdx, sdy, lx, ly, gx, gy self.union_and_update(widget, sdx, sdy, lx, ly, gx, gy) else: widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx+lx*self.gridw, self.cy+ly*self.gridh, self.cx+lx*self.gridw, self.cy+ly*self.gridh, self.gridw+1, self.gridh) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx+gx*self.gridw, self.cy+gy*self.gridh, self.cx+gx*self.gridw, self.cy+gy*self.gridh, self.gridw+1, self.gridh) def min3(self, v1, v2, v3): if v1 <= v2 and v1 != -1 or v2 == -1: if v1 <= v3 or v3 == -1: return v1 else: return v3 else: if v2 <= v3 and v3 == -1: return v2 else: return v3 def max3(self, v1, v2, v3): if v1 >= v2: if v1 >= v3: return v1 else: return v3 else: if v2 >= v3: return v2 else: return v3 def union_and_update(self, widget, sdx, sdy, lx, ly, gx, gy): sx = self.min3(sdx, lx, gx) sy = self.min3(sdy, ly, gy) ex = self.max3(sdx, lx, gx) ey = self.max3(sdy, ly, gy) #print "(%d,%d) (%d,%d)" %(sx,sy,ex,ey) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx+sx*self.gridw, self.cy+sy*self.gridh, self.cx+sx*self.gridw, self.cy+sy*self.gridh, (ex-sx+1)*self.gridw+1, (ey-sy+1)*self.gridh) def switch_order(self, sx, sy, gx, gy): if gx < sx: return self.switch_order(gx, sy, sx, gy) if gy < sy: return (sx, gy, gx, sy) return (sx, sy, gx, gy) def execute_draw_buf(self, cr): buf = self.draw_note_buf for i in range(len(buf)): flag = 0 if _showGraphcisEvent: print "(%d, %d, %d) %d %d %d %d?" %(buf[i][0], buf[i][1], buf[i][2], buf[i][3], buf[i][4], buf[i][5], buf[i][6]) for j in range(i): if buf[i] == buf[j]: flag = 1 if _showGraphcisEvent: print "(%d, %d, %d) %d %d ignore" %(buf[i][0], buf[i][1], buf[i][2], buf[i][3], buf[i][4]) break if flag == 0: if buf[i][3] == 0: self.draw_note(cr, buf[i][0], buf[i][1], buf[i][2], buf[i][4], buf[i][6], buf[i][5]) else: self.clear_note(cr, buf[i][0], buf[i][1], buf[i][2], buf[i][4]) def get_rev_color_list(self): colorlist = list() c = self.main.toolbar.colorsel for i in range(8): if 7-i != c: colorlist.append(7-i) colorlist.append(c) return colorlist def draw_selection_dif(self, cr): for i in range(self.ngrid_h): for j in range(self.ngrid_v): if self.mask[i][j] != self.mask_buf[i][j]: if _showGraphcisEvent: print "clean (%d,%d)"%(i,j) self.clean_cursor_mode(cr, i, j) self.umask = self.zeros(self.ngrid_h, self.ngrid_v) self.draw_note_buf = list() c = self.get_rev_color_list() for k in range(len(c)): for i in range(self.ngrid_h): for j in range(self.ngrid_v): if self.mask[i][j] != self.mask_buf[i][j]: if self.main.score.top[i][j] == c[k]: if _showGraphcisEvent: print "draw (%d,%d,%d)"%(i,j,c[k]) self.draw_grid(self.widget, cr, i, j, self.main.score.top[i][j], (int) (self.mask_buf[i][j] / 2), 1) # draw_note buffer mode self.execute_draw_buf(cr) for i in range(self.ngrid_h): for j in range(self.ngrid_v): if self.mask_buf[i][j] % 2 == 1 and (self.mask[i][j] != self.mask_buf[i][j] or self.umask[i][j] == 1): if _showGraphcisEvent: print "draw white (%d,%d)"%(i,j) self.draw_cursor_white(cr, i, j) self.mask[i][j] = self.mask_buf[i][j] def clean_selection_frame(self, cr, sx, sy, gx, gy): if sx == -1 or gx == -1: # if cursor is out of bound, return return (sx, sy, gx, gy) = self.switch_order(sx, sy, gx, gy) # for i in range(gx-sx+1): # for j in range(gy-sy+1): # if self.main.score.top[sx+i][sy+j] != -1: # self.draw_grid(self.widget, cr, sx+i, sy+j, self.main.score.top[sx+i][sy+j]) for i in range(gx-sx+1): self.clean_cursor_mode(cr, sx+i, sy) if sy != gy: self.clean_cursor_mode(cr, sx+i, gy) for i in range(gy-sy-1): self.clean_cursor_mode(cr, sx, sy+i+1) if sx != gx: self.clean_cursor_mode(cr, gx, sy+i+1) def draw_selection_frame(self, cr, sx, sy, gx, gy): if sx == -1 or gx == -1: # if cursor is out of bound, return return (sx, sy, gx, gy) = self.switch_order(sx, sy, gx, gy) (self.tsx, self.tsy, self.tgx, self.tgy) = (sx, sy, gx, gy) # self.mask_buf = self.zeros(self.ngrid_h, self.ngrid_v) for i in range(gx-sx+1): for j in range(gy-sy+1): if self.main.score.top[sx+i][sy+j] != -1: self.mask_buf[sx+i][sy+j] = 2 # (self.tsx, self.tsy, self.tgx, self.tgy) = (sx, sy, gx, gy) # self.draw_grid(self.widget, cr, sx+i, sy+j, self.main.score.top[sx+i][sy+j], 1) for i in range(gx-sx+1): self.mask_buf[sx+i][sy] = self.mask_buf[sx+i][sy] + 1 # self.draw_cursor_white(cr, sx+i, sy) if sy != gy: self.mask_buf[sx+i][gy] = self.mask_buf[sx+i][gy] + 1 # self.draw_cursor_white(cr, sx+i, gy) for i in range(gy-sy-1): self.mask_buf[sx][sy+i+1] = self.mask_buf[sx][sy+i+1] + 1 # self.draw_cursor_white(cr, sx, sy+i+1) if sx != gx: self.mask_buf[gx][sy+i+1] = self.mask_buf[gx][sy+i+1] + 1 # self.draw_cursor_white(cr, gx, sy+i+1) def draw_selected_grid(self, widget, cr, gx, gy, c, buf = 0): if _showGraphcisEvent: print "draw_selected_grid(%d,%d) c=%d" % (gx, gy, c) a = b = 1 while gx-a >= 0 and self.main.score.sel[c][gx-a][gy] != 0 and self.main.score.scut[c][gx-a][gy] == 0: a = a + 1 while gx+b < self.ngrid_h and self.main.score.sel[c][gx+b][gy] and self.main.score.scut[c][gx+b-1][gy] == 0: b = b + 1 v = self.main.score.sel[c][gx-a+1][gy] self.clear_note(cr, gx-a+1, gy, a+b-1, buf) self.draw_note(cr, gx-a+1, gy, a+b-1, c, v, 1, buf) for i in range(8): if i == c: continue j = gx-a+1 while j < gx+b: if self.main.score.top[j][gy] == i: self.draw_grid(widget, cr, j, gy, i, buf) d = 1 while j+d < self.ngrid_h and self.main.score.top[j+d][gy] == i: d = d + 1 j = j + d else: j = j + 1 def draw_grid(self, widget, cr, gx, gy, c, sel = 0, buf = 0): if _showGraphcisEvent: print "draw_grid(%d,%d) c=%d, sel=%d" % (gx, gy, c, sel) if c == -1: self.clear_note(cr, gx, gy, 1, 1, buf) return a = b = 1 if self.main.score.map[c][gx][gy] != 0: a = b = 1 while gx-a >= 0 and self.main.score.map[c][gx-a][gy] != 0 and self.main.score.cut[c][gx-a][gy] == 0: a = a + 1 while gx+b < self.ngrid_h and self.main.score.map[c][gx+b][gy] and self.main.score.cut[c][gx+b-1][gy] == 0: b = b + 1 self.clear_note(cr, gx-a+1, gy, a+b-1, 0, buf) v = self.main.score.map[c][gx-a+1][gy] if sel == 1 and self.tsx <= gx-a+1 and gx+b-1 <= self.tgx and self.tsy <= gy and gy <=self.tgy: # region_selection only self.draw_note(cr, gx-a+1, gy, a+b-1, c, v, 1, buf) else: self.draw_note(cr, gx-a+1, gy, a+b-1, c, v, 0, buf) (ta, tb) = a, b if self.main.score.sel[c][gx][gy] != 0: a = b = 1 while gx-a >= 0 and self.main.score.sel[c][gx-a][gy] != 0 and self.main.score.scut[c][gx-a][gy] == 0: a = a + 1 while gx+b < self.ngrid_h and self.main.score.sel[c][gx+b][gy] and self.main.score.scut[c][gx+b-1][gy] == 0: b = b + 1 v = self.main.score.sel[c][gx-a+1][gy] self.clear_note(cr, gx-a+1, gy, a+b-1, buf) self.draw_note(cr, gx-a+1, gy, a+b-1, c, v, 1, buf) if ta > a: a = ta if tb > b: b = tb for i in range(8): if i == c: continue j = gx-a+1 while j < gx+b: if self.main.score.top[j][gy] == i: self.draw_grid(widget, cr, j, gy, i, sel, buf) d = 1 while j+d < self.ngrid_h and self.main.score.top[j+d][gy] == i: d = d + 1 j = j + d else: j = j + 1 # self.draw_selected_grid(widget, cr, gx, gy, c, buf) # widget.queue_draw_area(self.cx+(gx-a+1)*self.gridw-1, self.cy+gy*self.gridh-1, self.gridw*(a+b-1)+2, self.gridh+2) def paint_cell(self, widget, gx, gy): # call by draw_cell, to add a cell, redraw the adjacent notes c = self.main.toolbar.colorsel if _showGraphcisEvent: print "map[%d][%d][%d] = %d" % (c,gx,gy,1) if self.main.score.map[c][gx][gy] == 0: self.main.score.map[c][gx][gy] = 1 if gx < self.ngrid_h and c == 7 and self.main.score.map[c][gx][gy] != 0: self.main.score.cut[c][gx][gy] = 1 else: self.main.score.cut[c][gx][gy] = 0 if gx > 0 and c == 7 and self.main.score.map[c][gx-1][gy] != 0: self.main.score.cut[c][gx-1][gy] = 1 if self.main.score.top[gx][gy] != self.get_first_color(gx, gy): self.main.score.top[gx][gy] = self.get_first_color(gx, gy) cr = self.pixmap.cairo_create() self.draw_grid(widget, cr, gx, gy, self.main.toolbar.colorsel) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx+gx*self.gridw, self.cy+gy*self.gridh, self.cx+gx*self.gridw, self.cy+gy*self.gridh, self.gridw+1, self.gridh) def erase_cell(self, widget, gx, gy): # call by draw_cell, to erase a cell, redraw the adjacent notes if _showGraphcisEvent: print "top[%d][%d] = %d" % (gx, gy, self.main.score.top[gx][gy]) if self.main.score.top[gx][gy] != -1: cr = self.pixmap.cairo_create() t = self.main.score.top[gx][gy] self.main.score.map[t][gx][gy] = 0 self.main.score.cut[t][gx][gy] = 0 self.main.score.top[gx][gy] = self.get_first_color(gx, gy) if _showGraphcisEvent: print "top[%d][%d] = %d" % (gx, gy, self.main.score.top[gx][gy]) if self.main.score.top[gx][gy] == -1: self.erase_grid(widget, cr, gx, gy) else: self.draw_grid(widget, cr, gx, gy, self.main.score.top[gx][gy]) if gx-1 >= 0 and self.main.score.top[gx-1][gy] != -1: self.draw_grid(widget, cr, gx-1, gy, self.main.score.top[gx-1][gy]) if gx+1 < self.ngrid_h and self.main.score.top[gx+1][gy] != -1: self.draw_grid(widget, cr, gx+1, gy, self.main.score.top[gx+1][gy]) #widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx+gx*self.gridw, self.cy+gy*self.gridh, self.cx+gx*self.gridw, self.cy+gy*self.gridh, self.gridw+1, self.gridh) def cut_cell(self, widget, gx, gy): if gx+1 < self.ngrid_h and self.main.score.top[gx][gy] != -1 and self.main.score.top[gx][gy] == self.main.score.top[gx+1][gy]: cr = self.pixmap.cairo_create() t = self.main.score.top[gx][gy] self.main.score.cut[t][gx][gy] = (self.main.score.cut[t][gx][gy] + 1)%2 self.draw_grid(widget, cr, gx, gy, t) self.draw_grid(widget, cr, gx+1, gy, t) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) def draw_cell(self, widget, gx, gy, force_write = False): # call by motion or button_press if not self.main.score.is_edited: self.main.score.is_edited = True self.main.window.set_title("Music Painter - " + self.main.username + " *") if self.main.toolbar.toolsel == 3: self.erase_cell(widget, gx, gy) elif self.main.toolbar.toolsel == 4: self.cut_cell(widget, gx, gy) elif self.main.toolbar.toolsel == 2: if gx == self.last_drag_gx and gy == self.last_drag_gy: # condition stands when call by button_press if not force_write and self.main.score.map[self.main.toolbar.colorsel][gx][gy] != 0: # start with an already painted grid self.erase_cell(widget, gx, gy) # assume the user intent to clean it self.just_clean = 1 else: # start with an unpainted grid self.paint_cell(widget, gx, gy) else: # call by button_motion if self.just_clean == 1: # undo the assumption self.just_clean = 0 self.paint_cell(widget, self.last_drag_gx, self.last_drag_gy) self.paint_cell(widget, gx, gy) self.main.score.drag_on(self.main.csound, self.main.toolbar.toolsel, self.main.toolbar.colorsel, gy) # make dragging sound def draw_canvas_highlight(self, flag): cr = self.pixmap.cairo_create() widget = self.widget if flag == 1: cr.set_source_rgba(1, 1, 1, 0.4) cr.rectangle(self.cx-1, self.cy+1, self.ngrid_h*self.gridw+2, self.ngrid_v*self.gridh-2) cr.fill() else: self.draw_canvas(cr) self.draw_score(cr) self.draw_buttons(cr) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) ''' def draw_canvas(self, cr): cr.set_source_rgb(0.84,0.84,1) cr.rectangle(0, 0, self.width, self.height) cr.fill() cr.set_source_rgb(0.93, 0.86, 0.72) cr.rectangle(self.cx, self.cy, self.ngrid_h*self.gridw, self.ngrid_v*self.gridh) cr.fill() cr.set_source_rgb(0, 0, 0) cr.set_line_width(0.5) cr.move_to(self.cx-2, self.cy) cr.line_to(self.cx-2, self.cy + self.ngrid_v*self.gridh) cr.move_to(self.cx + self.ngrid_h*self.gridw +2, self.cy) cr.line_to(self.cx + self.ngrid_h*self.gridw +2, self.cy + self.ngrid_v*self.gridh) for i in range(self.ngrid_v+1): cr.move_to(self.cx-2, self.cy+i*self.gridh) cr.line_to(self.cx+self.ngrid_h*self.gridw+2 , self.cy+i*self.gridh) cr.stroke() ''' # this draw_canvas has been replaced with: def canvas_cycle(self, cycle, offset, cr): x = 0 while x < self.ngrid_v: gradient = self.set_gradient(cycle,offset,x) cr.set_source_rgb(1.0-gradient, 0.95-gradient, 0.80-gradient) # canvas background color (changes) cr.rectangle(self.cx, self.cy+(self.gridh*(self.ngrid_v-x-1)), self.ngrid_h*self.gridw, self.gridh) x += 1.0 cr.fill() def set_cycle(self): cycle = [7, 7, 12, 5, 5, 6] return cycle[self.main.score.scale_mode] def set_offset(self): offset = offset = [4, 4, 4, 4, 4, 6] return offset[self.main.score.scale_mode] def set_gradient(self, cycle, offset, row): gradient = (row+1+cycle-offset)%(cycle)*.015 return gradient def draw_canvas(self, cr): cr.set_source_rgb(0.84,0.84,1) cr.rectangle(0, 0, self.width, self.height) cr.fill() self.canvas_cycle(self.set_cycle(),self.set_offset(),cr) cr.set_source_rgb(0, 0, 0) # canvas frame cr.set_line_width(0.5) cr.move_to(self.cx, self.cy) cr.line_to(self.cx, self.cy + self.ngrid_v*self.gridh) cr.move_to(self.cx + self.ngrid_h*self.gridw, self.cy) cr.line_to(self.cx + self.ngrid_h*self.gridw, self.cy + self.ngrid_v*self.gridh) for i in range(self.ngrid_v+1): # canvas horizontal grid line cr.move_to(self.cx, self.cy+i*self.gridh) cr.line_to(self.cx+self.ngrid_h*self.gridw, self.cy+i*self.gridh) cr.stroke() def draw_score_util(self, cr, map, cut, c, sel = 0): for i in range(8): if 7-i == c: continue; for j in range(self.ngrid_v): for k in range(self.ngrid_h): if map[7-i][k][j] != 0 and (k==0 or map[7-i][k-1][j] == 0 or cut[7-i][k-1][j] == 1): len = 1 while cut[7-i][k+len-1][j] == 0 and k+len < self.ngrid_h and map[7-i][k+len][j] != 0: len = len + 1 v = self.main.score.map[7-i][k][j] self.clear_note(cr, k, j, len, 0) self.draw_note(cr, k, j, len, 7-i, v, sel) for j in range(self.ngrid_v): for k in range(self.ngrid_h): if map[c][k][j] != 0 and (k==0 or map[c][k-1][j] == 0 or cut[c][k-1][j] == 1): len = 1 while cut[c][k+len-1][j] == 0 and k+len < self.ngrid_h and map[c][k+len][j] != 0: len = len + 1 v = self.main.score.map[c][k][j] self.clear_note(cr, k, j, len, 0) self.draw_note(cr, k, j, len, c, v, sel) def draw_score(self, cr): # redraw the entire score self.draw_score_util(cr, self.main.score.map, self.main.score.cut, self.main.toolbar.colorsel) if self.main.score.select_state != 0: self.draw_score_util(cr, self.main.score.sel, self.main.score.scut, self.main.toolbar.colorsel, 1) # determine if the input location is within the score_area # if not, return (-1, -1) # if so, return grid index (gx, gy) def within_score(self, x, y): if x < self.cx or y < self.cy or x >= self.cx+self.gridw*self.ngrid_h or y >= self.cy+self.gridh*self.ngrid_v: return -1, -1 return self.xy2gridxy(x, y) # call by within_score # or call directly for drag_selection, accept (gx, gy) even out of canvas # return grid index (gx, gy) def xy2gridxy(self, x, y): gx = (int)((x-self.cx)/self.gridw) gy = (int)((y-self.cy)/self.gridh) return gx, gy def set_color(self, cr, color, volume): v = [[1, 0.23, 0.23], #red [1, 0.5, 0], #orange [0.98, 0.99, 0.01], #yellow [0.635, 0.97, 0.01], #grass [0.15, 0.59, 0.07], #green [0, 1, 1], #lblue [0, 0.02, 0.88], #blue [0.58, 0.155, 1]] #purple if volume >= 1: t = math.pow(volume, 0.25) v1 = v[color][0] / t v2 = v[color][1] / t v3 = v[color][2] / t else: t = math.pow(volume, 1.35) v1 = 1 + t*(v[color][0]-1) v2 = 1 + t*(v[color][1]-1) v3 = 1 + t*(v[color][2]-1) cr.set_source_rgb(v1, v2, v3) def adjust_volume(self, gx, gy, t): v = -1 if t == 0: r = 1.05 else: r = 0.96 score = self.main.score flag = 0 if score.top[gx][gy] != -1: if score.select_state == 1: for i in range(8): if score.sel[i][gx][gy] != 0: len = 1 while gx-len >= 0 and score.sel[i][gx-len][gy] != 0 and score.scut[i][gx-len][gy] == 0: len = len + 1 score.sel[i][gx-len+1][gy] = score.sel[i][gx-len+1][gy] * r flag = 2 if score.sel[i][gx-len+1][gy] >= 3: score.sel[i][gx-len+1][gy] = 3 elif score.sel[i][gx-len+1][gy] <= 0.2: score.sel[i][gx-len+1][gy] = 0.2 if v == -1: v = score.sel[i][gx-len+1][gy] else: for i in range(8): if score.map[i][gx][gy] != 0: len = 1 while gx-len >= 0 and score.map[i][gx-len][gy] != 0 and score.cut[i][gx-len][gy] == 0: len = len + 1 score.map[i][gx-len+1][gy] = score.map[i][gx-len+1][gy] * r flag = 1 if score.map[i][gx-len+1][gy] >= 3: score.map[i][gx-len+1][gy] = 3 elif score.map[i][gx-len+1][gy] <= 0.2: score.map[i][gx-len+1][gy] = 0.2 if v == -1: v = score.map[i][gx-len+1][gy] if flag != 0: cr = self.pixmap.cairo_create() widget = self.widget c = score.top[gx][gy] self.draw_grid(widget, cr, gx, gy, c, (flag == 2)) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.width, self.height) return v