8
$\begingroup$

I'm trying to create an attached cell that can be mouse dragged. I'm envisioning mouse-dragging the blue header bar to bring the entire header and the graphic to a new location at which point both will be locked to that location. The graphic needs to be rotatable by mouse-drag.

This is what I have so far:

AttachCell[EvaluationNotebook[], DynamicModule[{pt = {0, 0}},
   
   EventHandler[Graphics[Inset[Style[Grid[{
         
         {Button["Close", NotebookDelete[EvaluationCell[]], 
           ImageSize -> All, Appearance -> Button]}, {Plot3D[
           Sin[x y], {x, 1, 4}, {y, 1, 3}, ImageSize -> 300]}},
        
        Frame -> True,
        Background -> {None, {LightBlue, White}}], 
       Deployed -> False],
      Dynamic[pt]],
     
     PlotRange -> 10, ImageSize -> Scaled[1], Frame -> False],
    
    {"MouseDragged" :> (pt = MousePosition["Graphics"])}, 
    PassEventsDown -> True, PassEventsUp -> True]], Center, 0, 
  Center];

Notice in the video below I can drag the graphic anywhere using the header. However, a mouse-drag inside the graphic is both rotating the graphic and dragging the graphic causing the strange behavior. I want the grid draggable but only from the blue header as I still want to rotate the graphic. Any ideas?

enter image description here

$\endgroup$
8
  • $\begingroup$ On a semi-related note, Mike Honeycrunch created this kind of functionality inside a manipulate using locators (mathematica.stackexchange.com/a/162574/33996) although I don't think locators would be applicable in my question here. $\endgroup$
    – B flat
    Apr 6, 2022 at 17:50
  • $\begingroup$ With this approach you can't select within the parent notebook, are you fine with that? $\endgroup$
    – Kuba
    Apr 12, 2022 at 10:24
  • $\begingroup$ @Kuba Yes. No need to select anything in the parent notebook while the attached cell is active. Having the ability scroll the parent notebook is all I need as shown in the animation above. $\endgroup$
    – B flat
    Apr 12, 2022 at 11:09
  • $\begingroup$ Just curious… this is part of a lesson I am working my students. I’m hoping to find a solution. I would be willing to pay someone but probably not appropriate on this site I’m guessing. Can anyone direct me to where I can get something like this built? I hope this question is not inappropriate. $\endgroup$
    – B flat
    Apr 13, 2022 at 2:33
  • 1
    $\begingroup$ @Bflat Why not create a new window of notebook? $\endgroup$
    – rnotlnglgq
    Apr 13, 2022 at 6:39

2 Answers 2

3
+500
$\begingroup$

Update

My code works well if linksnooper is used (see the video).

This may be related to the change of performance, event frequency, dynamic update strategy or caches.

I'm still looking for a way to configure that.


Discussion

Quite strange, this sometimes works and sometimes doesn't work:

cell = With[{plot = ToBoxes@Plot3D[Sin[x y], {x, 1, 4}, {y, 1, 3}, ImageSize -> 300]},
    Cell[BoxData@DynamicModuleBox[{pt = {0, 0}},
        GraphicsBox[InsetBox[
            PanelBox@StyleBox[
                GridBox[{
                    {TagBox[
                        ButtonBox["Drag to move and click to close", ButtonFunction :> NotebookDelete[EvaluationCell[]]]
                    , EventHandlerTag@{"MouseDragged" :> (pt = MousePosition["Graphics"]), PassEventsDown -> True, PassEventsUp -> True, Method -> "Preemptive"}]},
                    {DynamicBox[ToBoxes[pt,StandardForm]]},
                    {plot}
                }]
            , Deployed -> False]
        , Dynamic@pt, Top]
        , PlotRange -> 10, ImageSize -> Scaled@1, Frame -> False, Method->"Preemptive"]
    ]
    , "Text"
    , Editable -> False]
];
AttachCell[EvaluationNotebook[], cell, Center, 0, Center]

Once it works, you can try to drag the 3D graphics and meanwhile move the mouse to the button for severaltimes, then it may break down again.

attachcell

And if you try cell //CellPrint instead, that works stably. cellprint

$\endgroup$
7
  • $\begingroup$ Doesn't seem to work for me. It may be related to the error I get that DynamicModuleBoxOptions is not an option for DynamicModuleBox. (i.e. "DynamicModuleBoxOptions -> {Method -> "Preemptive"}" is highlighted in red. $\endgroup$
    – B flat
    Apr 11, 2022 at 22:13
  • $\begingroup$ @Bflat Oh, that was a mistake, I pasted the wrong version of code. $\endgroup$
    – rnotlnglgq
    Apr 12, 2022 at 3:28
  • $\begingroup$ hmmmm. It still doesn't seem to work. The attached cell appears but does not let me move it at all and the figure doesn't rotate. All I can do is click to close. I'm running Mathematica 13.0 on a MacOS 12.0.1 $\endgroup$
    – B flat
    Apr 12, 2022 at 8:41
  • $\begingroup$ @Bflat I updated two videos. It's true that my code is buggy, however I want to show: the code that works well as a normal cell may fail when it becomes an attached cell. $\endgroup$
    – rnotlnglgq
    Apr 12, 2022 at 11:12
  • 1
    $\begingroup$ @Bflat This is related to internal details of the front-end. I'm afraid that we may need a WRI staff to answer this. $\endgroup$
    – rnotlnglgq
    Apr 16, 2022 at 5:20
3
$\begingroup$

This works. Instead of attaching the graphic using dynamic Graphics Inset, I attached it directly to the notebook using the Attached Cell. To move the attached cell around the notebook I used event handlers that refresh on mousedrags while deleting their traces. That was tricky. . I think this is cleaner... but a bit harder to do. Here is a video and code below. If anyone wants to clean up my code... please do. I'm not much of a programmer and would like to see how I can be more efficient.

enter image description here

mo = EventHandler[
   DynamicModule[{x = 0}, Button["Close"], 
    Initialization :> (k = 
       AttachCell[EvaluationBox[], 
        DynamicModule[{}, 
         Style[
          Plot3D[Sin[x y], {x, 1, 4}, {y, 1, 3}, ImageSize -> 300, 
           SphericalRegion -> True, ImagePadding -> 10, 
           Background -> LightYellow, PerformanceGoal -> "Quality"], 
          Deployed -> False], InheritScope -> True], Bottom, 0, Top])],
   {"MouseClicked" :> (NotebookDelete[ParentCell[k]])}];

g[Dynamic[k_]] := 
  SetOptions[k, CellEventActions -> {"MouseDragged" :> (None),
     "MouseUp" :> (SelectionMove[InputNotebook[], Next, Cell];
       SelectionMove[InputNotebook[], Before, CellContents]), 
     PassEventsDown -> True
     }];

f[Dynamic[attachedCell_, init_]] := 
  SetOptions[ParentCell[k], CellEventActions -> {
     "MouseDragged" :> (
       NotebookDelete[init];
       NotebookDelete[attachedCell];
       attachedCell = 
        AttachCell[InputNotebook[], mo, {Left, Top}, 
         Offset[MousePosition["WindowAbsolute"]*{1, -1}, 0]];
       g[Dynamic[k]];
       f[Dynamic[attachedCell, init]];
       
       ), PassEventsDown -> True}];

DynamicModule[{init, attachedCell, p},
 
 Button["Start",
  SelectionMove[InputNotebook[], Before, CellContents];
  init = AttachCell[InputNotebook[], mo, Center, 0, Center];
  SetOptions[EvaluationNotebook[], 
   CellEventActions -> {"MouseDragged" :> (None)}];
  
  SetOptions[k, CellEventActions -> {"MouseDragged" :> (None),
     "MouseUp" :> (SelectionMove[InputNotebook[], Next, Cell];
       SelectionMove[InputNotebook[], Before, CellContents]), 
     PassEventsDown -> True
     }];
  SetOptions[ParentCell[k], CellEventActions -> {
     "MouseDragged" :> (
       NotebookDelete[init];
       NotebookDelete[attachedCell];
       attachedCell = 
        AttachCell[InputNotebook[], mo, {Left, Top}, 
         Offset[MousePosition["WindowAbsolute"]*{1, -1}, 0]];
       
       g[Dynamic[k]];
       f[Dynamic[attachedCell, init]];
       
       
       ), PassEventsDown -> True}]
  ]]
$\endgroup$
5
  • $\begingroup$ Is it really necessary to continuously delete and recreate a cell upon drag? Is it because there is no way to dynamically adjust the coordinates of the attached cell once it's created? $\endgroup$
    – QuantumDot
    Aug 27, 2022 at 18:37
  • $\begingroup$ Well, I did find this for CellPrint: Slider2D[Dynamic[xy], {0, 100}] CellPrint[Cell["x", CellMargins -> Dynamic[{xy, xy}]]]. Any way this could work for attached cell? $\endgroup$
    – QuantumDot
    Aug 28, 2022 at 0:28
  • $\begingroup$ Have you explored trying to create a new (small sized) notebook window with no frame? If you did, perhaps you could give me a hint as to why it wouldn't work, so I don't go down a path that ends in a dead-end. $\endgroup$
    – QuantumDot
    Aug 28, 2022 at 1:02
  • $\begingroup$ I'm sorry. I forgot the issue...As you can see in the code in my original question above, I can move the attached cell if I move the object it's attached to. It works as you suggest. However, it forced the 3D graphic itself to rotate when I moved the entire graphic. I couldn't get around this. Try it. My solution was how I got around the issue. I am hoping there is a faster method based on my original code without repeatedly deleting the traces... but I couldn't make it work with the 3D graphic. If you find a way... I'd really like to see. $\endgroup$
    – B flat
    Aug 28, 2022 at 1:16
  • $\begingroup$ I tried attaching a small size notebook, but the attached cell can't do that. Also, there is the other issue with the window appearing on top of the primary window. That option broke in Mathematica for windows and notebooks a while back. $\endgroup$
    – B flat
    Aug 28, 2022 at 1:28

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.