protected void DrawBar(Graphics gr, WorkingHoursConfiguration config, Bar bar)
        {
            if (bar == null)
            {
                return;
            }

            float height   = (float)bar.Height;
            float start    = (float)config.time_end - (float)bar.start.TimeOfDay.TotalHours - height;
            float x_offset = 0;

            // center for lone bars
            if (config.show_unlocked_hours && !config.show_work_hours ||
                !config.show_unlocked_hours && config.show_work_hours)
            {
                x_offset = 2;
            }
            else if (bar.is_unlocked)   // right for the second bar (unlocked bar)
            {
                x_offset = 8;
            }

            if (config.show_detailed_weeks)
            {
                gr.FillRectangle(bar.color, 25 + bar.day_of_week * 20 + x_offset, 10 + start * config.zoom_amount, 7, height * config.zoom_amount);
            }
            else
            {
                if (!bar.is_unlocked && bar.Height > 0)
                {
                    gr.DrawString(bar.Height.ToHourMinuteString(), font_small, Brushes.Black, 21 + bar.day_of_week * 20 + x_offset, -5 + (float)(config.GraphHours - bar.Height) * config.zoom_amount);
                }
                gr.FillRectangle(bar.color, 25 + bar.day_of_week * 20 + x_offset, 10 + (float)(config.GraphHours - bar.Height) * config.zoom_amount, 7, (float)bar.Height * config.zoom_amount);
            }
        }
