Click here to Skip to main content
Click here to Skip to main content

Improved and Recoded RibbonMenuButton

By , 5 Jun 2007
 
Screenshot - presentation.png

Introduction

First of all, thanks to everyone. I am grateful to know that people value this effort. I remember like yesterday when I was sixteen, more or less, and I saw many types of software, apps and games. For me, it was impossible to access and develop software then. I have learned a lot since, however, and I realize that it's now one million times easier to access this kind of software. Furthermore, if I can help anyone to create eye-candy apps, I've decided that they can use my code freely.

Background

I was thinking about how to make a fully customizable button and about how difficult it was changing RGB components. I decided to make RibbonColor, which has many options to operate with colors. If you play the demo app, you will understand quickly as you move the Hue, Sat and Brightness track bar. I have to admit that I have approximately 70% of the new RibbonControl library finished. However, as people are anxious to have improved code and have told me that I did not explain practically anything about my code, I've decided to do this like for dummies. So, here we go.

How to Use the Code

First of all, create a new Windows application. From the Solution Explorer, choose the option Add Existing Item. Then choose RibbonMenuButton.cs and Rebuild the project. Now, if you go to the form1 designer, in the toolbox you will have RibbonMenuButton. Drag it to the form. You will see a control without sense, but let's play with the properties. First, set properties for the RibbonMenuButton:

Screenshot - ribbonmenubuttonprops.png

When you have set the properties, add an image, set the text you want and set the font to Segoe UI if you have it. You will have something like this:

Screenshot - trialbutton.png

If you have compiled the project and you get this, the next step is to change the properties of the control. Let's see what each property represents. I recommend that you look at the button's Properties settings in the demo project:

  • Arrow: Paints an arrow ToRight or ToDown; this only paints, as the double functionality is in another property.
  • Colors: I think this doesn't need explanation; I recommend you to use the PlayGround app to choose your colors.
  • FadingSpeed: This facilitates fading between colors; choose 0 to avoid fading.
  • GroupPos: This is to make round corners on the Left, Right, Center (None), Top or Bottom.
  • ImageLocation: To put the image on the Left, Right, Top or Bottom.
  • ImageOffset: To offset from the borders.
  • MaxImageSize: To make buttons larger with a scaling image limit.
  • Radius: The corner radius.
  • ShowBase: If you want to show the BaseColor and BaseStroke color where Transparent is a color and makes fading. If set to No, it doesn't make fading.
  • SplitButton: Creates a double function button; the arrow section opens the associated ContextMenu and the other section, the main event.
  • SplitDistance: How big the arrow section button is.
  • Title: If you set this different from "", it automatically puts the title bold and under the text.
  • Text: If you have a title and want two lines of text, add \n to the text to make two lines.
  • KeepPress, IsPressed: If KeepPress is active on some buttons, when one of them is pressed, it keeps the press and the others in the containers lose the IsPress.

I have tried to crash the app, but it always works. So, I think the code is effectively error-free.

Points of Interest

If you want to learn more about these controls, I recommend that you take a look at:

  • this.Region: That's a good way to avoid matters of transparency.
  • LinearGradient With multiple colors, that makes the gradients easy.
  • MeasureString: That's a good method to position the text because you have to take away the base.OnPaint -> you have to do everything, including write the text.
  • TransformColors Method including the alpha opacity.
  • DrawArc method: As you can see, with the radius you can make smooth corners.
  • OnMouseUp: Here you can see what happens when the SplitButton is activated and IsPressed activated.
  • RibbonColor: I took the formulas from Wikipedia and Gimp. The System.Drawing.Color.GetHue, Sat and Brightness don't work well.

History

  • 5 June, 2007. 1.6 - Solved Repaint, ChangingSize and excessive CPU consumption. Added KeepPress and IsPress functionality.
  • 16 May, 2007. 1.5 - Because I had to recode everything when I learned how to use Hue, Saturation and Brightness.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Juan Pablo G.C.
Software Developer
Spain Spain
Member
I'm Electronic Engineer, I did my end degree project at Astrophysical Institute and Tech Institute. I'm HP Procurve AIS and ASE ,Microsoft 3.5 MCTS
I live in Canary Islands ,developing customized solutions
 
I'm developing with WPF4, SL4 MVVM, MVC3 Razor and WP7 projects, more info at my websites. Improving with Android and IOS.
 
Websites:
MemCards
Mareinsula


Take a look to my blog Juan Pablo G.C.
Mareinsula

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionneed vb.net 3.5 versionmemberMasood1234516 Dec '12 - 22:03 
can any one convert it to vb.net, i do but have some conversion bugs that could not be resolved.
GeneralMy vote of 5mvpKanasz Robert27 Sep '12 - 8:35 
Very good project. Smile | :) You've got my 5
GeneralRe: My vote of 5memberJuan Pablo G.C.2 Oct '12 - 0:37 
Thanks a lot (a long time ago...), if one of these days I make money by my own, I will create the Office Modern UI for touch, meanwhile I setting ready my W8 apps.
Juan Pablo G.C.
Mareinsula Blog
 

SuggestionBUGS FIX (when Radius less than 2 and TextAlign not work)memberxitour7 May '12 - 20:57 
Two BUGS
1:Exception if Radius is less than 2
2:TextAlign not work
 
