Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Jam
diff options
context:
space:
mode:
authoramartin <olpc@xo-05-28-21.localdomain>2007-09-10 17:27:56 (GMT)
committer amartin <olpc@xo-05-28-21.localdomain>2007-09-10 17:27:56 (GMT)
commit1e45ea378d862e98650c0acef27ae3e18425443f (patch)
tree1038e0897f460a29e3233e61e765d2b60c1e0a08 /Jam
parentbbda4f776235580b1f4a09510b2731ccded104ad (diff)
Jam keyboard shortcuts
Diffstat (limited to 'Jam')
-rw-r--r--Jam/Block.py98
-rw-r--r--Jam/Desktop.py58
-rw-r--r--Jam/JamMain.py100
-rw-r--r--Jam/Popup.py114
4 files changed, 324 insertions, 46 deletions
diff --git a/Jam/Block.py b/Jam/Block.py
index bbe6391..53048c2 100644
--- a/Jam/Block.py
+++ b/Jam/Block.py
@@ -20,6 +20,12 @@ class Block():
SNAP = 15
+ PAD = 4
+
+ KEYSIZE = 26
+ KEYOFFSET = HEIGHT - PAD - PAD - KEYSIZE
+ KEYMASK_START = 309
+
def __init__( self, owner, data ):
self.owner = owner
self.gc = owner.gc
@@ -161,6 +167,10 @@ class Block():
def setData( self, key, value ):
self.data[ key ] = value
+ def testMouseOver( self, event ):
+ if self.child: return self.child.testMouseOver( event )
+ return False
+
def button_press( self, event ):
if event.y < self.y or event.y > self.endY:
@@ -452,7 +462,7 @@ class Loop(Block):
HEAD = 13
BEAT = 23
- TAIL = BEAT + 4
+ TAIL = BEAT + Block.PAD
WIDTH = [ HEAD + BEAT*(n-1) + TAIL for n in range(Config.MAXIMUM_BEATS+1) ]
@@ -461,9 +471,12 @@ class Loop(Block):
MASK_START = 200
MASK_BEAT = MASK_START + HEAD
MASK_TAIL = MASK_START + HEAD + BEAT*3
+
+ KEYRECT = [ HEAD + Block.PAD, Block.KEYOFFSET, Block.KEYSIZE, Block.KEYSIZE ]
+ KEYRECT += [ KEYRECT[0]+KEYRECT[2], KEYRECT[1]+KEYRECT[3] ]
#::: data format:
- # { "name": name, "id": pageId [, "beats": 2-12, "regularity": 0-1 ] }
+ # { "name": name, "id": pageId [, "beats": 2-12, "regularity": 0-1, "key": shortcut ] }
#:::
def __init__( self, owner, data ):
Block.__init__( self, owner, data )
@@ -481,6 +494,12 @@ class Loop(Block):
if "regularity" not in self.data.keys():
self.data["regularity"] = random.random()
+ if "key" not in self.data.keys():
+ self.data["key"] = None
+
+ self.keyActive = False
+ self.keyImage = [ self.owner.getKeyImage( self.data["key"], False ),
+ self.owner.getKeyImage( self.data["key"], True ) ]
self.img = [ self.owner.getLoopImage( self.data["id"], False ),
self.owner.getLoopImage( self.data["id"], True ) ]
@@ -522,6 +541,10 @@ class Loop(Block):
self.owner.noteDB.updatePage( self.data["id"], PARAMETER.PAGE_BEATS, value )
self._updateWidth()
self.updateLoop()
+ elif key == "key":
+ self.keyImage = [ self.owner.getKeyImage( value, False ),
+ self.owner.getKeyImage( value, True ) ]
+ self.invalidate_rect()
def substitute( self, block ):
self.invalidateBranch( True )
@@ -583,12 +606,27 @@ class Loop(Block):
child.setActive( True )
self.owner.updateLoop( self.getRoot().child )
+ def _addParent( self, parent ):
+ Block._addParent( self, parent )
+
+ if self.parent.type == Instrument:
+ self.keyActive = True
+ else:
+ root = self.getRoot()
+ if root.type == Instrument:
+ root = root.child
+ if root.getData("key") == None:
+ root.setData( "key", self.data["key"] )
+ self.setData( "key", None )
+
def _removeParent( self ):
if self.active:
loopRoot = self.getRoot().child
parent = self.parent
else:
loopRoot = None
+
+ self.keyActive = False
Block._removeParent( self )
@@ -598,6 +636,21 @@ class Loop(Block):
self.setActive( False )
parent.child = None # disconnect us before updating
self.owner.updateLoop( loopRoot )
+
+ def testMouseOver( self, event ):
+ return self.testWithinKey( event )
+
+ def testWithinKey( self, event ):
+ if not self.keyActive:
+ return False
+
+ x = event.x - self.x
+ y = event.y - self.y
+
+ if Loop.KEYRECT[0] <= x <= Loop.KEYRECT[4] and Loop.KEYRECT[1] <= y <= Loop.KEYRECT[5]:
+ return self
+
+ return False
def _doButtonPress( self, event ): # we were hit with a button press
pass
@@ -643,7 +696,7 @@ class Loop(Block):
curx = self.x + Loop.HEAD
while beats > 3:
if curx >= stopX:
- return
+ break
elif curx + Loop.BEAT_MUL3 > startX:
x = max( startX, curx )
endX = min( stopX, curx + Loop.BEAT_MUL3 )
@@ -659,9 +712,7 @@ class Loop(Block):
curx += Loop.BEAT_MUL3
beats -= 3
- if beats:
- if curx >= stopX:
- return
+ if beats and curx < stopX:
endX = curx + Loop.BEAT*beats
if endX > startX:
x = max( startX, curx )
@@ -677,24 +728,28 @@ class Loop(Block):
pixmap.draw_drawable( self.gc, loop, x-self.x, y-self.y, x, y, width, height )
curx += Loop.BEAT*beats
-
+
+
#-- draw tail -----------------------------------------
- if curx >= stopX:
- return
-
- x = max( startX, curx )
- endX = min( stopX, self.endX )
- width = endX - x
+ if curx < stopX:
+ x = max( startX, curx )
+ endX = min( stopX, self.endX )
+ width = endX - x
- # draw border
- self.gc.set_clip_origin( curx-Loop.MASK_TAIL, self.y )
- pixmap.draw_rectangle( self.gc, True, x, y, width, height )
+ # draw border
+ self.gc.set_clip_origin( curx-Loop.MASK_TAIL, self.y )
+ pixmap.draw_rectangle( self.gc, True, x, y, width, height )
- # 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 )
+ # 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 )
+ #-- 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 )
+
def drawHighlight( self, startX, startY, stopX, stopY, pixmap ):
self.gc.foreground = self.owner.colors["Border_Highlight"]
@@ -726,6 +781,11 @@ class Loop(Block):
self.gc.set_clip_origin( x-Loop.MASK_TAIL, self.y )
pixmap.draw_rectangle( self.gc, True, x, self.y, Loop.TAIL, self.height )
+ def drawKeyHighlight( self, pixmap ):
+ self.gc.foreground = self.owner.colors["Border_Highlight"]
+ self.gc.set_clip_origin( self.x+Loop.KEYRECT[0]-Block.KEYMASK_START, self.y+Loop.KEYRECT[1]-Block.KEYSIZE )
+ pixmap.draw_rectangle( self.gc, True, self.x+Loop.KEYRECT[0], self.y+Loop.KEYRECT[1], Block.KEYSIZE, Block.KEYSIZE )
+
def clear( self ):
self.owner.noteDB.deleteNotesByTrack( [ self.data["id"] ], [ 0 ] )
diff --git a/Jam/Desktop.py b/Jam/Desktop.py
index a814132..e8a8afd 100644
--- a/Jam/Desktop.py
+++ b/Jam/Desktop.py
@@ -52,6 +52,7 @@ class Desktop( gtk.EventBox ):
self.possibleSubstitute = None
self.dragging = False
self.possibleDelete = False
+ self.overKey = False
#-- Popups --------------------------------------------
self.rightClicked = False
@@ -146,6 +147,9 @@ class Desktop( gtk.EventBox ):
def getInstrumentImage( self, id, active = False ):
return self.owner.getInstrumentImage( id, active )
+ def getKeyImage( self, key, active = False ):
+ return self.owner.getKeyImage( key, active )
+
def getLoopImage( self, id, active = False ):
return self.owner.getLoopImage( id, active )
@@ -242,27 +246,21 @@ class Desktop( gtk.EventBox ):
if self.clickedBlock:
if self.clickedBlock.type == Block.Instrument:
self.popup[Popup.Instrument].setBlock( self.clickedBlock )
- if self.popup[Popup.Instrument].is_up():
- self.popup[Popup.Instrument].updatePosition()
- else:
- self.popup[Popup.Instrument].popup( True )
-
elif self.clickedBlock.type == Block.Drum:
self.popup[Popup.Drum].setBlock( self.clickedBlock )
- if self.popup[Popup.Drum].is_up():
- self.popup[Popup.Drum].updatePosition()
- else:
- self.popup[Popup.Drum].popup( True )
-
elif self.clickedBlock.type == Block.Loop:
self.popup[Popup.Loop].setBlock( self.clickedBlock )
- if self.popup[Popup.Loop].is_up():
- self.popup[Popup.Loop].updatePosition()
- else:
- self.popup[Popup.Loop].popup( True )
self.clickedBlock = None
self.rightClicked = False
+ self.overKey = False # just in case
+ return
+
+ if self.overKey:
+ self.popup[Popup.Shortcut].setBlock( self.clickedBlock )
+ self.overKey.invalidate_rect( False )
+ self.overKey = False
+ self.clickedBlock = None
return
if self.possibleDelete:
@@ -304,7 +302,10 @@ class Desktop( gtk.EventBox ):
def on_motion_notify( self, widget, event ):
- if not self.clickedBlock or self.rightClicked:
+ if self.rightClicked:
+ return
+
+ if self.clickedBlock and self.overKey:
return
if event.is_hint or widget != self:
@@ -312,11 +313,31 @@ class Desktop( gtk.EventBox ):
event.x = float(x)
event.y = float(y)
event.state = state
-
+
+ blockCount = len(self.blocks)
+
+ if not self.clickedBlock:
+ if self.popup[Popup.Shortcut].is_up():
+ return
+ for i in range(blockCount-1, -1, -1):
+ over = self.blocks[i].testMouseOver( event )
+ if over:
+ if self.overKey != self.blocks[i]:
+ if self.overKey:
+ self.overKey.invalidate_rect( False )
+ self.overKey = over
+ self.overKey.invalidate_rect( False )
+ return
+ if self.overKey:
+ self.overKey.invalidate_rect( False )
+ self.overKey = False
+ return
+
self.dragging = True
if self.clickedBlock.motion_notify( event ): # first drag of root block, remove from self.blocks
self.blocks.remove( self.clickedBlock )
+ blockCount = len(self.blocks)
if event.y < 0 or event.y > self.alloc.height:
self.possibleDelete = True
@@ -324,7 +345,6 @@ class Desktop( gtk.EventBox ):
else:
self.possibleDelete = False
- blockCount = len(self.blocks)
if self.clickedBlock.canChild and blockCount:
for i in range(blockCount-1, -1, -1):
handled = self.blocks[i].testChild( self.clickedBlock.getParentAnchor() )
@@ -415,6 +435,10 @@ class Desktop( gtk.EventBox ):
if self.possibleSubstitute:
self.possibleSubstitute.drawHighlight( startX, startY, stopX, stopY, DA.window )
+ # draw key highlight
+ if self.overKey:
+ self.overKey.drawKeyHighlight( DA.window )
+
def invalidate_rect( self, x, y, width, height, base = True ):
self.dirtyRectToAdd.x = x
self.dirtyRectToAdd.y = y
diff --git a/Jam/JamMain.py b/Jam/JamMain.py
index 1954fe7..012aa21 100644
--- a/Jam/JamMain.py
+++ b/Jam/JamMain.py
@@ -122,7 +122,7 @@ class JamMain(SubActivity):
byte = 0
shift = 0
self.blockMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() )
-
+
pix = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+"sampleBG.png" )
self.sampleBg = gtk.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(), gtk.gdk.RGB_DITHER_NONE )
@@ -170,6 +170,18 @@ class JamMain(SubActivity):
self.loopImage = {} # get filled in through updateLoopImage
self.loopImageActive = {} #
+ #-- Key Images ----------------------------------------
+ self.keyImage = {}
+ self.keyImageActive = {}
+ # use hardware key codes to work on any keyboard layout (hopefully)
+ self.valid_shortcuts = { 18:"9", 19:"0", 20:"-", 21:"=",
+ 32:"O", 33:"P", 34:"[", 35:"]",
+ 48:";", 51:"'",
+ 60:".", 61:"/",
+ None:" " }
+ for key in self.valid_shortcuts.keys():
+ self.prepareKeyImage( key )
+
#-- Toolbars ------------------------------------------
self.activity.activity_toolbar.keep.show()
@@ -407,9 +419,11 @@ class JamMain(SubActivity):
if loopId == None: # create new loop
startTick = 0
+ firstTime = True
else: # update loop
startTick = self.csnd.loopGetTick( loopId )
self.csnd.loopDestroy( loopId )
+ firstTime = False
loopId = self.csnd.loopCreate()
@@ -436,10 +450,30 @@ class JamMain(SubActivity):
self.drumFillin.play()
- while startTick > ticks: # align with last beat
- startTick -= Config.TICKS_PER_BEAT
-
- startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ # sync to heartbeat
+ if False: # firstTime: # always force first note to play rather than snaping to nearest beat.. good idea?
+ startTick = ticks - Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ else:
+ while startTick > ticks: # align with last beat
+ startTick -= Config.TICKS_PER_BEAT
+ beatTick = int(startTick) % Config.TICKS_PER_BEAT
+ heartTick = self.csnd.loopGetTick( self.heartbeatLoop )
+ if beatTick > heartTick:
+ if beatTick - heartTick < heartTick + Config.TICKS_PER_BEAT - beatTick:
+ startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ else:
+ startTick = (1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ else:
+ if heartTick - beatTick < beatTick + Config.TICKS_PER_BEAT - heartTick:
+ startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ else:
+ startTick = (-1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+
+ if startTick >= ticks:
+ startTick -= ticks
+ elif startTick < 0:
+ startTick += ticks
+
self.csnd.loopSetTick( startTick, loopId )
if not self.paused:
@@ -454,9 +488,11 @@ class JamMain(SubActivity):
def _playLoop( self, id, volume, reverb, tune, loopId = None, force = False ):
if loopId == None: # create new loop
startTick = 0
+ firstTime = True
else: # update loop
startTick = self.csnd.loopGetTick( loopId )
self.csnd.loopDestroy( loopId )
+ firstTime = False
loopId = self.csnd.loopCreate()
@@ -481,11 +517,32 @@ class JamMain(SubActivity):
self.csnd.loopSetNumTicks( offset, loopId )
+
+ # sync to heartbeat
+ if False: # firstTime: # always force first note to play rather than snaping to nearest beat.. good idea?
+ startTick = offset - Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ else:
+ while startTick > offset: # align with last beat
+ startTick -= Config.TICKS_PER_BEAT
+ beatTick = int(startTick) % Config.TICKS_PER_BEAT
+ heartTick = self.csnd.loopGetTick( self.heartbeatLoop )
+ if beatTick > heartTick:
+ if beatTick - heartTick < heartTick + Config.TICKS_PER_BEAT - beatTick:
+ startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ else:
+ startTick = (1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ else:
+ if heartTick - beatTick < beatTick + Config.TICKS_PER_BEAT - heartTick:
+ startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ else:
+ startTick = (-1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+
+ if startTick >= offset:
+ startTick -= offset
+ elif startTick < 0:
+ startTick += offset
+
- while startTick > offset: # align with last beat
- startTick -= Config.TICKS_PER_BEAT
-
- startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
self.csnd.loopSetTick( startTick, loopId )
if not self.paused or force:
@@ -650,6 +707,10 @@ class JamMain(SubActivity):
if active: return self.instrumentImageActive[id]
else: return self.instrumentImage[id]
+ def getKeyImage( self, key, active = False ):
+ if active: return self.keyImageActive[key]
+ else: return self.keyImage[key]
+
def getLoopImage( self, id, active = False ):
if active: return self.loopImageActive[id]
else: return self.loopImage[id]
@@ -724,6 +785,27 @@ class JamMain(SubActivity):
self.gc.set_clip_origin( endX-self.sampleNoteMask.endOffset, y )
pixmap.draw_rectangle( self.gc, True, endX, y, 3, self.sampleNoteHeight )
+ def prepareKeyImage( self, key ):
+ win = gtk.gdk.get_default_root_window()
+ pangolayout = self.create_pango_layout( _(self.valid_shortcuts[key]) )
+ extents = pangolayout.get_pixel_extents()
+ x = ( Block.Block.KEYSIZE - extents[1][2] ) // 2
+ y = ( Block.Block.KEYSIZE - extents[1][3] ) // 2
+
+ pixmap = gtk.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 = gtk.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
+
def updateLoopImage( self, id ):
page = self.noteDB.getPage( id )
diff --git a/Jam/Popup.py b/Jam/Popup.py
index 6f6a7e1..8bca64c 100644
--- a/Jam/Popup.py
+++ b/Jam/Popup.py
@@ -85,7 +85,8 @@ class Popup( Palette ):
self.owner.activity.handler_unblock(self.owner.activity.focusInHandler)
def updatePosition( self ):
- self._update_cursor_position()
+ self.props.invoker._cursor_x = -1
+ self.props.invoker._cursor_y = -1
self._update_position()
def closePopup( self, widget, event ):
@@ -97,6 +98,12 @@ class Popup( Palette ):
def on_key_release( self, widget, event ):
self.owner.onKeyRelease( widget, event )
+ def setBlock( self, block ):
+ if self.is_up():
+ self.updatePosition()
+ else:
+ self.popup( True )
+
class Instrument( Popup ):
@@ -185,6 +192,8 @@ class Instrument( Popup ):
self.settingBlock = False
+ Popup.setBlock( self, block )
+
def handleVolume( self, widget ):
if not self.settingBlock:
self.block.setData( "volume", widget.get_value() )
@@ -300,6 +309,8 @@ class Drum( Popup ):
self.settingBlock = False
+ Popup.setBlock( self, block )
+
def handleVolume( self, widget ):
if not self.settingBlock:
self.block.setData( "volume", widget.get_value() )
@@ -309,6 +320,12 @@ class Drum( Popup ):
self.block.setData( "reverb", widget.get_value() )
def handleBeats( self, widget ):
+ # snap to 0 decimal places
+ val = widget.get_value()
+ if round( val ) != val:
+ widget.set_value( round( val ) )
+ return
+
if not self.settingBlock:
self.block.setData( "beats", int(round( widget.get_value() )) )
@@ -483,6 +500,8 @@ class Loop( Popup ):
if self.previewDA.alloced:
self.invalidatePreview( 0, 0, self.previewDA.width, self.previewDA.height, -1, True )
+ Popup.setBlock( self, block )
+
def popdown( self, immediate = False ):
self.applyNoteSelection( SELECTNOTES.NONE, 0, [], self.curPage )
@@ -501,6 +520,12 @@ class Loop( Popup ):
# Handelers
def handleBeats( self, widget ):
+ # snap to 0 decimal places
+ val = widget.get_value()
+ if round( val ) != val:
+ widget.set_value( round( val ) )
+ return
+
if not self.settingBlock:
self.curBeats = int(round( widget.get_value() ))
self.block.setData( "beats", self.curBeats )
@@ -1261,4 +1286,91 @@ 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()
+ self.set_content( self.GUI["mainBox"] )
+
+ #-- Keys ----------------------------------------------
+ # match keycodes from JamMain.valid_shortcuts
+ layout = [ [ 0.0, [ 18, 19, 20, 21 ] ],
+ [ 0.3, [ 32, 33, 34, 35 ] ],
+ [ 1.6, [ 48, 51 ] ],
+ [ 1.1, [ 60, 61 ] ] ]
+
+ self.GUI["keyBox"] = gtk.VBox()
+ self.GUI["mainBox"].pack_start( self.GUI["keyBox"], padding = style.DEFAULT_PADDING - 2 )
+
+ for row in layout:
+ offset = row[0]
+ hbox = gtk.HBox()
+ self.GUI["keyBox"].pack_start( hbox, padding = 2 )
+ separator = gtk.Label("")
+ separator.set_size_request( int(Block.Block.KEYSIZE*row[0]) + style.DEFAULT_PADDING, -1 )
+ hbox.pack_start( separator, False )
+ separator = gtk.Label("")
+ separator.set_size_request( style.DEFAULT_PADDING, -1 )
+ hbox.pack_end( separator, False )
+ for key in row[1]:
+ self.GUI[key] = gtk.ToggleButton()
+ self.GUI[key].connect( "expose-event", self.keyExpose )
+ self.GUI[key].connect( "toggled", self.keyToggled )
+ self.GUI[key].set_size_request( Block.Block.KEYSIZE, Block.Block.KEYSIZE )
+ self.GUI[key].key = key
+ self.GUI[key].image = [ self.owner.getKeyImage( key, False ),
+ self.owner.getKeyImage( key, True ) ]
+ hbox.pack_start( self.GUI[key], False, padding = 2 )
+
+ #-- None ----------------------------------------------
+ self.GUI["noneBox"] = gtk.HBox()
+ self.GUI["mainBox"].pack_start( self.GUI["noneBox"], padding = style.DEFAULT_PADDING )
+ self.GUI["noneButton"] = gtk.Button( _("None") )
+ self.GUI["noneButton"].connect( "clicked", self.handleNone )
+ self.GUI["noneBox"].pack_start( self.GUI["noneButton"], True, False, padding = style.DEFAULT_PADDING )
+
+ self.GUI["mainBox"].show_all()
+
+ self.key = None
+
+ def setBlock( self, block ):
+ self.settingBlock = True
+
+ if self.key != None:
+ self.GUI[self.key].set_active( False )
+
+ self.block = block
+ self.key = self.block.getData( "key" )
+
+ if self.key != None:
+ self.GUI[self.key].set_active( True )
+
+ self.settingBlock = False
+ Popup.setBlock( self, block )
+
+ 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 )
+ return True
+
+ def keyToggled( self, widget ):
+ if widget.get_active() and not self.settingBlock:
+ if self.key != None:
+ self.GUI[self.key].set_active( False )
+
+ self.key = widget.key
+
+ self.block.setData( "key", self.key )
+
+ self.popdown( True )
+
+ def handleNone( self, widget ):
+ if self.key != None:
+ self.GUI[self.key].set_active( False )
+ self.key = None
+ self.block.setData( "key", self.key )
+
+ self.popdown( True )