[jokosher-devel] [PATCH] for ticket #26 (Moving instruments)
- From: "Jens Geiregat" <jens geiregat gmail com>
- To: jokosher-devel-list gnome org
- Subject: [jokosher-devel] [PATCH] for ticket #26 (Moving instruments)
- Date: Fri, 4 Aug 2006 14:56:43 +0200
Ticket link:
http://jokosher.python-hosting.com/ticket/26
Moving the instruments is undo-able and save-able. When dragging
starts, the default drag-icon is changed into the image of the
instrument that is being dragged.
I had some problems with those drag-icons: they re-appeared exactly 5
minutes after the drag and drop. This seems to be fixed now though.
Jens "RealNitro" Geiregat
Index: InstrumentViewer.py
===================================================================
--- InstrumentViewer.py (revision 543)
+++ InstrumentViewer.py (working copy)
@@ -21,6 +21,11 @@
UNSELECTED_COLOUR = None
SELECTED_COLOUR = None
+ INSTR_DRAG_TYPE = 83 # Number only to be used inside Jokosher
+ DRAG_TARGETS = [ ( "jokosher_instr_move", # A custom name for the instruments
+ gtk.TARGET_SAME_APP, # Only move inside Jo
+ INSTR_DRAG_TYPE )] # Use the custom number
+
#_____________________________________________________________________
def __init__(self, project, instrument, projectview, mainview, small = False):
@@ -42,8 +47,10 @@
self.add(self.mainBox)
self.headerBox = gtk.VBox()
+ self.headerEventBox = gtk.EventBox()
+ self.headerEventBox.add(self.headerBox)
self.headerAlign = gtk.Alignment(0, 0, 1.0, 1.0)
- self.headerAlign.add(self.headerBox)
+ self.headerAlign.add(self.headerEventBox)
self.eventLane = EventLaneViewer(project, instrument, self, mainview, self.small)
self.mainBox.pack_start(self.headerAlign, False, False)
@@ -111,6 +118,18 @@
self.separator = gtk.HSeparator()
self.headerBox.pack_end(self.separator, False, True)
self.instrument.isSelected = False
+
+ # Begin Drag and Drop code
+ self.headerEventBox.drag_dest_set(gtk.DEST_DEFAULT_DROP,
+ self.DRAG_TARGETS,
+ gtk.gdk.ACTION_MOVE)
+ self.headerEventBox.connect('drag_motion', self.OnDragMotion)
+ self.headerEventBox.drag_source_set(gtk.gdk.BUTTON1_MASK,
+ self.DRAG_TARGETS,
+ gtk.gdk.ACTION_MOVE)
+ # Connect to drag_begin to add a custom icon
+ self.headerEventBox.connect('drag_begin', self.OnDragBegin)
+ self.headerEventBox.connect('drag_drop', self.OnDragDrop)
#_____________________________________________________________________
@@ -195,11 +214,13 @@
self.SELECTED_COLOUR = self.get_style().base[3]
self.modify_bg(gtk.STATE_NORMAL, self.SELECTED_COLOUR)
+ self.headerEventBox.modify_bg(gtk.STATE_NORMAL, self.SELECTED_COLOUR)
self.labeleventbox.modify_bg(gtk.STATE_NORMAL, self.SELECTED_COLOUR)
self.eventLane.modify_bg(gtk.STATE_NORMAL, self.SELECTED_COLOUR)
else:
self.modify_bg(gtk.STATE_NORMAL, self.UNSELECTED_COLOUR)
+ self.headerEventBox.modify_bg(gtk.STATE_NORMAL, self.UNSELECTED_COLOUR)
self.labeleventbox.modify_bg(gtk.STATE_NORMAL, self.UNSELECTED_COLOUR)
self.eventLane.modify_bg(gtk.STATE_NORMAL, self.UNSELECTED_COLOUR)
@@ -246,6 +267,66 @@
a.connect("activate", cb)
m.popup(None, None, None, mouse.button, mouse.time)
-
+
+ #______________________________________________________________________
+
+ def OnDragMotion(self, widget, context, x, y, time):
+ '''
+ Called each time the user moves his/her mouse while dragging.
+ 'if' clause checks if mouse is on an instrument that isn't the
+ source instrument. If so, it swaps that instrument and the
+ source instrument in the GUI. Swapping of the Instrument objects
+ in self.project.instruments happens in OnDragDrop().
+ '''
+ source_header = context.get_source_widget() # Will return an EventBox (self.headerEventBox)
+ if widget != source_header: # Dont swap with self
+ box = self.GetInstrumentViewVBox()
+ iv_array = box.get_children() # InstrumentView array
+ index_iv = iv_array.index(self)
+
+ source_iv = [iv for iv in iv_array if iv.headerEventBox == source_header][0]
+ index_source_iv = iv_array.index(source_iv)
+
+ box.reorder_child(source_iv, index_iv) # Immediate visual feedback
+ # Without these lines the icon would fly back to the start of the drag when dropping
+ context.drag_status(gtk.gdk.ACTION_MOVE, time)
+ return True
+
+ #______________________________________________________________________
+
+ def OnDragBegin(self, widget, context):
+ '''
+ Called at the start of the drag and drop.
+ Displays the instrument icon when dragging.
+ '''
+ widget.drag_source_set_icon_pixbuf(self.instrument.pixbuf)
+ return True
+
+ #______________________________________________________________________
+
+ def OnDragDrop(self, widget, context, x, y, time):
+ '''
+ Called when the user releases MOUSE1.
+ Calls MoveInstrument, which moves the dragged
+ instrument to the end position in the
+ self.project.instruments array.
+ MoveInstrument is undo-able.
+ '''
+ id = self.instrument.id
+ box = self.GetInstrumentViewVBox()
+ position = box.get_children().index(self)
+ self.project.MoveInstrument(id, position)
+
+ #______________________________________________________________________
+
+ def GetInstrumentViewVBox(self):
+ '''
+ Returns the instrumentBox if the current view is a RecordingView.
+ Returns the timebox if the current view is a CompactMixView.
+ '''
+ if hasattr(self.projectview, "instrumentBox"):
+ return self.projectview.instrumentBox
+ else:
+ return self.projectview.timebox
+
#=========================================================================
-
Index: Project.py
===================================================================
--- Project.py (revision 543)
+++ Project.py (working copy)
@@ -806,6 +806,23 @@
#_____________________________________________________________________
+ def MoveInstrument(self, id, position):
+ '''
+ Move an instrument in the instrument list.
+ Used for drag and drop ordering of instruments in
+ InstrumentViewer.py
+
+ undo : MoveInstrument(%(temp)d, %(temp1)d)
+ '''
+ self.temp = id
+ instr = [x for x in self.instruments if x.id == id][0]
+ self.temp1 = self.instruments.index(instr)
+
+ self.instruments.remove(instr)
+ self.instruments.insert(position, instr)
+
+ #_____________________________________________________________________
+
def ClearEventSelections(self):
''' Clears the selection of any events '''
for instr in self.instruments:
Index: RecordingView.py
===================================================================
--- RecordingView.py (revision 543)
+++ RecordingView.py (working copy)
@@ -79,31 +79,40 @@
def Update(self):
+ # Note: InstrumentViews MUST have the order that the instruments have in
+ # Project.instruments to keep the drag and drop of InstrumentViews
+ # consistent!
children = self.instrumentBox.get_children()
+ #Remove all instrumentviews, they will be added inside the for loop
+ for child in children:
+ self.instrumentBox.remove(child)
for instr in self.project.instruments:
+ #Find the InstrumentView that matches instr:
iv = None
for ident, instrV in self.views:
if instrV.instrument is instr:
iv = instrV
break
+ #If there is no InstrumentView for instr, create one:
if not iv:
iv = InstrumentViewer.InstrumentViewer(self.project, instr, self, self.mainview)
instr.AddListener(self)
+ #Add it to the views
self.views.append((instr.id, iv))
iv.headerAlign.connect("size-allocate", self.UpdateSize)
-
- if not iv in children:
- self.instrumentBox.pack_start(iv, False, False)
-
+ #Add the InstrumentView to the VBox
+ self.instrumentBox.pack_start(iv, False, False)
+ #Make sure the InstrumentView is visible:
iv.show()
-
+ #self.views is up to date now
for ident, iv in self.views:
#check if instrument has been deleted
if not iv.instrument in self.project.instruments and iv in children:
self.instrumentBox.remove(iv)
else:
- iv.Update()
+ iv.Update() #Update non-deleted instruments
+
if len(self.views) > 0:
self.UpdateSize(None, self.views[0][1].headerAlign.get_allocation())
else:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]