/// <summary>
        /// Creates an Image object containing a screen shot of a specific window
        /// </summary>
        /// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
        /// <returns></returns>
        public Image CaptureWindow(IntPtr handle)
        {
            // get te hDC of the target window
            IntPtr hdcSrc = User32.GetWindowDC(handle);

            // get the size
            User32.RECT windowRect = new User32.RECT();
            User32.GetWindowRect(handle, ref windowRect);
            //int width = windowRect.right - windowRect.left;
            //int height = windowRect.bottom - windowRect.top;
            int width  = ScreenPixelHelper.GetScreenSize().Width;
            int height = ScreenPixelHelper.GetScreenSize().Height;
            // create a device context we can copy to
            IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            // create a bitmap we can copy it to,
            // using GetDeviceCaps to get the width/height
            IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
            // select the bitmap object
            IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);

            // bitblt over
            GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
            // restore selection
            GDI32.SelectObject(hdcDest, hOld);
            // clean up
            GDI32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);
            // get a .NET image object for it
            Image img = Image.FromHbitmap(hBitmap);

            // free up the Bitmap object
            GDI32.DeleteObject(hBitmap);
            return(img);
        }
Exemplo n.º 2
0
        //Input: c is the proposed center, w is width of rectangle, h is the height
        //Output: returns a new center point so that the entire rectangle fits the screen
        public Point CalculateRectCenterToFitScreen(Point c, float w, float h)
        {
            Rectangle screenSize = ScreenPixelHelper.GetScreenSize();
            Point     r          = new Point(c.X, c.Y);

            if (c.X - w / 2 < 0)
            {
                //We need to shift to right
                r.X = c.X - (c.X - Convert.ToInt32(Math.Round(w / 2)));
            }
            if (c.X + w / 2 > screenSize.Width)
            {
                //shift to the left
                r.X = c.X - (c.X + Convert.ToInt32(Math.Round(w / 2)) - screenSize.Width);
            }
            if (c.Y - h / 2 < 0)
            {
                //We need to shift down
                r.Y = c.Y - (c.Y - Convert.ToInt32(Math.Round(h / 2)));
            }
            if (c.Y + h / 2 > screenSize.Height)
            {
                //shift up
                r.Y = c.Y - (c.Y + Convert.ToInt32(Math.Round(h / 2)) - screenSize.Height);
            }

            return(r);
        }
Exemplo n.º 3
0
        public void Update(Point p, float addedMagnification = 0)
        {
            if (!active)
            {
                return;
            }

            Rectangle screenSize = ScreenPixelHelper.GetScreenSize();

            p = BoundPointToRect(p, screenSize, 5);

            zoomPct                   = ConfigManager.zoomWindowMagnificationPct + addedMagnification;
            activeRectPctScreen       = ConfigManager.zoomWindowPctScreen;
            activeRectPaddedPctScreen = activeRectPctScreen + 15;
            aciveRectSrcPctScreen     = (float)activeRectPctScreen * 100 / (float)zoomPct;

            //Calculate the size and position of the source rectangle
            float w = (float)screenSize.Width * aciveRectSrcPctScreen / 100;
            float h = (float)screenSize.Height * aciveRectSrcPctScreen / 100;

            //Check based on the height, width, and p if we need to shift to fit on screen
            activeRectSrcCenter = CalculateRectCenterToFitScreen(p, w, h);
            int xScreen = activeRectSrcCenter.X - Convert.ToInt32(w / 2);
            int yScreen = activeRectSrcCenter.Y - Convert.ToInt32(h / 2);

            activeRectSrc = new Rectangle(xScreen, yScreen, Convert.ToInt32(w), Convert.ToInt32(h));


            float activeRectWidth  = (float)screenSize.Width * activeRectPctScreen / 100;
            float activeRectHeight = (float)screenSize.Height * activeRectPctScreen / 100;

            activeRectCenter = CalculateRectCenterToFitScreen(p, activeRectWidth, activeRectHeight);
            xScreen          = activeRectCenter.X - Convert.ToInt32((activeRectWidth / 2));
            yScreen          = activeRectCenter.Y - Convert.ToInt32((activeRectHeight / 2));
            activeRect       = new Rectangle(xScreen, yScreen, Convert.ToInt32(activeRectWidth), Convert.ToInt32(activeRectHeight));

            //Calculate the padded activeRect so that within this padding the zoombox does not cancel when user looks away
            float activeRectWidthPadded  = screenSize.Width * activeRectPaddedPctScreen / 100;
            float activeRectHeightPadded = screenSize.Height * activeRectPaddedPctScreen / 100;

            xScreen          = activeRectCenter.X - Convert.ToInt32((activeRectWidthPadded / 2));
            yScreen          = activeRectCenter.Y - Convert.ToInt32((activeRectHeightPadded / 2));
            activeRectPadded = new Rectangle(xScreen, yScreen, Convert.ToInt32(activeRectWidthPadded), Convert.ToInt32(activeRectHeightPadded));

            //Allows drawing cursor icons underneath the WinzoomForm.
            //wzuf is already fine and needs no updating since all it's location info happens in OnPaint

            //zbf.BackColor = Color.FromArgb(216,249,107); //a very unusual light green color
            wzf.magnification     = (float)zoomPct / 100;
            wzf.mag.magnification = (float)zoomPct / 100;
            wzf.Width             = Convert.ToInt32(activeRectWidth);
            wzf.Height            = Convert.ToInt32(activeRectHeight);
            wzf.StartPosition     = FormStartPosition.Manual;
            wzf.Location          = new Point(activeRect.X, activeRect.Y);
            wzf.mag.SetSourceRect(activeRectSrc);
            wzf.mag.SetActiveRect(activeRect);
            wzf.Invalidate();
        }
        public static Rectangle GetStartMenuRect()
        {
            Rectangle screenRect = ScreenPixelHelper.GetScreenSize();
            Rectangle waRect     = ScreenPixelHelper.GetScreenWorkingArea();

            //the taskbar might be located other than the bottom of the screen default
            //But it doesn't matter since we are showing this overlay form
            return(new Rectangle(0, waRect.Bottom, 48, screenRect.Bottom - waRect.Bottom)); //value measured with pixel ruler
        }
