//
// StyleProgress.cpp : Version 1.0 - see article at CodeProject.com
//
// Author: Darren Sessions
//
//
// Description:
// StyleProgress is a CProgressCtrl derived control that uses the Style class
// and GDI+ to support different styles
//
// History
// Version 1.0 - 2008 June 20
// - Initial public release
//
// License:
// This software is released under the Code Project Open License (CPOL),
// which may be found here: http://www.codeproject.com/info/eula.aspx
// You are free to use this software in any way you like, except that you
// may not sell this source code.
//
// This software is provided "as is" with no expressed or implied warranty.
// I accept no liability for any damage or loss of business that this
// software may cause.
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "StyleProgress.h"
StyleProgress::StyleProgress(void)
{
m_bCreated = FALSE;
// default gray
m_BackColor = RGB(0xC9, 0xC9, 0xC9);
// default green
m_ForeColor = RGB(0x00, 0xd3, 0x28);
m_Lower = 0;
m_Upper = 100;
m_Pos = 50;
m_Step = 5;
// default will step the bottom layer of the second stack
m_StepStackIdx = -1;
m_StepLayerIdx = 0;
m_StepLayerWidth = 0;
}
StyleProgress::~StyleProgress(void)
{
}
BEGIN_MESSAGE_MAP(StyleProgress, CProgressCtrl)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_WM_NCPAINT()
END_MESSAGE_MAP()
void StyleProgress::OnPaint()
{
CPaintDC dc(this); // device context for painting
// need to create if default
if(!m_bCreated) CreateDefaultStack();
m_Style.PaintStyle(&dc, m_ProgRect);
}
BOOL StyleProgress::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void StyleProgress::OnNcPaint()
{
// Needed to stop the base from painting the border
}
void StyleProgress::AddStack(Stack stack)
{
m_Style.AddStack(stack);
}
void StyleProgress::AddStepStack(Stack stack)
{
// this function must get called, so get m_ProgRect here
GetClientRect(m_ProgRect);
m_StepStackIdx = m_Style.AddStack(stack);
// default layer is zero - over ridden in SetStepLayer
m_StepLayerWidth = m_Style.m_Stacks[m_StepStackIdx].m_Layers[0].lrect.Width;
// the step layer needs to have its rect defined
// e.g. use the rect version FillSolid(rect, Blue) instead of FillSolid(Blue)
ASSERT(m_StepLayerWidth != 0);
m_bCreated = TRUE;
}
void StyleProgress:: SetStepLayer(int layerIdx)
{
// AddStepStack needs to be called before this funtion is called
ASSERT(m_StepStackIdx != -1);
m_StepLayerIdx = layerIdx;
m_StepLayerWidth = m_Style.m_Stacks[m_StepStackIdx].m_Layers[layerIdx].lrect.Width;
}
void StyleProgress::SetForeColor(COLORREF color, int Alpha)
{
m_ForeColor = color;
m_ForeAlpha = Alpha;
}
void StyleProgress::SetBackColor(COLORREF color, int Alpha)
{
m_BackColor = color;
m_BackAlpha = Alpha;
}
void StyleProgress::UpdateStack()
{
Rect frc, lrc; CRect crc;
float ratio; int width;
// AddStepStack needs to be called for 1 stack
ASSERT(m_StepStackIdx != -1);
// get the frame rect
frc = m_Style.m_Stacks[m_StepStackIdx].Frame.frect;
// calculate step position
ratio = float(m_Pos)/float(m_Upper - m_Lower);
width = (int)(ratio*m_StepLayerWidth);
// adjust the rects
frc.Width = width;
lrc.Width = width;
// set the new rects
m_Style.m_Stacks[m_StepStackIdx].Frame.frect = frc;
m_Style.m_Stacks[m_StepStackIdx].Regenerate(m_StepLayerIdx);
// need to regenerate any stacks above this one
for(int i = (m_StepStackIdx+1); i < (int)m_Style.m_Stacks.size(); i++)
{
m_Style.m_Stacks[i].Regenerate();
}
}
int StyleProgress::SetStep(int step)
{
if(step <= m_Upper)
{
m_Step = step;
}
return m_Step;
}
void StyleProgress::SetRange(int lower, int upper)
{
// negative range values not implemented
ASSERT(lower >= 0 && upper > 0);
if(upper > lower)
{
m_Upper = upper;
m_Lower = lower;
}
}
int StyleProgress::SetPos(int pos)
{
if (pos <= m_Lower) m_Pos = m_Lower;
else if (pos >= m_Upper) m_Pos = m_Upper;
else m_Pos = pos;
if(!m_bCreated) CreateDefaultStack();
UpdateStack();
Invalidate();
return m_Pos;
}
int StyleProgress::StepIt()
{
int newPos = m_Pos + m_Step;
if (m_Pos == m_Upper) m_Pos = m_Step;
else if (newPos > m_Upper) m_Pos = m_Upper;
else m_Pos = newPos;
if(m_bCreated)
{
UpdateStack();
Invalidate();
}
return m_Pos;
}
////////////////////////////////////////
/// DEFAULT PROGRESS CONTOL STACK //////
////////////////////////////////////////
void StyleProgress::CreateDefaultStack()
{
// define the rects
GetClientRect(m_ProgRect); CRect EffRect(m_ProgRect); CRect TopRect(m_ProgRect);
// some adustments
EffRect.DeflateRect(1, 1);
TopRect.DeflateRect(1, 1);
//=============== Background Layers ===================//
Stack ProgressBack(m_ProgRect, m_BackColor);
ProgressBack.SetShape(ROUNDRECT, 1);
ProgressBack.SetOuterBorder(1, RGB(0xB2, 0xB2, 0xB2));
ProgressBack.SetMiddleBorder(1, Clr(100,White));
ProgressBack.FillBar(EffRect, LEFT_EDGE, 8, Clr(40,Black), Clr(0,Black));
ProgressBack.FillBar(EffRect, RIGHT_EDGE, 8, Clr(0,Black), Clr(40,Black));
float btprof[3] = { 0.0f, 0.20f, 1.0f };
ProgressBack.FillBar(EffRect, TOP_EDGE, 6, Clr(200,White), Clr(241,White), Clr(40,White), btprof);
float bbprof[3] = { 0.0f, 0.80f, 1.0f };
ProgressBack.FillBar(EffRect, BOTTOM_EDGE, 6, Clr(0,White), Clr(100,White), Clr(80,White), bbprof);
//=========== Foreground Layers ======================//
Stack ProgressFront(TopRect);
ProgressFront.FillSolid(TopRect, m_ForeColor);
// top and bottom
float tprof[3] = { 0.0f, 0.15f, 1.0f };
ProgressFront.FillBar(TopRect, TOP_EDGE, 6, Clr(180,White), Clr(200,White), Clr(128,White), tprof);
ProgressFront.FillBar(TopRect, BOTTOM_EDGE, 6, Clr(0,White), Clr(100,White));
float lprof[3] = { 0.0f, 0.15f, 1.0f };
float rprof[3] = { 0.0f, 0.85f, 1.0f };
ProgressFront.FillBar(TopRect, LEFT_EDGE, 20, Clr(20,Black), Clr(40,Black), Clr(0,Black), lprof);
ProgressFront.FillBar(TopRect, RIGHT_EDGE, 20, Clr(0,Black), Clr(40,Black), Clr(20,Black), rprof);
// add it to the style
AddStack(ProgressBack);
AddStepStack(ProgressFront);
}