5
$\begingroup$

In Mathematica, it is possible to create a Table or Grid of \[Placeholder] boxes. For example, I can make a 3-by-3 Grid of \[Placeholder] boxes:

Grid[
 Table[\[Placeholder], {3}, {3}],
 Frame -> All, ItemSize -> Full]

Grid

Then, I can click on one of the placeholders (for example, the top left-hand placeholder) to change focus to it:

GridFocus

Once focus is on one of the placeholders, I can use the arrow keys on the keyboard or the Tab key to change the focus to one of the other placeholders (at least in Windows XP; I have not tested this on later versions of Windows or Mac or Linux).

Using the Tab key is particularly handy, because it cycles through the placeholders in the "canonical" order (i.e., cells {1,1}, {1,2}, {1,3}, {2,1}, {2,2}, {2,3}, {3,1}, {3,2}, {3,3} where the elements are {row index, column index}):

GridTab

But, it can somewhat of a chore to cycle through the placeholders using Tab, especially for large n-by-n grids. My question is, is it possible to interactively change focus in a grid using the keyboard?

For example, suppose that I label the rows with letters and the columns with numbers:

TableForm[
 Table[\[Placeholder], {3}, {3}],
 TableHeadings -> {{"a", "b", "c"}, {"1", "2", "3"}}]

GridLabeled

Is there any way to write a function in which I could type "b2", for example, using the keyboard and have Mathematica automatically change focus to the placeholder at coordinate b2, like the following?

GridLabeledFocus

With the focus now at "b2", I can mark this coordinate it in some way, perhaps by typing an "x":

GridLabeledFocusMarked

Remember the board game Battleship? It is basically a game of placing "x" at "hit" coordinates (and placing nothing at "miss" coordinates):

BoardGame

I would like to use Mathematica to specify and mark coordinates in a grid interactively, using the keyboard. It doesn't matter how the coordinates are marked. In other words, I don't necessarily need the script to change \[Placeholder] focus in a Grid; I just need to be able to specify coordinates such as "b2" interactively (i.e., in real time, not from a list of predefined coordinates) and be able to mark those coordinates in some way. So, in this sense, it doesn't necessarily need to be a Grid of \[Placeholder]s. It could be a Grid of Checkboxes. It could be a Grid of Rectangles that change color when specified using the keyboard. In other words, the important feature I am looking for is to use the keyboard to specify coordinates, not mouse clicks.

Do you have any initial thoughts of how I can accomplish this? Do I need to use Input or InputField, or are there other ways to get keyboard input from the user? Thanks so much for your time and help.

$\endgroup$
1
  • $\begingroup$ Closely related $\endgroup$
    – Kuba
    Jul 16, 2013 at 23:52

1 Answer 1

5
$\begingroup$

Build in interface

Undocumented and I don't know how to fully customize it but it seems it is something you're looking for:

TableView[RandomChoice[{0, 1}, {10, 10}]]

enter image description here

rubenko deliverd it here with a link to some info. As Jens have noticed it is not so great but You have to judge it by yourself.

Custom interface

If you do not need to have fully editable cells then maybe something like this:

n = 9; i = 1; j = 1; grid = Table[\[SelectionPlaceholder], {9}, {9}];
CreateDocument[
  ExpressionCell[
   With[{set = Sequence[ItemSize -> {4, 5}, Alignment -> {Center, Center}]},
    Framed[
     Row[{
       Grid[{{""}~Join~Range@n} // Transpose, set],
       Column[{
         Grid[{CharacterRange["a", "z"][[;; n]]}, set],
    Dynamic@Grid[grid, Background -> Dynamic@{None, None, {i, j} -> Red},
                       set, Frame -> All]
         }]}]]]
   , "Output"]
  ,
  NotebookEventActions -> {
    "UpArrowKeyDown" :> (i = Mod[i - 1, n, 1]),
    "DownArrowKeyDown" :> (i = Mod[i + 1, n, 1]),
    "RightArrowKeyDown" :> (j = Mod[j + 1, n, 1]),
    "LeftArrowKeyDown" :> (j = Mod[j - 1, n, 1]),
    {"KeyDown", "x"} :> (grid = ReplacePart[grid, {i, j} -> "X"]),
    {"KeyDown", "z"} :> (grid = ReplacePart[grid, {i, j} -> "\[CenterDot]"])
    }
  , WindowSize -> {800, 800}
  ]

enter image description here

$\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.