Exemplo n.º 5
0
        public bool BoxLargeEnough(Box b)
        {
            if (b == null)
            {
                return(false);
            }

            int threshold = ScreenPixelHelper.ConvertMmToPixels(ConfigManager.cursorMagnetClippingMinBoxWidthMm);

            return(b.width() >= threshold && b.height() >= threshold);
        }
Exemplo n.º 6
0
        private void CalibrationAdjusterManualForm_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            int s = ScreenPixelHelper.ConvertMmToPixels(1); //step size of keyboard arrow input to control the gaze point adjustment offset

            switch (e.KeyCode)
            {
            case Keys.Enter:
                currentCircle++;
                this.Invalidate();    // This forces the form to repaint
                break;

            case Keys.Up:
                ca.adjGridOffset[currentCircle].Offset(0, -1 * s);
                break;

            case Keys.Down:
                ca.adjGridOffset[currentCircle].Offset(0, s);
                break;

            case Keys.Left:
                ca.adjGridOffset[currentCircle].Offset(-1 * s, 0);
                break;

            case Keys.Right:
                ca.adjGridOffset[currentCircle].Offset(s, 0);
                break;

            case Keys.Alt:
            //no break stmt
            case Keys.Escape:
                ca.writeCalibrationAdjustmentCsv();
                this.Close();     //prevent altf4 crash
                break;

            case Keys.Space:
                //record adjustment
                Point wp       = controller.WarpPointer.GetWarpPoint();
                Point calpoint = ca.adjGrid[currentCircle];
                ca.adjGridOffset[currentCircle] = new Point((calpoint.X - wp.X), (calpoint.Y - wp.Y));
                this.Invalidate();    // This forces the form to repaint
                break;

            default:
                break;
            }

            //see if done all adjustment points
            if (currentCircle == 9)
            {
                ca.writeCalibrationAdjustmentCsv();
                currentCircle = 0;
                this.Close();
            }
        }
        //Calculates target circle radius based on number of iterations completed, max number of iterations, min and max circle radiuses
        private int GetTargetCircleRadius(int iter)
        {
            int maxIterations = ConfigManager.calibrationIterationCountMax;
            int minRadius     = ScreenPixelHelper.ConvertMmToPixels(1);
            int maxRadius     = ScreenPixelHelper.ConvertMmToPixels(ConfigManager.calibrationCircleSizeMm);

            int    rDiff       = maxRadius - minRadius;
            double rStep       = (double)rDiff / (double)(maxIterations - 1);
            int    iterBounded = Math.Min(iter, maxIterations - 1); //note: deliberately capping at maxIterations -1 and therefore never reaches 0.2% screen

            return((int)(maxRadius - iterBounded * rStep));
        }
Exemplo n.º 8
0
        public bool NearLastIbeamPoint(Point p)
        {
            if (lastIbeamPoint == null)
            {
                return(false);
            }

            int nearbyMm     = 7; //mm
            int nearbyPixels = ScreenPixelHelper.ConvertMmToPixels(nearbyMm);

            return(PointHelper.GetPointDistance(p, lastIbeamPoint) <= nearbyPixels);
        }
        public CursorOverlayForm()
        {
            InitializeComponent();
            FormBorderStyle = FormBorderStyle.None;

            this.Size = ScreenPixelHelper.GetScreenWorkingArea().Size;

            User32.SetWindowPos(this.Handle, User32.HWND_TOPMOST, 0, 0, 0, 0, (User32.SWP_NOMOVE | User32.SWP_NOSIZE | User32.SWP_SHOWWINDOW));

            UpArrowImage   = Properties.Resources.uparrow;
            DownArrowImage = Properties.Resources.downarrow;

            Logger.WriteMsg("CursorOverlayForm instantiated.");
        }
Exemplo n.º 10
0
        //whenever this method is called, it paints from scratch and does not append to what's already on the screen
        //this method is typically called whenever RefreshScreen is called (60 fps)
        protected override void OnPaint(PaintEventArgs e)
        {
            int       radius = ScreenPixelHelper.ConvertMmToPixels(1.25); //radius
            Point     p      = ca.adjGrid[currentCircle];
            Rectangle rec    = new Rectangle(p.X - radius, p.Y - radius, radius * 2, radius * 2);

            e.Graphics.DrawEllipse(Pens.White, rec);

            //draw gray gaze point
            p = controller.WarpPointer.GetNextPoint(controller.WarpPointer.GetGazePoint());
            p.Offset(ca.adjGridOffset[currentCircle]);

            rec = new Rectangle(p.X - radius, p.Y - radius, radius * 2, radius * 2);
            e.Graphics.FillEllipse(Brushes.Gray, rec);
        }