here is the right code
 
    public class RibbonMenuButton : Button
    {
        #region About Constructor
        public RibbonMenuButton()
        {
            this.SetStyle(ControlStyles.SupportsTransparentBackColor |
                          ControlStyles.UserPaint |
                          ControlStyles.ResizeRedraw |
                          ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.Opaque, false);
            this.FlatAppearance.BorderSize = 0;
            this.FlatStyle = FlatStyle.Flat;
            this.BackColor = Color.Transparent;
 
            timer1.Interval = 5;
            timer1.Tick += new EventHandler(timer1_Tick);
 
        }
        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            A0 = ColorBase.A;
            R0 = ColorBase.R;
            G0 = ColorBase.G;
            B0 = ColorBase.B;
            _colorStroke = _baseStroke;
 
            Rectangle r = new Rectangle(new Point(-1, -1), new Size(this.Width + _radius, this.Height + _radius));
            #region Transform to SmoothRectangle Region
            if (this.Size != null)
            {
                GraphicsPath pathregion = new GraphicsPath();
                DrawArc(r, pathregion);
                this.Region = new Region(pathregion);
            }
            #endregion
        }
        #endregion
 
        #region About Image Settings
        private e_imagelocation _imagelocation;
        public enum e_imagelocation
        {
            Top, Bottom, Left, Right, None
        }
        public e_imagelocation ImageLocation
        {
            get { return _imagelocation; }
            set { _imagelocation = value; this.Refresh(); }
        }
        private int _imageoffset;
        public int ImageOffset
        {
            get { return _imageoffset; }
            set { _imageoffset = value; }
        }
        private Point _maximagesize;
        public Point MaxImageSize
        {
            get { return _maximagesize; }
            set { _maximagesize = value; }
        }
 
        #endregion
 
        #region About Button Settings
        private e_showbase _showbase;
        private e_showbase _tempshowbase;
        public enum e_showbase
        {
            Yes, No
        }
        public e_showbase ShowBase
        {
            get { return _showbase; }
            set { _showbase = value; this.Refresh(); }
        }
        private int _radius = 6;
        public int Radius
        {
            get { return _radius; }
            set 
            {
                if (value > 0)
                {
                    _radius = value; 
                }else{
                    _radius = 2;
                }
                this.Refresh();
            }
        }
        private e_groupPos _grouppos;
        public enum e_groupPos
        {
            None, Left, Center, Right, Top, Bottom
        }
        public e_groupPos GroupPos
        {
            get { return _grouppos; }
            set { _grouppos = value; this.Refresh(); }
        }
 
        private e_arrow _arrow;
        public enum e_arrow
        {
            None, ToRight, ToDown
        }
        public e_arrow Arrow
        {
            get { return _arrow; }
            set { _arrow = value; this.Refresh(); }
        }
        private e_splitbutton _splitbutton;
        public enum e_splitbutton
        {
            No, Yes
        }
        public e_splitbutton SplitButton
        {
            get { return _splitbutton; }
            set { _splitbutton = value; this.Refresh(); }
        }
        private int _splitdistance = 0;
        public int SplitDistance
        {
            get { return _splitdistance; }
            set { _splitdistance = value; this.Refresh(); }
        }
        private string _title = "";
        public string Title
        {
            get { return _title; }
            set { _title = value; this.Refresh(); }
        }
        private bool _keeppress = false;
        public bool KeepPress
        {
            get { return _keeppress; }
            set { _keeppress = value; }
        }
        private bool _ispressed = false;
        public bool IsPressed
        {
            get { return _ispressed; }
            set { _ispressed = value; }
        }
 

        #endregion
 
        #region Menu Pos
        private Point _menupos = new Point(0, 0);
        public Point MenuPos
        {
            get { return _menupos; }
            set { _menupos = value; }
        }
        #endregion
 
        #region Colors
        private Color _baseColor = Color.FromArgb(186, 209, 240);
        private Color _onColor = Color.FromArgb(255, 214, 78);
        private Color _pressColor = Color.FromArgb(255, 128, 0);
 
        private Color _baseStroke = Color.FromArgb(152, 187, 213);
        private Color _onStroke = Color.FromArgb(196, 177, 118);
        private Color _pressStroke = Color.FromArgb(128, 64, 0);
        private Color _colorStroke = Color.FromArgb(255, 255, 255);
        private int A0, R0, G0, B0;
 
        public Color ColorBase
        {
            get { return _baseColor; }
            set
            {
                _baseColor = value;
                R0 = _baseColor.R;
                B0 = _baseColor.B;
                G0 = _baseColor.G;
                A0 = _baseColor.A;
                RibbonColor hsb = new RibbonColor(_baseColor);
                if (hsb.BC < 50)
                {
                    hsb.SetBrightness(60);
                }
                else
                {
                    hsb.SetBrightness(30);
                }
                if (_baseColor.A > 0)
                    _baseStroke = Color.FromArgb(100, hsb.GetColor());
                else
                    _baseStroke = Color.FromArgb(0, hsb.GetColor());
                this.Refresh();
            }
        }
        public Color ColorOn
        {
            get { return _onColor; }
            set
            {
                _onColor = value;
 
                RibbonColor hsb = new RibbonColor(_onColor);
                if (hsb.BC < 50)
                {
                    hsb.SetBrightness(60);
                }
                else
                {
                    hsb.SetBrightness(30);
                }
                if (_baseStroke.A > 0)
                    _onStroke = Color.FromArgb(100, hsb.GetColor());
                else
                    _onStroke = Color.FromArgb(0, hsb.GetColor());
                this.Refresh();
            }
        }
        public Color ColorPress
        {
            get { return _pressColor; }
            set
            {
                _pressColor = value;
 
                RibbonColor hsb = new RibbonColor(_pressColor);
                if (hsb.BC < 50)
                {
                    hsb.SetBrightness(60);
                }
                else
                {
                    hsb.SetBrightness(30);
                }
                if (_baseStroke.A > 0)
                    _pressStroke = Color.FromArgb(100, hsb.GetColor());
                else
                    _pressStroke = Color.FromArgb(0, hsb.GetColor());
                this.Refresh();
 
            }
        }
        public Color ColorBaseStroke
        {
            get { return _baseStroke; }
            set { _baseStroke = value; }
        }
        public Color ColorOnStroke
        {
            get { return _onStroke; }
            set { _onStroke = value; }
        }
        public Color ColorPressStroke
        {
            get { return _pressStroke; }
            set { _pressStroke = value; }
        }
        public Color GetColorIncreased(Color color, int h, int s, int b)
        {
            RibbonColor _color = new RibbonColor(color);
            int ss = _color.GetSaturation();
            float vc = b + _color.GetBrightness();
            float hc = h + _color.GetHue();
            float sc = s + ss;
 

            _color.VC = vc;
            _color.HC = hc;
            _color.SC = sc;
 
            return _color.GetColor();
 

        }
 
        public Color GetColor(int A, int R, int G, int B)
        {
            if (A + A0 > 255) { A = 255; } else { A = A + A0; }
            if (R + R0 > 255) { R = 255; } else { R = R + R0; }
            if (G + G0 > 255) { G = 255; } else { G = G + G0; }
            if (B + B0 > 255) { B = 255; } else { B = B + B0; }
 
            return Color.FromArgb(A, R, G, B);
        }
        #endregion
 
        protected override void OnPaint(PaintEventArgs pevent)
        {
            #region Variables & Conf
            Graphics g = pevent.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.High;
            Rectangle r = new Rectangle(new Point(-1, -1), new Size(this.Width + _radius, this.Height + _radius));
            #endregion
 
            #region Paint
            GraphicsPath path = new GraphicsPath();
            Rectangle rp = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
            DrawArc(rp, path);
            FillGradients(g, path);
            DrawImage(g);
            DrawString(g);
            DrawArrow(g);
            #endregion
        }
 
        protected override void OnResize(EventArgs e)
        {
            Rectangle r = new Rectangle(new Point(-1, -1), new Size(this.Width + _radius, this.Height + _radius));
            if (this.Size != null)
            {
                GraphicsPath pathregion = new GraphicsPath();
                DrawArc(r, pathregion);
                this.Region = new Region(pathregion);
            }
            base.OnResize(e);
        }
 
        #region Paint Methods
        public void FillGradients(Graphics gr, GraphicsPath pa)
        {
            int origin = this.Height / 3; int end = this.Height; int oe = (end - origin) / 2;
            LinearGradientBrush lgbrush; Rectangle rect;
            if (_showbase == e_showbase.Yes)
            {
                rect = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
                pa = new GraphicsPath();
                DrawArc(rect, pa);
                lgbrush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
 
                #region Main Gradient
                float[] pos = new float[4];
                pos[0] = 0.0F; pos[1] = 0.3F; pos[2] = 0.35F; pos[3] = 1.0F;
                Color[] colors = new Color[4];
                if (i_mode == 0)
                {
                    colors[0] = GetColor(0, 35, 24, 9);
                    colors[1] = GetColor(0, 13, 8, 3);
                    colors[2] = Color.FromArgb(A0, R0, G0, B0);
                    colors[3] = GetColor(0, 28, 29, 14);
                }
                else
                {
                    colors[0] = GetColor(0, 0, 50, 100);
                    colors[1] = GetColor(0, 0, 0, 30);
                    colors[2] = Color.FromArgb(A0, R0, G0, B0);
                    colors[3] = GetColor(0, 0, 50, 100);
                }
                ColorBlend mix = new ColorBlend();
                mix.Colors = colors;
                mix.Positions = pos;
                lgbrush.InterpolationColors = mix;
                gr.FillPath(lgbrush, pa);
                #endregion
 
                #region Fill Band
                rect = new Rectangle(new Point(0, 0), new Size(this.Width, this.Height / 3));
                pa = new GraphicsPath(); int _rtemp = _radius; _radius = _rtemp - 1;
                DrawArc(rect, pa);
                if (A0 > 80)
                {
                    gr.FillPath(new SolidBrush(Color.FromArgb(60, 255, 255, 255)), pa);
                }
                _radius = _rtemp;
                #endregion
 
                #region SplitFill
                if (_splitbutton == e_splitbutton.Yes & mouse)
                {
                    FillSplit(gr);
                }
                #endregion
 
                #region Shadow
                if (i_mode == 2)
                {
                    rect = new Rectangle(1, 1, this.Width - 2, this.Height);
                    pa = new GraphicsPath();
                    DrawShadow(rect, pa);
                    gr.DrawPath(new Pen(Color.FromArgb(50, 20, 20, 20), 2.0F), pa);
 
                }
                else
                {
                    rect = new Rectangle(1, 1, this.Width - 2, this.Height - 1);
                    pa = new GraphicsPath();
                    DrawShadow(rect, pa);
                    if (A0 > 80)
                    {
                        gr.DrawPath(new Pen(Color.FromArgb(100, 250, 250, 250), 3.0F), pa);
                    }
                }
                #endregion
 
                #region SplitLine
 
                if (_splitbutton == e_splitbutton.Yes)
                {
                    if (_imagelocation == e_imagelocation.Top)
                    {
                        switch (i_mode)
                        {
                            case 1:
                                gr.DrawLine(new Pen(_onStroke), new Point(1, this.Height - _splitdistance), new Point(this.Width - 1, this.Height - _splitdistance));
                                break;
                            case 2:
                                gr.DrawLine(new Pen(_pressStroke), new Point(1, this.Height - _splitdistance), new Point(this.Width - 1, this.Height - _splitdistance));
                                break;
                            default:
                                break;
                        }
                    }
                    else if (_imagelocation == e_imagelocation.Left)
                    {
                        switch (i_mode)
                        {
                            case 1:
                                gr.DrawLine(new Pen(_onStroke), new Point(this.Width - _splitdistance, 0), new Point(this.Width - _splitdistance, this.Height));
                                break;
                            case 2:
                                gr.DrawLine(new Pen(_pressStroke), new Point(this.Width - _splitdistance, 0), new Point(this.Width - _splitdistance, this.Height));
                                break;
                            default:
                                break;
                        }
                    }
 
                }
                #endregion
 
                rect = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
                pa = new GraphicsPath();
                DrawArc(rect, pa);
                gr.DrawPath(new Pen(_colorStroke, 0.9F), pa);
 
                pa.Dispose(); lgbrush.Dispose();
 

            }
        }
 
        int offsetx = 0, offsety = 0, imageheight = 0, imagewidth = 0;
        public void DrawImage(Graphics gr)
        {
            if (this.Image != null)
            {
                offsety = _imageoffset; offsetx = _imageoffset;
                if (_imagelocation == e_imagelocation.Left | _imagelocation == e_imagelocation.Right)
                {
                    imageheight = this.Height - offsety * 2;
                    if (imageheight > _maximagesize.Y & _maximagesize.Y != 0)
                    { imageheight = _maximagesize.Y; }
                    imagewidth = (int)((Convert.ToDouble(imageheight) / this.Image.Height) * this.Image.Width);
                }
                else if (_imagelocation == e_imagelocation.Top | _imagelocation == e_imagelocation.Bottom)
                {
                    imagewidth = this.Width - offsetx * 2;
                    if (imagewidth > _maximagesize.X & _maximagesize.X != 0)
                    { imagewidth = _maximagesize.X; }
                    imageheight = (int)((Convert.ToDouble(imagewidth) / this.Image.Width) * this.Image.Height);
 
                }
                switch (_imagelocation)
                {
                    case e_imagelocation.Left:
                        gr.DrawImage(this.Image, new Rectangle(offsetx, offsety, imagewidth, imageheight));
                        break;
                    case e_imagelocation.Right:
                        gr.DrawImage(this.Image, new Rectangle(this.Width - imagewidth - offsetx, offsety, imagewidth, imageheight));
                        break;
                    case e_imagelocation.Top:
                        offsetx = this.Width / 2 - imagewidth / 2;
                        gr.DrawImage(this.Image, new Rectangle(offsetx, offsety, imagewidth, imageheight));
                        break;
                    case e_imagelocation.Bottom:
                        gr.DrawImage(this.Image, new Rectangle(offsetx, this.Height - imageheight - offsety, imagewidth, imageheight));
                        break;
                    default:
                        break;
                }
            }
        }
 
        public void DrawString(Graphics gr)
        {
            if (this.Text != "")
            {
                int textwidth = (int)gr.MeasureString(this.Text, this.Font).Width;
                int textheight = (int)gr.MeasureString(this.Text, this.Font).Height;
 
                int extraoffset = 0;
                Font fontb = new Font(this.Font, FontStyle.Bold);
                if (_title != "")
                {
                    extraoffset = textheight / 2;
                }
 
                string s1 = this.Text; string s2 = "";
                int jump = this.Text.IndexOf("\\n");
 
                if (jump != -1)
                {
                    s2 = s1.Substring(jump + 3); s1 = s1.Substring(0, jump);
                }
 
                #region Calc Color Brightness
                RibbonColor __color = new RibbonColor(Color.FromArgb(R0, G0, B0));
                RibbonColor forecolor = new RibbonColor(this.ForeColor);
                Color _forecolor;
 
                if (__color.GetBrightness() > 50)
                {
                    forecolor.BC = 1;
                    forecolor.SC = 80;
                }
                else
                {
                    forecolor.BC = 99;
                    forecolor.SC = 20;
                }
                _forecolor = forecolor.GetColor();
                #endregion
 
                if (this.Image == null)
                {
                    switch (this.TextAlign)
                    { 
                        case ContentAlignment.BottomCenter:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, this.Height - textheight - 1));
                            break;
                        case ContentAlignment.BottomLeft:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(1, this.Height - textheight - 1));
                            break;
                        case ContentAlignment.BottomRight:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width - textwidth - 1, this.Height - textheight - 1));
                            break;
                        case ContentAlignment.MiddleCenter:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, this.Height / 2 - textheight / 2 - 1));
                            break;
                        case ContentAlignment.MiddleLeft:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(1, this.Height / 2 - textheight / 2 - 1));
                            break;
                        case ContentAlignment.MiddleRight:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width - textwidth - 1, this.Height / 2 - textheight / 2 - 1));
                            break;
                        case ContentAlignment.TopCenter:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, 1));
                            break;
                        case ContentAlignment.TopLeft:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(1, 1));
                            break;
                        case ContentAlignment.TopRight:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width - textwidth - 1, 1));
                            break;
                        default:
                            break;
                    }                
                }else{
                    switch (_imagelocation)
                    {
                        case e_imagelocation.Left:
                            if (this.Title != "")
                            {
                                gr.DrawString(this.Title, fontb, new SolidBrush(_forecolor), new PointF(offsetx + imagewidth + 4, this.Font.Size / 2));
                                gr.DrawString(s1, this.Font, new SolidBrush(_forecolor), new PointF(offsetx + imagewidth + 4, 2 * this.Font.Size + 1));
                                gr.DrawString(s2, this.Font, new SolidBrush(_forecolor), new PointF(offsetx + imagewidth + 4, 3 * this.Font.Size + 4));
                            }
                            else
                            {
                                gr.DrawString(s1, this.Font, new SolidBrush(_forecolor), new PointF(offsetx + imagewidth + 4, this.Height / 2 - this.Font.Size + 1));
                            }
 
                            break;
                        case e_imagelocation.Right:
                            gr.DrawString(this.Title, fontb, new SolidBrush(_forecolor), new PointF(offsetx, this.Height / 2 - this.Font.Size + 1 - extraoffset));
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(offsetx, extraoffset + this.Height / 2 - this.Font.Size + 1));
                            break;
                        case e_imagelocation.Top:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, offsety + imageheight));
                            break;
                        case e_imagelocation.Bottom:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, this.Height - imageheight - textheight - 1));
                            break;
                        case e_imagelocation.None:
                            gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, this.Height / 2 - textheight / 2 - 1));
                            break;
                        default:
                            break;
                    }
                }
                fontb.Dispose();
 
            }
        }
 
        public void DrawArc(Rectangle re, GraphicsPath pa)
        {
            int _radiusX0Y0 = _radius, _radiusXFY0 = _radius, _radiusX0YF = _radius, _radiusXFYF = _radius;
            switch (_grouppos)
            {
                case e_groupPos.Left:
                    _radiusXFY0 = 1; _radiusXFYF = 1;
                    break;
                case e_groupPos.Center:
                    _radiusX0Y0 = 1; _radiusX0YF = 1; _radiusXFY0 = 1; _radiusXFYF = 1;
                    break;
                case e_groupPos.Right:
                    _radiusX0Y0 = 1; _radiusX0YF = 1;
                    break;
                case e_groupPos.Top:
                    _radiusX0YF = 1; _radiusXFYF = 1;
                    break;
                case e_groupPos.Bottom:
                    _radiusX0Y0 = 1; _radiusXFY0 = 1;
                    break;
            }
            pa.AddArc(re.X, re.Y, _radiusX0Y0, _radiusX0Y0, 180, 90);
            pa.AddArc(re.Width - _radiusXFY0, re.Y, _radiusXFY0, _radiusXFY0, 270, 90);
            pa.AddArc(re.Width - _radiusXFYF, re.Height - _radiusXFYF, _radiusXFYF, _radiusXFYF, 0, 90);
            pa.AddArc(re.X, re.Height - _radiusX0YF, _radiusX0YF, _radiusX0YF, 90, 90);
            pa.CloseFigure();
 
        }
 
        public void DrawShadow(Rectangle re, GraphicsPath pa)
        {
            int _radiusX0Y0 = _radius, _radiusXFY0 = _radius, _radiusX0YF = _radius, _radiusXFYF = _radius;
            switch (_grouppos)
            {
                case e_groupPos.Left:
                    _radiusXFY0 = 1; _radiusXFYF = 1;
                    break;
                case e_groupPos.Center:
                    _radiusX0Y0 = 1; _radiusX0YF = 1; _radiusXFY0 = 1; _radiusXFYF = 1;
                    break;
                case e_groupPos.Right:
                    _radiusX0Y0 = 1; _radiusX0YF = 1;
                    break;
                case e_groupPos.Top:
                    _radiusX0YF = 1; _radiusXFYF = 1;
                    break;
                case e_groupPos.Bottom:
                    _radiusX0Y0 = 1; _radiusXFY0 = 1;
                    break;
            }
            pa.AddArc(re.X, re.Y, _radiusX0Y0, _radiusX0Y0, 180, 90);
            pa.AddArc(re.Width - _radiusXFY0, re.Y, _radiusXFY0, _radiusXFY0, 270, 90);
            pa.AddArc(re.Width - _radiusXFYF, re.Height - _radiusXFYF, _radiusXFYF, _radiusXFYF, 0, 90);
            pa.AddArc(re.X, re.Height - _radiusX0YF, _radiusX0YF, _radiusX0YF, 90, 90);
            pa.CloseFigure();
 
        }
 
        public void DrawArrow(Graphics gr)
        {
            int _size = 1;
 
            RibbonColor __color = new RibbonColor(Color.FromArgb(R0, G0, B0));
            RibbonColor forecolor = new RibbonColor(this.ForeColor);
            Color _forecolor;
 
            if (__color.GetBrightness() > 50)
            {
                forecolor.BC = 1;
                forecolor.SC = 80;
            }
            else
            {
                forecolor.BC = 99;
                forecolor.SC = 20;
            }
            _forecolor = forecolor.GetColor();
 
            switch (_arrow)
            {
                case e_arrow.ToDown:
                    if (_imagelocation == e_imagelocation.Left)
                    {
                        Point[] points = new Point[3];
                        points[0] = new Point(this.Width - 8 * _size - _imageoffset, this.Height / 2 - _size / 2);
                        points[1] = new Point(this.Width - 2 * _size - _imageoffset, this.Height / 2 - _size / 2);
                        points[2] = new Point(this.Width - 5 * _size - _imageoffset, this.Height / 2 + _size * 2);
                        gr.FillPolygon(new SolidBrush(_forecolor), points);
                    }
                    else if (_imagelocation == e_imagelocation.Top)
                    {
                        Point[] points = new Point[3];
                        points[0] = new Point(this.Width / 2 + 8 * _size - _imageoffset, this.Height - _imageoffset - 5 * _size);
                        points[1] = new Point(this.Width / 2 + 2 * _size - _imageoffset, this.Height - _imageoffset - 5 * _size);
                        points[2] = new Point(this.Width / 2 + 5 * _size - _imageoffset, this.Height - _imageoffset - 2 * _size);
                        gr.FillPolygon(new SolidBrush(_forecolor), points);
                    }
                    break;
                case e_arrow.ToRight:
                    if (_imagelocation == e_imagelocation.Left)
                    {
                        int arrowxpos = this.Width - _splitdistance + 2 * _imageoffset;
                        Point[] points = new Point[3];
                        points[0] = new Point(arrowxpos + 4, this.Height / 2 - 4 * _size);
                        points[1] = new Point(arrowxpos + 8, this.Height / 2);
                        points[2] = new Point(arrowxpos + 4, this.Height / 2 + 4 * _size);
                        gr.FillPolygon(new SolidBrush(_forecolor), points);
                    }
                    break;
                default:
                    break;
            }
 
        }
 
        public void FillSplit(Graphics gr)
        {
            Color _tranp = Color.FromArgb(200, 255, 255, 255);
            int x1 = this.Width - _splitdistance; int x2 = 0;
            int y1 = this.Height - _splitdistance; int y2 = 0;
            SolidBrush btransp = new SolidBrush(_tranp);
            #region Horizontal
            if (_imagelocation == e_imagelocation.Left)
            {
                if (xmouse < this.Width - _splitdistance & mouse) //Small button
                {
                    Rectangle _r = new Rectangle(x1 + 1, 1, this.Width - 2, this.Height - 1);
                    GraphicsPath p = new GraphicsPath();
                    int _rtemp = _radius; _radius = 4;
                    DrawArc(_r, p);
                    _radius = _rtemp;
                    gr.FillPath(btransp, p);
 
                }
                else if (mouse) //Big Button
                {
                    Rectangle _r = new Rectangle(x2 + 1, 1, this.Width - _splitdistance - 1, this.Height - 1);
                    GraphicsPath p = new GraphicsPath();
                    int _rtemp = _radius; _radius = 4;
                    DrawArc(_r, p);
                    _radius = _rtemp;
                    gr.FillPath(btransp, p);
                }
 
            }
            #endregion
 
            #region Vertical
            else if (_imagelocation == e_imagelocation.Top)
            {
                if (ymouse < this.Height - _splitdistance & mouse) //Small button
                {
                    Rectangle _r = new Rectangle(1, y1 + 1, this.Width - 1, this.Height - 1);
                    GraphicsPath p = new GraphicsPath();
                    int _rtemp = _radius; _radius = 4;
                    DrawArc(_r, p);
                    _radius = _rtemp;
                    gr.FillPath(btransp, p);
                }
                else if (mouse) //Big Button
                {
                    Rectangle _r = new Rectangle(1, y2 + 1, this.Width - 1, this.Height - _splitdistance - 1);
                    GraphicsPath p = new GraphicsPath();
                    int _rtemp = _radius; _radius = 4;
                    DrawArc(_r, p);
                    _radius = _rtemp;
                    gr.FillPath(btransp, p);
                }
            }
            #endregion
            btransp.Dispose();
 
        }
        #endregion
 
        #region About Fading
        private Timer timer1 = new Timer();
        int i_factor = 35;
        public int FadingSpeed
        {
            get { return i_factor; }
            set
            {
                if (value > -1)
                {
                    i_factor = value;
                }
            }
        }
        int i_fR = 1; int i_fG = 1; int i_fB = 1; int i_fA = 1;
        void timer1_Tick(object sender, EventArgs e)
        {
            #region Entering
            if (i_mode == 1)
            {
                if (System.Math.Abs(ColorOn.R - R0) > i_factor)
                { i_fR = i_factor; }
                else { i_fR = 1; }
                if (System.Math.Abs(ColorOn.G - G0) > i_factor)
                { i_fG = i_factor; }
                else { i_fG = 1; }
                if (System.Math.Abs(ColorOn.B - B0) > i_factor)
                { i_fB = i_factor; }
                else { i_fB = 1; }
 
                if (ColorOn.R < R0)
                {
                    R0 -= i_fR;
                }
                else if (ColorOn.R > R0)
                {
                    R0 += i_fR;
                }
 
                if (ColorOn.G < G0)
                {
                    G0 -= i_fG;
                }
                else if (ColorOn.G > G0)
                {
                    G0 += i_fG;
                }
 
                if (ColorOn.B < B0)
                {
                    B0 -= i_fB;
                }
                else if (ColorOn.B > B0)
                {
                    B0 += i_fB;
                }
 
                if (ColorOn == Color.FromArgb(R0, G0, B0))
                {
                    timer1.Stop();
                }
                else
                {
                    this.Refresh();
                }
            }
            #endregion
 
            #region Leaving
            if (i_mode == 0)
            {
 
                if (System.Math.Abs(ColorBase.R - R0) < i_factor)
                { i_fR = 1; }
                else { i_fR = i_factor; }
                if (System.Math.Abs(ColorBase.G - G0) < i_factor)
                { i_fG = 1; }
                else { i_fG = i_factor; }
                if (System.Math.Abs(ColorBase.B - B0) < i_factor)
                { i_fB = 1; }
                else { i_fB = i_factor; }
                if (System.Math.Abs(ColorBase.A - A0) < i_factor)
                { i_fA = 1; }
                else { i_fA = i_factor; }
 
                if (ColorBase.R < R0)
                {
                    R0 -= i_fR;
                }
                else if (ColorBase.R > R0)
                {
                    R0 += i_fR;
                }
                if (ColorBase.G < G0)
                {
                    G0 -= i_fG;
                }
                else if (ColorBase.G > G0)
                {
                    G0 += i_fG;
                }
                if (ColorBase.B < B0)
                {
                    B0 -= i_fB;
                }
                else if (ColorBase.B > B0)
                {
                    B0 += i_fB;
                }
                if (ColorBase.A < A0)
                {
                    A0 -= i_fA;
                }
                else if (ColorBase.A > A0)
                {
                    A0 += i_fA;
                }
                if (ColorBase == Color.FromArgb(A0, R0, G0, B0))
                {
                    timer1.Stop();
 
                }
                else
                {
 
                    this.Refresh();
                }
 
            }
            #endregion
 
            this.Refresh();
        }
        #endregion
 
        #region Mouse Events
        int i_mode = 0; //0 Entering, 1 Out,2 Press
        int xmouse = 0, ymouse = 0; bool mouse = false;
 
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            _colorStroke = ColorOnStroke;
            _tempshowbase = _showbase;
            _showbase = e_showbase.Yes;
            i_mode = 1;
            xmouse = PointToClient(Cursor.Position).X;
            mouse = true;
            A0 = 200;
            if (i_factor == 0)
            {
                R0 = _onColor.R; G0 = _onColor.G; B0 = _onColor.B;
            }
            timer1.Start();
        }
 
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            UpdateLeave();
        }
 
        public void UpdateLeave()
        {
            if (_keeppress == false | (_keeppress == true & _ispressed == false))
            {
                _colorStroke = ColorBaseStroke;
                _showbase = _tempshowbase;
                i_mode = 0;
                mouse = false;
                if (i_factor == 0)
                {
                    R0 = _baseColor.R; G0 = _baseColor.G; B0 = _baseColor.B;
                    this.Refresh();
                }
                else
                {
                    timer1.Stop();
                    timer1.Start();
                }
            }
        }
 
        protected override void OnMouseDown(MouseEventArgs mevent)
        {
            base.OnMouseDown(mevent);
            R0 = ColorPress.R; G0 = ColorPress.G; B0 = ColorPress.B;
            _colorStroke = ColorPressStroke;
            _showbase = e_showbase.Yes;
            i_mode = 2;
            xmouse = PointToClient(Cursor.Position).X;
            ymouse = PointToClient(Cursor.Position).Y;
            mouse = true;
        }
 
        protected override void OnMouseUp(MouseEventArgs mevent)
        {
            R0 = ColorOn.R; G0 = ColorOn.G; B0 = ColorOn.B;
            _colorStroke = ColorOnStroke;
            _showbase = e_showbase.Yes;
            i_mode = 1;
            mouse = true;
 
            #region ClickSplit
            if (_imagelocation == e_imagelocation.Left & xmouse > this.Width - _splitdistance & _splitbutton == e_splitbutton.Yes)
            {
                if (_arrow == e_arrow.ToDown)
                {
                    if (this.ContextMenuStrip != null)
                        this.ContextMenuStrip.Opacity = 1.0;
                    this.ContextMenuStrip.Show(this, 0, this.Height);
 
                }
                else if (_arrow == e_arrow.ToRight)
                {
                    if (this.ContextMenuStrip != null)
                    {
                        ContextMenuStrip menu = this.ContextMenuStrip;
                        this.ContextMenuStrip.Opacity = 1.0;
                        if (this.MenuPos.Y == 0)
                        {
                            this.ContextMenuStrip.Show(this, this.Width + 2, -this.Height);
                        }
                        else
                        {
                            this.ContextMenuStrip.Show(this, this.Width + 2, this.MenuPos.Y);
                        }
                    }
 
                }
            }
            else if (_imagelocation == e_imagelocation.Top & ymouse > this.Height - _splitdistance & _splitbutton == e_splitbutton.Yes)
            {
                if (_arrow == e_arrow.ToDown)
                {
                    if (this.ContextMenuStrip != null)
                        this.ContextMenuStrip.Show(this, 0, this.Height);
                }
            }
            #endregion
            else
            {
                base.OnMouseUp(mevent);
 
                #region Keep Press
                if (_keeppress)
                {
                    _ispressed = true;
 
                    try
                    {
                        foreach (Control _control in this.Parent.Controls)
                        {
                            if (typeof(RibbonMenuButton) == _control.GetType() & _control.Name != this.Name)
                            {
                                ((RibbonMenuButton)(_control))._ispressed = false;
                                ((RibbonMenuButton)(_control)).UpdateLeave();
                            }
                        }
                    }
                    catch { }
 

                }
                #endregion
 
            }
 

        }
 
        protected override void OnMouseMove(MouseEventArgs mevent)
        {
            if (mouse & this.SplitButton == e_splitbutton.Yes)
            {
                xmouse = PointToClient(Cursor.Position).X;
                ymouse = PointToClient(Cursor.Position).Y;
                this.Refresh();
            }
            base.OnMouseMove(mevent);
        }
 

        #endregion
    }
 
    public class RibbonColor
    {
 
        #region Constructors
        public RibbonColor(Color color)
        {
            rc = color.R;
            gc = color.G;
            bc = color.B;
            ac = color.A;
 
            HSV();
        }
 
        public RibbonColor(uint alpha, int hue, int saturation, int brightness)
        {
            hc = hue;
            sc = saturation;
            vc = brightness;
            ac = alpha;
 
            GetColor();
        }
        #endregion
 
        #region Alpha
        private uint ac = 0; //Alpha > -1
        public uint AC { get { return ac; } set { System.Math.Min(value, 255); } }
        #endregion
 
        #region RGB
        private int rc = 0, gc = 0, bc = 0; //RGB Components > -1 

        public int RC { get { return rc; } set { rc = System.Math.Min(value, 255); } }
        public int GC { get { return gc; } set { gc = System.Math.Min(value, 255); } }
        public int BC { get { return bc; } set { bc = System.Math.Min(value, 255); } }
 

        public Color GetColor()
        {
 
            int conv;
            double hue, sat, val;
            int basis;
 
            hue = (float)hc / 100.0f;
            sat = (float)sc / 100.0f;
            val = (float)vc / 100.0f;
 
            if ((float)sc == 0) // Gray Colors
            {
                conv = (int)(255.0f * val);
                rc = gc = bc = conv;
                return Color.FromArgb((int)rc, (int)gc, (int)bc);
            }
 
            basis = (int)(255.0f * (1.0 - sat) * val);
 
            switch ((int)((float)hc / 60.0f))
            {
                case 0:
                    rc = (int)(255.0f * val);
                    gc = (int)((255.0f * val - basis) * (hc / 60.0f) + basis);
                    bc = (int)basis;
                    break;
 
                case 1:
                    rc = (int)((255.0f * val - basis) * (1.0f - ((hc % 60) / 60.0f)) + basis);
                    gc = (int)(255.0f * val);
                    bc = (int)basis;
                    break;
 
                case 2:
                    rc = (int)basis;
                    gc = (int)(255.0f * val);
                    bc = (int)((255.0f * val - basis) * ((hc % 60) / 60.0f) + basis);
                    break;
 
                case 3:
                    rc = (int)basis;
                    gc = (int)((255.0f * val - basis) * (1.0f - ((hc % 60) / 60.0f)) + basis);
                    bc = (int)(255.0f * val);
                    break;
 
                case 4:
                    rc = (int)((255.0f * val - basis) * ((hc % 60) / 60.0f) + basis);
                    gc = (int)basis;
                    bc = (int)(255.0f * val);
                    break;
 
                case 5:
                    rc = (int)(255.0f * val);
                    gc = (int)basis;
                    bc = (int)((255.0f * val - basis) * (1.0f - ((hc % 60) / 60.0f)) + basis);
                    break;
            }
            return Color.FromArgb((int)ac, (int)rc, (int)gc, (int)bc);
 
        }
 
        public uint GetRed()
        {
            return GetColor().R;
        }
 
        public uint GetGreen()
        {
            return GetColor().G;
        }
 
        public uint GetBlue()
        {
            return GetColor().B;
        }
 
        #endregion
 
        #region HSV
 
        private int hc = 0, sc = 0, vc = 0;
 
        public float HC { get { return hc; } set { hc = (int)System.Math.Min(value, 359); hc = (int)System.Math.Max(hc, 0); } }
        public float SC { get { return sc; } set { sc = (int)System.Math.Min(value, 100); sc = (int)System.Math.Max(sc, 0); } }
        public float VC { get { return vc; } set { vc = (int)System.Math.Min(value, 100); vc = (int)System.Math.Max(vc, 0); } }
 
        public enum C { Red, Green, Blue, None }
        private int maxval = 0, minval = 0;
        private C CompMax, CompMin;
 
        private void HSV()
        {
            hc = this.GetHue();
            sc = this.GetSaturation();
            vc = this.GetBrightness();
        }
 
        public void CMax()
        {
            if (rc > gc)
            {
                if (rc < bc) { maxval = bc; CompMax = C.Blue; }
                else { maxval = rc; CompMax = C.Red; }
            }
            else
            {
                if (gc < bc) { maxval = bc; CompMax = C.Blue; }
                else { maxval = gc; CompMax = C.Green; }
            }
        }
 
        public void CMin()
        {
            if (rc < gc)
            {
                if (rc > bc) { minval = bc; CompMin = C.Blue; }
                else { minval = rc; CompMin = C.Red; }
            }
            else
            {
                if (gc > bc) { minval = bc; CompMin = C.Blue; }
                else { minval = gc; CompMin = C.Green; }
            }
 
        }
 
        public int GetBrightness()  //Brightness is from 0 to 100
        {
            CMax(); return 100 * maxval / 255;
        }
 
        public int GetSaturation() //Saturation from 0 to 100
        {
            CMax(); CMin();
            if (CompMax == C.None)
                return 0;
            else if (maxval != minval)
            {
                Decimal d_sat = Decimal.Divide(minval, maxval);
                d_sat = Decimal.Subtract(1, d_sat);
                d_sat = Decimal.Multiply(d_sat, 100);
                return Convert.ToUInt16(d_sat);
            }
            else
            {
                return 0;
            }
 
        }
 
        public int GetHue()
        {
            CMax(); CMin();
 
            if (maxval == minval)
            {
                return 0;
            }
            else if (CompMax == C.Red)
            {
                if (gc >= bc)
                {
                    Decimal d1 = Decimal.Divide((gc - bc), (maxval - minval));
                    return Convert.ToUInt16(60 * d1);
                }
                else
                {
                    Decimal d1 = Decimal.Divide((bc - gc), (maxval - minval));
                    d1 = 60 * d1;
                    return Convert.ToUInt16(360 - d1);
                }
            }
            else if (CompMax == C.Green)
            {
                if (bc >= rc)
                {
                    Decimal d1 = Decimal.Divide((bc - rc), (maxval - minval));
                    d1 = 60 * d1;
                    return Convert.ToUInt16(120 + d1);
                }
                else
                {
                    Decimal d1 = Decimal.Divide((rc - bc), (maxval - minval));
                    d1 = 60 * d1;
                    return Convert.ToUInt16(120 - d1);
                }
 

            }
            else if (CompMax == C.Blue)
            {
                if (rc >= gc)
                {
                    Decimal d1 = Decimal.Divide((rc - gc), (maxval - minval));
                    d1 = 60 * d1;
                    return Convert.ToUInt16(240 + d1);
                }
                else
                {
                    Decimal d1 = Decimal.Divide((gc - rc), (maxval - minval));
                    d1 = 60 * d1;
                    return Convert.ToUInt16(240 - d1);
                }
            }
            else
            {
                return 0;
            }
        }  //Hue from 0 to 100

        #endregion
 
        #region Methods
 
        public bool IsDark()
        {
            if (BC > 50)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
 
        public void IncreaseBrightness(int val)
        {
            this.VC = this.VC + val;
 
        }
 
        public void SetBrightness(int val)
        {
            this.VC = val;
 
        }
 
        public void IncreaseHue(int val)
        {
            this.HC = this.HC + val;
 
        }
 
        public void SetHue(int val)
        {
            this.HC = val;
 
        }
 
        public void IncreaseSaturation(int val)
        {
            this.SC = this.SC + val;
 
        }
 
        public void SetSaturation(int val)
        {
            this.SC = val;
 
        }
 
        public Color IncreaseHSV(int h, int s, int b)
        {
            this.HC = this.HC + h;
            this.SC = this.SC + s;
            this.VC = this.VC + b;
            return GetColor();
        }
 
        #endregion
 
    }

GeneralRe: BUGS FIX (when Radius less than 2 and TextAlign not work)memberJuan Pablo G.C.8 May '12 - 21:31 
It is incredible that these days from 2007 my code continues making being useful a lot. When I finish my last project I will review all the messages to create another version. Thank you all.
Juan Pablo G.C.
Mareinsula Blog
 

GeneralMy vote of 5memberDon_Hard5 Jun '11 - 3:05 
hermoso, me viene barvaro y como recien empieso no puedo hacerlo yo mismo gracias.
GeneralMy vote of 5memberhadre11 May '11 - 20:36 
Incre�ble de nuevo !!
GeneralMy vote of 5memberAnirudha_baba28 Jan '11 - 2:43 
Great...
GeneralDownload - Refactored w/ Lot's of Bug fixes and Performance ImprovmentsmemberTom Guinther26 Nov '10 - 6:25 
It is really sad that this control is rated so highly (perception rules) as it was very poorly written and is barely usable within a real application. Still, the overall drawing concepts were reasonable so I decided to spend 4 hours or so trying to make it more reasonable. After the 4 hours I think most of the common problems are resolved but I stopped once the basic functionality was no longer complete junk. All in all, this control could have been written correctly in about 4 hours so I don't think there is any point in wasting more time on it, but if I fix any other bugs I will update my solution (but not this post.)
 
The re-factoring will break existing code but most of the changes are relatively easy to fix.
The solution below is VS 2010. You can obviouly jack the code into the existing solution...but I leave that up to you.
 
https://sites.google.com/site/atomicdog63/home/RibbonMenuControlTest.zip?attredirects=0&d=1[^]
Tom Guinther
http://mothership.blogdns.net/cs/blog

GeneralRibbon buttonmemberViktor_BVP15 Nov '10 - 3:02 
Fine, Excellent, Indispensable. Thank You.
GeneralMy vote of 5memberViktor_BVP15 Nov '10 - 3:00 
Fine, Excellent, Indispensable. Thank You.
GeneralMy vote of 5memberHeaven20203 Nov '10 - 10:12 
excellent code
GeneralBrilliant :)memberAnt210010 Sep '10 - 12:39 
I really love this, thanks!
Check out my unit conversion software for Windows!

