Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Jam
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2013-01-23 16:03:32 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2013-01-25 22:07:42 (GMT)
commitc2adf88db4df23513e7476e1057275f6b6467bd5 (patch)
tree129141ab0c8e2c411404f4c5c74d2c180690dcb7 /Jam
parent20bf81d221e56080997d8cf60ee8d24b21ed127a (diff)
Partial port drawing operations to cairo
The activity starts but the canvas draw is wrong. The old code used bitmap masks to define non rectangular areas, like in the drum instruments or the loops. Part of this is implemented with cairo, but is not finished. As a final note, this is a too big patch, more work is needed, and probably part of the code can be refactored. Signed-off-by: Gonzalo Odiard <gonzalo@laptop.org>
Diffstat (limited to 'Jam')
-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
6 files changed, 475 insertions, 299 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 ):