Question How to edit the Time of an analog clock by dragging it's handles

zed

New member
Joined
Mar 11, 2016
Messages
3
Programming Experience
Beginner
Hi All,
It's my first week working with C# the requirement is to edit the Time of an analog Clock by dragging it's handles I have code for a clock from here https://www.youtube.com/watch?v=0dtbGKSF1R8 , is this even possible ? if so can someone
give me a clue please. I know I have to work with Mouse Events but not quite sure how to go about it. Many thanks
 
Thanks for your reply but I don't think that will solve my problem. I'm beginning to think it's not possible ...
 
It is possible and what I provided is not a cut and paste solution but an example of how you can drag and drop things that you've drawn. The very same principle can be applied to the drawn hands of a clock but if you don't want to bother understanding what's going on then that's your prerogative.
 
Thanks jmcilhinney for your reply of course I want to learn I have been battling with it I have three simple functions MouseDown, MouseMove and MouseUp in theory this should Drag the Graphic line(Handles) but it doesn't. any ideas ???
C#:
namespace Clock{
    public partial class Form1 : Form
    {
        #region Construct the clock 
        
        public Point Start { get; set; }
        public Point End { get; set; }


        public Form1()
        {
            InitializeComponent();
            //Set the double buffered to true to reduce flickering of the graphics 
            DoubleBuffered = true;


            //Create the timer and start it 
            ClockTimer.Tick += ClockTimer_Tick;
            ClockTimer.Enabled = true;
            ClockTimer.Interval = 1;
            ClockTimer.Start();
            Start = p1;
            End = p2;
        }

        #endregion

        #region Update the clock 

        /// <summary> 
        /// The tick event for the timer 
        /// </summary> 
        /// <param name="sender">The object that sends the trigger</param> 
        /// <param name="e">The event arguments for the event</param> 
        private void ClockTimer_Tick(object sender, EventArgs e)
        {
            Refresh();
        }


        /// <summary> 
        /// The timer to update the hands 
        /// </summary> 
        private Timer ClockTimer = new Timer();
        private Pen circle = new Pen(Color.Black, 2);
        private Pen secondHandle = new Pen(Color.Red, 1);
        private Pen minHandle = new Pen(Color.Black, 5);
        private Pen hrHandle = new Pen(Color.Black, 5);
        private Point p1;
        private Point p2;

        #endregion

        #region On paint 

        /// <summary> 
        /// Called when the control needs to draw itself 
        /// </summary> 
        /// <param name="pe">The paint event arguments for the control</param> 
        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);


            //Clear the graphics to the back color of the control 
            pe.Graphics.Clear(BackColor);


            //Draw the border of the clock 
            pe.Graphics.DrawEllipse(circle, 0, 0, 300, 300);


            //Find the radius of the control by dividing the width by 2 
            float radius = (300 / 2);


            //Find the origin of the circle by dividing the width and height of the control 
            PointF origin = new PointF(300 / 2, 300 / 2);


            //Draw only if ShowMajorSegments is true; 
            if (ShowMajorSegments)
            {
                //Draw the Major segments for the clock 
                for (float i = 0f; i != 390f; i += 30f)
                {
                    pe.Graphics.DrawLine(Pens.Red, PointOnCircle(radius - 1, i, origin), PointOnCircle(radius - 21, i, origin));
                }
            }


            //Draw only if ShowMinorSegments is true 
            if (ShowMinorSegments)
            {
                //Draw the minor segments for the control 
                for (float i = 0f; i != 366f; i += 6f)
                {
                    pe.Graphics.DrawLine(Pens.Black, PointOnCircle(radius, i, origin), PointOnCircle(radius - 10, i, origin));
                }
            }


            //Draw only if ShowSecondHand is true 
            if (ShowSecondhand)
                //Draw the second hand 
                pe.Graphics.DrawLine(secondHandle, origin, PointOnCircle(radius, DateTime.Now.Second * 6f, origin));
                
            //Draw only if ShowMinuteHand is true 
            if (ShowMinuteHand)
                //Draw the minute hand 
                pe.Graphics.DrawLine(minHandle, origin, PointOnCircle(radius * 0.75f, DateTime.Now.Minute * 6f, origin));
                minHandle.StartCap = LineCap.RoundAnchor;
                minHandle.EndCap = LineCap.ArrowAnchor;
                pe.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
               