GeneralMy vote of 5memberMember 32887887 Aug '10 - 8:42 
Great..
GeneralMy vote of 5memberpebeeye28 Jul '10 - 17:23 
how excellent it's
i do like it!
GeneralText Aligned Don't workmembersepel5 Apr '09 - 21:50 
Hi.
When I set TextAlign to right or left It hasn't any effect.
 
sepel

GeneralExtremely Awesome Workmember Xmen 9 Mar '09 - 23:54 
Thanks for the damn nice article...5 Wink | ;)
 
TVMU^P[[IGIOQHG^JSH`A#@`RFJ\c^JPL>;"[,*/|+&WLEZGc`AFXc!L
%^]*IRXD#@GKCQ`R\^SF_WcHbORY87֦ʻ6ϣN8ȤBcRAV\Z^&SU~%CSWQ@#2
W_AD`EPABIKRDFVS)EVLQK)JKSQXUFYK[M`UKs*$GwU#(QDXBER@CBN%
Rs0~53%eYrd8mt^7Z6]iTF+(EWfJ9zaK-i’TV.C\y<pŠjxsg-b$f4ia>
--------------------------------------------------------
128 bit encrypted signature, crack if you can

QuestionWhat about licence thenmemberBastianPL23 Jan '09 - 3:28 
Hi there is it possible to use this class in commercial project withour any restrictions ?
QuestionGreat! And how about glowing one?memberHugo Tomas23 Dec '08 - 23:36 
Hi,
Great button! And how about glowing one? Like this:
 
http://www.codeproject.com/KB/GDI-plus/glowbutton.aspx[^]
 
Hugo Tomas

GeneralColors, ForeColormemberInfinity99922 Dec '08 - 2:37 
When I set ForeColor as Gray or tints of Gray Button text color become red or tints of red.
Help me please... Why gray became red?
GeneralThank you so much for your amazing posts - I have few questionsmemberWael Salman19 Dec '08 - 1:35 
Hi,
 
Thank you again for your work , it is amazing Smile | :)
 
