Notifications
Clear all

[Closed] Timeslider controlled with the Mouse wheel

Hi all!

I did a quicky search and found an unanswered thread on this two years back but I was wondering if it was possible to map the time slider movement to the mouse wheel.

Cheers!

27 Replies

Hi,

check this out. Not a great solution yet, but a start non the less.


--******************************************************************************
--*
--*  MouseWheely v1.0
--*  by Ofer Zelichover (c) 02/2008
--*  www.oferz.com   maxscript@oferz.com
--*
--******************************************************************************
--*  You may use this script freely as you see fit.							*
--*  You may use parts or the script as a whole in your own scripts.		   *
--*  (it would be nice if you give me a credit if you do so ;))				*
--******************************************************************************
--*  This script comes with no waranty!										
--*  Although I tried this script and couldn't find any problems with it, I can,
--*  in no way be held responsible for any kind of loss or damage, whether	 
--*  direct or indirect, due to the use of this script.						
--*																			
--*  ********************************************************************	  
--*   IF YOU DON'T LIKE THE ABOVE STATEMENT, DON'T USE THIS SCRIPT 	  
--*  ********************************************************************	  
--*																			
--*  If you find any bugs in this script, please let me know.				  
--******************************************************************************
--* Description																*
--* -------------															  *
--* Allows the usage of the mouse wheel to scroll the time slider
--* 
--******************************************************************************
--* Isntallation and Usage:
--* ------------------------
--*  After you run this script, the script will appear in the
--*  "Os tools" category in the customize ui menu.
--*  Assign it to a keyboard shortcut/button/RC Menu
--*  After pressing the button/keyboard key/ RC menu item, use the mouse wheel
--*  to scroll the time slider. Click anywhere to stop the opration.
--*
--***************************************************************************


--*********************************************************
-- Start of macroScript
--************************************************************

macroScript Os_timeWheely
	category:"Os Tools"
	tooltip:"Use mouse wheel to scroll time slider"
	buttontext:"TimeWheely"
(
	local isOpen = false
	rollout ro_timeWheely "test"
	(
		dotNetControl cont "System.Windows.Forms.Control"

		on cont MouseWheel sender event do (
			sliderTime += event.delta/120
		)
		on cont lostFocus do (
			try (destroyDialog ro_timeWheely)catch()
		)
		
		on ro_timeWheely open do (
			cont.focus()
			isOpen = true
		)
		on ro_timeWheely close do (
			isOpen = false
			updateToolbarButtons()
		)
	)

	on isChecked do isOpen

	on execute do (
		if not isOpen then
			createDialog ro_timeWheely pos:[-10000,-10000]
		updateToolbarButtons()
	)
)

hOpe this helps,
o

Hi there!

Tried running it at work but we’re using MAX8 here, maybe that’s the reason it isn’t working… In any case, what version of MAX was it designed to work with and how do I install it properly?

Cheers

Hi,

It’s designed for max 9 and up, since it uses dotNet controls. I’ll look into making a max 8 version, if I can find a suitable activex control.

As for installation, just follow the instructions found in the header of the script.

cheers,
o

I have wanted control of the mouse wheel for sooooo long. I changed your script to control the falloff of Soft Selection for Editable Poly.

simply $.falloff instead of sliderTime.

I’m sure it’s crude but it works great for me. Esp with Bobo’s Base Jump.

I would love to be able to have this function active via Ctrl + MouseWheel, or Ctrl + Alt etc.

Yes indeedy!

Ofer, I just tried this at home and it works wonders. I’m soon purchasing a WACOM Bamboo tablet since I work better with a stylus and this script pretty much makes the buy all that better.

The Bamboo features a touch-wheel that behaves exactly like the one found on iPod’s and sends basic mouse wheel scroll data to different applications. I’ll be able to use this script along with the touch-wheel to scrub the timeslider in MAX now thanks to this so… thank you ever so much!

