[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!
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
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