Subversion Repositories AndroidProjects

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Reflection;
using System.ComponentModel;
using System.Threading;
using System.Globalization;


using BauzoidNET.graphics;
using BauzoidNET.graphics.sprite;
using BauzoidNET.math;

using OrderedPropertyGrid;

namespace ShapeEditor.file.shapes
{
    [TypeConverter(typeof(PropertySorter))]
    public class EllipseElement : BaseShapeElement
    {
        public const int NUM_HANDLES = 4;

        private Vector2[] mHandles = new Vector2[NUM_HANDLES];

        public float centerX = 0;
        public float centerY = 0;
        public float radiusX = 0;
        public float radiusY = 0;

        [Category("Coordinates"), PropertyOrder(10)]
        public float CenterX
        {
            get { return centerX; }
            set { centerX = value; }
        }

        [Category("Coordinates"), PropertyOrder(11)]
        public float CenterY
        {
            get { return centerY; }
            set { centerY = value; }
        }

        [Category("Coordinates"), PropertyOrder(12)]
        public float RadiusX
        {
            get { return radiusX; }
            set { radiusX = value; }
        }

        [Category("Coordinates"), PropertyOrder(13)]
        public float RadiusY
        {
            get { return radiusY; }
            set { radiusY = value; }
        }

        public EllipseElement(Document doc, string name, float _centerX, float _centerY, float _radiusX, float _radiusY)
            : base(doc, name)
        {
            centerX = _centerX; centerY = _centerY; radiusX = _radiusX; radiusY = _radiusY;

            for (int i = 0; i < NUM_HANDLES; i++)
                mHandles[i] = new Vector2();
        }

        public override void Render(SpriteTransform transform)
        {
            float z = mDocument.Owner.ZoomFactor;
           
            float x1 = centerX - radiusX;
            float y1 = centerY - radiusY;
            float x2 = centerX + radiusX;
            float y2 = centerY + radiusY;

            x1 *= z;
            y1 *= z;
            x2 *= z;
            y2 *= z;
            //RenderUtil.drawQuad(MainForm.App.getGraphics(), centerX * z, centerY * z, (centerX + radiusX) * z, (centerY + radiusY) * z, transform, Document.SHAPE_COLOR);
            RenderUtil.drawEllipse(MainForm.App.getGraphics(), x1, y1, x2, y2, transform, Document.SHAPE_COLOR);
        }

        public override void RenderSelected(SpriteTransform transform, bool drawHandles = true)
        {
            float z = mDocument.Owner.ZoomFactor;
            //RenderUtil.drawQuad(MainForm.App.getGraphics(), centerX * z, centerY * z, (centerX + radiusX) * z, (centerY + radiusY) * z, transform, Document.SHAPE_COLOR_SELECTED);

            float x1 = centerX - radiusX;
            float y1 = centerY - radiusY;
            float x2 = centerX + radiusX;
            float y2 = centerY + radiusY;

            x1 *= z;
            y1 *= z;
            x2 *= z;
            y2 *= z;

            RenderUtil.drawEllipse(MainForm.App.getGraphics(), x1, y1, x2, y2, transform, Document.SHAPE_COLOR_SELECTED);

            if (drawHandles)
            {
                for (int i = 0; i < NUM_HANDLES; i++)
                    mDocument.RenderHandle(mHandles[i].x, mHandles[i].y, transform);

                /*mDocument.RenderHandle(centerX - radiusX, centerY - radiusY, transform);
                mDocument.RenderHandle((centerX + radiusX), centerY - radiusY, transform);
                mDocument.RenderHandle(centerX - radiusX, (centerY + radiusY), transform);
                mDocument.RenderHandle((centerX + radiusX), (centerY + radiusY), transform);*/

            }
        }

        public override int GetNumHandles() { return NUM_HANDLES; }

        public override int FindHandleAt(float px, float py)
        {
            UpdateHandles();

            for (int i = 0; i < NUM_HANDLES; i++)
            {
                if (IsInsideHandle(px, py, mHandles[i].x, mHandles[i].y))
                    return i;
            }

            return -1;
        }

