Click here to Skip to main content
15,881,281 members
Articles / Programming Languages / C#

MediaSlider - An Alternative to the Trackbar Control - v1.3

Rate me:
Please Sign up or sign in to vote.
4.94/5 (60 votes)
28 Mar 2010CPOL5 min read 168.1K   14.5K   145   61
A fully featured animated trackbar control
MediaSlider

Anatomy of a Button

Rather than throw some boring code at you (and nobody reads that anyways...), I thought I'd lend some insight into how I constructed the visual styles used in this control..

The first thing I do, and I mean the very first step in the process, is to get a good idea of what you need from the usercontrol, and some idea of what you want the completed control to look like. I often browse wincustomize.com or professional control makers websites to get a feel for possible features and UI cues, also, look at windows/mac, and try to imagine how they created those graphics, and even how they might be improved upon.

The next step is to get the framework of the control up and running. Create the usercontrol, add all the basic functionality to it, and try to create a simple and problem free framework to work with. This is how I started with this slider, it wasn't until I had all of the basic functionality working that I started to write the graphics code. Throughout this process, it is important to keep everything as well organized as possible. One of the features I like best about .NET is the #region directive. It allows you to compartmentalize and organize large classes and methods into manageable chunks. Also I'd recommend using private properties or constants for internal measurements, as the code grows more complex, the likelihood that hard coded numbers will need to change becomes increasingly more likely. This is something I ran into when writing the Autosize feature of this control; because some numbers were coded in a method, a mistake caused me to waste an hour tracking down a problem.

Drawing a Glossy Button..

The first step is to fill the button with a solid backcolor. This is to ensure that if using transparent colors, the button will remain solid. Use white if you are using semi transparent colors and want a glow effect, otherwise use the button base color:

anatomy1.jpg

You can see from the above image that the button is out of scale. I do this so that subtleties of the gradient shadings are obvious. You can also see this is just a plain black border with a white fill, this is just the canvas before the addition of three gradients:

anatomy2.jpg

The first gradient is a vertical linear gradient with a blend factor using a translucent white at 180 alpha, fading into the button base color at the center. This gives the appearance of shape, that the button is protruding from a flat surface.

C#
using (GraphicsPath gp = new GraphicsPath())
{
    gp.AddEllipse(buttonRect);
    // fill with base color
    using (Brush br = new SolidBrush(Color.FromArgb(255, this.ButtonColor)))
        g.FillPath(br, gp);
    // add top sheen
    using (LinearGradientBrush fillBrush = new LinearGradientBrush(
        buttonRect,
        Color.FromArgb(180, Color.White),
        this.ButtonColor,
        LinearGradientMode.Vertical))
    {
        Blend blnd = new Blend();
        blnd.Positions = new float[] { 0f, .1f, .2f, .3f, .6f, 1f };
        blnd.Factors = new float[] { .2f, .3f, .4f, .5f, 1f, 1f };
        fillBrush.Blend = blnd;
        g.FillPath(fillBrush, gp);
    }

anatomy3.jpg

I also wanted a glow coming from underneath using an accent color, similar to the MediaPlayer buttons. The accent color is user definable, meaning that you can go from a subtle to a very pronounced effect. Though these images show you the property colors for the button on a white background, while designing them, I used the colors red and white on a black background. This gives you a much better sense of how the gradients are interacting. The bottom glow was made by adding a new ellipse to the graphics path, and pushing it to the bottom of the button and drawing it with a PathGradientBrush:

C#
// add the bottom glow
using (PathGradientBrush borderBrush = new PathGradientBrush(gp))
{
    using (GraphicsPath ga = new GraphicsPath())
    {
        accentRect.Inflate(0, (int)-(accentRect.Height * .2f));
        accentRect.Offset(0, (int)(ButtonSize.Width * .2f));
        ga.AddEllipse(accentRect);
        // center focus
        fx = accentRect.Width * .5f;
        fy = accentRect.Height * 1f;
        borderBrush.CenterColor = this.ButtonColor;
        borderBrush.SurroundColors = new Color[] { this.ButtonAccentColor };
        borderBrush.FocusScales = new PointF(1f, 0f);
        borderBrush.CenterPoint = new PointF(fx, fy);
        g.FillPath(borderBrush, ga);
    }

anatomy4.jpg

This last gradient adds a spotilght effect at about 300 degrees to the top of the button, making it seem like the light source is to the top left of the button image.

C#
// spotight offsets
fx = buttonRect.Width * .2f;
fy = buttonRect.Height * .05f;
// draw the spotlight
borderBrush.CenterColor = Color.FromArgb(120, Color.White);
 borderBrush.SurroundColors = new Color[] { Color.FromArgb(5, Color.Silver) };
borderBrush.FocusScales = new PointF(.2f, .2f);
borderBrush.CenterPoint = new PointF(fx, fy);
g.FillPath(borderBrush, gp);

This might all seem like a lot of effort for such a small button, but I think the details are important, and if anything, the button graphics could be made even more intricate. Also note that all of the button styles are actually rendered onto a Bitmap, created once, and require only a single DrawImage command to render. Otherwise this would not be flicker free..

anatomy5.jpg

Properties

I wanted most aspects of this to be modifiable, so left many of the properties open to customization:

  • Animated Run the animation effect when focused
  • AnimationSpeed Animation cycle speed [Fast Normal Slow]
  • AnimationSize Percentage of size of sprite width to track width [min .05 - max .2]
  • BackGroundImage Use an image for the slider background
  • ButtonAccentColor Modify button accent color
  • ButtonBorderColor Modify button border color
  • ButtonColor Modify button base color
  • ButtonCornerRadius Adjusts the slider buttons corner radius
  • ButtonSize Modify slider button size
  • ButtonStyle Set the button style [Round RoundedRectOverlap RoundedRectInline Hybrid PointerUpLeft PointerDownRight GlassInline GlassOverlap]
  • IsInited Returns the control's initialized state
  • LargeChange The number of clicks the slider moves in response to mouse clicks or pageup/pagedown
  • Maximum The maximum value for the position of the slider
  • MaxSize The maximum Size value for the control [private set]
  • Minimum The minimum value for the position of the slider
  • MinSize The minimum Size value for the control [private set]
  • Orientation The orientation of the control
  • PrecisionValue Returns the slider position to a floating point, requires SmoothScrolling set to true
  • SmallChange The number of positions the slider movers in response to arrow keys
  • SmoothScrolling Enable smooth scrolling style
  • Value The position of the slider
  • ShowButtonOnHover Show the slider button only when control is focused or mouse is hovering
  • SliderFlyOut Enable the flyout caption window [None OnFocus Persistant]
  • TickColor Modify slider tick color
  • TickStyle Select the tickstyle
  • TickType Select the tick drawing style
  • TrackBorderColor Modify slider border color
  • TrackDepth Adjust the slider track depth
  • TrackFillColor Set the track backcolor
  • TrackProgressColor Set the track backcolor
  • TrackShadow Enable track shadow
  • TrackShadowColor Modify track shadow color
  • TrackStyle The display style of track [Progress Value]

Styles

Some of the hilites:

Precision Style
precision.jpg
Round

trackshadow.jpg

RoundedRect

rect-inline.jpg

Glass

glass-over2.jpg

WMC Clone with Flyout Caption

flyout.jpg

WMP Clone with Focused Animation

animation.jpg

Caption Toolbar

toolbar.jpg

If you're running Aero, the toolbars in the caption area probably caught your notice... It's a good example of how to use this (why clutter up the demo form?).

It's all portable, just copy the ExtendFrame region's contents, update your directives and call the ExtendMargin method as in the example, or see my article on the subject.

License

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


Written By
Network Administrator vtdev.com
Canada Canada
Network and programming specialist. Started in C, and have learned about 14 languages since then. Cisco programmer, and lately writing a lot of C# and WPF code, (learning Java too). If I can dream it up, I can probably put it to code. My software company, (VTDev), is on the verge of releasing a couple of very cool things.. keep you posted.

Comments and Discussions

 
GeneralRe: some calculation issues Pin
John Underhill16-Feb-10 10:25
John Underhill16-Feb-10 10:25 
GeneralBug fix Pin
John Underhill15-Feb-10 6:14
John Underhill15-Feb-10 6:14 
GeneralRe: Bug fix Pin
WoleTall18-Feb-10 5:48
WoleTall18-Feb-10 5:48 
GeneralRe: Bug fix Pin
WoleTall18-Feb-10 17:32
WoleTall18-Feb-10 17:32 
GeneralRe: Bug fix Pin
John Underhill20-Feb-10 5:57
John Underhill20-Feb-10 5:57 
GeneralRe: Bug fix - Code correction Pin
John Underhill26-Feb-10 10:03
John Underhill26-Feb-10 10:03 
GeneralLast update Pin
John Underhill9-Feb-10 7:03
John Underhill9-Feb-10 7:03 
GeneralGreat Pin
Xmen Real 9-Feb-10 1:25
professional Xmen Real 9-Feb-10 1:25 
I love controls like this, have 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)JKQUFK[M`UKs*$GwU#QDXBER@CBN%
R0~53%eYrd8mt^7Z6]iTF+(EWfJ9zaK-i’TV.C\y<pŠjxsg-b$f4ia>

-----------------------------------------------
128 bit encrypted signature, crack if you can

GeneralNew version v1.1 Pin
John Underhill8-Feb-10 10:18
John Underhill8-Feb-10 10:18 
GeneralVery cool! Pin
Marcelo Ricardo de Oliveira7-Feb-10 22:15
Marcelo Ricardo de Oliveira7-Feb-10 22:15 
GeneralVERY NICE [modified] Pin
Johnny J.7-Feb-10 21:33
professionalJohnny J.7-Feb-10 21:33 
GeneralRe: VERY NICE [modified] Pin
Johnny J.8-Feb-10 0:11
professionalJohnny J.8-Feb-10 0:11 
GeneralRe: VERY NICE Pin
John Underhill8-Feb-10 8:26
John Underhill8-Feb-10 8:26 
GeneralRe: VERY NICE Pin
Johnny J.8-Feb-10 10:50
professionalJohnny J.8-Feb-10 10:50 
GeneralVery nice! Pin
fmaeseele7-Feb-10 21:10
fmaeseele7-Feb-10 21:10 
GeneralRe: Very nice! Pin
John Underhill8-Feb-10 8:28
John Underhill8-Feb-10 8:28 
GeneralRe: Very nice! Pin
fmaeseele9-Feb-10 1:20
fmaeseele9-Feb-10 1:20 
Generalsweet Pin
Don Kackman7-Feb-10 14:41
Don Kackman7-Feb-10 14:41 
GeneralNew version Pin
John Underhill7-Feb-10 13:11
John Underhill7-Feb-10 13:11 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.