I will be so happy and thankful if you answer me about my questions.
 
I am not so proffesional in C# .Net , but I am trying to dive deeply into this amazing language, I am software engineer since 8 years , but working with C++, emebdded .
 
1. How can you create dll and then add it to the ToolBox in order to have new tools that we can drag it to our controls??
 
2. How can you create specific ICon Image and locate it in its place in teh control??
 
3. whic resources, articles, researches did you use in order to study all of this stuff??
 

I will be thankfull i fyou can provice me with all the needed in order to start develp things like this??
 
thank you
Wael
 
Wael...Where Imagination Is Touched...

GeneralSome properties did not work :( [modified]memberTrung D8 Aug '08 - 20:49 
Hi Mr. Pablo,
First, I have to say that your library is pretty cool Rose | [Rose] . I hope that you will keep it going better Shucks | :-> .
 
But, I do not know how to make Mnemonic to the button.
Example when I type 'E&xit' the button's text display is still 'E&xit' when it has to be 'Exit' with underline at 'x' character.
 
I cannot make tab order among those buttons.
 
I cannot create the AcceptButton or CancelButton on my form.
 
I was thrown an exception when set the Radius <= 1 and i had to go to the *.designer.cs to edit.
 
The Text Alignment does not work too Smile | :) .
 
And when i run my Test application, i pressed on the button and there were 3 sides of the bounding rectangle work. I think if 4 sides work together, your button will be more cooler Big Grin | :-D
 
But did I do something wrong? Because your ribbon button extends the Button and so those properties above have to work.
 
I hope to see some good news from you. Have a nice day Big Grin | :-D .
 
modified on Saturday, August 9, 2008 3:00 AM