Exemplo n.º 11
0
        //TODO: refactor these methods to same one and use enums

        /*
         *  Returns true if:
         *      All gazepoints for the past minMs duration are within radiusMm of the first gaze point in the observed set.
         *
         *  This function should be called when you want to limit the fixation region to a certain millimeters within the
         *  gazepoint at minMs milliseconds ago.
         */
        public static bool IsStationaryFixation(int minMs, int radiusMm)
        {
            if (warpPointer == null)
            {
                return(false);
            }

            List <Point> rawGazePoints = warpPointer.GetGazeHistory();

            if (rawGazePoints == null || rawGazePoints.Count == 0)
            {
                return(false);
            }

            int sampleRate = warpPointer.GetSampleRate();

            //total number of samples that should be meet the fixation width criteria
            int lookbackSampleCount = (int)Math.Max(1, sampleRate * minMs / 1000);

            if (lookbackSampleCount > rawGazePoints.Count)
            {
                return(false);
            }

            //Find the average of all the lookbackSamples ...
            int   startIndex = Math.Max(0, rawGazePoints.Count - lookbackSampleCount);
            Point runningSum = new Point(0, 0);
            Point runningAvg = new Point(0, 0);

            for (int i = startIndex; i < rawGazePoints.Count; i++)
            {
                runningSum.X += rawGazePoints[i].X;
                runningSum.Y += rawGazePoints[i].Y;
            }
            runningAvg.X = runningSum.X / lookbackSampleCount;
            runningAvg.Y = runningSum.Y / lookbackSampleCount;

            //Check if distances between all points are within radius
            for (int i = startIndex + 1; i < rawGazePoints.Count; i++)
            {
                if (PointHelper.GetPointDistance(runningAvg, rawGazePoints[i]) > ScreenPixelHelper.ConvertMmToPixels(radiusMm))
                {
                    return(false); //this point is too far from the first point
                }
            }
            return(true);
        }
Exemplo n.º 12
0
        public List <Box> getNearBoxes(Point gp)
        {
            List <Box> nearby        = new List <Box>();
            int        nearThreshold = ScreenPixelHelper.ConvertMmToPixels(ConfigManager.cursorMagnetClippingThresholdMm);

            foreach (Box b in boxes)
            {
                //should only work if the box have height and width

                //if box is valid and the point is near a box defined by threshold, then we add it to the working set
                if ((isNearBox(gp, b, nearThreshold)) && (b.top != b.bottom && b.left != b.right))
                {
                    nearby.Add(b);
                    // Debug.WriteLine("Found Box nearby" + currentBox[0] + "," + currentBox[1] + "  " + Cursor.Position);
                }
            }
            return(nearby);
        }
Exemplo n.º 13
0
        private void AddGazeButtons()
        {
            //int buttonHeight = ScreenPixelHelper.ConvertMmToPixels(ConfigManager.dockButtonHeightMm);

            int buttonHeightOffsetPx = ScreenPixelHelper.ConvertMmToPixels(5);
            int buttonHeight         = (this.Height / gazeButtonTextStrings.Length) - buttonHeightOffsetPx;

            //Calculate vertical spacing between each of the buttons
            int heightStep = (this.Height - buttonHeight) / (gazeButtonTextStrings.Length - 1);

            for (int i = 0; i < gazeButtonTextStrings.Length; i++)
            {
                //create a new button
                Button b = new Button();
                b.AutoSize = false;
                b.Width    = this.Width;
                //TODO: replace with just height
                b.Height = buttonHeight;
                //Location of the button is relative to the form
                b.Location  = new Point(this.Width - b.Width, i * heightStep);
                b.Text      = gazeButtonTextStrings[i];
                b.Font      = new Font(FontFamily.GenericSansSerif, 14);
                b.TextAlign = ContentAlignment.MiddleRight;
                b.ForeColor = Color.White;
                b.BackColor = Color.Black;
                //remove border
                b.TabStop   = false;
                b.FlatStyle = FlatStyle.Flat;
                b.FlatAppearance.BorderSize = 0;

                //Apply padding to enlarge the "gazeable/clickable" area of the button
                //b.Padding = new Padding(buttonLeftPadding, buttonVerticalPadding, 0, buttonVerticalPadding);
                //b.Margin = new Padding(buttonLeftPadding, buttonVerticalPadding, 0, buttonVerticalPadding);

                b.Click += gazeButton_Click;
                //b.Paint += new System.Windows.Forms.PaintEventHandler(this.gazeButton_Paint);
                b.MouseEnter += gazeButton_MouseEnter;
                b.MouseLeave += gazeButton_MouseLeave;

                //TODO: ButtonBorderStyle.None
                gazeButtonsList.Add(b);
                this.Controls.Add(b);
            }
        }
Exemplo n.º 14
0
        public void setMode(Mode mode)
        {
            if (warp != null)
            {
                warp.Dispose();
            }
            if (prec != null)
            {
                prec.Dispose();
            }

            this.mode = mode;
            switch (mode)
            {
            case Mode.EYEX_AND_TRACKIR:
                warp = new EyeXWarpPointer(ScreenPixelHelper.ConvertMmToPixels(25));
                prec = new TrackIRPrecisionPointer(ScreenPixelHelper.ConvertMmToPixels(25), 0.3);
                break;

            case Mode.EYEX_AND_SMARTNAV:
                warp  = new EyeXWarpPointer(ScreenPixelHelper.ConvertMmToPixels(1));
                prec  = new NoPrecisionPointer();
                state = TrackingState.RUNNING;
                break;

            case Mode.EYEX_ONLY:
                warp = new EyeXWarpPointer(ScreenPixelHelper.ConvertMmToPixels(5));
                prec = new NoPrecisionPointer();
                break;
            }

            Logger.WriteVar(nameof(mode), mode);

            if (!warp.IsStarted())
            {
                state = TrackingState.ERROR;
            }

            if (!prec.IsStarted())
            {
                state = TrackingState.ERROR;
            }
        }
Exemplo n.º 15
0
        public bool WithinRect(Point p, ZOOMBOX_RECT_T rect_t)
        {
            if (!active)
            {
                return(false);
            }

            Rectangle rect = GetActiveRectFromType(rect_t);

            Rectangle screenSize = ScreenPixelHelper.GetScreenSize();

            p = BoundPointToRect(p, screenSize, 5);

            if (p.X >= rect.Left && p.X <= rect.Right && p.Y >= rect.Top && p.Y <= rect.Bottom)
            {
                return(true);
            }
            return(false);
        }
