I intend to write a small program that can be exported to CDF and consist of two main parts:

A. The construction of a layered structure consisting of different materials.

B. Superimposing calculation results (plots) on top of this construction.

One of the main points would include being able to drag and modify materials thicknesses and their position, while getting instant feedback how this affects the plot.

As shown in the following simplified code, it would be handy to be able to:

  1. Select any number of materials (layers) from a list.
  2. Be able to change their thickness, preferably by dragging the borders (not sliders).
  3. Move layers by dragging and dropping.
  4. Edit the material properties by double clicking.
  5. Adding your own materials.
  6. Save your own materials, preferably to the CDF-file itself.

     RectangleChart[{{T, 100}, {L, 100}, {M, 100}, {K, 100}, {P, 100}, {B,
         100}}, BarSpacing -> None, 
      ChartStyle -> {Brown, Gray, Yellow, LightGray, LightBrown, 
        LightRed}], {T, 25, 40, 
      Grid[{{Slider[##, Appearance -> Tiny], 
          InputField[#, FieldSize -> Tiny]}}] &}, {L, 50, 240, 
      Grid[{{Slider[##, Appearance -> Tiny], 
          InputField[#, FieldSize -> Tiny]}}] &}, {M, 50, 300, 
      Grid[{{Slider[##, Appearance -> Tiny], 
          InputField[#, FieldSize -> Tiny]}}] &}, {K, 25, 40, 
      Grid[{{Slider[##, Appearance -> Tiny], 
          InputField[#, FieldSize -> Tiny]}}] &}, {P, 35, 240, 
      Grid[{{Slider[##, Appearance -> Tiny], 
          InputField[#, FieldSize -> Tiny]}}] &}, {B, 20, 300, 
      Grid[{{Slider[##, Appearance -> Tiny], 
          InputField[#, FieldSize -> Tiny]}}] &}]

enter image description here

The question:

While I manage A and B very crudely, I have no idea how to begin with my wishlist 1-5. Does anyone have a suggestion as how to get started?

Of course I'm not looking for free coding here, but rather hints on whether this is possible and where there are good examples of the above 1-5.

I have gone through many demos without finding an answer to the above.

I also understand that the Enterprise Edition would probably solve the problems, but this is not possible for a hobbyist like me.


1 Answer 1


The following is only a sketch of what you would have to look into (Don't accept that answer too soon, I'm sure others might provide more detailed solutions):

  1. For variable numbers of rows you will need to nest two Manipulates, or two Dynamic expressions. For a relatively complex gui as you plan, I think it will pay off to learn to handle the lower level Dynamic and DynamicModule instead of just using Manipulate.
  2. To interact with the graphics components I think you will most probably end up to make use of EventHandler (and the MouseDown, MouseDragged and MouseMoved events) and MousePosition. There are some examples in the documentation for EventHandler which can serve as a starting point.
  3. similar to 2.
  4. similar to 2. and 3., along with CurrentValue["MouseClickCounts"]
  5. the main problem here seems to be 6., if you solve that 5. is just a button to append to the stored list of materials
  6. "save" is something you might want to explain in more detail. It is relatively simple to store a list of materials and their properties in e.g. a DynamicModule variable. DynamicModule-variables will be stored in the CDF document when that is saved and restored when opening that document in a new session, which probably is good enough for what you plan (?). Saving to an extra file or database will not be possible with the free CDF Player, but only for users of Mathematica or PlayerPro.

To answer your other questions: I think it is possible but not trivial to achieve everything you want. The Enterpize version would only help to create a CDF which would let users save material (or other) data to files or databases. If the basic functionality to store such data within a DynamicModule variable is good enough, any version of Mathematica which lets you store an interactive output as a CDF document will work fine.

I just found some old code where I was experimenting with these features. It isn't exactly solving your problem but might be a good starting point so I thought I'd share it:

    selected = None,
    rectangles = {{Red, {0, 0}, {1, 1}}},
    editor = "", numrows
  numrows = Length[rectangles];
    Button["Add Rectangle",
      AppendTo[rectangles, {Gray, {0, 0}, {1, 1}}];
      numrows = Length[rectangles]
          With[{idx = idx},
              Dynamic[rectangles[[idx, 1]]],
                  Rectangle[rectangles[[idx, 2]], rectangles[[idx, 3]]]], {
                    "MouseDown" :> If[CurrentValue["MouseClickCount"] == 1,
                        selected = idx,
                        editor = Panel[Grid[{
                          {"Rectangle", idx,
                                If[Length[rectangles] > 1,
                                  editor = "";
                                  rectangles = Delete[rectangles, idx];
                                  numrows = Length[rectangles]
                          {ColorSlider[Dynamic[rectangles[[idx, 1]]]], 
                         }, Spacings -> 0
        {idx, numrows}
      ], TrackedSymbols :> {numrows}]
  }, PlotRange -> {{-10, 10}, {-10, 10}}, Frame -> True, ImageSize -> 500
 ], {
    "MouseUp" :> (selected = None),
    "MouseDragged" :> If[IntegerQ[selected],
       rectangles[[selected, 2]] = {-0.5, -0.5} + MousePosition["Graphics"];
       rectangles[[selected, 3]] = {0.5, 0.5} + MousePosition["Graphics"];

Two things which make this work are probably not obvious:

  1. using an extra EventHandler for every rectangle to set the variable selected makes it possible to provide the drag and drop behavior "per rectangle".
  2. using an extra variable for numrows and triggering the complete update of all rectangles only when that changes makes the gui somewhat more reactive.

Everything else I think should become clear when reading the documentation of the functions used and hopfully is straightforward enough to be adopted to your needs...

  • $\begingroup$ Thanks Albert, I added an explanation of what I meant by saving. $\endgroup$
    – MathLind
    Commented Nov 24, 2014 at 15:39
  • $\begingroup$ @MathLind: I've seen your edit, I think that storing in a DynamiModule variables should provide what you are looking for, there is no need for a Enterprize version for that... $\endgroup$ Commented Nov 24, 2014 at 16:21
  • $\begingroup$ This is a great start for me Albert. I appreciate your help. I'm catching a flight in some hours and will be able to study your example in the coming days. $\endgroup$
    – MathLind
    Commented Nov 24, 2014 at 18:22

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.