GeneralRe: Fix the bugsmemberxitour7 May '12 - 20:52 
public class RibbonMenuButton : Button
{
#region About Constructor
public RibbonMenuButton()
{
this.SetStyle(ControlStyles.SupportsTransparentBackColor |
ControlStyles.UserPaint |
ControlStyles.ResizeRedraw |
ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.Opaque, false);
this.FlatAppearance.BorderSize = 0;
this.FlatStyle = FlatStyle.Flat;
this.BackColor = Color.Transparent;
 
timer1.Interval = 5;
timer1.Tick += new EventHandler(timer1_Tick);
 
}
protected override void OnCreateControl()
{
base.OnCreateControl();
A0 = ColorBase.A;
R0 = ColorBase.R;
G0 = ColorBase.G;
B0 = ColorBase.B;
_colorStroke = _baseStroke;
 
Rectangle r = new Rectangle(new Point(-1, -1), new Size(this.Width + _radius, this.Height + _radius));
#region Transform to SmoothRectangle Region
if (this.Size != null)
{
GraphicsPath pathregion = new GraphicsPath();
DrawArc(r, pathregion);
this.Region = new Region(pathregion);
}
#endregion
}
#endregion
 
#region About Image Settings
private e_imagelocation _imagelocation;
public enum e_imagelocation
{
Top, Bottom, Left, Right, None
}
public e_imagelocation ImageLocation
{
get { return _imagelocation; }
set { _imagelocation = value; this.Refresh(); }
}
private int _imageoffset;
public int ImageOffset
{
get { return _imageoffset; }
set { _imageoffset = value; }
}
private Point _maximagesize;
public Point MaxImageSize
{
get { return _maximagesize; }
set { _maximagesize = value; }
}
 
#endregion
 
#region About Button Settings
private e_showbase _showbase;
private e_showbase _tempshowbase;
public enum e_showbase
{
Yes, No
}
public e_showbase ShowBase
{
get { return _showbase; }
set { _showbase = value; this.Refresh(); }
}
private int _radius = 6;
public int Radius
{
get { return _radius; }
set
{
if (value > 0)
{
_radius = value;
}else{
_radius = 2;
}
this.Refresh();
}
}
private e_groupPos _grouppos;
public enum e_groupPos
{
None, Left, Center, Right, Top, Bottom
}
public e_groupPos GroupPos
{
get { return _grouppos; }
set { _grouppos = value; this.Refresh(); }
}
 
private e_arrow _arrow;
public enum e_arrow
{
None, ToRight, ToDown
}
public e_arrow Arrow
{
get { return _arrow; }
set { _arrow = value; this.Refresh(); }
}
private e_splitbutton _splitbutton;
public enum e_splitbutton
{
No, Yes
}
public e_splitbutton SplitButton
{
get { return _splitbutton; }
set { _splitbutton = value; this.Refresh(); }
}
private int _splitdistance = 0;
public int SplitDistance
{
get { return _splitdistance; }
set { _splitdistance = value; this.Refresh(); }
}
private string _title = "";
public string Title
{
get { return _title; }
set { _title = value; this.Refresh(); }
}
private bool _keeppress = false;
public bool KeepPress
{
get { return _keeppress; }
set { _keeppress = value; }
}
private bool _ispressed = false;
public bool IsPressed
{
get { return _ispressed; }
set { _ispressed = value; }
}
 

#endregion
 
#region Menu Pos
private Point _menupos = new Point(0, 0);
public Point MenuPos
{
get { return _menupos; }
set { _menupos = value; }
}
#endregion
 
#region Colors
private Color _baseColor = Color.FromArgb(186, 209, 240);
private Color _onColor = Color.FromArgb(255, 214, 78);
private Color _pressColor = Color.FromArgb(255, 128, 0);
 
private Color _baseStroke = Color.FromArgb(152, 187, 213);
private Color _onStroke = Color.FromArgb(196, 177, 118);
private Color _pressStroke = Color.FromArgb(128, 64, 0);
private Color _colorStroke = Color.FromArgb(255, 255, 255);
private int A0, R0, G0, B0;
 
public Color ColorBase
{
get { return _baseColor; }
set
{
_baseColor = value;
R0 = _baseColor.R;
B0 = _baseColor.B;
G0 = _baseColor.G;
A0 = _baseColor.A;
RibbonColor hsb = new RibbonColor(_baseColor);
if (hsb.BC < 50)
{
hsb.SetBrightness(60);
}
else
{
hsb.SetBrightness(30);
}
if (_baseColor.A > 0)
_baseStroke = Color.FromArgb(100, hsb.GetColor());
else
_baseStroke = Color.FromArgb(0, hsb.GetColor());
this.Refresh();
}
}
public Color ColorOn
{
get { return _onColor; }
set
{
_onColor = value;
 
RibbonColor hsb = new RibbonColor(_onColor);
if (hsb.BC < 50)
{
hsb.SetBrightness(60);
}
else
{
hsb.SetBrightness(30);
}
if (_baseStroke.A > 0)
_onStroke = Color.FromArgb(100, hsb.GetColor());
else
_onStroke = Color.FromArgb(0, hsb.GetColor());
this.Refresh();
}
}
public Color ColorPress
{
get { return _pressColor; }
set
{
_pressColor = value;
 
RibbonColor hsb = new RibbonColor(_pressColor);
if (hsb.BC < 50)
{
hsb.SetBrightness(60);
}
else
{
hsb.SetBrightness(30);
}
if (_baseStroke.A > 0)
_pressStroke = Color.FromArgb(100, hsb.GetColor());
else
_pressStroke = Color.FromArgb(0, hsb.GetColor());
this.Refresh();
 
}
}
public Color ColorBaseStroke
{
get { return _baseStroke; }
set { _baseStroke = value; }
}
public Color ColorOnStroke
{
get { return _onStroke; }
set { _onStroke = value; }
}
public Color ColorPressStroke
{
get { return _pressStroke; }
set { _pressStroke = value; }
}
public Color GetColorIncreased(Color color, int h, int s, int b)
{
RibbonColor _color = new RibbonColor(color);
int ss = _color.GetSaturation();
float vc = b + _color.GetBrightness();
float hc = h + _color.GetHue();
float sc = s + ss;
 

_color.VC = vc;
_color.HC = hc;
_color.SC = sc;
 
return _color.GetColor();
 

}
 
public Color GetColor(int A, int R, int G, int B)
{
if (A + A0 > 255) { A = 255; } else { A = A + A0; }
if (R + R0 > 255) { R = 255; } else { R = R + R0; }
if (G + G0 > 255) { G = 255; } else { G = G + G0; }
if (B + B0 > 255) { B = 255; } else { B = B + B0; }
 
return Color.FromArgb(A, R, G, B);
}
#endregion
 
protected override void OnPaint(PaintEventArgs pevent)
{
#region Variables & Conf
Graphics g = pevent.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.High;
Rectangle r = new Rectangle(new Point(-1, -1), new Size(this.Width + _radius, this.Height + _radius));
#endregion
 
#region Paint
GraphicsPath path = new GraphicsPath();
Rectangle rp = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
DrawArc(rp, path);
FillGradients(g, path);
DrawImage(g);
DrawString(g);
DrawArrow(g);
#endregion
}
 
protected override void OnResize(EventArgs e)
{
Rectangle r = new Rectangle(new Point(-1, -1), new Size(this.Width + _radius, this.Height + _radius));
if (this.Size != null)
{
GraphicsPath pathregion = new GraphicsPath();
DrawArc(r, pathregion);
this.Region = new Region(pathregion);
}
base.OnResize(e);
}
 
#region Paint Methods
public void FillGradients(Graphics gr, GraphicsPath pa)
{
int origin = this.Height / 3; int end = this.Height; int oe = (end - origin) / 2;
LinearGradientBrush lgbrush; Rectangle rect;
if (_showbase == e_showbase.Yes)
{
rect = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
pa = new GraphicsPath();
DrawArc(rect, pa);
lgbrush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
 
#region Main Gradient
float[] pos = new float[4];
pos[0] = 0.0F; pos[1] = 0.3F; pos[2] = 0.35F; pos[3] = 1.0F;
Color[] colors = new Color[4];
if (i_mode == 0)
{
colors[0] = GetColor(0, 35, 24, 9);
colors[1] = GetColor(0, 13, 8, 3);
colors[2] = Color.FromArgb(A0, R0, G0, B0);
colors[3] = GetColor(0, 28, 29, 14);
}
else
{
colors[0] = GetColor(0, 0, 50, 100);
colors[1] = GetColor(0, 0, 0, 30);
colors[2] = Color.FromArgb(A0, R0, G0, B0);
colors[3] = GetColor(0, 0, 50, 100);
}
ColorBlend mix = new ColorBlend();
mix.Colors = colors;
mix.Positions = pos;
lgbrush.InterpolationColors = mix;
gr.FillPath(lgbrush, pa);
#endregion
 
#region Fill Band
rect = new Rectangle(new Point(0, 0), new Size(this.Width, this.Height / 3));
pa = new GraphicsPath(); int _rtemp = _radius; _radius = _rtemp - 1;
DrawArc(rect, pa);
if (A0 > 80)
{
gr.FillPath(new SolidBrush(Color.FromArgb(60, 255, 255, 255)), pa);
}
_radius = _rtemp;
#endregion
 
#region SplitFill
if (_splitbutton == e_splitbutton.Yes & mouse)
{
FillSplit(gr);
}
#endregion
 
#region Shadow
if (i_mode == 2)
{
rect = new Rectangle(1, 1, this.Width - 2, this.Height);
pa = new GraphicsPath();
DrawShadow(rect, pa);
gr.DrawPath(new Pen(Color.FromArgb(50, 20, 20, 20), 2.0F), pa);
 
}
else
{
rect = new Rectangle(1, 1, this.Width - 2, this.Height - 1);
pa = new GraphicsPath();
DrawShadow(rect, pa);
if (A0 > 80)
{
gr.DrawPath(new Pen(Color.FromArgb(100, 250, 250, 250), 3.0F), pa);
}
}
#endregion
 
#region SplitLine
 
if (_splitbutton == e_splitbutton.Yes)
{
if (_imagelocation == e_imagelocation.Top)
{
switch (i_mode)
{
case 1:
gr.DrawLine(new Pen(_onStroke), new Point(1, this.Height - _splitdistance), new Point(this.Width - 1, this.Height - _splitdistance));
break;
case 2:
gr.DrawLine(new Pen(_pressStroke), new Point(1, this.Height - _splitdistance), new Point(this.Width - 1, this.Height - _splitdistance));
break;
default:
break;
}
}
else if (_imagelocation == e_imagelocation.Left)
{
switch (i_mode)
{
case 1:
gr.DrawLine(new Pen(_onStroke), new Point(this.Width - _splitdistance, 0), new Point(this.Width - _splitdistance, this.Height));
break;
case 2:
gr.DrawLine(new Pen(_pressStroke), new Point(this.Width - _splitdistance, 0), new Point(this.Width - _splitdistance, this.Height));
break;
default:
break;
}
}
 
}
#endregion
 
rect = new Rectangle(new Point(0, 0), new Size(this.Width - 1, this.Height - 1));
pa = new GraphicsPath();
DrawArc(rect, pa);
gr.DrawPath(new Pen(_colorStroke, 0.9F), pa);
 
pa.Dispose(); lgbrush.Dispose();
 

}
}
 
int offsetx = 0, offsety = 0, imageheight = 0, imagewidth = 0;
public void DrawImage(Graphics gr)
{
if (this.Image != null)
{
offsety = _imageoffset; offsetx = _imageoffset;
if (_imagelocation == e_imagelocation.Left | _imagelocation == e_imagelocation.Right)
{
imageheight = this.Height - offsety * 2;
if (imageheight > _maximagesize.Y & _maximagesize.Y != 0)
{ imageheight = _maximagesize.Y; }
imagewidth = (int)((Convert.ToDouble(imageheight) / this.Image.Height) * this.Image.Width);
}
else if (_imagelocation == e_imagelocation.Top | _imagelocation == e_imagelocation.Bottom)
{
imagewidth = this.Width - offsetx * 2;
if (imagewidth > _maximagesize.X & _maximagesize.X != 0)
{ imagewidth = _maximagesize.X; }
imageheight = (int)((Convert.ToDouble(imagewidth) / this.Image.Width) * this.Image.Height);
 
}
switch (_imagelocation)
{
case e_imagelocation.Left:
gr.DrawImage(this.Image, new Rectangle(offsetx, offsety, imagewidth, imageheight));
break;
case e_imagelocation.Right:
gr.DrawImage(this.Image, new Rectangle(this.Width - imagewidth - offsetx, offsety, imagewidth, imageheight));
break;
case e_imagelocation.Top:
offsetx = this.Width / 2 - imagewidth / 2;
gr.DrawImage(this.Image, new Rectangle(offsetx, offsety, imagewidth, imageheight));
break;
case e_imagelocation.Bottom:
gr.DrawImage(this.Image, new Rectangle(offsetx, this.Height - imageheight - offsety, imagewidth, imageheight));
break;
default:
break;
}
}
}
 
public void DrawString(Graphics gr)
{
if (this.Text != "")
{
int textwidth = (int)gr.MeasureString(this.Text, this.Font).Width;
int textheight = (int)gr.MeasureString(this.Text, this.Font).Height;
 
int extraoffset = 0;
Font fontb = new Font(this.Font, FontStyle.Bold);
if (_title != "")
{
extraoffset = textheight / 2;
}
 
string s1 = this.Text; string s2 = "";
int jump = this.Text.IndexOf("\\n");
 
if (jump != -1)
{
s2 = s1.Substring(jump + 3); s1 = s1.Substring(0, jump);
}
 
#region Calc Color Brightness
RibbonColor __color = new RibbonColor(Color.FromArgb(R0, G0, B0));
RibbonColor forecolor = new RibbonColor(this.ForeColor);
Color _forecolor;
 
if (__color.GetBrightness() > 50)
{
forecolor.BC = 1;
forecolor.SC = 80;
}
else
{
forecolor.BC = 99;
forecolor.SC = 20;
}
_forecolor = forecolor.GetColor();
#endregion
 
if (this.Image == null)
{
switch (this.TextAlign)
{
case ContentAlignment.BottomCenter:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, this.Height - textheight - 1));
break;
case ContentAlignment.BottomLeft:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(1, this.Height - textheight - 1));
break;
case ContentAlignment.BottomRight:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width - textwidth - 1, this.Height - textheight - 1));
break;
case ContentAlignment.MiddleCenter:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, this.Height / 2 - textheight / 2 - 1));
break;
case ContentAlignment.MiddleLeft:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(1, this.Height / 2 - textheight / 2 - 1));
break;
case ContentAlignment.MiddleRight:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width - textwidth - 1, this.Height / 2 - textheight / 2 - 1));
break;
case ContentAlignment.TopCenter:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, 1));
break;
case ContentAlignment.TopLeft:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(1, 1));
break;
case ContentAlignment.TopRight:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width - textwidth - 1, 1));
break;
default:
break;
}
}else{
switch (_imagelocation)
{
case e_imagelocation.Left:
if (this.Title != "")
{
gr.DrawString(this.Title, fontb, new SolidBrush(_forecolor), new PointF(offsetx + imagewidth + 4, this.Font.Size / 2));
gr.DrawString(s1, this.Font, new SolidBrush(_forecolor), new PointF(offsetx + imagewidth + 4, 2 * this.Font.Size + 1));
gr.DrawString(s2, this.Font, new SolidBrush(_forecolor), new PointF(offsetx + imagewidth + 4, 3 * this.Font.Size + 4));
}
else
{
gr.DrawString(s1, this.Font, new SolidBrush(_forecolor), new PointF(offsetx + imagewidth + 4, this.Height / 2 - this.Font.Size + 1));
}
 
break;
case e_imagelocation.Right:
gr.DrawString(this.Title, fontb, new SolidBrush(_forecolor), new PointF(offsetx, this.Height / 2 - this.Font.Size + 1 - extraoffset));
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(offsetx, extraoffset + this.Height / 2 - this.Font.Size + 1));
break;
case e_imagelocation.Top:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, offsety + imageheight));
break;
case e_imagelocation.Bottom:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, this.Height - imageheight - textheight - 1));
break;
case e_imagelocation.None:
gr.DrawString(this.Text, this.Font, new SolidBrush(_forecolor), new PointF(this.Width / 2 - textwidth / 2 - 1, this.Height / 2 - textheight / 2 - 1));
break;
default:
break;
}
}
fontb.Dispose();
 
}
}
 