Exemple #2
0
        public BarCreator( WorkingHoursConfiguration config, DateTime week_start, DateTime week_end )
        {
            this.config             = config;
            this.week_start         = week_start;
            this.week_end           = week_end;

            work_color              = new SolidBrush( config.work_bar_color );
            latest_work_color       = new SolidBrush( config.latest_work_bar_color );
            unlocked_color          = new SolidBrush( config.unlocked_bar_color );
            latest_unlocked_color   = new SolidBrush( config.latest_unlocked_bar_color );

            first_unlock_date       = invalid_date;
            last_unlock_date        = invalid_date;
            last_lock_date          = invalid_date;
        }
        public BarCreator(WorkingHoursConfiguration config, DateTime week_start, DateTime week_end)
        {
            this.config     = config;
            this.week_start = week_start;
            this.week_end   = week_end;

            work_color            = new SolidBrush(config.work_bar_color);
            latest_work_color     = new SolidBrush(config.latest_work_bar_color);
            unlocked_color        = new SolidBrush(config.unlocked_bar_color);
            latest_unlocked_color = new SolidBrush(config.latest_unlocked_bar_color);

            first_unlock_date = invalid_date;
            last_unlock_date  = invalid_date;
            last_lock_date    = invalid_date;
        }
        protected void DrawBackground(Graphics gr, WorkingHoursConfiguration config)
        {
            gr.DrawLine(pen_gray, 15, 10, 15, 10 + config.GraphHours * config.zoom_amount);
            for (int i = 0, hours = config.time_end;
                 i <= config.time_end - config.time_start;
                 i++, hours--)
            {
                if (config.full_background_lines)
                {
                    gr.DrawLine(pen_lightgray, 20, 10 + i * config.zoom_amount, 160, 10 + i * config.zoom_amount);
                }
                gr.DrawLine(pen_gray, 15, 10 + i * config.zoom_amount, 20, 10 + i * config.zoom_amount);

                if (config.show_detailed_weeks)
                {
                    if (hours < config.work_start.Hours || hours > config.work_end.Hours)
                    {
                        gr.DrawString(hours.ToString(), font_small, Brushes.LightGray, 1, 5 + i * config.zoom_amount);
                    }
                    else
                    {
                        gr.DrawString(hours.ToString(), font_small, Brushes.Black, 1, 5 + i * config.zoom_amount);
                    }
                }
                else
                {
                    if (config.GraphHours - i <= config.work_hours)
                    {
                        gr.DrawString((config.GraphHours - i).ToString(), font_small, Brushes.Black, 1, 5 + i * config.zoom_amount);
                    }
                    else
                    {
                        gr.DrawString((config.GraphHours - i).ToString(), font_small, Brushes.Red, 1, 5 + i * config.zoom_amount);
                    }
                }
            }

            // bar showing expected working hours
            if (!config.show_detailed_weeks)
            {
                int y = (int)(10 + (config.GraphHours - config.work_hours) * config.zoom_amount);
                if (config.full_background_lines)
                {
                    gr.DrawLine(new Pen(Color.LightSkyBlue, 3), 20, y, 160, y);
                }
                gr.DrawLine(new Pen(Color.DodgerBlue, 3), 15, y, 20, y);
            }
        }
        public void ShowDialog( IWin32Window owner, WorkingHoursConfiguration config )
        {
            b_work_bar_color.BackColor              = config.work_bar_color;
            b_unlocked_bar_color.BackColor          = config.unlocked_bar_color;
            b_latest_work_bar_color.BackColor       = config.latest_work_bar_color;
            b_latest_unlocked_bar_color.BackColor   = config.latest_unlocked_bar_color;
            c_zoom_amount.Value                     = config.zoom_amount;
            c_time_start.Value                      = config.time_start;
            c_time_end.Value                        = config.time_end;
            c_unlocked_hours.Value                  = Convert.ToDecimal( config.unlocked_hours );
            c_work_hours.Value                      = Convert.ToDecimal( config.work_hours );
            cb_show_detailed_weeks.Checked          = config.show_detailed_weeks;
            cb_show_work_hours.Checked              = config.show_work_hours;
            cb_show_unlocked_hours.Checked          = config.show_unlocked_hours;
            cb_full_background_lines.Checked        = config.full_background_lines;
            dtp_work_start.Value                    = DateTime.Today.Add( config.work_start );
            dtp_work_end.Value                      = DateTime.Today.Add( config.work_end );
            cb_log_program_start.Checked            = config.log_program_start;
            cb_log_program_shutdown.Checked         = config.log_program_shutdown;

            if ( ShowDialog( owner ) == DialogResult.OK )
            {
                config.work_bar_color               = b_work_bar_color.BackColor;
                config.unlocked_bar_color           = b_unlocked_bar_color.BackColor;
                config.latest_work_bar_color        = b_latest_work_bar_color.BackColor;
                config.latest_unlocked_bar_color    = b_latest_unlocked_bar_color.BackColor;
                config.zoom_amount                  = Convert.ToInt32( c_zoom_amount.Value );
                config.time_start                   = Convert.ToInt32( c_time_start.Value );
                config.time_end                     = Convert.ToInt32( c_time_end.Value );
                config.unlocked_hours               = Convert.ToDouble( c_unlocked_hours.Value );
                config.work_hours                   = Convert.ToDouble( c_work_hours.Value );
                config.show_detailed_weeks          = cb_show_detailed_weeks.Checked;
                config.show_work_hours              = cb_show_work_hours.Checked;
                config.show_unlocked_hours          = cb_show_unlocked_hours.Checked;
                config.full_background_lines        = cb_full_background_lines.Checked;
                config.work_start                   = dtp_work_start.Value.Subtract( dtp_work_start.Value.Subtract( dtp_work_start.Value.TimeOfDay ) );
                config.work_end                     = dtp_work_end.Value.Subtract( dtp_work_end.Value.Subtract( dtp_work_end.Value.TimeOfDay ) );
                config.log_program_start            = cb_log_program_start.Checked;
                config.log_program_shutdown         = cb_log_program_shutdown.Checked;
            }
        }
        public void ShowDialog(IWin32Window owner, WorkingHoursConfiguration config)
        {
            b_work_bar_color.BackColor            = config.work_bar_color;
            b_unlocked_bar_color.BackColor        = config.unlocked_bar_color;
            b_latest_work_bar_color.BackColor     = config.latest_work_bar_color;
            b_latest_unlocked_bar_color.BackColor = config.latest_unlocked_bar_color;
            c_zoom_amount.Value              = config.zoom_amount;
            c_time_start.Value               = config.time_start;
            c_time_end.Value                 = config.time_end;
            c_unlocked_hours.Value           = Convert.ToDecimal(config.unlocked_hours);
            c_work_hours.Value               = Convert.ToDecimal(config.work_hours);
            cb_show_detailed_weeks.Checked   = config.show_detailed_weeks;
            cb_show_work_hours.Checked       = config.show_work_hours;
            cb_show_unlocked_hours.Checked   = config.show_unlocked_hours;
            cb_full_background_lines.Checked = config.full_background_lines;
            dtp_work_start.Value             = DateTime.Today.Add(config.work_start);
            dtp_work_end.Value               = DateTime.Today.Add(config.work_end);
            cb_log_program_start.Checked     = config.log_program_start;
            cb_log_program_shutdown.Checked  = config.log_program_shutdown;

            if (ShowDialog(owner) == DialogResult.OK)
            {
                config.work_bar_color            = b_work_bar_color.BackColor;
                config.unlocked_bar_color        = b_unlocked_bar_color.BackColor;
                config.latest_work_bar_color     = b_latest_work_bar_color.BackColor;
                config.latest_unlocked_bar_color = b_latest_unlocked_bar_color.BackColor;
                config.zoom_amount           = Convert.ToInt32(c_zoom_amount.Value);
                config.time_start            = Convert.ToInt32(c_time_start.Value);
                config.time_end              = Convert.ToInt32(c_time_end.Value);
                config.unlocked_hours        = Convert.ToDouble(c_unlocked_hours.Value);
                config.work_hours            = Convert.ToDouble(c_work_hours.Value);
                config.show_detailed_weeks   = cb_show_detailed_weeks.Checked;
                config.show_work_hours       = cb_show_work_hours.Checked;
                config.show_unlocked_hours   = cb_show_unlocked_hours.Checked;
                config.full_background_lines = cb_full_background_lines.Checked;
                config.work_start            = dtp_work_start.Value.Subtract(dtp_work_start.Value.Subtract(dtp_work_start.Value.TimeOfDay));
                config.work_end              = dtp_work_end.Value.Subtract(dtp_work_end.Value.Subtract(dtp_work_end.Value.TimeOfDay));
                config.log_program_start     = cb_log_program_start.Checked;
                config.log_program_shutdown  = cb_log_program_shutdown.Checked;
            }
        }
        protected void DrawHours(WorkingHoursConfiguration config, List <EventEntry>[] days, DateTime start_of_week, DateTime end_of_week)
        {
            pb_image.Image = new Bitmap(20 + 15 * 10, config.GraphHours * config.zoom_amount + 60);
            pb_image.Size  = pb_image.Image.Size;
            Graphics gr = Graphics.FromImage(pb_image.Image);

            gr.Clear(Color.White);

            DrawBackground(gr, config);

            double work_avg     = 0;
            double unlocked_avg = 0;

            DrawBars(gr, config, days, start_of_week, end_of_week, out work_avg, out unlocked_avg);

            // draw dates
            for (int i = 0; i < days.Length; i++)
            {
                if (i > 4)
                {
                    gr.DrawString(start_of_week.AddDays(i).Day.ToString(), font_small, Brushes.OrangeRed, 27 + i * 20, config.GraphHours * config.zoom_amount + 20);
                }
                else
                {
                    gr.DrawString(start_of_week.AddDays(i).Day.ToString(), font_small, Brushes.Black, 27 + i * 20, config.GraphHours * config.zoom_amount + 20);
                }
            }
            if (!config.show_detailed_weeks)
            {
                gr.DrawString("W: " + work_avg.ToHourMinuteString(),
                              font_normal,
                              Brushes.Black,
                              pb_image.Width / 2 - 70,
                              config.GraphHours * config.zoom_amount + 40);
            }
            gr.DrawString(start_of_week.ToString("MMM"), font_normal, Brushes.Black, pb_image.Width / 2 - 10, config.GraphHours * config.zoom_amount + 40);
        }
