Esempio n. 1
0
void wxGenericCollapsiblePane::OnButton(wxCommandEvent& event)
{
    if ( event.GetEventObject() != m_pButton )
    {
        event.Skip();
        return;
    }

    Collapse(!IsCollapsed());

    // this change was generated by the user - send the event
    wxCollapsiblePaneEvent ev(this, GetId(), IsCollapsed());
    GetEventHandler()->ProcessEvent(ev);
}
//////////////////////////////////////////////////////////////////////////
// NOTE: This function must be thread-safe. Before adding stuff contact MarcoC.
void CVehicleMovementWarrior::ProcessMovement(const float deltaTime)
{
	if(!IsCollapsed())
	{
		CVehicleMovementHovercraft::ProcessMovement(deltaTime);
	}
}
//------------------------------------------------------------------------
bool CVehicleMovementWarrior::RequestMovement(CMovementRequest &movementRequest)
{
	if(IsCollapsing() || IsCollapsed())
		return false;

	return CVehicleMovementHovercraft::RequestMovement(movementRequest);
}
//------------------------------------------------------------------------
void CVehicleMovementWarrior::Collapse()
{
	if(IsCollapsing() || IsCollapsed())
		return;

	// start collapsing
	m_collapseTimer = 0.f;

	for(TThrusters::iterator it=m_vecThrusters.begin(); it!=m_vecThrusters.end(); ++it)
	{
		SThruster *pThruster = *it;

		if(pThruster->pPart && pThruster->heightAdaption > 0.f)
		{
			pThruster->enabled = true; // enable all for collapsing
			//pThruster->hoverHeight *= 0.5f;
			pThruster->heightAdaption *= 2.f;
		}
		else
		{
			pThruster->enabled = true;
			pThruster->hoverVariance = 0.f;
		}
	}

	// make sure engine gets updated
	m_pVehicle->GetGameObject()->EnableUpdateSlot(m_pVehicle, IVehicle::eVUS_EnginePowered);
	m_bEngineAlwaysOn = true;

	SGameObjectEvent event(eCGE_Event_Collapsing, eGOEF_ToScriptSystem);
	m_pVehicle->GetGameObject()->SendEvent(event);
}
Esempio n. 5
0
PRBool
nsMenuFrame::SizeToPopup(nsBoxLayoutState& aState, nsSize& aSize)
{
  if (!IsCollapsed(aState)) {
    PRBool widthSet, heightSet;
    nsSize tmpSize(-1, 0);
    nsIBox::AddCSSPrefSize(this, tmpSize, widthSet, heightSet);
    if (!widthSet && GetFlex(aState) == 0) {
      if (!mPopupFrame)
        return PR_FALSE;
      tmpSize = mPopupFrame->GetPrefSize(aState);
      aSize.width = tmpSize.width;

      // if there is a scroll frame, add the desired width of the scrollbar as well
      nsIScrollableFrame* scrollFrame = do_QueryFrame(mPopupFrame->GetFirstChild(nsnull));
      if (scrollFrame) {
        aSize.width += scrollFrame->GetDesiredScrollbarSizes(&aState).LeftRight();
      }

      return PR_TRUE;
    }
  }

  return PR_FALSE;
}
Esempio n. 6
0
void CDmeTrack::FindClipsWithinTime( DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
{
	if ( ( flags & DMESKIP_INVISIBLE ) && IsCollapsed() )
		return;

	if ( ( flags & DMESKIP_MUTED ) && IsMute() )
		return;

	int nClipCount = GetClipCount();
	for ( int j = 0; j < nClipCount; ++j )
	{
		CDmeClip *pSubClip = GetClip( j );
		if ( !pSubClip )
			continue;
		if ( ( flags & DMESKIP_MUTED ) && pSubClip->IsMute() )
			continue;

		DmeTime_t clipStart = pSubClip->GetStartTime();
		DmeTime_t clipEnd = pSubClip->GetEndTime();
		if ( clipStart >= startTime && clipEnd <= endTime )
		{
			clips.AddToTail( pSubClip );
		}
	}
}
Esempio n. 7
0
void CChildView::OnCollapse() 
{
    if (!IsCollapsed()) {
        m_expandToolbar = IsToolbarVisible();
        m_expandStatusbar = IsStatusbarVisible();
        m_expandMagnifier = m_magnifier.IsEnabled();    
        m_expandScreenInfo = m_dataDisplay.IsEnabled(MeaScreenSection);
        m_expandToolInfo = m_dataDisplay.IsEnabled(MeaRegionSection);
    }

    if (m_expandToolbar) {
        CFrameWnd *frame = GetParentFrame();
        frame->PostMessage(WM_COMMAND, ID_VIEW_TOOLBAR);
    }
    if (m_expandStatusbar) {
        CFrameWnd *frame = GetParentFrame();
        frame->PostMessage(WM_COMMAND, ID_VIEW_STATUSBAR);
    }
    if (m_expandMagnifier) {
        OnMagnifier();
    }
    if (m_expandScreenInfo) {
        OnScreenInfo();
    }
    if (m_expandToolInfo) {
        OnToolInfo();
    }
}
Esempio n. 8
0
nscoord
nsBox::GetBoxAscent(nsBoxLayoutState& aState)
{
  if (IsCollapsed(aState))
    return 0;

  return GetPrefSize(aState).height;
}
Esempio n. 9
0
wxString wxGenericCollapsiblePane::GetBtnLabel() const
{
    // on mac the triangle indicates the state, no string change
#ifdef __WXMAC__
    return m_strLabel;
#else
    return m_strLabel + (IsCollapsed() ? wxT(" >>") : wxT(" <<"));
#endif
}
Esempio n. 10
0
void wxCollapsiblePane::Collapse(bool collapse)
{
    // optimization
    if (IsCollapsed() == collapse)
        return;

    // do not send event in next signal handler call
    m_bIgnoreNextChange = true;
    gtk_expander_set_expanded(GTK_EXPANDER(m_widget), !collapse);
}
Esempio n. 11
0
void CChildView::OnUpdateCollapse(CCmdUI* pCmdUI) 
{
    CString label;

    if (IsCollapsed()) {
        VERIFY(label.LoadString(IDS_MEA_EXPAND));
    } else {
        VERIFY(label.LoadString(IDS_MEA_COLLAPSE));
    }

    pCmdUI->SetText(label);
}
Esempio n. 12
0
//HOWTO: 
void CMySuperGrid::HowToInsertItemsAfterTheGridHasBeenInitialized(int nIndex, const CString& str)
{
	CTreeItem *pSelItem = GetTreeItem(nIndex);
	if(pSelItem != NULL)
	{
		SetRedraw(0);
		BOOL bUpdate = FALSE;
		if(!IsCollapsed(pSelItem))
			bUpdate = TRUE;//Children are expanded, want to see update right away if not no visual update

		CItemInfo* lpRelative = new CItemInfo();
		lpRelative->SetItemText(str);
		lpRelative->AddSubItemText(_T("I am"));
		lpRelative->AddSubItemText(_T("now"));
		lpRelative->AddSubItemText(_T("going to insert"));
		lpRelative->AddSubItemText(_T("some items"));

		CTreeItem* pParent = InsertItem(pSelItem, lpRelative, bUpdate);
		for(int i=0; i < GetNumCol(); i++)
		{
			CItemInfo* lpItemInfo = new CItemInfo();
			CString strItem;
			strItem.Format(_T("Item %d"), i);
			//add items text
			lpItemInfo->SetItemText(strItem);
			//add subitem text
			for(int y=0;y < GetNumCol()-1; y++) 
			{
				CString str;
				str.Format(_T("SubItem %d of %s"), y, lpItemInfo->GetItemText());
				lpItemInfo->AddSubItemText(str);
			}
			//set combobox in last col
			lpItemInfo->SetControlType(lpItemInfo->CONTROLTYPE::combobox, GetNumCol()-2);
			CStringList list;
			for(int x = 0; x < 3; x++)
			{
				CString str;
				str.Format("ListItem %d",x);
				list.AddTail(str);
			}
			lpItemInfo->SetListData(GetNumCol()-2, &list);

			InsertItem(pParent, lpItemInfo);
		}
		SetRedraw(1);
		InvalidateRect(NULL);
		UpdateWindow();
	}
}
Esempio n. 13
0
nsSize
nsBox::GetMinSize(nsBoxLayoutState& aState)
{
  NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context");

  nsSize min(0,0);
  DISPLAY_MIN_SIZE(this, min);

  if (IsCollapsed(aState))
    return min;

  AddBorderAndPadding(min);
  nsIBox::AddCSSMinSize(aState, this, min);
  return min;
}
Esempio n. 14
0
nsSize
nsBox::GetMaxSize(nsBoxLayoutState& aState)
{
  NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context");

  nsSize maxSize(NS_INTRINSICSIZE, NS_INTRINSICSIZE);
  DISPLAY_MAX_SIZE(this, maxSize);

  if (IsCollapsed(aState))
    return maxSize;

  AddBorderAndPadding(maxSize);
  nsIBox::AddCSSMaxSize(aState, this, maxSize);
  return maxSize;
}
Esempio n. 15
0
void wxGenericCollapsiblePane::Collapse(bool collapse)
{
    // optimization
    if ( IsCollapsed() == collapse )
        return;

    // update our state
    m_pPane->Show(!collapse);

    // update button label
    // NB: this must be done after updating our "state"
    m_pButton->SetLabel(GetBtnLabel());

    OnStateChange(GetBestSize());
}
Esempio n. 16
0
nsSize
nsBox::GetPrefSize(nsBoxLayoutState& aState)
{
  NS_ASSERTION(aState.GetRenderingContext(), "must have rendering context");

  nsSize pref(0,0);
  DISPLAY_PREF_SIZE(this, pref);

  if (IsCollapsed(aState))
    return pref;

  AddBorderAndPadding(pref);
  nsIBox::AddCSSPrefSize(aState, this, pref);

  nsSize minSize = GetMinSize(aState);
  nsSize maxSize = GetMaxSize(aState);
  return BoundsCheck(minSize, pref, maxSize);
}
Esempio n. 17
0
suic::Size TreeViewItem::MeasureOverride(const suic::Size& availableSize)
{
    _expand->Measure(availableSize);
    _check.Measure(availableSize);

    suic::Size retSize;
    
    if (!IsCollapsed())
    {
        retSize = __super::MeasureOverride(availableSize);
    }

    retSize.cy += GetPadding().top;
    retSize.cy += GetPadding().bottom;
    retSize.cx += GetIndent();

    return retSize;
}
Esempio n. 18
0
//this is my override of GetIcon, override this to set what ever icon suits you
int CMySuperGrid::GetIcon(const CTreeItem* pItem)
{
	if(pItem!=NULL)
	{
		int n = GetData(pItem)->GetImage();
		if(n!=-1)
			return n;
		
		int iImage = 0;
		if(ItemHasChildren(pItem))
		{
			IsCollapsed(pItem) ? iImage = 1/*close icon*/:iImage = 0;/*open icon*/
		}
		else
			iImage = 2;//doc icon
		return iImage;
	}
	return 0;
}
Esempio n. 19
0
void wxGenericCollapsiblePane::Collapse(bool collapse)
{
    // optimization
    if ( IsCollapsed() == collapse )
        return;

    // update our state
    m_pPane->Show(!collapse);

    // update button label
#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__)
    m_pButton->SetOpen( !collapse );
#else
    // NB: this must be done after updating our "state"
    m_pButton->SetLabel(GetBtnLabel());
#endif


    OnStateChange(GetBestSize());
}
//------------------------------------------------------------------------
void CVehicleMovementWarrior::Reset()
{
	CVehicleMovementHovercraft::Reset();

	if(IsCollapsing() || IsCollapsed())
	{
		m_pVehicle->GetGameObject()->DisableUpdateSlot(m_pVehicle, IVehicle::eVUS_EnginePowered);
	}

	if(IsCollapsing())
	{
		m_bEngineAlwaysOn = false;
	}

	m_thrustersDamaged = 0;
	m_collapseTimer = -1.f;
	m_platformDown = false;
	m_collapsed = false;

	ResetThrusters();
}
Esempio n. 21
0
/* virtual */ ES_GetState
DOM_WindowSelection::GetName(OpAtom property_name, ES_Value *value, ES_Runtime *origining_runtime)
{
	switch (property_name)
	{
	case OP_ATOM_anchorNode:
	case OP_ATOM_focusNode:
		{
			DOM_Node *node;
			GET_FAILED_IF_ERROR(GetBoundaryNode(node, property_name == OP_ATOM_anchorNode));
			DOMSetObject(value, node);
		}
		return GET_SUCCESS;

	case OP_ATOM_anchorOffset:
	case OP_ATOM_focusOffset:
		{
			unsigned offset;
			GET_FAILED_IF_ERROR(GetBoundaryOffset(offset, property_name == OP_ATOM_anchorOffset));
			DOMSetNumber(value, offset);
		}
		return GET_SUCCESS;

	case OP_ATOM_isCollapsed:
		{
			BOOL is_collapsed;
			GET_FAILED_IF_ERROR(IsCollapsed(is_collapsed));
			DOMSetBoolean(value, is_collapsed);
		}
		return GET_SUCCESS;

	case OP_ATOM_rangeCount:
		GET_FAILED_IF_ERROR(UpdateRange());
		DOMSetNumber(value, range ? 1 : 0);
		return GET_SUCCESS;

	default:
		return GET_FAILED;
	}
}
Esempio n. 22
0
//-----------------------------------------------------------------------------
// Find clips at, intersecting or within a particular time interval
//-----------------------------------------------------------------------------
void CDmeTrack::FindClipsAtTime( DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
{
	if ( ( flags & DMESKIP_INVISIBLE ) && IsCollapsed() )
		return;

	if ( ( flags & DMESKIP_MUTED ) && IsMute() )
		return;

	int nClipCount = GetClipCount();
	for ( int j = 0; j < nClipCount; ++j )
	{
		CDmeClip *pSubClip = GetClip( j );
		if ( !pSubClip )
			continue;
		if ( ( flags & DMESKIP_MUTED ) && pSubClip->IsMute() )
			continue;

		if ( time.IsInRange( pSubClip->GetStartTime(), pSubClip->GetEndTime() ) )
		{
			clips.AddToTail( pSubClip );
		}
	}
}
Esempio n. 23
0
nsresult
nsBox::SyncLayout(nsBoxLayoutState& aState)
{
  /*
  PRBool collapsed = PR_FALSE;
  IsCollapsed(aState, collapsed);
  if (collapsed) {
    CollapseChild(aState, this, PR_TRUE);
    return NS_OK;
  }
  */
  

  if (GetStateBits() & NS_FRAME_IS_DIRTY)
     Redraw(aState);

  RemoveStateBits(NS_FRAME_HAS_DIRTY_CHILDREN | NS_FRAME_IS_DIRTY
                  | NS_FRAME_FIRST_REFLOW | NS_FRAME_IN_REFLOW);

  nsPresContext* presContext = aState.PresContext();

  PRUint32 flags = 0;
  GetLayoutFlags(flags);

  PRUint32 stateFlags = aState.LayoutFlags();

  flags |= stateFlags;

  nsRect rect(nsPoint(0, 0), GetSize());

  if (ComputesOwnOverflowArea()) {
    rect = GetOverflowRect();
  }
  else {
    if (!DoesClipChildren() && !IsCollapsed(aState)) {
      // See if our child frames caused us to overflow after being laid
      // out. If so, store the overflow area.  This normally can't happen
      // in XUL, but it can happen with the CSS 'outline' property and
      // possibly with other exotic stuff (e.g. relatively positioned
      // frames in HTML inside XUL).
      nsIFrame* box = GetChildBox();
      while (box) {
        nsRect bounds = box->GetOverflowRect() + box->GetPosition();
        rect.UnionRect(rect, bounds);

        box = box->GetNextBox();
      }
    }

    FinishAndStoreOverflow(&rect, GetSize());
  }

  nsIView* view = GetView();
  if (view) {
    // Make sure the frame's view is properly sized and positioned and has
    // things like opacity correct
    nsHTMLContainerFrame::SyncFrameViewAfterReflow(
                             presContext, 
                             this,
                             view,
                             &rect,
                             flags);
  } 

  return NS_OK;
}
//------------------------------------------------------------------------
void CVehicleMovementWarrior::Update(const float deltaTime)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	if(!IsCollapsing())
		CVehicleMovementHovercraft::Update(deltaTime);
	else
		CVehicleMovementBase::Update(deltaTime);

	if(IsCollapsing())
	{
		m_collapseTimer += deltaTime;

		// check platform
		Vec3 platformPos;

		if(m_pPlatformPos)
			platformPos = m_pPlatformPos->GetWorldSpaceTranslation();
		else
			platformPos.zero();

		float dist = platformPos.z - gEnv->p3DEngine->GetTerrainElevation(platformPos.x, platformPos.y);

		if(dist < 1.f)
		{
			m_platformDown = true;
		}

		// center turret
		RotatePart(m_pTurret, DEG2RAD(0.f), AXIS_Z, DEG2RAD(2.5f), deltaTime);

		// take down wing and cannon
		RotatePart(m_pWing, DEG2RAD(-12.5f), AXIS_X, DEG2RAD(3.f), deltaTime);
		RotatePart(m_pCannon, DEG2RAD(-20.f), AXIS_X, DEG2RAD(2.5f), deltaTime);

		if(!m_platformDown)
		{
			// handle legs to bring down platform
			TThrusters::iterator iter;

			for(iter=m_vecThrusters.begin(); iter!=m_vecThrusters.end(); ++iter)
			{
				SThruster *pThruster = *iter;

				if(pThruster->heightAdaption <= 0.f)
				{
					pThruster->hoverHeight = max(0.1f, pThruster->hoverHeight - 0.6f*deltaTime);
					continue;
				}
				else
				{
					//if (!pThruster->groundContact)
					//pThruster->hoverHeight = max(0.1f, pThruster->hoverHeight - 0.2f*deltaTime);
				}

				/*
				// special legs control
				float collapseSpeed = DEG2RAD(5.f);
				float maxDistMovable = 1.f/0.8f;

				float dist = (isneg(pThruster->prevDist)) ? 0.f : pThruster->hoverHeight - pThruster->prevDist;

				if (isneg(dist))
				{
				collapseSpeed *= max(0.f, 1.f + maxDistMovable*dist);
				}

				if (collapseSpeed > 0.f)
				{
				float angle = RotatePart(pThruster->pParentPart, DEG2RAD(m_collapsedLegAngle), collapseSpeed, deltaTime);
				RotatePart(pThruster->pPart, DEG2RAD(m_collapsedFeetAngle), collapseSpeed, deltaTime);
				}
				*/
			}
		}
		else
		{
			if(!m_collapsed)
			{
				Collapsed(true);
			}
		}
	}

	if(IsPowered() && !IsCollapsed())
	{
		// "normal" legs control here

		bool bStartComplete = (m_startComplete > 1.5f);
		float adaptionSpeed = IsCollapsing() ? 0.8f : 1.5f;
		int t = 0;

		for(TThrusters::iterator iter=m_vecThrusters.begin(); iter!=m_vecThrusters.end(); ++iter)
		{
			SThruster *pThruster = *iter;
			++t;

			if(pThruster->heightAdaption > 0.f && bStartComplete && pThruster->pPart && pThruster->pParentPart)
			{
				const char *footName = pThruster->pPart->GetName();
				EWarriorMovement mode = eWM_Hovering;
				float correction = 0.f, maxCorrection = 0.f;

				// adjust legs
				float error = 0.f;

				if(!pThruster->hit)
					error = pThruster->hoverHeight; // when not hit, correct downwards
				else if(pThruster->prevDist > 0.f)
					error = pThruster->prevDist - pThruster->hoverHeight;

				if(mode != eWM_None && abs(error) > 0.05f)
				{
					float speed = max(0.1f, min(1.f, abs(error))) * adaptionSpeed;
					correction = -sgn(error) * min(speed*deltaTime, abs(error)); // correct up to error

					// don't correct more than heightAdaption allows
					maxCorrection = abs((pThruster->heightInitial + sgn(correction)*pThruster->heightAdaption) - pThruster->pos.z);
					float minCorrection = (pThruster->groundContact) ? 0.f : -maxCorrection;

					correction = CLAMP(correction, minCorrection, maxCorrection);

					if(abs(correction) > 0.0001f)
					{
						// positive correction for leg, negative for foot
						Matrix34 legLocal  = pThruster->pParentPart->GetLocalBaseTM();
						Matrix34 footLocal = pThruster->pPart->GetLocalBaseTM();

						float radius = footLocal.GetTranslation().len();
						float deltaAngle = correction / radius; // this assumes correction on circle (accurate enough for large radius)

						Matrix34 legTM  = Matrix33(legLocal) * Matrix33::CreateRotationX(deltaAngle);
						Matrix34 footTM = Matrix33(footLocal) * Matrix33::CreateRotationX(-deltaAngle);

						legTM.SetTranslation(legLocal.GetTranslation());
						footTM.SetTranslation(footLocal.GetTranslation());

						pThruster->pParentPart->SetLocalBaseTM(legTM);
						pThruster->pPart->SetLocalBaseTM(footTM);
					}
				}

				if(IsProfilingMovement())
				{
					static ICVar *pDebugLeg = gEnv->pConsole->GetCVar("warrior_debug_leg");

					if(pDebugLeg && pDebugLeg->GetIVal() == t)
					{
						//CryLog("hoverErr %.2f, levelErr %.2f, neutralErr %.2f -> %s corr %.3f (max %.2f)", hoverError, levelError, neutralError, sMode, correction, maxCorrection);
					}
				}
			}
		}
	}

	// regain control
	if(m_collapseTimer > m_recoverTime)
	{
		Collapsed(false);
	}

	for(TThrusters::iterator it=m_vecThrusters.begin(); it!=m_vecThrusters.end(); ++it)
	{
		(*it)->groundContact = false;
	}
}
Esempio n. 25
0
wxString wxGenericCollapsiblePane::GetBtnLabel() const
{
    return m_strLabel + (IsCollapsed() ? wxT(" >>") : wxT(" <<"));
}
Esempio n. 26
0
void wxGenericCollapsiblePane::OnStateChange(const wxSize& sz)
{
    // minimal size has priority over the best size so set here our min size
    SetMinSize(sz);
    SetSize(sz);

    if (this->HasFlag(wxCP_NO_TLW_RESIZE))
    {
        // the user asked to explicitely handle the resizing itself...
        return;
    }


    //
    // NB: the following block of code has been accurately designed to
    //     as much flicker-free as possible; be careful when modifying it!
    //

    wxTopLevelWindow *
        top = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
    if ( top )
    {
        // NB: don't Layout() the 'top' window as its size has not been correctly
        //     updated yet and we don't want to do an initial Layout() with the old
        //     size immediately followed by a SetClientSize/Fit call for the new
        //     size; that would provoke flickering!

        if (top->GetSizer())
#ifdef __WXGTK__
        // FIXME: the SetSizeHints() call would be required also for GTK+ for
        //        the expanded->collapsed transition. Unfortunately if we
        //        enable this line, then the GTK+ top window won't always be
        //        resized by the SetClientSize() call below! As a side effect
        //        of this dirty fix, the minimal size for the pane window is
        //        not set in GTK+ and the user can hide it shrinking the "top"
        //        window...
        if (IsCollapsed())
#endif
            top->GetSizer()->SetSizeHints(top);


        // we shouldn't attempt to resize a maximized window, whatever happens
        if ( !top->IsMaximized() )
        {
            if ( IsCollapsed() )
            {
                // expanded -> collapsed transition
                if (top->GetSizer())
                {
                    // we have just set the size hints...
                    wxSize sz = top->GetSizer()->CalcMin();

                    // use SetClientSize() and not SetSize() otherwise the size for
                    // e.g. a wxFrame with a menubar wouldn't be correctly set
                    top->SetClientSize(sz);
                }
                else
                    top->Layout();
            }
            else
            {
                // collapsed -> expanded transition

                // force our parent to "fit", i.e. expand so that it can honour
                // our minimal size
                top->Fit();
            }
        }
    }
}
Esempio n. 27
0
suic::Size TreeViewItem::ArrangeOverride(const suic::Size& finalSize)
{
    // 先清除可视节点
    ClearVisualChildren();

    const int ITEMSPACE = 2;

    suic::Rect finalRect(0, 0, finalSize.cx, 0);

    // 布局扩展按钮
    if (_expand->IsVisible())
    {
        finalRect.right = finalRect.left + _expand->GetDesiredSize().cx;
        finalRect.top = (_header->GetDesiredSize().cy - _expand->GetDesiredSize().cy) / 2;
        finalRect.bottom = finalRect.top + _expand->GetDesiredSize().cy;

        AddVisualChild(_expand.get());
        _expand->Arrange(finalRect);

        finalRect.left = finalRect.right + 12;
    }

    // 布局选择按钮
    if (_check.IsVisible())
    {
        finalRect.right = finalRect.left + _check.GetDesiredSize().cx;
        finalRect.top = (_header->GetDesiredSize().cy - _check.GetDesiredSize().cy) / 2;
        finalRect.bottom = finalRect.top + _check.GetDesiredSize().cy;

        AddVisualChild(&_check);
        _check.Arrange(finalRect);

        finalRect.left = finalRect.right;
    }

    if (_icon)
    {
        // 布局图标
        suic::Rect rcIcon(_icon->GetContentBrounds());
    }

    finalRect.right = finalRect.left + _header->GetDesiredSize().cx;
    finalRect.top = 0;
    finalRect.bottom = _header->GetDesiredSize().cy;

    AddVisualChild(_header.get());
    _header->Arrange(finalRect);

    finalRect.top = finalRect.bottom;
    finalRect.left = GetIndent();

    if (!IsCollapsed())
    {
        for (int i = 0; i < GetItems()->GetCount(); ++i)
        {
            TreeViewItemPtr item(GetItems()->GetItem(i));

            finalRect.right = finalRect.left + item->GetDesiredSize().cx;
            finalRect.bottom = finalRect.top + item->GetDesiredSize().cy;

            AddVisualChild(item.get());
            item->Arrange(finalRect);

            finalRect.top = finalRect.bottom;
        }
    }

    return finalSize;
}