public void DrawArc(Rectangle re, GraphicsPath pa)
{
int _radiusX0Y0 = _radius, _radiusXFY0 = _radius, _radiusX0YF = _radius, _radiusXFYF = _radius;
switch (_grouppos)
{
case e_groupPos.Left:
_radiusXFY0 = 1; _radiusXFYF = 1;
break;
case e_groupPos.Center:
_radiusX0Y0 = 1; _radiusX0YF = 1; _radiusXFY0 = 1; _radiusXFYF = 1;
break;
case e_groupPos.Right:
_radiusX0Y0 = 1; _radiusX0YF = 1;
break;
case e_groupPos.Top:
_radiusX0YF = 1; _radiusXFYF = 1;
break;
case e_groupPos.Bottom:
_radiusX0Y0 = 1; _radiusXFY0 = 1;
break;
}
pa.AddArc(re.X, re.Y, _radiusX0Y0, _radiusX0Y0, 180, 90);
pa.AddArc(re.Width - _radiusXFY0, re.Y, _radiusXFY0, _radiusXFY0, 270, 90);
pa.AddArc(re.Width - _radiusXFYF, re.Height - _radiusXFYF, _radiusXFYF, _radiusXFYF, 0, 90);
pa.AddArc(re.X, re.Height - _radiusX0YF, _radiusX0YF, _radiusX0YF, 90, 90);
pa.CloseFigure();
 
}
 
public void DrawShadow(Rectangle re, GraphicsPath pa)
{
int _radiusX0Y0 = _radius, _radiusXFY0 = _radius, _radiusX0YF = _radius, _radiusXFYF = _radius;
switch (_grouppos)
{
case e_groupPos.Left:
_radiusXFY0 = 1; _radiusXFYF = 1;
break;
case e_groupPos.Center:
_radiusX0Y0 = 1; _radiusX0YF = 1; _radiusXFY0 = 1; _radiusXFYF = 1;
break;
case e_groupPos.Right:
_radiusX0Y0 = 1; _radiusX0YF = 1;
break;
case e_groupPos.Top:
_radiusX0YF = 1; _radiusXFYF = 1;
break;
case e_groupPos.Bottom:
_radiusX0Y0 = 1; _radiusXFY0 = 1;
break;
}
pa.AddArc(re.X, re.Y, _radiusX0Y0, _radiusX0Y0, 180, 90);
pa.AddArc(re.Width - _radiusXFY0, re.Y, _radiusXFY0, _radiusXFY0, 270, 90);
pa.AddArc(re.Width - _radiusXFYF, re.Height - _radiusXFYF, _radiusXFYF, _radiusXFYF, 0, 90);
pa.AddArc(re.X, re.Height - _radiusX0YF, _radiusX0YF, _radiusX0YF, 90, 90);
pa.CloseFigure();
 
}
 
public void DrawArrow(Graphics gr)
{
int _size = 1;
 
RibbonColor __color = new RibbonColor(Color.FromArgb(R0, G0, B0));
RibbonColor forecolor = new RibbonColor(this.ForeColor);
Color _forecolor;
 
if (__color.GetBrightness() > 50)
{
forecolor.BC = 1;
forecolor.SC = 80;
}
else
{
forecolor.BC = 99;
forecolor.SC = 20;
}
_forecolor = forecolor.GetColor();
 
switch (_arrow)
{
case e_arrow.ToDown:
if (_imagelocation == e_imagelocation.Left)
{
Point[] points = new Point[3];
points[0] = new Point(this.Width - 8 * _size - _imageoffset, this.Height / 2 - _size / 2);
points[1] = new Point(this.Width - 2 * _size - _imageoffset, this.Height / 2 - _size / 2);
points[2] = new Point(this.Width - 5 * _size - _imageoffset, this.Height / 2 + _size * 2);
gr.FillPolygon(new SolidBrush(_forecolor), points);
}
else if (_imagelocation == e_imagelocation.Top)
{
Point[] points = new Point[3];
points[0] = new Point(this.Width / 2 + 8 * _size - _imageoffset, this.Height - _imageoffset - 5 * _size);
points[1] = new Point(this.Width / 2 + 2 * _size - _imageoffset, this.Height - _imageoffset - 5 * _size);
points[2] = new Point(this.Width / 2 + 5 * _size - _imageoffset, this.Height - _imageoffset - 2 * _size);
gr.FillPolygon(new SolidBrush(_forecolor), points);
}
break;
case e_arrow.ToRight:
if (_imagelocation == e_imagelocation.Left)
{
int arrowxpos = this.Width - _splitdistance + 2 * _imageoffset;
Point[] points = new Point[3];
points[0] = new Point(arrowxpos + 4, this.Height / 2 - 4 * _size);
points[1] = new Point(arrowxpos + 8, this.Height / 2);
points[2] = new Point(arrowxpos + 4, this.Height / 2 + 4 * _size);
gr.FillPolygon(new SolidBrush(_forecolor), points);
}
break;
default:
break;
}
 
}
 
public void FillSplit(Graphics gr)
{
Color _tranp = Color.FromArgb(200, 255, 255, 255);
int x1 = this.Width - _splitdistance; int x2 = 0;
int y1 = this.Height - _splitdistance; int y2 = 0;
SolidBrush btransp = new SolidBrush(_tranp);
#region Horizontal
if (_imagelocation == e_imagelocation.Left)
{
if (xmouse < this.Width - _splitdistance & mouse) //Small button
{
Rectangle _r = new Rectangle(x1 + 1, 1, this.Width - 2, this.Height - 1);
GraphicsPath p = new GraphicsPath();
int _rtemp = _radius; _radius = 4;
DrawArc(_r, p);
_radius = _rtemp;
gr.FillPath(btransp, p);
 
}
else if (mouse) //Big Button
{
Rectangle _r = new Rectangle(x2 + 1, 1, this.Width - _splitdistance - 1, this.Height - 1);
GraphicsPath p = new GraphicsPath();
int _rtemp = _radius; _radius = 4;
DrawArc(_r, p);
_radius = _rtemp;
gr.FillPath(btransp, p);
}
 
}
#endregion
 
#region Vertical
else if (_imagelocation == e_imagelocation.Top)
{
if (ymouse < this.Height - _splitdistance & mouse) //Small button
{
Rectangle _r = new Rectangle(1, y1 + 1, this.Width - 1, this.Height - 1);
GraphicsPath p = new GraphicsPath();
int _rtemp = _radius; _radius = 4;
DrawArc(_r, p);
_radius = _rtemp;
gr.FillPath(btransp, p);
}
else if (mouse) //Big Button
{
Rectangle _r = new Rectangle(1, y2 + 1, this.Width - 1, this.Height - _splitdistance - 1);
GraphicsPath p = new GraphicsPath();
int _rtemp = _radius; _radius = 4;
DrawArc(_r, p);
_radius = _rtemp;
gr.FillPath(btransp, p);
}
}
#endregion
btransp.Dispose();
 
}
#endregion
 
#region About Fading
private Timer timer1 = new Timer();
int i_factor = 35;
public int FadingSpeed
{
get { return i_factor; }
set
{
if (value > -1)
{
i_factor = value;
}
}
}
int i_fR = 1; int i_fG = 1; int i_fB = 1; int i_fA = 1;
void timer1_Tick(object sender, EventArgs e)
{
#region Entering
if (i_mode == 1)
{
if (System.Math.Abs(ColorOn.R - R0) > i_factor)
{ i_fR = i_factor; }
else { i_fR = 1; }
if (System.Math.Abs(ColorOn.G - G0) > i_factor)
{ i_fG = i_factor; }
else { i_fG = 1; }
if (System.Math.Abs(ColorOn.B - B0) > i_factor)
{ i_fB = i_factor; }
else { i_fB = 1; }
 
if (ColorOn.R < R0)
{
R0 -= i_fR;
}
else if (ColorOn.R > R0)
{
R0 += i_fR;
}
 
if (ColorOn.G < G0)
{
G0 -= i_fG;
}
else if (ColorOn.G > G0)
{
G0 += i_fG;
}
 
if (ColorOn.B < B0)
{
B0 -= i_fB;
}
else if (ColorOn.B > B0)
{
B0 += i_fB;
}
 
if (ColorOn == Color.FromArgb(R0, G0, B0))
{
timer1.Stop();
}
else
{
this.Refresh();
}
}
#endregion
 
#region Leaving
if (i_mode == 0)
{
 
if (System.Math.Abs(ColorBase.R - R0) < i_factor)
{ i_fR = 1; }
else { i_fR = i_factor; }
if (System.Math.Abs(ColorBase.G - G0) < i_factor)
{ i_fG = 1; }
else { i_fG = i_factor; }
if (System.Math.Abs(ColorBase.B - B0) < i_factor)
{ i_fB = 1; }
else { i_fB = i_factor; }
if (System.Math.Abs(ColorBase.A - A0) < i_factor)
{ i_fA = 1; }
else { i_fA = i_factor; }
 
if (ColorBase.R < R0)
{
R0 -= i_fR;
}
else if (ColorBase.R > R0)
{
R0 += i_fR;
}
if (ColorBase.G < G0)
{
G0 -= i_fG;
}
else if (ColorBase.G > G0)
{
G0 += i_fG;
}
if (ColorBase.B < B0)
{
B0 -= i_fB;
}
else if (ColorBase.B > B0)
{
B0 += i_fB;
}
if (ColorBase.A < A0)
{
A0 -= i_fA;
}
else if (ColorBase.A > A0)
{
A0 += i_fA;
}
if (ColorBase == Color.FromArgb(A0, R0, G0, B0))
{
timer1.Stop();
 
}
else
{
 
this.Refresh();
}
 
}
#endregion
 
this.Refresh();
}
#endregion
 
#region Mouse Events
int i_mode = 0; //0 Entering, 1 Out,2 Press
int xmouse = 0, ymouse = 0; bool mouse = false;
 
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
_colorStroke = ColorOnStroke;
_tempshowbase = _showbase;
_showbase = e_showbase.Yes;
i_mode = 1;
xmouse = PointToClient(Cursor.Position).X;
mouse = true;
A0 = 200;
if (i_factor == 0)
{
R0 = _onColor.R; G0 = _onColor.G; B0 = _onColor.B;
}
timer1.Start();
}
 
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
UpdateLeave();
}
 
public void UpdateLeave()
{
if (_keeppress == false | (_keeppress == true & _ispressed == false))
{
_colorStroke = ColorBaseStroke;
_showbase = _tempshowbase;
i_mode = 0;
mouse = false;
if (i_factor == 0)
{
R0 = _baseColor.R; G0 = _baseColor.G; B0 = _baseColor.B;
this.Refresh();
}
else
{
timer1.Stop();
timer1.Start();
}
}
}
 
protected override void OnMouseDown(MouseEventArgs mevent)
{
base.OnMouseDown(mevent);
R0 = ColorPress.R; G0 = ColorPress.G; B0 = ColorPress.B;
_colorStroke = ColorPressStroke;
_showbase = e_showbase.Yes;
i_mode = 2;
xmouse = PointToClient(Cursor.Position).X;
ymouse = PointToClient(Cursor.Position).Y;
mouse = true;
}
 
