Click here to Skip to main content
15,881,882 members
Articles / Containers / Docker

SVG Artiste - An SVG Editor

Rate me:
Please Sign up or sign in to vote.
4.69/5 (23 votes)
3 Aug 2010CPOL14 min read 95.8K   15.4K   93  
A Vector based tool to create and edit SVG images
/***************************************************************************
 *   CopyRight (C) 2009 by Cristinel Mazarine                              *
 *   Author:   Cristinel Mazarine                                          *
 *   Contact:  cristinel@osec.ro                                           *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the Crom Free License as published by           *
 *   the SC Crom-Osec SRL; version 1 of the License                        *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   Crom Free License for more details.                                   *
 *                                                                         *
 *   You should have received a copy of the Crom Free License along with   *
 *   this program; if not, write to the contact@osec.ro                    *
 ***************************************************************************/

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace Crom.Controls.TabbedDocument
{
   /// <summary>
   /// Renderer for left tab button
   /// </summary>
   public class RightTabButtonRenderer : TabButtonRenderer
   {
      #region Fields.

      private const int                ButtonRightMargin                   = 2;
      private const int                PanelMargin                         = 0;
      private const int                ButtonVerticalMargins               = 16;
      private const int                ButtonWidth                         = 16;

      #endregion Fields.

      #region Instance.

      /// <summary>
      /// Default constructor
      /// </summary>
      public RightTabButtonRenderer()
      {
         BackGradientMode = LinearGradientMode.Horizontal;
      }

      #endregion Instance

      #region Public section.

      /// <summary>
      /// Draw the button
      /// </summary>
      /// <param name="bounds">button bounds</param>
      /// <param name="text">button text</param>
      /// <param name="selected">flag indicating that should use selected colors</param>
      /// <param name="font">font used to draw the text</param>
      /// <param name="icon">icon associated with the button</param>
      /// <param name="graphics">graphics</param>
      public override void Draw(Rectangle bounds, string text, bool selected, Font font, Icon icon, Graphics graphics)
      {
         using (GraphicsPath button = new GraphicsPath())
         {
            int x1 = bounds.X;
            int y1 = bounds.Bottom + (int)(bounds.Width * 0.75);

            int x2 = bounds.Right - 2;
            int y2 = bounds.Bottom - (int)(bounds.Width * 0.25) + 2;

            int x3 = bounds.Right;
            int y3 = bounds.Bottom - (int)(bounds.Width * 0.25) - 1;

            int x4 = bounds.Right;
            int y4 = bounds.Y + 2;

            int x5 = bounds.Right - 2;
            int y5 = bounds.Y;

            int x6 = bounds.X;
            int y6 = bounds.Y;

            button.AddLine(x1 - 1, y1, x2, y2);
            button.AddLine(x2, y2, x3, y3);
            button.AddLine(x3, y3, x4, y4);
            button.AddLine(x4, y4, x5, y5);
            button.AddLine(x5, y5, x6 - 1, y6);
            button.CloseFigure();

            bounds.X -= 2;
            bounds.Width += 2;
            using (LinearGradientBrush backBrush = new LinearGradientBrush(bounds, GetBackGradient2Color(selected), GetBackGradient1Color(selected), BackGradientMode))
            {
               graphics.FillPath(backBrush, button);

               using (Pen pen = new Pen(GetBorder2Color(selected)))
               {
                  graphics.DrawLine(pen, x1, y1, x2, y2);
                  graphics.DrawLine(pen, x2, y2, x3, y3);
                  graphics.DrawLine(pen, x3, y3, x4, y4);
                  graphics.DrawLine(pen, x4, y4, x5, y5);
                  graphics.DrawLine(pen, x5, y5, x6 - 1, y6);
               }

               using (Pen pen = new Pen(GetBorder1Color(selected)))
               {
                  graphics.DrawLine(pen, x1, y1 - 1, x2, y2 - 1);
               }

               if (selected == false)
               {
                  using (Pen pen = new Pen(GetBorder2Color(selected)))
                  {
                     graphics.DrawLine(pen, x1, y6 + 1, x6, y1);
                  }
               }
            }
         }

         Rectangle textBounds = bounds;
         textBounds.Y += 10;

         if (icon != null)
         {
            graphics.DrawIcon(icon, new Rectangle(bounds.X + 4, textBounds.Y + 2, ButtonWidth - 4, ButtonWidth - 4));
            textBounds.Y += ButtonWidth;
         }

         using (Brush textBrush = new SolidBrush(TextColor))
         {
            graphics.DrawString(text, font, textBrush, textBounds, new StringFormat(StringFormatFlags.DirectionVertical));
         }
      }

      /// <summary>
      /// Draw buttons line
      /// </summary>
      /// <param name="graphics">graphics object</param>
      /// <param name="panelBounds">panel bounds</param>
      /// <param name="buttonsPanelBounds">buttons panel bounds</param>
      public override void DrawButtonsLine(Graphics graphics, Rectangle panelBounds, Rectangle buttonsPanelBounds)
      {
         using (Pen pen = new Pen(GetBorder2Color(true)))
         {
            graphics.DrawLine(pen, buttonsPanelBounds.Left + 1, panelBounds.Top, buttonsPanelBounds.Left + 1, panelBounds.Bottom);
         }
      }

      /// <summary>
      /// Draw the scroll back button
      /// </summary>
      /// <param name="bounds">button bounds</param>
      /// <param name="state">flag indicating the state of the button</param>
      /// <param name="graphics">graphics</param>
      public override void DrawScrollBackButton(Rectangle bounds, zButtonState state, Graphics graphics)
      {
         int x1 = bounds.Left + bounds.Width / 2 + 1;
         int y1 = bounds.Top + 5;

         int y2 = y1 + 5;
         int x2 = x1 - 4;

         int y3 = y2;
         int x3 = x1 + 4;

         using (GraphicsPath arrowHeadPath = new GraphicsPath())
         {
            arrowHeadPath.AddLine(x1, y1, x2, y2);
            arrowHeadPath.AddLine(x2, y2, x3, y3);
            arrowHeadPath.CloseFigure();

            switch (state)
            {
               case zButtonState.Normal:
                  graphics.FillPath(Brushes.LightSteelBlue, arrowHeadPath);

                  //graphics.DrawLine(Pens.DarkBlue, x1, y1 - 1, x2, y2 - 1);
                  //graphics.DrawLine(Pens.DarkBlue, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.White, x3, y3 + 1, x1, y1 + 1);

                  break;

               case zButtonState.Focus:
                  graphics.FillPath(Brushes.LightGreen, arrowHeadPath);

                  //graphics.DrawLine(Pens.Blue, x1, y1 - 1, x2, y2 - 1);
                  //graphics.DrawLine(Pens.Blue, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.White, x3, y3 + 1, x1, y1 + 1);

                  break;

               case zButtonState.Pressed:
                  graphics.FillPath(Brushes.LightSteelBlue, arrowHeadPath);

                  //graphics.DrawLine(Pens.DarkBlue, x3, y3 + 1, x1, y1 + 1);
                  //graphics.DrawLine(Pens.DarkBlue, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.WhiteSmoke, x1, y1 - 1, x2, y2 - 1);

                  break;

               case zButtonState.UnderMouseCursor:
                  graphics.FillPath(Brushes.LightSteelBlue, arrowHeadPath);

                  //graphics.DrawLine(Pens.Blue, x1, y1 - 1, x2, y2 - 1);
                  //graphics.DrawLine(Pens.Blue, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.White, x3, y3 + 1, x1, y1 + 1);

                  break;

               case zButtonState.Disabled:
                  graphics.FillPath(Brushes.Gray, arrowHeadPath);

                  //graphics.DrawLine(Pens.DarkGray, x1, y1 - 1, x2, y2 - 1);
                  //graphics.DrawLine(Pens.DarkGray, x1, y1 + 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.White,    x2, y2 - 1, x3, y3 + 1);

                  break;
            }
         }
      }

      /// <summary>
      /// Draw the scroll next button
      /// </summary>
      /// <param name="bounds">button bounds</param>
      /// <param name="state">flag indicating the state of the button</param>
      /// <param name="graphics">graphics</param>
      public override void DrawScrollNextButton(Rectangle bounds, zButtonState state, Graphics graphics)
      {
         int x1 = bounds.Left + bounds.Width / 2 + 1;
         int y1 = bounds.Bottom - 5;

         int y2 = y1 - 4;
         int x2 = x1 - 4;

         int y3 = y2;
         int x3 = x1 + 4;

         using (GraphicsPath arrowHeadPath = new GraphicsPath())
         {
            arrowHeadPath.AddLine(x1, y1, x2, y2);
            arrowHeadPath.AddLine(x2, y2, x3, y3);
            arrowHeadPath.CloseFigure();

            switch (state)
            {
               case zButtonState.Normal:
                  graphics.FillPath(Brushes.LightSteelBlue, arrowHeadPath);

                  //graphics.DrawLine(Pens.DarkBlue, x1, y1 - 1, x2, y2 - 1);
                  //graphics.DrawLine(Pens.DarkBlue, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.White, x3, y3 + 1, x1, y1 + 1);

                  break;

               case zButtonState.Focus:
                  graphics.FillPath(Brushes.LightGreen, arrowHeadPath);

                  //graphics.DrawLine(Pens.Blue, x1, y1 - 1, x2, y2 - 1);
                  //graphics.DrawLine(Pens.Blue, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.White, x3, y3 + 1, x1, y1 + 1);

                  break;

               case zButtonState.Pressed:
                  graphics.FillPath(Brushes.LightSteelBlue, arrowHeadPath);

                  //graphics.DrawLine(Pens.DarkBlue, x3, y3 + 1, x1, y1 + 1);
                  //graphics.DrawLine(Pens.DarkBlue, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.WhiteSmoke, x1, y1 - 1, x2, y2 - 1);

                  break;

               case zButtonState.UnderMouseCursor:
                  graphics.FillPath(Brushes.LightSteelBlue, arrowHeadPath);

                  //graphics.DrawLine(Pens.Blue, x1, y1 - 1, x2, y2 - 1);
                  //graphics.DrawLine(Pens.Blue, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.White, x3, y3 + 1, x1, y1 + 1);

                  break;

               case zButtonState.Disabled:
                  graphics.FillPath(Brushes.Gray, arrowHeadPath);

                  //graphics.DrawLine(Pens.DarkGray, x1, y1 - 1, x2, y2 - 1);
                  //graphics.DrawLine(Pens.DarkGray, x2, y2 - 1, x3, y3 + 1);
                  //graphics.DrawLine(Pens.White, x3, y3 + 1, x1, y1 + 1);

                  break;
            }
         }
      }

      /// <summary>
      /// Checks if the panel has scrolls
      /// </summary>
      /// <param name="panelBounds">panel bounds</param>
      /// <param name="lastButtonBounds">last button bounds</param>
      /// <returns>true if the panel has scrolls</returns>
      public override bool HasScroll(Rectangle panelBounds, Rectangle lastButtonBounds)
      {
         return lastButtonBounds.Bottom >= panelBounds.Bottom;
      }

      /// <summary>
      /// Get the bounds of the scroll back button
      /// </summary>
      /// <param name="panelBounds">bounds of the panel</param>
      /// <returns>bounds of the scroll back button</returns>
      public override Rectangle GetScrollBackButtonBounds(Rectangle panelBounds)
      {
         return new Rectangle(panelBounds.Left + 3, panelBounds.Top - ButtonWidth, ButtonWidth - ButtonRightMargin, ButtonWidth - ButtonRightMargin);
      }

      /// <summary>
      /// Get the bounds of the scroll next button
      /// </summary>
      /// <param name="panelBounds">bounds of the panel</param>
      /// <returns>bounds of the scroll next button</returns>
      public override Rectangle GetScrollNextButtonBounds(Rectangle panelBounds)
      {
         return new Rectangle(panelBounds.Left + 3, panelBounds.Bottom + 4, ButtonWidth - ButtonRightMargin, ButtonWidth - ButtonRightMargin);
      }

      /// <summary>
      /// Get first button bounds
      /// </summary>
      /// <param name="panelBounds">bounds of the panel</param>
      /// <param name="hasScroll">flag indicating that panel has scrolls</param>
      /// <param name="scrolPos">scroll position</param>
      /// <param name="text">text of the button</param>
      /// <param name="font">font used to draw the button</param>
      /// <param name="icon">icon associated with the button</param>
      /// <param name="graphics">graphics object</param>
      /// <returns>bounds of the first button</returns>
      public override Rectangle GetFirstButtonBounds(Rectangle panelBounds, bool hasScroll, int scrolPos, string text, Font font, Icon icon, Graphics graphics)
      {
         int dY = 4 + PanelMargin;

         if (hasScroll)
         {
            dY += ButtonWidth - ButtonRightMargin;
         }

         return GetButtonBounds(panelBounds.Right - ButtonRightMargin - ButtonWidth - 1, -scrolPos + dY, text, font, icon, graphics);
      }

      /// <summary>
      /// Get next button bounds
      /// </summary>
      /// <param name="previousBounds">bounds of the previous button</param>
      /// <param name="text">text of the button</param>
      /// <param name="font">font used to draw the button</param>
      /// <param name="icon">icon associated with the button</param>
      /// <param name="graphics">graphics object</param>
      /// <returns>bounds of the next button</returns>
      public override Rectangle GetNextButtonBounds(Rectangle previousBounds, string text, Font font, Icon icon, Graphics graphics)
      {
         return GetButtonBounds(previousBounds.Left, previousBounds.Bottom + 2, text, font, icon, graphics);
      }

      /// <summary>
      /// Get client rectangle for the panel bounds
      /// </summary>
      /// <param name="panelBounds">bounds of the panel</param>
      /// <returns>client rectangle for the panel</returns>
      public override Rectangle GetClientRectangle(Rectangle panelBounds)
      {
         Rectangle clientRectangle = new Rectangle();

         clientRectangle.X       = panelBounds.X;
         clientRectangle.Y       = panelBounds.Y;
         clientRectangle.Width   = panelBounds.Width - clientRectangle.X - ButtonRightMargin - ButtonWidth;
         clientRectangle.Height  = panelBounds.Height - 1;

         return clientRectangle;
      }

      /// <summary>
      /// Get buttons clip rectangle
      /// </summary>
      /// <param name="panelBounds">bounds of the panel</param>
      /// <param name="hasScroll">true if the panel has scroll</param>
      /// <param name="captionButtonsCount">number of caption buttons that may be drawn on buttons panel</param>
      /// <returns>clip rectangle for the buttons</returns>
      public override Rectangle GetButtonsClipRectangle(Rectangle panelBounds, bool hasScroll, int captionButtonsCount)
      {
         int dY = 4 + PanelMargin;

         if (hasScroll)
         {
            dY += ButtonWidth - ButtonRightMargin;
         }

         int dh = ButtonWidth * captionButtonsCount;

         return new Rectangle(panelBounds.Right - ButtonRightMargin - ButtonWidth - 1, dY, ButtonWidth + 2, panelBounds.Bottom - 2 * dY - PanelMargin - dh);
      }

      /// <summary>
      /// Get the rectangle which will contain caption buttons drawn on panel buttons
      /// </summary>
      /// <param name="panelBounds">panel bounds</param>
      /// <param name="captionButtonsCount">number of caption buttons</param>
      /// <returns>rectangle containing caption buttons</returns>
      public override Rectangle GetCaptionButtonsRectangle(Rectangle panelBounds, int captionButtonsCount)
      {
         int width  = ButtonWidth - ButtonRightMargin;
         int height = ButtonWidth * captionButtonsCount;

         return new Rectangle(panelBounds.Right - ButtonWidth - 2, panelBounds.Bottom - height - PanelMargin, width, height);
      }

      /// <summary>
      /// Get the caption button index
      /// </summary>
      /// <param name="captionButtonsBounds">bounds of the caption buttons block</param>
      /// <param name="point">point where to search the button</param>
      /// <returns>zero based caption button index</returns>
      public override int GetCaptionButtonIndex(Rectangle captionButtonsBounds, Point point)
      {
         if (captionButtonsBounds.Contains(point) == false)
         {
            return -1;
         }

         return (point.Y - captionButtonsBounds.Top) / ButtonWidth;
      }

      /// <summary>
      /// Can undo the displacement of the next button (the next button was displaced before)
      /// </summary>
      /// <param name="displacedButton">displaced button</param>
      /// <param name="selectedButton">selected button</param>
      /// <param name="mouseLocation">current mouse location</param>
      /// <returns>true if can undo</returns>
      internal override bool CanUndoDisplaceNext(TabButton displacedButton, TabButton selectedButton, Point mouseLocation)
      {
         return true;
      }

      /// <summary>
      /// Can undo the displacement of the previous button (the previous button was displaced before)
      /// </summary>
      /// <param name="displacedButton">displaced button</param>
      /// <param name="selectedButton">selected button</param>
      /// <param name="mouseLocation">current mouse location</param>
      /// <returns>true if can undo</returns>
      internal override bool CanUndoDisplaceBack(TabButton displacedButton, TabButton selectedButton, Point mouseLocation)
      {
         return mouseLocation.Y < displacedButton.Top + selectedButton.Height;
      }

      /// <summary>
      /// Checks if can scroll next
      /// </summary>
      /// <param name="lastButton">last button</param>
      /// <param name="scrollNextBounds">scroll-next bounds</param>
      /// <returns>true if can scroll next</returns>
      internal override bool CanScrollNext(TabButton lastButton, Rectangle scrollNextBounds)
      {
         return lastButton.Top + lastButton.Height > scrollNextBounds.Top;
      }

      /// <summary>
      /// Get scroll position
      /// </summary>
      /// <param name="buttons">buttons collection</param>
      /// <param name="firstShownButtonIndex">zero based first shown button index</param>
      /// <returns>scroll position</returns>
      internal override int GetScrollPos(IList<TabButton> buttons, int firstShownButtonIndex)
      {
         int scrollPos = 0;
         for (int buttonIndex = 0; buttonIndex < firstShownButtonIndex; buttonIndex++)
         {
            scrollPos += buttons[buttonIndex].Height;
         }

         return scrollPos;
      }

      #endregion Public section.

      #region Private section.

      /// <summary>
      /// Get button bounds
      /// </summary>
      /// <param name="xPos">x position of the button</param>
      /// <param name="yPos">y position of the button</param>
      /// <param name="text">text of the button</param>
      /// <param name="font">font used to draw the button</param>
      /// <param name="icon">icon associated with the button</param>
      /// <param name="graphics">graphics object</param>
      /// <returns>bounds of the button</returns>
      private Rectangle GetButtonBounds(int xPos, int yPos, string text, Font font, Icon icon, Graphics graphics)
      {
         int height = ButtonVerticalMargins + (int)graphics.MeasureString(text, font).Width;

         Rectangle bounds = new Rectangle();

         bounds.X       = xPos;
         bounds.Y       = yPos;
         bounds.Width   = ButtonWidth;
         bounds.Height  = height;

         if (icon != null)
         {
            bounds.Height += ButtonWidth;
         }

         return bounds;
      }

      #endregion Private section.
   }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer
Singapore Singapore
He is a Microsoft technology enthusiast, who wish to create applications which others find useful.He loves making small tools and getting involved in architecting bigger systems.

He is currently working as a professional developer in a software development firm in .Net technologies.

He likes reading technical blogs, contributing to opensource and most importantly, enjoying life.

His ambition is to be an impressive software maker.

Comments and Discussions