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$
  • $\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 '15 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 '15 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 '15 at 0:59
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$
  • $\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 '15 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 '15 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 '15 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$
  • $\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 '15 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 '15 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 '15 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 '15 at 5:53
  • $\begingroup$ @PFD Sorry, I seem to be making a lot of copy/paste errors recently. $\endgroup$ – Mr.Wizard Jan 23 '15 at 6:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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