You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
4.0 KiB
161 lines
4.0 KiB
#include "stdafx.h"
|
|
#include "SSplitBar.h"
|
|
#include <layout\SouiLayoutParamStruct.h>
|
|
#include <layout\SouiLayout.h>
|
|
namespace SOUI
|
|
{
|
|
|
|
SSplitBar::SSplitBar():m_bDragging(FALSE)
|
|
,m_bResizeHostWnd(FALSE)
|
|
,m_nSizeMin(0)
|
|
,m_nSizeMax(0)
|
|
,m_bVertical(FALSE)
|
|
{
|
|
|
|
}
|
|
|
|
SSplitBar::~SSplitBar()
|
|
{
|
|
|
|
}
|
|
|
|
LRESULT SSplitBar::OnCreate( LPVOID )
|
|
{
|
|
if(0 != __super::OnCreate(NULL)) return 1;
|
|
ORIENTATION pi = m_bVertical ? Vert : Horz;
|
|
m_nOrginPos = GetLayoutParam()->GetSpecifiedSize(pi).toPixelSize(GetScale());
|
|
m_nTrackingPos = m_nOrginPos;
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL SSplitBar::OnSetCursor(const CPoint &pt)
|
|
{
|
|
HCURSOR hCursor=GETRESPROVIDER->LoadCursor(m_bVertical?IDC_SIZEWE:IDC_SIZENS);
|
|
SetCursor(hCursor);
|
|
return TRUE;
|
|
}
|
|
|
|
void SSplitBar::OnLButtonDown(UINT nFlags,CPoint pt)
|
|
{
|
|
SWindow::OnLButtonDown(nFlags, pt);
|
|
|
|
m_ptDragPrev = pt;
|
|
m_bDragging = TRUE;
|
|
}
|
|
|
|
void SSplitBar::OnLButtonUp(UINT nFlags,CPoint pt)
|
|
{
|
|
SWindow::OnLButtonUp(nFlags, pt);
|
|
|
|
m_bDragging = FALSE;
|
|
ORIENTATION pi = m_bVertical ? Vert : Horz;
|
|
m_nOrginPos = GetLayoutParam()->GetSpecifiedSize(pi).toPixelSize(GetScale());
|
|
m_nTrackingPos = m_nOrginPos;
|
|
}
|
|
|
|
void SSplitBar::OnMouseMove(UINT nFlags,CPoint pt)
|
|
{
|
|
SWindow::OnMouseMove(nFlags, pt);
|
|
|
|
static int nLastUpdateTicks = 0;
|
|
|
|
int now = GetTickCount();
|
|
if (now - nLastUpdateTicks < 30 || !m_bDragging)
|
|
{
|
|
return;
|
|
}
|
|
nLastUpdateTicks = now;
|
|
|
|
int nWindowOffset = 0;
|
|
int nOffset = 0;
|
|
|
|
// 计算两次鼠标的位置偏差
|
|
|
|
if (m_bVertical)
|
|
nOffset = pt.x - m_ptDragPrev.x;
|
|
else
|
|
nOffset = pt.y - m_ptDragPrev.y;
|
|
|
|
// 计算分隔栏新的位置
|
|
|
|
//SwndLayout * pLayout = GetLayout();
|
|
ORIENTATION pi = m_bVertical ? Vert : Horz;
|
|
SouiLayoutParamStruct* pLayout = (SouiLayoutParamStruct*)GetLayoutParamT<SouiLayoutParam>()->GetRawData();
|
|
|
|
int nNewPos = m_nOrginPos + nOffset * pLayout->posLeft.cMinus;
|
|
|
|
/*
|
|
* - 有一种情况要特殊处理:既要修改hostwnd的尺寸,top/left又是以-XXX的方式定义。
|
|
* 这里的逻辑比较复杂,我自己也搞得很晕@_@
|
|
*
|
|
* - 因为在需要修改宿主窗口的情况下,left/top如果以right/bottom为锚点,在修改了hostwnd的尺寸后,
|
|
* 不需要再修改位置信息,否则在逻辑上位置信息会被叠加计算。
|
|
* 举个例子:假如原始的y pos位置是-100,窗口的高度为300,此时y的位置是200(相对底部对齐)
|
|
* 拖动分隔条往上移动了5个px,如果位置信息被改成了-105,窗口减少了5px,变成了295。最后计算出来
|
|
* 的位置变成了190
|
|
*
|
|
* - 在这种情况下,不受maxsize和minisize的控制。因为分隔栏和bottom/right的相对位置不变,所以从
|
|
* 使用的角度讲,是没有超出 [maxsize,minisize] 的范围的
|
|
*/
|
|
|
|
HWND hWnd = GetContainer()->GetHostHwnd();
|
|
BOOL bZoomed = ::IsZoomed(hWnd);
|
|
BOOL bResizeWnd = m_bResizeHostWnd && !bZoomed;
|
|
if (!(bResizeWnd && pLayout->posLeft.cMinus < 0))
|
|
{
|
|
if (nNewPos > m_nSizeMax)
|
|
nNewPos = m_nSizeMax;
|
|
|
|
if (nNewPos < m_nSizeMin)
|
|
nNewPos = m_nSizeMin;
|
|
|
|
if (nNewPos == pLayout->posLeft.nPos.toPixelSize(100))
|
|
return;
|
|
|
|
pLayout->posLeft.nPos = nNewPos;
|
|
}
|
|
|
|
// 调整窗口
|
|
|
|
nWindowOffset = nNewPos - m_nTrackingPos;
|
|
nWindowOffset *= pLayout->posLeft.cMinus;
|
|
m_nTrackingPos = nNewPos;
|
|
|
|
if (bResizeWnd)
|
|
ResizeHostWindow(nWindowOffset);
|
|
else
|
|
RequestRelayout();
|
|
}
|
|
|
|
void SSplitBar::ResizeHostWindow(int nOffset)
|
|
{
|
|
if ( m_bResizeHostWnd && nOffset != 0)
|
|
{
|
|
HWND hWnd = GetContainer()->GetHostHwnd();
|
|
|
|
CRect rcWnd;
|
|
::GetWindowRect(hWnd, rcWnd);
|
|
|
|
if (m_bVertical)
|
|
{
|
|
::MoveWindow(hWnd,
|
|
rcWnd.left,
|
|
rcWnd.top,
|
|
rcWnd.Width() + nOffset,
|
|
rcWnd.Height(),
|
|
TRUE);
|
|
}
|
|
else
|
|
{
|
|
::MoveWindow(hWnd,
|
|
rcWnd.left,
|
|
rcWnd.top,
|
|
rcWnd.Width(),
|
|
rcWnd.Height() + nOffset,
|
|
TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
}//namespace SOUI
|
|
|