/*
In Maya GUI: Add Attribute "wheel" to object "Cat". Although the variable does nothing,
we'll use it to calculate which direction around a wheel that we'd like to move.
The variable "wheel" will be used to calculate "translate X" and "translate Y".
 
 
"Cat" stands for "Catcher". It runs after the "Target" in a game.
Or you could just think of it as a "cat" that chases after a "mouse" ...
or after several "mice".
*/
 
 
// The value given to "$maxrad" tells what the maximum number to steps to move
// the catcher in one slider click.
global float $wheel0 = 0., $maxrad = 8.;
global float $xar[], $yar[];
global int $level = 0;
 
 
 
 
catWindow();
 
 
global proc catWindow() {
 
/* Delete the window if it already exists. */
if ((`window -ex catWindow`) == true ) deleteUI catWindow;
/* Create a window. "-rtf" fits the window to controls. */
window -rtf true -title "Cat Control" catWindow;
/* Allow window to be resized with scroll bars. */
scrollLayout -horizontalScrollBarThickness 16 -verticalScrollBarThickness 16;
/* This layout requires either #columns or #rows. "-cw" is the column width (col# width).
"-cs" is column spacing (col# spacing). */
rowColumnLayout -numberOfColumns 3 -cw 1 375 -cw 2 35 -cs 2 5 -cw 3 35 -cs 3 5;
 
 
/* A call to each one of these routines sets up one row of sliders and buttons. */
setSlider( "Cat Spin", "Cat.wheel", -180, 180 );
 
 
/* Now display the window. */
showWindow catWindow;
 
 
}
 
 
global proc setSlider( string $name, string $attr, int $min, int $max ) {
/*
This routine sets up one row of sliders and buttons.
The string "$attr" contains "object.attribute".
Notice the addition of "-cc" to force a procedure call when the slider
is moved or when the slider button is pressed.
*/
 
 
attrFieldSliderGrp -min $min -max $max -label $name -at $attr -cc "spinWheel";
 
 
/* Each button command defines a button and tells it which procedure
to call when pressed. */
 
 
button -label "Reset" -al "center" -c "resetCat";
button -label "Back" -al "center" -c "backCat";
 
}
 
 
 
 
 
 
 
 
global proc spinWheel() {
/*
When you move the slider you actually spin the wheel. The entire slider length
covers 360 degrees. When you move the slider or just click on the slider button,
you move the catcher a certain amount. You only move it one unit when you
move the slider, but you move in more and more when you click on the slider button
without sliding it. When you just click and don't slide you move it 1, 2, 4, 8 spaces
on successive clicks.
*/
 
 
// These global variables are defined everywhere they are used.
// They get their initial settings at the top of the program.
global float $wheel0, $maxrad;
global float $xar[], $yar[];
global int $level;
 
 
float $rad, $wheel, $x, $y, $x0, $y0;
int $i;
 
 
// Get the value of the slider.
$wheel = `getAttr Cat.wheel`;
 
 
// Check it against the value it had the last time it was moved.
if ($wheel == $wheel0) {
        /* Didn't move slider at all. Just clicked. Therefore, increase radius level. */
        $level++;
 
 
        // Calculate the radius and cap it off at $maxrad.
        for( $rad = 1., $i = 1; $rad <= $maxrad && $i < $level; $i++)
                $rad *= 2.;
}
else {
        /* Slider moved. So, calculate new angle.
        Reset the radius to its smallest value. */
        $rad = 1.; $level = 0;
        $wheel0 = $wheel; // slider value changed, so save it as the new old value.
}
 
 
// Get the current catcher position.
$x0 = `getAttr Cat.tx`;
$y0 = `getAttr Cat.ty`;
 
 
// Calculate its new position and save it in the arrays.
$xar[$level] = $x = $x0 + ($rad * cos (deg_to_rad( $wheel )));
$yar[$level] = $y = $y0 + ($rad * sin (deg_to_rad( $wheel )));
 
 
// Move the catcher to its new position.
setAttr Cat.tx $x;
setAttr Cat.ty $y;
}
 
 
 
 
 
 
global proc resetCat() {
/*
Move the catcher to the center of the world and reset all variables.
Don't initialize the slider wheel position, however.
*/
global float $wheel0, $maxrad;
global float $xar[], $yar[];
global int $level;
 
$level = 0;
$xar[0] = $yar[0] = 0.;
setAttr Cat.tx 0;
setAttr Cat.ty 0;
}
 
 
 
 
 
 
global proc backCat() {
/*
Everytime this button is clicked, it moves the catcher back one step.
It uses the saved array positions to do it. It's like an "undo".
Notice that we have to stop when there are no more saved values.
In other words, we can't go back before the first array position ($level == 0).
*/
global float $xar[], $yar[];
global int $level;
 
$level--;
if ($level >= 0) {
        $x = $xar[$level];
        $y = $yar[$level];
        setAttr Cat.tx $x;
        setAttr Cat.ty $y;
}
else $level = 0;
}