Exemplo n.º 16
0
        public Point StayOrExitBox(Point gp)
        {
            //iterate through all the most recent raw gaze points and check that they all are at least thresholdPixels away
            int threshold = ScreenPixelHelper.ConvertMmToPixels(ConfigManager.cursorMagnetClippingExitThresholdMm);

            List <Point> rawGazePoints = mc.WarpPointer.GetGazeHistory();

            if (rawGazePoints == null || rawGazePoints.Count == 0 || ClippedBox == null)
            {
                winzoomAvailable = true;
                return(gp); //todo: out of bound?
            }

            int sampleRate = mc.WarpPointer.GetSampleRate();

            int recentDurationMs    = ConfigManager.cursorMagnetClippingExitDurationMs; //todo: config
            int lookbackSampleCount = sampleRate * recentDurationMs / 1000;
            int startIndex          = Math.Max(0, rawGazePoints.Count - lookbackSampleCount);

            //all points have to leave the box by at least exitThreshold amount in order to consider exit
            //equivalent to having 1 point not leave the box by exitThreshold to continue staying

            for (int i = startIndex; i < rawGazePoints.Count; i++)
            {
                //use the calibration adjusted value for the raw data
                Point adjustedGp = new Point(rawGazePoints[i].X, rawGazePoints[i].Y);
                adjustedGp.Offset(calibrationAdjuster.GetCalibrationAdjustment(adjustedGp));
                if (isNearBox(adjustedGp, ClippedBox, ScreenPixelHelper.ConvertMmToPixels(ConfigManager.cursorMagnetClippingExitThresholdMm)))
                {
                    //stay in box, since 1 point is still threshold/2 near the perimeter of the currently clipped box
                    return(ClippedBox.center());
                }
            }

            //We went through the most recent gaze points and all of them are more than threshold away
            //Exit this box
            ClippedBox       = null;
            winzoomAvailable = true;
            return(gp); //todo: out of bound
        }
Exemplo n.º 17
0
        public Point limitToScreenBounds(Point p)
        {
            Rectangle screenSize = ScreenPixelHelper.GetScreenSize();
            int       margin     = 5;

            if (p.X < margin)
            {
                p.X = margin;
            }
            if (p.Y < margin)
            {
                p.Y = margin;
            }
            if (p.X >= screenSize.Width - margin)
            {
                p.X = screenSize.Width - margin;
            }
            if (p.Y >= screenSize.Height - margin - 5)
            {
                p.Y = screenSize.Height - margin - 5;
            }

            return(p);
        }
Exemplo n.º 18
0
        protected override void OnPaint(PaintEventArgs e)
        {
            User32.SetFormTransparent(this.Handle);

            //Convert the current warp point a point on the screen
            Point wp = warpPointer.GetWarpPoint();

            wp.Offset(calibrationAdjuster.GetCalibrationAdjustment(wp));
            Point     screenPoint = wz.ConvertToScreenPoint(wp);
            Rectangle screenSize  = ScreenPixelHelper.GetScreenSize();

            if (ConfigManager.zoomboxGrid)
            {
                //Draw a vertical line
                e.Graphics.DrawLine(Pens.Black, new Point(screenPoint.X, screenSize.Top), new Point(screenPoint.X, screenSize.Bottom));

                //Draw a horizontal line
                e.Graphics.DrawLine(Pens.Black, new Point(screenSize.Left, screenPoint.Y), new Point(screenSize.Right, screenPoint.Y));
            }
            else
            {
                DrawApplicableCursorSymbol(e, screenPoint);
            }
        }
Exemplo n.º 19
0
        private void DockForm_Load(object sender, EventArgs e)
        {
            //1. Setup dock so that form window takes calculated user-amount of space on right side
            int dockWidth = ScreenPixelHelper.ConvertMmToPixels(ConfigManager.dockFormMaxWidthMm);

            //Calculate dock height
            Rectangle wa         = ScreenPixelHelper.GetScreenWorkingArea();
            int       dockHeight = wa.Height;

            //calculate dock location
            Point dockLocation = new Point(wa.Right - dockWidth, wa.Top);

            this.Location  = dockLocation;
            this.Size      = new Size(dockWidth, dockHeight);
            this.BackColor = Color.Black;

            //Add all the buttons for the dock
            AddGazeButtons();
            SetActiveGazeButton(GAZE_BUTTON_TYPE.NONE);

            Logger.WriteMsg("About to register dockbar.");
            //Now let's dock the window
            RegisterDockbar();
        }
