4
$\begingroup$

I'd like to generate a code that:

1) starts with a grid of circles (in general, it won't be a square grid) 2) allows the user to choose some of those circles 3) allows the user to choose the type of this circle (let's say, giving them different colors) 4) export the {x,y,type} for those circles.

I truly don't even know where to start. Is this worth doing with mathematica? If so, which functions am I looking for?

image generated by selecting spheres in a grid

$\endgroup$
3
  • $\begingroup$ How many types need to be selected? If it is only two or perhaps three a modifier key or repeated clicking might be applicable. More and you likely need some kind of menu. $\endgroup$
    – Mr.Wizard
    Jan 23, 2015 at 0:48
  • 1
    $\begingroup$ probably 1-5 types. I think ideally I would 1st press a number, then click and that would assign this number-type to it. $\endgroup$
    – PFD
    Jan 23, 2015 at 0:55
  • $\begingroup$ Okay. I posted a very basic example below with only one "type." Please review it and then specify how you would like your actual method to differ. $\endgroup$
    – Mr.Wizard
    Jan 23, 2015 at 0:59

2 Answers 2

8
$\begingroup$

If you want full flexibility you should try EventHandler and graphics primitives. If you can decipher the following example you will get the idea:

color = Black;
positions = Position[DiskMatrix[5], 1];
disks = {color, Disk[#, 0.4]} & /@ positions;

eventHandler[item : {c_, obj_: Disk[p_, _]}] := {c, EventHandler[obj,
   "MouseClicked" :> (disks = (disks /. item :> {color, obj}))
   ]}
mouseAppearance[obj_] := MouseAppearance[obj, "LinkHand"]

Deploy@Column[{
   Dynamic@Graphics[mouseAppearance@*eventHandler /@ disks, ImageSize -> 300],
   RadioButtonBar[Dynamic[color], {Black, Red, Green, Blue, Yellow}]
   }, Alignment -> Center]

Example

In order to export your data you may define a function such as

types = {Black -> 0, Red -> 1, Green -> 2, Blue -> 3, Yellow -> 4};
export := disks /. {c_, Disk[pos_, _]} :> {c /. types, pos}

You mentioned that you might prefer keyboard shortcuts for the different colors. To achieve that I would start by trying to use NotebookEventActions as in Make EventHandler work for clicks and keys in a Dynamic display.

$\endgroup$
3
  • $\begingroup$ I was planning in putting something like this together for "Step 3" today but I see I don't need to. +1 $\endgroup$
    – Mr.Wizard
    Jan 23, 2015 at 17:22
  • $\begingroup$ Combining this answer with @Mr.Wizard 'hex' and I have both cases I needed. EventHandler, Defer & Deploy were 3 new functions I had to learn. +2 $\endgroup$
    – PFD
    Jan 23, 2015 at 17:38
  • $\begingroup$ @PFD I'm glad we could be of help. Let us know if you have any problem with the final implementation. $\endgroup$
    – Mr.Wizard
    Jan 23, 2015 at 17:47
5
$\begingroup$

Step 1

As a very quick example of how one might start, with the limitation of only one "type" available:

convert[Grid[m_?MatrixQ, ___]] := m[[All, All, 1]]

Defer[convert]@Grid[ConstantArray[RadioButton[], {4, 7}], Spacings -> {0.2, 0}]

Which outputs:

enter image description here

You then make a selection:

enter image description here

And evaluate it (the output), yielding:

{{False, False, False, True, False, False, False},
 {False, False, False, False, True, True, True},
 {False, False, True, False, False, False, False},
 {False, False, False, False, False, False, False}}

This could easily be converted to your {x,y,type} format with something like:

MapIndexed[Append[#2, #] &, %, {2}]

Step 2

Still not addressing the need for multiple types but now with non-rectangular packing, easily generalized to arbitrary placement:

hex = Join @@ Array[{#2 + #, (#2 - #)/Sqrt[3]} &, {5, 5}, -2];

convert2[g_Graphics] := 
 Cases[g, Inset[RadioButton[value_, True], pos_] :> {value, pos}, -3]

Graphics[{
 Inset[RadioButton[], #] & /@ hex
}, ImageSize -> 150] // Defer[convert2]

enter image description here

And when evaluated:

{{False, {-4, 0}}, {True, {-3, 1/Sqrt[3]}}, . . .,
 {False, {3, -(1/Sqrt[3])}}, {False, {4, 0}}}
$\endgroup$
5
  • $\begingroup$ Besides the choice of types, how should I go about making a hexagonal - other than a square - grid of buttons? Other than that, your solution pretty much covers it. Tx. $\endgroup$
    – PFD
    Jan 23, 2015 at 4:40
  • $\begingroup$ @PFD Sorry, when you said "won't be a square grid" I thought you meant it would be a rectangular grid. Can the elements lie on a rectangular grid (but some be missing around the periphery) or do the individual cells need a different "packing" such as hexagonal? $\endgroup$
    – Mr.Wizard
    Jan 23, 2015 at 4:48
  • $\begingroup$ A meant a different packing, but 99.9% of the case it will be either square or hexagonal. I think I can work with a generalized case if I can understand how to make a hexagonal array. $\endgroup$
    – PFD
    Jan 23, 2015 at 4:59
  • $\begingroup$ what's 'hex' in the code above? I could use a PopupMenu instead of RadioButton for choices. Tx. $\endgroup$
    – PFD
    Jan 23, 2015 at 5:53
  • $\begingroup$ @PFD Sorry, I seem to be making a lot of copy/paste errors recently. $\endgroup$
    – Mr.Wizard
    Jan 23, 2015 at 6:02

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.