How to make a cell highlight on mouse down?

6

3

When a cell has WholeCellGroupOpener set to True, it becomes a clickable button that toggles its cell group open and closed.

How can I make the cell change color when I press down on it so I know I have clicked the right thing? This is the behavior you would expect to see from most buttons.

Here's what it looks like - the issue is that you can't tell when I press the mouse down:

enter image description here

Here's the code I tried so far in the stylesheet:

Cell[StyleData["Text"],
 CellEventActions->{"MouseDown" :> (SelectionMove[
      InputNotebook[], All, ButtonCell]; SetOptions[
      NotebookSelection[
       InputNotebook[]], Background -> LightGreen]), "MouseUp" :> (SelectionMove[
      InputNotebook[], All, ButtonCell]; SetOptions[
      NotebookSelection[
       InputNotebook[]], Background -> White]; FrontEndExecute[
      FrontEndToken["OpenCloseGroup"]])}
      ]

M.R.

Posted 2015-08-28T14:13:28.643

Reputation: 30 727

What you are asking for is not the normal behavior for openers even outside of Mathematica. – m_goldberg – 2015-08-28T14:44:29.673

I guess so, but I think the triangle on the left is ugly so I hide it so this sort of visual feedback would be great – M.R. – 2015-08-28T14:46:23.403

@m_goldberg does the gif I added to the post help you see what I mean? – M.R. – 2015-08-28T22:29:50.577

Answers

4

You can use CellEventActions by adding it to the Stylesheet or hard-coding it for each cell. Here is a cell that changes when clicked.

DynamicModule[{bgd = LightRed}, 
    CellPrint[
        TextCell["Click within this cell", "Output", 
            Background -> Dynamic[bgd], 
            CellEventActions -> {"MouseClicked" :> (bgd = LightGreen)}
        ]
    ]
];

Rather than having it change once you can have it set a variable that indicates the CellID or something which determines whether or not the cell should be highlighted, such as the following two cells which toggle back and forth when clicked (disclaimer, this uses a lot of Dynamic stuff and may choke the frontend):

DynamicModule[{selected = 3}, 
    CellPrint[{
        TextCell["Click within this cell", "Output", 
            Background -> Dynamic[If[selected === 1, Yellow, Gray]], 
            CellEventActions -> {"MouseClicked" :> (selected = 1)}], 
        TextCell["Click within this cell", "Output", 
            Background -> Dynamic[If[selected === 2, Yellow, Gray]],
            CellEventActions -> {"MouseClicked" :> (selected = 2)}]
    }]
];

UPDATE (to embed in stylesheet): The following let's this work in a stylesheet, although MouseDown and MouseUp behave differently when clicking between cells and this will cause some unexpected behaviour.

Cell[
    StyleData["Text"],
    CellEventActions -> {
        "MouseDown" :> SetOptions[EvaluationCell[], Background -> GrayLevel[0.5]], 
        "MouseUp" :> Quiet[
            SetOptions[EvaluationCell[], Background -> GrayLevel[1]];
            SelectionMove[EvaluationCell[], All, Cell];
            FrontEndTokenExecute["OpenCloseGroup"]
        ], 
        PassEventsDown -> True
    }
    (*uncomment the following if you want Deployed like WholeCellGroupOpener*)
    (*,
        Deployed -> True
    *)
]

UPDATE 2: Probably what you were looking for

Cell[StyleData["Text"],
    CellEventActions->{
        "MouseDown" :> 
            With[{cell = EvaluationCell[]}, 
                SetOptions[cell, Background -> GrayLevel[0.5]]; 
                RunScheduledTask[SetOptions[cell, Background -> GrayLevel[1]], {0.2, 1}]], 
        "MouseUp" :> RemoveScheduledTasks[ScheduledTasks[]],
         PassEventsDown -> True},
    WholeCellGroupOpener -> True
]

Kyle Keane

Posted 2015-08-28T14:13:28.643

Reputation: 202

I don't want an action not on mouse clicked, but only when pushing down... also this doesn't work in stylesheets. – M.R. – 2015-08-28T23:07:02.110

1You can use the event handler MouseDown rather than MouseClicked if you wish, there is also MouseUp, MouseEntered and MouseExited if you want to get fancy :). It can be modified to work in stylesheets using the CellID option and CurrentValue, but it would take some finesse. – Kyle Keane – 2015-08-28T23:12:39.277

Oh yeah, and MouseMoved... – Kyle Keane – 2015-08-28T23:34:24.280

Did you try putting this into a stylesheet? It prevents the cell from opening. – M.R. – 2015-08-29T21:19:30.557

I can not accept this answer because it doesn't work in a stylesheet. – M.R. – 2015-08-31T01:40:10.323

1Append PassEventsDown->True to the CellEventActions and it should work – Kyle Keane – 2015-08-31T01:44:35.470

1Also I'm not sure if ButtonCell is a valid selector for SelectionMove, I guess it is safer just to use Cell – Kyle Keane – 2015-08-31T01:49:22.077

It would really help if you posted the exact stylesheet cell that you claim works. – M.R. – 2015-08-31T16:19:06.020

Added code to the answer. There are complexities using MouseDown and MouseUp, namely they do not behave the same when clicking between cells to create an insertion point. This is the reason for the Quiet in the code, because when clicking between cells there is no EvaluationCell for MouseUp, but there is one for MouseDown. You can add logic to handle this case if you are clicking between cells. Hope this helps. – Kyle Keane – 2015-08-31T19:52:48.177

Looking at your original question, I added another option that might be more useful. – Kyle Keane – 2015-08-31T20:18:46.933