cfddf38a67
This doesn't (seem to) work quite right because of the way Flash does handles component dimensions. It's designed to be overridden. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4450 542714f4-19e9-0310-aa3c-eee0fc999fb1
148 lines
3.9 KiB
ActionScript
148 lines
3.9 KiB
ActionScript
package com.threerings.mx.controls {
|
|
|
|
import flash.display.DisplayObject;
|
|
import flash.display.Graphics;
|
|
import flash.display.Sprite;
|
|
|
|
import flash.events.Event;
|
|
import flash.events.MouseEvent;
|
|
|
|
import flash.geom.Matrix;
|
|
import flash.geom.Rectangle;
|
|
|
|
import mx.containers.Canvas;
|
|
|
|
/**
|
|
* A control for scrolling some component separately.
|
|
*/
|
|
public class ScrollBox extends Canvas
|
|
{
|
|
public function ScrollBox (
|
|
target :DisplayObject, maxWidth :int, maxHeight :int)
|
|
{
|
|
_target = target;
|
|
_maxWidth = maxWidth;
|
|
_maxHeight = maxHeight;
|
|
|
|
opaqueBackground = 0xFFFFFF;
|
|
|
|
_box = new Sprite();
|
|
rawChildren.addChild(_box);
|
|
|
|
recheckBounds();
|
|
|
|
// TODO: only when something changes
|
|
addEventListener(Event.ENTER_FRAME, enterFrame);
|
|
|
|
_box.addEventListener(MouseEvent.MOUSE_DOWN, spritePressed);
|
|
}
|
|
|
|
override public function setActualSize (w :Number, h :Number) :void
|
|
{
|
|
super.setActualSize(w, h);
|
|
|
|
recheckBounds();
|
|
|
|
graphics.clear();
|
|
graphics.lineStyle(1, 0);
|
|
graphics.drawRect(0, 0, width, height);
|
|
}
|
|
|
|
protected function enterFrame (vent :Event) :void
|
|
{
|
|
if (!_dragging) {
|
|
recheckBounds();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the bounds of the scrollable area. Broken-out for easy overridding.
|
|
*/
|
|
protected function getScrollBounds () :Rectangle
|
|
{
|
|
var bounds :Rectangle = _target.transform.pixelBounds;
|
|
// var m :Matrix = _target.transform.concatenatedMatrix;
|
|
// bounds.topLeft = m.transformPoint(bounds.topLeft);
|
|
// bounds.bottomRight = m.transformPoint(bounds.bottomRight);
|
|
return bounds;
|
|
}
|
|
|
|
protected function recheckBounds () :void
|
|
{
|
|
var bounds :Rectangle = getScrollBounds();
|
|
|
|
// see what's visible, what's not..
|
|
var scroller :Rectangle = _target.scrollRect;
|
|
if (scroller == null) {
|
|
scroller = bounds.clone();
|
|
}
|
|
|
|
if ((_bounds != null) && _bounds.equals(bounds) &&
|
|
(_scroller != null) && _scroller.equals(scroller)) {
|
|
return;
|
|
}
|
|
|
|
_bounds = bounds.clone();
|
|
_scroller = scroller;
|
|
|
|
_scale = Math.min(1,
|
|
Math.min(_maxWidth / _bounds.width, _maxHeight / _bounds.height));
|
|
width = _scale * _bounds.width;
|
|
height = _scale * _bounds.height;
|
|
|
|
drawBox(_box, _scroller.width * _scale, _scroller.height * _scale);
|
|
|
|
_box.x = (_scroller.x - _bounds.x) * _scale;
|
|
_box.y = (_scroller.y - _bounds.y) * _scale;
|
|
}
|
|
|
|
protected function drawBox (box :Sprite, ww :Number, hh :Number) :void
|
|
{
|
|
var g :Graphics = _box.graphics;
|
|
g.clear();
|
|
g.beginFill(0x0000FF);
|
|
g.drawRect(0, 0, ww, hh);
|
|
g.endFill();
|
|
}
|
|
|
|
protected function spritePressed (evt :MouseEvent) :void
|
|
{
|
|
_box.addEventListener(Event.ENTER_FRAME, boxUpdate);
|
|
_box.startDrag(true,
|
|
new Rectangle(0, 0, width - _box.width, height - _box.height));
|
|
stage.addEventListener(MouseEvent.MOUSE_UP, spriteReleased);
|
|
_dragging = true;
|
|
}
|
|
|
|
protected function spriteReleased (evt :MouseEvent) :void
|
|
{
|
|
stage.removeEventListener(MouseEvent.MOUSE_UP, spriteReleased);
|
|
_box.stopDrag();
|
|
_box.removeEventListener(Event.ENTER_FRAME, boxUpdate);
|
|
_dragging = false;
|
|
}
|
|
|
|
protected function boxUpdate (evt :Event) :void
|
|
{
|
|
var r :Rectangle = _target.scrollRect;
|
|
r.x = (_box.x / _scale) + _bounds.x;
|
|
r.y = (_box.y / _scale) + _bounds.y;
|
|
_target.scrollRect = r;
|
|
}
|
|
|
|
protected var _dragging :Boolean;
|
|
|
|
protected var _target :DisplayObject;
|
|
|
|
protected var _maxWidth :int;
|
|
protected var _maxHeight :int;
|
|
|
|
protected var _box :Sprite;
|
|
|
|
protected var _scale :Number;
|
|
|
|
protected var _bounds :Rectangle;
|
|
protected var _scroller :Rectangle;
|
|
}
|
|
}
|