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

📄 calendardisplay.as

📁 用Flex实现的一个关于减肥系统的web界面,内部没有实际的业务逻辑,只是一个原形.
💻 AS
📖 第 1 页 / 共 5 页
字号:
		}
		
		// the last hour visible on screen based on our current scroll position.
		private function get lastVisibleHour():Number
		{
			return _scrollHour + Math.floor(_dayAreaHeight / _hourHeight*2)/2;
		}

		// this function will return the scroll position the can best guarantee that the events
		// passed in would be visible on screen.
		private function computeScrollHourToDisplayEvents(events:Array):Number
		{
			if(events.length == 0)
				return 8;
				
			var hoursSortedByStartTime:Array = events.concat();
			hoursSortedByStartTime.sort(function(lhs:CalendarEvent, rhs:CalendarEvent):Number
			{
				var ltime:Number = _tz.timeOnly(lhs.start);
				var rtime:Number = _tz.timeOnly(rhs.end);
				return (rhs.allDay || ltime < rtime)? -1:
					   (lhs.allDay || ltime > rtime)? 1:
					   					0;
			}
			);
			return hoursSortedByStartTime[0].allDay? 8:hoursSortedByStartTime[0].start.hours;
		}
		

//----------------------------------------------------------------------------------------------------
// animation callbacks
//----------------------------------------------------------------------------------------------------
		
		// initialization function for the layout of new events appearing on screen.  The LayoutAnimator
		// will call this for each event that gets rendered for the first time.
		private function setupNewEventTarget(target:LayoutTarget):void
		{
			// if it's an item being dragged, we don't want any animation on it,
			// just to have it initialize to its starting position, size, and scale.
			if(_dragEventData != null && IDataRenderer(target.item).data == _dragEventData.event)
			{
				target.item.setActualSize(target.unscaledWidth,target.unscaledHeight);
				target.item.x = target.x;
				target.item.y = target.y;
				var m:Matrix = DisplayObject(target.item).transform.matrix;
				m.a = m.d = 1;
				DisplayObject(target.item).transform.matrix = m;
			}
			else
			{
				// we want new items to zoom out from their center point.
				target.item.setActualSize(target.unscaledWidth,target.unscaledHeight);
				target.item.x = target.x + target.unscaledWidth/2;
				target.item.y = target.y + target.unscaledHeight/2;
				m = DisplayObject(target.item).transform.matrix;
				m.a = m.d = 0;
				DisplayObject(target.item).transform.matrix = m;
			}
		}
		
		// an initializer function for items that we want to fade in to place
		// at their full size.
		private function fadeInTarget(target:LayoutTarget):void
		{
			target.item.setActualSize(target.unscaledWidth,target.unscaledHeight);
			target.item.x = target.x;
			target.item.y = target.y;
			target.item.alpha = 0;
		}
		
		// a remove function for items that we want to fade out in place
		// at their full size.
		private function fadeOutTarget(target:LayoutTarget):void
		{
			target.alpha = 0;
			target.unscaledHeight = target.item.height;
			target.unscaledWidth  = target.item.width;
			target.x = target.item.x;
			target.y = target.item.y;						
		}
		
		
