Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Canvas.py
diff options
context:
space:
mode:
Diffstat (limited to 'Canvas.py')
-rw-r--r--Canvas.py1502
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