        public override bool IsInside(float px, float py)
        {
            px -= mDocument.Sprite.transform.x;
            py -= mDocument.Sprite.transform.y;

            px /= mDocument.Owner.ZoomFactor;
            py /= mDocument.Owner.ZoomFactor;

            //return ((px >= centerX) && (px <= (centerX + radiusX)) && (py >= centerY) && (py <= (centerY + radiusY)));

            if (radiusX == 0)
                return false;
            if (radiusY == 0)
                return false;

            float dx = (px - centerX);
            float dy = (py - centerY);

            if (((dx * dx) / (radiusX * radiusX) + (dy * dy) / (radiusY * radiusY)) <= 1)
                return true;

            return false;
//              return (((dx*dx)/(radiusX*radiusX) + (dy*dy)/(radiusY*radiusY)) <= 1);         
        }

        public void UpdateHandles()
        {
            mHandles[0].set(centerX - radiusX, centerY - radiusY);
            mHandles[1].set(centerX + radiusX, centerY - radiusY);
            mHandles[2].set(centerX - radiusX, centerY + radiusY);
            mHandles[3].set(centerX + radiusX, centerY + radiusY);
        }

        public override Cursor GetCursor(int handle)
        {
            if (handle == 0)
                return Cursors.SizeNWSE;
            else if (handle == 1)
                return Cursors.SizeNESW;
            else if (handle == 2)
                return Cursors.SizeNESW;
            else if (handle == 3)
                return Cursors.SizeNWSE;
            return Cursors.Arrow;
        }

        public bool IsInsideHandle(float px, float py, float handleX, float handleY)
        {
            px -= mDocument.Sprite.transform.x;
            py -= mDocument.Sprite.transform.y;

            px /= mDocument.Owner.ZoomFactor;
            py /= mDocument.Owner.ZoomFactor;

            if ((Math.Abs(handleX - px) < Document.HANDLE_SIZE / 2) && (Math.Abs(handleY - py) < Document.HANDLE_SIZE / 2))
                return true;

            return false;
        }

        public override void DragHandle(int handle, float dx, float dy)
        {
            UpdateHandles();

            dx /= mDocument.Owner.ZoomFactor;
            dy /= mDocument.Owner.ZoomFactor;

            if (handle == 0)
            {
                // upper left
                centerX += dx/2; radiusX -= dx/2;
                centerY += dy/2; radiusY -= dy/2;
            }
            else if (handle == 1)
            {
                // upper right
                centerX += dx/2; radiusX += dx/2;
                centerY += dy/2; radiusY -= dy/2;
            }
            else if (handle == 2)
            {
                // lower left
                centerX += dx/2; radiusX -= dx/2;
                centerY += dy/2;  radiusY += dy/2;
            }
            else if (handle == 3)
            {
                // lower right
                centerX += dx/2; radiusX += dx/2;
                centerY += dy/2; radiusY += dy/2;
            }

            mDocument.SetDirty();

            UpdateHandles();

            UpdateName();
        }

        public override void DragMove(float dx, float dy)
        {
            centerX += dx / mDocument.Owner.ZoomFactor;
            centerY += dy / mDocument.Owner.ZoomFactor;

            mDocument.SetDirty();

            UpdateHandles();

            UpdateName();
        }

        public void UpdateName()
        {
            //ShapeName = "rect " + Math.Min(centerX, centerX + radiusX) + ", " + Math.Min(centerY, centerY + radiusY) + ", " + Math.Abs(radiusX) + ", " + Math.Abs(radiusY);
            ShapeName = "ellipse " + centerX + ", " + centerY + ", " + radiusX + ", " + radiusY;
            typeof(ListBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, mDocument.Owner.ElementsListBox, new object[] { });
        }

        public override void FixCoordinates()
        {
            if (radiusX < 0)
            {
                radiusX = -radiusX;
                /*centerX = centerX + radiusX;
                radiusX = -radiusX;*/

            }
            if (radiusY < 0)
            {
                radiusY = -radiusY;
                /*centerY = centerY + radiusY;
                radiusY = -radiusY;*/

            }
        }

        public override void WriteFile(System.IO.TextWriter tw)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            tw.WriteLine("ellipse " + centerX + ", " + centerY + ", " + radiusX + ", " + radiusY + ";");
        }

    }
}