            //Draw only if ShowHourHand is true 
            if (ShowHourHand)
                //Draw the hour hand 
                pe.Graphics.DrawLine(hrHandle, origin, PointOnCircle(radius * 0.50f, DateTime.Now.Hour * 30f, origin));
                hrHandle.StartCap = LineCap.RoundAnchor;
                hrHandle.EndCap = LineCap.ArrowAnchor;
                pe.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        }


        #endregion


        #region On size changed 


        /// <summary> 
        /// Triggered when the size of the control changes 
        /// </summary> 
        /// <param name="e">The event arguments for the event</param> 
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);


            //Make sure the control is square 
            if (Size.Height != Size.Width)
                Size = new Size(Size.Width, Size.Width);


            //Redraw the control 
            Refresh();
        }

        #endregion

        #region Point on circle 

        /// <summary> 
        /// Find the point on the circumference of a circle 
        /// </summary> 
        /// <param name="radius">The radius of the circle</param> 
        /// <param name="angleInDegrees">The angle of the point to origin</param> 
        /// <param name="origin">The origin of the circle</param> 
        /// <returns>Return the point</returns> 
        private PointF PointOnCircle(float radius, float angleInDegrees, PointF origin)
        {
            //Find the x and y using the parametric equation for a circle 
            float x = (float)(radius * Math.Cos((angleInDegrees - 90f) * Math.PI / 180F)) + origin.X;
            float y = (float)(radius * Math.Sin((angleInDegrees - 90f) * Math.PI / 180F)) + origin.Y;


            /*Note : The "- 90f" is only for the proper rotation of the clock. 
             * It is not part of the parament equation for a circle*/


            //Return the point 
            return new PointF(x, y);
        }


        #endregion


        #region Show Minor Segments 


        /// <summary> 
        /// Indicates if the minor segements are shown 
        /// </summary> 
        private bool showMinorSegments = true;


        /// <summary> 
        /// Indicates if the minor segements are shown 
        /// </summary> 
        public bool ShowMinorSegments
        {
            get
            {
                return showMinorSegments;
            }
            set
            {
                showMinorSegments = value;
                Refresh();
            }
        }


        #endregion


        #region Show Major Segments 


        /// <summary> 
        /// Indicates if the major segements are shown 
        /// </summary> 
        private bool showMajorSegments = true;


        /// <summary> 
        /// Indicates if the major segements are shown 
        /// </summary> 
        public bool ShowMajorSegments
        {
            get
            {
                return showMajorSegments;
            }
            set
            {
                showMajorSegments = value;
                Refresh();
            }
        }


        #endregion


        #region Show Second Hand 


        /// <summary> 
        /// Indicates if the second hand is shown 
        /// </summary> 
        private bool showSecondHand = true;


        /// <summary> 
        /// Indicates if the second hand is shown 
        /// </summary> 
        public bool ShowSecondhand
        {
            get
            {
                return showSecondHand;
            }
            set
            {
                showSecondHand = value;
                Refresh();
            }
        }


        #endregion


        #region Show Minute Hand 


        /// <summary> 
        /// Indicates if the minute hand is shown 
        /// </summary> 
        private bool showMinuteHand = true;


        /// <summary> 
        /// Indicates if the minute hand is shown 
        /// </summary> 
        public bool ShowMinuteHand
        {
            get
            {
                return showMinuteHand;
            }
            set
            {
                showMinuteHand = value;
                Refresh();
            }
        }


        #endregion


        #region Show Hour Hand 


        /// <summary> 
        /// Indicates if the hour hand is shown 
        /// </summary> 
        private bool showHourHand = true;


        /// <summary> 
        /// Indicates if the hour hand is shown 
        /// </summary> 
        public bool ShowHourHand
        {
            get
            {
                return showHourHand;
            }
            set
            {
                showHourHand = value;
                Refresh();
            }
        }




        #endregion     


        public float slope
        {
            get
            {
                return (((float)End.Y - (float)Start.Y) / ((float)End.X - (float)Start.X));
            }
        }
        public float YIntercept
        {
            get
            {
                return Start.Y - slope * Start.X;
            }
        }


        public bool IsPointOnLine(Point p, int cushion)
        {
            float temp = (slope * p.X + YIntercept);
            if (temp >= (p.Y - cushion) && temp <= (p.Y + cushion))
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        Point deltaStart;
        Point deltaEnd;
        bool dragging = false;


        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left  && IsPointOnLine(e.Location, 5))
            {
                dragging = true;
                deltaStart = new Point(Start.X - e.Location.X, Start.Y - e.Location.Y);
                deltaEnd = new Point(End.X - e.Location.X, End.Y - e.Location.Y);
            }   
        }


        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (dragging && deltaStart != null && deltaEnd != null)
            {
                Start = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y);
                End = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y);
                this.Refresh();
            }
        }


        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            dragging = false;
        }
    }
}


 
Back
Top Bottom