Sunday, December 21, 2008

Extended DKnob (a round JSlider)

What is the problem with the ubiquitous slider control? It is limited by its length! The step is as small as one pixel -- you just cannot scroll less than one pixel by mouse on the screen. For instance, you have a 100 thousand-frame video (one hour is almost 100.000 frames). Even provided a very long, one thousand pixel slider over the whole screen, it is not just uncomfortable to move the mouse pixel-by-pixel to reach specific frame, it is just impossible! I have seen that professional video analytics wind the cassettes by round knobs. The speed of playback (forward and backward) is smoothly regulated by the knobs. Let's leave aside the fact that modern video editors use sliders for rough positioning and get the corresponding frames in a special view area. I use this just as example. Perhaps, my example is bad and the knobs are really outdated. Anyway, I have compared these two methods of winding in, say, year 2004 and came to an awesome discovery: the knobs do not have the limits - once a full turn is made, you are free to go further and make another round! They are infinite-size sliders! Why are they not used in SW?

After some research, actually the very first google match, points us to DKnob. This is Java-implemented control demo. I have reworked it a little removing the weird behaviour that it sometimes spins wrong, counter-intuitive, ways. I also translated the drawing on transforms. Yet, what is great about the demo is that it hints to us that there is more that one winding strategy possible. First, in the simple strategy, you press a mouse button and slide along x-axis, rotating the wheel a proportional distance. Secondly, we can capture the knob at one point so that the center-point line will follow the mouse pointer on the screen. This is round strategy. Finally, I have invented an extra exponential strategy considering that the first two suffer from the granularity problem. This mine allows navigating extremely large spaces with super high precision.

In the first strategy, the step size is fixed: say, one mm of mouse dragging advances the position by one angular second (one frame). In other words, dragging the mouse at some speed we wind a video at some FPS. As I told, the linear slider drops the precision (more frames per mouse unit shift) when it controls a larger range. Breaking the slider size limit, the knob enables preserving the precision. But this comes with a penalty and creates the precision-vs-speed dilemma: the longer is a video the longer is its rewinding at fixed fps. Consider if you rewind a 4-sec clip at 1 round per second or a 2-hour video. The second strategy allows the user to adjust the winding speed over the precision dynamically: the further the mouse pointer from the knob center the finer is angle advance. Of course, you can always have multiple sliders: a rough one for the rough positioning and another for fine position adjustment. Just like modern video editors do. Tackling this (far-fetched) issue of multiple scales, I have invented some universal control. It covers all scales in one touch!

Explained the theoretic need for dynamic scale change, I must to say that the second, round, strategy indeed allows the user to control values smoothly in range from ones to thousands. The limits are imposed by the human inability to spin the knob too fast by stimulating its center, and hence, how far we go at low rate; on the other hand, the screen size limits the mouse distance from knob center, hence, the precision. In fact, the policy exploits the hyperbolic scale change, .i.e. 1/r, which differential has no effect on high distances r. Normally, the exponential scale change is done to control the high dynamic ranges switching from micro to milli to kilo to macro. This is what my strategy does: the horizontal mouse dragging changes the value by fixed portions likewise the simple strategy while the unit of change is determined by y-distance. Moving the mouse pointer vertically from the knob center exponentially increases the unit. This exactly corresponds to the computer floating-point model with its mantissa-x and exponent-y. So, playing with my control, you explore the floating point type space. So, I admit that my component is useful not more than the reals are. :)

Here is the jar, which includes the sources

No comments: