What is FrontEnd`AttachedCell?
Intro
One day I was playing with Developer`
package and found DateSetter
which uses some kind of floating elements that I found useful.
After taking a look at a source code I found out it was FrontEnd`AttachedCell
. From the code one could learn enough to create something useful:
Usage
FrontEnd`AttachCell[
parentObject, (*Box or Cell Object*)
attachedCellBoxes,
{Automatic, {Left, Bottom}}, (*1*)
{Left, Top}, (*2*)
"ClosingActions" -> {...} (*3*)
]
- I don't know what an
Automatic
is there for but the second part is setting alignment anchor point in theparentBoxObject
- alignment anchor point in the
attached cell
- "The
ClosingActions
determines actions which automatically dismiss the attached cells". Available actions:"ParentChanged", "EvaluatorQuit", "OutsideMouseClick", "SelectionDeparture", "MouseExit"
.
I couldn't figure everything out by myself so let's quote John Fultz whom I've asked about details:
Kuba:
[...]
I'm aware it is undocumented but I'm curious if it is stable. [...]
Can you give me any insight in "ClosingActions"? [...]
Can I AttachCell for DockedCells elements? [...]
John Fultz:
Yes, this functionality is used all over the place. At some point, it'll graduate to a
System`
level function, but even when it does, we'll probably maintain backward compatibility with the current stuff.The
"ClosingActions"
determines actions which automatically dismiss the attached cells. You can manually dismiss a cell by doingNotebookDelete
on the attached cell'sCellObject
. But there are some circumstances where it's much easier to let the system do it for you. It can be a list of any of the following:"SelectionDeparture"
-- if the selection leaves the parent, the attached cell, or any of the attached cell's children (the selection might be in the attached cell if the attached cell hasInputFields
)."ParentChanged"
-- if any change is made to the parent of the attached cell"MouseExit"
-- if the mouse leaves the region of the attached cell"OutsideMouseClick"
-- if a click happens anywhere outside of the attached cell. This includes clicks of the right and middle mouse buttons.
Yes, that works, too. Except that the docked view will clip attached cells, so if the attached cell doesn't live fully within the docked view, it may not be very useful.
My example:
attachTo[parentbox_] := MathLink`CallFrontEnd[
FrontEnd`AttachCell[
parentbox,
ToBoxes[ExpressionCell[
EventHandler[Panel["floating panel"],
"MouseExited" :> (NotebookDelete[ParentCell[EvaluationBox[]]];)
],
StripOnInput -> True, Background -> White,
CellFrameColor -> LightBlue, CellFrameMargins -> 0, CellFrame -> 2
]],
{Automatic, {Right, Bottom}},
{Left, Top},
"ClosingActions" -> {"ParentChanged", "EvaluatorQuit", "OutsideMouseClick"}
]]
DynamicModule[{parentBox, attachedCell},
EventHandler[
Panel["test"],
{ "MouseEntered" :> (
NotebookDelete @ attachedCell;
attachedCell = attachTo[parentBox];
)}
],
Initialization :> ( parentBox = EvaluationBox[]; )
]
Notice that I'm not using "MouseExit" closing action
but an EventHandler + NotebookDelete
. That's because if the initial position of the attached cell is away from cursor then it won't appear at all.
Possible issues
- the tricky thing is to get the
parentBoxObject
. - it's not the same as e.g. menu in
PopupMenu
since attached cell is restricted to notebook area only while the menu is able to be outside.
This is potentially useful info from a scrape I did building on this. The alignment position can be an Offset
spec too, a la:
MathLink`CallFrontEnd[
FrontEnd`AttachCell[EvaluationCell[],
Cell["wheee"],
{Offset[{10, -71}, 15], {Left, Bottom}},
{Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]
];
Which gives better placement control
For the scrape I just found all the uses in my $InstallationDirectory
:
{
"/Applications/Mathematica.app/Contents/AddOns/Applications/\
DemoChannels/Oneliner.m" ->
HoldComplete[
FrontEnd`AttachCell[SystemSearchDump`$tnb, ToBoxes[\!\(
PanelBox[
TagBox[GridBox[{
{
InterpretationBox[\!\(\*
StyleBox["\<\"Send to channel:\"\>",
StripOnInput->False,
FontSize->Medium]\),
Text[
Style["Send to channel:", Medium]]]},
{
TagBox[
InputFieldBox[Dynamic[SystemSearchDump`in$$], String,
ImageSize->{758., 20}],
EventHandlerTag[{"ReturnKeyDown" :> (ChannelSend["Demos:Oneliner",
ToExpression[
SystemSearchDump`in$$, InputForm,
Unevaluated]]; SystemSearchDump`in$$ = Null),
Method -> "Preemptive", PassEventsDown -> Automatic,
PassEventsUp -> True}]]}
},
DefaultBaseStyle->"Column",
GridBoxAlignment->{
"Columns" -> {{Left}}, "ColumnsIndexed" -> {},
"Rows" -> {}, "RowsIndexed" -> {}, "Items" -> {},
"ItemsIndexed" -> {}},
GridBoxItemSize->{
"Columns" -> {{Automatic}}, "ColumnsIndexed" -> {},
"Rows" -> {{Automatic}}, "RowsIndexed" -> {},
"Items" -> {}, "ItemsIndexed" -> {}}],
"Column"]]\)], {0, {Center, Bottom}}, {Center, Bottom}]],
"/Applications/Mathematica.app/Contents/Documentation/English/\
Packages/Compatibility/Documentation/English/Tutorials/PlotLegends.\
nb" -> HoldComplete[
FrontEnd`AttachCell[Typeset`box$,
FrontEndResource[
"RGBColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ExamplePages/CreateChartLegends.nb" ->
HoldComplete[
FrontEnd`AttachCell[Typeset`box$,
FrontEndResource[
"GrayLevelColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ExamplePages/LegendPointMarkers.nb" ->
HoldComplete[
FrontEnd`AttachCell[Typeset`box$,
FrontEndResource[
"HueColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ReferencePages/Interpreters/Color.nb" ->
HoldComplete[
FrontEnd`AttachCell[Typeset`box$,
FrontEndResource[
"CMYKColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ReferencePages/Symbols/ClusterClassify.nb" ->
HoldComplete[
FrontEnd`AttachCell[Typeset`box$,
FrontEndResource[
"LABColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ReferencePages/Symbols/ColorDistance.nb" ->
HoldComplete[
FrontEnd`AttachCell[Typeset`box$,
FrontEndResource[
"LCHColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ReferencePages/Symbols/ColorNegate.nb" ->
HoldComplete[
FrontEnd`AttachCell[Typeset`box$,
FrontEndResource[
"LUVColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ReferencePages/Symbols/ColorNegate.nb" ->
HoldComplete[
FrontEnd`AttachCell[Typeset`box$,
FrontEndResource[
"XYZColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ReferencePages/Symbols/Graph.nb" ->
HoldComplete[
FrontEnd`AttachCell[WSMLink`box$,
FrontEndResource[
"GrayLevelColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/Documentation/English/System/\
ReferencePages/Symbols/WhitePoint.nb" ->
HoldComplete[
FrontEnd`AttachCell[WSMLink`box$,
FrontEndResource[
"XYZColorValueSelector"], {0, {Left, Bottom}}, {Left, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/SystemFiles/Components/MUnit/\
Kernel/Palette.m" ->
HoldComplete[
FrontEnd`AttachCell[EvaluationCell[], SystemSearchDump`cell,
SystemSearchDump`pos, SystemSearchDump`opos]],
"/Applications/Mathematica.app/Contents/SystemFiles/Components/\
WolframAlphaClient/Kernel/WolframAlphaClient.m" ->
HoldComplete[
FrontEnd`AttachCell[SystemSearchDump`box,
SystemSearchDump`cell, {Offset[{7, 7}, 0], {SystemSearchDump`hpos,
Bottom}}, {SystemSearchDump`hpos, Top},
"ClosingActions" -> {"SelectionDeparture", "ParentChanged",
"EvaluatorQuit"}]],
"/Applications/Mathematica.app/Contents/SystemFiles/Components/\
WolframAlphaClient/Kernel/WolframAlphaClient.m" ->
HoldComplete[
FrontEnd`AttachCell[SystemSearchDump`box,
Cell[BoxData[ToBoxes[SystemSearchDump`b]]], {Offset[{2, 2},
0], {Left, Bottom}}, {Right, Bottom}]],
"/Applications/Mathematica.app/Contents/SystemFiles/Components/\
WolframAlphaClient/Kernel/WolframAlphaClient.m" ->
HoldComplete[
FrontEnd`AttachCell[SystemSearchDump`cell,
Cell[BoxData[ToBoxes[\!\(\*
TagBox["SystemSearchDump`b",
EventHandlerTag[{
"MouseExited" :> (
NotebookDelete[SystemSearchDump`attached]; Unset[
SystemSearchDump`attached]), Method -> "Preemptive",
PassEventsDown -> Automatic, PassEventsUp -> True}]]\)]],
Magnification ->
AbsoluteCurrentValue[SystemSearchDump`cell,
Magnification]], {Offset[{0, 0}, 0], {Center,
Center}}, {Center, Center}]],
"/Applications/Mathematica.app/Contents/SystemFiles/Components/\
WolframAlphaClient/Kernel/WolframAlphaClient.m" ->
HoldComplete[
FrontEnd`AttachCell[SystemSearchDump`box,
Cell[BoxData[ToBoxes[\!\(\*
TagBox["SystemSearchDump`b",
EventHandlerTag[{
"MouseExited" :> (
NotebookDelete[SystemSearchDump`attached]; Unset[
SystemSearchDump`attached]), Method -> "Preemptive",
PassEventsDown -> Automatic, PassEventsUp -> True}]]\)]],
Magnification ->
AbsoluteCurrentValue[SystemSearchDump`box,
Magnification]], {Offset[{0, 0}, 0], {Center,
Center}}, {Center, Center}]],
"/Applications/Mathematica.app/Contents/SystemFiles/Components/\
WolframAlphaClient/Kernel/WolframAlphaClient.m" ->
HoldComplete[
FrontEnd`AttachCell[SystemSearchDump`box,
Cell[BoxData[ToBoxes[SystemSearchDump`b]],
Magnification ->
AbsoluteCurrentValue[SystemSearchDump`box,
Magnification]], {Offset[{0, 0}, 0], {Center,
Center}}, {Center, Center}, "ClosingActions" -> {"MouseExit"}]]
}