Ejemplo n.º 1
0
        /// <summary>
        /// Calculate the appointment bounds. This works out the size and
        /// shape that the appointments will take up on the screen,
        /// and handles any other calculations such as overlaps. This method
        /// is called from OnPaint only when the property BoundsValidAppointment
        /// is set to false (this property is set to false in cases such as
        /// when the control has been resized or the appointment list has
        /// changed).
        /// </summary>
        protected override void CalculateAppointmentBounds(Graphics graphics)
        {
            //int appSeparator = 3;
            //recalculate the appointments
            foreach (DayWithHourRegion day in this.DayRegions)
            {
                //clear day and hour appointment regions
                day.Appointments.Clear();
                foreach (HourRegion hour in day.Hours)
                {
                    hour.Appointments.Clear();
                }

                //TODO: cater for overlapping multiple timeslots
                foreach (Appointment app in Appointments)
                {
                    if (app.DateStart.Year == day.Date.Year && app.DateStart.DayOfYear == day.Date.DayOfYear)
                    {
                        AppointmentWithHourRegion appRegion = new AppointmentWithHourRegion(app);
                        day.Appointments.Add(appRegion);
                        foreach (HourRegion hour in day.Hours)
                        {
                            if (app.DateStart.Hour == hour.Hour) // && app.DateStart.Hour <= hour.Hour)
                            {
                                hour.Appointments.Add(appRegion);
                            }
                        }
                    }
                }
                foreach (AppointmentWithHourRegion appt1 in day.Appointments)
                {
                    foreach (AppointmentWithHourRegion appt2 in day.Appointments)
                    {
                        if (appt1 != appt2
                            &&
                            appt1.Appointment.DateEnd != appt2.Appointment.DateStart
                            &&
                            appt1.Appointment.DateStart != appt2.Appointment.DateEnd
                            &&
                            (
                                appt2.Appointment.DateStart == appt1.Appointment.DateStart
                                ||
                                appt2.Appointment.DateEnd == appt1.Appointment.DateEnd
                                ||
                                (appt2.Appointment.DateStart < appt1.Appointment.DateEnd &&
                                 appt2.Appointment.DateStart > appt1.Appointment.DateStart)
                                ||
                                (appt2.Appointment.DateEnd < appt1.Appointment.DateEnd &&
                                 appt2.Appointment.DateEnd > appt1.Appointment.DateStart)
                                ||
                                (appt1.Appointment.DateEnd < appt2.Appointment.DateEnd &&
                                 appt1.Appointment.DateEnd > appt2.Appointment.DateStart)

                            )
                            )
                        {
                            appt1.HasOverlaps = true;
                            appt2.HasOverlaps = true;
                            if (!appt1.OverlappingAppointments.Contains(appt2))
                            {
                                appt1.OverlappingAppointments.Add(appt2);
                            }
                            if (!appt2.OverlappingAppointments.Contains(appt1))
                            {
                                appt2.OverlappingAppointments.Add(appt1);
                            }
                        }
                    }
                }
                //roughly work out appt bounds and starting slot
                for (int i = 0; i < day.Hours.Count; i++)
                {
                    HourRegion hour  = day.Hours[i];
                    int        apptY = hour.Bounds.Y;
                    if (hour.Appointments.Count > 0)
                    {
                        int hourX = hour.Bounds.X;

                        int apptX = hourX;
                        for (int j = 0; j < hour.Appointments.Count; j++)
                        {
                            AppointmentWithHourRegion app = hour.Appointments[j];

                            //work out starting slot
                            int startMinute = app.Appointment.DateStart.Minute;
                            if (startMinute >= 0 && startMinute < 15)
                            {
                                app.StartingSlot = 0;
                            }
                            else if (startMinute >= 15 && startMinute < 30)
                            {
                                app.StartingSlot = 1;
                            }
                            else if (startMinute >= 30 && startMinute < 45)
                            {
                                app.StartingSlot = 2;
                            }
                            else if (startMinute >= 45 && startMinute < 60)
                            {
                                app.StartingSlot = 3;
                            }

                            //work out duration and therefore height
                            TimeSpan span           = app.Appointment.DateEnd.Subtract(app.Appointment.DateStart);
                            int      tempApptHeight = ((span.Hours * 60 + span.Minutes) / 15) * hour.Bounds00.Height;
                            int      tempApptY      = apptY + (app.StartingSlot * hour.Bounds00.Height);

                            int apptWidth = hour.Bounds.Width;

                            //if we have overlaps, things get nasty
                            if (app.HasOverlaps)
                            {
                                int hourAppWidth = apptWidth / hour.Appointments.Count;
                                apptWidth = hourAppWidth;
                            }
                            app.Bounds = new Rectangle(apptX, tempApptY, apptWidth, tempApptHeight);

                            //set the bounds
                            apptX += apptWidth;
                        }
                    }
                }

                //go over again a few times to resolve overlaps
                for (int i = 0; i < 5; i++)
                {
                    handleOverlaps(day);
                }
            }
            BoundsValidAppointment = true;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Calculate the time slot bounds. This works out the size and
        /// shape that days will take up on the screen. This method
        /// is called from OnPaint only when the property BoundsValidTimeSlot
        /// is set to false (this property is set to false in cases such as
        /// when the control has been resized or the date shown has
        /// changed).
        /// </summary>
        protected override void CalculateTimeSlotBounds(Graphics g)
        {
            if (Width == 0 || Height == 0)
            {
                return;
            }

            DayRegions.Clear();
            hourHeaders.Clear();

            int numberOfDays = 1;

            //set up the start day
            if (!SingleDay)
            {
                //five days
                numberOfDays = 5;
                if (Date.DayOfWeek != DayOfWeek.Monday)
                {
                    //handle sunday being set - go forwards in that case
                    if (Date.DayOfWeek == DayOfWeek.Sunday)
                    {
                        Date = Date.AddDays(1);
                    }
                    else if (Date.DayOfWeek == DayOfWeek.Saturday)
                    {
                        Date = Date.AddDays(2);
                    }
                    else
                    {
                        DateTime temp = Date;
                        while (temp.DayOfWeek != DayOfWeek.Monday)
                        {
                            temp = temp.AddDays(-1);
                        }
                        Date = temp;
                    }
                }
            }

            //set up days
            for (int i = 0; i < numberOfDays; i++)
            {
                DayWithHourRegion day = new DayWithHourRegion();
                day.Date             = Date.AddDays(i);
                day.IsInCurrentMonth = true;
                this.DayRegions.Add(day);
            }

            int hourCount = 0;

            //set up hours
            for (int j = 0; j < DayRegions.Count; j++)
            {
                DayWithHourRegion day = DayRegions[j] as DayWithHourRegion;
                if (day != null)
                {
                    for (int i = 0; i < 24; i++)
                    {
                        if (RenderWorkingHoursOnly)
                        {
                            if (i >= (WorkStartHour - 1) && i < (WorkEndHour + 1))
                            {
                                HourRegion hour = new HourRegion();
                                hour.IsWorkingHour = (i >= WorkStartHour && i < WorkEndHour);
                                hour.Hour          = i;
                                day.Hours.Add(hour);
                            }
                        }
                        else
                        {
                            HourRegion hour = new HourRegion();
                            hour.IsWorkingHour = (i >= WorkStartHour && i < WorkEndHour);
                            hour.Hour          = i;
                            day.Hours.Add(hour);
                        }
                    }
                    if (j == 0)
                    {
                        hourCount = day.Hours.Count;
                    }
                }
            }

            int timeMarkerWidth = 0;

            if (this.Width > 120)
            {
                timeMarkerWidth = 80;
            }

            int dayHeaderHeight = (int)(RendererCache.Current.Header.GetTextInfo(g, this.Font).Height * 1.2);

            int hourHeight = ((Height - 1 - dayHeaderHeight) / hourCount);
            int xCurrent   = timeMarkerWidth;
            int hourWidth  = (Width - timeMarkerWidth - 1) / numberOfDays;

            int bounds15height = (hourHeight) / 4;

            //set up day and hour bounds
            for (int j = 0; j < DayRegions.Count; j++)
            {
                DayWithHourRegion day = DayRegions[j] as DayWithHourRegion;

                if (day != null)
                {
                    int yCurrent = dayHeaderHeight;
                    //set up day bounds
                    day.Bounds      = new Rectangle(xCurrent, 0, hourWidth, hourHeight * day.Hours.Count);
                    day.Name        = day.Date.DayOfWeek.ToString();
                    day.TitleBounds = new Rectangle(xCurrent, 0, hourWidth, dayHeaderHeight);
                    day.BodyBounds  = new Rectangle(day.Bounds.X, day.Bounds.Y, day.Bounds.Width, day.Bounds.Height);


                    foreach (HourRegion hour in day.Hours)
                    {
                        //work out the hour bounds
                        hour.Bounds = new Rectangle(xCurrent, yCurrent, hourWidth, hourHeight);

                        //work out the 15 minute divisions
                        hour.Bounds00 = new Rectangle(xCurrent, yCurrent, hourWidth, bounds15height);
                        hour.Bounds15 = new Rectangle(xCurrent, yCurrent + hour.Bounds00.Height, hourWidth,
                                                      bounds15height);
                        hour.Bounds30 = new Rectangle(xCurrent, yCurrent + hour.Bounds00.Height + hour.Bounds15.Height,
                                                      hourWidth, bounds15height);
                        hour.Bounds45 = new Rectangle(xCurrent,
                                                      yCurrent + hour.Bounds00.Height + hour.Bounds15.Height +
                                                      hour.Bounds30.Height, hourWidth,
                                                      bounds15height);

                        if (j == 0)
                        {
                            HeaderRegion header = new HeaderRegion();
                            header.Bounds = new Rectangle(0, yCurrent, timeMarkerWidth, hourHeight);
                            header.Name   = string.Format("{0}:00", hour.Hour);
                            hourHeaders.Add(header);
                        }
                        yCurrent += hourHeight;
                    }
                }
                xCurrent += hourWidth;
            }
            BoundsValidTimeSlot = true;
        }