Re: Locator

*To*: mathgroup at smc.vnet.net*Subject*: [mg88393] Re: Locator*From*: Albert Retey <awnl at arcor.net>*Date*: Sat, 3 May 2008 06:20:28 -0400 (EDT)*References*: <fvegs2$5de$1@smc.vnet.net>

Hi, > Very recently I started using Mathematica with the hopes of accomplishing the following. I have had some progress by using extensively the documentation center, however, any help will be really appreciated. I have 2 questions in particular and have described them below: Unusual things to try when starting to use Mathematica :-) > I have created 3 notebooks with the following command: > lst = Table[ > NotebookCreate[WindowSize -> {240, 240}, WindowTitle -> "new", > WindowMargins -> {{RandomInteger[{0, 100}], Automatic}, { Automatic, > RandomInteger[{0, 50}]}}], {3}]; > >>From all the open notebooks I get the 3 newly generated notebooks and get their locations. The following command does work however, it gives me a red symbol in Mathematica which I assume means that something is missing. Any ideas as to what is missing?: > newlst=Map[WindowMargins /. Options@# &, > Select[Notebooks[], > StringMatchQ[("WindowTitle" /. NotebookInformation[#]), "new"] &]] > > I then retrieve the notebook locations for the 3 notebooks. > coord = Map[({#[[1, 1]], #[[2, 2]] }) &, newlst] > > Finally, I want to create locators for each of the above notebooks, such that when I move the locators the notebooks are moved. In other words, the {x,y} position of the locators is mapped to the WindowMargins of that particular notebook. I have successfully created the locators but I have no clue how to map the locators such that the notebooks are moved. Below is the code for it: > > DynamicModule[{pt = new1}, > LocatorPane[Dynamic[pt], > Dynamic@ > ListPlot[pt, AxesOrigin -> {0, 0}, PlotRange -> {{0, 100}, {0, 50}}]]] > > I can move the locators, but with the moving of locators I need to the move corresponding notebook. Any help would be of great help when experimenting it is usually easier to get things working for a simple case. Here I'll start of with one notebook. Note that NotebookCreate returns a notebookobject which you can refer to later, so there is no need to search Notebooks[] for it: nb = NotebookCreate[ WindowSize -> {240, 240}, WindowMargins -> { {RandomInteger[{0, 100}], Automatic}, {Automatic, RandomInteger[{0, 50}]} } ] these define the screensizes and are handy lateron: screenheight = (ScreenRectangle /. Options[$FrontEnd])[[2, 2]] screenwidth = (ScreenRectangle /. Options[$FrontEnd])[[1, 2]] this is a function that moves the window for a given notebook to new values of WindowMargins: movenb[nb_, {x_, y_}] := SetOptions[nb, WindowMargins -> {{x, Automatic}, {Automatic, screenheight - y}}] This shows a LocatorPane which will move the window. The trick is to use the two argument version of Dynamic: DynamicModule[{pt = {#1, screenheight - #2} & @@ Flatten[WindowMargins /. Options[nb]][[{1, -1}]]}, LocatorPane[ Dynamic[pt, Function[pt = #; movenb[nb, pt]; pt] ], Graphics[{}, Frame -> True, PlotRange -> (ScreenRectangle /. Options[$FrontEnd]) ] ]] It turns out that handling lists is easier with this, which uses Locator instead of LocatorPane and happens to be more compact in this case as well: DynamicModule[{pt = {#1, screenheight - #2} & @@ Flatten[WindowMargins /. Options[nb]][[{1, -1}]]}, Graphics[{Locator[Dynamic[pt, Function[pt = #; movenb[nb, pt]; pt] ]]}, Frame -> True, PlotRange -> (ScreenRectangle /. Options[$FrontEnd]) ] ] now we are ready to work with a list of notebooks: nblst = Table[NotebookCreate[ WindowSize -> {240, 240}, WindowMargins -> { {RandomInteger[{0, screenwidth}], Automatic}, {Automatic, RandomInteger[{0, screenheight}]} } ], {3}] This defines a graphics with one locator for each window: nbcoords = Map[Flatten[WindowMargins /. Options[#]][[{1, -1}]] &, nblst] With[{screenheight = (ScreenRectangle /. Options[$FrontEnd])[[2, 2]]}, DynamicModule[{ ptlst = {#1, screenheight - #2} & @@@ nbcoords }, Graphics[{ Table[ With[{nn = n}, Locator[ Dynamic[ptlst[[nn]], Function[movenb[nblst[[nn]], #]; ptlst[[nn]] = #]] ] ], {n, Length[nblst]}] }, Frame -> True, PlotRange -> (ScreenRectangle /. Options[$FrontEnd]) ] ] ] to make it look nicer you might want to use rectangles as representations for your windows. You might want them to be of the correct relative size and use the top left corner for their positions to reflect more closely the actual window on screen, which I did not implement here: Deploy@DynamicModule[{ ptlst = {#1, screenheight - #2} & @@@ nbcoords }, Graphics[{ Table[ With[{nn = n}, Locator[ Dynamic[ptlst[[nn]], Function[movenb[nblst[[nn]], #]; ptlst[[nn]] = #]], Graphics[{Opacity[0.5], Rectangle[]}, ImageSize -> 48] ] ], {n, Length[nblst]}] }, Frame -> True, PlotRange -> (ScreenRectangle /. Options[$FrontEnd]), FrameTicks -> None ] ] hth, albert