diff options
Diffstat (limited to 'Canvas.py')
-rw-r--r-- | Canvas.py | 1502 |
1 files changed, 1502 insertions, 0 deletions
diff --git a/Canvas.py b/Canvas.py new file mode 100644 index 0000000..7cb75ae --- /dev/null +++ b/Canvas.py @@ -0,0 +1,1502 @@ +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 |