//----------------------------------------------------------------------------------------------------
// managing event data
//----------------------------------------------------------------------------------------------------

		// this function makes sure that our EventData objects, which store all the metadata we need to
		// render a single CalendarEvent, are in sync with our data provider.
		private function updateEventData():void
		{
			// normally, when we update the screen, any events that were previously
			// on screen animate to their new position, and any new ones appear.
			// Sometimes, however, we don't want existing events to animate into place...
			// we just want all events on screen to just appear in place (i.e., sometimes
			// it would look odd to the user to try and correlate the previous view to the new
			// view).
			if(false && _removeAllEventData)
			{
				// throw out all previous event data.  Our animation keys off the identify of our
				// eventData objects, so if we throw them all out, every event will be new from an
				// animation perspective.
				removeAllEventData();
				for(var i:int = 0;i<_visibleEvents.length;i++)
				{
					var event:CalendarEvent = _visibleEvents[i];
					buildEventData(event);
				}
			}
			else
			{
				// we keep a dictionary so we can look up 
				// event data by event.  Here we're going to
				// iterate through our visible events, and build a new lookup dtable.
				// for each event, we'll see if we have a matching eventData in our old 
				// lookup table. If we do, we transfer it to the new one and remove it from the old
				// one. Otherwise, we'll create a new one and add it to the new lookup table.  In the
				// end, we should be left with two lookup tables...the new one, with data for each event
				// now visible on screen, and the old one, which should at that point only have the data
				// for items that are no longer on screen.  So at that point we just cleanup the unneeded old
				// event data, and call it a day.
				var oldEventData:Dictionary = _eventData;
				_eventData = new Dictionary();
				
				for(i = 0;i<_visibleEvents.length;i++)
				{
					event = _visibleEvents[i];
					// try and find data for this event in the old lookup table
					var ed:EventData = oldEventData[event];
					if(ed == null)
					{
						// none existed, so create new data.
						buildEventData(event);
					}
					else
					{
						// some existed, so add it to the lookup table
						_eventData[event] = ed;
						// make sure it's still correct for our new state.
						validateEventData(ed);
						// and remove it from the old lookup table.
						delete oldEventData[event];
					}
				}
				for(var anEvent:* in oldEventData)
				{
					// throw out everything remaining from the old lookup table.
					removeEventData(oldEventData[anEvent]);
				}			
			}
			
		}
		
		// utility function that cleans up every piece of EventData in our lookup table.
		private function removeAllEventData():void
		{
			for(var aKey:* in _eventData)
			{
				var data:EventData = _eventData[aKey];

				for(var i:int=0;i<data.renderers.length;i++)
				{
					// clean up the renderers associated with this event data.
					var renderer:UIComponent = data.renderers[i];
					renderer.parent.removeChild(renderer);
					// make sure our layout animator forgets about it.
					var target:LayoutTarget = _animator.releaseTarget(renderer);
					if(target != null)
						target.animate = false;										
				}
			}
			// all our event data is gone, so start with a fresh lookup table.
			_eventData = new Dictionary();
		}
		
		// remove a single piece of EventData from our lookup table
		private function removeEventData(data:EventData):void
		{
			for(var i:int=0;i<data.renderers.length;i++)
			{
				// clean up all of its renderers
				var renderer:UIComponent = data.renderers[i];
				renderer.parent.removeChild(renderer);
				// and remove it from the lookup table.
				var target:LayoutTarget = _animator.releaseTarget(renderer);
				if(target != null)
					target.animate = false;										
			}
		}
		
		// initalize a new eventData structure for the given CalendarEvent.
		private function buildEventData(event:CalendarEvent):EventData
		{
			var data:EventData = _eventData[event] = new EventData();
			data.renderers = [];
			data.event = event;
			validateEventData(data);
			return data;
		}
		
		
		// utility function that validates a single EventData structure to make 
		// sure it has the right information for the event given our current state.
		private function validateEventData(data:EventData):void
		{
			var event:CalendarEvent = data.event;
			// EventData.range contains the visible portion of the this event's range,
			// given our current visible range. So we intersect the two.
			data.range = event.range.intersect(_visibleRange);
			
			// now, we know how long the visible portion of this event is. We want 
			// to create the renderers we need to display it.  Usually it's 
			// 1-1, but sometimes we need more than one renderer for an event. 
			// specifically, if we're showing multiple weeks, and the event spans
			// more than one week, we'll need 1 renderer for each visible week it spans.
			// find out how many weeks it spans.
			var weekSpan:int = _tz.rangeWeekSpan(data.range);
			// figure out where we're going to place these events.  Because we scroll and mask
			// intra-day events in days view, we need to place it in a different parent
			// than all/multi day events
			var parent:UIComponent = (event.allDay)? _allDayEventLayer:_eventLayer;
			var sn:String = getStyle("eventStyleName");
			var rendererCount:Number = data.renderers.length;

			// if we don't have enough renderers for this event			
			if(weekSpan > rendererCount)
			{
				for(var i:int = rendererCount;i<weekSpan;i++)
				{				
					// create a renderer, listen for mouse down events
					var renderer:CalendarEventRenderer = new CalendarEventRenderer();
					renderer.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownOnEventHandler);
					data.renderers.push(renderer);
					// assign it the right data and style.
					renderer.data = event;
					renderer.styleName = sn;
					parent.addChild(renderer);
					if(data == _dragEventData)					
					{
						// if we're currently dragging this event, we need to give it a nice dropshadow.
						// TODO: centralize the configuration of  a dragging item, and make it customizable
						renderer.filters = [
							_dragFilter
						]									
					}
				}
			}
			else
			{
				// we have too many renderers, so let's throw the extra ones away.
				for(i = weekSpan;i<rendererCount;i++)
				{
					renderer = data.renderers[i];
					//Check if the renderer is null, if null, we needn't remove it.
					if(renderer!=null){
						renderer.parent.removeChild(renderer);
					}
				}
				data.renderers.splice(weekSpan,rendererCount-weekSpan);
			}
		}
		