Exemple #8
0
        public void ShowDialog( IWin32Window owner, WorkingHoursConfiguration configuration, List< EventEntry > events )
        {
            if ( events.Count > 0 )
            {
                DateTime d              = events[ 0 ].date;
                DateTime start_of_week  = d.Subtract( new TimeSpan( (int)( d.DayOfWeek )-1, d.Hour, d.Minute, d.Second, d.Millisecond ) );
                DateTime end_of_week    = start_of_week.AddDays( 7 );
                int today               = d.MondayFirstDoW();

                // partition the events into weeks = array of days
                // then create 1 WeekGraph control for every week in the event list
                List< EventEntry >[] days = new List<EventEntry>[ 7 ]; for ( int i=0; i<7; i++ ) days[ i ] = new List<EventEntry>();
                foreach ( EventEntry ee in events )
                {
                    if ( ee.date.CompareTo( end_of_week ) >= 0 )
                    {   // the next week has begun
                        flp_weeks.Controls.Add( new WeekGraph( configuration, days, start_of_week, end_of_week ) );
                        days            = new List<EventEntry>[ 7 ]; for ( int i=0; i<7; i++ ) days[ i ] = new List< EventEntry >();
                        start_of_week   = ee.date.Subtract( new TimeSpan( (int)( ee.date.DayOfWeek )-1, ee.date.Hour, ee.date.Minute, ee.date.Second, ee.date.Millisecond ) );
                        end_of_week     = start_of_week.AddDays( 7 );
                    }
                    days[ ee.date.MondayFirstDoW() ].Add( ee );
                }
                Control last_weekgraph = new WeekGraph( configuration, days, start_of_week, end_of_week );
                flp_weeks.Controls.Add( last_weekgraph );

                // fit the parent form's area to the flowlayoutpanel as closely as possible...
                Rectangle working_area  = Screen.GetWorkingArea( this );
                int controls_per_row    = Math.Min( configuration.max_weeks_per_row,
                                                    Math.Min( working_area.Width / flp_weeks.Controls[ 0 ].Width, flp_weeks.Controls.Count )
                                                  );
                int target_width        = controls_per_row * flp_weeks.Controls[ 0 ].Width;
                int target_height       = 0;
                int control_rows        = ( ( flp_weeks.Controls.Count + controls_per_row - 1 ) / controls_per_row );  // rounded up
                bool scrollbar_appeared = false;
                if ( working_area.Height > 1.5* control_rows * flp_weeks.Controls[ 0 ].Height )
                {
                    target_height = ( (flp_weeks.Controls.Count + controls_per_row - 1 ) / controls_per_row ) * flp_weeks.Controls[ 0 ].Height;
                }
                else if ( working_area.Height > flp_weeks.Controls[ 0 ].Height )
                {
                    target_height = flp_weeks.Controls[ 0 ].Height;
                    scrollbar_appeared = true;
                }
                else
                {
                    target_height = working_area.Height * 8 / 10;
                    scrollbar_appeared = true;
                }
                if ( scrollbar_appeared )
                {
                    target_width += SystemInformation.VerticalScrollBarWidth;
                }

                this.Width  = 10 + target_width;
                this.Height = 10 + target_height + b_ok.Height + this.Height - this.ClientRectangle.Height;

                flp_weeks.ScrollControlIntoView( last_weekgraph );
            }

            ShowDialog( owner );
        }