Now, on to being nitpicky if I may… Would there be any way to leave this function perpetually on? I don’t mind sacrificing the mouse-wheel zoom to be able to have your script running permanently since I zoom with CTRL+ALT+MMB as of now anyway…
Basically I’m asking if there’s anyway to bind a key to set the state of your script to a permanent ON state basically. Right now it seems to turn off whenever I click somewhere.

Cheers and thanks again!

Hi,

Glad you like it.

As I said in my first post, this isn’t a perfect solution. The problem is, the dotNetControl has to have focus for it to catch the mouse wheel event. That’s why it can’t be on all the time, since when you click some place else, it losses focus and therefore stop firing the mouse wheel event.
Just thinking out loud here – one very ugly solutions could be to use a timer that will re-focus the dotNet control, but that will drive you nut. I don’t think you’ll be able to use max’s shortcut, or rename objects, because the focus from those fields we be stolen in favour of the the mouse wheel control.
I guess I’ll have to keep thinking about it.

In the mean time, here’s an updated version. I’m now using a struct s_MouseWheel, so if anyone else wants to use the mouse wheel for whatever, they just need to create an instace on the struct, register a callback fn for it (using the struct’s registerFn function), and start it.
Another thing I added is support for ctrl key. Press the ctrl key while scrolling the mouse wheel to increase/decrease the time slide jumps by 10 frames.

cheers,
o


--******************************************************************************
--*
--*  MouseWheely v1.2
--*  by Ofer Zelichover (c) 02/2008
--*  www.oferz.com   maxscript@oferz.com
--*
--******************************************************************************
--*  You may use this script freely as you see fit.							*
--*  You may use parts or the script as a whole in your own scripts.		   *
--*  (it would be nice if you give me a credit if you do so ;))				*
--******************************************************************************
--*  This script comes with no waranty!										
--*  Although I tried this script and couldn't find any problems with it, I can,
--*  in no way be held responsible for any kind of loss or damage, whether	 
--*  direct or indirect, due to the use of this script.						
--*																			
--*  ********************************************************************	  
--*   IF YOU DON'T LIKE THE ABOVE STATEMENT, DON'T USE THIS SCRIPT 	  
--*  ********************************************************************	  
--*																			
--*  If you find any bugs in this script, please let me know.				  
--******************************************************************************
--* Description																*
--* -------------															  *
--* Allows the usage of the mouse wheel to scroll the time slider
--* 
--******************************************************************************
--* Isntallation and Usage:
--* ------------------------
--*  After you run this script, the script will appear in the
--*  "Os tools" category in the customize ui menu.
--*  Assign it to a keyboard shortcut/button/RC Menu
--*  After pressing the button/keyboard key/ RC menu item, use the mouse wheel
--*  to scroll the time slider. Click anywhere to stop the opration.
--*
--***************************************************************************

--------- Struct definition
global s_MouseWheel
struct s_MouseWheel (
	message = undefined,
	func = undefined,
	valueDivider = 120,
	fn createRollout = 
	(
		rollout ro_MouseWheel "test" 
		(
			local lastTimeValue = sliderTime
			local onChangeFn
			local isActive = false
			local msg = false
			local divider = 120
			
			dotNetControl cont "System.Windows.Forms.Control"
			
			on cont MouseWheel sender event do (
				if isKindOf onChangeFn MAXScriptFunction then (
					onChangeFn (event.delta / divider)
				)
			)
			on cont lostFocus do (
				try (destroyDialog ro_MouseWheel)catch()
			)
			
			on ro_MouseWheel open do (
				isActive = true
				enableAccelerators = false
				cont.focus()
			)
			on ro_MouseWheel close do (
				if msg then
					popPrompt()
				isActive = false
				enableAccelerators = true
				updateToolbarButtons()
			)
		)
		ro_MouseWheel
	),
	roll = createRollout(),
	
	fn registerFn f =
	(
		func = f
		roll.onChangeFn = func
		if superclassOf valueDivider == Number then
			roll.divider = valueDivider
		else
			roll.divider = 120
		roll.msg = message != undefined 
	),
	
	fn unregisterFn =
	(
		registerFn undefined
	),
	
	fn start msg: =
	(
		if isKindOf func MAXScriptFunction then (
			if msg != unsupplied then
				message = msg
			try(destroyDialog roll)catch()
			createDialog roll pos:[-10000,-10000]
			registerFn func
			if message != undefined then (
				pushPrompt (message as string)
			)
			true
		) else (
			roll.isActive = false
			false
		)
	),
	
	fn isActive = 
	(
		isProperty roll #isActive and roll.isActive
	)
	
) -- end of s_MouseWheel struct