protected override void OnMouseUp(MouseEventArgs mevent)
{
R0 = ColorOn.R; G0 = ColorOn.G; B0 = ColorOn.B;
_colorStroke = ColorOnStroke;
_showbase = e_showbase.Yes;
i_mode = 1;
mouse = true;
 
#region ClickSplit
if (_imagelocation == e_imagelocation.Left & xmouse > this.Width - _splitdistance & _splitbutton == e_splitbutton.Yes)
{
if (_arrow == e_arrow.ToDown)
{
if (this.ContextMenuStrip != null)
this.ContextMenuStrip.Opacity = 1.0;
this.ContextMenuStrip.Show(this, 0, this.Height);
 
}
else if (_arrow == e_arrow.ToRight)
{
if (this.ContextMenuStrip != null)
{
ContextMenuStrip menu = this.ContextMenuStrip;
this.ContextMenuStrip.Opacity = 1.0;
if (this.MenuPos.Y == 0)
{
this.ContextMenuStrip.Show(this, this.Width + 2, -this.Height);
}
else
{
this.ContextMenuStrip.Show(this, this.Width + 2, this.MenuPos.Y);
}
}
 
}
}
else if (_imagelocation == e_imagelocation.Top & ymouse > this.Height - _splitdistance & _splitbutton == e_splitbutton.Yes)
{
if (_arrow == e_arrow.ToDown)
{
if (this.ContextMenuStrip != null)
this.ContextMenuStrip.Show(this, 0, this.Height);
}
}
#endregion
else
{
base.OnMouseUp(mevent);
 
#region Keep Press
if (_keeppress)
{
_ispressed = true;
 
try
{
foreach (Control _control in this.Parent.Controls)
{
if (typeof(RibbonMenuButton) == _control.GetType() & _control.Name != this.Name)
{
((RibbonMenuButton)(_control))._ispressed = false;
((RibbonMenuButton)(_control)).UpdateLeave();
}
}
}
catch { }
 

}
#endregion
 
}
 

}
 
protected override void OnMouseMove(MouseEventArgs mevent)
{
if (mouse & this.SplitButton == e_splitbutton.Yes)
{
xmouse = PointToClient(Cursor.Position).X;
ymouse = PointToClient(Cursor.Position).Y;
this.Refresh();
}
base.OnMouseMove(mevent);
}
 

#endregion
}
 
public class RibbonColor
{
 
#region Constructors
public RibbonColor(Color color)
{
rc = color.R;
gc = color.G;
bc = color.B;
ac = color.A;
 
HSV();
}
 
public RibbonColor(uint alpha, int hue, int saturation, int brightness)
{
hc = hue;
sc = saturation;
vc = brightness;
ac = alpha;
 
GetColor();
}
#endregion
 
#region Alpha
private uint ac = 0; //Alpha > -1
public uint AC { get { return ac; } set { System.Math.Min(value, 255); } }
#endregion
 
#region RGB
private int rc = 0, gc = 0, bc = 0; //RGB Components > -1
 
public int RC { get { return rc; } set { rc = System.Math.Min(value, 255); } }
public int GC { get { return gc; } set { gc = System.Math.Min(value, 255); } }
public int BC { get { return bc; } set { bc = System.Math.Min(value, 255); } }
 

public Color GetColor()
{
 
int conv;
double hue, sat, val;
int basis;
 
hue = (float)hc / 100.0f;
sat = (float)sc / 100.0f;
val = (float)vc / 100.0f;
 
if ((float)sc == 0) // Gray Colors
{
conv = (int)(255.0f * val);
rc = gc = bc = conv;
return Color.FromArgb((int)rc, (int)gc, (int)bc);
}
 
basis = (int)(255.0f * (1.0 - sat) * val);
 
switch ((int)((float)hc / 60.0f))
{
case 0:
rc = (int)(255.0f * val);
gc = (int)((255.0f * val - basis) * (hc / 60.0f) + basis);
bc = (int)basis;
break;
 
case 1:
rc = (int)((255.0f * val - basis) * (1.0f - ((hc % 60) / 60.0f)) + basis);
gc = (int)(255.0f * val);
bc = (int)basis;
break;
 
case 2:
rc = (int)basis;
gc = (int)(255.0f * val);
bc = (int)((255.0f * val - basis) * ((hc % 60) / 60.0f) + basis);
break;
 
case 3:
rc = (int)basis;
gc = (int)((255.0f * val - basis) * (1.0f - ((hc % 60) / 60.0f)) + basis);
bc = (int)(255.0f * val);
break;
 
case 4:
rc = (int)((255.0f * val - basis) * ((hc % 60) / 60.0f) + basis);
gc = (int)basis;
bc = (int)(255.0f * val);
break;
 
case 5:
rc = (int)(255.0f * val);
gc = (int)basis;
bc = (int)((255.0f * val - basis) * (1.0f - ((hc % 60) / 60.0f)) + basis);
break;
}
return Color.FromArgb((int)ac, (int)rc, (int)gc, (int)bc);
 
}
 
public uint GetRed()
{
return GetColor().R;
}
 
public uint GetGreen()
{
return GetColor().G;
}
 
public uint GetBlue()
{
return GetColor().B;
}
 
#endregion
 
#region HSV
 
private int hc = 0, sc = 0, vc = 0;
 
public float HC { get { return hc; } set { hc = (int)System.Math.Min(value, 359); hc = (int)System.Math.Max(hc, 0); } }
public float SC { get { return sc; } set { sc = (int)System.Math.Min(value, 100); sc = (int)System.Math.Max(sc, 0); } }
public float VC { get { return vc; } set { vc = (int)System.Math.Min(value, 100); vc = (int)System.Math.Max(vc, 0); } }
 
public enum C { Red, Green, Blue, None }
private int maxval = 0, minval = 0;
private C CompMax, CompMin;
 
private void HSV()
{
hc = this.GetHue();
sc = this.GetSaturation();
vc = this.GetBrightness();
}
 
public void CMax()
{
if (rc > gc)
{
if (rc < bc) { maxval = bc; CompMax = C.Blue; }
else { maxval = rc; CompMax = C.Red; }
}
else
{
if (gc < bc) { maxval = bc; CompMax = C.Blue; }
else { maxval = gc; CompMax = C.Green; }
}
}
 
public void CMin()
{
if (rc < gc)
{
if (rc > bc) { minval = bc; CompMin = C.Blue; }
else { minval = rc; CompMin = C.Red; }
}
else
{
if (gc > bc) { minval = bc; CompMin = C.Blue; }
else { minval = gc; CompMin = C.Green; }
}
 
}
 
public int GetBrightness() //Brightness is from 0 to 100
{
CMax(); return 100 * maxval / 255;
}
 
public int GetSaturation() //Saturation from 0 to 100
{
CMax(); CMin();
if (CompMax == C.None)
return 0;
else if (maxval != minval)
{
Decimal d_sat = Decimal.Divide(minval, maxval);
d_sat = Decimal.Subtract(1, d_sat);
d_sat = Decimal.Multiply(d_sat, 100);
return Convert.ToUInt16(d_sat);
}
else
{
return 0;
}
 
}
 
public int GetHue()
{
CMax(); CMin();
 
if (maxval == minval)
{
return 0;
}
else if (CompMax == C.Red)
{
if (gc >= bc)
{
Decimal d1 = Decimal.Divide((gc - bc), (maxval - minval));
return Convert.ToUInt16(60 * d1);
}
else
{
Decimal d1 = Decimal.Divide((bc - gc), (maxval - minval));
d1 = 60 * d1;
return Convert.ToUInt16(360 - d1);
}
}
else if (CompMax == C.Green)
{
if (bc >= rc)
{
Decimal d1 = Decimal.Divide((bc - rc), (maxval - minval));
d1 = 60 * d1;
return Convert.ToUInt16(120 + d1);
}
else
{
Decimal d1 = Decimal.Divide((rc - bc), (maxval - minval));
d1 = 60 * d1;
return Convert.ToUInt16(120 - d1);
}
 

}
else if (CompMax == C.Blue)
{
if (rc >= gc)
{
Decimal d1 = Decimal.Divide((rc - gc), (maxval - minval));
d1 = 60 * d1;
return Convert.ToUInt16(240 + d1);
}
else
{
Decimal d1 = Decimal.Divide((gc - rc), (maxval - minval));
d1 = 60 * d1;
return Convert.ToUInt16(240 - d1);
}
}
else
{
return 0;
}
} //Hue from 0 to 100
 
#endregion
 
#region Methods
 
public bool IsDark()
{
if (BC > 50)
{
return false;
}
else
{
return true;
}
}
 
public void IncreaseBrightness(int val)
{
this.VC = this.VC + val;
 
}
 
public void SetBrightness(int val)
{
this.VC = val;
 
}
 
public void IncreaseHue(int val)
{
this.HC = this.HC + val;
 
}
 
public void SetHue(int val)
{
this.HC = val;
 
}
 
public void IncreaseSaturation(int val)
{
this.SC = this.SC + val;
 
}
 
public void SetSaturation(int val)
{
this.SC = val;
 
}
 
public Color IncreaseHSV(int h, int s, int b)
{
this.HC = this.HC + h;
this.SC = this.SC + s;
this.VC = this.VC + b;
return GetColor();
}
 
#endregion
 
}
GeneralTab key pressmemberpiyush74198205 May '08 - 20:21 
I have placed two textbox and one this button.
 
Now when i move from one control to another by Tab key press the button don't get focus.
 
Whey you replace this button with normal button, the normal button get focus and it show this by border around button. But this button don't.
 
Can you help me ?
Generalstrip menu does not work by memembertrupik27 Feb '08 - 20:14 
When I set ContextStripMenu to a Ribbon menu and click the button, the menu does not render itself correctly. It just is all black.
 
In design time, when I click the Type here area in the RibbonMenu to add a new menu item, the UI stucks in some kind of endless cycle.
 
Am I the only one having this trouble???
GeneralFound a bug on right clicking a button... [modified]memberOctopod10 Jan '08 - 5:50 
Its easy to reproduce, simply right click in the right part (the contextual part with the arrow) of the button named "Paste History Menu".
 
Then try to click another button... it's now stuck.
 
The same bug occurs with all buttons that have same kind of contextuel part ("Write & Close" for example).
 
Anyway, pretty cool control, really good work.
 
Alexis.
 
modified on Monday, January 14, 2008 5:20:39 PM

Generalso coolmemberJackChen19877 Jan '08 - 22:11 
Thank you I love you so much Laugh | :laugh: Big Grin | :-D Poke tongue | ;-P
GeneralI'm confusedmembertcsoccerman4 Dec '07 - 13:49 
First i'd like to say that this is the control that many many many many many people are looking for. It includes may features of lots of seperate controls out there. Someone made a split button (a boring one too). someone made a glowing one. someone made a colorful one. You joined all that together. Now people like me can have a common button throughout their app and still have all the functions they need. Thank you.
 
Second, I can't quite figure out a few things. First of all, i can't seem to get the arrow to point right, even though that's what i set it as. Second, the color part is a little confusing, can you discribe that a little more? What does ispressed and keepressed mean and theres just a few things that don't seem to be working visually. The Grouppos for example.
GeneralAnother CPU bugmemberJordiproatec29 Nov '07 - 2:30 
When I click the ribbonmenubutton lots of OnPaint events was send by the "set" method in the ColorBase, ColorOn and ColorPress properties:
public Color ColorBase
{
get { return _baseColor; }
set
{
_baseColor = value;
R0 = _baseColor.R;
B0 = _baseColor.B;
G0 = _baseColor.G;
A0 = _baseColor.A;
RibbonColor hsb = new RibbonColor(_baseColor);
if (hsb.BC < 50)
{
hsb.SetBrightness(60);
}
else
{
hsb.SetBrightness(30);
}
if (_baseColor.A > 0)
_baseStroke = Color.FromArgb(100, hsb.GetColor());
else
_baseStroke = Color.FromArgb(0, hsb.GetColor());
here---> this.Invalidate();
}
}

 

I fix this executing the set code only when the property change:
public Color ColorBase
{
get { return _baseColor; }
set
{
if (_baseColor != value)
{
_baseColor = value;
R0 = _baseColor.R;
B0 = _baseColor.B;
G0 = _baseColor.G;
A0 = _baseColor.A;
RibbonColor hsb = new RibbonColor(_baseColor);
if (hsb.BC < 50)
{
hsb.SetBrightness(60);
}
else
{
hsb.SetBrightness(30);
}
if (_baseColor.A > 0)
_baseStroke = Color.FromArgb(100, hsb.GetColor());
else
_baseStroke = Color.FromArgb(0, hsb.GetColor());
this.Invalidate();
}
}
}

 
Thanks for reading and excuse my poor English
General3 bug fixes (includin CPU issues)membergpgemini13 Oct '07 - 11:01 
Hi,
 
First of all - Jaun, I LOVE your control, it's probably one of the best in CodeProject.
 
But as soon as I started using it, i noticed it has CPU consumption issues (I always have SiMeter on, so noticing it was a breeze).
It has two CPU problems, first is that moving the mouse around the buttons causes major CPU usage, which probably happens due to over-painting the buttons (and should be fixed by optimizing the code), and second that it has bursts of massive CPU usage with no user/mouse interaction. The latter is obviously a bug.
 
all bugs/fixes here relate to the RibbonMenuButton.cs file.
(fixed file is linked at the end of the post)
 
Bug #1: when moving the mouse quickly over a split button, or two non-split buttons, the CPU usage jumps to 100% until the mouse is moved over the buttons again (do it too many times and you are stuck with 100%).
This is a major application killer, and obviously cannot be left unfixed.
To locate the CPU leakage, I went to the immediate suspect: OnPaint().
Added a WriteLine("Paint" + DateTime.Millisecond) to see each time a button is painted, and I saw it was bombarding with OnPaint() calls for no reason.
Add a breakpoint AFTER the bombardment has started and you find the perpetrator:
timer1_Tick() is being called, and executes the following in the "Leaving" region:
else
{
this.Refresh();
}

Obviously the timer went out of control, so I added a timer1.Stop() statement before this.Refresh():
else
{
timer1.Stop();
this.Refresh();
}

And what do you know, the bug is gone.
Hurray !
But obviously this timer is good for something ...
Since I only use non-fading buttons (I want maximum performance) I tried the fix on a fading button, and sadly it broke.
So I tested to see if the bug is unique to non-fading buttons, or affects all buttons, and turns out it only happens with non-fading buttons.
So I patched the fix to affect only non-fading buttons:
else
{
if (i_factor == 0)
timer1.Stop();
this.Refresh();
}

 
Bug #1 fixed.
 
Bug #2: When the mouse is hovering over a button, periodic OnPaint() calls are executed.
With the WriteLine() thing in OnPaint I was able to notice a weird behavior, that had little effect on CPU usage but was clearly a bug - a hovering non-moving mouse over a button was producing OnPaint() calls, slowly but constantly (around 2-10 per second), with varying effect on different buttons.
To catch this, I added a breakpoint in OnPaint that hit after 50 passes (to avoid regular OnPaint calls) and put the mouse over a button. After a few seconds I found the second perpetrator:
The overrriden OnMouseMove() method.
protected override void OnMouseMove(MouseEventArgs mevent) {
if (mouse & this.SplitButton == e_splitbutton.Yes) {
xmouse = PointToClient(Cursor.Position).X;
ymouse = PointToClient(Cursor.Position).Y;
this.Refresh();
}
base.OnMouseMove(mevent);
}

After taking a look at it, I found nothing wrong about it (except the really weird way to get xmouse and ymouse, why not use the mevent.X and mevent.Y values ?).
The only suspicious thing was using this.Refresh() inside a OnMoueMove() event handler.
So I tested it in a small program outside, and indeed, calling this.Refresh() (or this.Invalidate()) inside a OnMouseMove() handler is a BAD idea - it causes the OnMouseMove() event to be called repeatedly and indefinitely.
It's probably some internal WinForms bug/feature (or maybe it's an abuse of the API), but either way I fixed it by checking that the mouse has ACTUALLY moved, before calling this.Refresh():
protected override void OnMouseMove(MouseEventArgs mevent)
{
if (mouse & this.SplitButton == e_splitbutton.Yes)
{
prev_xmouse = xmouse;
prev_ymouse = ymouse;
xmouse = PointToClient(Cursor.Position).X;
ymouse = PointToClient(Cursor.Position).Y;
if (prev_xmouse != xmouse || prev_ymouse != ymouse)
this.Refresh();
}
base.OnMouseMove(mevent);
}

 
Bug #2 fixed.
 
Bug #3: This one is a non-CPU related, when RIGHT-clicking the arrow of a split-button, AND then clicking outside the opened context menu, ALL the RibbonButtons stop reacting to mouse events (except click events) until the context menu is clicked properly.
This one was obviously related to mouseDown and mouseUp events, so I cheched them out.
I found that when clicking the button, there is a check in the MouseUp event if the click was inside the arrow area (hmmmm, suspicious already) and if so, the conetxt menu is opened under the button, if not, the event is passes to the base.
First attempt: lets pass the event to the base either way. Quickly enough it turned out to be a bad idea. But why ? Since this causes the context menu to open under the mouse, and then in a split of a second to move under the button. Taking another look at the problem I noticed that when right-clicking the button NOT in the arrow area, the context menu is opened under the mouse, and in the arrow area it is overridden and is opened under the button. But in the latter case, the base class event handler is never called. The mouseUp event never reaches the base class and the mouse state is messed up.
To fix this, I added a check in the MouseUp method, if the click is a RIGHT-click, pass the event to the base class and return, the effect of this is that the context menu is opened naturally and all is good, if the click is a LEFT-click the context menu is opened manually under the button, and all is good.
 
Bug #3 fixed.
 

Ce tout.
The fixed file is here:
http://gpgemini.googlepages.com/RibbonMenuButton.zip
Notice that these are plain patches to the found bugs, I hope Juan takes a look at them and fixes them properly in the next release.
GeneralTextAlign requests are ignoredmemberGrantM2 Oct '07 - 10:19 
TextAlign requests are being ignored, even in the demo application. Any suggestions? They don't shift at all from their current locations.
 
Other than that, I love it!
QuestionHow to unable a RibbonMenuButton?memberivanchain@hotmail.com16 Sep '07 - 14:43 
I want to do this:
Unable a button, that means, the button could not be clicked and the image on it is showed as grey-color.
 
I tried to set the RibbonMenuButton.enable to false, the result is: yes, the button could not be clicked, BUT, the image on it is still a colorful one, just looks like a common button.
 
So If I don't click it, I can't tell an enable button or an unable button from appearance. I thinks this is not good.
 
thanks!
 
123

GeneralHi, about the iconsmemberivanchain@hotmail.com11 Sep '07 - 3:44 
Hi, I read your answers that you get the icons from the gnome.
 
Sorry for my stupid, I don't know how to download the icons there. Could you tell me?
 
For example, I found an icons set at:
http://art.gnome.org/themes/icon/1112
I tried to download it, but the .rar package could not be opened(report an error). and The context seem to be .tar file, not the icon file. How do you get the png out?
 
thanks.
 
123

GeneralRe: Hi, about the iconsmemberAlpha Nerd24 May '08 - 7:32 
Some are icons from the Tango theme. They have a normal RAR file, which I have decompressed with WinRAR suceesfully.
GeneralUsing this button as toolstripbuttonmemberVincent_ws10 Sep '07 - 17:09 
Hi nice work! I'd like to put the ribbon menu button in my toolstrip. Anyone has any suggestion how to do it? Thanks in advance!
 
Any way this is really a brilliant control!! Big Grin | :-D
Generalmissing Ribbon MenumemberKamalmostofi31 Aug '07 - 11:40 
Hi,
 
I have added the reference and the control to my toolbox, but I don't have RibbonMenu control in my toolbox!
 
How can I add it to my project?
 
Thanks for your help,
 
Kamal
AnswerRe: missing Ribbon Menumemberqien15 Oct '07 - 22:32 
hello
you should add the RibbonMenuButton.cs into the SolutionExplorer, then reset it.
QuestionImage clippingmemberjoncle12312 Aug '07 - 7:50 
Hi there,
 
Many thanks for this control; we need more people in the community that contribute stuff like this.
 
I'm sure this is trivial, but I'm not sure where to start. If I set an image for the button (which gets scaled down to fit quite nicely), which has a radius of 25, the top left of it gets 'rounded' correctly; however, the top right remains rectangular. I'd send you a screen shot, but I'm not sure how on this thing.
 
Any suggestions, or further clarification by me, please let me know.
 
Many thanks again,
 
Jon.
 
The words of the prophets are written on the subway walls...
GeneralCPU problemsmemberRoey C4 Aug '07 - 11:05 
hi, first of all, this project is great and the look and feel is very professional.
but! when you're working on graphics, thing that takes a lot of cpu power you have to make a close look on the performances issues.
 
i saw that the worst problem with your code is that when you start timers, you refresh the controls even if it's not needed. this thing is simple to solve, here are two methods:
1. refresh it only if the painting parameters has changed.
2. stop the timer when the colors transformations has been completed.
 
i would go on to 2, since it's more elegant and frugal.
 
i hope you make a new release with fixed peroformance.
 
Roey

 
Don't believe to what you hear on the news...

GeneralRe: CPU problemsmemberRoey C4 Aug '07 - 11:07 
one more thing, i was talking about you're reounded buttons...
Smile | :)
 
Don't believe to what you hear on the news...

QuestionIsPressed = true paint bug [modified]memberalleph26 Jul '07 - 9:51 
it's not paint the ribbonbutton at the begining when its IsPressed property is set true and that's the solution;
 

protected override void OnCreateControl()
{
base.OnCreateControl();
.......
if (_keeppress && _ispressed) this.UpdateEnter();//Add this line into this Method.
}
 
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
UpdateEnter();//Extracted Method Calling
}
 
//This method extracted from the OnMouseEnter method
public void UpdateEnter()
{
_colorStroke = ColorOnStroke;
_tempshowbase = _showbase;
_showbase = e_showbase.Yes;
i_mode = 1;
xmouse = PointToClient(Cursor.Position).X;
mouse = true;
A0 = 200;
if (i_factor == 0)
{
R0 = _onColor.R; G0 = _onColor.G; B0 = _onColor.B;
}
timer1.Start();
}

 

-- modified at 19:23 Thursday 26th July, 2007
 
Ismail SEZEN
Physicist

QuestionBug?memberjdem26 Jul '07 - 5:33 
Hi
 
very very nice Button. I think I found a small bug. When you set the ImageLocation to "Left", SplitButton to "Yes" and the Arrow to "ToDown" and then klick on the part of the Button which should open the context menu I ve geht an exception.
 
The problem ist in file "RibbonMenuButton.cs" in the "ClickSplit" region. I think this
 
if (_arrow == e_arrow.ToDown)
{
if (this.ContextMenuStrip != null)
this.ContextMenuStrip.Opacity = 1.0;
this.ContextMenuStrip.Show(this, 0, this.Height);
}
 
has to be this
 
if (_arrow == e_arrow.ToDown)
{
if (this.ContextMenuStrip != null)
{
this.ContextMenuStrip.Opacity = 1.0;
this.ContextMenuStrip.Show(this, 0, this.Height);
}
}
 
Best regards,
Bastian
Generalabout Office 2007 UI Licencememberalleph24 Jul '07 - 21:43 
Altough My English is not very well, I read an article about Office 2007 UI Licensing and I wonder whether or not it's possible to use this nice-look buttons on our products without Office 2007 UI Licence? Microsoft suggests some guidelines how to implement a ribbon controls as office 2007 UI style. But this ribbon buttons are made without this guideline. Anybody can give more explanation about this issue? below some links about this subject.
Licensing the 2007 Microsoft Office User Interface
Office 2007 UI License
 
Ismail SEZEN
Physicist

AnswerRe: about Office 2007 UI LicencememberPraded5 Aug '07 - 3:26 
If you're interested, that had been already discussed on other article of Juan Pablo about Ribbon Form and Round button

Generalmistake ,deadlinessmemberqingtianyu911 Jul '07 - 19:43 
I set attribute Radius = 0 (default : 6),then report mistake,deadliness
Generalthe code..memberSeishin#19 Jun '07 - 5:00 
Hi!
first of all i'd like you to know that your control looks really great. all this stuff like split button, group pos is really cool..
but when i look at the code hell begins..
 
public enum e_splitbutton
{
No, Yes
}
isn't this something like bool but more memory consuming??
public enum e_showbase
{
Yes, No
}
...
set { _showbase = value; this.Refresh(); }i guess Invalidate() would be more appropriate
if (A + A0 > 255) { A = 255; } else { A = A + A0; }A = Math.Min(255, A + A0); just look better..
xmouse = PointToClient(Cursor.Position).X;
ymouse = PointToClient(Cursor.Position).Y;
xmouse and ymouse could be a Point.. and you call PointToClient(Cursor.Position) twice :/..
 
and so on..
on my machine (Sempron3000+ 1GiB DDR400) with 7 buttons when hovering cpu goes up to 80%...
the title of your article is "Improved and Recoded RibbonMenuButton".. man.. i wonder how it looked before..
 
my suggestion - work on the performance of the button, because as I said, it looks just great!!

 
life is study!!!

GeneralRe: the code.. [modified]memberMario M.16 Sep '07 - 5:15 
It also has a bug in click handling, when you click a ribbonbutton which opens a dialog, then you close that dialog the button sends the message again and it opens the dialog again, you close that dialog again and then it sends the message to it's parent too.
 

GeneralIconsmembershawn3219 Jun '07 - 2:31 
this control is great. May I ask where you got your icon library?
 

 
-Shawn
GeneralRe: IconsmemberJuan Pablo G.C.19 Jun '07 - 4:20 
Of course, is one the unofficial tango icons library from gnome
 
Juan Pablo G.C.
Overrider Blog
 

GeneralCustomer Border Formmembercdemez11 Jun '07 - 21:34 
Take a look at :
 
http://www.codeplex.com/CustomerBorderForm
 
Why not integrate with this library, at least for the form.
 
Wink | ;-)
 
Krys

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 5 Jun 2007
Article Copyright 2007 by Juan Pablo G.C.
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid