#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); } } };