--*********************************************************
-- Start of macroScript
--************************************************************

macroScript Os_timeWheely
	category:"Os Tools"
	tooltip:"Use mouse wheel to scroll time slider"
	buttontext:"TimeWheely"
(
	global s_MouseWheel
	local mouseWheel = s_MouseWheel()
	
	fn onMouseWheelChanged val =
	(
		if keyboard.controlPressed then
			val *= 10
		sliderTime += val
	)
	
	mouseWheel.registerFn onMouseWheelChanged

	on isChecked do mouseWheel.isActive()

	on execute do (
		mouseWheel.start msg:"Scroll mouse wheel to slide the time slider"
		updateToolbarButtons()
	)
) -- end of Os_timeWheely macroscript


That’s great! I got a feeling the window focus was the issue while using it but it’s definitely worth having nonetheless. Ideally it would be set to ON all the time so you don’t have to keep entering a ‘timeslider wheel control mode’ so to speak.

I noticed this script isn’t on your site. Will you keep posting updates in this thread or can we expect to be able to follow your progress over at your site?

Again, many thanks! It’s seemingly-simple little scripts like yours that make using a 3D app all the more expressive!

Cheers!

OK, I found a serious bug in the previous version I posted. When you re-open max you get a bunch of errors. This version solves this, plus I added some more features to the strcut in case anyone want’s to use it for their own stuff.

As for the timer idea, it was a bad one. You can’t work in max once it’s on, you can pretty much only scroll the time slider, and my guess is that’s not the only reason you have max open
I need to find a way to fire a callback or event to easily fire up the script without being too obtrusive. I’ll keep thinking about it.

