Type.registerNamespace('Sys.Extended.UI');
Sys.Extended.UI.ResizableControlBehavior = function(element) {
Sys.Extended.UI.ResizableControlBehavior.initializeBase(this, [element]);
// Properties
this._handleCssClass = "";
this._resizableCssClass = "";
this._handleOffsetX = 0;
this._handleOffsetY = 0;
this._minimumWidth = 0;
this._minimumHeight = 0;
this._maximumWidth = 100000;
this._maximumHeight = 100000;
// Variables
this._frame = null;
this._handle = null;
this._handleHolder = null;
this._lining = null;
this._tracking = false;
this._lastClientX = 0;
this._lastClientY = 0;
// Delegates
this._onmouseoverDelegate = null;
this._onmouseoutDelegate = null;
this._onmousedownDelegate = null;
this._onmousemoveDelegate = null;
this._onmouseupDelegate = null;
this._onselectstartDelegate = null;
}
Sys.Extended.UI.ResizableControlBehavior.prototype = {
initialize: function() {
Sys.Extended.UI.ResizableControlBehavior.callBaseMethod(this, 'initialize');
this._frame = this.get_element();
var savedSizeString = Sys.Extended.UI.ResizableControlBehavior.callBaseMethod(this, 'get_ClientState');
if(savedSizeString && (-1 != savedSizeString.indexOf(','))) {
var savedSize = savedSizeString.split(',');
this._frame.style.width = savedSize[0] + 'px';
this._frame.style.height = savedSize[1] + 'px';
}
// The this._lining lets us measure the interior of the this._frame easily and
// protects the contents of this._frame (when resizing) from interactions
// with the mouse (ex: IFRAME grabbing mouse capture in IE or Firefox)
this._lining = document.createElement('DIV');
this._lining.style.width = $common.getCurrentStyle(this._frame, 'width');
this._lining.style.height = $common.getCurrentStyle(this._frame, 'height');
this._lining.style.position = 'absolute';
this._lining.style.backgroundColor = 'black'; // Keeps browsers from ignoring the content-free element
this._lining.style.opacity = "0"; // Makes the lining invisible
this._lining.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=0)"; // Ditto, for IE
this._lining.style.visibility = 'hidden';
this._frame.insertBefore(this._lining, this._frame.firstChild);
// The this._handleHolder provedes a wrapper with absolute positioning
// so that this._handle can be absolutely positioned relative to the
// this._frame instead of the page
this._handleHolder = document.createElement('DIV');
this._handleHolder.style.width = '0px';
this._handleHolder.style.height = '0px';
this._handleHolder.style.position = ((Sys.Browser.agent === Sys.Browser.Opera) ? 'relative' : 'absolute');
this._frame.insertBefore(this._handleHolder, this._frame.firstChild);
// The this._handle represents the UI handle for the user to grab with
// the mouse
this._handle = document.createElement('DIV');
this._handle.className = this._handleCssClass;
this._handle.style.position = 'absolute';
this._handleHolder.appendChild(this._handle);
this._onmouseoverDelegate = Function.createDelegate(this, this._onmouseover);
$addHandler(this._handle, 'mouseover', this._onmouseoverDelegate);
this._onmouseoutDelegate = Function.createDelegate(this, this._onmouseout);
$addHandler(this._handle, 'mouseout', this._onmouseoutDelegate);
this._onmousedownDelegate = Function.createDelegate(this, this._onmousedown);
$addHandler(this._handle, 'mousedown', this._onmousedownDelegate);
this._onmousemoveDelegate = Function.createDelegate(this, this._onmousemove);
this._onmouseupDelegate = Function.createDelegate(this, this._onmouseup);
this._onselectstartDelegate = Function.createDelegate(this, this._onselectstart);
this._resizeControl(0, 0, 0, 0);
this._rememberSize();
},
dispose: function() {
if(this._onmouseoverDelegate) {
$removeHandler(this._handle, 'mouseover', this._onmouseoverDelegate);
this._onmouseoverDelegate = null;
}
if(this._onmouseoutDelegate) {
$removeHandler(this._handle, 'mouseout', this._onmouseoutDelegate);
this._onmouseoutDelegate = null;
}
if(this._onmousedownDelegate) {
$removeHandler(this._handle, 'mousedown', this._onmousedownDelegate);
this._onmousedownDelegate = null;
}
if(this._onmousemoveDelegate) {
if(this.tracking)
$removeHandler(document, 'mousemove', this._onmousemoveDelegate);
this._onmousemoveDelegate = null;
}
if(this._onmouseupDelegate) {
if(this.tracking)
$removeHandler(document, 'mouseup', this._onmouseupDelegate);
this._onmouseupDelegate = null;
}
if(this._onselectstartDelegate) {
if(this.tracking) {
$removeHandler(document, 'selectstart', this._onselectstartDelegate);
if(Sys.Browser.agent === Sys.Browser.Opera)
$removeHandler(document, 'mousedown', this._onselectstartDelegate);
}
this._onselectstartDelegate = null;
}
Sys.Extended.UI.ResizableControlBehavior.callBaseMethod(this, 'dispose');
},
_onmouseover: function() {
Sys.UI.DomElement.addCssClass(this._frame, this._resizableCssClass);
},
_onmouseout: function() {
if(!this._tracking)
Sys.UI.DomElement.removeCssClass(this._frame, this._resizableCssClass);
},
_onmousedown: function(e) {
// TODO: Fix for new event model
if(!e) e = event;
this._onmousedownImplementation(e.clientX, e.clientY);
},
_onmousedownImplementation: function(clientX, clientY) {
this._tracking = true;
this._resizeControl(clientX, clientY, 0, 0);
this._lining.style.visibility = 'visible'; // Overlay resizing control to avoid interacting with it (ex: IFRAME)
$addHandler(document, 'mousemove', this._onmousemoveDelegate);
$addHandler(document, 'mouseup', this._onmouseupDelegate);
$addHandler(document, 'selectstart', this._onselectstartDelegate);
if(Sys.Browser.agent === Sys.Browser.Opera)
$addHandler(document, 'mousedown', this._onselectstartDelegate);
this.raise_resizeBegin();
},
_onmousemove: function(e) {
// TODO: Fix for new event model
if(!e) e = event;
this._onmousemoveImplementation(e.clientX, e.clientY);
},
_onmousemoveImplementation: function(clientX, clientY) {
if(this._tracking) {
var deltaX = (clientX - this._lastClientX);
var deltaY = (clientY - this._lastClientY);
this._resizeControl(clientX, clientY, deltaX, deltaY);
}
},
_onmouseup: function() {
this._tracking = false;
this._rememberSize();
this._lining.style.visibility = 'hidden';
$removeHandler(document, 'mousemove', this._onmousemoveDelegate);
$removeHandler(document, 'mouseup', this._onmouseupDelegate);
$removeHandler(document, 'selectstart', this._onselectstartDelegate);
if(Sys.Browser.agent === Sys.Browser.Opera)
$removeHandler(document, 'mousedown', this._onselectstartDelegate);
Sys.UI.DomElement.removeCssClass(this._frame, this._resizableCssClass);
},
_onselectstart: function(e) {
// Don't allow selection during drag
e.preventDefault();
return false;
},
_resizeControl: function(clientX, clientY, deltaX, deltaY) {
// Save last client X/Y
this._lastClientX = clientX;
this._lastClientY = clientY;
// Calculate new lining/frame width/height
var _liningWidth = Math.min(Math.max(this._lining.offsetWidth + deltaX, Math.max(this._minimumWidth, this._handle.offsetWidth)), this._maximumWidth),
_liningHeight = Math.min(Math.max(this._lining.offsetHeight + deltaY, Math.max(this._minimumHeight, this._handle.offsetHeight)), this._maximumHeight);
// Set new lining/frame width/height
this._lining.style.width = _liningWidth + 'px';
this._lining.style.height = _liningHeight + 'px';
this._frame.style.width = _liningWidth + 'px';
this._frame.style.height = _liningHeight + 'px';
// Calculate new handle left/top
var _handleLeft = this._lining.offsetWidth - this._handle.offsetWidth + this._handleOffsetX,
_handleTop = this._lining.offsetHeight - this._handle.offsetHeight + this._handleOffsetY;
// Set new handle left/top
this._handle.style.left = _handleLeft + 'px';
this._handle.style.top = _handleTop + 'px';
// Raise the resizing event
this.raise_resizing();
},
_rememberSize: function() {
var size = this.get_size();
// save the size in ClientState
Sys.Extended.UI.ResizableControlBehavior.callBaseMethod(this, 'set_ClientState', [size.width + ',' + size.height]);
// Raise the resize event
this.raise_resize();
},
_measurementToNumber: function(m) {
// Get the magnitude of a measurement
// "m" - Measurement
// returns - magnitude of a measurement
return m.replace('px', '');
},
///
/// The name of the CSS class to apply to the resize handle
///
/// get_handleCssClass
/// set_handleCssClass
///
get_handleCssClass: function() {
return this._handleCssClass;
},
set_handleCssClass: function(value) {
if(this._handleCssClass)
throw String.format(Sys.Extended.UI.Resources.ResizableControlBehavior_CannotChangeProperty, 'handleCssClass');
this._handleCssClass = value;
this.raisePropertyChanged('handleCssClass');
},
get_HandleCssClass: function() {
Sys.Extended.Deprecated("get_HandleCssClass()", "get_handleCssClass()");
return this.get_handleCssClass();
},
set_HandleCssClass: function(value) {
Sys.Extended.Deprecated("set_HandleCssClass(value)", "set_handleCssClass(value)");
this.set_handleCssClass(value);
},
///
/// The name of the CSS class to apply to the element when resizing
///
/// get_resizableCssClass
/// set_resizableCssClass
///
get_resizableCssClass: function() {
return this._resizableCssClass;
},
set_resizableCssClass: function(value) {
if(this._resizableCssClass)
throw String.format(Sys.Extended.UI.Resources.ResizableControlBehavior_CannotChangeProperty, 'resizableCssClass');
this._resizableCssClass = value;
this.raisePropertyChanged('resizableCssClass');
},
get_ResizableCssClass: function() {
Sys.Extended.Deprecated("get_ResizableCssClass()", "get_resizableCssClass()");
return this.get_resizableCssClass();
},
set_ResizableCssClass: function(value) {
Sys.Extended.Deprecated("set_ResizableCssClass(value)", "set_resizableCssClass(value)");
this.set_resizableCssClass(value);
},
///
/// X-Offset to apply to the location of the resize handle
///
/// get_handleOffsetX
/// set_handleOffsetX
///
get_handleOffsetX: function() {
return this._handleOffsetX;
},
set_handleOffsetX: function(value) {
if(this._handleOffsetX != value) {
this._handleOffsetX = value;
this.raisePropertyChanged('handleOffsetX');
}
},
get_HandleOffsetX: function() {
Sys.Extended.Deprecated("get_HandleOffsetX()", "get_handleOffsetX()");
return this.get_handleOffsetX();
},
set_HandleOffsetX: function(value) {
Sys.Extended.Deprecated("set_HandleOffsetX(value)", "set_handleOffsetX(value)");
this.set_handleOffsetX(value);
},
///
/// Y-Offset to apply to the location of the resize handle
///
/// get_handleOffsetY
/// set_handleOffsetY
///
get_handleOffsetY: function() {
return this._handleOffsetY;
},
set_handleOffsetY: function(value) {
if(this._handleOffsetY != value) {
this._handleOffsetY = value;
this.raisePropertyChanged('handleOffsetY');
}
},
get_HandleOffsetY: function() {
Sys.Extended.Deprecated("get_HandleOffsetY()", "get_handleOffsetY()");
return this.get_handleOffsetY();
},
set_HandleOffsetY: function(value) {
Sys.Extended.Deprecated("set_HandleOffsetY(value)", "set_handleOffsetY(value)");
this.set_handleOffsetY(value);
},
///
/// Minimum width of the resizable element
///
/// get_minimumWidth
/// set_minimumWidth
///
get_minimumWidth: function() {
return this._minimumWidth;
},
set_minimumWidth: function(value) {
if(this._minimumWidth != value) {
this._minimumWidth = value;
this.raisePropertyChanged('minimumWidth');
}
},
get_MinimumWidth: function() {
Sys.Extended.Deprecated("get_MinimumWidth()", "get_minimumWidth()");
return this.get_minimumWidth();
},
set_MinimumWidth: function(value) {
Sys.Extended.Deprecated("set_MinimumWidth(value)", "set_minimumWidth(value)");
this.set_minimumWidth(value);
},
///
/// Minimum height of the resizable element
///
/// get_minimumHeight
/// set_minimumHeight
///
get_minimumHeight: function() {
return this._minimumHeight;
},
set_minimumHeight: function(value) {
if(this._minimumHeight != value) {
this._minimumHeight = value;
this.raisePropertyChanged('minimumHeight');
}
},
get_MinimumHeight: function() {
Sys.Extended.Deprecated("get_MinimumHeight()", "get_minimumHeight()");
return this.get_minimumHeight();
},
set_MinimumHeight: function(value) {
Sys.Extended.Deprecated("set_MinimumHeight(value)", "set_minimumHeight(value)");
this.set_minimumHeight(value);
},
///
/// Maximum width of the resizable element
///
/// get_maximumWidth
/// set_maximumWidth
///
get_maximumWidth: function() {
return this._maximumWidth;
},
set_maximumWidth: function(value) {
if(this._maximumWidth != value) {
this._maximumWidth = value;
this.raisePropertyChanged('maximumWidth');
}
},
get_MaximumWidth: function() {
Sys.Extended.Deprecated("get_MaximumWidth()", "get_maximumWidth()");
return this.get_maximumWidth();
},
set_MaximumWidth: function(value) {
Sys.Extended.Deprecated("set_MaximumWidth(value)", "set_maximumWidth(value)");
this.set_maximumWidth(value);
},
///
/// Maximum height of the resizable element
///
/// get_maximumHeight
/// set_maximumHeight
///
get_maximumHeight: function() {
return this._maximumHeight;
},
set_maximumHeight: function(value) {
if(this._maximumHeight != value) {
this._maximumHeight = value;
this.raisePropertyChanged('maximumHeight');
}
},
get_MaximumHeight: function() {
Sys.Extended.Deprecated("get_MaximumHeight()", "get_maximumHeight()");
return this.get_maximumHeight();
},
set_MaximumHeight: function(value) {
Sys.Extended.Deprecated("set_MaximumHeight(value)", "set_maximumHeight(value)");
this.set_maximumHeight(value);
},
///
/// Fires as the element is being resized
///
///
///
add_resizing: function(handler) {
this.get_events().addHandler("resizing", handler);
},
remove_resizing: function(handler) {
this.get_events().removeHandler("resizing", handler);
},
raise_resizing: function() {
var onResizingHandler = this.get_events().getHandler("resizing");
if(onResizingHandler)
onResizingHandler(this, Sys.EventArgs.Empty);
},
raiseResizing: function() {
Sys.Extended.Deprecated("raiseResizing()", "raise_resizing()");
this.raise_resizing();
},
///
/// The Resizing event handler
///
/// get_resizing
/// set_resizing
///
get_resizing: function() {
// Function to invoke on resizing (can a Function, name of a Function, or expression that evaluates to a Function)
return this.get_events().getHandler("resizing");
},
set_resizing: function(value) {
if(value && (0 < value.length)) {
var func = $common.resolveFunction(value);
if(func)
this.add_resizing(func);
else
throw Error.argumentType('value', typeof (value), 'Function', String.format(Sys.Extended.UI.Resources.ResizableControlBehavior_InvalidHandler, 'resizing'));
}
},
///
/// Fires when the element has been resized
///
///
///
add_resize: function(handler) {
this.get_events().addHandler("resize", handler);
},
remove_resize: function(handler) {
this.get_events().removeHandler("resize", handler);
},
raise_resize: function() {
var onResizeHandler = this.get_events().getHandler("resize");
if(onResizeHandler)
onResizeHandler(this, Sys.EventArgs.Empty);
},
raiseResize: function() {
Sys.Extended.Deprecated("raiseResize()", "raise_resize()");
this.raise_resize();
},
///
/// The Resize event handler
///
/// get_resize
/// set_resize
///
get_resize: function() {
// Function to invoke on resize (can be a Function, name of a Function, or expression that evaluates to a Function)
return this.get_events().getHandler("resize");
},
set_resize: function(value) {
if(value && (0 < value.length)) {
var func = $common.resolveFunction(value);
if(func)
this.add_resize(func);
else
throw Error.argumentType('value', typeof (value), 'Function', String.format(Sys.Extended.UI.Resources.ResizableControlBehavior_InvalidHandler, 'resize'));
}
},
///
/// Fires when the element starts being resized
///
///
///
add_resizeBegin: function(handler) {
this.get_events().addHandler("resizeBegin", handler);
},
remove_resizeBegin: function(handler) {
this.get_events().removeHandler("resizeBegin", handler);
},
raise_resizeBegin: function() {
var onResizeBeginHandler = this.get_events().getHandler("resizeBegin");
if(onResizeBeginHandler)
onResizeBeginHandler(this, Sys.EventArgs.Empty);
},
add_resizebegin: function(handler) {
Sys.Extended.Deprecated("add_resizebegin(handler)", "add_resizeBegin(handler)");
this.add_resizeBegin(handler);
},
remove_resizebegin: function(handler) {
Sys.Extended.Deprecated("remove_resizebegin(handler)", "remove_resizeBegin(handler)");
this.remove_resizeBegin(handler);
},
raiseResizeBegin: function() {
Sys.Extended.Deprecated("raiseResizeBegin()", "raise_resizeBegin()");
this.raise_resizeBegin();
},
///
/// The ResizeBegin event handler
///
/// get_resizeBegin
/// set_resizeBegin
///
get_resizeBegin: function() {
// Function to invoke on resizebegin (can be a Function, name of a Function, or expression that evaluates to a Function)
return this.get_events().getHandler("resizeBegin");
},
set_resizeBegin: function(value) {
if(value && (0 < value.length)) {
var func = $common.resolveFunction(value);
if(func)
this.add_resizeBegin(func);
else
throw Error.argumentType('value', typeof (value), 'Function', String.format(Sys.Extended.UI.Resources.ResizableControlBehavior_InvalidHandler, 'resizeBegin'));
}
},
get_resizebegin: function() {
Sys.Extended.Deprecated("get_resizebegin()", "get_resizeBegin()");
return this.get_resizeBegin();
},
set_resizebegin: function(value) {
Sys.Extended.Deprecated("set_resizebegin(value)", "set_resizeBegin(value)");
this.set_resizeBegin(value);
},
///
/// Size of the target (of the form {width, height})
///
/// get_size
/// set_size
///
get_size: function() {
return {
width: this._measurementToNumber($common.getCurrentStyle(this._lining, 'width')),
height: this._measurementToNumber($common.getCurrentStyle(this._lining, 'height'))
};
},
set_size: function(value) {
var deltaX = value.width - this._measurementToNumber($common.getCurrentStyle(this._lining, 'width')),
deltaY = value.height - this._measurementToNumber($common.getCurrentStyle(this._lining, 'height'));
this._resizeControl(0, 0, deltaX, deltaY);
this._rememberSize();
this.raisePropertyChanged('size');
},
get_Size: function() {
Sys.Extended.Deprecated("get_Size()", "get_size()");
return this.get_size();
},
set_Size: function(value) {
Sys.Extended.Deprecated("set_Size(value)", "set_size(value)");
this.set_size(value);
}
}
Sys.Extended.UI.ResizableControlBehavior.registerClass('Sys.Extended.UI.ResizableControlBehavior', Sys.Extended.UI.BehaviorBase);