7
$\begingroup$

A single RGBColor expression displays as a little square, showing the color. I just found that this little square is both a tooltip and a button. It seems to be new in version 10. When I click on it, I get a user interface showing three sliders for changing red, green and blue and a slider for the opacity. This gives a very nice way of changing the displayed color, in my opinion much simpler and more flexible than ColorSlider and ColorSetter.

I can use this interface in a very primitive way. Type

InputForm[RGBColor[0,0,0]]

Do not evaluate, but evaluate the argument RGBColor[0,0,0] in place so that a black square appears. Click on this button, construct the color and press shift-enter.

Is a better way to use this interface, similar to ColorSlider or ColorSetter?


Personally, I prefer the just discovered interface highly over those of ColorSlider and ColorSetter. The latter two, however, allow a dynamic argument, and that is what I am looking for with the new interface.

$\endgroup$
4
  • $\begingroup$ &Kuba I would like to have a function myColorSetter, that uses the RGBColor interface, or adapt the existing ColorSlider and ColorSetter such that they use this interface. I can do something with EventHandlers and so, but my feeling is that it could be done simpler. $\endgroup$ Commented Jul 15, 2015 at 16:00
  • 1
    $\begingroup$ Also not entirely sure what the question is (or what the definition of 'better' would be here other than personal preference). But note that there is an additional user interface, not yet mentioned, which under the code completion when you start typing RG or RGB: There is a popup which lets you 'choose color...' with a slider interface similar to what you get when you click a formatted color. $\endgroup$ Commented Jul 15, 2015 at 18:02
  • 1
    $\begingroup$ @Arnoud. That is good information: typing RG and then use the interface from the code completion (the same as when I click on the RGBColor button) for choosing a color is certainly 'better' than the way I did it in my question. Of course it is personal preference which color interface we like best for picking a color. Personally, I prefer the just discovered interface highly over those of ColorSlider and ColorSetter. The latter two, however, allow a dynamic argument, and that is what I am looking for with the new interface. Is there a kernel command for calling this interface? $\endgroup$ Commented Jul 15, 2015 at 18:22
  • 2
    $\begingroup$ There is no kernel interface for it. This is a snippet of code that I extracted from the 'color button' which shows the frontend resource that comes up as an attached cell: FrontEndResource["RGBColorValueSelector"] // CellPrint $\endgroup$ Commented Jul 15, 2015 at 18:44

2 Answers 2

6
$\begingroup$

Ok, I read it again and again and I think I know what you are after.

Here's quick fix/adjustment to make this thing a valid controller:

SetAttributes[customColorSetter, HoldFirst]

customColorSetter[var_] := (
  If[! MatchQ[var, _RGBColor], var = Black];
  Delete[
     FrontEndResource["RGBColorValueSelector"][[1, 1]],
     {{1, 1}}
  ]  /. $CellContext`colorVal$$ :> var // RawBoxes
  )

Basically I'm stripping a Cell head and deleting inner DynamicModule's first variable spec $CellContext`colorVal$$ and replacing everywhere else this variable with our.

At the end you may want to add some procedures to drop OK and Cancel buttons but it is already quite nice.

It is based on undocumented code so I won't bet much on it's behaviour in the future:

ClearAll @ myColor

Panel[
 Column[{
   customColorSetter[myColor],
   "", 
   "value of global variable:",
   Dynamic @ myColor
   }, 
   BaseStyle -> 18]
 ]

enter image description here

$\endgroup$
1
  • $\begingroup$ &Kuba. This looks very promising, many thanks. I have to study this very carefully, maybe until over our holidays. $\endgroup$ Commented Jul 16, 2015 at 9:14
3
$\begingroup$

As Arnoud Buzing has mentioned, when manually entering an RGBColor, in the code completion we find a user interface for finding the color components. This user interface is the same as that turns up when we click on a displayed RGBColor expression.

I was wondering if this new interface could be used with Dynamic as well. Kuba showed that when we replace one of the variables in the boxes of the interface by a kernel variable, this indeed can be done. But it turns out that not everything works. The opacity is not assigned to this kernel variable, and the effect of pressing the keys of the interface is rather disastrous, Kuba already suggested to do something with these buttons.

Here is a solution that simply removes the code for the opacity and the two buttons, and then uses Kuba's replacement.

Module[{zzz, pos},
  zzz=FrontEndResource["RGBColorValueSelector"][[1,1]] ; 
  pos=Position[zzz, "Advanced"];
  zzz= Delete[zzz , Take[#,16]& /@ pos];
  pos=Position[zzz, "Opacity"];
  zzz= Delete[zzz , Take[#,16]& /@ pos];
  pos=Position[zzz, ButtonBox];
  zzz= Delete[zzz , Take[#,14]& /@ pos];
  With[{boxes=zzz},
    colorSliders[ Dynamic[var_]] := 
    RawBoxes[Delete[boxes,{{1,1}}]/.{$CellContext`colorVal$$:>var}]
  ]
]

The resulting function colorSliders is not quite as good as it should be. It can be used only with a Dynamic argument, and it always starts with RGBColor[0.5,0.5,0.5]. Of course, that can be improved as well, but that would amount to writing a new interface and not simply adapting the existing one. Anyway, it works fine:

Row[{colorSliders[Dynamic[x]], Spacer[50], Graphics[{Dynamic[x], Disk[]}, PlotRange->1], Spacer[50], ColorSlider[Dynamic[x], ImageSize->{200,80}]}]

enter image description here

I think that WRI did a nice job with this new interface. The effect of moving any of the sliders can be seen in the background color of each of the sliders. Of course, it is a matter of taste, but I prefer the new interface above the existing ColorSlider.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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