Exemplo n.º 20
0
        /*
         *  Returns true if:
         *      The speed of eye movement does not exceed (radiusMM / ConfigManager.fixationMinDurationMs) millimeters/seconds
         *      measured over a total duration of minMs.
         *
         *  This function should be called when it's acceptable for the eyes to continue moving slowly and still count it as fixation.
         */
        public static bool IsMovingFixation(int minMs, int radiusMm)
        {
            if (warpPointer == null)
            {
                return(false);
            }

            List <Point> rawGazePoints = warpPointer.GetGazeHistory();

            if (rawGazePoints == null || rawGazePoints.Count == 0)
            {
                return(false);
            }

            int sampleRate = warpPointer.GetSampleRate();

            //total number of samples that should be meet the fixation width criteria
            int lookbackSampleCount = (int)Math.Max(1, sampleRate * minMs / 1000);

            if (lookbackSampleCount > rawGazePoints.Count)
            {
                return(false);
            }

            //moving window samples amount
            int windowSampleCount = Math.Max(sampleRate * ConfigManager.fixationMinDurationMs / 1000, 1);
            int stopIndex         = Math.Max(0, rawGazePoints.Count - windowSampleCount);

            //Get average of the first window
            //We start at the most recent point in history

            Point runningSum = new Point(0, 0);
            Point runningAvg = new Point(0, 0);

            for (int i = rawGazePoints.Count - 1; i >= stopIndex; i--)
            {
                runningSum.X += rawGazePoints[i].X;
                runningSum.Y += rawGazePoints[i].Y;
            }
            runningAvg.X = runningSum.X / windowSampleCount;
            runningAvg.Y = runningSum.Y / windowSampleCount;

            //Check that each point in the current window meets the fixation width criteria
            for (int i = rawGazePoints.Count - 1; i >= stopIndex; i--)
            {
                if (PointHelper.GetPointDistance(runningAvg, rawGazePoints[i]) > ScreenPixelHelper.ConvertMmToPixels(radiusMm))
                {
                    return(false); //this point is too far from the avg
                }
            }

            //slide window until we complete lookbackSampleCount many
            stopIndex = Math.Max(0, rawGazePoints.Count - lookbackSampleCount);
            int lowerIndex = rawGazePoints.Count - 1 - windowSampleCount;

            while (lowerIndex >= stopIndex)
            {
                int upperIndex = lowerIndex + windowSampleCount;
                //Remove one point from window
                runningSum.X -= rawGazePoints[upperIndex].X;
                runningSum.Y -= rawGazePoints[upperIndex].Y;

                //Add another point to the window
                runningSum.X += rawGazePoints[lowerIndex].X;
                runningSum.Y += rawGazePoints[lowerIndex].Y;

                //Recalculate avg
                runningAvg.X = runningSum.X / windowSampleCount;
                runningAvg.Y = runningSum.Y / windowSampleCount;

                //See if newest point is within the average
                if (PointHelper.GetPointDistance(runningAvg, rawGazePoints[lowerIndex]) > ScreenPixelHelper.ConvertMmToPixels(radiusMm))
                {
                    return(false); //this point is too far from the avg
                }

                lowerIndex--;
            }

            //Been through lookbackSampleCount and all of them according to the moving window are within fixation width requirement
            return(true);
        }
Exemplo n.º 21
0
        private Point getScreenCenter()
        {
            Rectangle screenSize = ScreenPixelHelper.GetScreenSize();

            return(new Point(screenSize.Width / 2, screenSize.Height / 2));
        }
 //NOTE: it doesn't really matter if user's taskbar is arranged elsewhere since we are using this hider form
 public static Point GetStartMenuLocation()
 {
     return(new Point(ScreenPixelHelper.ConvertMmToPixels(3), ScreenPixelHelper.GetScreenSize().Height - ScreenPixelHelper.ConvertMmToPixels(4)));
 }
Exemplo n.º 23
0
        //It is hardcoded to set to the right side
        private void ABSetPos()
        {
            Rectangle screenSize = ScreenPixelHelper.GetScreenSize();

            try
            {
                APPBARDATA abd = new APPBARDATA();
                abd.cbSize = Marshal.SizeOf(abd);
                abd.hWnd   = this.Handle;
                abd.uEdge  = (int)ABEdge.ABE_RIGHT;

                if (abd.uEdge == (int)ABEdge.ABE_LEFT || abd.uEdge == (int)ABEdge.ABE_RIGHT)
                {
                    abd.rc.top    = 0;
                    abd.rc.bottom = screenSize.Height;
                    if (abd.uEdge == (int)ABEdge.ABE_LEFT)
                    {
                        abd.rc.left  = 0;
                        abd.rc.right = Size.Width;
                    }
                    else
                    {
                        abd.rc.right = screenSize.Width;
                        abd.rc.left  = abd.rc.right - Size.Width;
                    }
                }
                else
                {
                    abd.rc.left  = 0;
                    abd.rc.right = screenSize.Width;
                    if (abd.uEdge == (int)ABEdge.ABE_TOP)
                    {
                        abd.rc.top    = 0;
                        abd.rc.bottom = Size.Height;
                    }
                    else
                    {
                        abd.rc.bottom = screenSize.Height;
                        abd.rc.top    = abd.rc.bottom - Size.Height;
                    }
                }

                // Query the system for an approved size and position.
                SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref abd);

                // Adjust the rectangle, depending on the edge to which the
                // appbar is anchored.
                switch (abd.uEdge)
                {
                case (int)ABEdge.ABE_LEFT:
                    abd.rc.right = abd.rc.left + Size.Width;
                    break;

                case (int)ABEdge.ABE_RIGHT:
                    abd.rc.left = abd.rc.right - Size.Width;
                    break;

                case (int)ABEdge.ABE_TOP:
                    abd.rc.bottom = abd.rc.top + Size.Height;
                    break;

                case (int)ABEdge.ABE_BOTTOM:
                    abd.rc.top = abd.rc.bottom - Size.Height;
                    break;
                }

                // Pass the final bounding rectangle to the system.
                SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref abd);

                // Move and size the appbar so that it conforms to the
                // bounding rectangle passed to the system.
                MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top,
                           abd.rc.right - abd.rc.left, abd.rc.bottom - abd.rc.top, true);
            }
            catch (Exception ex)
            {
                Logger.WriteError(ex.ToString());
            }
        }
