Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Background: The following snippet is what I (intend to) use in a Manipulate form where up to 12 different colors can be selected:

 Manipulate[{sliderCol1},
  Row[{"Kleur 1: ", ColorSlider[
     Dynamic[sliderCol1] ,
     AppearanceElements -> {"SwatchSpectrum"},
     ImageSize -> {200, 40},
     BaselinePosition -> Scaled[.25]]}
   ]
 ]

To make this work with fields sliderCol1 to sliderColn (where $n$ = 2, …, 12), I see no other option than copying the code in Row so many times.

Question: Is there a less verbose way of implenting a multiple (here 12) color selector using color sliders?

share|improve this question
    
Note you can create a swatch as simply as Manipulate[x, {x, Red}], or maybe Manipulate[x, {{x, Red, "Kleur 1"}, Red}]. –  Szabolcs Apr 9 '12 at 9:47
    
That gets me going a while. Thanks - ( I got the snippet from a Wolfram Demonstrations file!, anyway I 'll bang my head against the wall a few times. ) –  ndroock1 Apr 9 '12 at 9:54
    
I realize it does not answer your question---which is why I kept it as a comment. In general, it would be interesting to know how to implement custom controls which can be used in the standard way, i.e. control[Dynamic[var]] would set var. var in this case could be a list of colours. I feel rusty though so maybe this is just not the right approach ... –  Szabolcs Apr 9 '12 at 9:59
    
I feel a similar question was asked already, but can't find it. Maybe it's on SO. Maybe someone remembers. –  Vitaliy Kaurov Apr 9 '12 at 10:17
add comment

3 Answers

up vote 12 down vote accepted

With this one you just click the circle to be color-edited. No need to pick an index number first.

DynamicModule[{x = 1},
 Manipulate[c[[x]] = color;
  Grid[
   Table[
    Setter[Dynamic[x, (color = c[[#1]]; x = #1) &], i*4 + j, 
     Graphics[{FaceForm[c[[i*4 + j]]], Disk[]}, ImageSize -> 40]
     ], {i, 0, 2}, {j, 4}
    ]
   ], {color, Red},
  Initialization :> {c = ConstantArray[Black, 12]}]
 ]

Mathematica graphics

Note that I used Dynamic's alternative syntax form, where you determine what should happen if the argument needs to be updated. In this case I use it to set the starting color of the color selector to be the current color of the circle being clicked. Otherwise the color of the circle would be set by the current setting of the color setter. This may be or may not be how you want the control to behave. Just change it to Dynamic[x] if you want to have the other behavior.

share|improve this answer
    
That's the one I will use, thank you. –  ndroock1 Apr 9 '12 at 10:53
    
Neat idea :) +1 –  Vitaliy Kaurov Apr 9 '12 at 18:14
    
To avoid having global variables in Manipulate you could add x and c to the list of controls with ControlType -> None. –  Heike Apr 10 '12 at 10:52
    
@Heike that, or use a DynamicModule. Will update tonight. –  Sjoerd C. de Vries Apr 10 '12 at 12:21
add comment

If to have multiple controls is not essential, to avoid interface overcrowding, one could try another approach. You do not need 12 controls to control 12 different things. You could just have 2 inter-connected controls: the color and the indexer telling the color which thing to change. Here is an example:

Manipulate[c[k] = color;
 GraphicsGrid@Partition[Graphics /@Table[{c[a], Disk[], 
 Text[Style[ToString[a], Blue, 30]]}, {a, 12}], 4],
 Button["Random Reset", Table[c[a] = Hue[RandomReal[1, 3]], {a, 12}]],
 Button["Black Reset", Table[c[a] = Black , {a, 12}]],
 {color, Red}, {{k, 1, "index"}, Range[12], Setter}, 
 Initialization :> {Table[c[a] = Hue[RandomReal[1, 3]], {a, 12}]}]

enter image description here

Notice c[k] are global variables here - localize if leaks can cause problems.

share|improve this answer
    
Very neat indeed, if the index numbers were placed in a grid to match the physical layout of the colour disks, that would be even sweeter. –  image_doctor Apr 9 '12 at 10:25
    
@image_doctor thank you, done. –  Vitaliy Kaurov Apr 9 '12 at 10:35
add comment

This is one way to do this

With[{n = 12},
 With[{names = ToExpression[Array["sl" <> ToString[#] &, n]]},
  Manipulate[
   GraphicsGrid[Partition[Graphics[{{#, Disk[]}}] & /@ names, 4], 
    Spacings -> {0, 0}],

   Evaluate[Sequence @@
     MapIndexed[
      {{#, Hue[#2[[1]]/n], Row[{"Kleur ", #2[[1]]}]}, 
        ColorSlider[#, AppearanceElements -> {"SwatchSpectrum"},
          ImageSize -> {200, 40}, 
          BaselinePosition -> Scaled[.25]] &} &, names]
    ]]]]

Here, names contains a list of variables {sl1,...,sl12}. This list is used to construct a sequence of controls. Since Manipulate has attribute HoldAll, we need Evaluate to construct the controls before they're used in Manipulate.

Mathematica graphics

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.