public MainWindow()
        {
            Fake_InitializeComponent();

            DragInfo = new DragInfo_();
            OpObject = new ObjectMapElement();
        }
        private void glc_MouseUp(Object sender, MouseEventArgs e)
        {
            // Was to drag but didn't, treated as clicked
            if (!DragInfo.WasDragging)
            {
                // This behavious is usually cancelling actions
                if (DragInfo.State == DragState.RightButton)
                {
                    IsSplitting            = false;
                    PreviousSplittedVertex = null;
                }
                else if (DragInfo.State == DragState.LeftButton)
                {
                    OpObject = ObjectMapFuzzy(e.X, e.Y, 3, (int)ObjectType.ModelVertex);

                    TryKeepSelection();

                    if (OpObject.Type == ObjectType.ModelVertex)
                    {
                        ModelVertex_Click();
                    }
                    else if (OpObject.Type == ObjectType.ModelEdge)
                    {
                        ModelEdge_Click();
                    }
                    else if (OpObject.Type == ObjectType.ModelFacet)
                    {
                        ModelFacet_Click();
                    }
                }
            }
            else if (DragInfo.State == DragState.None)
            {
                TryKeepSelection();
            }

            if (DragInfo.State == DragState.BoxSelect)
            {
                BoxSelect_Finished();
                this.BoxSelectingType = ObjectType.None;
            }

            DragInfo.Reset();
        }
        ObjectMapElement ObjectMapFuzzy(int x, int y,
                                        int r = 3, int obj_upbound = int.MaxValue)
        {
            int type = 0;
            int offx = -r, offy = -r;

            UpdateObjectMap();

            for (int i = -r; i <= r; i++)
            {
                for (int j = -r; j <= r; j++)
                {
                    int Y = Viewport.Height - y - 1 + i, X = x + j;
                    int cur_type = UnpackVal(obj_map_buffer[Y, X, 0]).Item2;

                    if (cur_type > type && cur_type <= obj_upbound &&
                        offx * offx + offy * offy > i * i + j * j)
                    {
                        type = cur_type;
                        offy = i;
                        offx = j;
                    }
                }
            }

            int max_x = x + offx, max_y = Viewport.Height - y - 1 + offy;

            ObjectMapElement me = new ObjectMapElement();
            // in controller map, index-0 means emptiness
            var val = UnpackVal(obj_map_buffer[max_y, max_x, 0]);

            me.Index    = val.Item1;
            me.Type     = (ObjectType)val.Item2;
            me.Position = new Vector3(obj_map_buffer[max_y, max_x, 1],
                                      obj_map_buffer[max_y, max_x, 2],
                                      obj_map_buffer[max_y, max_x, 3]);

            me.ScreenX = max_x;
            me.ScreenY = Viewport.Height - max_y - 1;

            return(me);
        }
        private void glc_MouseMove(Object sender, MouseEventArgs e)
        {
            DragState s = DragInfo.State;

            DragInfo.CurrentX = e.X;
            DragInfo.CurrentY = e.Y;

            if (DragInfo.CurrentX == DragInfo.StartX &&
                DragInfo.CurrentY == DragInfo.StartY &&
                !DragInfo.WasDragging)
            {
                return;
            }

            if (s == DragState.None)
            {
                return;
            }

            if (s < DragState.RawStates)
            {
                if (s == DragState.LeftButton)
                {
                    OpObject = ObjectMapFuzzy(DragInfo.StartX, DragInfo.StartY);

                    bool save_selected_pos = true;

                    if (BoxSelectingType != ObjectType.None)
                    {
                        DragInfo.State = DragState.BoxSelect;
                    }
                    else if (OpObject.Type == ObjectType.TranslationTransformer)
                    {
                        DragInfo.State = DragState.TranslationTransformer;
                    }
                    else if (OpObject.Type == ObjectType.ScalingTransformer)
                    {
                        DragInfo.State = DragState.ScalingTransformer;
                    }
                    else if (OpObject.Type == ObjectType.RotationTransformer)
                    {
                        DragInfo.State = DragState.RotationTransformer;
                    }
                    else
                    {
                        DragInfo.State    = DragState.None;
                        save_selected_pos = false;
                    }

                    if (save_selected_pos)
                    {
                        var start_pos = new List <Tuple <int, Vector3> >();
                        foreach (MeshVertex v in Model.SelectedVertices)
                        {
                            start_pos.Add(new Tuple <int, Vector3>(
                                              v.Index, v.Position));
                        }
                        DragInfo.StartInfo = start_pos;
                    }
                }

                if (s == DragState.MiddleButton)
                {
                    DragInfo.State     = DragState.CameraRotation;
                    DragInfo.StartInfo = new Transformation(MainCamera.Tf);
                }

                if (s == DragState.RightButton)
                {
                    DragInfo.State     = DragState.CameraTranslation;
                    DragInfo.StartInfo = new Transformation(MainCamera.Tf);
                }

                glc_MouseMove(sender, e);
                DragInfo.WasDragging = true;
                return;
            }

            if (s == DragState.CameraRotation)
            {
                CameraRotation_Drag();
            }
            else if (s == DragState.CameraTranslation)
            {
                CameraTranslation_Drag();
            }
            else if (s == DragState.TranslationTransformer)
            {
                TranslationTransformer_Drag();
            }
            else if (s == DragState.ScalingTransformer)
            {
                ScalingTransformer_Drag();
            }
            else if (s == DragState.RotationTransformer)
            {
                RotationTransformer_Drag();
            }

            DragInfo.WasDragging = true;
        }