import gtk from copy import deepcopy class BricksArea(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) 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.LEAVE_NOTIFY_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK) def init_data(self): self.ngrid_h = 64 self.ngrid_v = 18 self.fix_button = 0 self.brick_added = False self.scroll_width = -1 # to be set self.scroll_x = 0 self.bricks_total_width = -1 # to be set self.scroll_state = 0 self.drag_state = 0 self.bricks_cnt = self.main.score.work_bricks_cnt #print "bricks_cnt = %d" % self.bricks_cnt self.scroll_highlight = -1 # 0 left 1 main 2 right self.brick_highlight = -1 self.label_highlight = -1 self.button_highlight = -1 self.btns = ["Save", "Explore"] self.to_canvas = 0 self.drag_brick = -1 self.active_group = 0 self.group_list = ["Working Area","My Melody","My Rhythm","Scale","Collected Melody", "Collected Rhythm", "Trash Can"] self.gx0 = [-1 for i in range(7)] # to be set self.gx1 = [-1 for i in range(7)] # to be set def init_graphics(self): self.ready = 0 self.cx = (int)(0.09 * self.width) self.cy = 40 self.btn_h = 42 self.gridw = 1+ (int)(0.4+1.0*self.width/64/4) v1 = (int)(1.0*(self.height - 2 * self.cy) / self.ngrid_v) v2 = (int)((0.25 * (self.main.canvas.height - 108) - 6) / self.ngrid_v) if v2 < v1: self.gridh = v2 else: self.gridh = v1 # print "(" + str(self.gridw) +"," + str(self.gridh) + ")" self.chei = self.ngrid_v*self.gridh + 4 self.cwid = self.ngrid_h*self.gridw + 12 self.bdiv = 10 self.sx0, self.sx1 = self.cx+2, self.width - 20 self.max_sx = 0 # to be set 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 configure_event(self, widget, event): x, y, width, height = widget.get_allocation() self.pixmap = gtk.gdk.Pixmap(widget.window, width, height) self.left_margin_pixmap = gtk.gdk.Pixmap(widget.window, self.cx, height) return True def enter_notify_event(self, widget, event): # print "bricksarea.enter" self.main.cursor_area = 3 self.main.grab_focus() def leave_notify_event(self, widget, event): # print "bricksarea.leave" if self.main.cursor_area == 3: self.main.cursor_area = 0 if self.scroll_highlight != -1 or self.brick_highlight != -1: self.scroll_highlight = -1 self.brick_highlight = -1 self.draw_scores() if self.label_highlight != -1: self.label_highlight = -1 cr = self.pixmap.cairo_create() widget = self.widget self.draw_labels(cr, 1) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) return def button_press_event(self, widget, event): self.fix_button = self.fix_button + 1 if self.fix_button != 1: return if event.button == 1: t = self.is_scrolling(event.x, event.y) if t == 1: # click right on the scrollbar self.scroll_state = 1 self.start_drag_x = event.x elif t == 2 or t == 4: # left if t == 4: self.scroll_x = self.scroll_x - self.scroll_width/8 else: self.scroll_x = self.scroll_x - self.scroll_width/4 if self.scroll_x < 0: self.scroll_x = 0 self.draw_scores() elif t == 3 or t == 5: # right if t == 5: self.scroll_x = self.scroll_x + self.scroll_width/8 else: self.scroll_x = self.scroll_x + self.scroll_width/4 if self.scroll_x >= self.max_sx: self.scroll_x = self.max_sx - 1 self.draw_scores() else: t = self.is_on_brick(event.x, event.y) if t == self.bricks_cnt: if self.bricks_cnt != 20: # add a brick, only for working_area if self.active_group == 0: # add a brick self.bricks_cnt = self.bricks_cnt + 1 self.main.score.work_bricks_cnt = self.bricks_cnt self.brick_highlight = self.bricks_cnt self.update_scroll(-1, 1) self.draw_scores() elif self.active_group == 6: #clear bricks for i in range(self.bricks_cnt): self.main.score.bricks[i].clear_self() self.bricks_cnt = 0 self.main.score.trash_bricks_cnt = 0 self.brick_highlight = 0 self.draw_scores() elif t != -1: # click on a brick if self.main.score.bricks[t].is_blank != 1: self.drag_brick = t score = self.main.score if score.select_state == 1: score.de_selection() self.main.canvas.draw_deselection() self.drag_state = 1 self.to_canvas = 0 # pending on the cursor is dragged into the canvas area else: # blank brick can only be thrown to trash can self.drag_brick = t score = self.main.score if score.select_state == 1: score.de_selection() self.main.canvas.draw_deselection() self.drag_state = 2 else: t = self.is_on_label(event.x, event.y) if t != -1 and t != self.active_group: self.active_group = t score = self.main.score if t == 0: score.bricks = score.work_bricks self.bricks_cnt = score.work_bricks_cnt elif t == 1: score.bricks = score.mymelody_bricks self.bricks_cnt = score.mymelody_bricks_cnt elif t == 2: score.bricks = score.myrhythm_bricks self.bricks_cnt = score.myrhythm_bricks_cnt elif t == 3: self.main.score.bricks = score.scale_bricks self.bricks_cnt = score.scale_bricks_cnt elif t == 4: self.main.score.bricks = score.cmelody_bricks self.bricks_cnt = score.cmelody_bricks_cnt elif t == 5: self.main.score.bricks = score.crhythm_bricks self.bricks_cnt = score.crhythm_bricks_cnt elif t == 6: self.main.score.bricks = score.trash_bricks self.bricks_cnt = score.trash_bricks_cnt self.label_highlight = -1 cr = self.pixmap.cairo_create() widget = self.widget self.draw_labels(cr, 1) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) self.draw_scores() else: t = self.is_on_button(event.x, event.y) if t == 0: # Save flag = self.main.score.save_working_brick self.main.score.save_working_brick = True self.main.score.save_profile(self.main.username) self.main.score.save_working_brick = flag #browser = self.main.browser #if browser.flag == 0: #self.change_into_browser() #self.fix_button = 0 #self.main.author_box.set_active(1) #self.main.type_box.set_active(1) #self.main.scale_box.set_active(0) #browser.flag = 2 #elif browser.flag == 2: #self.change_back() #self.fix_button = 0 #else: #self.main.author_box.set_active(1) #self.main.type_box.set_active(1) #self.main.scale_box.set_active(0) #browser.flag = 2 elif t == 1: # Explore browser = self.main.browser # 0 browser off 1 explore all brick 2 explore my brick if browser.flag == 0: # 3 explore all composition 4 explore my composition self.change_into_browser() self.fix_button = 0 self.main.author_box.set_active(0) self.main.type_box.set_active(1) self.main.scale_box.set_active(0) browser.flag = 1 elif browser.flag == 1: self.change_back() self.fix_button = 0 else: self.main.author_box.set_active(0) self.main.type_box.set_active(1) self.main.scale_box.set_active(0) browser.flag = 1 def change_into_browser(self): browser = self.main.browser window = self.main.window if self.platform != "sugar-xo": window.remove(self.main.layout) self.main.layout.remove(self) self.main.browser_layout.put(self, 0, self.main.toolbararea_height + self.main.canvas_height) if self.platform == "sugar-xo": window.set_canvas(self.main.browser_layout) self.main.browser_layout.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(55040, 55040, 65535)) else: window.add(self.main.browser_layout) window.show_all() def change_back(self): browser = self.main.browser window = self.main.window if self.platform != "sugar-xo": window.remove(self.main.browser_layout) self.main.browser_layout.remove(self) self.main.layout.put(self, 0, self.main.toolbararea_height + self.main.canvas_height) if self.platform == "sugar-xo": window.set_canvas(self.main.layout) else: window.add(self.main.layout) window.show_all() browser.flag = 0 def change_active_group(self, grp): self.active_group = grp score = self.main.score if grp == 0: score.bricks = score.work_bricks self.bricks_cnt = score.work_bricks_cnt elif grp == 1: score.bricks = score.mymelody_bricks self.bricks_cnt = score.mymelody_bricks_cnt elif grp == 2: score.bricks = score.myrhythm_bricks self.bricks_cnt = score.myrhythm_bricks_cnt elif grp == 4: score.bricks = score.cmelody_bricks self.bricks_cnt = score.cmelody_bricks_cnt elif grp == 5: score.bricks = score.crhythm_bricks self.bricks_cnt = score.crhythm_bricks_cnt cr = self.pixmap.cairo_create() widget = self.widget self.draw_labels(cr, 1) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) self.draw_scores() def delete_dragged_brick(self): a = self.active_group d = self.drag_brick c = self.bricks_cnt score = self.main.score for i in range(c-d-1): score.bricks[d+i].copy_brick(score.bricks[d+i+1]) score.bricks[c-1].clear_self() self.bricks_cnt = self.bricks_cnt - 1 if a == 0: score.work_bricks_cnt = score.work_bricks_cnt - 1 elif a == 1: score.mymelody_bricks_cnt = score.mymelody_bricks_cnt - 1 elif a == 2: score.myrhythm_bricks_cnt = score.myrhythm_bricks_cnt - 1 elif a == 4: score.cmelody_bricks_cnt = score.cmelody_bricks_cnt - 1 elif a == 5: score.crhythm_bricks_cnt = score.crhythm_bricks_cnt - 1 elif a == 5: score.trash_bricks_cnt = score.trash_bricks_cnt - 1 def check_same(self, bricks, cnt, brick): if brick.filename == "": return False for i in range(cnt): if bricks[i].filename == brick.filename: return True return False def add_brick(self, g, brick): score = self.main.score if g == 0: if score.work_bricks_cnt == score.wsize or self.check_same(score.work_bricks, score.work_bricks_cnt, brick): return False score.work_bricks[score.work_bricks_cnt].copy_brick(brick) # score.work_bricks[score.work_bricks_cnt].filename = "" score.work_bricks_cnt = score.work_bricks_cnt + 1 self.brick_added = True elif g == 1: if score.mymelody_bricks_cnt == score.csize or self.check_same(score.mymelody_bricks, score.mymelody_bricks_cnt, brick): return False # if not brick.is_pitch_brick(): # return False t = score.mymelody_bricks_cnt score.mymelody_bricks[t].copy_brick(brick) score.mymelody_bricks[t].brick_type = 0 # if score.mymelody_bricks[t].filename == "": # score.mymelody_bricks[t].write_score(score) # score.check_if_server_has_file(score.mymelody_bricks[t].filename) score.mymelody_bricks_cnt = score.mymelody_bricks_cnt + 1 self.brick_added = True elif g == 2: if score.myrhythm_bricks_cnt == score.csize or self.check_same(score.myrhythm_bricks, score.myrhythm_bricks_cnt, brick): return False # if not brick.is_rhythm_brick(): # return False t = score.myrhythm_bricks_cnt score.myrhythm_bricks[t].copy_brick(brick) score.myrhythm_bricks[t].brick_type = 2 # if score.myrhythm_bricks[t].filename == "": # score.myrhythm_bricks[t].write_score(score) # score.check_if_server_has_file(score.myrhythm_bricks[t].filename) score.myrhythm_bricks_cnt = score.myrhythm_bricks_cnt + 1 self.brick_added = True elif g == 4: if score.cmelody_bricks_cnt == score.csize or self.check_same(score.cmelody_bricks, score.cmelody_bricks_cnt, brick): return False score.cmelody_bricks[score.cmelody_bricks_cnt].copy_brick(brick) # score.cmelody_bricks[score.cmelody_bricks_cnt].brick_type = 0 score.cmelody_bricks_cnt = score.cmelody_bricks_cnt + 1 elif g == 5: if score.crhythm_bricks_cnt == score.csize or self.check_same(score.crhythm_bricks, score.crhythm_bricks_cnt, brick): return False score.crhythm_bricks[score.crhythm_bricks_cnt].copy_brick(brick) # score.crhythm_bricks[score.crhythm_bricks_cnt].brick_type = 2 score.crhythm_bricks_cnt = score.crhythm_bricks_cnt + 1 elif g == 6: if score.trash_bricks_cnt == score.tsize: for i in range(score.trash_bricks_cnt-1): score.trash_bricks[i].copy_brick(score.trash_bricks[i+1]) score.trash_bricks[score.trash_bricks_cnt-1].copy_brick(brick) else: score.trash_bricks[score.trash_bricks_cnt].copy_brick(brick) score.trash_bricks_cnt = score.trash_bricks_cnt + 1 self.main.browser.active_brick_list.remove(brick.filename) self.main.browser.change_status(brick.filename, 0) else: return False return True def button_release_event(self, widget, event): # print "bricksarea.mouse_btn_release (%d,%d)" % (event.x, event.y) self.fix_button = 0 if self.drag_state == 1: if self.main.score.bricks[self.drag_brick].brick_type == 1: if self.main.browser.flag == 0: gx, gy = self.main.canvas.within_score(event.x, event.y + self.main.canvas_height) if gx != -1 and gy != -1: self.main.score.scale_mode = self.drag_brick self.main.canvas.draw_canvas_highlight(0) self.draw_scores() elif self.main.score.bricks[self.drag_brick].brick_type == 0 or self.main.score.bricks[self.drag_brick].brick_type == 2: t = self.is_on_label(event.x, event.y) a = self.active_group if a != t and (a == 0 and (t == 1 or t == 2) or t == 6 and a != 3 or a == 6 and t >= 0 and t <= 2): if self.add_brick(t, self.main.score.bricks[self.drag_brick]): if a == 6: name = self.main.score.bricks[self.drag_brick].filename self.main.browser.active_brick_list.append(name) self.main.browser.change_status(name, 1) self.delete_dragged_brick() cr = self.pixmap.cairo_create() widget = self.widget self.draw_labels(cr, 1) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) self.draw_scores() self.drag_state = 0 if self.drag_state == 2 and self.is_on_label(event.x, event.y) == 6: # blank brick can only be thrown way self.delete_dragged_brick() self.draw_scores() self.drag_state = 0 if self.scroll_state == 1: self.scroll_state = 0 t = self.is_on_brick(event.x, event.y) if self.drag_brick != -1 and self.drag_brick == t and self.bricks_cnt > t: # and event.type == gtk.gdk._2BUTTON_PRESS self.main.score.bricks[t].play_music() return 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 self.scroll_state == 1: tsx = self.scroll_x + (event.x - self.start_drag_x) if tsx < 0: tsx = 0 elif tsx >= self.max_sx: tsx = self.max_sx if tsx != self.scroll_x: self.scroll_x = tsx self.start_drag_x = event.x self.draw_scores() elif self.drag_state == 1: if self.main.browser.flag == 0: if self.to_canvas == 0: # check if the brick has been dragged into the canvas gx, gy = self.main.canvas.within_score(event.x, event.y + self.main.canvas_height) if gx != -1 and gy != -1: # yes it is self.to_canvas = 1 score = self.main.score t = self.drag_brick if score.bricks[t].brick_type != 1: self.main.toolbar.toolsel = 1 self.main.toolbar.update() if score.bricks[t].brick_type == 0 or score.bricks[t].brick_type == 2: score.drag = deepcopy(score.bricks[t].map) score.dcut = deepcopy(score.bricks[t].cut) score.select_state = 1 (self.start_drag_gx, self.start_drag_gy) = (score.bricks[t].cx, score.bricks[t].cy) if score.bricks[t].brick_type == 2: self.main.canvas.move_selection(self.start_drag_gx, self.start_drag_gy, gx, self.start_drag_gy) else: self.main.canvas.move_selection(self.start_drag_gx, self.start_drag_gy, gx, gy) (self.last_gx, self.last_gy) = (gx, gy) elif score.bricks[t].brick_type == 1: # scale brick self.main.canvas.draw_canvas_highlight(1) self.last_gx = 0 else: if self.main.score.bricks[self.drag_brick].brick_type == 1: gx, gy = self.main.canvas.within_score(event.x, event.y + self.main.canvas_height) if self.last_gx == -1 and gx != -1 and gy != -1: # within canvas self.main.canvas.draw_canvas_highlight(1) self.last_gx = 0 elif self.last_gx == 0 and gx == -1 and gy == -1: self.main.canvas.draw_canvas_highlight(0) self.last_gx = -1 else: gx, gy = self.main.canvas.xy2gridxy(event.x, event.y + self.main.canvas_height) if not (gx == self.last_gx and gy == self.last_gy): if self.main.score.bricks[self.drag_brick].brick_type == 0: self.main.canvas.move_selection(self.start_drag_gx, self.start_drag_gy, gx, gy) elif self.main.score.bricks[self.drag_brick].brick_type == 2: self.main.canvas.move_selection(self.start_drag_gx, self.start_drag_gy, gx, self.start_drag_gy) (self.last_gx, self.last_gy) = (gx, gy) else: t = self.is_scrolling(event.x, event.y) if self.scroll_highlight != -1 or t == 1 or t == 4 or t == 5: if t == 1 or t == 4 or t == 5: self.scroll_highlight = t else: self.scroll_highlight = -1 cr = self.pixmap.cairo_create() widget = self.widget self.draw_scroll(cr) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) t = self.is_on_brick(event.x, event.y) if t != self.brick_highlight and (self.brick_highlight != -1 or t != -1): t2 = self.brick_highlight self.brick_highlight = t if t2 != -1: self.draw_1_score(t2) if t != -1: self.draw_1_score(t) t = self.is_on_label(event.x, event.y) if t != self.active_group and t != self.label_highlight and (self.label_highlight != -1 or t != -1): t2 = self.label_highlight self.label_highlight = t cr = self.pixmap.cairo_create() widget = self.widget if t2 != -1: self.draw_label(cr, self.gx0[t2], self.gx1[t2], self.cy - 36, self.group_list[t2], 0, 0) if t != -1: self.draw_label(cr, self.gx0[t], self.gx1[t], self.cy - 36, self.group_list[t], 0, 1) t = self.active_group self.draw_label(cr, self.gx0[t], self.gx1[t], self.cy - 36, self.group_list[t], 1, 1) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) t = self.is_on_button(event.x, event.y) if t != self.button_highlight and (self.button_highlight != -1 or t != -1): self.button_highlight = t self.draw_buttons() def expose_event(self, widget, event): self.widget = widget self.ready = 1 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(cr) self.draw_labels(cr) self.draw_scores() widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, x, y, x, y, width, height) return False def is_on_button(self, x, y): if x < 12 or x >= self.cx - 12: return -1 for i in range(len(self.btns)): 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 = self.pixmap.cairo_create() #cr = self.left_margin_pixmap.cairo_create() cr.set_source_rgb(0.72, 0.78, 0.9) cr.rectangle(0, 0, self.cx, self.height) cr.fill() widget = self.widget 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.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]) widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, 0, 0, 0, 0, self.cx-3, self.height) def draw_score_util(self, cr, sx, map, cut, wid = 64): fx = -1 for k in range(self.ngrid_h): if fx != -1 and k-fx >= wid: continue; for i in range(8): for j in range(self.ngrid_v): 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): if fx == -1: fx = k len = 1 while cut[7-i][k+len-1][j] == 0 and k-fx+len < wid and k+len < self.ngrid_h and map[7-i][k+len][j] != 0: len = len + 1 v = map[7-i][k][j] self.draw_note(cr, sx, k - fx, j, len, 7-i, v) def draw_mini_score(self, cr, sx, brick, flag): self.draw_score_canvas(cr, sx, brick.swid, flag) if brick.is_blank == 0: self.draw_score_util(cr, sx, brick.map, brick.cut) def is_on_label(self, x, y): if y < self.cy - 36 or y >= self.cy - 6: return -1 for i in range(len(self.group_list)): if x >= self.gx0[i] and x < self.gx1[i]: return i return -1 def is_scrolling(self, x, y): y0 = self.cy + self.chei + 2 if y < y0 or y >= y0 + 22: return -1 if x < self.sx0 or x >= self.sx1: return -1 if x >= self.sx0 + self.scroll_x + 22 and x < self.sx0 + self.scroll_x + 22 + self.scroll_width: return 1 if x < self.sx0 + self.scroll_x + 22: if x < self.sx0 + 22: return 4 # left button return 2 if x >= self.sx1 - 22: return 5 # right button return 3 def is_on_brickarea(self, x, y): if y < self.cy - 2 or y > self.cy + self.chei + 2: return False if x < self.sx0 or x > self.sx1: return False return True def is_on_brick(self, ex, y): if y < self.cy - 2 or y > self.cy + self.chei + 2: return -1 if self.max_sx == 0: x = 5 else: xoffset = (self.bricks_total_width - self.sx1 + self.sx0) * self.scroll_x / self.max_sx x = -xoffset + 5 for i in range(self.bricks_cnt): brick = self.main.score.bricks[i] if (x + brick.width * self.gridw) >= 0 and x < (self.sx1 - self.sx0): if ex >= self.cx + x and ex < self.cx + x + brick.width * self.gridw: return i x = x + brick.width * self.gridw + 10 if self.active_group == 0: if (x + 50) >= 0 and x < (self.sx1 - self.sx0): if ex >= self.cx + x and ex < self.cx + x + 50 and y >= self.cy + self.chei/3 and y < self.cy + self.chei/3 + 22: return self.bricks_cnt elif self.active_group == 6: if (x + 50) >= 0 and x < (self.sx1 - self.sx0): if ex >= self.cx + x and ex < self.cx + x + 50 and y >= self.cy + self.chei/3 and y < self.cy + self.chei/3 + 22: return self.bricks_cnt return -1 def update_scroll(self, target = -1, stay_in_max = 0): self.bricks_total_width = 0 w = self.sx1 - self.sx0 for i in range(self.bricks_cnt): self.bricks_total_width = self.bricks_total_width + self.main.score.bricks[i].width*self.gridw if self.active_group == 0 and i == self.bricks_cnt - 1: self.bricks_total_width = self.bricks_total_width + 40 elif self.active_group == 6 and i == self.bricks_cnt - 1: self.bricks_total_width = self.bricks_total_width + 70 else: self.bricks_total_width = self.bricks_total_width + self.bdiv if self.bricks_total_width > (self.sx1 - self.sx0): self.scroll_width = (self.sx1 - self.sx0) * (self.sx1 - self.sx0 - 44) / self.bricks_total_width else: self.scroll_width = (self.sx1 - self.sx0 - 44) self.max_sx = self.sx1-self.sx0-44-self.scroll_width if stay_in_max == 1 or self.scroll_x > self.max_sx: self.scroll_x = self.max_sx def draw_curvy_rectangle(self, cr, x0, y0, x1, y1, r, highlight): if highlight == 0: cr.set_source_rgb(0.80,0.80,0.80) else: cr.set_source_rgb(0.92,0.92,0.92) 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.98, 0.98, 0.98) cr.stroke() def draw_active_rectangle(self, cr, x0, y0, x1, y1, r, frame_only = 0): x00 = self.sx0 - 2 x2 = self.sx1 + 2 y2 = self.cy + self.chei + 24 cr.set_source_rgb(0.92,0.92,0.92) if frame_only == 1: cr.rectangle(x0, y0, x1-x0, y1-y0+1) cr.fill() 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(x2-r, y1) cr.curve_to(x2, y1, x2, y1, x2, y1+r) cr.line_to(x2, y2-r) cr.curve_to(x2, y2, x2, y2, x2-r, y2) cr.line_to(x00+r, y2) cr.curve_to(x00, y2, x00, y2, x00, y2-r) cr.line_to(x00, y1+r) cr.curve_to(x00, y1, x00, y1, x00+r, y1) cr.line_to(x0-r, y1) cr.curve_to(x0, y1, x0, y1, x0, y1-r) cr.close_path() if frame_only == 0: cr.fill_preserve() cr.set_line_width(1) cr.set_source_rgb(0.98, 0.98, 0.1) cr.stroke() def draw_label(self, cr, x0, x1, y, text, active = 0, highlight = 0): cr.set_font_size(18) x_bearing, y_bearing, width, height = cr.text_extents(text)[:4] y0 = y y1 = y + 18 + 12 r = 4 if active == 0: self.draw_curvy_rectangle(cr, x0, y0, x1, y1, r, highlight) else: self.draw_active_rectangle(cr, x0, y0, x1, y1, r, highlight) # last parameter served as frame_only flag cr.set_source_rgb(0.4, 0.4, 0.4) #cr.select_font_face("Georgia", # cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.move_to(x0 + 6 - x_bearing, y + 6 - y_bearing) cr.show_text(text) def measure_text(self, cr): cr.set_font_size(18) t = 12 for i in range(len(self.group_list)): x_bearing, y_bearing, width, height = cr.text_extents(self.group_list[i])[:4] self.gx0[i] = self.cx + t self.gx1[i] = self.cx + t + width + 12 t = t + width + 12 + 8 def draw_labels(self, cr, f = 0): if self.gx0[0] == -1: self.measure_text(cr) for i in range(len(self.group_list)): if self.active_group != i: self.draw_label(cr, self.gx0[i], self.gx1[i], self.cy - 36, self.group_list[i]) i = self.active_group self.draw_label(cr, self.gx0[i], self.gx1[i], self.cy - 36, self.group_list[i], 1, f) def draw_scroll(self, cr): self.update_scroll() x0, y0 = self.sx0 , self.cy + self.chei x1, y1 = self.sx1, y0 + 22 cr.set_source_rgb(0.72, 0.78, 0.9) cr.rectangle(x0, y0, x1-x0, y1-y0) cr.fill() cr.set_source_rgb(0.72 * 0.8, 0.78 * 0.8, 0.9 * 0.8) cr.rectangle(x0+16, y0, x1-x0-32, y1-y0) cr.fill() cr.set_source_rgb(0.95, 0.95, 0.95) self.draw_scroll_btn(cr, x0, y0, 20, 0, (self.scroll_highlight == 4)) self.draw_scroll_btn(cr, x1 - 22, y0, 20, 1, (self.scroll_highlight == 5)) self.draw_scroll_btn(cr, x0 + 22 + self.scroll_x, y0, self.scroll_width, 2, (self.scroll_highlight == 1)) def draw_1_score(self, target): cr = self.pixmap.cairo_create() widget = self.widget if self.max_sx != 0: xoffset = (self.bricks_total_width - self.sx1 + self.sx0) * self.scroll_x / self.max_sx else: xoffset = 0 x = -xoffset + 5 for i in range(self.bricks_cnt+1): if i == self.bricks_cnt: if self.active_group == 0: # add brick button if i == target: if x + 40 >= 0 and x < (self.sx1 - self.sx0): self.draw_scroll_btn(cr, self.cx + x, self.cy + self.chei/3, 22, 3, i == self.brick_highlight) if self.active_group == 6: # clear brick button if i == target: if x + 80 >= 0 and x < (self.sx1 - self.sx0): self.draw_scroll_btn(cr, self.cx + x, self.cy + self.chei/3, 60, 4, i == self.brick_highlight) else: brick = self.main.score.bricks[i] if (x + brick.width * self.gridw) >= 0 and x < (self.sx1 - self.sx0) and i == target: self.draw_mini_score(cr, x, brick, i == self.brick_highlight or self.active_group == 3 and self.main.score.scale_mode == i) x = x + brick.width * self.gridw + self.bdiv widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) def draw_1_score_b(self, target, map, cut): cr = self.pixmap.cairo_create() widget = self.widget if self.max_sx != 0: xoffset = (self.bricks_total_width - self.sx1 + self.sx0) * self.scroll_x / self.max_sx else: xoffset = 0 x = -xoffset + 5 for i in range(self.bricks_cnt): brick = self.main.score.bricks[i] if (x + brick.width * self.gridw) >= 0 and x < (self.sx1 - self.sx0) and i == target: self.draw_score_canvas(cr, x, brick.swid, 1) self.draw_score_util(cr, x, map, cut, brick.swid) x = x + brick.width * self.gridw + self.bdiv widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) def draw_scores(self): self.draw_buttons() cr = self.pixmap.cairo_create() widget = self.widget self.draw_scroll(cr) cr.set_source_rgb(0.72, 0.78, 0.9) cr.rectangle(self.cx+2, self.cy-5, self.sx1-self.sx0, self.chei+6) cr.fill() if self.max_sx != 0: xoffset = (self.bricks_total_width - self.sx1 + self.sx0) * self.scroll_x / self.max_sx else: xoffset = 0 x = -xoffset + 5 for i in range(self.bricks_cnt+1): if i == self.bricks_cnt: if self.active_group == 0: # add brick button if x + 40 >= 0 and x < (self.sx1 - self.sx0): self.draw_scroll_btn(cr, self.cx + x, self.cy + self.chei/3, 22, 3, i == self.brick_highlight) elif self.active_group == 6: # clear brick button if x + 80 >= 0 and x < (self.sx1 - self.sx0): self.draw_scroll_btn(cr, self.cx + x, self.cy + self.chei/3, 60, 4, i == self.brick_highlight) else: brick = self.main.score.bricks[i] if (x + brick.width * self.gridw) >= 0 and x < (self.sx1 - self.sx0): self.draw_mini_score(cr, x, brick, (i == self.brick_highlight or self.active_group == 3 and self.main.score.scale_mode == i)) x = x + brick.width * self.gridw + self.bdiv widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], self.pixmap, self.cx, 0, self.cx, 0, self.sx1-self.sx0, self.height) def draw(self, cr): cr.set_source_rgb(0.72, 0.78, 0.9) cr.rectangle(0, 0, self.width, self.height) cr.fill() def draw_note(self, cr, sx, gx, gy, len, c, v): # given a cairo_context and the location of note, draw the note (frame and color) x0, y0 = self.cx+sx + gx*self.gridw, self.cy+gy*self.gridh x1, y1 = x0+self.gridw*len+1, y0+self.gridh r = self.gridw/2 self.main.canvas.set_color(cr, c, v) cr.rectangle(x0, y0, x1-x0, y1-y0) # 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(0.6) cr.set_source_rgb(0.5, 0.5, 0.5) cr.stroke() def draw_score_canvas(self, cr, sx, h, flag): x0, y0 = self.cx + sx-2, self.cy-2 x1, y1 = x0+self.gridw*h+5, y0+self.gridh*self.ngrid_v+4 r = (y1-y0) / 6 if (x1-x0) / 4 < r: r = (x1-x0) / 4 if flag: cr.set_source_rgb(0.99, 0.99, 0.99) else: cr.set_source_rgb(0.9, 0.9, 0.9) 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(2) cr.set_source_rgb(0.5, 0.5, 0.5) cr.stroke() def draw_scroll_btn(self, cr, x, y, w, opt, h): x0, y0 = x+1, y+1 x1, y1 = x0+w, y0+20 if opt == 4: y1 = y0 + 26 r = 10 if opt == 3 or opt == 4: if h== 1: cr.set_source_rgb(0.9, 0.9, 0.1) else: cr.set_source_rgb(0.9, 0.9, 0.9) else: if h == 1: cr.set_source_rgb(0.85,0.85,0.98) else: cr.set_source_rgb(0.75,0.75,0.95) 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.98, 0.98, 0.98) cr.stroke() if opt == 0: cr.set_source_rgb(0.4, 0.4, 0.9) cr.move_to(x0+14, y0+3) cr.line_to(x0+6, y0+10) cr.line_to(x0+14, y0+17) cr.set_line_width(2) cr.stroke() elif opt == 1: cr.set_source_rgb(0.4, 0.4, 0.9) cr.move_to(x0+6, y0+3) cr.line_to(x0+14, y0+10) cr.line_to(x0+6, y0+17) cr.set_line_width(2) cr.stroke() elif opt == 3: cr.set_source_rgb(0.8, 0, 0) cr.move_to(x0+5, y0+10) cr.line_to(x0+17, y0+10) cr.move_to(x0+11, y0+4) cr.line_to(x0+11, y0+16) cr.set_line_width(2) cr.stroke() elif opt == 4: cr.set_font_size(18) x_bearing, y_bearing, width, height = cr.text_extents("Clear")[:4] cr.set_source_rgb(0.4, 0.4, 0.4) cr.move_to(x0 + 8 - x_bearing, y0 + 6 - y_bearing) cr.show_text("Clear")