//----------------------------------------------------------------------------------------------------
// click event handlers
//----------------------------------------------------------------------------------------------------

		// event handler called when the user clicks on a day header.
		private function headerClickHandler(e:MouseEvent):void
		{
			var d:Date = IDataRenderer(e.currentTarget).data as Date;
			if(d == null)
				return;
			// rename and redispatch the event
			var newEvent:CalendarDisplayEvent = new CalendarDisplayEvent(CalendarDisplayEvent.HEADER_CLICK);
			newEvent.dateTime = d;
			dispatchEvent(newEvent);
		}

		// event handler called when the user clicks on a day		
		private function dayClickHandler(e:MouseEvent):void
		{
			
			
			
			var d:Date = IDataRenderer(e.currentTarget).data as Date;
			if(d == null)
				return;
			//rename and redispatch the event
			var newEvent:CalendarDisplayEvent = new CalendarDisplayEvent(CalendarDisplayEvent.DAY_CLICK);
			newEvent.dateTime = d;
			dispatchEvent(newEvent);
			
		}
		
		

//----------------------------------------------------------------------------------------------------
// event dragging behavior
//----------------------------------------------------------------------------------------------------

		// converts a point, in the calendar's coordinate system, into a date.
		private function localToDateTime(pt:Point):Date
		{
			var result:Date = new Date(_visibleRange.start);
			if(_displayMode == "day" || _displayMode == "days")
			{
				// in day(s) mode, we only have one row.  So we convert our horizontal position into
				// an index by dividing by the width of each day
				var dayIndex:Number = (pt.x - _border.left)/_cellWidth;				
				dayIndex = Math.floor(Math.max(dayIndex,0));
				
				// in day(s) mode, the vertical position corresponds to the hour.  So we divide the y value
				// by the height of one our, accounting for our current scroll position.
				var hourCount:Number = (pt.y + _scroller.scrollPosition - _allDayAreaHeight)/_hourHeight;
				// round off to half hours (this probably should be configurable)
				// TODO: make the roundoff configurable
				hourCount = Math.round(hourCount*2)/2;
				// if the mouse is too high or too low, it will round out to the next day. So clamp it.
				hourCount = Math.max(0,Math.min(24,hourCount));
				
				
				
				// add our hour and day calculations to the start of our visible range to get the actual time represented.
				result.date += dayIndex;
				result.milliseconds = result.seconds = result.minutes = 0;
				result.hours = Math.floor(hourCount);
				result.minutes = (hourCount - result.hours)*60;
				// we didn't clamp our day range...so if we go beyond our horizontal range, clamp it to the last day of the visible range.
				if(result > _visibleRange.end)
				{
					result.fullYear = _visibleRange.end.fullYear;
					result.date = _visibleRange.end.date;
					result.month = _visibleRange.end.month;
				}
			}
			else
		

⌨️ 快捷键说明

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