Progress bar like in Windows Media Player Topic is solved

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
Post Reply
User avatar
kolo
Earned some good credits
Earned some good credits
Posts: 120
Joined: Tue Jun 21, 2005 1:19 pm
Location: Russia, Cheboksary
Contact:

Progress bar like in Windows Media Player

Post by kolo » Wed Apr 19, 2006 9:35 am

I like how look progress bar in Windows Media Player 10, and wrote my own control like it. wmProgressBar control need some optimization for drawing - then value change fast, it blinking.

wmProgressBar.h

Code: Select all

#ifndef _WM_PROGRESS_BAR
#define _WM_PROGRESS_BAR

class wmProgressBar : public wxPanel
{
private:
	int curPercent;
	wxBitmap memBitmap;

	wmProgressBar();
	// event handlers
	void OnPaint(wxPaintEvent&);	
public: 
	wmProgressBar(wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = 
		wxDefaultPosition,const wxSize& size = wxDefaultSize,
		const wxString& name = "wmProgressBar");
	~wmProgressBar();

	void SetValue(int& value);
	int GetValue();

	DECLARE_EVENT_TABLE();
};

#endif
wmProgressBar.cpp

Code: Select all

#pragma warning( disable : 4996)
#pragma warning( disable : 4189)

#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "wmProgressBar.h"

wmProgressBar::wmProgressBar()
{
}

wmProgressBar::wmProgressBar(wxWindow *parent, wxWindowID id/* = -1*/,
							 const wxPoint &pos/* = wxDefaultPosition*/,
							 const wxSize &size/* = wxDefaultSize*/,
							 const wxString &name/* = "wmProgressBar"*/)
							 : wxPanel(parent, id, pos, size, wxTAB_TRAVERSAL, name)
{
	curPercent = 0;
	memBitmap = wxBitmap(size.GetWidth(), size.GetHeight());
}

wmProgressBar::~wmProgressBar()
{
}

void wmProgressBar::SetValue(int& value)
{
	if (value < 0 || value > 100) value = -1;
	else
	{
		curPercent = value;
		Refresh();
	}
}

inline int wmProgressBar::GetValue()
{
	return curPercent;
}


BEGIN_EVENT_TABLE(wmProgressBar, wxPanel)
	EVT_PAINT(wmProgressBar::OnPaint)
END_EVENT_TABLE()

void wmProgressBar::OnPaint(wxPaintEvent& event)
{
	wxPaintDC dc(this);

	wxSize size = GetSize();
	int width = size.GetWidth();
	int height = size.GetHeight();

	// set up colors, fonts, pens, etc.
	wxFont font = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);

	dc.BeginDrawing();

	// drawing borders
	dc.DrawRectangle(wxPoint(0, 0), size);
	
	dc.SetFont(font);

	// draw gradient colour area
	wxMemoryDC mdc;
	mdc.SelectObject(memBitmap);
	mdc.SetBrush(*wxWHITE);
	mdc.DrawRectangle(wxPoint(0, 0), wxSize(width, height));

	int grRed =99, grGreen = 255, grBlue = 56;
	int onePercentWidth = static_cast<int>(width / 100);
	for (int i = 0; i < curPercent; ++i)
	{
		wxColour gradientColour(grRed, grGreen, grBlue);

		wxPen grPen(gradientColour);
		wxBrush grBrush(gradientColour);

		mdc.SetPen(grPen);
		mdc.SetBrush(grBrush);

		mdc.DrawRectangle(wxPoint(onePercentWidth*i+1, 1), 
			wxSize(onePercentWidth, height-2));	

		grRed--;
		grGreen -= 2;
		if (i % 2) grBlue--;
	}
	dc.Blit(wxPoint(0,0), wxSize(width, height), &mdc, wxPoint(0,0));

	// draw progress bar current state
	int textW, textH;
	wxString percentString = wxString::Format("%i", curPercent) + '%';
	dc.GetTextExtent(percentString, &textW, &textH);

	int textX = static_cast<int>((width - textW)/2);
	int textY = static_cast<int>((height - textH)/2);
	dc.DrawText(percentString, wxPoint(textX, textY));

	dc.EndDrawing();

	event.Skip();
}
Enjoy it!
only MSW & MSVS ))

protocol
Moderator
Moderator
Posts: 680
Joined: Wed Jan 18, 2006 6:13 pm
Location: Dallas, TX
Contact:

Post by protocol » Wed Apr 19, 2006 2:03 pm

From what I can see...

Look into buffered dc.
check out: http://www.wxwidgets.org/manuals/2.6.3/ ... redpaintdc
You can replace some of you other wxDC use with the classes from the buffered paint realm.


example:
I wrote: Instead on every time they set the value:

Code: Select all

        wxSize size = GetSize();
        int width = size.GetWidth();
        int height = size.GetHeight();
You can call this when they actually resize the window.
--

Code: Select all

                grRed--;
pre-decrement (as you did in the FOR loop [save the temp variables])
--
If I think of anything else I let you know.
/* UIKit && wxWidgets 2.8 && Cocoa && .Net */
QuRegExmm
wxPCRE & ObjPCRE - Regex It!

priyank_bolia
wxWorld Domination!
wxWorld Domination!
Posts: 1339
Joined: Wed Aug 03, 2005 8:10 am
Location: BANGALORE, INDIA
Contact:

Post by priyank_bolia » Thu Apr 20, 2006 5:32 am

Any screenshot

CaptainMorgan
Earned a small fee
Earned a small fee
Posts: 22
Joined: Sun Jun 24, 2007 10:52 am

Post by CaptainMorgan » Fri Jun 29, 2007 7:42 am

priyank_bolia wrote:Any screenshot
That'd be cool....

carlo
Earned a small fee
Earned a small fee
Posts: 16
Joined: Sat Apr 04, 2009 12:43 am

Post by carlo » Sat Apr 04, 2009 12:54 am

great work! thanks for sharing it. oh and btw, sorry for the bump... but is there a way to reduce the flickering of it? (it just happens when I'm using SetValue in a loop (inrementing the counter...) is there a way to reduce the flickering? thanks

protocol
Moderator
Moderator
Posts: 680
Joined: Wed Jan 18, 2006 6:13 pm
Location: Dallas, TX
Contact:

Post by protocol » Sat Apr 04, 2009 7:22 am

carlo wrote:great work! thanks for sharing it. oh and btw, sorry for the bump... but is there a way to reduce the flickering of it? (it just happens when I'm using SetValue in a loop (inrementing the counter...) is there a way to reduce the flickering? thanks
Look into "double buffering" to prevent flickering.
/* UIKit && wxWidgets 2.8 && Cocoa && .Net */
QuRegExmm
wxPCRE & ObjPCRE - Regex It!

Post Reply