Exemple #9
0
        protected void DrawHours( WorkingHoursConfiguration config, List< EventEntry >[] days, DateTime start_of_week, DateTime end_of_week )
        {
            pb_image.Image      = new Bitmap( 20 + 15*10, config.GraphHours * config.zoom_amount + 60 );
            pb_image.Size       = pb_image.Image.Size;
            Graphics gr         = Graphics.FromImage( pb_image.Image );
            gr.Clear( Color.White );

            DrawBackground( gr, config );

            double work_avg     = 0;
            double unlocked_avg = 0;
            DrawBars( gr, config, days, start_of_week, end_of_week, out work_avg, out unlocked_avg);

            // draw dates
            for ( int i=0; i<days.Length; i++ )
            {
                if ( i > 4 )
                {
                    gr.DrawString( start_of_week.AddDays( i ).Day.ToString(), font_small, Brushes.OrangeRed, 27 + i*20, config.GraphHours * config.zoom_amount + 20 );
                }
                else
                {
                    gr.DrawString( start_of_week.AddDays( i ).Day.ToString(), font_small, Brushes.Black,     27 + i*20, config.GraphHours * config.zoom_amount + 20 );
                }
            }
            if ( !config.show_detailed_weeks )
            {
                gr.DrawString( "W: " + work_avg.ToHourMinuteString(),
                                font_normal,
                                Brushes.Black,
                                pb_image.Width / 2 - 70,
                                config.GraphHours * config.zoom_amount + 40 );
            }
            gr.DrawString( start_of_week.ToString( "MMM" ), font_normal, Brushes.Black, pb_image.Width / 2 - 10, config.GraphHours * config.zoom_amount + 40 );
        }
Exemple #10
0
        protected void DrawBars(    Graphics                    gr, 
                                    WorkingHoursConfiguration   config, 
                                    List< EventEntry >[]        days, 
                                    DateTime                    start_of_week, 
                                    DateTime                    end_of_week, 
                                    out double                  work_hours_week, 
                                    out double                  unlocked_hours_week )
        {
            double work_hours_day       = 0;
            double unlocked_hours_day   = 0;
            int work_days               = 0;
            work_hours_week             = 0;
            unlocked_hours_week         = 0;
            BarCreator bar_creator      = new BarCreator( config, start_of_week, end_of_week );

            for ( int i = 0; i < days.Length; i++ )
            {
                work_hours_day     = 0;
                unlocked_hours_day = 0;

                foreach ( EventEntry ee in days[ i ] )
                {
                    Bar bar = bar_creator.GetBar( ee );
                    if ( config.show_detailed_weeks || bar == null )
                    {
                        DrawBar( gr, config, bar );
                    }
                    else
                    {
                        if ( bar.is_unlocked )
                        {
                            unlocked_hours_day += bar.Height;
                        }
                        else
                        {
                            work_hours_day += bar.Height;
                        }
                    }
                }

                foreach ( Bar b in bar_creator.GetFinalBarsForDay() ) // last unlock - now
                {
                    if ( config.show_detailed_weeks )
                    {
                        DrawBar( gr, config, b );
                    }
                    else
                    {
                        if ( b.is_unlocked )
                        {
                            unlocked_hours_day += b.Height;
                        }
                        else
                        {
                            work_hours_day += b.Height;
                        }
                    }
                }
                if ( !config.show_detailed_weeks )
                {
                    Bar b1 = new Bar( new SolidBrush( config.work_bar_color     ), i, false, start_of_week.AddDays( i ), start_of_week.AddDays( i + work_hours_day     / 24 ) );
                    Bar b2 = new Bar( new SolidBrush( config.unlocked_bar_color ), i, true,  start_of_week.AddDays( i ), start_of_week.AddDays( i + unlocked_hours_day / 24 ) );
                    DrawBar( gr, config, b1 );
                    DrawBar( gr, config, b2 );
                }

                if ( work_hours_day > 0 || unlocked_hours_day > 0 )
                {
                    work_days++;
                }

                work_hours_week     += work_hours_day;
                unlocked_hours_week += unlocked_hours_day;
            }
            work_hours_week     /= work_days;
            unlocked_hours_week /= work_days;
        }
Exemple #11
0
        protected void DrawBar( Graphics gr, WorkingHoursConfiguration config, Bar bar )
        {
            if ( bar == null ) return;

            float height    = (float)bar.Height;
            float start     = (float)config.time_end - (float)bar.start.TimeOfDay.TotalHours - height;
            float x_offset  = 0;

            // center for lone bars
            if (     config.show_unlocked_hours && !config.show_work_hours ||
                    !config.show_unlocked_hours &&  config.show_work_hours )
            {
                x_offset = 2;
            }
            else if ( bar.is_unlocked ) // right for the second bar (unlocked bar)
            {
                x_offset = 8;
            }

            if ( config.show_detailed_weeks )
            {
                gr.FillRectangle( bar.color, 25 + bar.day_of_week*20 + x_offset, 10 + start * config.zoom_amount, 7, height * config.zoom_amount );
            }
            else
            {
                if ( !bar.is_unlocked && bar.Height > 0 )
                {
                    gr.DrawString( bar.Height.ToHourMinuteString(), font_small, Brushes.Black, 21 + bar.day_of_week*20 + x_offset, -5 + (float)( config.GraphHours - bar.Height ) * config.zoom_amount );
                }
                gr.FillRectangle( bar.color, 25 + bar.day_of_week*20 + x_offset, 10 + (float)(config.GraphHours - bar.Height) * config.zoom_amount, 7, (float)bar.Height * config.zoom_amount );
            }
        }
Exemple #12
0
        protected void DrawBackground( Graphics gr, WorkingHoursConfiguration config )
        {
            gr.DrawLine( pen_gray, 15, 10, 15, 10 + config.GraphHours * config.zoom_amount );
            for ( int   i = 0, hours = config.time_end;
                        i <= config.time_end - config.time_start;
                        i++, hours-- )
            {
                if ( config.full_background_lines )
                {
                    gr.DrawLine( pen_lightgray, 20, 10 + i*config.zoom_amount, 160, 10 + i*config.zoom_amount );
                }
                gr.DrawLine( pen_gray, 15, 10 + i*config.zoom_amount, 20, 10 + i*config.zoom_amount );

                if ( config.show_detailed_weeks )
                {
                    if ( hours < config.work_start.Hours || hours > config.work_end.Hours )
                    {
                        gr.DrawString( hours.ToString(), font_small, Brushes.LightGray, 1, 5 + i * config.zoom_amount );
                    }
                    else
                    {
                        gr.DrawString( hours.ToString(), font_small, Brushes.Black, 1, 5 + i * config.zoom_amount );
                    }
                }
                else
                {
                    if ( config.GraphHours - i <= config.work_hours )
                    {
                        gr.DrawString( ( config.GraphHours - i ).ToString(), font_small, Brushes.Black, 1, 5 + i * config.zoom_amount );
                    }
                    else
                    {
                        gr.DrawString( ( config.GraphHours - i ).ToString(), font_small, Brushes.Red, 1, 5 + i * config.zoom_amount );
                    }
                }
            }

            // bar showing expected working hours
            if ( !config.show_detailed_weeks )
            {
                int y = (int)(10 + ( config.GraphHours - config.work_hours ) * config.zoom_amount);
                if ( config.full_background_lines )
                {
                    gr.DrawLine( new Pen( Color.LightSkyBlue, 3 ), 20, y, 160, y );
                }
                gr.DrawLine( new Pen( Color.DodgerBlue, 3 ), 15, y, 20, y );
            }
        }
Exemple #13
0
        public WeekGraph( WorkingHoursConfiguration configuration, List< EventEntry >[] days, DateTime start_of_week, DateTime end_of_week )
        {
            InitializeComponent();

            DrawHours( configuration, days, start_of_week, end_of_week );
        }
        public void ShowDialog(IWin32Window owner, WorkingHoursConfiguration configuration, List <EventEntry> events)
        {
            if (events.Count > 0)
            {
                DateTime d             = events[0].date;
                DateTime start_of_week = d.Subtract(new TimeSpan((int)(d.DayOfWeek) - 1, d.Hour, d.Minute, d.Second, d.Millisecond));
                DateTime end_of_week   = start_of_week.AddDays(7);
                int      today         = d.MondayFirstDoW();

                // partition the events into weeks = array of days
                // then create 1 WeekGraph control for every week in the event list
                List <EventEntry>[] days = new List <EventEntry> [7]; for (int i = 0; i < 7; i++)
                {
                    days[i] = new List <EventEntry>();
                }
                foreach (EventEntry ee in events)
                {
                    if (ee.date.CompareTo(end_of_week) >= 0)
                    {   // the next week has begun
                        flp_weeks.Controls.Add(new WeekGraph(configuration, days, start_of_week, end_of_week));
                        days = new List <EventEntry> [7]; for (int i = 0; i < 7; i++)
                        {
                            days[i] = new List <EventEntry>();
                        }
                        start_of_week = ee.date.Subtract(new TimeSpan((int)(ee.date.DayOfWeek) - 1, ee.date.Hour, ee.date.Minute, ee.date.Second, ee.date.Millisecond));
                        end_of_week   = start_of_week.AddDays(7);
                    }
                    days[ee.date.MondayFirstDoW()].Add(ee);
                }
                Control last_weekgraph = new WeekGraph(configuration, days, start_of_week, end_of_week);
                flp_weeks.Controls.Add(last_weekgraph);

                // fit the parent form's area to the flowlayoutpanel as closely as possible...
                Rectangle working_area     = Screen.GetWorkingArea(this);
                int       controls_per_row = Math.Min(configuration.max_weeks_per_row,
                                                      Math.Min(working_area.Width / flp_weeks.Controls[0].Width, flp_weeks.Controls.Count)
                                                      );
                int  target_width       = controls_per_row * flp_weeks.Controls[0].Width;
                int  target_height      = 0;
                int  control_rows       = ((flp_weeks.Controls.Count + controls_per_row - 1) / controls_per_row);      // rounded up
                bool scrollbar_appeared = false;
                if (working_area.Height > 1.5 * control_rows * flp_weeks.Controls[0].Height)
                {
                    target_height = ((flp_weeks.Controls.Count + controls_per_row - 1) / controls_per_row) * flp_weeks.Controls[0].Height;
                }
                else if (working_area.Height > flp_weeks.Controls[0].Height)
                {
                    target_height      = flp_weeks.Controls[0].Height;
                    scrollbar_appeared = true;
                }
                else
                {
                    target_height      = working_area.Height * 8 / 10;
                    scrollbar_appeared = true;
                }
                if (scrollbar_appeared)
                {
                    target_width += SystemInformation.VerticalScrollBarWidth;
                }

                this.Width  = 10 + target_width;
                this.Height = 10 + target_height + b_ok.Height + this.Height - this.ClientRectangle.Height;

                flp_weeks.ScrollControlIntoView(last_weekgraph);
            }

            ShowDialog(owner);
        }
        protected void DrawBars(Graphics gr,
                                WorkingHoursConfiguration config,
                                List <EventEntry>[]        days,
                                DateTime start_of_week,
                                DateTime end_of_week,
                                out double work_hours_week,
                                out double unlocked_hours_week)
        {
            double work_hours_day     = 0;
            double unlocked_hours_day = 0;
            int    work_days          = 0;

            work_hours_week     = 0;
            unlocked_hours_week = 0;
            BarCreator bar_creator = new BarCreator(config, start_of_week, end_of_week);

            for (int i = 0; i < days.Length; i++)
            {
                work_hours_day     = 0;
                unlocked_hours_day = 0;

                foreach (EventEntry ee in days[i])
                {
                    Bar bar = bar_creator.GetBar(ee);
                    if (config.show_detailed_weeks || bar == null)
                    {
                        DrawBar(gr, config, bar);
                    }
                    else
                    {
                        if (bar.is_unlocked)
                        {
                            unlocked_hours_day += bar.Height;
                        }
                        else
                        {
                            work_hours_day += bar.Height;
                        }
                    }
                }

                foreach (Bar b in bar_creator.GetFinalBarsForDay())   // last unlock - now
                {
                    if (config.show_detailed_weeks)
                    {
                        DrawBar(gr, config, b);
                    }
                    else
                    {
                        if (b.is_unlocked)
                        {
                            unlocked_hours_day += b.Height;
                        }
                        else
                        {
                            work_hours_day += b.Height;
                        }
                    }
                }
                if (!config.show_detailed_weeks)
                {
                    Bar b1 = new Bar(new SolidBrush(config.work_bar_color), i, false, start_of_week.AddDays(i), start_of_week.AddDays(i + work_hours_day / 24));
                    Bar b2 = new Bar(new SolidBrush(config.unlocked_bar_color), i, true, start_of_week.AddDays(i), start_of_week.AddDays(i + unlocked_hours_day / 24));
                    DrawBar(gr, config, b1);
                    DrawBar(gr, config, b2);
                }

                if (work_hours_day > 0 || unlocked_hours_day > 0)
                {
                    work_days++;
                }

                work_hours_week     += work_hours_day;
                unlocked_hours_week += unlocked_hours_day;
            }
            work_hours_week     /= work_days;
            unlocked_hours_week /= work_days;
        }
        public WeekGraph(WorkingHoursConfiguration configuration, List <EventEntry>[] days, DateTime start_of_week, DateTime end_of_week)
        {
            InitializeComponent();

            DrawHours(configuration, days, start_of_week, end_of_week);
        }