?? calendardisplay.as
字號:
_computedRange = ranges._computedRange;
updateDetails();
dayCount = _tz.rangeDaySpan(_visibleRange);
_dayCache.count = dayCount;
_headerCache.count = dayCount;
}
// alright, we've got the right number of
// renderers...now allocate them.
var tmp:Date = new Date(_visibleRange.start);
for(var cPos:int = 0;cPos<_columnLength;cPos++)
{
for(var rPos:int=0;rPos < _rowLength;rPos++)
{
var index:int = rPos + cPos*_rowLength;
var inst:UIComponent = _dayCache.instances[index];
var header:UIComponent = _headerCache.instances[index];
// if we're outside the official computed range, we'll pass in a null
// value, so we get a blank header and grey color. This is debatable
// UI, I suppose. Should probably be more configurable.
if(_computedRange.contains(tmp) == false)
{
IDataRenderer(inst).data = null;
IDataRenderer(header).data = null;
}
else
{
IDataRenderer(inst).data = new Date(tmp);
IDataRenderer(header).data = new Date(tmp);
}
tmp.date++;
}
}
updateEventData();
invalidateDisplayList();
}
// given a range and display mode, returns the computed and visible
// ranges for the calendar. Computed range is the value passed in, expanded
// to match the unit referred to by displayMode...i.e., expanded to the nearest
// day, week, or month boundary.
// visibleRange is the computedRange expanded to the nearest day or week boundary.
private function computeRanges(value:DateRange,displayMode:String):Object
{
var _visibleRange:DateRange;
var _computedRange:DateRange;
switch(displayMode)
{
case "day":
_visibleRange = new DateRange(value.start);
_tz.expandRangeToDays(_visibleRange,true);
_computedRange = _visibleRange.clone();
break;
case "days":
_visibleRange = value.clone();
_tz.expandRangeToDays(_visibleRange,true);
_computedRange = _visibleRange.clone();
break;
case "week":
_visibleRange = new DateRange(value.start);
_tz.expandRangeToWeeks(_visibleRange);
_computedRange = _visibleRange.clone();
break;
case "weeks":
_visibleRange = value.clone();
_tz.expandRangeToDays(_visibleRange,true);
_computedRange = _visibleRange.clone();
_tz.expandRangeToWeeks(_visibleRange);
break;
case "month":
default:
_visibleRange = new DateRange(value.start);
_tz.expandRangeToMonths(_visibleRange,true);
_computedRange = _visibleRange.clone();
_tz.expandRangeToWeeks(_visibleRange);
}
return {
_visibleRange: _visibleRange,
_computedRange: _computedRange
};
}
// various cached calculations based on the current state of the calculation
private function updateDetails():void
{
// first, compute the border of the day/event area
_border.left = 0;
_border.right = 0;
_border.top = 0;
_border.bottom = 0;
switch(layoutMode)
{
case LayoutMode.DAYS:
_border.left = _hourGrid.gutterWidth;
_border.right = _scroller.measuredWidth;
break;
case LayoutMode.WEEKS:
default:
break;
}
// now how long (in days) a row and column of the visible range is
_rowLength = Math.min(MAXIMUM_ROW_LENGTH,_tz.rangeDaySpan(_visibleRange));
_columnLength = Math.ceil(_tz.rangeDaySpan(_visibleRange)/_rowLength);
// how big each day area will be
_cellWidth = (unscaledWidth - _border.left - _border.right)/_rowLength;
_cellHeight = (unscaledHeight - _border.top - _border.bottom)/_columnLength;
// and the set of events the intersect our visible range.
var endingEvents:SortedArray = _allEventsSortedByStart.slice(_visibleRange.start,null,eventEndDateCompare);
endingEvents.compareFunction = startEventCompare;
_visibleEvents = endingEvents.slice(null,_visibleRange.end,eventStartDateCompare).values;
// how big one hour is, if we're in day-view mode.
_hourHeight = Math.max(MIN_HOUR_HEIGHT,_cellHeight / 24);
}
//----------------------------------------------------------------------------------------------------
// Layout functions
//----------------------------------------------------------------------------------------------------
// our main layout function
private function generateLayout():void
{
if( _displayMode == "day" || _displayMode == "days" )
{
layoutDays();
}
else
{
layoutMonth();
}
}
// does the layout
private function layoutCells():void
{
for(var cPos:int = 0;cPos<_columnLength;cPos++)
{
for(var rPos:int=0;rPos < _rowLength;rPos++)
{
var index:int = rPos + cPos*_rowLength;
var inst:UIComponent = _dayCache.instances[index];
var header:UIComponent = _headerCache.instances[index];
var target:LayoutTarget = _animator.targetFor(inst);
target.unscaledHeight = _cellHeight;
target.unscaledWidth = _cellWidth;
target.x = _border.left + rPos * _cellWidth;
target.y = _border.top + cPos * _cellHeight;
target = _animator.targetFor(header);
target.unscaledHeight = header.measuredHeight;
target.unscaledWidth = _cellWidth;
target.x = _border.left + rPos * _cellWidth;
target.y = _border.top + cPos * _cellHeight;
}
}
}
// our main layout routine for anything that lays out full days...
// i.e., day, days, or weeks display mode.
private function layoutDays():void
{
var startOfDay:Date = dateForIndex(0);
var endOfDay:Date = dateForIndex(1);
var openEventsDict:Dictionary = new Dictionary();
var reservations:ReservationAgent = new ReservationAgent();
var events:Array = _visibleEvents.concat();
var renderTop:int;
var data:EventData;
var renderer:UIComponent;
var target:LayoutTarget;
var rPos:int;
var event:CalendarEvent;
var header:UIComponent;
var openingEvents:Array;
var i:int;
_allDayAreaHeight = 0;
// lay out the background day and header renderers
layoutCells();
// make sure our scrollbar is visible, and in the right place,
// since we'll be needing it.
target = _animator.targetFor(_scroller);
target.initializeFunction = fadeInTarget;
target.x = unscaledWidth - _scroller.measuredWidth;
target.y = _border.top;
target.unscaledWidth = _scroller.measuredWidth;
target.unscaledHeight = _cellHeight;
target.alpha = 1;
// extract the all-day events out of our visible events
// these will be in order, sorted by start time.
var allDayEvents:Array = [];
for(i=events.length-1;i>=0;i--)
{
event = events[i];
if(event.allDay) // || event.range.daySpan > 1)
{
allDayEvents.unshift(events.splice(i,1)[0]);
}
}
// now, for each column/day (we only have one row, so we don't bother
// iterating over rows)
for(rPos=0;rPos < _rowLength;rPos++)
{
var index:int = rPos;
header = _headerCache.instances[index];
// look at the all-day events that were 'open' on the previous day
for(var anEvent:* in openEventsDict)
{
// if it ended before today, remove it from our open set
if(anEvent.event.end < startOfDay)
{
delete openEventsDict[anEvent];
// and release its marker reserving space in the 'all day event'
// track at the top of the calendar
reservations.release(anEvent);
}
}
// now if we have any all-day events that haven't started yet,
// we need to check and see which of them will be starting today.
if(allDayEvents.length > 0)
{
openingEvents = [];
// these are in order sorted by start time, so iterate forward until we find
// one that starts _later_ than today
while(allDayEvents.length > 0 && allDayEvents[0].start.getTime() < endOfDay.getTime())
{
// this events starts today, so add it to our list of open events
data = _eventData[allDayEvents.shift()];
openEventsDict[data] = true;
openingEvents.push(data);
}
renderTop = header.measuredHeight;
var allDayBorderThickness:Number = getStyle("allDayDividerThickness");
if(isNaN(allDayBorderThickness))
allDayBorderThickness = 0;
// now for each event that just opened today
for(i=0;i<openingEvents.length;i++)
{
data = openingEvents[i];
// reserve some space for it at the top of the all-day area.
var reservation:int = reservations.reserve(data);
// force the renderer into the collapsed 'line' mode, and lay it out.
// note that while EventData might have multiple renderers associated
// with it, we know that since we're only looking at a single line of
// days in our layout, there will only be one renderer here.
renderer = data.renderers[0];
ICalendarEventRenderer(renderer).displayMode = "line";
target = layoutSingleEvent(data,renderer,
_border.left + rPos * _cellWidth + EVENT_INSET,
_border.top + renderTop + renderer.measuredHeight * reservation,
_cellWidth * Math.max(1,_tz.rangeDaySpan(data.range)) - 2*EVENT_INSET,
renderer.measuredHeight
);
// we're tracking how big the all-day-area is, so make sure it grows as necessary to
// accomodate this renderer.
_allDayAreaHeight = Math.max(_allDayAreaHeight,target.y + target.unscaledHeight + 2 + allDayBorderThickness);
}
}
startOfDay.date = startOfDay.date+1;
endOfDay.date = endOfDay.date+1;
}
// ok, we're done laying out our all-day events..now we know how big they'll be.
// and thus how much space we have to lay our the actual days. We'll
// lay out all the trappings of the day area (scrollbar, grid, etc).
// reset our day bounds back to our first day.
startOfDay = dateForIndex(0);
endOfDay = dateForIndex(1);
// if we didn't have any all day events, this value didn't get set.
// so make sure it's large enough to accomodate the top of the first header,
// even if there are no all day events.
_allDayAreaHeight = Math.max(_allDayAreaHeight,_border.top + header.measuredHeight);
// how big the area allocated for the day itself is.
_dayAreaHeight = unscaledHeight - _border.bottom - _allDayAreaHeight;
// we now know the size of a day vs. the amount of space available for it, so
// update our scroll properties.
_scroller.setScrollProperties(_dayAreaHeight,0,_hourHeight * 24 - _dayAreaHeight,1);
// if we don't have a current hour we're scrolled to, calculate an appropriate hour to
// render the maximum number of events possible.
if(isNaN(_scrollHour))
{
_scrollHour = computeScrollHourToDisplayEvents(_visibleEvents);
}
// if our calendar has been resized, it's possible that our scrollHour is now to high...
// i.e., if we're scrolled to 10 pm, and we can show four hours, rather than showing off
// the day, we want to adjust our scrollhour to 8 pm.
if(_scrollHour * _hourHeight > _hourHeight * 24 - _dayAreaHeight)
_scrollHour = 24-_dayAreaHeight/_hourHeight;
// update the scrollbar to reflect our now calculated scroll position.
_scroller.scrollPosition = _scrollHour * _hourHeight;
// now that we know the height of our all day events, we know the size of our day-area.
// so we can update the mask that will clip out our intra-day events.
_eventLayer.mask = _eventMask;
_eventMask.graphics.clear();
_eventMask.graphics.beginFill(0);
_eventMask.graphics.drawRect(0, _allDayAreaHeight,unscaledWidth - _border.right,_dayAreaHeight+1);
_eventMask.graphics.endFill();
// make sure our hour gridlines stretches across the
// day area. It should be tall enough to stretch across the entire day region, _not_
// just the visible day region.
target = _animator.targetFor(_hourGrid);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -