175 lines
3.9 KiB
C++
175 lines
3.9 KiB
C++
|
|
#include "TabLayout.h"
|
|||
|
|
|
|||
|
|
namespace ezui {
|
|||
|
|
TabLayout::TabLayout(Object* parentObject) :Control(parentObject)
|
|||
|
|
{
|
|||
|
|
Init();
|
|||
|
|
}
|
|||
|
|
void TabLayout::Init()
|
|||
|
|
{
|
|||
|
|
m_timer = new Timer(this);
|
|||
|
|
m_timer->Tick = [this](Timer* sender) {
|
|||
|
|
|
|||
|
|
HWND hWnd = this->Hwnd();
|
|||
|
|
BeginInvoke([this, hWnd, sender]() {
|
|||
|
|
if (!::IsWindow(hWnd))return;
|
|||
|
|
|
|||
|
|
m_stepAcc += m_stepPerFrame;
|
|||
|
|
int stepMove = m_stepAcc;
|
|||
|
|
m_stepAcc -= stepMove;
|
|||
|
|
m_nowOffset += stepMove;
|
|||
|
|
|
|||
|
|
// 检查是否到达终点
|
|||
|
|
if ((m_offset > 0 && m_nowOffset >= m_offset) ||
|
|||
|
|
(m_offset < 0 && m_nowOffset <= m_offset)) {
|
|||
|
|
m_nowOffset = m_offset;
|
|||
|
|
sender->Stop();
|
|||
|
|
this->Sort(); // 对齐页面
|
|||
|
|
this->Invalidate();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
for (size_t i = 0; i < GetControls().size(); ++i) {
|
|||
|
|
Control* ctl = GetControls()[i];
|
|||
|
|
if (m_dlideDirection == SlideDirection::Horizontal) {
|
|||
|
|
ctl->SetRect(Rect(m_initial[i] - m_nowOffset, 0, Width(), Height()));
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
ctl->SetRect(Rect(0, m_initial[i] - m_nowOffset, Width(), Height()));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
this->Invalidate();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
TabLayout::~TabLayout()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
void TabLayout::Remove(Control* ctl, bool freeCtl)
|
|||
|
|
{
|
|||
|
|
size_t index = this->IndexOf(ctl);
|
|||
|
|
__super::Remove(ctl, freeCtl);
|
|||
|
|
int newIndex = this->GetControls().size() - 1;
|
|||
|
|
newIndex = newIndex < 0 ? 0 : newIndex;
|
|||
|
|
this->SetPageIndex(newIndex);
|
|||
|
|
TryPendLayout();
|
|||
|
|
}
|
|||
|
|
void TabLayout::Sort()
|
|||
|
|
{
|
|||
|
|
int pos = 0;
|
|||
|
|
for (auto itor = GetControls().begin(); itor != GetControls().end(); ++itor)
|
|||
|
|
{
|
|||
|
|
if (m_dlideDirection == SlideDirection::Horizontal) {
|
|||
|
|
int x = Width() * (pos - m_pageIndex);//子控件索引-当前所在页索引
|
|||
|
|
(*itor)->SetRect(Rect(x, 0, Width(), Height()));
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
int y = Height() * (pos - m_pageIndex);//子控件索引-当前所在页索引
|
|||
|
|
(*itor)->SetRect(Rect(0, y, Width(), Height()));
|
|||
|
|
}
|
|||
|
|
(*itor)->SetVisible(true);
|
|||
|
|
++pos;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
void TabLayout::SetAttribute(const UIString& key, const UIString& value) {
|
|||
|
|
__super::SetAttribute(key, value);
|
|||
|
|
if (key == "tabindex") {
|
|||
|
|
this->SetPageIndex(std::atoi(value.c_str()));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
void TabLayout::OnLayout()
|
|||
|
|
{
|
|||
|
|
Sort();
|
|||
|
|
this->EndLayout();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Control* TabLayout::Add(Control* childCtl)
|
|||
|
|
{
|
|||
|
|
auto ret = __super::Add(childCtl);
|
|||
|
|
this->TryPendLayout();
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void TabLayout::SetPageIndex(int index)
|
|||
|
|
{
|
|||
|
|
this->m_pageIndex = index;
|
|||
|
|
this->TryPendLayout();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
void TabLayout::SlideToPage(int index, SlideDirection dlideDirection, int durationMs, int fps)
|
|||
|
|
{
|
|||
|
|
//滑动方向
|
|||
|
|
m_dlideDirection = dlideDirection;
|
|||
|
|
|
|||
|
|
Sort();//先直接归位
|
|||
|
|
int offsetTotal = (index - m_pageIndex) * (m_dlideDirection == SlideDirection::Horizontal ? Width() : Height());
|
|||
|
|
if (offsetTotal == 0) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 记录初始坐标
|
|||
|
|
int controlCount = GetControls().size();
|
|||
|
|
|
|||
|
|
m_initial.clear();
|
|||
|
|
m_initial.resize(controlCount);
|
|||
|
|
for (int i = 0; i < controlCount; ++i) {
|
|||
|
|
if (m_dlideDirection == SlideDirection::Horizontal) {
|
|||
|
|
m_initial[i] = GetControls()[i]->X();
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
m_initial[i] = GetControls()[i]->Y();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_nowOffset = 0;
|
|||
|
|
m_offset = offsetTotal;
|
|||
|
|
m_pageIndex = index;
|
|||
|
|
|
|||
|
|
int FRAME_INTERVAL_MS = 1000 / fps;
|
|||
|
|
int totalFrames = durationMs / FRAME_INTERVAL_MS;
|
|||
|
|
if (totalFrames <= 0) {
|
|||
|
|
totalFrames = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_stepPerFrame = offsetTotal * 1.0f / totalFrames;
|
|||
|
|
m_timer->Interval = FRAME_INTERVAL_MS;
|
|||
|
|
m_timer->Start();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
void TabLayout::SetPage(Control* ctl)
|
|||
|
|
{
|
|||
|
|
#ifdef _DEBUG
|
|||
|
|
ASSERT(ctl->Parent == this);
|
|||
|
|
#endif // _DEBUG
|
|||
|
|
this->m_pageIndex = this->IndexOf(ctl);
|
|||
|
|
this->TryPendLayout();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Control* TabLayout::GetPage() {
|
|||
|
|
int pos = 0;
|
|||
|
|
for (auto& it : GetControls()) {
|
|||
|
|
if (pos == this->m_pageIndex) {
|
|||
|
|
return it;
|
|||
|
|
}
|
|||
|
|
++pos;
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
int TabLayout::GetPageIndex()
|
|||
|
|
{
|
|||
|
|
return m_pageIndex;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void TabLayout::OnChildPaint(PaintEventArgs& args)
|
|||
|
|
{
|
|||
|
|
ViewControls.clear();
|
|||
|
|
Control* currPage = this->GetPage();
|
|||
|
|
if (currPage) {//仅绘制当前页
|
|||
|
|
ViewControls.push_back(currPage);
|
|||
|
|
currPage->SendEvent(args);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|