Exemplo n.º 24
0
        //This function gets called pretty much every precision gaze mouse form refresh
        public void ShowCursorOverlay(Point p)
        {
            if (activeGazeButton == GAZE_BUTTON_TYPE.DOWN || activeGazeButton == GAZE_BUTTON_TYPE.UP)
            {
                if (cursorOverlayForm == null || cursorOverlayForm.IsDisposed)
                {
                    Logger.WriteMsg("New Cursor Overlay Form being created.");
                    cursorOverlayForm = new CursorOverlayForm();
                }

                //Only update the overlay location if there is a change by more than 5 mm
                if (PointHelper.GetPointDistance(p, cursorOverlayForm.currentPoint) > ScreenPixelHelper.ConvertMmToPixels(5))
                {
                    cursorOverlayForm.currentPoint = p;

                    if (activeGazeButton == GAZE_BUTTON_TYPE.DOWN)
                    {
                        cursorOverlayForm.UpdateOverlayType(CursorOverlayForm.OVERLAY_TYPE.DOWNARROW);
                    }
                    else if (activeGazeButton == GAZE_BUTTON_TYPE.UP)
                    {
                        cursorOverlayForm.UpdateOverlayType(CursorOverlayForm.OVERLAY_TYPE.UPARROW);
                    }

                    if (!cursorOverlayForm.Visible)
                    {
                        Logger.WriteMsg("Cursor OverlyForm about to be shown.");
                        cursorOverlayForm.Show();
                    }
                    else
                    {
                        cursorOverlayForm.Invalidate();
                    }
                }
            }
            else
            {
                HideCursorOverlayForm();
            }
        }
 public static Rectangle GetScreenSize()
 {
     return(ScreenPixelHelper.GetScreenSize());
 }
Exemplo n.º 26
0
        public Point ConvertToScreenPoint(Point p)
        {
            Rectangle screenSize = ScreenPixelHelper.GetScreenSize();

            p = BoundPointToRect(p, screenSize, 5);

            int delta = ScreenPixelHelper.ConvertMmToPixels(1);

            //We want to find the "center" which is the focal point of where magnified and system cursor intersect
            //on the winzoom box.  It is different whether edge or corner, or if winzoom box is in middle of screen
            int x = 0;

            if (Math.Abs(activeRect.Left - activeRectSrc.Left) < delta)
            {
                x = 0;
            }
            else if (Math.Abs(activeRect.Right - activeRectSrc.Right) < delta)
            {
                x = screenSize.Width;
            }
            else if (activeRect.Left < delta) //only activeRect is left aligned
            {
                //Experimentally and analytically determined this formula
                x = Convert.ToInt32((Convert.ToDouble(activeRectSrc.Left) * zoomPct / (zoomPct - 100)));
            }
            else if (Math.Abs(activeRect.Right - screenSize.Width) < delta) //only activeRect is right aligned
            {
                int xdiff       = (activeRect.Right - activeRectSrc.Right); //this will be a positive number
                int xDiffScaled = Convert.ToInt32((Convert.ToDouble(xdiff) * zoomPct / (zoomPct - 100)));
                x = activeRect.Right - xDiffScaled;
            }
            else
            {
                x = activeRectSrcCenter.X;
            }

            int y = 0;

            if (Math.Abs(activeRect.Top - activeRectSrc.Top) < delta)
            {
                y = 0;
            }
            else if (Math.Abs(activeRect.Bottom - activeRectSrc.Bottom) < delta)
            {
                y = screenSize.Height;
            }
            else if (activeRect.Top < delta) //only activeRect is left aligned
            {
                y = Convert.ToInt32((activeRectSrc.Top * zoomPct / (zoomPct - 100)));
            }
            else if (Math.Abs(activeRect.Bottom - screenSize.Width) < delta)  //only activeRect is right aligned
            {
                int ydiff       = (activeRect.Bottom - activeRectSrc.Bottom); //this will be a positive number
                int yDiffScaled = Convert.ToInt32((ydiff * zoomPct / (zoomPct - 100)));
                y = activeRect.Bottom - yDiffScaled;
            }
            else
            {
                y = activeRectSrcCenter.Y;
            }

            //This center is essentially the focal point of the magnified cursor and system cursor
            Point center = new Point(x, y);
            Point diff   = new Point(p.X - center.X, p.Y - center.Y);

            //The magnified cursor and the actively controlled cursor are the same point in top left corner of activeRectSrc
            //As main cursor moves, magnified cursor moves away twice as fast if we return p and do no adjustments
            //Therefore we need to divide the distance of gaze point from top left corner by zoomFactor to get magnified and gaze point to be same

            return(new Point(center.X + Convert.ToInt32((float)diff.X / ((float)zoomPct / (float)100)),
                             center.Y + Convert.ToInt32((float)diff.Y / ((float)zoomPct / (float)100))));;
        }
