blob: cf6037eabef16f9a71fdb2809d6e30cc8303468e [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// 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 mx.controls
{
import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventPhase;
import flash.events.KeyboardEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.text.TextFormat;
import flash.ui.Keyboard;
import flash.utils.getQualifiedClassName;
import mx.core.FlexSprite;
import mx.core.FlexVersion;
import mx.core.IFlexModuleFactory;
import mx.core.IFontContextComponent;
import mx.core.IUITextField;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.core.mx_internal;
import mx.events.CalendarLayoutChangeEvent;
import mx.events.DateChooserEvent;
import mx.events.FlexEvent;
import mx.graphics.RectangularDropShadow;
import mx.managers.IFocusManagerComponent;
import mx.styles.StyleManager;
import mx.styles.StyleProxy;
import mx.utils.GraphicsUtil;
use namespace mx_internal;
//--------------------------------------
// Events
//--------------------------------------
/**
* Dispatched when a date is selected or changed.
*
* @eventType mx.events.CalendarLayoutChangeEvent.CHANGE
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Event(name="change", type="mx.events.CalendarLayoutChangeEvent")]
/**
* Dispatched when the month changes due to user interaction.
*
* @eventType mx.events.DateChooserEvent.SCROLL
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Event(name="scroll", type="mx.events.DateChooserEvent")]
//--------------------------------------
// Styles
//--------------------------------------
include "../styles/metadata/FocusStyles.as"
include "../styles/metadata/GapStyles.as"
include "../styles/metadata/IconColorStyles.as"
include "../styles/metadata/LeadingStyle.as"
include "../styles/metadata/TextStyles.as"
/**
* Alpha level of the color defined by the <code>backgroundColor</code>
* property.
* Valid values range from 0.0 to 1.0.
* @default 1.0
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="backgroundAlpha", type="Number", inherit="no", theme="halo")]
/**
* Background color of the DateChooser control.
*
* @default 0xFFFFF
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="backgroundColor", type="uint", format="Color", inherit="no", theme="halo")]
/**
* Alpha of the border.
* @default 1
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="borderAlpha", type="Number", inherit="no", theme="spark")]
/**
* Color of the border.
* The following controls support this style: Button, CheckBox,
* ComboBox, MenuBar,
* NumericStepper, ProgressBar, RadioButton, ScrollBar, Slider, and any
* components that support the <code>borderStyle</code> style.
* The default value depends on the component class;
* if not overridden for the class, the default value is <code>0xB7BABC</code>
* for the Halo theme and <code>0x696969</code> for the Spark theme.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="borderColor", type="uint", format="Color", inherit="no", theme="halo, spark")]
/**
* Bounding box thickness.
* Only used when <code>borderStyle</code> is set to <code>"solid"</code>.
* @default 1
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="borderThickness", type="Number", format="Length", inherit="no", theme="halo")]
/**
* Visibility of the border.
*
* @default 1
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="borderVisible", type="Boolean", inherit="no", theme="spark")]
/**
* The alpha of the content background for this component.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="contentBackgroundAlpha", type="Number", inherit="yes", theme="spark")]
/**
* Color of the content area of the component.
*
* @default 0xFFFFFF
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="contentBackgroundColor", type="uint", format="Color", inherit="yes", theme="spark")]
/**
* Radius of corners of the component.
*
* The default value for the Halo theme is <code>4</code>.
* The default value for the Spark theme is <code>0</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="cornerRadius", type="Number", format="Length", inherit="no", theme="halo, spark")]
/**
* Color of focus ring when the component is in focus
*
* @default 0x70B2EE
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="focusColor", type="uint", format="Color", inherit="yes", theme="spark")]
/**
* Colors of the band at the top of the DateChooser control.
* The default value is <code>[ 0xE1E5EB, 0xF4F5F7 ]</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="headerColors", type="Array", arrayType="uint", format="Color", inherit="yes", theme="halo, spark")]
/**
* Name of the style sheet definition to configure the text (month name and year)
* and appearance of the header area of the control.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="headerStyleName", type="String", inherit="no")]
/**
* Alpha transparencies used for the highlight fill of controls.
* The first value specifies the transparency of the top of the highlight and the second value specifies the transparency
* of the bottom of the highlight. The highlight covers the top half of the skin.
*
* @default [ 0.3, 0.0 ]
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="highlightAlphas", type="Array", arrayType="Number", inherit="no", theme="halo")]
/**
* Name of the class to use as the skin for the next month arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextMonthSkin", type="Class", inherit="no", states="up, over, down, disabled")]
/**
* Name of the class to use as the skin for the next month arrow
* when the arrow is disabled.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextMonthDisabledSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the next month arrow
* when the user presses the mouse button down on the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextMonthDownSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the next month arrow
* when the user moves the mouse pointer over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextMonthOverSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the next month arrow
* when the mouse pointer is not over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextMonthUpSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the next year arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextYearSkin", type="Class", inherit="no", states="up, over, down, disabled")]
/**
* Name of the class to use as the skin for the next year arrow
* when the arrow is disabled.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextYearDisabledSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the next Year arrow
* when the user presses the mouse button down on the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextYearDownSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the next Year arrow
* when the user moves the mouse pointer over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextYearOverSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the next Year arrow
* when the mouse pointer is not over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserNextYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="nextYearUpSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the previous month arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevMonthSkin", type="Class", inherit="no", states="up, over, down, disabled")]
/**
* Name of the class to use as the skin for the previous month arrow
* when the arrow is disabled.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevMonthDisabledSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the previous month arrow
* when the user presses the mouse button down over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevMonthDownSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the previous month arrow
* when the user holds the mouse pointer over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevMonthOverSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the previous month arrow
* when the mouse pointer is not over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserMonthArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevMonthSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevMonthUpSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the previous year arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevYearSkin", type="Class", inherit="no", states="up, over, down, disabled")]
/**
* Name of the class to use as the skin for the previous Year arrow
* when the arrow is disabled.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevYearDisabledSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the previous Year arrow
* when the user presses the mouse button down over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevYearDownSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the previous Year arrow
* when the user holds the mouse pointer over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevYearOverSkin", type="Class", inherit="no")]
/**
* Name of the class to use as the skin for the previous Year arrow
* when the mouse button not over the arrow.
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserYearArrowSkin</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserPrevYearSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="prevYearUpSkin", type="Class", inherit="no")]
/**
* Color of the highlight area of the date when the user holds the
* mouse pointer over a date in the DateChooser control.
*
* The default value for the Halo theme is <code>0xB2E1FF</code>.
* The default value for the Spark theme is <code>0xCEDBEF</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="rollOverColor", type="uint", format="Color", inherit="yes")]
/**
* Name of the class to use as the skin for the
* highlight area of the date when the user holds the
* mouse pointer over a date in the DateChooser control.
*
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserIndicator</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserRollOverIndicatorSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="rollOverIndicatorSkin", type="Class", inherit="no")]
/**
* Color of the highlight area of the currently selected date
* in the DateChooser control.
*
* The default value for the Halo theme is <code>0x7FCEFF</code>.
* The default value for the Spark theme is <code>0xA8C6EE</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="selectionColor", type="uint", format="Color", inherit="yes")]
/**
* Name of the class to use as the skin for the
* highlight area of the currently selected date
* in the DateChooser control.
*
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserIndicator</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserSelectionIndicatorSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="selectionIndicatorSkin", type="Class", inherit="no")]
/**
* Color of any symbol of a component. Examples include the check mark of a CheckBox or
* the arrow of a ScrollBar button.
*
* @default 0x000000
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="symbolColor", type="uint", format="Color", inherit="yes", theme="spark")]
/**
* Color of the background of today's date.
*
* The default value for the Halo theme is <code>0x818181</code>
* The default value for the Spark theme is <code>0xC6D0DB</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="todayColor", type="uint", format="Color", inherit="yes", theme="halo, spark")]
/**
* Name of the class to use as the skin for the
* highlight area of today's date
* in the DateChooser control.
*
* The default value for the Halo theme is <code>mx.skins.halo.DateChooserIndicator</code>.
* The default value for the Spark theme is <code>mx.skins.spark.DateChooserTodayIndicatorSkin</code>.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="todayIndicatorSkin", type="Class", inherit="no")]
/**
* Name of the style sheet definition to configure the appearance of the current day's
* numeric text, which is highlighted
* in the control when the <code>showToday</code> property is <code>true</code>.
* Specify a "color" style to change the font color.
* If omitted, the current day text inherits
* the text styles of the control.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="todayStyleName", type="String", inherit="no")]
/**
* Name of the style sheet definition to configure the weekday names of
* the control. If omitted, the weekday names inherit the text
* styles of the control.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Style(name="weekDayStyleName", type="String", inherit="no")]
//--------------------------------------
// Other metadata
//--------------------------------------
[AccessibilityClass(implementation="mx.accessibility.DateChooserAccImpl")]
[DefaultBindingProperty(source="selectedDate", destination="selectedDate")]
[DefaultTriggerEvent("change")]
[IconFile("DateChooser.png")]
[RequiresDataBinding(true)]
[ResourceBundle("controls")]
[ResourceBundle("SharedResources")]
/**
* The DateChooser control displays the name of a month, the year,
* and a grid of the days of the month, with columns labeled
* for the day of the week.
* The user can select a date, a range of dates, or multiple dates.
* The control contains forward and back arrow buttons
* for changing the month and year.
* You can let users select multiple dates, disable the selection
* of certain dates, and limit the display to a range of dates.
*
* <p>The DateChooser control has the following default characteristics:</p>
* <table class="innertable">
* <tr>
* <th>Characteristic</th>
* <th>Description</th>
* </tr>
* <tr>
* <td>Default size</td>
* <td>A size large enough to hold the calendar, and wide enough to display the day names</td>
* </tr>
* <tr>
* <td>Minimum size</td>
* <td>0 pixels</td>
* </tr>
* <tr>
* <td>Maximum size</td>
* <td>No limit</td>
* </tr>
* </table>
*
* @mxml
*
* <p>The <code>&lt;mx:DateChooser&gt;</code> tag inherits all of the tag attributes
* of its superclass, and adds the following tag attributes:</p>
*
* <pre>
* &lt;mx:DateChooser
* <strong>Properties</strong>
* allowDisjointSelection="true|false"
* allowMultipleSelection="false|true"
* dayNames="["S", "M", "T", "W", "T", "F", "S"]"
* disabledDays="<i>No default</i>"
* disabledRanges="<i>No default</i>"
* displayedMonth="<i>Current month</i>"
* displayedYear="<i>Current year</i>"
* firstDayOfWeek="0"
* maxYear="2100"
* minYear="1900"
* monthNames="["January", "February", "March", "April", "May",
* "June", "July", "August", "September", "October", "November",
* "December"]"
* monthSymbol=""
* selectableRange="<i>No default</i>"
* selectedDate="<i>No default</i>"
* selectedRanges="<i>No default</i>"
* showToday="true|false"
* yearNavigationEnabled="false|true"
* yearSymbol=""
*
* <strong>Styles</strong>
* backgroundColor="0xFFFFFF"
* backgroundAlpha="1.0"
* borderColor="0xAAB3B3"
* borderThickness="1"
* color="0x0B333C"
* cornerRadius="4"
* disabledColor="0xAAB3B3"
* disabledIconColor="0x999999"
* fillAlphas="[0.6, 0.4]"
* fillColors="[0xFFFFFF, 0xCCCCCC]"
* focusAlpha="0.5"
* focusRoundedCorners"tl tr bl br"
* fontAntiAliasType="advanced"
* fontFamily="Verdana"
* fontGridFitType="pixel"
* fontSharpness="0"
* fontSize="10"
* fontStyle="normal|italic"
* fontThickness="0"
* fontWeight="normal|bold"
* headerColors="[0xE1E5EB, 0xF4F5F7]"
* headerStyleName="headerDateText"
* highlightAlphas="[0.3, 0.0]"
* horizontalGap="8"
* iconColor="0x111111"
* leading="2"
* nextMonthDisabledSkin="DateChooserMonthArrowSkin"
* nextMonthDownSkin="DateChooserMonthArrowSkin"
* nextMonthOverSkin="DateChooserMonthArrowSkin"
* nextMonthSkin = "DateChooserMonthArrowSkin"
* nextMonthUpSkin="DateChooserMonthArrowSkin"
* nextYearDisabledSkin="DateChooserYearArrowSkin"
* nextYearDownSkin="DateChooserYearArrowSkin"
* nextYearOverSkin="DateChooserYearArrowSkin"
* nextYearSkin = "DateChooserYearArrowSkin"
* nextYearUpSkin="DateChooserYearArrowSkin"
* prevMonthDisabledSkin="DateChooserMonthArrowSkin"
* prevMonthDownSkin="DateChooserMonthArrowSkin"
* prevMonthOverSkin="DateChooserMonthArrowSkin"
* prevMonthSkin = "DateChooserMonthArrowSkin"
* prevMonthUpSkin="DateChooserMonthArrowSkin"
* prevYearDisabledSkin="DateChooserYearArrowSkin"
* prevYearDownSkin="DateChooserYearArrowSkin"
* prevYearOverSkin="DateChooserYearArrowSkin"
* prevYearSkin = "DateChooserYearArrowSkin"
* prevYearUpSkin="DateChooserYearArrowSkin"
* rollOverColor="0xEEFEE6"
* rollOverIndicatorSkin="DateChooserIndicator"
* selectionColor="0xB7F39B"
* selectionIndicatorSkin="DateChooserIndicator"
* textAlign="left|right|center"
* textDecoration="none|underline"
* textIndent="0"
* todayColor="0x818181"
* todayIndicatorSkin="DateChooserIndicator"
* todayStyleName="todayStyle"
* verticalGap="6"
* weekDayStyleName="weekDayStyle"
*
* <strong>Events</strong>
* change="<i>No default</i>"
* scroll="<i>No default</i>"
* /&gt;
* </pre>
*
* @see mx.controls.DateField
*
* @includeExample examples/DateChooserExample.mxml
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public class DateChooser extends UIComponent implements IFocusManagerComponent, IFontContextComponent
{
include "../core/Version.as";
//--------------------------------------------------------------------------
//
// Class constants
//
//--------------------------------------------------------------------------
/**
* @private
*/
private var HEADER_WIDTH_PAD:Number = 5;
/**
* @private
* Width pad month skins
*/
private var SKIN_WIDTH_PAD:Number = 6;
/**
* @private
*/
private var SKIN_HEIGHT_PAD:Number = 4;
/**
* @private
* Padding between buttons and also at the sides.
*/
private var YEAR_BUTTONS_PAD:Number = 6;
//--------------------------------------------------------------------------
//
// Class mixins
//
//--------------------------------------------------------------------------
/**
* @private
* Placeholder for mixin by DateChooserAccImpl.
*/
mx_internal static var createAccessibilityImplementation:Function;
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function DateChooser()
{
super();
tabEnabled = true;
tabFocusEnabled = true;
tabChildren = false;
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
mx_internal var background:UIComponent;
/**
* @private
*/
mx_internal var border:UIComponent;
/**
* @private
*/
mx_internal var headerDisplay:UIComponent;
/**
* @private
* The internal UITextField that displays
* the currently visible month and year.
*/
mx_internal var monthDisplay:IUITextField;
/**
* @private
*/
mx_internal var fwdMonthHit:Sprite;
/**
* @private
*/
mx_internal var backMonthHit:Sprite;
/**
* @private
*/
mx_internal var upYearHit:Sprite;
/**
* @private
*/
mx_internal var downYearHit:Sprite;
/**
* @private
*/
mx_internal var calHeader:UIComponent;
/**
* @private
*/
mx_internal var yearDisplay:IUITextField;
/**
* @private
* The internal Button which, when clicked,
* makes the DateChooser display the next year.
*/
mx_internal var upYearButton:Button;
/**
* @private
* The internal Button which, when clicked,
* makes the DateChooser display the previous year.
*/
mx_internal var downYearButton:Button;
/**
* @private
* The internal Button which, when clicked,
* makes the DateChooser display the next month.
*/
mx_internal var fwdMonthButton:Button;
/**
* @private
* The internal Button which, when clicked,
* makes the DateChooser display the previous month.
*/
mx_internal var backMonthButton:Button;
/**
* @private
* The internal CalendarLayout that displays the grid of dates.
*/
mx_internal var dateGrid:CalendarLayout;
/**
* @private
*/
mx_internal var dropShadow:RectangularDropShadow;
/**
* @private
*/
private var previousSelectedCellIndex:Number = NaN;
/**
* @private
*/
private var monthSkinWidth:Number = 6;
/**
* @private
*/
private var monthSkinHeight:Number = 11;
/**
* @private
*/
private var yearSkinWidth:Number = 10;
/**
* @private
*/
private var yearSkinHeight:Number = 8;
/**
* @private
*/
private var headerHeight:Number = 30;
//--------------------------------------------------------------------------
//
// Overridden properties
//
//--------------------------------------------------------------------------
//----------------------------------
// baselinePosition
//----------------------------------
/**
* @private
* The baselinePosition of a DateChooser is calculated
* for its month/year text.
*/
override public function get baselinePosition():Number
{
if (!validateBaselinePosition())
return NaN;
return monthDisplay.y + monthDisplay.baselinePosition;
}
//----------------------------------
// enabled
//----------------------------------
/**
* @private
* Storage for the enabled property.
*/
private var _enabled:Boolean = true;
/**
* @private
*/
private var enabledChanged:Boolean = false;
[Bindable("enabledChanged")]
[Inspectable(category="General", enumeration="true,false", defaultValue="true")]
/**
* @private
*/
override public function get enabled():Boolean
{
return _enabled;
}
/**
* @private
*/
override public function set enabled(value:Boolean):void
{
if (value == _enabled)
return;
_enabled = value;
super.enabled = value;
enabledChanged = true;
invalidateProperties();
}
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// allowDisjointSelection
//----------------------------------
/**
* @private
* Storage for the allowDisjointSelection property.
*/
private var _allowDisjointSelection:Boolean = true;
/**
* @private
*/
private var allowDisjointSelectionChanged:Boolean = false;
[Bindable("allowDisjointSelectionChanged")]
[Inspectable(category="General", defaultValue="true")]
/**
* If <code>true</code>, specifies that non-contiguous(disjoint)
* selection is allowed in the DateChooser control.
* This property has an effect only if the
* <code>allowMultipleSelection</code> property is <code>true</code>.
* Setting this property changes the appearance of the
* DateChooser control.
*
* @default true;
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get allowDisjointSelection():Boolean
{
return _allowDisjointSelection;
}
/**
* @private
*/
public function set allowDisjointSelection(value:Boolean):void
{
_allowDisjointSelection = value;
allowDisjointSelectionChanged = true;
invalidateProperties();
}
//----------------------------------
// allowMultipleSelection
//----------------------------------
/**
* @private
* Storage for the allowMultipleSelection property.
*/
private var _allowMultipleSelection:Boolean = false;
/**
* @private
*/
private var allowMultipleSelectionChanged:Boolean = false;
[Bindable("allowMultipleSelectionChanged")]
[Inspectable(category="General", defaultValue="false")]
/**
* If <code>true</code>, specifies that multiple selection
* is allowed in the DateChooser control.
* Setting this property changes the appearance of the DateChooser control.
*
* @default false
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get allowMultipleSelection():Boolean
{
return _allowMultipleSelection;
}
/**
* @private
*/
public function set allowMultipleSelection(value:Boolean):void
{
_allowMultipleSelection = value;
allowMultipleSelectionChanged = true;
invalidateProperties();
}
//----------------------------------
// calendarLayoutStyleFilters
//----------------------------------
/**
* The set of styles to pass from the DateChooser to the calendar layout.
* @see mx.styles.StyleProxy
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function get calendarLayoutStyleFilters():Object
{
return null;
}
//----------------------------------
// dayNames
//----------------------------------
/**
* @private
* Storage for the dayNames property.
*/
private var _dayNames:Array;
/**
* @private
*/
private var dayNamesChanged:Boolean = false;
/**
* @private
*/
private var dayNamesOverride:Array;
[Bindable("dayNamesChanged")]
[Inspectable(arrayType="String", defaultValue="null")]
/**
* The weekday names for DateChooser control.
* Changing this property changes the day labels
* of the DateChooser control.
* Sunday is the first day (at index 0).
* The rest of the week names follow in the normal order.
*
* @default [ "S", "M", "T", "W", "T", "F", "S" ].
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get dayNames():Array
{
return _dayNames;
}
/**
* @private
*/
public function set dayNames(value:Array):void
{
dayNamesOverride = value;
_dayNames = value != null ?
value :
resourceManager.getStringArray(
"controls", "dayNamesShortest");
// _dayNames will be null if there are no resources.
_dayNames = _dayNames ? _dayNames.slice(0) : null;
dayNamesChanged = true;
invalidateProperties();
}
//----------------------------------
// disabledDays
//----------------------------------
/**
* @private
* Storage for the disabledDays property.
*/
private var _disabledDays:Array = [];
/**
* @private
*/
private var disabledDaysChanged:Boolean = false;
[Bindable("disabledDaysChanged")]
[Inspectable(arrayType="Date")]
/**
* The days to disable in a week.
* All the dates in a month, for the specified day, are disabled.
* This property changes the appearance of the DateChooser control.
* The elements of this array can have values from 0 (Sunday) to
* 6 (Saturday).
* For example, a value of <code>[ 0, 6 ]</code>
* disables Sunday and Saturday.
*
* @default []
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get disabledDays():Array
{
return _disabledDays;
}
/**
* @private
*/
public function set disabledDays(value:Array):void
{
_disabledDays = value;
disabledDaysChanged = true;
invalidateProperties();
}
//----------------------------------
// disabledRanges
//----------------------------------
/**
* @private
* Storage for the disabledRanges property.
*/
private var _disabledRanges:Array = [];
/**
* @private
*/
private var disabledRangesChanged:Boolean = false;
[Bindable("disabledRangesChanged")]
[Inspectable(arrayType="Object")]
/**
* Disables single and multiple days.
*
* <p>This property accepts an Array of objects as a parameter.
* Each object in this array is a Date object, specifying a
* single day to disable; or an object containing either or both
* of the <code>rangeStart</code> and <code>rangeEnd</code> properties,
* each of whose values is a Date object.
* The value of these properties describes the boundaries
* of the date range.
* If either is omitted, the range is considered
* unbounded in that direction.
* If you specify only <code>rangeStart</code>,
* all the dates after the specified date are disabled,
* including the <code>rangeStart</code> date.
* If you specify only <code>rangeEnd</code>,
* all the dates before the specified date are disabled,
* including the <code>rangeEnd</code> date.
* To disable a single day, use a single Date object specifying a date
* in the Array. Time values are zeroed out from the Date
* object if they are present.</p>
*
* <p>The following example, disables the following dates: January 11
* 2006, the range January 23 - February 10 2006, and March 1 2006
* and all following dates.</p>
*
* <p><code>disabledRanges="{[ new Date(2006,0,11), {rangeStart:
* new Date(2006,0,23), rangeEnd: new Date(2006,1,10)},
* {rangeStart: new Date(2006,2,1)} ]}"</code></p>
*
* @default []
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get disabledRanges():Array
{
return _disabledRanges;
}
/**
* @private
*/
public function set disabledRanges(value:Array):void
{
_disabledRanges = scrubTimeValues(value);
disabledRangesChanged = true;
invalidateProperties();
}
//----------------------------------
// displayedMonth
//----------------------------------
/**
* @private
* Storage for the displayedMonth property.
*/
private var _displayedMonth:int = (new Date()).getMonth();
/**
* @private
*/
private var displayedMonthChanged:Boolean = false;
[Bindable("scroll")]
[Bindable("viewChanged")]
[Inspectable(category="General")]
/**
* Used together with the <code>displayedYear</code> property,
* the <code>displayedMonth</code> property specifies the month
* displayed in the DateChooser control.
* Month numbers are zero-based, so January is 0 and December is 11.
* Setting this property changes the appearance of the DateChooser control.
*
* <p>The default value is the current month.</p>
*
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get displayedMonth():int
{
if (dateGrid && _displayedMonth != dateGrid.displayedMonth)
return dateGrid.displayedMonth;
else
return _displayedMonth;
}
/**
* @private
*/
public function set displayedMonth(value:int):void
{
if (isNaN(value) || displayedMonth == value)
return;
_displayedMonth = value;
displayedMonthChanged = true;
invalidateProperties();
if (dateGrid)
dateGrid.displayedMonth = value; // if it's already this value shouldn't do anything
}
//----------------------------------
// displayedYear
//----------------------------------
/**
* @private
* Storage for the displayedYear property.
*/
private var _displayedYear:int = (new Date()).getFullYear();
/**
* @private
*/
private var displayedYearChanged:Boolean = false;
[Bindable("scroll")]
[Bindable("viewChanged")]
[Inspectable(category="General")]
/**
* Used together with the <code>displayedMonth</code> property,
* the <code>displayedYear</code> property specifies the year
* displayed in the DateChooser control.
* Setting this property changes the appearance of the DateChooser control.
*
* <p>The default value is the current year.</p>
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get displayedYear():int
{
if (dateGrid)
return dateGrid.displayedYear;
else
return _displayedYear;
}
/**
* @private
*/
public function set displayedYear(value:int):void
{
if (isNaN(value) || displayedYear == value)
return;
_displayedYear = value;
displayedYearChanged = true;
invalidateProperties();
if (dateGrid)
dateGrid.displayedYear = value;// if it's already this value shouldn't do anything
}
//----------------------------------
// firstDayOfWeek
//----------------------------------
/**
* @private
* Storage for the firstDayOfWeek property.
*/
private var _firstDayOfWeek:Object;
/**
* @private
*/
private var firstDayOfWeekChanged:Boolean = false;
/**
* @private
*/
private var firstDayOfWeekOverride:Object;
[Bindable("firstDayOfWeekChanged")]
[Inspectable(defaultValue="null")]
/**
* Number representing the day of the week to display in the
* first column of the DateChooser control.
* The value must be in the range 0 to 6, where 0 corresponds to Sunday,
* the first element of the <code>dayNames</code> Array.
*
* <p>Setting this property changes the order of the day columns.
* For example, setting it to 1 makes Monday the first column
* in the control.</p>
*
* @default 0 (Sunday)
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get firstDayOfWeek():Object
{
return _firstDayOfWeek;
}
/**
* @private
*/
public function set firstDayOfWeek(value:Object):void
{
firstDayOfWeekOverride = value;
_firstDayOfWeek = value != null ?
int(value) :
resourceManager.getInt(
"controls", "firstDayOfWeek");
firstDayOfWeekChanged = true;
invalidateProperties();
}
//----------------------------------
// fontContext
//----------------------------------
/**
* @private
*/
public function get fontContext():IFlexModuleFactory
{
return moduleFactory;
}
/**
* @private
*/
public function set fontContext(moduleFactory:IFlexModuleFactory):void
{
this.moduleFactory = moduleFactory;
}
//----------------------------------
// maxYear
//----------------------------------
/**
* @private
* Storage for the maxYear property.
*/
private var _maxYear:int = 2100;
/**
* The last year selectable in the control.
*
* @default 2100
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get maxYear():int
{
return _maxYear;
}
/**
* @private
*/
public function set maxYear(value:int):void
{
if (_maxYear == value)
return;
_maxYear = value;
}
//----------------------------------
// minYear
//----------------------------------
/**
* @private
* Storage for the minYear property.
*/
private var _minYear:int = 1900;
/**
* The first year selectable in the control.
*
* @default 1900
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get minYear():int
{
return _minYear;
}
/**
* @private
*/
public function set minYear(value:int):void
{
if (_minYear == value)
return;
_minYear = value;
}
//----------------------------------
// monthNames
//----------------------------------
/**
* @private
* Storage for the monthNames property.
*/
private var _monthNames:Array;
/**
* @private
*/
private var monthNamesChanged:Boolean = false;
/**
* @private
*/
private var monthNamesOverride:Array;
[Bindable("monthNamesChanged")]
[Inspectable(arrayType="String", defaultValue="null")]
/**
* Names of the months displayed at the top of the DateChooser control.
* The <code>monthSymbol</code> property is appended to the end of
* the value specified by the <code>monthNames</code> property,
* which is useful in languages such as Japanese.
*
* @default [ "January", "February", "March", "April", "May", "June",
* "July", "August", "September", "October", "November", "December" ]
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get monthNames():Array
{
return _monthNames;
}
/**
* @private
*/
public function set monthNames(value:Array):void
{
monthNamesOverride = value;
_monthNames = value != null ?
value :
resourceManager.getStringArray(
"SharedResources", "monthNames");
// _monthNames will be null if there are no resources.
_monthNames = _monthNames ? monthNames.slice(0) : null;
monthNamesChanged = true;
invalidateProperties();
invalidateSize();
}
//----------------------------------
// monthSymbol
//----------------------------------
/**
* @private
* Storage for the monthSymbol property.
*/
private var _monthSymbol:String;
/**
* @private
*/
private var monthSymbolChanged:Boolean = false;
/**
* @private
*/
private var monthSymbolOverride:String;
[Bindable("monthSymbolChanged")]
[Inspectable(defaultValue="")]
/**
* This property is appended to the end of the value specified
* by the <code>monthNames</code> property to define the names
* of the months displayed at the top of the DateChooser control.
* Some languages, such as Japanese, use an extra
* symbol after the month name.
*
* @default ""
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get monthSymbol():String
{
return _monthSymbol;
}
/**
* @private
*/
public function set monthSymbol(value:String):void
{
monthSymbolOverride = value;
_monthSymbol = value != null ?
value :
resourceManager.getString(
"SharedResources", "monthSymbol");
monthSymbolChanged = true;
invalidateProperties();
}
//----------------------------------
// nextMonthStyleFilters
//----------------------------------
/**
* The set of styles to pass from the DateChooser to the next month button.
* @see mx.styles.StyleProxy
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function get nextMonthStyleFilters():Object
{
return _nextMonthStyleFilters;
}
private static var _nextMonthStyleFilters:Object =
{
"highlightAlphas" : "highlightAlphas",
"nextMonthUpSkin" : "nextMonthUpSkin",
"nextMonthOverSkin" : "nextMonthOverSkin",
"nextMonthDownSkin" : "nextMonthDownSkin",
"nextMonthDisabledSkin" : "nextMonthDisabledSkin",
"nextMonthSkin" : "nextMonthSkin",
"repeatDelay" : "repeatDelay",
"repeatInterval" : "repeatInterval"
};
//----------------------------------
// nextYearStyleFilters
//----------------------------------
/**
* The set of styles to pass from the DateChooser to the next year button.
* @see mx.styles.StyleProxy
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function get nextYearStyleFilters():Object
{
return _nextYearStyleFilters;
}
private static var _nextYearStyleFilters:Object =
{
"highlightAlphas" : "highlightAlphas",
"nextYearUpSkin" : "nextYearUpSkin",
"nextYearOverSkin" : "nextYearOverSkin",
"nextYearDownSkin" : "nextYearDownSkin",
"nextYearDisabledSkin" : "nextYearDisabledSkin",
"nextYearSkin" : "nextYearSkin",
"repeatDelay" : "repeatDelay",
"repeatInterval" : "repeatInterval"
};
//----------------------------------
// prevMonthStyleFilters
//----------------------------------
/**
* The set of styles to pass from the DateChooser to the previous month button.
* @see mx.styles.StyleProxy
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function get prevMonthStyleFilters():Object
{
return _prevMonthStyleFilters;
}
private static var _prevMonthStyleFilters:Object =
{
"highlightAlphas" : "highlightAlphas",
"prevMonthUpSkin" : "prevMonthUpSkin",
"prevMonthOverSkin" : "prevMonthOverSkin",
"prevMonthDownSkin" : "prevMonthDownSkin",
"prevMonthDisabledSkin" : "prevMonthDisabledSkin",
"prevMonthSkin" : "prevMonthSkin",
"repeatDelay" : "repeatDelay",
"repeatInterval" : "repeatInterval"
};
//----------------------------------
// prevYearStyleFilters
//----------------------------------
/**
* The set of styles to pass from the DateChooser to the previous year button.
* @see mx.styles.StyleProxy
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function get prevYearStyleFilters():Object
{
return _prevYearStyleFilters;
}
private static var _prevYearStyleFilters:Object =
{
"highlightAlphas" : "highlightAlphas",
"prevYearUpSkin" : "prevYearUpSkin",
"prevYearOverSkin" : "prevYearOverSkin",
"prevYearDownSkin" : "prevYearDownSkin",
"prevYearDisabledSkin" : "prevYearDisabledSkin",
"prevYearSkin" : "prevYearSkin",
"repeatDelay" : "repeatDelay",
"repeatInterval" : "repeatInterval"
};
//----------------------------------
// selectableRange
//----------------------------------
/**
* @private
* Storage for the selectableRange property.
*/
private var _selectableRange:Object;
/**
* @private
*/
private var selectableRangeChanged:Boolean = false;
[Bindable("selectableRangeChanged")]
/**
* Range of dates between which dates are selectable.
* For example, a date between 04-12-2006 and 04-12-2007
* is selectable, but dates out of this range are disabled.
*
* <p>This property accepts an Object as a parameter.
* The Object contains two properties, <code>rangeStart</code>
* and <code>rangeEnd</code>, of type Date.
* If you specify only <code>rangeStart</code>,
* all the dates on and after the specified date are enabled.
* If you only specify <code>rangeEnd</code>,
* all the dates on and before the specified date are enabled.
* To enable only a single day in a DateChooser control,
* you can pass a Date object directly. Time values are
* zeroed out from the Date object if they are present.</p>
*
* <p>The following example enables only the range
* January 1, 2006 through June 30, 2006. Months before January
* and after June do not appear in the DateChooser.</p>
*
* <p><code>selectableRange="{{rangeStart : new Date(2006,0,1),
* rangeEnd : new Date(2006,5,30)}}"</code></p>
*
* @default null
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get selectableRange():Object
{
return _selectableRange;
}
/**
* @private
*/
public function set selectableRange(value:Object):void
{
_selectableRange = scrubTimeValue(value);
selectableRangeChanged = true;
invalidateProperties();
}
//----------------------------------
// selectedDate
//----------------------------------
/**
* @private
* Storage for the selectedDate property.
*/
private var _selectedDate:Date;
/**
* @private
*/
private var selectedDateChanged:Boolean = false;
[Bindable("change")]
[Bindable("valueCommit")]
[Inspectable(category="General")]
/**
* Date selected in the DateChooser control.
* If the incoming Date object has any time values,
* they are zeroed out.
*
* <p>Holding down the Control key when selecting the
* currently selected date in the control deselects it,
* sets the <code>selectedDate</code> property to <code>null</code>,
* and then dispatches the <code>change</code> event.</p>
*
* @default null
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get selectedDate():Date
{
return _selectedDate;
}
/**
* @private
*/
public function set selectedDate(value:Date):void
{
_selectedDate = scrubTimeValue(value) as Date;
selectedDateChanged = true;
invalidateProperties();
}
//----------------------------------
// selectedRanges
//----------------------------------
/**
* @private
* Storage for the selectedRanges property.
*/
private var _selectedRanges:Array = [];
/**
* @private
*/
private var selectedRangesChanged:Boolean = false;
[Bindable("change")]
[Bindable("valueCommit")]
[Inspectable(arrayType="Date")]
/**
* Selected date ranges.
*
* <p>This property accepts an Array of objects as a parameter.
* Each object in this array has two date Objects,
* <code>rangeStart</code> and <code>rangeEnd</code>.
* The range of dates between each set of <code>rangeStart</code>
* and <code>rangeEnd</code> (inclusive) are selected.
* To select a single day, set both <code>rangeStart</code> and <code>rangeEnd</code>
* to the same date. Time values are zeroed out from the Date
* object if they are present.</p>
*
* <p>The following example, selects the following dates: January 11
* 2006, the range January 23 - February 10 2006. </p>
*
* <p><code>selectedRanges="{[ {rangeStart: new Date(2006,0,11),
* rangeEnd: new Date(2006,0,11)}, {rangeStart:new Date(2006,0,23),
* rangeEnd: new Date(2006,1,10)} ]}"</code></p>
*
* @default []
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get selectedRanges():Array
{
_selectedRanges = dateGrid.selectedRanges;
return _selectedRanges;
}
/**
* @private
*/
public function set selectedRanges(value:Array):void
{
_selectedRanges = scrubTimeValues(value);
selectedRangesChanged = true;
invalidateProperties();
}
//----------------------------------
// showToday
//----------------------------------
/**
* @private
* Storage for the showToday property.
*/
private var _showToday:Boolean = true;
/**
* @private
*/
private var showTodayChanged:Boolean = false;
[Bindable("showTodayChanged")]
[Inspectable(category="General", defaultValue="true")]
/**
* If <code>true</code>, specifies that today is highlighted
* in the DateChooser control.
* Setting this property changes the appearance of the DateChooser control.
*
* @default true
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get showToday():Boolean
{
return _showToday;
}
/**
* @private
*/
public function set showToday(value:Boolean):void
{
_showToday = value;
showTodayChanged = true;
invalidateProperties();
}
//----------------------------------
// yearNavigationEnabled
//----------------------------------
/**
* @private
* Storage for the yearNavigationEnabled property.
*/
private var _yearNavigationEnabled:Boolean = false;
/**
* @private
*/
private var yearNavigationEnabledChanged:Boolean = false;
[Bindable("yearNavigationEnabledChanged")]
[Inspectable(defaultValue="false")]
/**
* Enables year navigation. When <code>true</code>
* an up and down button appear to the right
* of the displayed year. You can use these buttons
* to change the current year.
* These button appear to the left of the year in locales where year comes
* before the month in the date format.
*
* @default false
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get yearNavigationEnabled():Boolean
{
return _yearNavigationEnabled;
}
/**
* @private
*/
public function set yearNavigationEnabled(value:Boolean):void
{
_yearNavigationEnabled = value;
yearNavigationEnabledChanged = true;
invalidateProperties();
}
//----------------------------------
// yearSymbol
//----------------------------------
/**
* @private
* Storage for the yearSymbol property.
*/
private var _yearSymbol:String;
/**
* @private
*/
private var yearSymbolChanged:Boolean = false;
/**
* @private
*/
private var yearSymbolOverride:String;
[Bindable("yearSymbolChanged")]
[Inspectable(defaultValue="")]
/**
* This property is appended to the end of the year
* displayed at the top of the DateChooser control.
* Some languages, such as Japanese,
* add a symbol after the year.
*
* @default ""
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get yearSymbol():String
{
return _yearSymbol;
}
/**
* @private
*/
public function set yearSymbol(value:String):void
{
yearSymbolOverride = value;
_yearSymbol = value != null ?
value :
resourceManager.getString(
"controls", "yearSymbol");
yearSymbolChanged = true;
invalidateProperties();
}
//--------------------------------------------------------------------------
//
// Overridden methods: UIComponent
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function initializeAccessibility():void
{
if (DateChooser.createAccessibilityImplementation != null)
DateChooser.createAccessibilityImplementation(this);
}
/**
* @private
* Create subobjects in the component. This method creates textfields for
* dates in a month, month scroll buttons, header row, background and border.
*/
override protected function createChildren():void
{
super.createChildren();
if (!background)
{
background = new UIComponent();
addChild(background);
UIComponent(background).styleName = this;
}
if (!border)
{
border = new UIComponent();
addChild(border);
UIComponent(border).styleName = this;
}
// Create the dateGrid.
// This must be created before calling updateDateDisplay().
if (!dateGrid)
{
dateGrid = new CalendarLayout();
dateGrid.styleName = new StyleProxy(this, calendarLayoutStyleFilters);
addChild(dateGrid);
dateGrid.addEventListener(CalendarLayoutChangeEvent.CHANGE,
dateGrid_changeHandler);
dateGrid.addEventListener(DateChooserEvent.SCROLL,
dateGrid_scrollHandler);
}
if (!calHeader)
{
calHeader = new UIComponent();
addChild(calHeader);
calHeader.styleName = this;
}
createMonthDisplay(-1);
createYearDisplay(-1);
if (_yearNavigationEnabled)
getYearNavigationButtons();
// Create the next-month button.
if (!fwdMonthButton)
{
fwdMonthButton = new Button();
fwdMonthButton.styleName = new StyleProxy(this,nextMonthStyleFilters);
fwdMonthButton.autoRepeat = true;
fwdMonthButton.focusEnabled = false;
fwdMonthButton.upSkinName = "nextMonthUpSkin";
fwdMonthButton.overSkinName = "nextMonthOverSkin";
fwdMonthButton.downSkinName = "nextMonthDownSkin";
fwdMonthButton.disabledSkinName = "nextMonthDisabledSkin";
fwdMonthButton.skinName = "nextMonthSkin";
fwdMonthButton.upIconName = "";
fwdMonthButton.overIconName = "";
fwdMonthButton.downIconName = "";
fwdMonthButton.disabledIconName = "";
fwdMonthButton.addEventListener(FlexEvent.BUTTON_DOWN,
fwdMonthButton_buttonDownHandler);
addChild(fwdMonthButton);
}
// Create the previous-month button.
if (!backMonthButton)
{
backMonthButton = new Button();
backMonthButton.styleName = new StyleProxy(this, prevMonthStyleFilters);
backMonthButton.focusEnabled = false;
backMonthButton.autoRepeat = true;
backMonthButton.upSkinName = "prevMonthUpSkin";
backMonthButton.overSkinName = "prevMonthOverSkin";
backMonthButton.downSkinName = "prevMonthDownSkin";
backMonthButton.disabledSkinName = "prevMonthDisabledSkin";
backMonthButton.skinName = "prevMonthSkin";
backMonthButton.upIconName = "";
backMonthButton.overIconName = "";
backMonthButton.downIconName = "";
backMonthButton.disabledIconName = "";
backMonthButton.addEventListener(FlexEvent.BUTTON_DOWN,
backMonthButton_buttonDownHandler);
addChild(backMonthButton);
}
if (!fwdMonthHit)
{
fwdMonthHit = new FlexSprite();
fwdMonthHit.name = "fwdMonthHit";
addChild(fwdMonthHit);
fwdMonthHit.visible = false;
fwdMonthButton.hitArea = fwdMonthHit;
}
if (!backMonthHit)
{
backMonthHit = new FlexSprite();
backMonthHit.name = "backMonthHit";
addChild(backMonthHit);
backMonthHit.visible = false;
backMonthButton.hitArea = backMonthHit;
}
}
/**
* @private
*/
override protected function commitProperties():void
{
super.commitProperties();
if (hasFontContextChanged() && yearDisplay != null)
{
// re-create the children so we can display the embedded font from the new font context
var childIndex:int = getChildIndex(DisplayObject(yearDisplay));
removeYearDisplay();
createYearDisplay(childIndex);
childIndex= getChildIndex(DisplayObject(monthDisplay));
removeMonthDisplay();
createMonthDisplay(childIndex);
}
if (showTodayChanged)
{
showTodayChanged = false;
dateGrid.showToday = _showToday;
dispatchEvent(new Event("showTodayChanged"));
}
if (enabledChanged)
{
enabledChanged = false;
fwdMonthButton.enabled = _enabled;
backMonthButton.enabled = _enabled;
monthDisplay.enabled = _enabled;
yearDisplay.enabled = _enabled;
if (_yearNavigationEnabled)
{
upYearButton.enabled = _enabled;
downYearButton.enabled = _enabled;
}
dateGrid.enabled = _enabled;
dispatchEvent(new Event("enabledChanged"));
}
if (firstDayOfWeekChanged)
{
firstDayOfWeekChanged = false;
dateGrid.firstDayOfWeek = int(_firstDayOfWeek);
dispatchEvent(new Event("firstDayOfWeekChanged"));
}
if (displayedMonthChanged)
{
displayedMonthChanged = false;
dateGrid.displayedMonth = _displayedMonth;
invalidateDisplayList();
dispatchEvent(new Event("viewChanged"));
}
if (displayedYearChanged)
{
displayedYearChanged = false;
dateGrid.displayedYear = _displayedYear;
invalidateDisplayList();
dispatchEvent(new Event("viewChanged"));
}
if (dayNamesChanged)
{
dayNamesChanged = false;
// _dayNames will be null if there are no resources.
dateGrid.dayNames = _dayNames ? _dayNames.slice(0) : null;
dispatchEvent(new Event("dayNamesChanged"));
}
if (disabledDaysChanged)
{
disabledDaysChanged = false;
dateGrid.disabledDays = _disabledDays.slice(0);
dispatchEvent(new Event("disabledDaysChanged"));
}
if (selectableRangeChanged)
{
selectableRangeChanged = false;
dateGrid.selectableRange = _selectableRange is Array ? _selectableRange.slice(0) : _selectableRange;
dispatchEvent(new Event("selectableRangeChanged"));
invalidateDisplayList();
}
if (disabledRangesChanged)
{
disabledRangesChanged = false;
dateGrid.disabledRanges = _disabledRanges.slice(0);
dispatchEvent(new Event("disabledRangesChanged"));
}
if (selectedDateChanged)
{
selectedDateChanged = false;
dateGrid.selectedDate = _selectedDate;
invalidateDisplayList();
dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
}
if (selectedRangesChanged)
{
selectedRangesChanged = false;
dateGrid.selectedRanges = _selectedRanges;
invalidateDisplayList();
dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
}
if (allowMultipleSelectionChanged)
{
allowMultipleSelectionChanged = false;
dateGrid.allowMultipleSelection = _allowMultipleSelection;
invalidateDisplayList();
dispatchEvent(new Event("allowMultipleSelectionChanged"));
}
if (allowDisjointSelectionChanged)
{
allowDisjointSelectionChanged = false;
dateGrid.allowDisjointSelection = _allowDisjointSelection;
invalidateDisplayList();
dispatchEvent(new Event("allowDisjointSelectionChanged"));
}
if (monthNamesChanged)
{
monthNamesChanged = false;
setMonthWidth();
invalidateDisplayList();
dispatchEvent(new Event("monthNamesChanged"));
}
if (yearNavigationEnabledChanged)
{
if (_yearNavigationEnabled)
{
getYearNavigationButtons();
}
else if (upYearButton && downYearButton)
{
removeChild(upYearButton);
removeChild(downYearButton);
removeChild(upYearHit);
removeChild(downYearHit);
upYearButton = null;
downYearButton = null;
upYearHit = null;
downYearHit = null;
}
yearNavigationEnabledChanged = false;
invalidateSize();
invalidateDisplayList();
dispatchEvent(new Event("yearNavigationEnabledChanged"));
}
if (yearSymbolChanged)
{
yearSymbolChanged = false;
invalidateSize();
invalidateDisplayList();
dispatchEvent(new Event("yearSymbolChanged"));
}
if (monthSymbolChanged)
{
monthSymbolChanged = false;
setMonthWidth();
invalidateSize();
invalidateDisplayList();
dispatchEvent(new Event("monthSymbolChanged"));
}
}
/**
* @private
*/
override protected function measure():void
{
super.measure();
updateDateDisplay();
setMonthWidth();
var borderThickness:Number = getStyle("borderThickness");
// Wait until the initial style values have been set on this element,
// and then pass those initial values down to my children
monthSkinWidth = fwdMonthButton.getExplicitOrMeasuredWidth();
monthSkinHeight = fwdMonthButton.getExplicitOrMeasuredHeight();
if (_yearNavigationEnabled)
{
yearSkinWidth = upYearButton.getExplicitOrMeasuredWidth();
yearSkinHeight = upYearButton.getExplicitOrMeasuredHeight();
}
else
{
yearSkinWidth = 0;
yearSkinHeight = 0;
}
headerHeight = Math.ceil(Math.max(monthSkinHeight,
monthDisplay.getExplicitOrMeasuredHeight()))
+ SKIN_HEIGHT_PAD * 2;
//monthDisplay.width = dateGrid.getExplicitOrMeasuredWidth() - allPads - yearWidth;
measuredWidth = Math.max(dateGrid.getExplicitOrMeasuredWidth()
+ borderThickness*2,
monthDisplay.width + yearDisplay.getExplicitOrMeasuredWidth() +
HEADER_WIDTH_PAD + yearSkinWidth + YEAR_BUTTONS_PAD +
(monthSkinWidth + SKIN_WIDTH_PAD * 2) * 2);
measuredHeight = headerHeight + dateGrid.getExplicitOrMeasuredHeight() + borderThickness * 2;
measuredMinWidth = dateGrid.minWidth;
measuredMinHeight = dateGrid.minHeight + headerHeight;
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
updateDateDisplay();
var borderThickness:Number = getStyle("borderThickness");
var cornerRadius:Number = getStyle("cornerRadius");
var borderColor:Number = getStyle("borderColor");
var borderAlpha:Number = getStyle("borderAlpha");
if (FlexVersion.compatibilityVersion >= FlexVersion.VERSION_4_0)
{
// Need to simulate borderVisible by setting borderThickness
// to 0.
if (getStyle("borderVisible") == false)
borderThickness = 0;
}
var w:Number = unscaledWidth - borderThickness*2;
var h:Number = unscaledHeight - borderThickness*2;
// Wait until the initial style values have been set on this element,
// and then pass those initial values down to my children
monthSkinWidth = fwdMonthButton.getExplicitOrMeasuredWidth();
monthSkinHeight = fwdMonthButton.getExplicitOrMeasuredHeight();
var monthHeight:Number = monthDisplay.getExplicitOrMeasuredHeight();
var yearWidth:Number = yearDisplay.getExplicitOrMeasuredWidth();
if (_yearNavigationEnabled)
{
yearSkinWidth = upYearButton.getExplicitOrMeasuredWidth();
yearSkinHeight = upYearButton.getExplicitOrMeasuredHeight();
}
var dateFormat:String = resourceManager.getString(
"SharedResources", "dateFormat");
var swapOrder:Boolean = yearBeforeMonth(dateFormat);
var yearX:Number;
if (swapOrder)
yearX = borderThickness + monthSkinWidth + SKIN_WIDTH_PAD + HEADER_WIDTH_PAD;
else
yearX = w - (monthSkinWidth + HEADER_WIDTH_PAD +
yearSkinWidth + YEAR_BUTTONS_PAD) + borderThickness;
var dateHeight:Number = borderThickness + (headerHeight - monthHeight) / 2;
var allPads:Number = HEADER_WIDTH_PAD + yearSkinWidth +
(monthSkinWidth + SKIN_WIDTH_PAD * 2) * 2;
monthDisplay.setActualSize(Math.max(w - allPads - yearWidth, 0), monthHeight);
if (swapOrder)
monthDisplay.move(yearX + yearWidth + YEAR_BUTTONS_PAD + yearSkinWidth, dateHeight);
else
monthDisplay.move(borderThickness + monthSkinWidth + SKIN_WIDTH_PAD + HEADER_WIDTH_PAD, dateHeight);
monthDisplay.visible = true;
yearDisplay.setActualSize(yearWidth + YEAR_BUTTONS_PAD, monthHeight);
if (swapOrder)
yearDisplay.move(yearX + YEAR_BUTTONS_PAD, dateHeight);
else
yearDisplay.move(yearX - yearWidth - YEAR_BUTTONS_PAD, dateHeight);
yearDisplay.visible = true;
dateGrid.setActualSize(w, h - headerHeight);
dateGrid.move(borderThickness, headerHeight + borderThickness);
var backgroundContext:Graphics = background.graphics;
backgroundContext.clear();
backgroundContext.beginFill(0xFFFFFF);
backgroundContext.drawRoundRect(0, 0, w, h, cornerRadius * 2, cornerRadius * 2);
backgroundContext.endFill();
background.$visible = true;
var borderContext:Graphics = border.graphics;
borderContext.clear();
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
borderContext.beginFill(borderColor);
else
borderContext.beginFill(borderColor, enabled ? borderAlpha : borderAlpha / 2);
borderContext.drawRoundRect(0, 0, unscaledWidth, unscaledHeight,
cornerRadius * 2, cornerRadius * 2);
borderContext.drawRoundRect(borderThickness, borderThickness,
unscaledWidth - borderThickness * 2,
unscaledHeight - borderThickness * 2,
cornerRadius * 2, cornerRadius * 2);
borderContext.endFill();
// Here we attempt to detect that we are using a halo skin on our
// DateChooser There is no guaranteed way to check for halo skins.
// The closest we can do is to look for "skins.halo" in the qualified
// class name one of our skinnable styles.
var isHalo:Boolean = false;
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
isHalo = true;
}
else
{
var borderSkinClass:Class = getStyle("borderSkin");
isHalo = borderSkinClass &&
(getQualifiedClassName(borderSkinClass).indexOf("skins.halo") >= 0);
}
// The Halo theme and versions of Flex prior to 4 use backgroundColor
// with Flex 4 we prefer contentBackgroundColor but will fall back to
// backgroundColor just in case.
var bgColor:uint = StyleManager.NOT_A_COLOR;
if (isHalo || FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
bgColor = getStyle("backgroundColor");
}
else
{
// The contentBackgroundColor style trumps backgroundColor if specified.
var bgColorObj:* = getStyle("contentBackgroundColor");
bgColor = (bgColorObj === undefined) ? getStyle("backgroundColor") : bgColorObj;
}
// The Halo theme and version of Flex prior to 4 use backgroundAlpha
// with Flex 4 we prefer contentBackgroundAlpha but will fall back to
// backgroundAlpha just in case
var bgAlpha:Number = 1;
if (isHalo || FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
bgAlpha = getStyle("backgroundAlpha");
}
else
{
var bgAlphaObj:* = getStyle("contentBackgroundAlpha");
bgAlpha = (bgAlphaObj === undefined) ? getStyle("backgroundAlpha") : bgAlphaObj;
}
borderContext.beginFill(bgColor, bgAlpha);
borderContext.drawRoundRect(borderThickness, borderThickness, w, h,
cornerRadius > 0 ? (cornerRadius - 1) * 2 : 0,
cornerRadius > 0 ? (cornerRadius - 1) * 2 : 0);
borderContext.endFill();
border.visible = true;
var headerColors:Array = getStyle("headerColors");
if (!headerColors)
headerColors = [0xFFFFFF, 0xD8D8D8];
var headerContext:Graphics = calHeader.graphics;
headerContext.clear();
styleManager.getColorNames(headerColors);
var matrix:Matrix = new Matrix();
matrix.createGradientBox(w, headerHeight, Math.PI / 2, 0, 0);
headerContext.beginGradientFill(GradientType.LINEAR, headerColors,
[1.0,1.0], [ 0, 0xFF], matrix);
GraphicsUtil.drawRoundRectComplex(headerContext, borderThickness, borderThickness,
w, headerHeight, cornerRadius, cornerRadius, 0, 0);
headerContext.endFill();
// Apply Spark chromeColor tint if applicable.
if (!isHalo && FlexVersion.compatibilityVersion >= FlexVersion.VERSION_4_0)
{
var chromeColor:uint = getStyle("chromeColor");
// These values derived from SparkSkin.as.
var defaultColorValue:Number = 0xCC;
var defaultColor:Number = 0xCCCCCC;
if (chromeColor != defaultColor)
{
var colorTransform:ColorTransform = new ColorTransform();
colorTransform.redOffset = ((chromeColor & (0xFF << 16)) >> 16) - defaultColorValue;
colorTransform.greenOffset = ((chromeColor & (0xFF << 8)) >> 8) - defaultColorValue;
colorTransform.blueOffset = (chromeColor & 0xFF) - defaultColorValue;
colorTransform.alphaMultiplier = alpha;
calHeader.transform.colorTransform = colorTransform;
}
else
{
calHeader.transform.colorTransform = new ColorTransform();
}
}
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
borderContext.lineStyle(borderThickness, borderColor);
else
borderContext.lineStyle(borderThickness, borderColor, enabled ? borderAlpha : borderAlpha / 2);
borderContext.moveTo(borderThickness, headerHeight + borderThickness);
borderContext.lineTo(w + borderThickness, headerHeight + borderThickness);
calHeader.$visible = true;
// Note: Height of header is not dependent on unscaledHeight.
fwdMonthButton.setActualSize(monthSkinWidth, monthSkinHeight);
backMonthButton.setActualSize(monthSkinWidth, monthSkinHeight);
fwdMonthButton.move(w - (monthSkinWidth + HEADER_WIDTH_PAD) + borderThickness,
Math.round(borderThickness + (headerHeight - monthSkinHeight) / 2));
backMonthButton.move(HEADER_WIDTH_PAD + borderThickness,
Math.round(borderThickness + (headerHeight - monthSkinHeight) / 2));
if (_yearNavigationEnabled)
{
// Assumption, up and down Button's are symmettrical.
upYearButton.setActualSize(yearSkinWidth, yearSkinHeight);
downYearButton.setActualSize(yearSkinWidth, yearSkinHeight);
upYearButton.x = yearX;
upYearButton.y = Math.floor(headerHeight / 2 - yearSkinHeight / 2 - 2);
downYearButton.x = yearX;
downYearButton.y = Math.floor(headerHeight / 2 + yearSkinHeight / 2 - 2);
pointX = upYearButton.x - SKIN_WIDTH_PAD / 2;
pointY = upYearButton.y - SKIN_HEIGHT_PAD / 2;
var upG:Graphics = upYearHit.graphics;
upG.clear();
upG.beginFill(0xCC0000, 0);
upG.moveTo(pointX, pointY);
upG.lineTo(pointX + yearSkinWidth + SKIN_WIDTH_PAD, pointY);
upG.lineTo(pointX + yearSkinWidth + SKIN_WIDTH_PAD, pointY + yearSkinHeight + SKIN_HEIGHT_PAD / 2);
upG.lineTo(pointX, pointY + yearSkinHeight + SKIN_HEIGHT_PAD / 2);
upG.lineTo(pointX, pointY);
upG.endFill();
pointX = downYearButton.x - SKIN_WIDTH_PAD / 2;
pointY = downYearButton.y;
var downG:Graphics = downYearHit.graphics;
downG.clear();
downG.beginFill(0xCC0000, 0);
downG.moveTo(pointX, pointY);
downG.lineTo(pointX + yearSkinWidth + SKIN_WIDTH_PAD, pointY);
downG.lineTo(pointX + yearSkinWidth + SKIN_WIDTH_PAD, pointY + yearSkinHeight + SKIN_HEIGHT_PAD / 2);
downG.lineTo(pointX, pointY + yearSkinHeight + SKIN_HEIGHT_PAD / 2);
downG.lineTo(pointX, pointY);
downG.endFill();
}
var pointX:Number = fwdMonthButton.x - SKIN_WIDTH_PAD / 2;
var pointY:Number = fwdMonthButton.y - SKIN_HEIGHT_PAD;
var fwdG:Graphics = fwdMonthHit.graphics;
fwdG.clear();
fwdG.beginFill(0xCC0000, 0);
fwdG.moveTo(pointX, pointY);
fwdG.lineTo(pointX + monthSkinWidth + SKIN_WIDTH_PAD / 2, pointY);
fwdG.lineTo(pointX + monthSkinWidth + SKIN_WIDTH_PAD / 2, pointY + monthSkinHeight + SKIN_HEIGHT_PAD);
fwdG.lineTo(pointX, pointY + monthSkinHeight + SKIN_HEIGHT_PAD);
fwdG.lineTo(pointX, pointY);
fwdG.endFill();
pointX = backMonthButton.x - SKIN_WIDTH_PAD / 2;
pointY = backMonthButton.y - SKIN_HEIGHT_PAD;
var bkG:Graphics = backMonthHit.graphics;
bkG.clear();
bkG.beginFill(0xCC0000, 0);
bkG.moveTo(pointX, pointY);
bkG.lineTo(pointX + monthSkinWidth + SKIN_WIDTH_PAD / 2, pointY);
bkG.lineTo(pointX + monthSkinWidth + SKIN_WIDTH_PAD / 2, pointY + monthSkinHeight + SKIN_HEIGHT_PAD);
bkG.lineTo(pointX, pointY + monthSkinHeight + SKIN_HEIGHT_PAD);
bkG.lineTo(pointX, pointY);
bkG.endFill();
var dsStyle:Object = getStyle("dropShadowEnabled");
var dsvStyle:Object = getStyle("dropShadowVisible");
graphics.clear();
if (dsStyle == true || dsvStyle == true)
{
// Calculate the angle and distance for the shadow
var distance:Number = getStyle("shadowDistance");
var direction:String = getStyle("shadowDirection");
var angle:Number;
angle = 90; // getDropShadowAngle(distance, direction);
distance = Math.abs(distance) + 2;
// Create a RectangularDropShadow object, set its properties, and
// draw the shadow
if (!dropShadow)
dropShadow = new RectangularDropShadow();
dropShadow.distance = distance;
dropShadow.angle = angle;
dropShadow.color = getStyle("dropShadowColor");
dropShadow.alpha = 0.4;
dropShadow.tlRadius = cornerRadius;
dropShadow.trRadius = cornerRadius;
dropShadow.blRadius = cornerRadius;
dropShadow.brRadius = cornerRadius;
dropShadow.drawShadow(graphics, borderThickness, borderThickness, w, h);
}
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
if (styleProp == null || styleProp == "styleName" ||
styleProp == "borderColor" || styleProp == "headerColor" ||
styleProp == "headerColors" || styleProp == "backgroundColor" ||
styleProp =="horizontalGap" || styleProp == "verticalGap" ||
styleProp =="backgroundAlpha")
{
invalidateDisplayList();
}
if (styleProp == null || styleProp == "styleName" ||
styleProp == "headerStyleName" && monthDisplay)
{
var dateHeaderStyleName:Object = getStyle("headerStyleName");
if (!dateHeaderStyleName)
dateHeaderStyleName = this;
if (monthDisplay)
monthDisplay.styleName = dateHeaderStyleName;
if (yearDisplay)
yearDisplay.styleName = dateHeaderStyleName;
if (backMonthButton)
backMonthButton.styleName = new StyleProxy(this, prevMonthStyleFilters);
if (fwdMonthButton)
fwdMonthButton.styleName = new StyleProxy(this, nextMonthStyleFilters);
if (upYearButton)
upYearButton.styleName = new StyleProxy(this, nextYearStyleFilters);
if (downYearButton)
downYearButton.styleName = new StyleProxy(this, prevYearStyleFilters);
}
}
/**
* @private
*/
override protected function resourcesChanged():void
{
super.resourcesChanged();
dayNames = dayNamesOverride;
firstDayOfWeek = firstDayOfWeekOverride;
monthNames = monthNamesOverride;
monthSymbol = monthSymbolOverride;
yearSymbol = yearSymbolOverride;
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @private
* Creates the month display label
* and adds it as a child of this component.
*
* @param childIndex The index of where to add the child.
* If -1, the text field is appended to the end of the list.
*/
mx_internal function createMonthDisplay(childIndex:int):void
{
if (!monthDisplay)
{
monthDisplay = IUITextField(createInFontContext(UITextField));
var textFormat:TextFormat = determineTextFormatFromStyles();
monthDisplay.defaultTextFormat = textFormat;
monthDisplay.visible = false;
monthDisplay.selectable = false;
if (childIndex == -1)
addChild(DisplayObject(monthDisplay));
else
addChildAt(DisplayObject(monthDisplay), childIndex);
var dateHeaderStyleName:Object = getStyle("headerStyleName");
if (!dateHeaderStyleName)
dateHeaderStyleName = this;
monthDisplay.styleName = dateHeaderStyleName;
setMonthWidth();
}
}
/**
* @private
* Removes the month dislay label from this component.
*/
mx_internal function removeMonthDisplay():void
{
if (monthDisplay)
{
removeChild(DisplayObject(monthDisplay));
monthDisplay = null;
}
}
/**
* @private
* Creates the month display label and adds it as a child of this component.
*
* @param childIndex The index of where to add the child.
* If -1, the text field is appended to the end of the list.
*/
mx_internal function createYearDisplay(childIndex:int):void
{
if (!yearDisplay)
{
yearDisplay = IUITextField(createInFontContext(UITextField));
var textFormat:TextFormat = determineTextFormatFromStyles();
yearDisplay.defaultTextFormat = textFormat;
yearDisplay.visible = false;
yearDisplay.selectable = false;
if (childIndex == -1)
addChild(DisplayObject(yearDisplay));
else
addChildAt(DisplayObject(yearDisplay), childIndex);
var dateHeaderStyleName:Object = getStyle("headerStyleName");
if (!dateHeaderStyleName)
dateHeaderStyleName = this;
yearDisplay.styleName = dateHeaderStyleName;
}
}
/**
* @private
* Removes the month dislay label from this component.
*/
mx_internal function removeYearDisplay():void
{
if (yearDisplay)
{
removeChild(DisplayObject(yearDisplay));
yearDisplay = null;
}
}
/**
* @private
*/
mx_internal function updateDateDisplay():void
{
// monthNames will be null if there are no resources.
var monthName:String = monthNames ?
monthNames[dateGrid.displayedMonth] :
"";
// month name could be null and want to display "null"
if (monthName == null)
monthName = "";
monthDisplay.text = monthName + monthSymbol;
yearDisplay.text = displayedYear.toString() + yearSymbol;
}
/**
* @private
*/
private function getYearNavigationButtons():void
{
// Create the next-Year button.
if (!upYearButton)
{
upYearButton = new Button();
upYearButton.styleName = new StyleProxy(this, nextYearStyleFilters);
upYearButton.autoRepeat = true;
upYearButton.focusEnabled = false;
upYearButton.upSkinName = "nextYearUpSkin";
upYearButton.overSkinName = "nextYearOverSkin";
upYearButton.downSkinName = "nextYearDownSkin";
upYearButton.disabledSkinName = "nextYearDisabledSkin";
upYearButton.skinName = "nextYearSkin";
upYearButton.upIconName = "";
upYearButton.overIconName = "";
upYearButton.downIconName = "";
upYearButton.disabledIconName = "";
upYearButton.addEventListener(FlexEvent.BUTTON_DOWN,
upYearButton_buttonDownHandler);
addChild(upYearButton);
}
// Create the previous-Year button.
if (!downYearButton)
{
downYearButton = new Button();
downYearButton.styleName = new StyleProxy(this, prevYearStyleFilters);
downYearButton.focusEnabled = false;
downYearButton.autoRepeat = true;
downYearButton.upSkinName = "prevYearUpSkin";
downYearButton.overSkinName = "prevYearOverSkin";
downYearButton.downSkinName = "prevYearDownSkin";
downYearButton.disabledSkinName = "prevYearDisabledSkin";
downYearButton.skinName = "prevYearSkin";
downYearButton.upIconName = "";
downYearButton.overIconName = "";
downYearButton.downIconName = "";
downYearButton.disabledIconName = "";
downYearButton.addEventListener(FlexEvent.BUTTON_DOWN,
downYearButton_buttonDownHandler);
addChild(downYearButton);
}
if (!upYearHit)
{
upYearHit = new FlexSprite();
upYearHit.name = "upYearHit";
addChild(upYearHit);
upYearHit.visible = false;
upYearButton.hitArea = upYearHit;
}
if (!downYearHit)
{
downYearHit = new FlexSprite();
downYearHit.name = "downYearHit";
addChild(downYearHit);
downYearHit.visible = false;
downYearButton.hitArea = downYearHit;
}
}
/**
* @private
*/
mx_internal function setMonthWidth():void
{
var tempWidth:Number = 0;
var longestMonth:int;
var longestMonthWidth:Number = 0;
for (var i:int = 0; i < 12; i++)
{
// monthNames will be null if there are no resources.
var monthName:String = monthNames ? monthNames[i] : "";
tempWidth = measureText(monthName + monthSymbol).width;
if (longestMonthWidth < tempWidth)
{
longestMonthWidth = tempWidth;
longestMonth = i;
}
}
// monthNames will be null if there are no resources.
var longestMonthName:String = monthNames ? monthNames[longestMonth] : "";
var longestMonthText:String = longestMonthName + monthSymbol;
var longestMonthUITextField:IUITextField = monthDisplay;
var oldMonth:String = monthDisplay.text;
longestMonthUITextField.text = longestMonthText
monthDisplay.width = longestMonthWidth * longestMonthUITextField.getExplicitOrMeasuredWidth()
/ measureText(longestMonthText).width;
longestMonthUITextField.text = oldMonth;
}
/**
* @private
* Returns true if year comes before month in DateFormat.
* Used for correct placement of year and month in header.
*/
private function yearBeforeMonth(dateFormat:String):Boolean
{
// dateFormat will be null if there are no resources.
var n:int = dateFormat != null ? dateFormat.length : 0;
for (var i:int = 0; i < n; i++)
{
if (dateFormat.charAt(i) == "M")
return false;
else if (dateFormat.charAt(i) == "Y")
return true;
}
return false;
}
/**
* @private
* This method scrubs out time values from incoming date objects
*/
mx_internal function scrubTimeValue(value:Object):Object
{
if (value is Date)
{
return new Date(value.getFullYear(), value.getMonth(), value.getDate());
}
else if (value is Object)
{
var range:Object = {};
if (value.hasOwnProperty("rangeStart") && value.rangeStart is Date)
{
range.rangeStart = new Date(value.rangeStart.getFullYear(),
value.rangeStart.getMonth(),
value.rangeStart.getDate());
}
if (value.hasOwnProperty("rangeEnd") && value.rangeEnd is Date)
{
range.rangeEnd = new Date(value.rangeEnd.getFullYear(),
value.rangeEnd.getMonth(),
value.rangeEnd.getDate());
}
return range;
}
return null;
}
/**
* @private
* This method scrubs out time values from incoming date objects
*/
mx_internal function scrubTimeValues(values:Array):Array
{
var dates:Array = [];
for (var i:int = 0; i < values.length; i++)
{
dates[i] = scrubTimeValue(values[i]);
}
return dates;
}
//--------------------------------------------------------------------------
//
// Overridden event handlers: UIComponent
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function keyDownHandler(event:KeyboardEvent):void
{
// Ignore events that bubble up from the child CalendarLayout.
// such as those we redispatch below.
if (event.eventPhase != EventPhase.AT_TARGET)
return;
if (event.keyCode == Keyboard.PAGE_UP)
{
backMonthButton_buttonDownHandler(event);
}
else if (event.keyCode == Keyboard.PAGE_DOWN)
{
fwdMonthButton_buttonDownHandler(event);
}
else if (event.keyCode == 189) // - or _ key used to step down year
{
if (_yearNavigationEnabled)
downYearButton_buttonDownHandler(event);
}
else if (event.keyCode == 187) // + or = key used to step up year
{
if (_yearNavigationEnabled)
upYearButton_buttonDownHandler(event);
}
// Redispatch the event from the CalendarLayout
// to let its keyDownHandler() handle it.
dateGrid.dispatchEvent(event);
// Prevent keys from going to scrollBars when
// the DateChooser is handling them.
event.stopPropagation();
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
/**
* @private
* event is either a KeyboardEvent or a FlexEvent
*/
private function upYearButton_buttonDownHandler(event:Event):void
{
if (maxYear < displayedYear + 1)
return;
if ((selectableRange) &&
(dateGrid.selRangeMode == 1 || dateGrid.selRangeMode == 3))
{
var newDate:Object = CalendarLayout.getNewIncrementDate(displayedYear, displayedMonth, 1, 0);
if (selectableRange.rangeEnd != null)
var testDate:Date = new Date(newDate.year, newDate.month,
selectableRange.rangeEnd.getDate());
if (selectableRange.rangeEnd == null || selectableRange.rangeEnd >= testDate)
{
dateGrid.stepDate(1, 0, event);
invalidateDisplayList();
}
}
else if (dateGrid.selRangeMode != 4 || !selectableRange)
{
dateGrid.stepDate(1, 0, event);
invalidateDisplayList();
}
}
/**
* @private
* event is either a KeyboardEvent or a FlexEvent
*/
private function downYearButton_buttonDownHandler(event:Event):void
{
if (minYear > displayedYear - 1)
return;
if (selectableRange &&
(dateGrid.selRangeMode == 1 || dateGrid.selRangeMode == 2))
{
var newDate:Object = CalendarLayout.getNewIncrementDate(displayedYear, displayedMonth, -1, 0);
if (selectableRange.rangeStart != null)
var testDate:Date = new Date(newDate.year, newDate.month,
selectableRange.rangeStart.getDate());
if (selectableRange.rangeStart == null || selectableRange.rangeStart <= testDate)
{
dateGrid.stepDate(-1, 0, event);
invalidateDisplayList();
}
}
else if (dateGrid.selRangeMode != 4 || !selectableRange)
{
dateGrid.stepDate(-1, 0, event);
invalidateDisplayList();
}
}
/**
* @private
* event is either a KeyboardEvent or a FlexEvent
*/
private function fwdMonthButton_buttonDownHandler(event:Event):void
{
if ((maxYear < displayedYear + 1) && (displayedMonth == 11))
return;
if ((selectableRange) &&
(dateGrid.selRangeMode == 1 || dateGrid.selRangeMode == 3))
{
var newDate:Object = CalendarLayout.getNewIncrementDate(displayedYear, displayedMonth, 0, 1);
if (selectableRange.rangeEnd != null)
var testDate:Date = new Date(newDate.year, newDate.month,
selectableRange.rangeEnd.getDate());
if (selectableRange.rangeEnd == null || selectableRange.rangeEnd >= testDate)
{
dateGrid.stepDate(0, 1, event);
invalidateDisplayList();
}
}
else if (dateGrid.selRangeMode != 4 || !selectableRange)
{
dateGrid.stepDate(0, 1, event);
invalidateDisplayList();
}
}
/**
* @private
* event is either a KeyboardEvent or a FlexEvent
*/
private function backMonthButton_buttonDownHandler(event:Event):void
{
if ((minYear > displayedYear - 1) && (displayedMonth == 0))
return;
if (selectableRange &&
(dateGrid.selRangeMode == 1 || dateGrid.selRangeMode == 2))
{
var newDate:Object = CalendarLayout.getNewIncrementDate(displayedYear, displayedMonth, 0, -1);
if (selectableRange.rangeStart != null)
var testDate:Date = new Date(newDate.year, newDate.month,
selectableRange.rangeStart.getDate());
if (selectableRange.rangeStart == null || selectableRange.rangeStart <= testDate)
{
dateGrid.stepDate(0, -1, event);
invalidateDisplayList();
}
}
else if (dateGrid.selRangeMode != 4 || !selectableRange)
{
dateGrid.stepDate(0, -1, event);
invalidateDisplayList();
}
}
/**
* @private
*/
private function dateGrid_scrollHandler(event:DateChooserEvent):void
{
dispatchEvent(event);
}
/**
* @private
*/
private function dateGrid_changeHandler(event:CalendarLayoutChangeEvent):void
{
_selectedDate = CalendarLayout(event.target).selectedDate;
var e:CalendarLayoutChangeEvent = new
CalendarLayoutChangeEvent(CalendarLayoutChangeEvent.CHANGE);
e.newDate = event.newDate;
e.triggerEvent = event.triggerEvent;
dispatchEvent(e);
}
/**
* @private
* If we are scaled, then we need to perform layout again.
* Our monthDisplay and yearDisplay rely on us being attached to the stage
* in order to get an accurate size.
*/
private function addedToStageHandler(event:Event):void
{
if (scaleX != 1 || scaleY != 1)
{
invalidateSize();
}
}
}
}