Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Jam/Block.py173
-rw-r--r--Jam/Desktop.py76
-rw-r--r--Jam/JamMain.py212
-rw-r--r--Jam/Parasite.py42
-rw-r--r--Jam/Picker.py166
-rw-r--r--Jam/Popup.py105
-rw-r--r--common/Util/CairoUtil.py44
-rw-r--r--common/Util/ThemeWidgets.py25
8 files changed, 523 insertions, 320 deletions
diff --git a/Jam/Block.py b/Jam/Block.py
index 004adae..97a95a2 100644
--- a/Jam/Block.py
+++ b/Jam/Block.py
@@ -7,6 +7,7 @@ import common.Config as Config
from common.Config import scale
from common.Util.NoteDB import PARAMETER
+from common.Util import CairoUtil
#::: NOTE:
# All the graphics resources are loaded in Desktop and referenced here as necessary
@@ -26,7 +27,6 @@ class Block:
def __init__( self, owner, data ):
self.owner = owner
- self.gc = owner.gc
self.data = {}
for key in data.keys():
@@ -243,31 +243,31 @@ class Block:
def invalidate_rect( self, base = True ):
self.owner.invalidate_rect( self.x, self.y, self.width, self.height, base )
- def draw( self, startX, startY, stopX, stopY, pixmap ):
+ def draw(self, startX, startY, stopX, stopY, ctx):
if stopY <= self.y or startY >= self.endY:
return False
- self._drawB( startX, startY, stopX, stopY, pixmap )
+ self._drawB(startX, startY, stopX, stopY, ctx)
- def _drawB( self, startX, startY, stopX, stopY, pixmap ):
+ def _drawB( self, startX, startY, stopX, stopY, ctx):
if stopX <= self.x:
return False
if self.child:
- self.child._drawB( startX, startY, stopX, stopY, pixmap )
+ self.child._drawB(startX, startY, stopX, stopY, ctx)
if startX >= self.endX:
return False
- self._doDraw( startX, startY, stopX, stopY, pixmap )
+ self._doDraw(startX, startY, stopX, stopY, ctx)
return True
- def _doDraw( self, startX, startY, stopX, stopY, pixmap ):
+ def _doDraw( self, startX, startY, stopX, stopY, ctx):
pass # override in subclasses
- def drawHighlight( self, startX, startY, stopX, stopY, pixmap ):
+ def drawHighlight( self, startX, startY, stopX, stopY, ctx):
pass # override in subclasses
class Instrument(Block):
@@ -332,7 +332,7 @@ class Instrument(Block):
self.owner.activateInstrument( self )
Block.button_release( self, event )
- def _doDraw( self, startX, startY, stopX, stopY, pixmap ):
+ def _doDraw( self, startX, startY, stopX, stopY, ctx):
x = max( startX, self.x )
y = max( startY, self.y )
endX = min( stopX, self.endX )
@@ -340,15 +340,29 @@ class Instrument(Block):
width = endX - x
height = endY - y
+ ctx.save()
# draw border
- if self.active: self.gc.foreground = self.owner.colors["Border_Active"]
- else: self.gc.foreground = self.owner.colors["Border_Inactive"]
- self.gc.set_clip_origin( self.x-Instrument.MASK_START, self.y )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
+ CairoUtil.draw_round_rect(ctx, x, y, width, height)
+ ctx.set_line_width(3)
+ if self.active:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Bg_Active"]))
+ else:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Bg_Inactive"]))
+ ctx.fill_preserve()
+ if self.active:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Border_Active"]))
+ else:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Border_Inactive"]))
+ ctx.stroke()
- # draw block
- self.gc.set_clip_origin( self.x-Instrument.MASK_START, self.y-self.height )
- pixmap.draw_drawable( self.gc, self.img[self.active], x-self.x, y-self.y, x, y, width, height )
+ ctx.translate(x, y)
+ ctx.set_source_surface(self.img[self.active])
+ ctx.paint()
+ ctx.restore()
def drawHighlight( self, startX, startY, stopX, stopY, pixmap ):
self.gc.foreground = self.owner.colors["Border_Highlight"]
@@ -480,28 +494,54 @@ class Drum(Block):
self.owner.activateDrum( self )
Block.button_release( self, event )
- def _doDraw( self, startX, startY, stopX, stopY, pixmap ):
+ def _doDraw(self, startX, startY, stopX, stopY, ctx):
x = max( startX, self.x )
y = max( startY, self.y )
endX = min( stopX, self.endX )
endY = min( stopY, self.endY )
width = endX - x
height = endY - y
-
+ ctx.save()
# draw border
- if self.active: self.gc.foreground = self.owner.colors["Border_Active"]
- else: self.gc.foreground = self.owner.colors["Border_Inactive"]
- self.gc.set_clip_origin( self.x-Drum.MASK_START, self.y )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
+ CairoUtil.draw_drum_mask(ctx, x, y, width)
+
+ ctx.set_line_width(3)
+ if self.active:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Bg_Active"]))
+ else:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Bg_Inactive"]))
+ ctx.fill_preserve()
+ if self.active:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Border_Active"]))
+ else:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Border_Inactive"]))
+ ctx.stroke()
# draw block
- self.gc.set_clip_origin( self.x-Drum.MASK_START, self.y-self.height )
- pixmap.draw_drawable( self.gc, self.img[self.active], x-self.x, y-self.y, x, y, width, height )
+ ctx.save()
+ ctx.translate(x, y)
+ ctx.set_source_surface(self.img[self.active])
+ ctx.paint()
+ ctx.restore()
# draw key
- self.gc.set_clip_origin( self.x+Drum.KEYRECT[0]-Block.KEYMASK_START, self.y+Drum.KEYRECT[1] )
- pixmap.draw_drawable( self.gc, self.keyImage[ self.active ], 0, 0, self.x+Drum.KEYRECT[0], self.y+Drum.KEYRECT[1], Block.KEYSIZE, Block.KEYSIZE )
+ #self.gc.set_clip_origin( self.x+Drum.KEYRECT[0]-Block.KEYMASK_START,
+ # self.y+Drum.KEYRECT[1] )
+ ctx.save()
+ ctx.translate(self.x + Drum.KEYRECT[0] - Block.KEYMASK_START,
+ self.y + Drum.KEYRECT[1])
+ ctx.set_source_surface(self.keyImage[ self.active ])
+ ctx.paint()
+ ctx.restore()
+
+ #pixmap.draw_drawable( self.gc, , 0, 0, self.x+Drum.KEYRECT[0],
+ #self.y+Drum.KEYRECT[1], Block.KEYSIZE, Block.KEYSIZE )
+ ctx.restore()
def drawHighlight( self, startX, startY, stopX, stopY, pixmap ):
self.gc.foreground = self.owner.colors["Border_Highlight"]
@@ -752,14 +792,21 @@ class Loop(Block):
self.owner.activateLoop( root.child )
Block.button_release( self, event )
- def _doDraw( self, startX, startY, stopX, stopY, pixmap ):
+ def _doDraw( self, startX, startY, stopX, stopY, ctx):
y = max( startY, self.y )
endY = min( stopY, self.endY )
height = endY - y
loop = self.img[ self.active ]
- if self.active: self.gc.foreground = self.owner.colors["Border_Active"]
- else: self.gc.foreground = self.owner.colors["Border_Inactive"]
+ ctx.save()
+ # TODO: we have all this logic here again?
+ # is not the same than in Picker.py line 330 ?
+ if self.active:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Border_Active"]))
+ else:
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.owner.colors["Border_Inactive"]))
#-- draw head -----------------------------------------
@@ -768,14 +815,18 @@ class Loop(Block):
endX = min( stopX, self.x + Loop.HEAD )
width = endX - x
+ ctx.save()
# draw border
- self.gc.set_clip_origin( self.x-Loop.MASK_START, self.y )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
+ # self.gc.set_clip_origin( self.x-Loop.MASK_START, self.y )
+ ctx.rectangle(x, y, width, height)
+ ctx.fill()
# draw block
- self.gc.set_clip_origin( self.x-Loop.MASK_START, self.y-self.height )
- pixmap.draw_drawable( self.gc, loop, x-self.x, y-self.y, x, y, width, height )
-
+ #self.gc.set_clip_origin( self.x-Loop.MASK_START, self.y-self.height )
+ ctx.translate(x, y)
+ ctx.set_source_surface(loop)
+ ctx.paint()
+ ctx.restore()
#-- draw beats ----------------------------------------
beats = self.owner.noteDB.getPage(self.data["id"]).beats - 1 # last beat is drawn with the tail
@@ -788,13 +839,19 @@ class Loop(Block):
endX = min( stopX, curx + Loop.BEAT_MUL3 )
width = endX - x
+ ctx.save()
# draw border
- self.gc.set_clip_origin( curx-Loop.MASK_BEAT, self.y )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
-
+ #self.gc.set_clip_origin( curx-Loop.MASK_BEAT, self.y )
+ ctx.rectangle(x, y, width, height)
+ ctx.fill()
# draw block
- self.gc.set_clip_origin( curx-Loop.MASK_BEAT, self.y-self.height )
- pixmap.draw_drawable( self.gc, loop, x-self.x, y-self.y, x, y, width, height )
+ #self.gc.set_clip_origin( curx-Loop.MASK_BEAT, self.y-self.height )
+ ctx.translate(x, y)
+ ctx.set_source_surface(loop)
+ ctx.paint()
+ #pixmap.draw_drawable( self.gc, loop, x-self.x, y-self.y, x,
+ # y, width, height )
+ ctx.restore()
curx += Loop.BEAT_MUL3
beats -= 3
@@ -805,14 +862,18 @@ class Loop(Block):
endX = min( stopX, endX )
width = endX - x
+ ctx.save()
# draw border
- self.gc.set_clip_origin( curx-Loop.MASK_BEAT, self.y )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
+ #self.gc.set_clip_origin( curx-Loop.MASK_BEAT, self.y )
+ ctx.rectangle(x, y, width, height)
+ ctx.fill()
# draw block
- self.gc.set_clip_origin( curx-Loop.MASK_BEAT, self.y-self.height )
- pixmap.draw_drawable( self.gc, loop, x-self.x, y-self.y, x, y, width, height )
-
+ #self.gc.set_clip_origin( curx-Loop.MASK_BEAT, self.y-self.height )
+ ctx.translate(x, y)
+ ctx.set_source_surface(loop)
+ ctx.paint()
+ ctx.restore()
curx += Loop.BEAT*beats
@@ -822,19 +883,29 @@ class Loop(Block):
x = max( startX, curx )
endX = min( stopX, self.endX )
width = endX - x
-
+ ctx.save()
# draw border
- self.gc.set_clip_origin( curx-Loop.MASK_TAIL, self.y )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
+ #self.gc.set_clip_origin( curx-Loop.MASK_TAIL, self.y )
+ ctx.rectangle(x, y, width, height)
+ ctx.fill()
# draw block
- self.gc.set_clip_origin( curx-Loop.MASK_TAIL, self.y-self.height )
- pixmap.draw_drawable( self.gc, loop, x-self.x, y-self.y, x, y, width, height )
+ #self.gc.set_clip_origin( curx-Loop.MASK_TAIL, self.y-self.height )
+ ctx.translate(x, y)
+ ctx.set_source_surface(loop)
+ ctx.paint()
+ ctx.restore()
#-- draw key ------------------------------------------
if self.keyActive:
- self.gc.set_clip_origin( self.x+Loop.KEYRECT[0]-Block.KEYMASK_START, self.y+Loop.KEYRECT[1] )
- pixmap.draw_drawable( self.gc, self.keyImage[ self.active ], 0, 0, self.x+Loop.KEYRECT[0], self.y+Loop.KEYRECT[1], Block.KEYSIZE, Block.KEYSIZE )
+ #self.gc.set_clip_origin( self.x+Loop.KEYRECT[0]-
+ # Block.KEYMASK_START, self.y+Loop.KEYRECT[1] )
+ ctx.save()
+ ctx.translate(self.x + Loop.KEYRECT[0], self.y + Loop.KEYRECT[1])
+ ctx.set_source_surface(self.keyImage[ self.active ])
+ ctx.paint()
+ ctx.restore()
+ ctx.restore()
def drawHighlight( self, startX, startY, stopX, stopY, pixmap ):
self.gc.foreground = self.owner.colors["Border_Highlight"]
diff --git a/Jam/Desktop.py b/Jam/Desktop.py
index ac84c3f..c62d018 100644
--- a/Jam/Desktop.py
+++ b/Jam/Desktop.py
@@ -1,3 +1,5 @@
+import logging
+
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Gdk
@@ -7,6 +9,7 @@ import common.Config as Config
from gettext import gettext as _
import common.Util.InstrumentDB as InstrumentDB
+from common.Util import CairoUtil
from Jam import Block
from Jam import Popup
@@ -21,17 +24,15 @@ class Desktop( Gtk.EventBox ):
self.drawingArea = Gtk.DrawingArea()
self.add( self.drawingArea )
- # take drawing setup from owner
- self.gc = owner.gc
self.colors = owner.colors
- self.blockMask = owner.blockMask
+ # TODO the masks are pending
+ # self.blockMask = owner.blockMask
self.noteDB = owner.noteDB
self.dirtyRectToAdd = Gdk.Rectangle() # used by the invalidate_rect function
- self.screenBuf = None
self.screenBufDirty = False
- self.screenBufDirtyRect = ()
+ self.screenBufDirtyRect = Gdk.Rectangle()
self.blocks = [] # items on the desktop
self.activeInstrument = None
@@ -45,7 +46,7 @@ class Desktop( Gtk.EventBox ):
self.connect( "button-press-event", self.on_button_press )
self.connect( "button-release-event", self.on_button_release )
self.connect( "motion-notify-event", self.on_motion_notify )
- self.drawingArea.connect( "expose-event", self.on_expose )
+ self.drawingArea.connect("draw", self.__draw_cb)
self.clickedBlock = None
self.possibleParent = None
@@ -68,10 +69,8 @@ class Desktop( Gtk.EventBox ):
b.dumpToStream( ostream )
def on_size_allocate( self, widget, allocation ):
- if self.screenBuf == None or self.alloc.width != allocation.width or self.alloc.height != allocation.height:
- win = Gdk.get_default_root_window()
- self.screenBuf = Gdk.Pixmap( win, allocation.width, allocation.height )
- self.invalidate_rect( 0, 0, allocation.width, allocation.height )
+
+ self.invalidate_rect(0, 0, allocation.width, allocation.height)
self.alloc = allocation
self.absoluteLoc = [0,0]
parent = self.get_parent()
@@ -313,10 +312,10 @@ class Desktop( Gtk.EventBox ):
return
if event.is_hint or widget != self:
- x, y, state = self.window.get_pointer()
+ _pp, x, y, _flags = self.get_window().get_pointer()
event.x = float(x)
event.y = float(y)
- event.state = state
+ #event.state = state
blockCount = len(self.blocks)
@@ -387,55 +386,55 @@ class Desktop( Gtk.EventBox ):
#==========================================================
# Drawing
- def draw( self ):
+ def draw(self, ctx):
startX = self.screenBufDirtyRect.x
startY = self.screenBufDirtyRect.y
stopX = startX + self.screenBufDirtyRect.width
stopY = startY + self.screenBufDirtyRect.height
- self.gc.set_clip_rectangle( self.screenBufDirtyRect )
+ #self.gc.set_clip_rectangle( self.screenBufDirtyRect )
# draw background
- self.gc.foreground = self.colors["bg"]
- self.screenBuf.draw_rectangle( self.gc, True, startX, startY, self.screenBufDirtyRect.width, self.screenBufDirtyRect.height )
-
+ ctx.save()
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(self.colors["bg"]))
+ ctx.rectangle(startX, startY, self.screenBufDirtyRect.width,
+ self.screenBufDirtyRect.height )
+ ctx.fill()
+ ctx.restore()
# draw blocks
- self.gc.set_clip_mask( self.blockMask )
+ #self.gc.set_clip_mask( self.blockMask )
for block in self.blocks:
- block.draw( startX, startY, stopX, stopY, self.screenBuf )
+ block.draw(startX, startY, stopX, stopY, ctx)
self.screenBufDirty = False
- def on_expose( self, DA, event ):
+ def __draw_cb(self, DA, ctx):
if self.screenBufDirty:
- self.draw()
+ self.draw(ctx)
self.drawingAreaDirty = False
- startX = event.area.x
- startY = event.area.y
- stopX = event.area.x + event.area.width
- stopY = event.area.y + event.area.height
+# startX = event.area.x
+# startY = event.area.y
+# stopX = event.area.x + event.area.width
+# stopY = event.area.y + event.area.height
- self.gc.set_clip_rectangle( event.area )
+# self.gc.set_clip_rectangle( event.area )
- # draw base
- DA.window.draw_drawable( self.gc, self.screenBuf, startX, startY, startX, startY, event.area.width, event.area.height )
if self.possibleDelete:
return
- self.gc.set_clip_mask( self.blockMask )
-
# draw possible parent
- if self.possibleParent:
- self.possibleParent.drawHighlight( startX, startY, stopX, stopY, DA.window )
+ # TODO
+ #if self.possibleParent:
+ # self.possibleParent.drawHighlight( startX, startY, stopX, stopY, DA.window )
# draw dragged objects
if self.dragging:
- self.clickedBlock.draw( startX, startY, stopX, stopY, DA.window )
+ self.clickedBlock.draw(startX, startY, stopX, stopY, ctx)
# draw possible substitute
if self.possibleSubstitute:
@@ -443,7 +442,7 @@ class Desktop( Gtk.EventBox ):
# draw key highlight
if self.overKey:
- self.overKey.drawKeyHighlight( DA.window )
+ self.overKey.drawKeyHighlight(DA.get_window())
def invalidate_rect( self, x, y, width, height, base = True ):
self.dirtyRectToAdd.x = x
@@ -459,8 +458,11 @@ class Desktop( Gtk.EventBox ):
self.screenBufDirtyRect.width = width
self.screenBufDirtyRect.height = height
else:
- self.screenBufDirtyRect = self.screenBufDirtyRect.union( self.dirtyRectToAdd )
+ self.screenBufDirtyRect = \
+ Gdk.rectangle_union(self.screenBufDirtyRect,
+ self.dirtyRectToAdd)
self.screenBufDirty = True
- if self.drawingArea.window != None:
- self.drawingArea.window.invalidate_rect( self.dirtyRectToAdd, True )
+ if self.drawingArea.get_window() != None:
+ self.drawingArea.get_window().invalidate_rect(self.dirtyRectToAdd,
+ True)
self.drawingAreaDirty = True
diff --git a/Jam/JamMain.py b/Jam/JamMain.py
index 99b5059..ec295cb 100644
--- a/Jam/JamMain.py
+++ b/Jam/JamMain.py
@@ -3,6 +3,7 @@ from gi.repository import Gdk
from gi.repository import GdkPixbuf
from gi.repository import GObject
from gi.repository import Pango
+from gi.repository import PangoCairo
import cairo
import os
@@ -43,6 +44,7 @@ from common.Util import OS
from common.Tooltips import Tooltips
import common.Util.Network as Net
+from common.Util import CairoUtil
import xdrlib
import time
@@ -57,11 +59,6 @@ from math import sqrt
# wrapping during sync correction
HEARTBEAT_BUFFER = 100
-def hexa_to_cairo_color(color_hexa):
- _, color = Gdk.Color.parse(color_hexa)
- logging.error('color %s class %s', color, color.__class__)
- return (color.red / 65536.0, color.green / 65536.0, color.blue / 65536.0)
-
class JamMain(Gtk.EventBox):
@@ -117,27 +114,31 @@ class JamMain(Gtk.EventBox):
xoColorKey = ("#8D8D8D,#FFDDEA")
xoColor = XoColor(xoColorKey)
- win = Gdk.get_default_root_window()
- self.colors = {"bg": Config.PANEL_BCK_COLOR,
- "black": style.COLOR_BLACK.get_html(),
+ # colors in Config and in XoColor are strings,
+ # the colors in style are style.Color, transform all to Gdk.Color
+ self.colors = {"bg": CairoUtil.get_gdk_color(Config.PANEL_BCK_COLOR),
+ "black": style.COLOR_BLACK.get_gdk_color(),
#"Picker_Bg": colormap.alloc_color("#404040"),
#"Picker_Bg_Inactive": colormap.alloc_color("#808080"),
- "Picker_Bg": style.COLOR_TOOLBAR_GREY.get_html(),
- "Picker_Bg_Inactive": style.COLOR_BUTTON_GREY.get_html(),
- "Picker_Fg": style.COLOR_WHITE.get_html(),
- "Border_Active": xoColor.get_stroke_color(),
- "Border_Inactive": "#8D8D8D",
- "Border_Highlight": "#FFFFFF",
- "Bg_Active": xoColor.get_fill_color(),
- "Bg_Inactive": "#DBDBDB",
- "Preview_Note_Fill": Config.BG_COLOR,
- "Preview_Note_Border": Config.FG_COLOR,
- "Preview_Note_Selected": style.COLOR_WHITE.get_html(),
- "Note_Fill_Active": lighten("#590000"),
+ "Picker_Bg": style.COLOR_TOOLBAR_GREY.get_gdk_color(),
+ "Picker_Bg_Inactive": style.COLOR_BUTTON_GREY.get_gdk_color(),
+ "Picker_Fg": style.COLOR_WHITE.get_gdk_color(),
+ "Border_Active": \
+ CairoUtil.get_gdk_color(xoColor.get_stroke_color()),
+ "Border_Inactive": CairoUtil.get_gdk_color("#8D8D8D"),
+ "Border_Highlight": CairoUtil.get_gdk_color("#FFFFFF"),
+ "Bg_Active": CairoUtil.get_gdk_color(xoColor.get_fill_color()),
+ "Bg_Inactive": CairoUtil.get_gdk_color("#DBDBDB"),
+ "Preview_Note_Fill": CairoUtil.get_gdk_color(Config.BG_COLOR),
+ "Preview_Note_Border": CairoUtil.get_gdk_color(Config.FG_COLOR),
+ "Preview_Note_Selected": style.COLOR_WHITE.get_gdk_color(),
+ # TODO: lighten here can be removed, check if is used in other
+ # places
+ "Note_Fill_Active": Gdk.Color(*lighten("#590000")),
# base "Border_Active"
- "Note_Fill_Inactive": lighten("#8D8D8D"),
+ "Note_Fill_Inactive": Gdk.Color(*lighten("#8D8D8D")),
# base "Border_Inactive"
- "Beat_Line": "#959595"}
+ "Beat_Line": CairoUtil.get_gdk_color("#959595")}
self.colors["Note_Border_Active"] = self.colors["Border_Active"]
self.colors["Note_Border_Inactive"] = self.colors["Border_Inactive"]
@@ -171,11 +172,10 @@ class JamMain(Gtk.EventBox):
self.blockMask = Gdk.bitmap_create_from_data(
None, bitmap, pix.get_width(), pix.get_height())
- pix = GdkPixbuf.Pixbuf.new_from_file(imagefile('sampleBG.png'))
- self.sampleBg = Gdk.Pixmap(win, pix.get_width(), pix.get_height())
- self.sampleBg.draw_pixbuf(self.gc, pix, 0, 0, 0, 0, pix.get_width(),
- pix.get_height(), Gdk.RGB_DITHER_NONE)
- self.sampleBg.endOffset = pix.get_width() - 5
+ """
+ self.sampleBg = cairo.ImageSurface.create_from_png(
+ imagefile('sampleBG.png'))
+ """
if True: # load sample note clipmask
pix = GdkPixbuf.Pixbuf.new_from_file(imagefile('sampleNoteMask.png'))
pixels = pix.get_pixels()
@@ -283,7 +283,7 @@ class JamMain(Gtk.EventBox):
#-- GUI -----------------------------------------------
if True: # GUI
- self.modify_bg(Gtk.StateType.NORMAL, self.colors["bg"]) # window bg
+ self.modify_bg(Gtk.StateType.NORMAL, self.colors["bg"])
self.GUI = {}
self.GUI["mainVBox"] = Gtk.VBox()
@@ -296,18 +296,20 @@ class JamMain(Gtk.EventBox):
#-- Bank ----------------------------------------------
separator = Gtk.Label(label=" ")
separator.set_size_request(-1, style.TOOLBOX_SEPARATOR_HEIGHT)
- self.GUI["mainVBox"].pack_start(separator, False)
+ self.GUI["mainVBox"].pack_start(separator, False, True, 0)
self.GUI["notebook"] = Gtk.Notebook()
self.GUI["notebook"].set_scrollable(True)
self.GUI["notebook"].modify_bg(Gtk.StateType.NORMAL,
self.colors["Picker_Bg"])
self.GUI["notebook"].modify_bg(Gtk.StateType.ACTIVE,
self.colors["Picker_Bg_Inactive"])
- self.GUI["notebook"].props.tab_vborder = style.TOOLBOX_TAB_VBORDER
- self.GUI["notebook"].props.tab_hborder = style.TOOLBOX_TAB_HBORDER
+ # TODO gtk3 no available anymore?
+ #self.GUI["notebook"].props.tab_vborder = style.TOOLBOX_TAB_VBORDER
+ #self.GUI["notebook"].props.tab_hborder = style.TOOLBOX_TAB_HBORDER
self.GUI["notebook"].set_size_request(-1, scale(160))
self.GUI["notebook"].connect("switch-page", self.setPicker)
- self.GUI["mainVBox"].pack_start(self.GUI["notebook"], False, False)
+ self.GUI["mainVBox"].pack_start(self.GUI["notebook"], False,
+ False, 0)
self.pickers = {}
self.pickerScroll = {}
for type in [Picker.Instrument, Picker.Drum, Picker.Loop]:
@@ -410,10 +412,10 @@ class JamMain(Gtk.EventBox):
self.activity.connect("shared", self.shared)
- if self.activity._shared_activity: # PEER
- self.activity._shared_activity.connect("buddy-joined",
+ if self.activity.shared_activity: # PEER
+ self.activity.shared_activity.connect("buddy-joined",
self.buddy_joined)
- self.activity._shared_activity.connect("buddy-left",
+ self.activity.shared_activity.connect("buddy-left",
self.buddy_left)
self.activity.connect("joined", self.joined)
self.network.setMode(Net.MD_WAIT)
@@ -972,29 +974,32 @@ class JamMain(Gtk.EventBox):
x = (Block.Block.WIDTH - pix.get_width()) // 2
y = (Block.Block.HEIGHT - pix.get_height()) // 2
- img = cairo.ImageSurface(cairo.FORMAT_RGB24, Block.Block.WIDTH,
+ img = cairo.ImageSurface(cairo.FORMAT_ARGB32, Block.Block.WIDTH,
Block.Block.HEIGHT)
# TODO: two images? may be we can draw the rectangle with cairo later
ctx = cairo.Context(img)
- ctx.set_source_rgb(*hexa_to_cairo_color(self.colors["Bg_Inactive"]))
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Bg_Inactive"]))
ctx.rectangle(0, 0, Block.Block.WIDTH, Block.Block.HEIGHT)
ctx.translate(x, y)
ctx.set_source_surface(pix, 0, 0)
ctx.paint()
self.instrumentImage[id] = img
- img2 = cairo.ImageSurface(cairo.FORMAT_RGB24, Block.Block.WIDTH,
+ img2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, Block.Block.WIDTH,
Block.Block.HEIGHT)
ctx2 = cairo.Context(img2)
- ctx2.set_source_rgb(*hexa_to_cairo_color(self.colors["Bg_Active"]))
+ ctx2.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Bg_Active"]))
ctx2.rectangle(0, 0, Block.Block.WIDTH, Block.Block.HEIGHT)
ctx2.translate(x, y)
ctx2.set_source_surface(pix, 0, 0)
ctx2.paint()
self.instrumentImageActive[id] = img2
- def _drawNotes(self, pixmap, beats, notes, active):
- self.gc.set_clip_mask(self.sampleNoteMask)
+ def _drawNotes(self, ctx, beats, notes, active):
+ #self.gc.set_clip_mask(self.sampleNoteMask)
+ ctx.save()
for note in notes: # draw N notes
x = self.ticksToPixels(note.cs.onset)
# include end cap offset
@@ -1006,73 +1011,86 @@ class JamMain(Gtk.EventBox):
y = self.pitchToPixels(note.cs.pitch)
# draw fill
if active:
- self.gc.foreground = self.colors["Note_Fill_Active"]
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Note_Fill_Active"]))
else:
- self.gc.foreground = self.colors["Note_Fill_Inactive"]
- self.gc.set_clip_origin(x, y - self.sampleNoteHeight)
- pixmap.draw_rectangle(self.gc, True, x + 1, y + 1, width + 1,
- self.sampleNoteHeight - 2)
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Note_Fill_Inactive"]))
+ #self.gc.set_clip_origin(x, y - self.sampleNoteHeight)
+ ctx.rectangle(x + 1, y + 1, width + 1, self.sampleNoteHeight - 2)
+ ctx.fill()
# draw border
if active:
- self.gc.foreground = self.colors["Note_Border_Active"]
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Note_Border_Active"]))
else:
- self.gc.foreground = self.colors["Note_Border_Inactive"]
- self.gc.set_clip_origin(x, y)
- pixmap.draw_rectangle(self.gc, True, x, y, width,
- self.sampleNoteHeight)
- self.gc.set_clip_origin(endX - self.sampleNoteMask.endOffset, y)
- pixmap.draw_rectangle(self.gc, True, endX, y, 3,
- self.sampleNoteHeight)
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Note_Border_Inactive"]))
+ #self.gc.set_clip_origin(x, y)
+ ctx.rectangle(x, y, width, self.sampleNoteHeight)
+ ctx.fill()
+ #self.gc.set_clip_origin(endX - self.sampleNoteMask.endOffset, y)
+ ctx.rectangle(endX, y, 3, self.sampleNoteHeight)
+ ctx.fill()
+ ctx.restore()
def prepareKeyImage(self, key):
- win = Gdk.get_default_root_window()
- pangolayout = self.create_pango_layout(_(self.valid_shortcuts[key]))
+ text =_(self.valid_shortcuts[key])
+
+ # TODO: two images? may be we can draw the rectangle with cairo later
+ self.keyImage[key] = self._prepare_key_image(text,
+ self.colors["Bg_Inactive"], self.colors["Border_Inactive"])
+
+ self.keyImageActive[key] = self._prepare_key_image(text,
+ self.colors["Bg_Active"], self.colors["Border_Active"])
+
+ def _prepare_key_image(self, text, bg_color, border_color):
+ img = cairo.ImageSurface(cairo.FORMAT_ARGB32, Block.Block.KEYSIZE,
+ Block.Block.KEYSIZE)
+ ctx = cairo.Context(img)
+ pango_layout = PangoCairo.create_layout(ctx)
fontDesc = Pango.FontDescription("bold")
- pangolayout.set_font_description(fontDesc)
- extents = pangolayout.get_pixel_extents()
- x = (Block.Block.KEYSIZE - extents[1][2]) // 2
- y = (Block.Block.KEYSIZE - extents[1][3]) // 2
-
- pixmap = Gdk.Pixmap(win, Block.Block.KEYSIZE, Block.Block.KEYSIZE)
- self.gc.foreground = self.colors["Border_Inactive"]
- pixmap.draw_rectangle(self.gc, True, 0, 0, Block.Block.KEYSIZE,
- Block.Block.KEYSIZE)
- self.gc.foreground = self.colors["Bg_Inactive"]
- pixmap.draw_layout(self.gc, x, y, pangolayout)
- self.keyImage[key] = pixmap
-
- pixmap = Gdk.Pixmap(win, Block.Block.KEYSIZE, Block.Block.KEYSIZE)
- self.gc.foreground = self.colors["Border_Active"]
- pixmap.draw_rectangle(self.gc, True, 0, 0, Block.Block.KEYSIZE,
- Block.Block.KEYSIZE)
- self.gc.foreground = self.colors["Bg_Active"]
- pixmap.draw_layout(self.gc, x, y, pangolayout)
- self.keyImageActive[key] = pixmap
+ pango_layout.set_font_description(fontDesc)
+ pango_layout.set_text(unicode(text), len(unicode(text)))
+ extents = pango_layout.get_pixel_extents()
+ x = (Block.Block.KEYSIZE - extents[1].width) // 2
+ y = (Block.Block.KEYSIZE - extents[1].height) // 2
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(border_color))
+ ctx.rectangle(0, 0, Block.Block.KEYSIZE, Block.Block.KEYSIZE)
+ ctx.fill()
+ ctx.translate(x, y)
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(bg_color))
+ PangoCairo.show_layout(ctx, pango_layout)
+ ctx.stroke()
+ return img
def updateLoopImage(self, id):
page = self.noteDB.getPage(id)
- win = Gdk.get_default_root_window()
width = Block.Loop.WIDTH[page.beats]
height = Block.Loop.HEIGHT
-
- self.gc.set_clip_rectangle((0, 0, width, height))
-
- pixmap = Gdk.Pixmap(win, width, height)
- self.gc.foreground = self.colors["Bg_Inactive"]
- pixmap.draw_rectangle(self.gc, True, 0, 0, width, height)
- self._drawNotes(pixmap, page.beats, self.noteDB.getNotesByTrack(id, 0),
- False)
- self.loopImage[id] = pixmap
-
- self.gc.set_clip_rectangle((0, 0, width, height))
-
- pixmap = Gdk.Pixmap(win, width, height)
- self.gc.foreground = self.colors["Bg_Active"]
- pixmap.draw_rectangle(self.gc, True, 0, 0, width, height)
- self._drawNotes(pixmap, page.beats, self.noteDB.getNotesByTrack(id, 0),
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
+ ctx = cairo.Context(surface)
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Bg_Inactive"]))
+ ctx.rectangle(0, 0, width, height)
+ ctx.fill()
+
+ self._drawNotes(ctx, page.beats, self.noteDB.getNotesByTrack(id, 0),
+ False)
+ self.loopImage[id] = surface
+
+ #self.gc.set_clip_rectangle((0, 0, width, height))
+
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
+ ctx = cairo.Context(surface)
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Bg_Active"]))
+ ctx.rectangle(0, 0, width, height)
+ ctx.fill()
+ self._drawNotes(ctx, page.beats, self.noteDB.getNotesByTrack(id, 0),
True)
- self.loopImageActive[id] = pixmap
+ self.loopImageActive[id] = surface
def ticksToPixels(self, ticks):
return self.loopTickOffset + int(round(ticks * self.pixelsPerTick))
@@ -1157,9 +1175,9 @@ class JamMain(Gtk.EventBox):
def shared(self, activity):
if Config.DEBUG:
print "TamTamJam:: successfully shared, start host mode"
- self.activity._shared_activity.connect("buddy-joined",
+ self.activity.shared_activity.connect("buddy-joined",
self.buddy_joined)
- self.activity._shared_activity.connect("buddy-left", self.buddy_left)
+ self.activity.shared_activity.connect("buddy-left", self.buddy_left)
self.network.setMode(Net.MD_HOST)
self.updateSync()
self.syncTimeout = GObject.timeout_add(1000, self.updateSync)
@@ -1167,7 +1185,7 @@ class JamMain(Gtk.EventBox):
def joined(self, activity):
if Config.DEBUG:
print "TamTamJam:: joined activity!!"
- for buddy in self.activity._shared_activity.get_joined_buddies():
+ for buddy in self.activity.shared_activity.get_joined_buddies():
print buddy.props.ip4_address
def buddy_joined(self, activity, buddy):
diff --git a/Jam/Parasite.py b/Jam/Parasite.py
index c5ac2ec..f29bee6 100644
--- a/Jam/Parasite.py
+++ b/Jam/Parasite.py
@@ -5,6 +5,7 @@ import common.Config as Config
from common.Util.NoteDB import PARAMETER
from common.Util.CSoundClient import new_csound_client
+from common.Util import CairoUtil
class LoopParasite:
@@ -31,7 +32,6 @@ class LoopParasite:
self.lastDragP = 0
self.lastDragD = 0
- self.gc = self.owner.gc
self.colors = self.owner.colors
self.updateParameter( None, None )
@@ -325,24 +325,36 @@ class LoopParasite:
#=======================================================
# Draw
- def draw( self, win, gc, startX, stopX ):
- if stopX < self.x: return False # we don't need to draw and no one after us will draw
- if startX > self.x + self.width: return True # we don't need to draw, but maybe a later note does
+ def draw(self, ctx, startX, stopX):
+ # we don't need to draw and no one after us will draw
+ if stopX < self.x:
+ return False
+ # we don't need to draw, but maybe a later note does
+ if startX > self.x + self.width:
+ return True
# draw fill
- self.gc.foreground = self.colors["Preview_Note_Fill"]
- self.gc.set_clip_origin( self.x, self.y-self.owner.sampleNoteHeight )
- self.owner.previewBuffer.draw_rectangle( self.gc, True, self.x+1, self.y+1, self.width-2, self.owner.sampleNoteHeight-2 )
+ ctx.save()
+ ctx.set_source_rgb(CairoUtil.gdk_color_to_cairo(
+ self.colors["Preview_Note_Fill"]))
+ ctx.rectangle(self.x + 1, self.y + 1, self.width - 2,
+ self.owner.sampleNoteHeight - 2)
+ ctx.fill()
+
# draw border
if self.selected:
- self.gc.foreground = self.colors["Preview_Note_Selected"]
+ ctx.set_source_rgb(CairoUtil.gdk_color_to_cairo(
+ self.colors["Preview_Note_Selected"]))
else:
- self.gc.foreground = self.colors["Preview_Note_Border"]
- self.gc.set_clip_origin( self.x, self.y )
+ ctx.set_source_rgb(CairoUtil.gdk_color_to_cairo(
+ self.colors["Preview_Note_Border"]))
+ #self.gc.set_clip_origin( self.x, self.y )
endX = self.x + self.width - 3
- self.owner.previewBuffer.draw_rectangle( self.gc, True, self.x, self.y, self.width-3, self.owner.sampleNoteHeight )
- self.gc.set_clip_origin( endX-self.owner.sampleNoteMask.endOffset, self.y )
- self.owner.previewBuffer.draw_rectangle( self.gc, True, endX, self.y, 3, self.owner.sampleNoteHeight )
-
+ ctx.rectangle(self.x, self.y, self.width - 3,
+ self.owner.sampleNoteHeight)
+ ctx.fill()
+ #self.gc.set_clip_origin( endX-self.owner.sampleNoteMask.endOffset, self.y )
+ ctx.rectangle(endX, self.y, 3, self.owner.sampleNoteHeight)
+ ctx.fill()
+ ctx.restore()
return True # we drew something
-
diff --git a/Jam/Picker.py b/Jam/Picker.py
index 5456555..3d1288e 100644
--- a/Jam/Picker.py
+++ b/Jam/Picker.py
@@ -1,13 +1,16 @@
from gi.repository import Gtk
from gi.repository import Gdk
+from gi.repository import GdkPixbuf
import os
-
+import cairo
import sets
+import StringIO
from common.Util.CSoundClient import new_csound_client
from common.port.scrolledbox import HScrolledBox
import common.Config as Config
+from common.Util import CairoUtil
from gettext import gettext as _
from sugar3.graphics.palette import Palette, WidgetInvoker
@@ -24,10 +27,9 @@ class Picker(HScrolledBox):
self.owner = owner
- # take drawing setup from owner
- self.gc = owner.gc
self.colors = owner.colors
- self.blockMask = owner.blockMask
+ # TODO gtk3 no masks yet
+ #self.blockMask = owner.blockMask
self.filter = filter
@@ -142,35 +144,47 @@ class Instrument( Picker ):
data = { "name": self.instrumentDB.instId[id].nameTooltip,
"id": id }
- win = Gdk.get_default_root_window()
width = Block.Instrument.WIDTH
height = Block.Instrument.HEIGHT
- pixmap = Gdk.Pixmap( win, width, height )
-
- self.gc.set_clip_rectangle( ( 0, 0, width, height ) )
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
+ ctx = cairo.Context(surface)
# draw bg
- self.gc.foreground = self.colors["Picker_Bg"]
- pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Picker_Bg"]))
+ ctx.rectangle(0, 0, width, height)
+ ctx.fill_preserve()
- self.gc.set_clip_mask( self.blockMask )
+ # TODO gtk3 no masks yet
+ #self.gc.set_clip_mask( self.blockMask )
# draw border
- self.gc.foreground = self.colors["Border_Inactive"]
- self.gc.set_clip_origin( -Block.Instrument.MASK_START, 0 )
- pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+
+ # TODO gtk3 mask
+ #self.gc.set_clip_origin( -Block.Instrument.MASK_START, 0 )
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Border_Inactive"]))
+ ctx.rectangle(0, 0, width, height)
+ ctx.stroke()
# draw block
- inst = self.owner.getInstrumentImage( data["id"] )
- self.gc.set_clip_origin( -Block.Instrument.MASK_START, -height )
- pixmap.draw_drawable( self.gc, inst, 0, 0, 0, 0, width, height )
+ #self.gc.set_clip_origin( -Block.Instrument.MASK_START, -height )
+ ctx.set_source_surface(self.owner.getInstrumentImage(data["id"]), 0, 0)
+ ctx.paint()
- image = Gtk.Image()
- image.set_from_pixmap( pixmap, None )
+ # may be there are a better way to put the content of the surface in
+ # a GtkImage
+ pixbuf_data = StringIO.StringIO()
+ surface.write_to_png(pixbuf_data)
+ pxb_loader = GdkPixbuf.PixbufLoader.new_with_type('png')
+ pxb_loader.write(pixbuf_data.getvalue())
+ pxb_loader.close()
+
+ image = Gtk.Image.new_from_pixbuf(pxb_loader.get_pixbuf())
block = Gtk.EventBox()
- block.modify_bg( Gtk.StateType.NORMAL, self.colors["Picker_Bg"] )
- block.add( image )
+ block.modify_bg(Gtk.StateType.NORMAL, self.colors["Picker_Bg"])
+ block.add(image)
Picker.addBlock( self, data, data["name"], block )
@@ -210,35 +224,46 @@ class Drum( Picker ):
data = { "name": self.instrumentDB.instId[id].nameTooltip,
"id": id }
- win = Gdk.get_default_root_window()
width = Block.Drum.WIDTH
height = Block.Drum.HEIGHT
- pixmap = Gdk.Pixmap( win, width, height )
- self.gc.set_clip_rectangle( ( 0, 0, width, height ) )
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
+ ctx = cairo.Context(surface)
+
# draw bg
- self.gc.foreground = self.colors["Picker_Bg"]
- pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Picker_Bg"]))
+ ctx.rectangle(0, 0, width, height)
+ ctx.fill_preserve()
- self.gc.set_clip_mask( self.blockMask )
+ # TODO gtk3 masaks pending
+ #self.gc.set_clip_mask( self.blockMask )
# draw border
- self.gc.foreground = self.colors["Border_Inactive"]
- self.gc.set_clip_origin( -Block.Drum.MASK_START, 0 )
- pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Border_Inactive"]))
+ ctx.rectangle(0, 0, width, height)
+ ctx.stroke()
# draw block
- inst = self.owner.getInstrumentImage( data["id"] )
- self.gc.set_clip_origin( -Block.Drum.MASK_START, -height )
- pixmap.draw_drawable( self.gc, inst, 0, 0, 0, 0, width, height )
+ #self.gc.set_clip_origin( -Block.Drum.MASK_START, -height )
+ ctx.set_source_surface(self.owner.getInstrumentImage(data["id"]), 0, 0)
+ ctx.paint()
+
+ # may be there are a better way to put the content of the surface in
+ # a GtkImage
+ pixbuf_data = StringIO.StringIO()
+ surface.write_to_png(pixbuf_data)
+ pxb_loader = GdkPixbuf.PixbufLoader.new_with_type('png')
+ pxb_loader.write(pixbuf_data.getvalue())
+ pxb_loader.close()
- image = Gtk.Image()
- image.set_from_pixmap( pixmap, None )
+ image = Gtk.Image.new_from_pixbuf(pxb_loader.get_pixbuf())
block = Gtk.EventBox()
- block.modify_bg( Gtk.StateType.NORMAL, self.colors["Picker_Bg"] )
- block.add( image )
+ block.modify_bg(Gtk.StateType.NORMAL, self.colors["Picker_Bg"])
+ block.add(image)
Picker.addBlock( self, data, data["name"], block )
@@ -307,29 +332,33 @@ class Loop( Picker ):
page = self.owner.noteDB.getPage( id )
- win = Gdk.get_default_root_window()
width = Block.Loop.WIDTH[page.beats]
height = Block.Loop.HEIGHT
- pixmap = Gdk.Pixmap( win, width, height )
- self.gc.set_clip_rectangle( ( 0, 0, width, height ) )
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
+ ctx = cairo.Context(surface)
# draw bg
- self.gc.foreground = self.colors["Picker_Bg"]
- pixmap.draw_rectangle( self.gc, True, 0, 0, width, height )
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Picker_Bg"]))
+ ctx.rectangle(0, 0, width, height)
+ ctx.fill()
- self.gc.set_clip_mask( self.blockMask )
- self.gc.foreground = self.owner.colors["Border_Inactive"]
+ #self.gc.set_clip_mask( self.blockMask )
+ ctx.set_source_rgb(*CairoUtil.gdk_color_to_cairo(
+ self.colors["Border_Inactive"]))
#-- draw head -----------------------------------------
# draw border
- self.gc.set_clip_origin( -Block.Loop.MASK_START, 0 )
- pixmap.draw_rectangle( self.gc, True, 0, 0, Block.Loop.HEAD, height )
+ #self.gc.set_clip_origin( -Block.Loop.MASK_START, 0 )
+ ctx.rectangle(0, 0, Block.Loop.HEAD, height)
+ ctx.fill()
# draw block
- self.gc.set_clip_origin( -Block.Loop.MASK_START, -height )
- pixmap.draw_drawable( self.gc, loop, 0, 0, 0, 0, Block.Loop.HEAD, height )
+ #self.gc.set_clip_origin( -Block.Loop.MASK_START, -height )
+ ctx.set_source_surface(loop)
+ ctx.paint()
#-- draw beats ----------------------------------------
@@ -337,12 +366,17 @@ class Loop( Picker ):
curx = Block.Loop.HEAD
while beats > 3:
# draw border
- self.gc.set_clip_origin( curx-Block.Loop.MASK_BEAT, 0 )
- pixmap.draw_rectangle( self.gc, True, curx, 0, Block.Loop.BEAT_MUL3, height )
+ #self.gc.set_clip_origin( curx-Block.Loop.MASK_BEAT, 0 )
+ ctx.rectangle(curx, 0, Block.Loop.BEAT_MUL3, height)
+ ctx.fill()
# draw block
- self.gc.set_clip_origin( curx-Block.Loop.MASK_BEAT, -height )
- pixmap.draw_drawable( self.gc, loop, curx, 0, curx, 0, Block.Loop.BEAT_MUL3, height )
+ #self.gc.set_clip_origin( curx-Block.Loop.MASK_BEAT, -height )
+ ctx.save()
+ ctx.translate(curx, 0)
+ ctx.set_source_surface(loop)
+ ctx.paint()
+ ctx.restore()
curx += Block.Loop.BEAT_MUL3
beats -= 3
@@ -351,27 +385,43 @@ class Loop( Picker ):
w = Block.Loop.BEAT*beats
# draw border
- self.gc.set_clip_origin( curx-Block.Loop.MASK_BEAT, 0 )
- pixmap.draw_rectangle( self.gc, True, curx, 0, w, height )
+ #self.gc.set_clip_origin( curx-Block.Loop.MASK_BEAT, 0 )
+ ctx.rectangle(curx, 0, w, height)
+ ctx.fill()
# draw block
- self.gc.set_clip_origin( curx-Block.Loop.MASK_BEAT, -height )
- pixmap.draw_drawable( self.gc, loop, curx, 0, curx, 0, w, height )
+ #self.gc.set_clip_origin( curx-Block.Loop.MASK_BEAT, -height )
+ ctx.set_source_surface(loop)
+ ctx.save()
+ ctx.translate(curx, 0)
+ ctx.set_source_surface(loop)
+ ctx.paint()
+ #pixmap.draw_drawable( self.gc, loop, curx, 0, curx, 0, w, height )
+ ctx.restore()
curx += w
#-- draw tail -----------------------------------------
# draw border
+ """
self.gc.set_clip_origin( curx-Block.Loop.MASK_TAIL, 0 )
pixmap.draw_rectangle( self.gc, True, curx, 0, Block.Loop.TAIL, height )
# draw block
self.gc.set_clip_origin( curx-Block.Loop.MASK_TAIL, -height )
pixmap.draw_drawable( self.gc, loop, curx, 0, curx, 0, Block.Loop.TAIL, height )
+ """
+
+ # may be there are a better way to put the content of the surface in
+ # a GtkImage
+ pixbuf_data = StringIO.StringIO()
+ surface.write_to_png(pixbuf_data)
+ pxb_loader = GdkPixbuf.PixbufLoader.new_with_type('png')
+ pxb_loader.write(pixbuf_data.getvalue())
+ pxb_loader.close()
- image = Gtk.Image()
- image.set_from_pixmap( pixmap, None )
+ image = Gtk.Image.new_from_pixbuf(pxb_loader.get_pixbuf())
block = Gtk.EventBox()
block.modify_bg( Gtk.StateType.NORMAL, self.colors["Picker_Bg"] )
diff --git a/Jam/Popup.py b/Jam/Popup.py
index 51de523..98fd0d6 100644
--- a/Jam/Popup.py
+++ b/Jam/Popup.py
@@ -391,9 +391,9 @@ class Loop( Popup ):
self.settingBlock = False
- self.gc = self.owner.gc
self.colors = self.owner.colors
- self.sampleNoteMask = self.owner.sampleNoteMask
+ # TODO: gtk3 masks not available yet
+ #self.sampleNoteMask = self.owner.sampleNoteMask
self.noteDB = self.owner.noteDB
self.csnd = new_csound_client()
@@ -478,7 +478,7 @@ class Loop( Popup ):
True, padding=style.DEFAULT_PADDING)
self.previewDA = self.GUI["previewDA"] = Gtk.DrawingArea()
self.GUI["previewDA"].connect( "size-allocate", self.handlePreviewAlloc )
- self.GUI["previewDA"].connect( "expose-event", self.handlePreviewExpose )
+ self.GUI["previewDA"].connect("draw", self.__draw_cb)
self.GUI["previewEventBox"].add( self.GUI["previewDA"] )
self.GUI["mainBox"].show_all()
@@ -489,25 +489,28 @@ class Loop( Popup ):
self.dirtyRectToAdd = ( 0, 0, 0, 0 )
self.sampleBg = self.owner.sampleBg
- self.GUI["previewDA"].set_size_request( -1, self.sampleBg.get_size()[1] )
+ self.GUI["previewDA"].set_size_request(-1, self.sampleBg.get_height())
self.sampleNoteHeight = self.owner.sampleNoteHeight
- self.sampleNoteMask = self.owner.sampleNoteMask
-
- self.pitchPerPixel = float(Config.NUMBER_OF_POSSIBLE_PITCHES-1) / (self.sampleBg.get_size()[1] - self.sampleNoteHeight)
- self.pixelsPerPitch = float(self.sampleBg.get_size()[1] - self.sampleNoteHeight)/(Config.MAXIMUM_PITCH - Config.MINIMUM_PITCH)
+ # TODO: gtk3 Masks not available yet
+ #self.sampleNoteMask = self.owner.sampleNoteMask
+
+ self.pitchPerPixel = float(Config.NUMBER_OF_POSSIBLE_PITCHES-1) / \
+ (self.sampleBg.get_height() - self.sampleNoteHeight)
+ self.pixelsPerPitch = float(self.sampleBg.get_height() - \
+ self.sampleNoteHeight) / (Config.MAXIMUM_PITCH - \
+ Config.MINIMUM_PITCH)
# Temporary Initialization
self.pixelsPerTick = [0] + [ 1 for i in range(1,Config.MAXIMUM_BEATS+1) ]
self.ticksPerPixel = [0] + [ 1 for i in range(1,Config.MAXIMUM_BEATS+1) ]
- self.cursor = { \
- "default": None, \
- "drag-onset": Gdk.Cursor.new(Gdk.SB_RIGHT_ARROW), \
- "drag-pitch": Gdk.Cursor.new(Gdk.BOTTOM_SIDE), \
- "drag-duration": Gdk.Cursor.new(Gdk.RIGHT_SIDE), \
- "drag-playhead": Gdk.Cursor.new(Gdk.SB_H_DOUBLE_ARROW), \
- "pencil": Gdk.Cursor.new(Gdk.PENCIL), \
- "paste": Gdk.Cursor.new(Gdk.CursorType.CENTER_PTR), \
- "error": None }
+ self.cursor = {"default": None,
+ "drag-onset": Gdk.Cursor.new(Gdk.CursorType.SB_RIGHT_ARROW),
+ "drag-pitch": Gdk.Cursor.new(Gdk.CursorType.BOTTOM_SIDE),
+ "drag-duration": Gdk.Cursor.new(Gdk.CursorType.RIGHT_SIDE),
+ "drag-playhead": Gdk.Cursor.new(Gdk.CursorType.SB_H_DOUBLE_ARROW),
+ "pencil": Gdk.Cursor.new(Gdk.CursorType.PENCIL),
+ "paste": Gdk.Cursor.new(Gdk.CursorType.CENTER_PTR),
+ "error": None}
self.recording = False
self.recordLoop = None
@@ -722,7 +725,7 @@ class Loop( Popup ):
def handlePreviewMotion( self, widget, event ):
if event.is_hint:
- x, y, state = self.previewDA.window.get_pointer()
+ x, y, state = self.previewDA.get_window().get_pointer()
event.x = float(x)
event.y = float(y)
event.state = state
@@ -808,7 +811,7 @@ class Loop( Popup ):
# draw background
self.previewBuffer.draw_drawable( self.gc, self.sampleBg, 0, 0, 0, 0, self.previewDA.width-5, self.previewDA.height )
- self.previewBuffer.draw_drawable( self.gc, self.sampleBg, self.sampleBg.endOffset, 0, self.previewDA.width-5, 0, 5, self.previewDA.height )
+ self.previewBuffer.draw_drawable( self.gc, self.sampleBg, self.sampleBg.get_width() - 5, 0, self.previewDA.width-5, 0, 5, self.previewDA.height )
# draw beat lines
self.gc.set_line_attributes( Config.BEAT_LINE_SIZE, Gdk.LINE_ON_OFF_DASH, Gdk.CAP_BUTT, Gdk.JOIN_MITER )
@@ -821,28 +824,46 @@ class Loop( Popup ):
self.gc.set_clip_mask( self.sampleNoteMask )
notes = self.owner.noteDB.getNotesByTrack( page, self.activeTrack, self )
for n in notes:
+ # TODO:
+ # LoopParasite changed signature to (ctx, x, y)
if not n.draw( self.previewBuffer, self.gc, startX, stopX ): break
self.previewDirty = False
- def handlePreviewExpose( self, widget, event ):
+ def __draw_cb(self, widget, ctx):
if self.previewDirty:
self.previewDraw()
- self.gc.set_clip_rectangle( event.area )
-
# draw base
- widget.window.draw_drawable( self.gc, self.previewBuffer, event.area.x, event.area.y, event.area.x, event.area.y, event.area.width, event.area.height )
+ #Gtk.DrawingArea.do_draw(self, ctx)
- if self.marqueeLoc: # draw the selection rect
- self.gc.set_line_attributes( Config.MARQUEE_SIZE, Gdk.LINE_ON_OFF_DASH, Gdk.CAP_BUTT, Gdk.JOIN_MITER )
- self.gc.foreground = self.colors["Preview_Note_Selected"]
- widget.window.draw_rectangle( self.gc, False, self.marqueeRect[0][0], self.marqueeRect[0][1], self.marqueeRect[1][0], self.marqueeRect[1][1] )
+ # draw the selection rect
+ if self.marqueeLoc:
+ ctx.save()
+ ctx.set_line_width(Config.MARQUEE_SIZE)
+ ctx.set_dash((10,10)) # Gdk.LINE_ON_OFF_DASH equivalent?
+ ctx.set_line_cap(cairo.LINE_CAP_BUTT)
+ ctx.set_line_join(cairo.LINE_JOIN_MITER)
+ ctx.set_source_rgb(CairoUtil.gdk_color_to_cairo(
+ self.colors["Preview_Note_Selected"]))
+ ctx.rectangle(self.marqueeRect[0][0], self.marqueeRect[0][1],
+ self.marqueeRect[1][0], self.marqueeRect[1][1])
+ ctx.stroke()
+ ctx.restore()
if self.recording: # draw playhead
- self.gc.set_line_attributes( Config.PLAYHEAD_SIZE, Gdk.LINE_SOLID, Gdk.CAP_BUTT, Gdk.JOIN_MITER )
- self.gc.foreground = self.colors["black"]
- widget.window.draw_line( self.gc, self.playheadX, event.area.y, self.playheadX, event.area.y + event.area.height )
+ ctx.save()
+ ctx.set_line_width(Config.PLAYHEAD_SIZE)
+ ctx.set_line_cap(cairo.LINE_CAP_BUTT)
+ ctx.set_line_join(cairo.LINE_JOIN_MITER)
+ ctx.set_source_rgb(CairoUtil.gdk_color_to_cairo(
+ self.colors["black"]))
+ # TODO: event properties is not available anymore
+ # use clipping?
+ ctx.rectangle(self.playheadX, event.area.y, self.playheadX,
+ event.area.y + event.area.height)
+ ctx.stroke()
+ ctx.restore()
def invalidatePreview( self, x, y, width, height, page = -1, base = True ):
if page != -1 and page != self.getPage():
@@ -863,8 +884,9 @@ class Loop( Popup ):
self.previewDirtyRect = self.previewDirtyRect.union( self.dirtyRectToAdd )
self.previewDirty = True
- if self.previewDA.window != None:
- self.previewDA.window.invalidate_rect( self.dirtyRectToAdd, True )
+ if self.previewDA.get_window() != None:
+ self.previewDA.get_window().invalidate_rect(self.dirtyRectToAdd,
+ True)
#=======================================================
# Recording
@@ -1379,7 +1401,7 @@ class Loop( Popup ):
self.setCursor("pencil")
def setCursor( self, cursor ):
- self.window.set_cursor(self.cursor[cursor])
+ self.get_window().set_cursor(self.cursor[cursor])
def ticksToPixels( self, beats, ticks ):
return int(round( ticks * self.pixelsPerTick[beats] ))
@@ -1404,8 +1426,6 @@ class Shortcut( Popup ):
def __init__( self, label, owner ):
Popup.__init__( self, label, owner )
- self.gc = self.owner.gc
-
self.GUI = {}
self.GUI["mainBox"] = Gtk.VBox()
@@ -1425,7 +1445,7 @@ class Shortcut( Popup ):
for row in layout:
offset = row[0]
hbox = Gtk.HBox()
- self.GUI["keyBox"].pack_start( hbox, padding = 2 )
+ self.GUI["keyBox"].pack_start(hbox, True, True, padding=2)
separator = Gtk.Label(label="")
separator.set_size_request( int(Block.Block.KEYSIZE*row[0]) + style.DEFAULT_PADDING, -1 )
hbox.pack_start(separator, False, True, 0)
@@ -1434,7 +1454,7 @@ class Shortcut( Popup ):
hbox.pack_end(separator, False, True, 0)
for key in row[1]:
self.GUI[key] = Gtk.ToggleButton()
- self.GUI[key].connect( "expose-event", self.keyExpose )
+ self.GUI[key].connect("draw", self.__draw_cb)
self.GUI[key].connect( "toggled", self.keyToggled )
self.GUI[key].set_size_request( Block.Block.KEYSIZE, Block.Block.KEYSIZE )
self.GUI[key].key = key
@@ -1481,10 +1501,13 @@ class Shortcut( Popup ):
else:
self.owner.onKeyPress( widget, event )
- def keyExpose( self, widget, event ):
- self.gc.set_clip_mask( self.owner.blockMask )
- self.gc.set_clip_origin( event.area.x - Block.Block.KEYMASK_START, event.area.y )
- widget.window.draw_drawable( self.gc, widget.image[widget.get_active()], 0, 0, event.area.x, event.area.y, event.area.width, event.area.height )
+ def __draw_cb(self, widget, ctx):
+ # TODO gtk3 no mask yet
+ #self.gc.set_clip_mask( self.owner.blockMask )
+ #self.gc.set_clip_origin( event.area.x - Block.Block.KEYMASK_START, event.area.y )
+ # TODO: why is doing this?
+ #widget.window.draw_drawable( self.gc, widget.image[widget.get_active()], 0, 0, event.area.x, event.area.y, event.area.width, event.area.height )
+ Gtk.ToggleButton.do_draw(self, ctx)
return True
def keyToggled( self, widget ):
diff --git a/common/Util/CairoUtil.py b/common/Util/CairoUtil.py
new file mode 100644
index 0000000..7918210
--- /dev/null
+++ b/common/Util/CairoUtil.py
@@ -0,0 +1,44 @@
+# useful methods to work with cairo in TamTam
+from gi.repository import Gdk
+
+def gdk_color_to_cairo(color):
+ return (color.red / 65536.0, color.green / 65536.0, color.blue / 65536.0)
+
+def get_gdk_color(str_color):
+ result, color = Gdk.Color.parse(str_color)
+ return color
+
+def draw_round_rect(ctx, x, y, width, height, radio=10):
+ # Move to A
+ ctx.move_to(x + radio, y)
+ # Straight line to B
+ ctx.line_to(x + width - radio, y)
+ # Curve to C, Control points are both at Q
+ ctx.curve_to(x + width, y, x + width, y, x + width, y + radio)
+ # Move to D
+ ctx.line_to(x + width, y + height - radio)
+ # Curve to E
+ ctx.curve_to(x + width, y + height, x + width, y + height,
+ x + width - radio, y + height)
+ # Line to F
+ ctx.line_to(x + radio, y + height)
+ # Curve to G
+ ctx.curve_to(x, y + height, x, y + height, x, y + height - radio)
+ # Line to H
+ ctx.line_to(x, y + radio)
+ # Curve to A
+ ctx.curve_to(x, y, x, y, x + radio, y)
+
+def draw_drum_mask(ctx, x, y, size):
+ side = size / 3
+ ctx.move_to(x + side, y)
+ ctx.new_path()
+ ctx.line_to(x + side * 2, y)
+ ctx.line_to(x + size, y + side)
+ ctx.line_to(x + size, y + side * 2)
+ ctx.line_to(x + side * 2, y + size)
+ ctx.line_to(x + side, y + size)
+ ctx.line_to(x, y + side * 2)
+ ctx.line_to(x, y + side)
+ ctx.line_to(x + side, y)
+ ctx.close_path()
diff --git a/common/Util/ThemeWidgets.py b/common/Util/ThemeWidgets.py
index 5eb6da5..a941ebf 100644
--- a/common/Util/ThemeWidgets.py
+++ b/common/Util/ThemeWidgets.py
@@ -4,15 +4,12 @@ import cairo
import logging
import common.Config as Config
from common.Config import imagefile
+from common.Util import CairoUtil
from sugar3.graphics.combobox import ComboBox
from sugar3.graphics.palette import Palette, WidgetInvoker
-def gdk_color_to_cairo(color):
- return (color.red / 65536.0, color.green / 65536.0, color.blue / 65536.0)
-
-
class ImageVScale(Gtk.VScale):
def __init__(self, image_name, adjustment=None, slider_border=0,
@@ -703,7 +700,7 @@ class RoundFixed(Gtk.Fixed):
# within the dirty rect, but drawing seems to be quite fast compared
# to python code, so just leave it at clipping by each geometry feature
- cr.set_source_rgb(*gdk_color_to_cairo(self.bordercolor))
+ cr.set_source_rgb(*CairoUtil.gdk_color_to_cairo(self.bordercolor))
if self.borderW:
if stopY > self.corner and startY < self.heightMINcorner:
if startX < self.borderW: # draw left border
@@ -1223,30 +1220,16 @@ class keyButton(Gtk.Button):
self.cr = self.window.cairo_create()
self.cr.set_source_rgb(self.fillcolor[0], self.fillcolor[1],
self.fillcolor[2])
- self.draw_round_rect(self.cr, self.drawX - self.width // 2,
+ CairoUtil.draw_round_rect(self.cr, self.drawX - self.width // 2,
self.drawY - self.height // 2, self.width, self.height, 10)
self.cr.fill()
self.cr.set_line_width(3)
self.cr.set_source_rgb(self.strokecolor[0], self.strokecolor[1],
self.strokecolor[2])
- self.draw_round_rect(self.cr, self.drawX - self.width // 2,
+ CairoUtil.draw_round_rect(self.cr, self.drawX - self.width // 2,
self.drawY - self.height // 2, self.width, self.height, 10)
self.cr.stroke()
- def draw_round_rect(self, context, x, y, w, h, r):
- context.move_to(x + r, y) # Move to A
- context.line_to(x + w - r, y) # Straight line to B
- # Curve to C, Control points are both at Q
- context.curve_to(x + w, y, x + w, y, x + w, y + r)
- context.line_to(x + w, y + h - r) # Move to D
- # Curve to E
- context.curve_to(x + w, y + h, x + w, y + h, x + w - r, y + h)
- context.line_to(x + r, y + h) # Line to F
- context.curve_to(x, y + h, x, y + h, x, y + h - r) # Curve to G
- context.line_to(x, y + r) # Line to H
- context.curve_to(x, y, x, y, x + r, y) # Curve to A
- return
-
def set_fillcolor(self, r, g, b):
self.fillcolor = [r, g, b]
self.queue_draw()