For now, I’ll keep posting the updates here, until I update it on my website (I’m just too lazy…)


 --******************************************************************************
 --*
 --*  MouseWheely v1.5
 --*  by Ofer Zelichover (c) 02/2008
 --*  www.oferz.com   maxscript@oferz.com
 --*
 --******************************************************************************
 --*  You may use this script freely as you see fit.							*
 --*  You may use parts or the script as a whole in your own scripts.		   *
 --*  (it would be nice if you give me a credit if you do so ;))				*
 --******************************************************************************
 --*  This script comes with no waranty!										
 --*  Although I tried this script and couldn't find any problems with it, I can,
 --*  in no way be held responsible for any kind of loss or damage, whether	 
 --*  direct or indirect, due to the use of this script.						
 --*																			
 --*  ********************************************************************	  
 --*   IF YOU DON'T LIKE THE ABOVE STATEMENT, DON'T USE THIS SCRIPT 	  
 --*  ********************************************************************	  
 --*																			
 --*  If you find any bugs in this script, please let me know.				  
 --******************************************************************************
 --* Description																*
 --* -------------															  *
 --* Allows the usage of the mouse wheel to scroll the time slider
 --* 
 --******************************************************************************
 --* Isntallation and Usage:
 --* ------------------------
 --*  After you run this script, the script will appear in the
 --*  "Os tools" category in the customize ui menu.
 --*  Assign it to a keyboard shortcut/button/RC Menu
 --*  After pressing the button/keyboard key/ RC menu item, use the mouse wheel
 --*  to scroll the time slider. Click anywhere to stop the opration.
 --*
 --***************************************************************************
 
 
 --*********************************************************
 -- Start of macroScript
 --************************************************************
 
 macroScript Os_timeWheely
 	category:"Os Tools"
 	tooltip:"Use mouse wheel to scroll time slider"
 	buttontext:"TimeWheely"
 (
 	--------- Struct definition
 	global s_MouseWheel
 	struct s_MouseWheel (
 		message = undefined, 	-- The message that will be displayed in the status bar. 
 								-- You can pass the message as a msg: parameter to the start function
 								-- instead of setting it directly.
 		onChangeFunc = undefined, 			-- The onChange callback function. DO NOT set it directly. Use registerFn instead.
 		onActivateFunc = undefined, 		-- The onActivate callback function. DO NOT set it directly. Use registerFn instead.
 		onDeactivateFunc = undefined, 		-- The onDeactivate callback function. DO NOT set it directly. Use registerFn instead.
 		persistentWindow = false, 	-- If true, the window will always open (after the first start command).
 									-- If false, the window will be closed when the control loses focus. This mode is slightly less
 									-- effective (not noticable), but is safer.
 		valueDivider = 120,		-- The scroll wheel delta will be divided by this number before being passed to the callback.
 
 		fn createRollout = 
 		(
 			rollout ro_MouseWheel "test" 
 			(
 				-- Local Variable Definitions
 				--------------------------------------
 				local onChangeFn, onActivateFn, onDeActivateFn
 				local isActive = false
 				local msg = false
 				local divider = 120
 				local persistentWin = false
 				local alt = false, ctrl = false, shift = false
 				
 
 				-- User Interface
 				--------------------------------------
 				dotNetControl cont "System.Windows.Forms.Control"
 				
 
 				-- Functions
 				--------------------------------------
 				fn init =
 				(
 					if isKindOf onActivateFn MAXScriptFunction then 
 						onActivateFn()
 					isActive = true
 					enableAccelerators = false
 					cont.focus()
 				)
 				
 				fn done =
 				(
 					if msg then (
 						popPrompt()
 						msg = false
 					)
 					isActive = false
 					enableAccelerators = true
 					if isKindOf onDeActivateFn MAXScriptFunction then 
 						onDeActivateFn()
 				)
 
 				
 				-- Event Handlers
 				----------------------------------------
 				on cont MouseWheel sender event do (
 					if isKindOf onChangeFn MAXScriptFunction then (
 						onChangeFn (event.delta / divider) alt:alt ctrl:ctrl shift:shift
 					)
 				)
 				on cont lostFocus do (
 					if not persistentWin then
 						try (destroyDialog ro_MouseWheel)catch()
 					else
 						done()
 				)
 				on cont KeyDown sender event do (
 					alt = event.Alt
 					ctrl = event.Control
 					shift = event.Shift
 					event.SuppressKeyPress = true
 					event.Handled = false
 				)
 				on cont KeyUp sender event do (
 					alt = event.Alt
 					ctrl = event.Control
 					shift = event.Shift
 					event.SuppressKeyPress = true
 					event.Handled = false
 				)
 
 				on ro_MouseWheel open do init()
 				on ro_MouseWheel close do done()
 			) -- end of ro_MouseWheel rollout
 			
 			-- Return the rollout
 			ro_MouseWheel
 		),
 		roll = createRollout(),
 		
 		fn setRollParams =
 		(
 			roll.onChangeFn = onChangeFunc
 			roll.onActivateFn = onActivateFunc
 			roll.onDeActivateFn = onDeactivateFunc
 			if superclassOf valueDivider == Number then
 				roll.divider = valueDivider
 			else
 				roll.divider = 120
 			roll.msg = message != undefined 
 			roll.persistentWin = persistentWindow
 		),
 		
 		fn registerFn onChange: onActivate: onDeactivate: =
 		(
 			local changed = false
 			if isKindOf onChange MAXScriptFunction then (
 				onChangeFunc = onChange
 				changed = true
 			)
 			if isKindOf onActivate MAXScriptFunction then (
 				onActivateFunc = onActivate
 				changed = true
 			)
 			if isKindOf onDeactivate MAXScriptFunction then (
 				onDeactivateFunc = onDeactivate
 				changed = true
 			)
 			changed
 		),
 		
 		fn unregisterFn type =
 		(
 			type = (type as string) as name
 			case type of (
 				#onChange: 		onChangeFunc = undefined
 				#onActivate: 	onActivateFunc = undefined
 				#onDeactivate: 	onDeactivateFunc = undefined
 				#all: 			(onChangeFunc = undefined; onActivateFunc = undefined; onDeactivateFunc = undefined)
 			)
 			setRollParams()
 			true
 		),
 		
 		fn start msg: =
 		(
 			if isKindOf onChangeFunc MAXScriptFunction then (
 				if msg != unsupplied then
 					message = msg
 				if not persistentWindow then
 					try(destroyDialog roll)catch()
 				if not persistentWindow or not roll.open then
 					createDialog roll pos:[-10000,-10000]
 				setRollParams()
 				if message != undefined then (
 					pushPrompt (message as string)
 				)
 				if persistentWindow then
 					roll.init()
 				true
 			) else (
 				roll.isActive = false
 				false
 			)
 		),
 		
 		fn stop =
 		(
 			if not persistentWindow then
 				try(destroyDialog roll)catch()
 			else
 				roll.focus()
 		),
 		
 		fn isActive = 
 		(
 			isProperty roll #cont and isProperty roll.cont #Focused and roll.cont.Focused
 		)
 		
 	) -- end of s_MouseWheel struct
 ------------------------------------------------------------------------------
 
 
 	
 	-- Initialize the mouseWheel struct
 	local mouseWheel = s_MouseWheel()
 	
 	fn onMouseWheelChanged val alt: ctrl: shift: =
 	(
 		if ctrl then
 			val *= 10
 		sliderTime += val
 	)
 	fn onDeAct = updateToolbarButtons()
 	
 	mouseWheel.persistentWindow = true
 	mouseWheel.registerFn onChange:onMouseWheelChanged onDeactivate:onDeAct
 	
 	
 	-- MacroScript Event Handlers
 	---------------------------------------
 	on isChecked do mouseWheel.isActive()
 
 	on execute do (
 		if mouseWheel.isActive() then (
 			mouseWheel.stop()
 		) else (
 			mouseWheel.start msg:"Scroll mouse wheel to slide the time slider"
 		)
 		updateToolbarButtons()
 	)
 ) -- end of Os_timeWheely macroscript
 
 

enjoy,
o

Fairly cool, thanks for posting (and updating)! I slowly start to look into .Net and this is yet another nice example why I should do it.

Do you think dotNet could also be used to do things ‘on key press’? For example, turn on snaps only while the S key is being pressed down and turn off snaps as soon as the S key is released?

Cheers
– MartinB

1 Reply
(@ofer_z)
Joined: 11 months ago

Posts: 0

I don’t have much experience with it either. The implementation in max is actually quite simple, the problem I find is figuring out what controls are available.

Do you think dotNet could also be used to do things ‘on key press’? For example, turn on snaps only while the S key is being pressed down and turn off snaps as soon as the S key is released?

Cheers
– MartinB

That’s where I’m stuck now with this script. The problem is how do I capture general events from input devices without having the focus on this control. So far, I didn’t find a way, that’s why you have to activate this mode (by setting the focus to the control). But having to activate it, kind of defets the purpose of what you wish to do.
If anyone has any idea how to capture global events, I’ll be happy to hear.

cheers,
o

Page 1 / 3