Best way to do delayed repeating buttons?
Got a two-part question here, experts.
Are you ready to bring home the gold in the Workaround Olympics?
(Test your skill!)
I'm making a patch to control an ancient sampler via sysex. Sadly, it doesn't like to have its parameters changed via direct parameter-specific sysex message, but rather by sysex equivalents of front-panel keystrokes. Perverse? Stupid? You bet. And as you might imagine, this makes it _really_ hard to make a slick editor. Case in point: Most editors done for this device (including mine, currently) have had no sliders for parameters, but rather just inc/dec keys for each one. Yes, it's absurd. To address this, I posted a question the other day about detecting change of direction in a stream of numbers, the idea being that I could use a slider's output to ultimately be sending bangs to either the inc or dec keys, depending on slider direction.
That whole thing works fine now.
Problem is, even with speedlim in place, it seems that the slider itself is capable of generating big and fast jumps in value in which intermediate steps are lost before they even get to speedlim. Result: The slider very quickly gets out of sync with the actual current parameter value on the device itself.
What I would like ideally is a way to constrain a slider's rate of output (like speedlim is meant to do), only internally, so that the sliders in the patch are prevented from generating more than one event every, say, 100ms.
I've tried putting speedlim at various places in the "signal flow": Right after the slider, right before the midiout object, the result is the same. I was hoping that with speedlim in place, each individual value change event being output from a slider would simply be dutifully queued and output only at a maximum of the time interval specified by speedlim. However, this doesn't seem to be the case. What is happening is that if a slider is moved any faster than "painfully slow", big blocks of intermediary values are lost, causing the out-of-sync-with-device situation.
Kind of defeats the purpose, really.
Am I doing it wrong?
Is this solvable?
If not, here's part 2 of my question, an alternate possibility:
Does anyone happen to know an easy way to do button functionality wherein, if you hold the mouse button down on a button, it'll start sending repeated bangs every x milliseconds after a delay of n? I need to do this for a whole lot of buttons independently in a patch (so that each button has this behavior but they're all completely independent, of course.) This is probably stupidly simple, but I can't work out a way to do it that doesn't involve having to build a whole mechanism involving delay, metro and tracking mousestate output specifically for each button. The point is to emulate the (quite common) behavior of a hardware device which will increment/decrement values quickly if you keep your finger on the inc/dec keys for more than about 500ms.
Sorry if this is all embarrassingly elementary. If it is, your wasted time will be refunded.
Just trying to avoid carpal tunnel syndrome over here, brought on by having to click the mouse individually for every last parameter change in this gosh-forsaken heckhole of a patch.
Thanks much.
Have you tried a [ubutton] triggering a [metro] ?
Yup, thanks - that does work, but I was ideally looking for the delayed functionality based on mousedown (assuming the slider idea I mentioned in my original post isn't possible to make work properly.) The reason for this is that if I use the simple ubutton-metro method, if I set the metro time value very short (e.g. 50ms or so), normal usage of the button will usually result in more than one actual message unintentionally being sent. So an onset delay would act as a way to distinguish between the intent to do a single click vs. a flow of repeated ones by holding down the mouse. From what I can tell, in order for that to happen, I'd have to have individual mousestate objects for every button, including a mechanism to if-then-else the whole thing by coordinate location for each one to make it specific per-button (because without the coordinates, _any_ mousedown anywhere in the patcher window would trigger every button controlled by mousestate.) That's a lot of pain, and it makes me think there's gotta be an easier way somehow. Of course, it would be a lot better to get the slider object to produce nice queued slow output as per my original post in this case, that'd work best...
How about using [mousefilter] on the slider?
Unfortunately, this method eliminates all the values between where the slider starts on mousedown and where it ends up on mouseup. And because this whole thing is based on sending bangs to inc/dec buttons rather than specific values to a parameter (maddeningly), it makes the whole thing not work.
The only way a slider would actually work in this case is for all values in its range to be transmitted, only slowly and in a queued way so that, like good little soldiers, they all go out in order and get where they're going (performing the functional equivalent of having hit the inc or dec key the same number of times as there are steps in the range of slider adjustment you just covered by moving it), only at a predetermined rate. Ugh. Anyway, thanks for trying and also for that delayed/repeated button thing - I think that is gonna be the best compromise here. I do appreciate the help - You solved my original problem!
Hey, one other minor thing - In the example patcher you attached, there's the "click here" fpic on top of the ubutton. Well, for some reason I can't duplicate this configuration using my own fpic/ubutton successfully - It's like the fpic is "functionally opaque" and prevents the ubutton from working when I have them one on top of the other while the patch is running. Must be something stupid I'm missing, but I don't see any difference in the parameters of your fpic and mine when I look at the Inspector. Any ideas? So many details to sort out...Thanks :)