Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加对圆环形滚动条的支持 #105

Merged
merged 1 commit into from
Aug 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions bin/resources/themes/default/controls/controls.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@
<Slider class="slider_green" value="70" margin="10"/>
</HBox>
</VBox>
<VBox width="120">
<CircleProgress name="circleprogress" circular="true" height="80" width="80"
circlewidth="10" bgcolor="gray" fgcolor="green" clockwise="true" min="1" max="100" value="75" margin="10"
textpadding="10,32,10,10" normaltextcolor="darkcolor" indicator="logo_18x18.png"/>
</VBox>
</HBox>

<Control class="splitline_hor_level1"/>
<!-- RichEdit -->
<RichEdit class="prompt" name="edit" bkcolor="bk_wnd_lightcolor" width="stretch" height="stretch"
Expand Down
5 changes: 5 additions & 0 deletions samples/controls/controls_form.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,9 @@ void ControlForm::OnProgressValueChagned(float value)
{
auto progress = dynamic_cast<ui::Progress*>(FindControl(L"progress"));
progress->SetValue(value);
auto circleprogress = dynamic_cast<ui::Progress*>(FindControl(L"circleprogress"));
circleprogress->SetValue(value);
TCHAR szBuffer[32] = {0};
swprintf_s(szBuffer, _T("%.0f%%"), value);
circleprogress->SetText(szBuffer);
}
206 changes: 206 additions & 0 deletions tool_kits/duilib/Control/CircleProgress.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#include "stdafx.h"
#include "CircleProgress.h"
#include "shlwapi.h"

namespace ui
{
CircleProgress::CircleProgress() :
m_bCircular(true),
m_bClockwise(true),
m_nCircleWidth(1),
m_dwBackgroundColor(0),
m_dwForegroundColor(0),
m_dwGradientColor(0),
m_pIndicator(nullptr)
{

}

void CircleProgress::SetAttribute(const std::wstring& srName, const std::wstring& strValue)
{
if (srName == _T("circular")) SetCircular(strValue == _T("true"));
else if (srName == _T("circlewidth")) SetCircleWidth(_ttoi(strValue.c_str()));
else if (srName == _T("indicator")) SetIndicator(strValue);
else if (srName == _T("clockwise")) SetClockwiseRotation(strValue == _T("true"));
else if (srName == _T("bgcolor")) {
LPCTSTR pValue = strValue.c_str();
while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
SetBackgroudColor(pValue);
}
else if (srName == _T("fgcolor")) {
LPCTSTR pValue = strValue.c_str();
while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
SetForegroudColor(pValue);
}
else if (srName == _T("gradientcolor")) {
LPCTSTR pValue = strValue.c_str();
while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
SetCircleGradientColor(pValue);
}
else Progress::SetAttribute(srName, strValue);
}

void CircleProgress::PaintStatusImage(IRenderContext* pRender)
{
Progress::PaintStatusImage(pRender);
if (m_bCircular)
{
//ĿǰIRenderContext���кܶ�GDI+�ӿ�δʵ�֣���ʱֱ����gdi+��ͼ��
//�Ժ���ܻ��������ʵ��1��DrawArc 2��Pen����brush(����)��� 3��������������Graphics����
int direction = m_bClockwise ? 1 : -1; //��ת����
int bordersize = 1; //���ȿ���Ŀǰʹ��1����

Gdiplus::Graphics graphics(pRender->GetDC());
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
Gdiplus::Pen bgPen(m_dwBackgroundColor, m_nCircleWidth);
// Բ������
CPoint center;
center.x = m_rcItem.left + (m_rcItem.right - m_rcItem.left) / 2;
center.y = m_rcItem.top + (m_rcItem.bottom - m_rcItem.top) / 2;

// �ؼ������ڵ���������εı߽�
int side = min(m_rcItem.right - m_rcItem.left, m_rcItem.bottom - m_rcItem.top);
//UiRect rcBorder; ��Ȼ����UiRect �� RectF��ת��������ֱ����gdi��RectF��
Gdiplus::RectF rcBorder;
rcBorder.X = center.x - side / 2;
rcBorder.Y = center.y - side / 2;
rcBorder.Width = rcBorder.Height = side;

Gdiplus::RectF outer = rcBorder;
if (m_pIndicator) {
outer.Inflate(-1.0F *m_pIndicator->GetWidth() / 2, -1.0F * m_pIndicator->GetWidth() / 2);
}
else
{
outer.Inflate(-0.5 * m_nCircleWidth, -0.5 * m_nCircleWidth);
}
outer.Inflate(-1, -1);


if (m_dwGradientColor == 0)
{
//��ʹ�ý���ɫ��ֱ����ǰ��ɫ����
Gdiplus::Pen fgPen(m_dwForegroundColor, m_nCircleWidth);
graphics.DrawArc(&bgPen, outer, 270, 360); //270�������濪ʼ��������Ϊ0�Ļ��������ұ߿�ʼ
graphics.DrawArc(&fgPen, outer, 270, direction * 360 * (m_nValue - m_nMin) / (m_nMax - m_nMin));
}
else
{
Gdiplus::REAL factors[4] = { 0.0f, 0.4f, 0.6f, 1.0f };
Gdiplus::REAL positions[4] = { 0.0f, 0.2f, 0.8f, 1.0f };

Gdiplus::LinearGradientBrush lgbrush(rcBorder, m_dwForegroundColor, m_dwGradientColor, Gdiplus::LinearGradientModeVertical);
lgbrush.SetBlend(factors, positions, 4);
graphics.DrawArc(&bgPen, outer, 270, 360);
Gdiplus::Pen fgPen(&lgbrush, m_nCircleWidth);
graphics.DrawArc(&fgPen, outer, 270, direction * 360 * (m_nValue - m_nMin) / (m_nMax - m_nMin));

}

//����תָʾ��ͼ�꣬��Ҫ�õ�����
if (m_pIndicator)
{
Gdiplus::Matrix matrix;
matrix.RotateAt(direction * 360 * (m_nValue - m_nMin) / (m_nMax - m_nMin), Gdiplus::PointF(center.x, center.y), Gdiplus::MatrixOrderAppend);
graphics.SetTransform(&matrix);
Gdiplus::RectF rectf;
rectf.X = center.x - m_pIndicator->GetWidth() / 2;
rectf.Y = outer.Y + bordersize / 2 -m_pIndicator->GetHeight() / 2;
rectf.Width = m_pIndicator->GetWidth();
rectf.Height = m_pIndicator->GetHeight();
graphics.DrawImage(m_pIndicator, rectf);
}

}
}

void CircleProgress::ClearImageCache()
{
__super::ClearImageCache();
if (m_pIndicator)
{
delete m_pIndicator;
m_pIndicator = nullptr;
}
}



void CircleProgress::SetCircular(bool bCircular /*= true*/)
{
m_bCircular = bCircular;
Invalidate();
}


void CircleProgress::SetClockwiseRotation(bool bClockwise /*= true*/)
{
if (bClockwise != m_bClockwise)
{
m_bClockwise = bClockwise;
if (m_pIndicator)
{
//�Ѿ���ת��ͼƬ����ת���෴�ķ���
m_pIndicator->RotateFlip(Gdiplus::Rotate180FlipNone);
}

}
}

void CircleProgress::SetCircleWidth(int nCircleWidth)
{
m_nCircleWidth = nCircleWidth;
Invalidate();
}


void CircleProgress::SetBackgroudColor(const std::wstring& strColor)
{
m_dwBackgroundColor = GlobalManager::GetTextColor(strColor);
ASSERT(m_dwBackgroundColor != 0);
Invalidate();
}

void CircleProgress::SetForegroudColor(const std::wstring& strColor)
{
m_dwForegroundColor = GlobalManager::GetTextColor(strColor);
ASSERT(m_dwForegroundColor != 0);
Invalidate();
}

void CircleProgress::SetIndicator(const std::wstring& sIndicatorImage)
{
if (m_sIndicatorImage != sIndicatorImage)
{
m_sIndicatorImage = sIndicatorImage;
if (m_pIndicator)
{
delete m_pIndicator;
m_pIndicator = nullptr;
}
std::wstring imagepath = m_sIndicatorImage;
if (!::PathFileExistsW(imagepath.c_str())) {
imagepath = GlobalManager::GetResourcePath() + m_pWindow->GetWindowResourcePath() + imagepath;
}
if (!::PathFileExistsW(imagepath.c_str())) {
return;
}
m_pIndicator = new Gdiplus::Image(imagepath.c_str());

Gdiplus::Status state = m_pIndicator->GetLastStatus();
if (Gdiplus::Ok == state)
{
// �ٶ�ͼƬָ����
m_pIndicator->RotateFlip(m_bClockwise ? Gdiplus::Rotate90FlipNone : Gdiplus::Rotate270FlipNone);
Invalidate();
}
}
}

void CircleProgress::SetCircleGradientColor(const std::wstring& strColor)
{
m_dwGradientColor = GlobalManager::GetTextColor(strColor);
ASSERT(m_dwGradientColor != 0);
Invalidate();
}
}
84 changes: 84 additions & 0 deletions tool_kits/duilib/Control/CircleProgress.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/** @file CircleProgress.h
* @brief Բ���͹������ؼ���Բ���м�������ı�����85%��
* @copyright (c) 2019-2022, NetEase Inc. All rights reserved
* @author Xuhuajie
* @date 2019/8/14
*/

#ifndef UI_CONTROL_CIRCLEPROGRESS_H_
#define UI_CONTROL_CIRCLEPROGRESS_H_

#pragma once

namespace ui
{

class UILIB_API CircleProgress : public Progress
{
public:
CircleProgress();

/// ��д���෽�����ṩ���Ի����ܣ���ο���������
virtual void SetAttribute(const std::wstring& strName, const std::wstring& strValue) override;
virtual void PaintStatusImage(IRenderContext* pRender) override;
virtual void ClearImageCache() override;

/**
* @brief ����Բ�ι�����
* @param[in] bCircular Ϊ true ʱ����ΪԲ�ι�������false ʱ����Ϊ������������Ĭ��Ϊ true
* @return ��
*/
void SetCircular(bool bCircular = true);
/**
* @brief ���õ�������
* @param[in] bClockwise Ϊ true ʱ����Ϊ˳ʱ�룬false ʱ����Ϊ��ʱ�룬Ĭ��Ϊ true
* @return ��
*/
void SetClockwiseRotation(bool bClockwise = true);
/**
* @brief ����Բ������
* @param[in] nCircleWidth ������ֵ
* @return ��
*/
void SetCircleWidth(int nCircleWidth);
/**
* @brief ���ý�����������ɫ
* @param[in] strColorҪ���õı�����ɫ�ַ��������ַ��������� global.xml �д���
* @return ��
*/
void SetBackgroudColor(const std::wstring& strColor);
/**
* @brief ���ý�����ǰ����ɫ
* @param[in] strColorҪ���õ�ǰ����ɫ�ַ��������ַ��������� global.xml �д���
* @return ��
*/
void SetForegroudColor(const std::wstring& strColor);
/**
* @brief ���ý�����ǰ��������ɫ����ForegroudColorͬʱʹ�ã����Բ�����,���޽���Ч��
* @param[in] strColorҪ���õ�ǰ��������ɫ�ַ��������ַ��������� global.xml �д���
* @return ��
*/
void SetCircleGradientColor(const std::wstring& strColor);
/**
* @brief ���ý���ָʾ�ƶ�ͼ��
* @param[in] sIndicatorImageҪ���õ�ͼƬ
* @return ��
*/
void SetIndicator(const std::wstring& sIndicatorImage);

protected:
bool m_bCircular;
bool m_bClockwise;
int m_nCircleWidth;
DWORD m_dwBackgroundColor;
DWORD m_dwForegroundColor;
DWORD m_dwGradientColor;
//Image m_IndicatorImage; //ʹ��image�����޷�����������Ҫ���þ���任
Gdiplus::Image* m_pIndicator; //����Ŀǰά����Դ����
std::wstring m_sIndicatorImage;

};

} // namespace ui

#endif // UI_CONTROL_CIRCLEPROGRESS_H_
1 change: 1 addition & 0 deletions tool_kits/duilib/Core/Define.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ EventType StringToEnum(const std::wstring& messageType);
#define DUI_CTR_COMBO (_T("Combo"))
#define DUI_CTR_SLIDER (_T("Slider"))
#define DUI_CTR_PROGRESS (_T("Progress"))
#define DUI_CTR_CIRCLEPROGRESS (_T("CircleProgress"))
#define DUI_CTR_SCROLLBAR (_T("ScrollBar"))

}// namespace ui
Expand Down
1 change: 1 addition & 0 deletions tool_kits/duilib/Core/WindowBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ Control* WindowBuilder::CreateControlByClass(const std::wstring& strControlClass
break;
case 14:
if (strControlClass == DUI_CTR_VIRTUALLISTBOX) pControl = new VirtualListBox;
else if (strControlClass == DUI_CTR_CIRCLEPROGRESS) pControl = new CircleProgress;
break;
case 15:
break;
Expand Down
1 change: 1 addition & 0 deletions tool_kits/duilib/UIlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
#include "Control/Option.h"

#include "Control/Progress.h"
#include "Control/CircleProgress.h"
#include "Control/Slider.h"

#include "Control/RichEdit.h"
Expand Down
Loading