# Question about modifying a Slider2D control

Background: I want to develop a custom control, based on a 2D slider. I currently have this ( working ) example.

  Manipulate[
If[(iOld != i || jOld != j),
lata[[1]] = i; lata[[2]] = j];
i = lata[[1]];
j = lata[[2]];
iOld = i;
jOld = j;
lata,
Row[{
Column[{
Control[{{i, i, "i"}, -5, 5, 0.25}],
Control[{{j, j, "j"}, -5, 5, 0.25}]}]
,
Control[{{lata, lata, "lata"}, {-5, -5}, {5, 5}, {0.25, 0.25}}]
}],
Initialization -> {
lata = {1, 0},
i = lata[[1]],
j = lata[[2]],
jOld = j,
iOld = i
}]


This control is a 2D Slider and two normal sliders in sync. Clearly the two sliders are not necessary but I like the built-in functionality of the slider's drop down precision- entry ( and auto play ).

Question: Is there an easy way to build a 2D Slider with the drop down precision provided for a normal slider, thus in x and y direction? Or do I have to build it from scratch? ( Update: Basically remove the two sliders =itself= but remain all other functionality in the example. )

-
@IstvánZachar There are two answers now :) – belisarius has settled May 7 '12 at 14:56

Something like the following?

 Manipulate[If[(iOld != i || jOld != j), lata[[1]] = i; lata[[2]] = j];
i = lata[[1]];
j = lata[[2]];
iOld = i;
jOld = j;
lata,
Column[{Row[{Opener[Dynamic[zz]], " lata"}],
PaneSelector[{True ->
Row[{Column[{Row[
{Control[{{i, 0, ""}, {-5, -5}, {5, 5}, {0.25, 0.25}, Animator[#, {-5, 5, 0.25},
AnimationRunning -> False, AnimationRate -> 4/5, Appearance -> Small,
AppearanceElements -> {"ResetButton","PlayPauseButton", "StepLeftButton",
"StepRightButton", "FasterSlowerButtons", "DirectionButton"}] &}],
Spacer[5],
Control[{{i, 0, ""}, {-5, -5}, {5, 5}, {0.25, 0.25},
InputField[#, FieldSize -> {4, 1}] &}]}] ,
Row[{Control[{{j, 0, ""}, {-5, -5}, {5, 5}, {0.25, 0.25},
Animator[#, {-5, 5, 0.25}, AnimationRunning -> False,
AnimationRate -> 4/5, Appearance -> Small,
AppearanceElements -> {"ResetButton","PlayPauseButton", "StepLeftButton",
"StepRightButton", "FasterSlowerButtons","DirectionButton"}] &}],
Spacer[5],
Control[{{j, 0, ""}, {-5, -5}, {5, 5}, {0.25, 0.25},
InputField[#, FieldSize -> {4, 1}] &}]}]}], Spacer[15],
Control[{{lata, lata, ""}, {-5, -5}, {5, 5}, {0.25, 0.25}}]}],
False ->
Control[{{lata, lata, ""}, {-5, -5}, {5, 5}, {0.25, 0.25}}]},
Dynamic[zz]]}],
Initialization -> {lata = {0, 0}, i = lata[[1]], j = lata[[2]], jOld = j, iOld = i}]


screenshots:

-
EXCELLENT. Code is somewhat verbose but that is to be expected of such a cool solution. Thank you very much. - Make sure this control is included in the forthcoming custom control collection or whatever. – ndroock1 May 7 '12 at 15:38
@ndroock1, thank you for the accept; perhaps you should have waited a while for a more complete answer. Both the code and the appearance/functionality can be made much cooler... and Slider2D does need quite a few enhancements. – kglr May 7 '12 at 15:50
@kguler and @ndroock1 nice design, but if you will share this with someone you should be careful. They can access option "Autorun" from the little cross in the top right corner which will fail in this case. It happens when dynamic things become too complex. Two choices here: you can fix the problem adjusting the code or simply set AppearanceElements -> None as an option for Manipulate to remove little cross (if you are satisfied with current code). – Vitaliy Kaurov May 7 '12 at 16:54
@Vitaliy, you are right; I was struggling with the Autorun behavior and the only "solution" (short of suppressing all that comes with the top-right cross button) that i could find was to set the AutorunSequencing so that all controls except the Slider2D are inactive under Autorun. – kglr May 7 '12 at 17:27

Perhaps something like this (the interface display needs some polishing):

appEl = {"StepRightButton", "PlayPauseButton", "FasterSlowerButtons"}
Manipulate[If[(iOld != i || jOld != j), lata[[1]] = i; lata[[2]] = j];
i = lata[[1]];
j = lata[[2]];
iOld = i;
jOld = j;
Row[{
Column[{
{Animator[Dynamic[i], {-5, 5, .25}, AnimationRunning -> False,
AppearanceElements -> appEl], InputField[ Dynamic[i]]},
{Animator[Dynamic[j], {-5, 5, .25}, AnimationRunning -> False,
AppearanceElements -> appEl], InputField[ Dynamic[j]]}
}],
Control[{{lata, lata, "lata"}, {-5, -5}, {5, 5}, {0.25, 0.25}}]
}],
Initialization -> {lata = {1, 0}, i = lata[[1]], j = lata[[2]], jOld = j, iOld = i},
AppearanceElements -> All]


-
just got the "new answer posted" notice with a 40 minutes delay just before I posted an answer also based on animator:) – kglr May 7 '12 at 14:16
@kguler I think you could undelete your answer. Your interface is nicer than mine – belisarius has settled May 7 '12 at 14:20
i should work on it a little more; perhaps to align the animator controls around the sides of Slider2D. – kglr May 7 '12 at 14:26
Yes, and isn't this how the Slider2D should have been by default in Mma? Anyway, as you said a tiny bit of customization is still required. - Is there a particular reason why you left the minus button out of this version? – ndroock1 May 7 '12 at 14:49
@ndroock1 I only focused on the barebone requirements, and did not worked out the presentation details. – belisarius has settled May 7 '12 at 14:53

This is basically the same concept as belisarius's and kguler's answers but I've put the definition of the controller in a function to make things a bit more portable.

Options[contr] = {"Trigger" -> {}, "InputField" -> {}, "Slider2D" -> {}};
SetAttributes[contr, HoldAll];

contr[Dynamic[a_], range_, opt : OptionsPattern[contr]] :=
Dynamic[
Labeled[
Slider2D[Dynamic[a], range, OptionValue["Slider2D"]],
OpenerView[{"",
Grid[Join[{{"\[LeftRightArrow]"}, {"\[UpDownArrow]"}},
{InputField[#, Number, OptionValue["InputField"], FieldSize -> {6, 1}],
Trigger[#, range[[All, 1]],
OptionValue["Trigger"],
AppearanceElements -> {"StepLeftButton", "StepRightButton",
"PlayPauseButton", "FasterSlowerButtons"}]} & /@
{Dynamic[a[[1]]], Dynamic[a[[2]]]}, 2]]}],
{{Right, Top}}]]


Example

Manipulate[a,
{{a, {1, 0}, "Lata"}, (contr[Dynamic[a], {{-5, -5}, {5, 5}, {.25, .25}}] &)}]


I'm using a Slider2D, two InputFields and two Triggers to create the control. You can set the options of these elements by setting the options "Slider2D" -> opt, "InputField" -> opt and/or "Trigger" -> opt. For example, to set the width of the input fields to 10 and the animation rate of the trigger to 3 you could do

Manipulate[a,
{{a, {1, 0},
"Lata"}, (contr[Dynamic[a], {{-5, -5}, {5, 5}, {.25, .25}},
"InputField" -> {FieldSize -> 10},
"Trigger" -> {AnimationRate -> 3}] &)}]

-