You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cf...@apache.org on 2012/08/06 23:26:02 UTC
svn commit: r1370028 [32/43] - in
/incubator/flex/whiteboard/cframpton/adobe.next: ./ frameworks/
frameworks/projects/advancedgrids/src/mx/collections/
frameworks/projects/advancedgrids/src/mx/controls/
frameworks/projects/airframework/src/mx/managers/...
Added: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateItemRenderer.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateItemRenderer.as?rev=1370028&view=auto
==============================================================================
--- incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateItemRenderer.as (added)
+++ incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateItemRenderer.as Mon Aug 6 21:25:54 2012
@@ -0,0 +1,825 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+
+package spark.components.calendarClasses
+{
+ import flash.display.DisplayObject;
+ import flash.events.Event;
+ import flash.geom.Point;
+ import flash.geom.Rectangle;
+
+ import mx.core.ILayoutDirectionElement;
+ import mx.core.IToolTip;
+ import mx.core.IUIComponent;
+ import mx.core.LayoutDirection;
+ import mx.core.mx_internal;
+ import mx.events.FlexEvent;
+ import mx.events.ToolTipEvent;
+ import mx.managers.ISystemManager;
+ import mx.managers.IToolTipManagerClient;
+ import mx.managers.ToolTipManager;
+ import mx.utils.PopUpUtil;
+
+ import spark.components.MonthGrid;
+ import spark.components.Group;
+ import spark.components.supportClasses.TextBase;
+
+ use namespace mx_internal;
+
+ //--------------------------------------
+ // Events
+ //--------------------------------------
+
+ /**
+ * Dispatched when the <code>data</code> property changes.
+ *
+ * @eventType mx.events.FlexEvent.DATA_CHANGE
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ [Event(name="dataChange", type="mx.events.FlexEvent")]
+
+ //--------------------------------------
+ // Excluded APIs
+ //--------------------------------------
+
+ [Exclude(name="transitions", kind="property")]
+
+ /**
+ * The DateItemRenderer class defines the base class for custom date item renderers
+ * for the Spark calendar control, DateChooser. It renders either one day of the week
+ * (e.g. M,T,W) or one day of the month (e.g. 1,2,3).
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public class DateItemRenderer extends Group implements IDateItemRenderer
+ {
+ include "../../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Static Methods
+ //
+ //--------------------------------------------------------------------------
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function DateItemRenderer()
+ {
+ super();
+
+ setCurrentStateNeeded = true;
+ accessibilityEnabled = false;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * True if the renderer has been created and commitProperties hasn't
+ * run yet. See commitProperties.
+ */
+ private var setCurrentStateNeeded:Boolean = false;
+
+ /**
+ * @private
+ * A flag determining if this renderer should play any
+ * associated transitions when a state change occurs.
+ */
+ mx_internal var playTransitions:Boolean = false;
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private function dispatchChangeEvent(type:String):void
+ {
+ if (hasEventListener(type))
+ dispatchEvent(new Event(type));
+ }
+
+ //----------------------------------
+ // baselinePosition override
+ //----------------------------------
+
+ /**
+ * @private
+ */
+ override public function get baselinePosition():Number
+ {
+ if (!validateBaselinePosition() || !labelDisplay)
+ return super.baselinePosition;
+
+ const labelPosition:Point = globalToLocal(labelDisplay.parent.localToGlobal(
+ new Point(labelDisplay.x, labelDisplay.y)));
+
+ return labelPosition.y + labelDisplay.baselinePosition;
+ }
+
+ //----------------------------------
+ // date
+ //----------------------------------
+
+ private var _date:Date = null;
+
+ /**
+ * @inheritDoc
+ *
+ * @default null
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get date():Date
+ {
+ return _data as Date;
+ }
+
+ //----------------------------------
+ // down
+ //----------------------------------
+
+ /**
+ * @private
+ * storage for the down property
+ */
+ private var _down:Boolean = false;
+
+ /**
+ * @inheritDoc
+ *
+ * @default false
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get down():Boolean
+ {
+ return _down;
+ }
+
+ /**
+ * @private
+ */
+ public function set down(value:Boolean):void
+ {
+ if (value == _down)
+ return;
+
+ _down = value;
+ setCurrentState(getCurrentRendererState(), playTransitions);
+ }
+
+ //----------------------------------
+ // dragging
+ //----------------------------------
+
+ private var _dragging:Boolean = false;
+
+ [Bindable("draggingChanged")]
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get dragging():Boolean
+ {
+ return _dragging;
+ }
+
+ /**
+ * @private
+ */
+ public function set dragging(value:Boolean):void
+ {
+ if (_dragging == value)
+ return;
+
+ _dragging = value;
+ setCurrentState(getCurrentRendererState(), playTransitions);
+ dispatchChangeEvent("draggingChanged");
+ }
+
+ //----------------------------------
+ // columnIndex
+ //----------------------------------
+
+ private var _columnIndex:int = -1;
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get columnIndex():int
+ {
+ return _columnIndex;
+ }
+
+ public function set columnIndex(value:int):void
+ {
+ _columnIndex = value;
+ }
+
+ //----------------------------------
+ // data
+ //----------------------------------
+
+ private var _data:Object = null;
+
+ [Bindable("dataChange")] // compatible with FlexEvent.DATA_CHANGE
+
+ /**
+ * The value of the data provider item for the grid row
+ * corresponding to the item renderer.
+ * This value corresponds to the object returned by a call to the
+ * <code>dataProvider.getItemAt(rowIndex)</code> method.
+ *
+ * <p>Item renderers can override this property definition to access
+ * the data for the entire row of the grid. </p>
+ *
+ * @default null
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get data():Object
+ {
+ return _data;
+ }
+
+ /**
+ * @private
+ */
+ public function set data(value:Object):void
+ {
+ if (_data == value)
+ return;
+
+ _data = value;
+
+ const eventType:String = "dataChange";
+ if (hasEventListener(eventType))
+ dispatchEvent(new FlexEvent(eventType));
+ }
+
+ //----------------------------------
+ // hovered
+ //----------------------------------
+
+ private var _hovered:Boolean = false;
+
+ /**
+ * @inheritDoc
+ *
+ * @default false
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get hovered():Boolean
+ {
+ return _hovered;
+ }
+
+ /**
+ * @private
+ */
+ public function set hovered(value:Boolean):void
+ {
+ if (value == _hovered)
+ return;
+
+ _hovered = value;
+ setCurrentState(getCurrentRendererState(), playTransitions);
+ }
+
+ //----------------------------------
+ // monthGrid
+ //----------------------------------
+
+ private var _monthGrid:MonthGrid = null;
+
+ [Bindable("monthGridChange")]
+
+ public function get monthGrid():MonthGrid
+ {
+ return _monthGrid;
+ }
+
+ /**
+ * @private
+ */
+ public function set monthGrid(value:MonthGrid):void
+ {
+ if (_monthGrid == value)
+ return;
+
+ _monthGrid = value;
+ }
+
+ //----------------------------------
+ // nextMonth
+ //----------------------------------
+
+ private var _nextMonth:Boolean = false;
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get nextMonth():Boolean
+ {
+ return _nextMonth;
+ }
+
+ public function set nextMonth(value:Boolean):void
+ {
+ _nextMonth = value;
+ }
+
+ //----------------------------------
+ // previousMonth
+ //----------------------------------
+
+ private var _previousMonth:Boolean = false;
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get previousMonth():Boolean
+ {
+ return _previousMonth;
+ }
+
+ public function set previousMonth(value:Boolean):void
+ {
+ _previousMonth = value;
+ }
+
+ //----------------------------------
+ // rowIndex
+ //----------------------------------
+
+ private var _rowIndex:int = -1;
+
+ [Bindable("rowIndexChanged")]
+
+ /**
+ * @inheritDoc
+ *
+ * <p>The Grid's <code>updateDisplayList()</code> method sets this property
+ * before calling <code>prepare()</code></p>.
+ *
+ * @default -1
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get rowIndex():int
+ {
+ return _rowIndex;
+ }
+
+ /**
+ * @private
+ */
+ public function set rowIndex(value:int):void
+ {
+ if (_rowIndex == value)
+ return;
+
+ _rowIndex = value;
+ dispatchChangeEvent("rowIndexChanged");
+ }
+
+ //----------------------------------
+ // selected
+ //----------------------------------
+
+ private var _selected:Boolean = false;
+
+ [Bindable("selectedChanged")]
+
+ /**
+ * @inheritDoc
+ *
+ * <p>The Grid's <code>updateDisplayList()</code> method sets this property
+ * before calling <code>preprare()</code></p>.
+ *
+ * @default false
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get selected():Boolean
+ {
+ return _selected;
+ }
+
+ /**
+ * @private
+ */
+ public function set selected(value:Boolean):void
+ {
+ if (_selected == value)
+ return;
+
+ _selected = value;
+ setCurrentState(getCurrentRendererState(), playTransitions);
+ dispatchChangeEvent("selectedChanged");
+ }
+
+ //----------------------------------
+ // showsCaret
+ //----------------------------------
+
+ private var _showsCaret:Boolean = false;
+
+ [Bindable("showsCaretChanged")]
+
+ /**
+ * @inheritDoc
+ *
+ * <p>The Grid's <code>updateDisplayList()</code> method sets this property
+ * before calling <code>preprare()</code></p>.
+ *
+ * @default false
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get showsCaret():Boolean
+ {
+ return _showsCaret;
+ }
+
+ /**
+ * @private
+ */
+ public function set showsCaret(value:Boolean):void
+ {
+ if (_showsCaret == value)
+ return;
+
+ _showsCaret = value;
+ setCurrentState(getCurrentRendererState(), playTransitions);
+ dispatchChangeEvent("labelDisplayChanged");
+ }
+
+ //----------------------------------
+ // today
+ //----------------------------------
+
+ private var _today:Boolean = false;
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get today():Boolean
+ {
+ return _today;
+ }
+
+ /**
+ * @private
+ */
+ public function set today(value:Boolean):void
+ {
+ if (_today == value)
+ return;
+
+ _today = value;
+ }
+
+ //----------------------------------
+ // weekDay
+ //----------------------------------
+
+ private var _weekDay:Boolean = false;
+
+ /**
+ * True if the day is not Saturday (day 6) or Sunday (day 0).
+ * Note there are a few locales which have a different definition of weekday.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get weekday():Boolean
+ {
+ return _weekDay;
+ }
+
+ /**
+ * @private
+ */
+ public function set weekday(value:Boolean):void
+ {
+ if (_weekDay == value)
+ return;
+
+ _weekDay = value;
+ }
+
+ //----------------------------------
+ // label
+ //----------------------------------
+
+ private var _label:String = "";
+
+ [Bindable("labelChanged")]
+
+ /**
+ * @copy IDateItemRenderer#label
+ *
+ * @default ""
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get label():String
+ {
+ return _label;
+ }
+
+ /**
+ * @private
+ */
+ public function set label(value:String):void
+ {
+ if (_label == value)
+ return;
+
+ _label = value;
+
+ if (labelDisplay)
+ labelDisplay.text = _label;
+
+ dispatchChangeEvent("labelChanged");
+ }
+
+ //----------------------------------
+ // labelDisplay
+ //----------------------------------
+
+ private var _labelDisplay:TextBase = null;
+
+ [Bindable("labelDisplayChanged")]
+
+ /**
+ * An optional visual component in the item renderer
+ * for displaying the <code>label</code> property.
+ * If you use this property to specify a visual component,
+ * the component's <code>text</code> property is kept synchronized
+ * with the item renderer's <code>label</code> property.
+ *
+ * @default null
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function get labelDisplay():TextBase
+ {
+ return _labelDisplay
+ }
+
+ /**
+ * @private
+ */
+ public function set labelDisplay(value:TextBase):void
+ {
+ if (_labelDisplay == value)
+ return;
+
+ _labelDisplay = value;
+ dispatchChangeEvent("labelDisplayChanged");
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods - ItemRenderer State Support
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Returns the name of the state to be applied to the renderer.
+ * For example, a basic item renderer returns the String "normal", "hovered",
+ * or "selected" to specify the renderer's state.
+ * If dealing with touch interactions (or mouse interactions where selection
+ * is ignored), "down" and "downAndSelected" can also be returned.
+ *
+ * <p>A subclass of GridItemRenderer must override this method to return a value
+ * if the behavior desired differs from the default behavior.</p>
+ *
+ * <p>In Flex 4.0, the 3 main states were "normal", "hovered", and "selected".
+ * In Flex 4.5, "down" and "downAndSelected" have been added.</p>
+ *
+ * <p>The full set of states supported (in order of precedence) are:
+ * <ul>
+ * <li>dragging</li>
+ * <li>downAndSelected</li>
+ * <li>selectedAndShowsCaret</li>
+ * <li>hoveredAndShowsCaret</li>
+ * <li>normalAndShowsCaret</li>
+ * <li>down</li>
+ * <li>selected</li>
+ * <li>hovered</li>
+ * <li>normal</li>
+ * </ul>
+ * </p>
+ *
+ * @return A String specifying the name of the state to apply to the renderer.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+
+ protected function getCurrentRendererState():String
+ {
+ // this code is pretty confusing without multi-dimensional states, but it's
+ // defined in order of precedence.
+
+ //if (dragging && hasState("dragging"))
+ // return "dragging";
+
+ //if (selected && down && hasState("downAndSelected"))
+ // return "downAndSelected";
+
+ if (selected && showsCaret && hasState("selectedAndShowsCaret"))
+ return "selectedAndShowsCaret";
+
+ if (hovered && showsCaret && hasState("hoveredAndShowsCaret"))
+ return "hoveredAndShowsCaret";
+
+ if (showsCaret && hasState("normalAndShowsCaret"))
+ return "normalAndShowsCaret";
+
+ //if (down && hasState("down"))
+ // return "down";
+
+ if (selected && hasState("selected"))
+ return "selected";
+
+ if (hovered && hasState("hovered"))
+ return "hovered";
+
+ if (hasState("normal"))
+ return "normal";
+
+ // If none of the above states are defined in the item renderer,
+ // we return null. This means the user-defined renderer
+ // will display but essentially be non-interactive visually.
+ return null;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden Methods
+ //
+ //--------------------------------------------------------------------------
+
+// override public function setLayoutBoundsPosition(x:Number, y:Number, postLayoutTransform:Boolean=true):void
+// {
+// trace("DateIR", date, "x", x, "y", y, "rowIndex", rowIndex, "colIndex", columnIndex);
+// super.setLayoutBoundsPosition(x, y, postLayoutTransform);
+// }
+
+ /**
+ * @private
+ */
+ override protected function commitProperties():void
+ {
+ super.commitProperties();
+
+ if (setCurrentStateNeeded)
+ {
+ setCurrentState(getCurrentRendererState(), playTransitions);
+ setCurrentStateNeeded = false;
+ }
+ }
+
+ /**
+ * @private
+ */
+ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+ {
+ super.updateDisplayList(width, height);
+ }
+
+ override public function toString():String
+ {
+ return "(" + rowIndex + "." + columnIndex + ") " + (date ? date.toLocaleString() : "") + " today=" + today + " weekDay=" + weekday + " selected=" + selected;
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function prepare(hasBeenRecycled:Boolean):void
+ {
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @langversion 3.0
+ * @playerversion Flash 10
+ * @playerversion AIR 2.5
+ * @productversion Flex 4.5
+ */
+ public function discard(willBeRecycled:Boolean):void
+ {
+ }
+ }
+}
\ No newline at end of file
Propchange: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateItemRenderer.as
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateItemRenderer.as
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateRange.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateRange.as?rev=1370028&view=auto
==============================================================================
--- incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateRange.as (added)
+++ incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateRange.as Mon Aug 6 21:25:54 2012
@@ -0,0 +1,722 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.components.calendarClasses
+{
+import flash.events.Event;
+import flash.events.EventDispatcher;
+
+import mx.core.mx_internal;
+import mx.events.FlexEvent;
+import mx.utils.ObjectUtil;
+
+import spark.components.DateChooser;
+import spark.components.calendarClasses.DateUtil;
+
+use namespace mx_internal;
+
+ //--------------------------------------
+ // Other metadata
+ //--------------------------------------
+
+ [DefaultProperty("requestedStartDate")]
+
+ /**
+ * The DateRange class defines a data structure
+ * used by the Spark date classes to represent a period of time. It can be used to
+ * represent dates. The time properties of each Date object are scrubbed, i.e. set to zeros.
+ *
+ * Usages:
+ * - a date (a single point in time)
+ * - a range of dates with an explicit start date and end date (startDate <= date <= endDate)
+ * - a start date and a delta of the number of days to the end date
+ * (ex. range is today to today + 3 days or today + -3 days)
+ * - all dates, before a given date (< startDate)
+ * - all dates, after a given date (> startDate)
+ *
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public class DateRange extends EventDispatcher
+ {
+ include "../../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Normalize the vector.
+ * Sort ranges.
+ * Look for intersections of adjacent ranges and combine ranges.
+ */
+ static public function normalizeDateRanges(dateRangeVector:Vector.<DateRange>):Vector.<DateRange>
+ {
+ // Return -1 if date1 < date2, 0 if equal, and 1 if date1 > date2 in sort order.
+ function sortFunction(date1:DateRange, date2:DateRange):Number
+ {
+ return DateUtil.dateCompare(date1.startDate, date2.startDate);
+ }
+
+ if (!dateRangeVector)
+ return null;
+
+ // Sort based on startDate.
+ dateRangeVector = dateRangeVector.sort(sortFunction);
+
+ // Combine overlapping and adjacent date ranges.
+ var i:int = 0;
+ while(i < dateRangeVector.length)
+ {
+ const previousItem:DateRange = i == 0 ? null : dateRangeVector[i-1];
+ const item:DateRange = dateRangeVector[i];
+ if (previousItem && (previousItem.intersects(item) || previousItem.adjacent(item)))
+ {
+ dateRangeVector[i - 1] = previousItem.union(item);
+ dateRangeVector.splice(i, 1);
+ }
+ else
+ {
+ i++;
+ }
+ }
+
+ return dateRangeVector;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * If you specify only <code>requestedStartDate</code>, then this range represents a
+ * single date.
+ * If you specify <code>requestedStartDate</code> and <code>requestedEndDate</code>, and
+ * code>requestedStartDate</code> is less than or equal to <code>requestedEndDate</code>,
+ * all dates between, and including, <code>requestedStartDate</code> and
+ * <code>requestedEndDate</code> will be included in the range.
+ *
+ * <p>You may also specify a range with a <code>requestedStartDate</code> and
+ * <code>deltaDays</code>.</p>
+ *
+ * <p>You may also limit the span of the range by setting <code>minDate</code> and/or
+ * <code>maxDate</code>. Use <code>startDate</code> and <code>endDate</code> to get
+ * the actual range.</p>
+ *
+ * @see #deltaDays
+ * @see #endDate
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function DateRange(requestedStartDate:Date=null, requestedEndDate:Date=null)
+ {
+ super();
+
+ if (requestedStartDate)
+ {
+ this.requestedStartDate = new Date(requestedStartDate.fullYear,
+ requestedStartDate.month,
+ requestedStartDate.date);
+ }
+ else
+ {
+ const now:Date = new Date();
+ this.requestedStartDate = new Date(now.fullYear, now.month, now.date);
+ }
+
+ if (requestedEndDate)
+ {
+ this.requestedEndDate = new Date(requestedEndDate.fullYear,
+ requestedEndDate.month,
+ requestedEndDate.date);
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ // Set to true to recalculate the start and end dates.
+ private var datesInRangeChanged:Boolean = true;
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+
+ //----------------------------------
+ // includeDatesAfterStartDate
+ //----------------------------------
+
+ // Removed by PARB to simplify the interface. Change minDate to startDate.
+
+ //----------------------------------
+ // includeDatesBeforeStartDate
+ //----------------------------------
+
+ // Removed by PARB to simplify the interface. Change maxDate to startDate.
+
+ //----------------------------------
+ // deltaDays
+ //----------------------------------
+
+ private var _deltaDays:int = 0;
+
+ [Bindable("deltaDaysChanged")]
+
+ /**
+ * If set, the range will be include all dates between <code>startDate</code> to
+ * <code>startDate</code> + <code>deltaDays</code>. If <code>deltaDays</code> is negative,
+ * the range extends from <code>startDate</code> - <code>deltaDays</code> to
+ * <code>startDate</code>.
+ *
+ * @default 0
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get deltaDays():int
+ {
+ return _deltaDays;
+ }
+
+ /**
+ * @private
+ */
+ public function set deltaDays(value:int):void
+ {
+ if (value == _deltaDays)
+ return;
+
+ resetEndDateProperties();
+
+ _deltaDays = value;
+ datesInRangeChanged = true;
+
+ dispatchChangeEvent("deltaDaysChanged");
+ }
+
+ //----------------------------------
+ // endDate
+ //----------------------------------
+
+ private var _endDate:Date;
+
+ /**
+ * The actual latest date in the range.
+ */
+ public function get endDate():Date
+ {
+ commitDateRange();
+
+ return new Date(_endDate.time);
+ }
+
+ //----------------------------------
+ // minDate
+ //----------------------------------
+
+ private var _minDate:Date = new Date(DateChooser.MIN_DATE_DEFAULT.time);
+
+ [Bindable("minDateChanged")]
+
+ /**
+ * The earliest date that can be included in the range.
+ * The earliest valid date is January 1, 1601.
+ *
+ * @default January 1, 1900
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get minDate():Date
+ {
+ return new Date(_minDate.time);
+ }
+
+ /**
+ * @private
+ */
+ public function set minDate(value:Date):void
+ {
+ if (_minDate == value)
+ return;
+
+ if (value == null || value.time < DateChooser.MIN_DATE.time)
+ value = new Date(DateChooser.MIN_DATE.time);
+
+ _minDate = value;
+ datesInRangeChanged = true;
+
+ dispatchChangeEvent("minDateChanged");
+ }
+
+ //----------------------------------
+ // maxDate
+ //----------------------------------
+
+ private var _maxDate:Date = new Date(DateChooser.MAX_DATE_DEFAULT.time);
+
+ [Bindable("maxDateChanged")]
+
+ /**
+ * The latest date that can be included in the range.
+ * The latest valid date is December 31, 9999.
+ *
+ * @default December 31, 2100
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get maxDate():Date
+ {
+ return new Date(_maxDate.time);
+ }
+
+ /**
+ * @private
+ */
+ public function set maxDate(value:Date):void
+ {
+ if (_maxDate == value)
+ return;
+
+ if (value == null || value.time > DateChooser.MAX_DATE.time)
+ value = new Date(DateChooser.MAX_DATE.time);
+
+ _maxDate = value;
+ datesInRangeChanged = true;
+
+ dispatchChangeEvent("maxDateChanged");
+ }
+
+ //----------------------------------
+ // requestedEndDate
+ //----------------------------------
+
+ private var _requestedEndDate:Date = null;
+
+ [Bindable("requestedEndDateChanged")]
+
+ /**
+ * If set, the range will be include all dates between, and including,
+ * <code>startDate</code> and <code>endDate</code>.
+ * <code>endDate</code> must be greater than or equal to <code>startDate</code>.
+ * This value may be adjusted for <code>maxDate</code>.
+ *
+ * @see #endDate
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get requestedEndDate():Date
+ {
+ return _requestedEndDate;
+ }
+
+ /**
+ * @private
+ */
+ public function set requestedEndDate(value:Date):void
+ {
+ if (value == _requestedEndDate)
+ return;
+
+ resetEndDateProperties();
+
+ _requestedEndDate = value ? new Date(value.fullYear, value.month, value.date) : null;
+ datesInRangeChanged = true;
+
+ dispatchChangeEvent("endDateChanged");
+ }
+
+ //----------------------------------
+ // requestedStartDate
+ //----------------------------------
+
+ private var _requestedStartDate:Date = null;
+
+ [Bindable("requestedStartDateChanged")]
+
+ /**
+ * The requested starting date for the range.
+ * This must be specified to have a valid range.
+ *
+ * @see #startDate
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get requestedStartDate():Date
+ {
+ return _requestedStartDate;
+ }
+
+ /**
+ * @private
+ */
+ public function set requestedStartDate(value:Date):void
+ {
+ if (value == _requestedStartDate)
+ return;
+
+ _requestedStartDate = value ? new Date(value.fullYear, value.month, value.date) : null;
+ datesInRangeChanged = true;
+
+ dispatchChangeEvent("startDateChanged");
+ }
+
+ //----------------------------------
+ // startDate
+ //----------------------------------
+
+ private var _startDate:Date;
+
+ /**
+ * The actual earliest date in the range.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function get startDate():Date
+ {
+ commitDateRange();
+
+ return new Date(_startDate.time);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden methods
+ //
+ //--------------------------------------------------------------------------
+
+ override public function toString():String
+ {
+ return "[DateRange" +
+ " startDate=" + startDate.toLocaleDateString() +
+ " endDate=" + endDate.toLocaleDateString() +
+ "]";
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Public Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Returns a new <code>DateRange</code> which is a copy of this.
+ *
+ * @return DateRange Returns a copy of this DateRange.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function clone():DateRange
+ {
+ var range:DateRange = new DateRange(_requestedStartDate);
+
+ range.requestedEndDate = _requestedEndDate;
+
+ range.deltaDays = _deltaDays;
+
+ return range;
+ }
+
+ /**
+ * Determines whether the date range specified by the <code>startDate</code>
+ * and <code>endDate</code> parameters is contained within this DateRange object.
+ *
+ * <p>The time properties in the <code>startDate</code> and <code>endDate</code> parameters
+ * are ignored when the comparison is done.</p>
+ *
+ * @param startDate The starting date of the range being checked.
+ * @param endDate The ending of the range being checked.
+ *
+ * @return true if the range that you specify is contained by this DateRange object;
+ * otherwise false.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function isRangeIncluded(startDate:Date, endDate:Date):Boolean
+ {
+ return isDateIncluded(startDate) && isDateIncluded(endDate);
+ }
+
+ /**
+ * Determines if the specified <code>date</code> is within this date range.
+ * The time value in the <code>date</code> object is ignored when the comparison is done.
+ *
+ * @param date The date to check.
+ *
+ * @return true if date is in this range
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function isDateIncluded(date:Date):Boolean
+ {
+ return ObjectUtil.dateCompare(startDate, date) <= 0 &&
+ ObjectUtil.dateCompare(endDate, date) >= 0;
+ }
+
+ /**
+ * Determines whether <code>dateRange</code> is adjacent to this
+ * DateRange object.
+ * Two ranges are adjacent if the start day of one range is the day after
+ * the last day of the other range.
+ *
+ * <p>The time properties in the <code>dateRange</code> parameter
+ * are ignored when the comparison is done.</p>
+ *
+ * @param dateRange The DateRange object to compare against this DateRange object.
+ *
+ * @return Boolean A value of true if the range that you specify is adjacent to this
+ * DateRange object; otherwise false.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function adjacent(dateRange:DateRange):Boolean
+ {
+ if (!dateRange)
+ return false;
+
+ // r1 has the earlier (or same) start date of the two ranges.
+ const r1:DateRange = DateUtil.dateCompare(startDate, dateRange.startDate) <= 0 ?
+ this : dateRange;
+ const r2:DateRange = DateUtil.dateCompare(startDate, dateRange.startDate) <= 0 ?
+ dateRange : this;
+
+ if (!r1.intersects(r2))
+ {
+ const nextDay:Date = new Date(r1.endDate.fullYear, r1.endDate.month, r1.endDate.date + 1);
+ return DateUtil.datesEqual(nextDay, r2.startDate);
+ }
+
+ return false;
+ }
+
+ /**
+ * Determines whether the date range <code>toInteresect</code> interesects this
+ * DateRange object.
+ *
+ * <p>The time properties in the <code>toIntersect</code> parameter is
+ * are ignored when the comparison is done.</p>
+ *
+ * @param toIntersect The DateRange object to compare against this DateRange object.
+ *
+ * @return Boolean A value of true if the range that you specify interesects this
+ * DateRange object; otherwise false.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function intersects(toIntersect:DateRange):Boolean
+ {
+ if (!toIntersect)
+ return false;
+
+ // r1 has the earlier (or same) start date of the two ranges.
+ const r1:DateRange = DateUtil.dateCompare(startDate, toIntersect.startDate) <= 0 ?
+ this : toIntersect;
+ const r2:DateRange = DateUtil.dateCompare(startDate, toIntersect.startDate) <= 0 ?
+ toIntersect : this;
+
+ // The ranges are ordered. If the 2nd range starts before the 1st range ends there
+ // is an intersection.
+ return r2.startDate <= r1.endDate;
+ }
+
+ /**
+ * If the DateRange object specified in the toIntersect parameter intersects with this
+ * DateRange object, returns the area of intersection as a DateRange object.
+ * If the DateRanges do not intersect, this method returns <code>null</code>.
+ *
+ * <p>The time properties in the <code>toIntersect</code> paraemeter is
+ * are ignored when the comparison is done.</p>
+ *
+ * @param toIntersect The DateRange object to compare against this DateRange object.
+ *
+ * @return DateRange A DateRange object that equals the area of intersection.
+ * If the DateRanges do not intersect, this method returns null.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function intersection(toIntersect:DateRange):DateRange
+ {
+ // The intersection is the later (or same) startDate and the earlier (or same) endDate
+ // and startDate is less than or equal the endDate.
+ const newStartDate:Date = DateUtil.dateCompare(startDate, toIntersect.startDate) >= 0 ?
+ startDate : toIntersect.startDate;
+
+ const newEndDate:Date = DateUtil.dateCompare(endDate, toIntersect.endDate) <= 0 ?
+ endDate : toIntersect.endDate;
+
+ return DateUtil.dateCompare(newStartDate, newEndDate) <= 0 ?
+ new DateRange(newStartDate, newEndDate) : null;
+ }
+
+ /**
+ * Adds two date ranges together to create a new DateRange object, by setting the
+ * <code>startDate</code> of the new range to the earlier start date of the two ranges and
+ * by setting the <code>endDate</code> of the new range to the later end date of the two
+ * ranges.
+ *
+ * <p>If <code>toUnion</code> is <code>null</code> the new DateRange will be the same
+ * as this DateRange.</p>
+ *
+ * <p>The time properties in the <code>startDate</code> and <code>endDate</code> parameters
+ * are ignored.</p>
+ *
+ * @param range The date range to union with this date range.
+ *
+ * @return DateRange A new DateRange object that is the union of the two date ranges.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function union(toUnion:DateRange):DateRange
+ {
+ if (!toUnion)
+ return new DateRange(startDate, endDate);
+
+ // Find the earliest start date.
+ var compareResult:int = DateUtil.dateCompare(startDate, toUnion.startDate);
+ const earliestStartDate:Date = compareResult <= 0 ? startDate : toUnion.startDate;
+
+ // Find the latest end date.
+ compareResult = DateUtil.dateCompare(endDate, toUnion.endDate);
+ const latestEndDate:Date = compareResult >= 0 ? endDate : toUnion.endDate;
+
+ return new DateRange(earliestStartDate, latestEndDate);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Private Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Only one of these properties should be set at a time.
+ */
+ private function resetEndDateProperties():void
+ {
+ _endDate = null;
+ _deltaDays = 0;
+ }
+
+ private function commitDateRange():void
+ {
+ if (!datesInRangeChanged)
+ return;
+
+ datesInRangeChanged = false;
+
+ _startDate = _requestedStartDate;
+
+ if (_requestedEndDate != null)
+ {
+ // FIXME: endDate < startDate
+ _endDate = _requestedEndDate;
+ }
+ else
+ {
+ var deltaDate:Date = new Date(
+ _requestedStartDate.fullYear, _requestedStartDate.month, _requestedStartDate.date + deltaDays,
+ _requestedStartDate.hours, _requestedStartDate.minutes, _requestedStartDate.seconds, _requestedStartDate.milliseconds);
+
+ if ( deltaDays >= 0)
+ {
+ _startDate = _requestedStartDate;
+ _endDate = deltaDate;
+ }
+ else
+ {
+ _startDate = deltaDate;
+ _endDate = _requestedStartDate;
+ }
+ }
+
+ // Check the range falls within the bounds.
+
+ if (minDate.time > maxDate.time)
+ minDate.time = maxDate.time;
+
+ if (_startDate.time < minDate.time)
+ _startDate.time = minDate.time;
+
+ if (_endDate.time > maxDate.time)
+ _endDate.time = maxDate.time;
+ }
+
+ /**
+ * @private
+ */
+ private function dispatchChangeEvent(type:String):void
+ {
+ if (hasEventListener(type))
+ dispatchEvent(new Event(type));
+ }
+ }
+}
\ No newline at end of file
Propchange: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateRange.as
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateRange.as
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateSelection.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateSelection.as?rev=1370028&view=auto
==============================================================================
--- incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateSelection.as (added)
+++ incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateSelection.as Mon Aug 6 21:25:54 2012
@@ -0,0 +1,627 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package spark.components.calendarClasses
+{
+import flash.geom.Rectangle;
+
+import mx.core.mx_internal;
+import mx.utils.ObjectUtil;
+
+import spark.components.calendarClasses.DateRange;
+import spark.components.supportClasses.Range;
+
+use namespace mx_internal;
+
+[ExcludeClass]
+
+/**
+ * Te DateSelection class tracks a date selector's set of selected date.
+ *
+ * @see spark.components.DateChooser
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+public class DateSelection
+{
+ include "../../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class variables
+ //
+ //--------------------------------------------------------------------------
+ /**
+ * The number of milliseconds in one day
+ */
+ public static const MILLISECONDS_IN_DAY : Number = 86400000;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3.0
+ * @productversion Flex 5.0
+ */
+ public function DateSelection()
+ {
+ super();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+
+ /**
+ * Ordered List of selected DateRanges. There should not be any overlapping
+ * ranges or contiguous ranges.
+ */
+ private var dateRanges:Vector.<DateRange> = new Vector.<DateRange>();
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // count
+ //----------------------------------
+
+ /**
+ * The number of selected ranges. A range can may contain one or more consecutive dates.
+ *
+ * @default 0
+ *
+ * @return Number of selected ranges.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function get count():int
+ {
+ return dateRanges.length;
+ }
+
+ //----------------------------------
+ // lastSelectedDate
+ //----------------------------------
+
+ private var _lastSelectedDate:Date = null;
+
+ /**
+ * The last date that was selected.
+ * If the last selection was a range this will be the last date in the range.
+ * This is reset if the selection is reset or a date is removed from the selection.
+ *
+ * @default null
+ *
+ * @return The last selected Date.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function get lastSelectedDate():Date
+ {
+ return _lastSelectedDate ? new Date(_lastSelectedDate.time) : null;
+ }
+
+ /**
+ * Returns a list of all the selected dates.
+ *
+ * @return Vector of selected dates or, if none are selected, a Vector of length 0.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function allDates():Vector.<Date>
+ {
+ var dateList:Vector.<Date> = new Vector.<Date>;
+
+ for each (var range:DateRange in dateRanges)
+ {
+ var nextDate:Date = new Date(range.startDate.getTime());
+ var endTime:Number = range.endDate.getTime();
+
+ while (nextDate.getTime() <= endTime)
+ {
+ dateList.push(new Date(nextDate.getTime()));
+ nextDate.date++;
+ }
+ }
+
+ return dateList;
+ }
+
+ /**
+ * Returns a list of all the selected date ranges.
+ *
+ * @return Vector of selected date ranges or, if none, a Vector of length 0.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function allDateRanges():Vector.<DateRange>
+ {
+ var rangeList:Vector.<DateRange> = new Vector.<DateRange>(0);
+
+ for each (var range:DateRange in dateRanges)
+ {
+ rangeList.push(range.clone());
+ }
+
+ return rangeList;
+ }
+
+ /**
+ * Removes the current selection.
+ *
+ * @return true if the list of selected items has changed.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function removeAll():Boolean
+ {
+ var selectionChanged:Boolean = count > 0;
+
+ dateRanges.length = 0;
+ _lastSelectedDate = null;
+
+ return selectionChanged;
+ }
+
+ /**
+ * Determines if the date is in the current selection.
+ *
+ * @param date The date.
+ *
+ * @return true if the date is in the selection.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function containsDate(date:Date):Boolean
+ {
+ if (date == null)
+ return false;
+
+ return isDateSelected(DateUtil.scrubTimeValue(date));
+ }
+
+ /**
+ * Determines if all the dates between <code>startDate</code> and <code>endDate</code,
+ * exclusive, are contained in the current selection.
+ * The <code>startDate</code> must be less than or equal to the <code>endDate/<code>.
+ *
+ * @param startDate The start date.
+ *
+ * @param endDate The end date.
+ *
+ * @return true if the dates are in the selection.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function containsDateRange(startDate:Date, endDate:Date):Boolean
+ {
+ if (!validateDateRange(startDate, endDate))
+ return false;
+
+ const scrubbedStartDate:Date = DateUtil.scrubTimeValue(startDate)
+ const scrubbedEndDate:Date = DateUtil.scrubTimeValue(endDate);
+
+ for each (var range:DateRange in dateRanges)
+ {
+ if (range.isRangeIncluded(scrubbedStartDate, scrubbedEndDate))
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Determines if all the dates between <code>startDate</code> and <code>endDate</code,
+ * exclusive, are the only dates contained in the current selection.
+ *
+ * @param startDate The start date.
+ *
+ * @param endDate The end date.
+ *
+ * @return true if the dates are the only dates in the selection.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function containsOnlyDateRange(startDate:Date, endDate:Date):Boolean
+ {
+ if (!validateDateRange(startDate, endDate))
+ return false;
+
+ const scrubbedStartDate:Date = DateUtil.scrubTimeValue(startDate)
+ const scrubbedEndDate:Date = DateUtil.scrubTimeValue(endDate);
+
+ if (dateRanges.length == 1)
+ {
+ var range:DateRange = dateRanges[0];
+ if (range.startDate.time == scrubbedStartDate.time &&
+ range.endDate.time == scrubbedEndDate.time)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Selects the given date.
+ *
+ * @param date The date to select.
+ *
+ * @return true if the date is selected.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function setDate(date:Date):Boolean
+ {
+ if (date == null)
+ return false;
+
+ internalSetDateRange(DateUtil.scrubTimeValue(date), DateUtil.scrubTimeValue(date));
+ _lastSelectedDate = date;
+
+ return true;
+ }
+
+ /**
+ * Adds the date to the selection.
+ *
+ * @param date The date to add to the selection.
+ *
+ * @return true if the date is added to the selection.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function addDate(date:Date):Boolean
+ {
+ if (date == null)
+ return false;
+
+ const changed:Boolean = internalAddDateRange(DateUtil.scrubTimeValue(date));
+ if (changed)
+ _lastSelectedDate = date;
+
+ return changed;
+ }
+
+ /**
+ * Removes the date from the selection.
+ *
+ * @param date The date to remove from the selection.
+ *
+ * @return true if the date is removed from the selection.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function removeDate(date:Date):Boolean
+ {
+ if (date == null)
+ return false;
+
+ const changed:Boolean = internalRemoveDate(DateUtil.scrubTimeValue(date));
+ if (changed)
+ _lastSelectedDate = null;
+
+ return changed;
+ }
+
+ /**
+ * Sets the selection to the dates between <code>startDate</code> and <code>endDate</code>,
+ * inclusive.
+ *
+ * @param startDate The earliest date in the selection.
+ *
+ * @param endDate The latest date in the selection.
+ *
+ * @return true if the selection is set to the dates in the range.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function setDateRange(startDate:Date, endDate:Date):Boolean
+ {
+ // This assumes caller checks whether dates are selectable.
+
+ if (!validateDateRange(startDate, endDate))
+ return false;
+
+ dateRanges.length = 0;
+
+ const changed:Boolean =
+ internalAddDateRange(DateUtil.scrubTimeValue(startDate),
+ DateUtil.scrubTimeValue(endDate));
+
+ if (changed)
+ _lastSelectedDate = endDate;
+
+ return changed;
+ }
+
+ /**
+ * Adds the dates between <code>startDate</code> and <code>endDate</code>,
+ * inclusive, to the selection.
+ *
+ * @param startDate The earliest date in the selection.
+ *
+ * @param endDate The latest date in the selection.
+ *
+ * @return true if the dates in the range are added to the selection.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 11
+ * @playerversion AIR 3
+ * @productversion Flex 5.0
+ */
+ public function addDateRange(startDate:Date, endDate:Date):Boolean
+ {
+ // This assumes caller checks whether dates are selectable.
+
+ if (!validateDateRange(startDate, endDate))
+ return false;
+
+ const changed:Boolean =
+ internalAddDateRange(DateUtil.scrubTimeValue(startDate),
+ DateUtil.scrubTimeValue(endDate));
+ if (changed)
+ _lastSelectedDate = endDate;
+
+ return changed;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Check the range. Both start and end dates must be specified and
+ * startDate <= endDate.
+ */
+ protected function validateDateRange(startDate:Date, endDate:Date):Boolean
+ {
+ return (startDate && endDate && DateUtil.dateCompare(startDate, endDate) != 1);
+ }
+
+ /**
+ * True if the given date is contained in the list of selected dates.
+ */
+ private function isDateSelected(date:Date):Boolean
+ {
+ // This assumes times are are scrubbed.
+
+ for each (var range:DateRange in dateRanges)
+ {
+ if (range.isDateIncluded(date))
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @private
+ * Initalize the list of dateRanges with this one.
+ */
+ private function internalSetDateRange(startDate:Date, endDate:Date):void
+ {
+ // This assumes times are scrubbed.
+
+ dateRanges.length = 0;
+ dateRanges.push(new DateRange(startDate, endDate));
+ }
+
+ /**
+ * Adds the range to the selection. Overlapping and continguous ranges are combined.
+ */
+ private function internalAddDateRange(startDate:Date, endDate:Date=null):Boolean
+ {
+ // Assumes the time values have been scrubbed.
+
+ if (endDate == null)
+ endDate = startDate;
+
+ var newRange:DateRange;
+ var previousRange:DateRange;
+ var range:DateRange;
+
+ // Find the insertion point based on start date.
+
+ for (var i:int = 0; i < dateRanges.length; i++)
+ {
+ range = dateRanges[i];
+
+ if (range.isRangeIncluded(startDate, endDate))
+ return false;
+
+ // The new entry belongs here.
+ if (startDate.time <= range.startDate.time)
+ break;
+
+ previousRange = range;
+ }
+
+ // If this range overlaps or is adjacent to the previous range,
+ // just extend the previous range.
+ if (previousRange &&
+ (previousRange.endDate.time >= startDate.time ||
+ previousRange.endDate.time + MILLISECONDS_IN_DAY == startDate.time))
+ {
+ newRange = previousRange;
+ newRange.requestedEndDate = endDate;
+ // i is already at the next entry
+ }
+ else
+ {
+ // Insert this range.
+ newRange = new DateRange(startDate, endDate);
+ dateRanges.splice(i, 0, newRange);
+ i++;
+ }
+
+ // Look at the remaining entries for overlaps/intersections and adjacencies. As soon as
+ // there aren't any, we're done.
+ for (i = i; i < dateRanges.length; )
+ {
+ range = dateRanges[i];
+
+ if (newRange.isRangeIncluded(range.startDate, range.endDate))
+ {
+ // remove this range since it is contained in newRange
+ dateRanges.splice(i, 1);
+ }
+ else if (newRange.intersects(range))
+ {
+ // combine newRange and this range and remove this range
+ if (ObjectUtil.dateCompare(newRange.endDate, range.endDate) < 0)
+ newRange.requestedEndDate = range.endDate;
+ dateRanges.splice(i, 1);
+ }
+ else if (newRange.endDate.time + MILLISECONDS_IN_DAY == range.startDate.time)
+ {
+ // new range is before and adjacent to existing range so combine them in newRange
+ // and remove this range
+ newRange.requestedEndDate = range.endDate;
+ dateRanges.splice(i, 1);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @private
+ * Remove the given date from the list of dateRanges.
+ */
+ private function internalRemoveDate(date:Date):Boolean
+ {
+ // Assumes the time values have been scrubbed.
+
+ var dateRangesLength:int = dateRanges.length;
+ for (var i:int = 0; i < dateRangesLength; i++)
+ {
+ var range:DateRange = dateRanges[i];
+
+ // Ranges sorted by start time. If range start time greater than date it means the
+ // date isn't in the selection.
+ if (ObjectUtil.dateCompare(range.startDate, date) > 0)
+ break;
+
+ // Date not in this range.
+ if (!range.isDateIncluded(date))
+ continue;
+
+ // Ok, we know the date is in this range.
+
+ if (ObjectUtil.dateCompare(range.startDate, date) == 0)
+ {
+ if (ObjectUtil.dateCompare(range.startDate, range.endDate) == 0)
+ {
+ // Single date. Removing date means removing range.
+ dateRanges.splice(i, 1);
+ return true;
+ }
+ else
+ {
+ // Move range start to the next day. Position of range in list not changed.
+ range.requestedStartDate = new Date(range.startDate.time + MILLISECONDS_IN_DAY);
+ return true;
+ }
+ }
+ else if (ObjectUtil.dateCompare(range.endDate, date) == 0)
+ {
+ // Move range end back one day. Position of range in list not changed.
+ range.requestedEndDate = new Date(range.endDate.time - MILLISECONDS_IN_DAY);
+ return true;
+ }
+ else
+ {
+ // Remove date from the middle of the range. Split range into two ranges.
+ var newStartDate:Date = new Date(date);
+ newStartDate.date++;
+ var newRange:DateRange = new DateRange(newStartDate, range.endDate);
+
+ date.date--;
+ range.requestedEndDate = date;
+
+ // Insert the new range after this range.
+ dateRanges.splice(i + 1, 0, newRange);
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
+}
Propchange: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateSelection.as
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/flex/whiteboard/cframpton/adobe.next/frameworks/projects/spark/src/spark/components/calendarClasses/DateSelection.as
------------------------------------------------------------------------------
svn:mime-type = text/plain