# Change the selected parameter via the mouse wheel
# Just hover anywhere over the window and use the mouse wheel
# + without shift or control pressed: scroll the window
# + with control pressed: multiply or divide the value to add/substract by 10
# + with shift pressed: add/substract the value
# + with control and shift pressed: control action first, then shift action
# - poor python coding by Dizzi
import poser
import wx
import wx.aui
import os.path

class WheelPosing(wx.Panel):
	selectedParamName=""
	offset=1.0
	def __init__(self,parent,title):
		wx.Panel.__init__(self, parent)
		self.sizer = wx.BoxSizer(wx.VERTICAL)
		self.SetSizer(self.sizer)
		self.SetAutoLayout(1)
		self.sizer.SetSizeHints(self)
		list=self.GetParamList()
		self.listBox = wx.ListBox(self, 60, (10, 60), (200, 220), list, wx.LB_SINGLE|wx.LB_NEEDED_SB)
		self.Bind(wx.EVT_LISTBOX, self.EvtListBoxClick, self.listBox)
		self.Bind(wx.EVT_MOUSEWHEEL, self.Wheel)
		self.sizer.Add(self.listBox, 1, wx.EXPAND|wx.ALL, 0)
		self.txtValue = wx.TextCtrl(self, 0)
		self.txtValue.SetEditable(0)
		self.sizer.Add(self.txtValue)
		self.txtValueOffset = wx.TextCtrl(self, 0)
		self.txtValueOffset.SetEditable(0)
		self.sizer.Add(self.txtValueOffset)
		self.txtValueOffset.SetValue(str(self.offset))
		self.Layout()
		poser.Scene().SetEventCallback(self.evcbParam)
	def __del__(self):
		poser.Scene().ClearEventCallback()
	def EvtListBoxClick(self, event):
		self.SelectionChanged(event)

	def CheckList(self):
		self.listBox.Set(self.GetParamList())
	def GetParamList(self):
		list=[]
		for parm in poser.Scene().CurrentActor().Parameters():
			if not parm.Hidden():
			   list = list + [parm.Name()]
		return list
	def SelectionChanged(self,event):
		self.selectedParamName=event.GetString()
		self.txtValue.SetValue(str(poser.Scene().CurrentActor().Parameter(self.selectedParamName).Value()))

	def Wheel(self, event):
#		delta = event.GetWheelDelta()
		rotation = event.GetWheelRotation()
#		print 'delta: ' + repr(delta) + ' rotation:' + repr(rotation)
		if (event.ControlDown()):
			if rotation>0:
				self.offset=self.offset*10
			else:
			   self.offset=self.offset/10
			self.txtValueOffset.SetValue(str(self.offset))
		if (event.ShiftDown()):
			if rotation>0:
				self.AddToDial(self.offset)
			else:
			   self.AddToDial(-1*self.offset)
	def AddToDial(self, amount):
		scene=poser.Scene()
		param=scene.CurrentActor().Parameter(self.selectedParamName)
		param.SetValue(param.Value()+amount)
		self.txtValue.SetValue(str(param.Value()))
		scene.Draw()
	
	def evcbParam(self, iScene, iEventType):
		if (iEventType & poser.kEventCodeACTORSELECTIONCHANGED):
			self.CheckList()
		if (iEventType & poser.kEventCodeACTORDELETED):
			self.CheckList()
		if (iEventType & poser.kEventCodeITEMRENAMED):
			self.CheckList()

name = "Wheel Posing"
man = poser.WxAuiManager()
root = man.GetManagedWindow()

win = WheelPosing(root, name)
pane = wx.aui.AuiPaneInfo()
pane.Caption(name).CaptionVisible().CloseButton().Resizable().DestroyOnClose()
pane.FloatingSize(wx.Size(150, 125)).BestSize(wx.Size(50, 50)).Right().PinButton().Dock()
man.AddPane(win, pane)
pane.Show()
man.Update()