Exemplo n.º 27
0
        public Point ClipToBox(Point gp)
        {
            //Check if LinkDict is not populated
            if (ClippedBox == null)
            {
                if (!boxesInitComplete || boxes.Count < 1)
                {
                    return(gp);
                }
                //We also want to make sure that the gp is not near the Windows Taskbar, otherwise have difficulty using start menu or switching applications
                Rectangle workingArea = ScreenPixelHelper.GetScreenWorkingArea();

                //We also want to make sure browser navigation buttons can be clicked comfortably
                int topBar = 105;

                if (gp.X < workingArea.Left || gp.X > workingArea.Right || gp.X < (workingArea.Top + topBar - 15) || gp.Y > workingArea.Bottom)
                {
                    winzoomAvailable = true;
                    return(gp);
                }
                List <Box> nearby = new List <Box>();
                nearby.AddRange(getNearBoxes(gp));

                if (nearby.Count == 0)
                {
                    winzoomAvailable = true;
                    return(gp);
                }
                if (nearby.Count == 1)//if no box around, we keep the cursor where it is
                {
                    //We clip to the center of the clickable element
                    winzoomAvailable = false;
                    ClippedBox       = nearby[0];
                    return(ClippedBox.center());
                }
                else
                {
                    if (!CheckAllBoxesLargeEnough(nearby))
                    {
                        winzoomAvailable = true;
                        ClippedBox       = null;
                        return(gp);
                    }

                    ClippedBox       = findClosestBox(gp, nearby);//closest Box
                    winzoomAvailable = false;
                    return(ClippedBox.center());
                }
            }
            else //box was previously clipped
            {
                /*
                 * if(no box around)
                 *      ruturn ClippedBox.center or (-100,-100)either exit or stay
                 * else
                 *      if GP is in direction of anotherBox
                 *         return  changeBox()
                 *      else
                 *          either exit or stay
                 */


                //no other box around, //exit

                List <Box> otherNearby = getNearBoxes(gp);


                if (otherNearby.Contains(ClippedBox))
                {
                    otherNearby.Remove(ClippedBox);
                }                                                                         //remove the clipped box as it is itself
                if (otherNearby.Count == 0)
                {
                    return(StayOrExitBox(gp));
                }
                else
                {
                    if (!CheckAllBoxesLargeEnough(otherNearby))
                    {
                        //must use winzoom and exit since we've approached a really small box, force exit from box
                        winzoomAvailable = true;
                        ClippedBox       = null;
                        return(gp);
                    }

                    if (ClippedBox.ContainsPoint(gp))
                    {
                        return(ClippedBox.center());
                    }

                    //Check if gp is contained by any of the otherNearby boxes, and if so is it at least changeBoxPercThresh into it
                    foreach (Box b in otherNearby)
                    {
                        //If it's a large box then a few pixels should be enough to enter it... and for a small box use a small percentage of it
                        if (b.ContainsPointPercentageWithin(ClippedBox, gp, ConfigManager.cursorMagnetClippingChangeBoxIntoPerc) ||
                            b.ContainsPointPixelsWithin(ClippedBox, gp, ScreenPixelHelper.ConvertMmToPixels(ConfigManager.cursorMagnetClippingExitThresholdMm))
                            )
                        {
                            winzoomAvailable = false;
                            ClippedBox       = b;
                            return(b.center());
                        }
                    }

                    //the gazepoint has not met the criteria for changing to a different box, see if it should stay or exit
                    return(StayOrExitBox(gp));
                }
            }
        }
        //whenever this method is called, it paints from scratch and does not append to what's already on the screen
        //this method is typically called whenever RefreshScreen is called (60 fps)
        protected override void OnPaint(PaintEventArgs e)
        {
            //Draw overall target circle (which shrinks with duration)
            int       radius   = GetTargetCircleRadius(iteration);
            Point     calpoint = ca.adjGrid[currentCircle];
            Rectangle rec      = new Rectangle(calpoint.X - radius, calpoint.Y - radius, radius * 2, radius * 2);

            if (iteration == 0)
            {
                e.Graphics.DrawEllipse(Pens.White, rec);
            }
            else if (iteration < ConfigManager.calibrationIterationCountMax - 1)
            {
                e.Graphics.DrawEllipse(Pens.DarkCyan, rec);
                //also draw inner circles to guide
                radius = GetTargetCircleRadius(iteration + 1);
                rec    = new Rectangle(calpoint.X - radius, calpoint.Y - radius, radius * 2, radius * 2);
                e.Graphics.DrawEllipse(Pens.DarkMagenta, rec);
            }
            else
            {
                e.Graphics.FillEllipse(Brushes.DarkMagenta, rec);
                e.Graphics.DrawEllipse(Pens.DarkCyan, rec);
            }

            //Reset the iterations and calibrating this point if user has already been trying longer than expected
            if (iteration > ConfigManager.calibrationIterationCountMax + 1)
            {
                calstate  = CalState.WAITING_FOCUS;
                iteration = 0;
            }


            Point gp = controller.WarpPointer.GetNextPoint(controller.WarpPointer.GetGazePoint());

            //detect whether gaze point is close to the calibration circle (at most 7cm of screen away)
            if (PointHelper.GetPointDistance(gp, calpoint) < ScreenPixelHelper.ConvertMmToPixels(70))
            {
                //draw gray gaze point as long as it's not the final iteration(s)
                int   gazeRadius = ScreenPixelHelper.ConvertMmToPixels(1) / 2;
                Point p          = controller.WarpPointer.GetNextPoint(controller.WarpPointer.GetGazePoint());
                p.Offset(ca.adjGridOffset[currentCircle]);
                rec = new Rectangle(p.X - gazeRadius, p.Y - gazeRadius, gazeRadius * 2, gazeRadius * 2);

                if (iteration < ConfigManager.calibrationIterationCountMax)
                {
                    e.Graphics.FillEllipse(Brushes.Gray, rec);

                    if (iteration > 0)
                    {
                        //Get antipoint, which is basically located on other cide of currentCircle
                        int   xDiff = p.X - ca.adjGrid[currentCircle].X;
                        int   yDiff = p.Y - ca.adjGrid[currentCircle].Y;
                        Point ap    = new Point(p.X - xDiff * 2, p.Y - yDiff * 2);

                        rec = new Rectangle(ap.X - gazeRadius, ap.Y - gazeRadius, gazeRadius * 2, gazeRadius * 2);
                        e.Graphics.FillEllipse(Brushes.Gray, rec);
                    }
                }


                if (calstate == CalState.WAITING_FOCUS)
                {
                    StartTimer();
                    calstate = CalState.FOCUS_IN_PROGRESS;
                    return;
                }
                else if (calstate == CalState.FOCUS_IN_PROGRESS)
                {
                    if (DoneWaitingTime(150))
                    {
                        calstate = CalState.FOCUSED;
                    }
                    else
                    {
                        return;
                    }
                }
                else if (calstate == CalState.FOCUSED)
                {
                    //Done waiting the focus time and eyes are focussed
                    UpdateCalibrationAdjustmentWithCurrentGaze();

                    StartTimer();
                    sampleCollectionStartTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                    calstate  = CalState.COLLECTING_SAMPLES;
                    iteration = 0;
                    return;
                }
                else if (calstate == CalState.COLLECTING_SAMPLES)
                {
                    //Done waiting time to start collecting samples

                    //We don't want the gaze to lag across the screen so we trick the user thinking it's centered already
                    if (iteration == 0 || iteration == 1)
                    {
                        UpdateCalibrationAdjustmentWithCurrentGaze();
                    }

                    if (DoneWaitingTime(ConfigManager.calibrationIterationTimeMs))
                    {
                        //Check if current gaze point is close to the center of the target circle
                        iteration++;
                        Point  wp                     = controller.WarpPointer.GetWarpPoint();
                        double pointDistance          = PointHelper.GetPointDistance(calpoint, wp);
                        int    pointDistanceThreshold = ScreenPixelHelper.ConvertMmToPixels(ConfigManager.calibrationCompletedThresholdMm);
                        UpdateCalibrationAdjustmentWithCurrentGaze();
                        if (iteration >= ConfigManager.calibrationIterationCountMax &&
                            pointDistance < pointDistanceThreshold)
                        {
                            //calibration for this point is successful
                            currentCircle++;
                            if (currentCircle == 9)
                            {
                                ca.writeCalibrationAdjustmentCsv();
                                currentCircle = 0;
                                Cursor.Show();
                                this.Close();
                            }
                        }
                        else
                        {
                            StartTimer();
                        }
                        this.Invalidate();// This forces the form to repaint
                    }
                }
            }
            else
            {
                iteration = 0;
                calstate  = CalState.WAITING_FOCUS;
            }
        }
Exemplo n.º 29
0
        public void Show(Point p, float addedMagnification = 0)
        {
            if (active)
            {
                return;
            }
            Logger.WriteEvent();
            active = true;


            Rectangle screenSize = ScreenPixelHelper.GetScreenSize();

            p = BoundPointToRect(p, screenSize, 5);

            zoomPct                   = ConfigManager.zoomWindowMagnificationPct + addedMagnification;
            activeRectPctScreen       = ConfigManager.zoomWindowPctScreen;
            activeRectPaddedPctScreen = activeRectPctScreen + 15;
            aciveRectSrcPctScreen     = (float)activeRectPctScreen * 100 / (float)zoomPct;

            //Calculate the size and position of the source rectangle
            float w = (float)screenSize.Width * aciveRectSrcPctScreen / 100;
            float h = (float)screenSize.Height * aciveRectSrcPctScreen / 100;

            //Check based on the height, width, and p if we need to shift to fit on screen
            activeRectSrcCenter = CalculateRectCenterToFitScreen(p, w, h);
            int xScreen = activeRectSrcCenter.X - Convert.ToInt32(w / 2);
            int yScreen = activeRectSrcCenter.Y - Convert.ToInt32(h / 2);

            activeRectSrc = new Rectangle(xScreen, yScreen, Convert.ToInt32(w), Convert.ToInt32(h));


            float activeRectWidth  = (float)screenSize.Width * activeRectPctScreen / 100;
            float activeRectHeight = (float)screenSize.Height * activeRectPctScreen / 100;

            activeRectCenter = CalculateRectCenterToFitScreen(p, activeRectWidth, activeRectHeight);
            xScreen          = activeRectCenter.X - Convert.ToInt32((activeRectWidth / 2));
            yScreen          = activeRectCenter.Y - Convert.ToInt32((activeRectHeight / 2));
            activeRect       = new Rectangle(xScreen, yScreen, Convert.ToInt32(activeRectWidth), Convert.ToInt32(activeRectHeight));

            //Calculate the padded activeRect so that within this padding the zoombox does not cancel when user looks away
            float activeRectWidthPadded  = screenSize.Width * activeRectPaddedPctScreen / 100;
            float activeRectHeightPadded = screenSize.Height * activeRectPaddedPctScreen / 100;

            xScreen          = activeRectCenter.X - Convert.ToInt32((activeRectWidthPadded / 2));
            yScreen          = activeRectCenter.Y - Convert.ToInt32((activeRectHeightPadded / 2));
            activeRectPadded = new Rectangle(xScreen, yScreen, Convert.ToInt32(activeRectWidthPadded), Convert.ToInt32(activeRectHeightPadded));

            //Allows drawing cursor icons underneath the WinzoomForm.
            wzuf = new WinzoomUnderlayForm(warpPointer, calibrationAdjuster, this);
            wzuf.StartPosition     = FormStartPosition.Manual;
            wzuf.WindowState       = FormWindowState.Maximized;
            wzuf.AllowTransparency = true;
            wzuf.TransparencyKey   = wzuf.BackColor;
            wzuf.TopMost           = true;
            wzuf.Show();

            //zbf.BackColor = Color.FromArgb(216,249,107); //a very unusual light green color
            wzf = new WinzoomForm(this);
            wzf.magnification     = (float)zoomPct / 100;
            wzf.mag.magnification = (float)zoomPct / 100;
            wzf.Width             = Convert.ToInt32(activeRectWidth);
            wzf.Height            = Convert.ToInt32(activeRectHeight);
            wzf.StartPosition     = FormStartPosition.Manual;
            wzf.Location          = new Point(activeRect.X, activeRect.Y);
            wzf.mag.SetSourceRect(activeRectSrc);
            wzf.mag.SetActiveRect(activeRect);
            wzf.Show();
        }