AutoCAD like selection style

Here's the Eyershot 7 code to simulate the selection style of AutoCAD®. To make it work in earlier Eyeshot versions just derive from Viewport instead of SingleViewportLayout.

Clicking the mouse will set the pick state to "Pick". When moving the mouse to the right more than 10 pixels, the pick state changes to Enclosed and when moving to the left of the same amount the pick state becomes Crossing.

A transparent rectangle is drawn in overlay according to the pick state and when releasing the mouse the selection is performed according to the pick state.

    public class MyViewportLayout : devDept.Eyeshot.SingleViewportLayout 
    { 
        private enum pickState 
        { 
            Pick, 
            Enclosed, 
            Crossing 
        }; 

        private pickState currPickState; 
        private bool buttonPressed; 

        private System.Drawing.Point initialLocation; 
        private System.Drawing.Point currentLocation; 

        protected override void OnMouseDown(MouseEventArgs e) 
        { 
            if (e.Button == MouseButtons.Left && ActionMode == actionType.None) 
            { 
                if (!ViewCubeIcon.Contains(e.Location)) 
                { 
                    buttonPressed = true; 
                    initialLocation = currentLocation = e.Location; 
                    currPickState = pickState.Pick; 
                } 
            } 

            base.OnMouseDown(e); 
        } 

        protected override void OnMouseMove(MouseEventArgs e) 
        { 
            if (buttonPressed) 
            { 
                int diffX = e.Location.X - initialLocation.X; 

                if (diffX > 10) 
                    currPickState = pickState.Enclosed; 
                else if (diffX < -10) 
                    currPickState = pickState.Crossing; 
                else 
                    currPickState = pickState.Pick; 

                currentLocation = e.Location; 

                PaintBackBuffer(); 
                SwapBuffers(); 
            } 

            base.OnMouseMove(e); 
        } 

        protected override void OnMouseUp(MouseEventArgs e) 
        { 
            if (buttonPressed) 
            { 
                buttonPressed = false; 
                int ent; 
                int[] ents; 

                for (int i = 0; i < Entities.Count; i++) 
                { 
                    Entities[i].Selected = false; 
                } 

                int dx = currentLocation.X - initialLocation.X; 
                int dy = currentLocation.Y - initialLocation.Y; 

                System.Drawing.Point p1 = initialLocation; 
                System.Drawing.Point p2 = currentLocation; 

                NormalizeBox(ref p1, ref p2); 

                switch (currPickState) 
                { 
                    case pickState.Pick: 

                        ent = GetEntityUnderMouseCursor(currentLocation); 

                        if (ent >= 0) 
                            Entities[ent].Selected = true; 

                        break; 

                    case pickState.Crossing: 

                        if (dx != 0 && dy != 0) 
                        { 
                            ents = GetAllCrossingEntities(new Rectangle(p1, new Size(Math.Abs(dx), Math.Abs(dy)))); 

                            for (int i = 0; i < ents.Length; i++) 

                                Entities[ents[i]].Selected = true; 
                        } 

                        break; 

                    case pickState.Enclosed: 

                        if (dx != 0 && dy != 0) 
                        { 
                            ents = GetAllEnclosedEntities(new Rectangle(p1, new Size(Math.Abs(dx), Math.Abs(dy)))); 

                            for (int i = 0; i < ents.Length; i++) 

                                Entities[ents[i]].Selected = true; 
                        } 
                        break; 

                } 
                Invalidate(); 
            } 

            base.OnMouseUp(e); 
        } 

        protected override void DrawOverlay(float drawScale, RectangleF zoomRect) 
        { 
            if (buttonPressed) 
            { 
                if (currPickState == pickState.Crossing) 
                    DrawSelectionBox(initialLocation, currentLocation, Color.DarkBlue, true, true); 
                else if (currPickState == pickState.Enclosed) 
                    DrawSelectionBox(initialLocation, currentLocation, Color.DarkRed, true, false); 
            } 
        } 

        void DrawSelectionBox(System.Drawing.Point p1, System.Drawing.Point p2, Color transparentColor, bool drawBorder, bool dottedBorder) 
        { 
            NormalizeBox(ref p1, ref p2); 

            gl.Enable(gl.BLEND); 

            gl.Color4ub(transparentColor.R, transparentColor.G, transparentColor.B, 40); 
            gl.Disable(gl.CULL_FACE); 
            gl.PolygonMode(gl.FRONT, gl.FILL); 

            gl.Begin(gl.POLYGON); 

            DrawBox(p1.X + 1, p1.Y + 1, p2.X, p2.Y, 0); 

            gl.End(); 
            gl.Disable(gl.BLEND); 

            if (drawBorder) 
            { 
                gl.Color3ub(transparentColor.R, transparentColor.G, transparentColor.B); 

                if (dottedBorder) 
                { 
                    gl.LineStipple(1, 0x0F0F); 
                    gl.Enable(gl.LINE_STIPPLE); 
                } 

                gl.Begin(gl.LINE_LOOP); 

                DrawBox(p1.X, p1.Y, p2.X, p2.Y, 1); 

                gl.End(); 

                if (dottedBorder) 
                    gl.Disable(gl.LINE_STIPPLE); 
            } 
        } 

        protected void DrawBox(int firstX, int firstY, int secondX, int secondY, int zOffset) 
        { 

            gl.Vertex3i(firstX, Height - firstY, zOffset); 
            gl.Vertex3i(secondX, Height - firstY, zOffset); 

            gl.Vertex3i(secondX, Height - secondY, zOffset); 
            gl.Vertex3i(firstX, Height - secondY, zOffset); 

        } 

        internal static void NormalizeBox(ref System.Drawing.Point p1, ref System.Drawing.Point p2) 
        { 

            int firstX = Math.Min(p1.X, p2.X); 
            int firstY = Math.Min(p1.Y, p2.Y); 
            int secondX = Math.Max(p1.X, p2.X); 
            int secondY = Math.Max(p1.Y, p2.Y); 

            p1.X = firstX; 
            p1.Y = firstY; 
            p2.X = secondX; 
            p2.Y = secondY; 

        } 
    } 
Have more questions? Submit a request

4 Comments

  • 0
    Avatar
    Anssi Kettunen

    In EyeShot 7.0 replace

    override void DrawOverlay(float drawScale, RectangleF zoomRect)

    with

    override void DrawOverlay(DrawSceneParams myParams)

  • 0
    Avatar
    Nandini

    If I have a Line Entity on top of a Solid Entity and trying to select Line Entity, the following statement gets the Solid Entity and not the line. How can I select the Line?

    ent = GetEntityUnderMouseCursor(currentLocation);

  • 0
    Avatar
    Luca Cornazzani

    Hi Nandini,

    our HelpDesk is the right place to ask questions not directly related to the topic of this page.

    Please open a ticket there.

  • 0
    Avatar
    Matt Salzer

    How can I get the drawn rectangle to stay on the screen after a mouseup event is performed?

Please sign in to leave a comment.