⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calendardisplay.as

📁 用Flex实现的一个关于减肥系统的web界面,内部没有实际的业务逻辑,只是一个原形.
💻 AS
📖 第 1 页 / 共 5 页
字号:
			target.initializeFunction = fadeInTarget;
			target.releaseFunction = fadeOutTarget;
			target.x = 0;
			target.y = _allDayAreaHeight - _scroller.scrollPosition;
			target.unscaledWidth = unscaledWidth - _border.right;
			target.unscaledHeight = 24 * _hourHeight;
			target.alpha = 1;

			// lay out the border that demarks the all-day event area.
			target = _animator.targetFor(_allDayEventBorder);
			target.x = _border.left+1;
			target.y = _border.top + header.measuredHeight+1;
			target.unscaledWidth = unscaledWidth - _border.left - _border.right - 1;
			target.unscaledHeight = _allDayAreaHeight - target.y - 1;

			// allright, time to lay out our intra-day events.			

			var daysEvents:Array = null;
			
			// for each day
			for(rPos=0;rPos < _rowLength;rPos++)
			{
				daysEvents = null;
				// find the first event in our (sorted by start time) visible event list that starts
				// _later_ than today.
				for(i=0;i<events.length;i++)
				{
					if(events[i].start.getTime() >= endOfDay.getTime())
					{
						// we found one that doesn't start today; let's grab
						// the ones that _do_ start today.
						daysEvents = events.splice(0,i);
						break;
					}
				}
				// if we didn't find one that starts later than today,
				// then _all_ of them start today.
				if(daysEvents == null)
					daysEvents = events;
					
				// OK, we have a day and a set of events on that day...go lay them out.
				layoutSingleDay(daysEvents,_border.left + rPos * _cellWidth,_allDayAreaHeight,_cellWidth,_cellHeight - header.measuredHeight);
				
				
				// advance our markers to the next day.
				startOfDay.date = startOfDay.date+1;
				endOfDay.date = endOfDay.date+1;														
			}
		}
		
		// our layout routine that lays out the intra-day events in a single day.
		private function layoutSingleDay(events:Array, cellLeft:Number,cellTop:Number,_cellWidth:Number,_cellHeight:Number):void
		{
			var openEvents:SortedArray = new SortedArray(null,"end");
			var data:EventData;
			var reservations:ReservationAgent = new ReservationAgent();
			var pendingEvents:Array = [];
			var maxOpenEvents:int = 0;
			var renderer:UIComponent;
			var i:int;
			var target:LayoutTarget;
			
			// we're going to loop until we've process all our events
			while(1)
			{
				
				// if we're out of all events, we can stop.
				if(events.length == 0 && openEvents.length == 0)
					break;
				
				// here's our basic strategy...loop forward, finding all the events that are open at the same time.
				// assign each of those a slot.  As events end, we free up their slot, and reassign them as new events
				// start.  So first, we need to loop forward, finding all the events that start before the next event
				// ends
				while(events.length > 0 && (openEvents.length == 0 || events[0].start.getTime() <= openEvents[0].end.getTime()))
				{
					// we need to consider this event.
					var nextEvent:CalendarEvent = events.shift();
					data = _eventData[nextEvent];
					// assign an unused space to our event.
					data.lane = reservations.reserve(nextEvent);
					openEvents.addItem(nextEvent);
					maxOpenEvents = Math.max(maxOpenEvents,openEvents.length);
				}
				
				// OK, we have a list of events that are open at the same time.  Each open event has a slot assigned to it.
				// Now we loop forward, closing out all events that close before the next event starts.
				while(openEvents.length > 0 && (events.length == 0 || openEvents[0].end.getTime() < events[0].start.getTime()))
				{
					var closingEvent:CalendarEvent = openEvents.shift();
					// we're going to need to do some postprocessing on these events, so let's add it to a running list.
					pendingEvents.push(closingEvent);
					// free up its slot for reuse.
					reservations.release(closingEvent);

					// if we have no open events left, then we've considered a full set of contiguous events. That means
					// that for each of the events in this block, we have all the info we need to decide how to render it.
					// so we'll do our postprocessing, and position each event.
					if(openEvents.length == 0)
					{
						// we know the maximum number of events we'll have open at any one time...that tells us how						
						// wide each event will be.
						var laneWidth:Number = _cellWidth/maxOpenEvents;
						
						for(i=0;i<pendingEvents.length;i++)
						{
							data = _eventData[pendingEvents[i]];
							renderer = data.renderers[0];
							// make sure the renderer is in its expanded mode.
							ICalendarEventRenderer(renderer).displayMode = "box";
							// now lay out that single event.  It's position
							// is a combination of what hour it starts, what slot it got placed in,
							// its duration, the scroll position of the calendar, and the borders.
							target = layoutSingleEvent(data,renderer,
								cellLeft + EVENT_INSET + data.lane * laneWidth,
								-_scroller.scrollPosition + _hourHeight * ((data.range.start.getTime() - _tz.startOfDay(data.range.start).getTime()) / DateUtils.MILLI_IN_HOUR) + cellTop,
								laneWidth - 2*EVENT_INSET,
								_hourHeight * (data.range.end.getTime() - data.range.start.getTime()) / DateUtils.MILLI_IN_HOUR
							);
							target.animate = true;
							renderer.visible = true;					
						}
						
						// on to our next block of contiguous events.
						maxOpenEvents = 0;
						pendingEvents = [];
					}
				}

			}

		}

		// our main layout routine that is responsible for rendering month view.
		private function layoutMonth():void
		{
			var startOfDay:Date = dateForIndex(0);
			var endOfDay:Date = dateForIndex(1);
			var openEvents:SortedArray = new SortedArray(null,"end");
			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 cPos:int;
			var i:int;
			var openingEvents:Array;
			var aboveBottom:Boolean;
			
			// first layout the days and day headers.
			layoutCells();
			
			// since we're rendering full screen, and we're not doing any scrolling, we 
			// won't need a mask.
			_eventLayer.mask = null; 
			_eventMask.visible = false;

			// we won't do any scrolling, so let's hide our scrollbar.
			target = _animator.releaseTarget(_scroller);
			if(target != null)
				target.animate = false;
			
			// month view doesn't have any gridlines, so hide the gridlines.
			target = _animator.releaseTarget(_hourGrid);
			if(target != null)
				target.animate = false;
			
			// same things for our all-day event border.
			target = _animator.releaseTarget(_allDayEventBorder);
			if(target != null)
				target.animate = false;

			// alright, now we're going to lay out day by day. So for each row, for each column...
			for(cPos = 0;cPos<_columnLength;cPos++)
			{
				for(rPos=0;rPos < _rowLength;rPos++)
				{
					// the index of the current day in our visible range.
					var index:int = rPos + cPos*_rowLength;
					// the header for this day.
					var header:UIComponent = _headerCache.instances[index];

					// look at our list of open events. If any of these events 
					// have ended before today....
					while (openEvents.length > 0 && openEvents[0].end < startOfDay)
					{
						reservations.release(openEvents.shift());
					}
					
					// if there are still events we haven't processed yet...
					if(events.length > 0)
					{
						openingEvents = [];
						
						
						// find all the events from our (start time sorted) list that start _before_ today.
						// note that since we're trimming this list as we go, this really means all the events 
						// that start _today_.		
						while(events.length > 0 && events[0].start.getTime() < endOfDay.getTime())
						{
							data = _eventData[events.shift()];
							openEvents.addItem(data.event);
							openingEvents.push(data);
						}
						
						//we're going to lay out these events vertically. So start from the bottom of the header.
						renderTop = header.measuredHeight;
						
						// for each opening event...
						for(i=0;i<openingEvents.length;i++)
						{
							data = openingEvents[i];
							// assign it a slot.
							var reservation:int = reservations.reserve(data.event);
							// now if the event only intersects with a single week
							if(_tz.rangeWeekSpan(data.range) == 1)
							{
								// it should only have a single renderer
								renderer = data.renderers[0];
								// put it into its compact line mode.
								ICalendarEventRenderer(renderer).displayMode = "line";
								// and lay out that one single renderer to match the length of the event
								// (at least, the length of its intersection with the visible range)
								target = layoutSingleEvent(data,renderer,
									_border.left + rPos * _cellWidth + EVENT_INSET,
									_border.top + cPos * _cellHeight + renderTop + renderer.measuredHeight * reservation,
									_cellWidth * Math.max(1,_tz.rangeDaySpan(data.range)) - 2*EVENT_INSET,
									renderer.measuredHeight
								);
								// if this event is below the bottom of the day it is contained in,
								// we want to hide it.
								aboveBottom = (target.y + target.unscaledHeight <= _border.top + (cPos+1) * _cellHeight)
								target.animate = aboveBottom;
								renderer.visible = aboveBottom;
							}
							else
							{
								// this event intersects with multiple weeks. That means it needs to span
								// multiple rows. So it should have N renderers associated with it,
								// one for each week it intersects. We need to lay each one out appropriately.
								var weekSpan:int = _tz.rangeWeekSpan(data.range);
								// how many days this event (or its intersection with the visible range)
								// spans.
								var daysRemaining:int = _tz.rangeDaySpan(data.range);
								// where the renderer should start. For our first renderer, it will start on the first
								// day of the event.  All remaining renderers will start on sunday.
								var rendererStart:int = rPos;
								// for each week it intersects
								for(var j:int = 0;j<weekSpan;j++)
								{
									// grab a renderer assigned to it.
									renderer = data.renderers[j];
									if(renderer != null){
										// put it in compact mode.
										ICalendarEventRenderer(renderer).displayMode = "line";
										// figure out how long it should be, based on its start position, and 
										// the length of the event.
										var currentDaySpan:int = Math.min(daysRemaining, 7 - rendererStart);
										// and position it.
										target = layoutSingleEvent(data,renderer,
											_border.left + rendererStart * _cellWidth + EVENT_INSET,
											_border.top + (cPos + j) * _cellHeight + renderTop + renderer.measuredHeight * reservation,
											_cellWidth * currentDaySpan - 2*EVENT_INSET,
											renderer.measuredHeight
										);
										// again, if we have so many events that this event ends up below the bottom of the day,
										// we'll hide it.
										aboveBottom = (target.y + target.unscaledHeight <= _border.top + (cPos+j+1) * _cellHeight)
										target.animate = aboveBottom;
										renderer.visible = aboveBottom;
										
										// keep track of how many days remain to be rendererd for this event.
										daysRemaining -= currentDaySpan;
										// and make a note of the fact that for the next week, we want the renderer to start
										// on day 0...sunday.
										rendererStart  = 0;
									}
								}
							}
							
						}
					}
					
					// advance to our next day.
					startOfDay.date = startOfDay.date+1;
					endOfDay.date = endOfDay.date+1;														
				}
			}
		}

		// utility function for laying out a single day.
		private function layoutSingleEvent(eventData:EventData, renderer:UIComponent,x:Number,y:Number,w:Number,h:Number):LayoutTarget
		{
			// grab our LayoutTarget object for this event renderer.
			var target:LayoutTarget = _animator.targetFor(renderer);
			// to make our lives easier, we don't bother trying to deal with tracking which events have been renderered before, and which
			// ones haven't.  We just give the layoutTarget an init function, and if the layout animator has never seen it before,
			// it calls the init function for us.
			target.initializeFunction = setupNewEventTarget;
			target.alpha = 1;
						
			// we'll render events that are currently the target of a drag operation a little differently
			if(_dragEventData == eventData)
			{
				
				// if it's being moved, we want it to have a nice transparent look to indicate that its position is temporary.
				if (_dragType != DragType.RESIZE)
				{
					target.alpha = .5;
				}
			}
			target.x = x;
			target.y = y;


			target.unscaledHeight = h;
			target.unscaledWidth = w
			return target;
		}




		
		
//----------------------------------------------------------------------------------------------------
// scrolling
//----------------------------------------------------------------------------------------------------

		// callback for when the user scrolls with the scrollbar.
		private function scrollHandler(event:ScrollEvent):void
		{
			_scrollHour = _scroller.scrollPosition / _hourHeight;
			_animator.invalidateLayout(false);
			// scrolling is live feedback, so we don't want to bother with animation.
			_animator.updateLayoutWithoutAnimation();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -