Files
2017-05-30 22:09:10 +08:00

338 lines
11 KiB
C++

#include "StdAfx.h"
#include "UISlider.h"
namespace DuiLib
{
CSliderUI::CSliderUI() : m_uButtonState(0), m_nStep(1),m_bSendMove(false)
{
m_uTextStyle = DT_SINGLELINE | DT_CENTER;
m_szThumb.cx = m_szThumb.cy = 10;
}
LPCTSTR CSliderUI::GetClass() const
{
return _T("SliderUI");
}
UINT CSliderUI::GetControlFlags() const
{
if( IsEnabled() ) return UIFLAG_SETCURSOR;
else return 0;
}
LPVOID CSliderUI::GetInterface(LPCTSTR pstrName)
{
if( _tcscmp(pstrName, DUI_CTR_SLIDER) == 0 ) return static_cast<CSliderUI*>(this);
return CProgressUI::GetInterface(pstrName);
}
void CSliderUI::SetEnabled(bool bEnable)
{
CControlUI::SetEnabled(bEnable);
if( !IsEnabled() ) {
m_uButtonState = 0;
}
}
int CSliderUI::GetChangeStep()
{
return m_nStep;
}
void CSliderUI::SetChangeStep(int step)
{
m_nStep = step;
}
void CSliderUI::SetThumbSize(SIZE szXY)
{
m_szThumb = szXY;
}
RECT CSliderUI::GetThumbRect() const
{
if( m_bHorizontal ) {
int left = m_rcItem.left + (m_rcItem.right - m_rcItem.left - m_szThumb.cx) * (m_nValue - m_nMin) / (m_nMax - m_nMin);
int top = (m_rcItem.bottom + m_rcItem.top - m_szThumb.cy) / 2;
return CDuiRect(left, top, left + m_szThumb.cx, top + m_szThumb.cy);
}
else {
int left = (m_rcItem.right + m_rcItem.left - m_szThumb.cx) / 2;
int top = m_rcItem.bottom - m_szThumb.cy - (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy) * (m_nValue - m_nMin) / (m_nMax - m_nMin);
return CDuiRect(left, top, left + m_szThumb.cx, top + m_szThumb.cy);
}
}
LPCTSTR CSliderUI::GetThumbImage() const
{
return m_sThumbImage;
}
void CSliderUI::SetThumbImage(LPCTSTR pStrImage)
{
m_sThumbImage = pStrImage;
Invalidate();
}
LPCTSTR CSliderUI::GetThumbHotImage() const
{
return m_sThumbHotImage;
}
void CSliderUI::SetThumbHotImage(LPCTSTR pStrImage)
{
m_sThumbHotImage = pStrImage;
Invalidate();
}
LPCTSTR CSliderUI::GetThumbPushedImage() const
{
return m_sThumbPushedImage;
}
void CSliderUI::SetThumbPushedImage(LPCTSTR pStrImage)
{
m_sThumbPushedImage = pStrImage;
Invalidate();
}
void CSliderUI::SetValue(int nValue) //2014.7.28 redrain 当鼠标正在滑动滑块时不会收到SetValue的影响,比如滑动改变音乐的进度,不会因为外部一直调用SetValue而让我们无法滑动滑块
{
if( (m_uButtonState & UISTATE_CAPTURED) != 0 )
return;
CProgressUI::SetValue(nValue);
}
void CSliderUI::DoEvent(TEventUI& event)
{
if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
if( m_pParent != NULL ) m_pParent->DoEvent(event);
else CProgressUI::DoEvent(event);
return;
}
if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
{
if( IsEnabled() ) {//2014.7.28 redrain 注释掉原来的代码,加上这些代码后可以让Slider不是在鼠标弹起时才改变滑块的位置
m_uButtonState |= UISTATE_CAPTURED;
int nValue;
if( m_bHorizontal ) {
if( event.ptMouse.x >= m_rcItem.right - m_szThumb.cx / 2 ) nValue = m_nMax;
else if( event.ptMouse.x <= m_rcItem.left + m_szThumb.cx / 2 ) nValue = m_nMin;
else nValue = m_nMin + (m_nMax - m_nMin) * (event.ptMouse.x - m_rcItem.left - m_szThumb.cx / 2 ) / (m_rcItem.right - m_rcItem.left - m_szThumb.cx);
}
else {
if( event.ptMouse.y >= m_rcItem.bottom - m_szThumb.cy / 2 ) nValue = m_nMin;
else if( event.ptMouse.y <= m_rcItem.top + m_szThumb.cy / 2 ) nValue = m_nMax;
else nValue = m_nMin + (m_nMax - m_nMin) * (m_rcItem.bottom - event.ptMouse.y - m_szThumb.cy / 2 ) / (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy);
}
if(m_nValue !=nValue && nValue>=m_nMin && nValue<=m_nMax)
{
m_nValue =nValue;
Invalidate();
}
}
return;
}
// if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
// {
// if( IsEnabled() ) {
// RECT rcThumb = GetThumbRect();
// if( ::PtInRect(&rcThumb, event.ptMouse) ) {
// m_uButtonState |= UISTATE_CAPTURED;
// }
// }
// return;
// }
if( event.Type == UIEVENT_BUTTONUP )
{
int nValue;
if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
m_uButtonState &= ~UISTATE_CAPTURED;
}
if( m_bHorizontal ) {
if( event.ptMouse.x >= m_rcItem.right - m_szThumb.cx / 2 ) nValue = m_nMax;
else if( event.ptMouse.x <= m_rcItem.left + m_szThumb.cx / 2 ) nValue = m_nMin;
else nValue = m_nMin + (m_nMax - m_nMin) * (event.ptMouse.x - m_rcItem.left - m_szThumb.cx / 2 ) / (m_rcItem.right - m_rcItem.left - m_szThumb.cx);
}
else {
if( event.ptMouse.y >= m_rcItem.bottom - m_szThumb.cy / 2 ) nValue = m_nMin;
else if( event.ptMouse.y <= m_rcItem.top + m_szThumb.cy / 2 ) nValue = m_nMax;
else nValue = m_nMin + (m_nMax - m_nMin) * (m_rcItem.bottom - event.ptMouse.y - m_szThumb.cy / 2 ) / (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy);
}
if(/*m_nValue !=nValue && 2014.7.28 redrain 这个注释很关键,是他导致了鼠标拖动滑块无法发出DUI_MSGTYPE_VALUECHANGED消息*/nValue>=m_nMin && nValue<=m_nMax)
{
m_nValue =nValue;
m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED);
Invalidate();
}
return;
}
if( event.Type == UIEVENT_CONTEXTMENU )
{
return;
}
if( event.Type == UIEVENT_SCROLLWHEEL )
{
switch( LOWORD(event.wParam) ) {
case SB_LINEUP:
SetValue(GetValue() + GetChangeStep());
m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED);
return;
case SB_LINEDOWN:
SetValue(GetValue() - GetChangeStep());
m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED);
return;
}
}
if( event.Type == UIEVENT_MOUSEMOVE )
{
if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {//2014.7.28 redrain 重写这个消息判断让Slider发出DUI_MSGTYPE_VALUECHANGED_MOVE消息,让他在滑动过程也发出消息,比如用在改变音量时,一边滑动就可以一边改变音量
if( m_bHorizontal ) {
if( event.ptMouse.x >= m_rcItem.right - m_szThumb.cx / 2 ) m_nValue = m_nMax;
else if( event.ptMouse.x <= m_rcItem.left + m_szThumb.cx / 2 ) m_nValue = m_nMin;
else m_nValue = m_nMin + (m_nMax - m_nMin) * (event.ptMouse.x - m_rcItem.left - m_szThumb.cx / 2 ) / (m_rcItem.right - m_rcItem.left - m_szThumb.cx);
}
else {
if( event.ptMouse.y >= m_rcItem.bottom - m_szThumb.cy / 2 ) m_nValue = m_nMin;
else if( event.ptMouse.y <= m_rcItem.top + m_szThumb.cy / 2 ) m_nValue = m_nMax;
else m_nValue = m_nMin + (m_nMax - m_nMin) * (m_rcItem.bottom - event.ptMouse.y - m_szThumb.cy / 2 ) / (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy);
}
if (m_bSendMove)
m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED_MOVE);
Invalidate();
}
// Generate the appropriate mouse messages
POINT pt = event.ptMouse;
RECT rcThumb = GetThumbRect();
if( IsEnabled() && ::PtInRect(&rcThumb, event.ptMouse) ) {
m_uButtonState |= UISTATE_HOT;
Invalidate();
}else
{
m_uButtonState &= ~UISTATE_HOT;
Invalidate();
}
return;
}
// if( event.Type == UIEVENT_MOUSEMOVE )
// {
// if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
// if( m_bHorizontal ) {
// if( event.ptMouse.x >= m_rcItem.right - m_szThumb.cx / 2 ) m_nValue = m_nMax;
// else if( event.ptMouse.x <= m_rcItem.left + m_szThumb.cx / 2 ) m_nValue = m_nMin;
// else m_nValue = m_nMin + (m_nMax - m_nMin) * (event.ptMouse.x - m_rcItem.left - m_szThumb.cx / 2 ) / (m_rcItem.right - m_rcItem.left - m_szThumb.cx);
// }
// else {
// if( event.ptMouse.y >= m_rcItem.bottom - m_szThumb.cy / 2 ) m_nValue = m_nMin;
// else if( event.ptMouse.y <= m_rcItem.top + m_szThumb.cy / 2 ) m_nValue = m_nMax;
// else m_nValue = m_nMin + (m_nMax - m_nMin) * (m_rcItem.bottom - event.ptMouse.y - m_szThumb.cy / 2 ) / (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy);
// }
// Invalidate();
// }
// return;
// }
if( event.Type == UIEVENT_SETCURSOR )
{
RECT rcThumb = GetThumbRect();
if( IsEnabled()) {
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)));
return;
}
}
// if( event.Type == UIEVENT_SETCURSOR )
// {
// RECT rcThumb = GetThumbRect();
// if( IsEnabled() && ::PtInRect(&rcThumb, event.ptMouse) ) {
// ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)));
// return;
// }
// }
if( event.Type == UIEVENT_MOUSEENTER )
{//2014.7.28 redrain 只有鼠标在滑块的范围内才变为UISTATE_HOT
// if( IsEnabled() ) {
// m_uButtonState |= UISTATE_HOT;
// Invalidate();
// }
// return;
}
if( event.Type == UIEVENT_MOUSELEAVE )
{
if( IsEnabled() ) {
m_uButtonState &= ~UISTATE_HOT;
Invalidate();
}
return;
}
CControlUI::DoEvent(event);
}
void CSliderUI::SetCanSendMove(bool bCanSend) //2014.7.28 redrain
{
m_bSendMove = bCanSend;
}
bool CSliderUI::GetCanSendMove() const //2014.7.28 redrain
{
return m_bSendMove;
}
void CSliderUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
if( _tcscmp(pstrName, _T("thumbimage")) == 0 ) SetThumbImage(pstrValue);
else if( _tcscmp(pstrName, _T("thumbhotimage")) == 0 ) SetThumbHotImage(pstrValue);
else if( _tcscmp(pstrName, _T("thumbpushedimage")) == 0 ) SetThumbPushedImage(pstrValue);
else if( _tcscmp(pstrName, _T("thumbsize")) == 0 ) {
SIZE szXY = {0};
LPTSTR pstr = NULL;
szXY.cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
szXY.cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
SetThumbSize(szXY);
}
else if( _tcscmp(pstrName, _T("step")) == 0 ) {
SetChangeStep(_ttoi(pstrValue));
}
else if( _tcscmp(pstrName, _T("sendmove")) == 0 ) {
SetCanSendMove(_tcscmp(pstrValue, _T("true")) == 0);
}
else CProgressUI::SetAttribute(pstrName, pstrValue);
}
void CSliderUI::PaintStatusImage(HDC hDC)
{
CProgressUI::PaintStatusImage(hDC);
RECT rcThumb = GetThumbRect();
rcThumb.left -= m_rcItem.left;
rcThumb.top -= m_rcItem.top;
rcThumb.right -= m_rcItem.left;
rcThumb.bottom -= m_rcItem.top;
if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
if( !m_sThumbPushedImage.IsEmpty() ) {
m_sImageModify.Empty();
m_sImageModify.SmallFormat(_T("dest='%d,%d,%d,%d'"), rcThumb.left, rcThumb.top, rcThumb.right, rcThumb.bottom);
if( !DrawImage(hDC, (LPCTSTR)m_sThumbPushedImage, (LPCTSTR)m_sImageModify) ) m_sThumbPushedImage.Empty();
else return;
}
}
else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
if( !m_sThumbHotImage.IsEmpty() ) {
m_sImageModify.Empty();
m_sImageModify.SmallFormat(_T("dest='%d,%d,%d,%d'"), rcThumb.left, rcThumb.top, rcThumb.right, rcThumb.bottom);
if( !DrawImage(hDC, (LPCTSTR)m_sThumbHotImage, (LPCTSTR)m_sImageModify) ) m_sThumbHotImage.Empty();
else return;
}
}
if( !m_sThumbImage.IsEmpty() ) {
m_sImageModify.Empty();
m_sImageModify.SmallFormat(_T("dest='%d,%d,%d,%d'"), rcThumb.left, rcThumb.top, rcThumb.right, rcThumb.bottom);
if( !DrawImage(hDC, (LPCTSTR)m_sThumbImage, (LPCTSTR)m_sImageModify) ) m_sThumbImage.Empty();
else return;
}
}
}