incubator-flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cframp...@apache.org
Subject 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/...
Date Mon, 06 Aug 2012 21:26:02 GMT
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



Mime
View raw message