Here's a more robust version of Rojo's answer:
BeginPackage["DragPane`"];
DragPane::usage = "implements a draggable Pane";
BeginPackage["`Package`"];
DragPaneDynamicModule::usage = "the dynamic module used by DragPane";
EndPackage[];
Begin["`Private`"];
Options[DragPaneDynamicModule] =
Join[
Options[Pane],
{
AutoAction -> False
}
];
DragPaneDynamicModule[
exp_,
{width_, height_},
ops : OptionsPattern[]
] :=
With[
{
boxSize =
{#[[1]], 3 + Total@#[[2 ;;]]} &@First@
FrontEndExecute@
GetBoundingBoxSizePacket[
Cell[BoxData[ToBoxes[exp]],
"Output",
PageWidth -> \[Infinity],
ShowCellBracket -> False,
CellMargins -> {{0, 0}, {0, 0}}
]
]
},
DynamicModule[
{
scrollX = 0., scrollY = 0.,
maxWidth =
If[! NumericQ@width,
boxSize[[1]],
Max@{boxSize[[1]], width}
],
boxWidth =
If[! NumericQ@width, Min@{boxSize[[1]], 360} , width],
maxHeight =
If[! NumericQ@height,
boxSize[[2]],
Max@{boxSize[[2]], height}
],
boxHeight =
If[! NumericQ@height, Min@{boxSize[[2]], 360} , height],
setXScroll,
setYScroll,
getXScroll,
getYScroll,
scrolling = False,
refWidth, refX,
refHeight, refY
},
Pane[
EventHandler[
Pane[
Pane[exp, 2*boxSize, Alignment -> {Left, Top}],
Full,
ScrollPosition :>
Dynamic[
If[
TrueQ[scrolling],
{
setXScroll[],
setYScroll[]
},
{scrollX, scrollY}
],
Function[
scrollX =
Clip[#[[1]], {0., Max@{maxWidth - boxWidth, 0.}}];
scrollY =
Clip[#[[2]], {0., Max@{maxHeight - boxHeight, 0.}}];
],
TrackedSymbols :> {scrollX, scrollY}
],
Alignment -> {Left, Top}
],
{
If[TrueQ@OptionValue[AutoAction],
"MouseEntered",
"MouseDown"
] :>
(
refX = scrollX;
refY = scrollY;
{refWidth, refHeight} = MousePosition["ScreenAbsolute"];
scrolling = True
),
If[TrueQ@OptionValue[AutoAction],
"MouseMoved",
"MouseDragged"
] :>
(
If[! AllTrue[{refWidth, refHeight}, NumericQ],
refX = scrollX;
refY = scrollY;
{refWidth, refHeight} = MousePosition["ScreenAbsolute"];
scrolling = True
];
setXScroll[];
),
If[TrueQ@OptionValue[AutoAction],
"MouseExited",
"MouseUp"
] :>
(
scrolling = False;
setXScroll[];
setYScroll[];
Clear[refWidth, refHeight, refX, refY];
)
}
] // MouseAppearance[#, "PanView"] &,
FilterRules[
{
ImageSize ->
Dynamic[{boxWidth, boxHeight}],
ops
},
Options[Pane]
]
],
Initialization :>
{
getXScroll[x_] :=
Clip[
refX + refWidth - x,
{0., Max@{maxWidth - boxWidth, 0.}}
];
getXScroll[] :=
getXScroll[First@MousePosition["ScreenAbsolute"]],
setXScroll[x___] :=
scrollX = getXScroll[x],
getYScroll[y_] :=
Clip[
refY + refHeight - y,
{0., Max@{maxHeight - boxHeight, 0.}}
];
getYScroll[] :=
getYScroll[Last@MousePosition["ScreenAbsolute"]],
setYScroll[y___] :=
scrollY = getYScroll[y]
}
]
];
Options[DragPane] =
Options[DragPaneDynamicModule];
DragPane[
exp_,
w : _?NumericQ | Automatic,
ops : OptionsPattern[]
] :=
DragPane[exp, {w, Automatic}, ops];
DragPane[
exp_,
ops : OptionsPattern[]
] :=
DragPane[exp,
OptionValue[ImageSize],
ops
];
Format[dp :
DragPane[exp_, {width_, height_}, ops : OptionsPattern[]],
StandardForm] :=
Interpretation[
DragPaneDynamicModule[exp, {width, height}, ops],
dp
];
End[];
EndPackage[]
- The scrolling is more stable
- It only displays as the scrollable form. That is, its expression form remains
DragPane
.
- It supports scrolling in y as well, but only if there's space
- It can take
AppearanceElements -> "ResizeArea"
- I added
AutoAction
as a bit of a joke
Here's a good example:
DragPane[
ImageResize[ExampleData[{"TestImage", "Mandrill"}],
Scaled[2]
]
]

With
or something? Btw, Win7/mma 8, when I drag it right to the most significant digits I can drag it out of frame, but not to the left. I mean, you have to drag it inside the cell for it to work $\endgroup$With
, I just didn't do it on the first try. $\endgroup$