⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wxsdragwindow.cpp

📁 非常好用的可移植的多平台C/C++源代码编辑器
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    int PosX = 0, PosY = 0;
    int SizeX = 0, SizeY = 0;

    if ( !CurDragWidget )
    {
        wxsWidget* Widget = CurDragPoint->Widget;
        Widget->GetPreview()->GetPosition(&PosX,&PosY);

        // Calculating new widget's position and size
        DragPointData* LeftTopPoint = FindLeftTop(CurDragPoint);
        PosX += LeftTopPoint->PosX - LeftTopPoint->DragInitPosX;
        PosY += LeftTopPoint->PosY - LeftTopPoint->DragInitPosY;
        SizeX = LeftTopPoint->WidgetPoints[Right]->PosX - LeftTopPoint->PosX;
        SizeY = LeftTopPoint->WidgetPoints[Btm]->PosY - LeftTopPoint->PosY;

        // Correcting negative size
        if ( SizeX < 0 )
        {
            PosX += SizeX;
            LeftTopPoint->PosX += SizeX;
            SizeX = -SizeX;
        }
        if ( SizeY < 0 )
        {
            PosY += SizeY;
            LeftTopPoint->PosY += SizeY;
            SizeY = -SizeY;
        }

        // Applying changes
        wxsWidgetBaseParams& Params = Widget->GetBaseParams();
        if ( LeftTopPoint->PosX != LeftTopPoint->DragInitPosX ||
             LeftTopPoint->PosY != LeftTopPoint->DragInitPosY )
        {
            Params.DefaultPosition =
                Widget->GetParent() && Widget->GetParent()->GetInfo().Sizer;
            Params.PosX = PosX;
            Params.PosY = PosY;
        }
        Params.DefaultSize = false;
        Params.SizeX = SizeX;
        Params.SizeY = SizeY;
        Widget->UpdateProperties();
        Widget->PropertiesUpdated(false,false);     // This will recreate preview
    }
    else
    {
        wxsWindowEditor* Editor = (wxsWindowEditor*)RootWidget->GetResource()->GetEditor();

        std::vector<wxsWidget*> AllToMove;
        GetSelectionNoChildren(AllToMove);

        // Finding out what new parent widget will be
        wxsWidget* NewParent = UnderCursor;

        bool NewParentIsSizer = NewParent->GetInfo().Sizer;
        int NewInSizerPos = -1;
        int Cnt = (int)AllToMove.size();

        for(;;)
        {
            bool ForceMoreParent = false;
            for ( int i=0; i<Cnt; i++ )
            {
                if ( AllToMove[i] == NewParent ) ForceMoreParent = true;
            }

            if ( NewParent->IsContainer() && !ForceMoreParent ) break;
            NewParent = NewParent->GetParent();
            if ( !NewParent )
            {
                CurDragPoint = NULL;
                CurDragWidget = NULL;
                return;
            }

            NewParentIsSizer = NewParent->GetInfo().Sizer;
            if ( NewParentIsSizer )
            {
                NewInSizerPos = NewParent->FindChild(UnderCursor);

                // To make dragging more natural, we have to
                // change insert pos little bit

                if ( (CurDragWidget->GetParent() == NewParent) &&
                     (NewParent->FindChild(CurDragWidget) < NewInSizerPos) )
                {
                    NewInSizerPos++;
                }
            }
        }

        // First pass - checking if widget can be moved and
        //              recalculating position
        for ( int i=0; i<Cnt; i++ )
        {
            wxsWidget* Moved = AllToMove[i];
            if ( (Moved != NewParent) &&
                 (Moved->FindChild(NewParent,0) < 0) &&
                  NewParent->CanAddChild(Moved) )
            {
                wxsWidgetBaseParams& Params = Moved->GetBaseParams();
                DragPointData* LeftTopPoint = FindLeftTop(Moved);
                if ( LeftTopPoint )
                {
                    FindAbsolutePosition(Moved,&PosX,&PosY);
                    PosX += LeftTopPoint->PosX - LeftTopPoint->DragInitPosX;
                    PosY += LeftTopPoint->PosY - LeftTopPoint->DragInitPosY;

                    NewParent->GetPreview()->ScreenToClient(&PosX,&PosY);
                    Params.PosX = PosX;
                    Params.PosY = PosY;
                }
            }
            else
            {
                // This widget won't be moved
                AllToMove.erase(AllToMove.begin()+i);
                i--;
                Cnt--;
            }
        }

        // Second pass - changing resource structure
        // Must kill preview to avoid seg faults caused by
        // differences between preview structure and resource's
        // structure
        Editor->KillPreview();
        for ( int i=0; i<Cnt; i++ )
        {
            wxsWidget* Moved = AllToMove[i];
            wxsWidget* OldParent = Moved->GetParent();
            int OldInSizerPos = OldParent->FindChild(Moved);

            if ( NewParent == OldParent )
            {
                if ( NewParentIsSizer )
                {
                    if ( NewInSizerPos != OldInSizerPos )
                    {
                        Moved->KillTree(wxsTREE());
                        OldParent->ChangeChildPos(OldInSizerPos,NewInSizerPos);
                        NewInSizerPos = OldParent->FindChild(Moved);
                        Moved->BuildTree(wxsTREE(),NewParent->GetTreeId(),NewInSizerPos);
                    }
                }
            }
            else
            {
                Moved->KillTree(wxsTREE());
                OldParent->DelChildId(OldInSizerPos);
                NewParent->AddChild(Moved,NewInSizerPos);
                Moved->BuildTree(wxsTREE(),NewParent->GetTreeId(),NewInSizerPos);
            }

            wxsWidgetBaseParams& Params = Moved->GetBaseParams();
            Params.DefaultPosition = NewParentIsSizer;
            if ( NewInSizerPos >= 0 )
            {
                NewInSizerPos++;
            }
        }

        wxsTREE()->Refresh();
        RootWidget->PropertiesUpdated(false,false);
    }

    CurDragPoint = NULL;
    CurDragWidget = NULL;
}

void wxsDragWindow::UpdateCursor(bool Dragging,DragPointData* NewDragPoint,wxsWidget* NewDragWidget)
{
    if ( !Dragging )
    {
        // We're not dragging - checkign what's under cursor
    	if ( !NewDragWidget && NewDragPoint )
    	{
    		switch ( NewDragPoint->Type )
    		{
                case LeftTop:
                case RightBtm:
                    SetCur(wxCURSOR_SIZENWSE);
                    break;

                case Top:
                case Btm:
                    SetCur(wxCURSOR_SIZENS);
                    break;

                case RightTop:
                case LeftBtm:
                    SetCur(wxCURSOR_SIZENESW);
                    break;

                case Left:
                case Right:
                    SetCur(wxCURSOR_SIZEWE);
                    break;

                default:
                    SetCur(wxCURSOR_ARROW);
    		}
    	}
    	else
    	{
    		SetCur(wxCURSOR_ARROW);
    	}
    }
    else
    {
        if ( CurDragWidget )
        {
            SetCur( CurDragPoint->NoAction ? wxCURSOR_NO_ENTRY : wxCURSOR_SIZING );
        }
        else if ( CurDragPoint )
        {
            if ( CurDragPoint->NoAction ) SetCur(wxCURSOR_NO_ENTRY);
        }
        else
        {
            SetCur(wxCURSOR_ARROW);
        }
    }
}

void wxsDragWindow::OnSelectWidget(wxsEvent& event)
{
    if ( BlockWidgetSelect ) return;
    if ( !IsInside(event.GetWidget(),RootWidget) )
    {
        ClearDragPoints();
    }
    else
    {
        wxsWidget* Wdg = event.GetWidget();
        if ( Wdg->GetParent() ) Wdg->GetParent()->EnsurePreviewVisible(Wdg);
        if ( ::wxGetKeyState(WXK_CONTROL) )
        {
            GrayDragPoints();
            BlackDragPoints(Wdg);
        }
        else
        {
            ClearDragPoints();
            BuildDragPoints(Wdg);
            BlackDragPoints(Wdg);
        }
    }
    Refresh();
}

void wxsDragWindow::OnUnselectWidget(wxsEvent& event)
{
    for ( size_t i = 0; i < DragPoints.size(); )
    {
    	DragPointData* DPD = DragPoints[i];
    	if ( DPD->Widget == event.GetWidget() )
    	{
    		DragPoints.erase(DragPoints.begin()+i);
    	}
    	else
    	{
    		i++;
    	}
    }
    UpdateGraphics();
}

void wxsDragWindow::ClearDragPoints()
{
    for ( DragPointsI i = DragPoints.begin(); i!=DragPoints.end(); ++i )
    {
    	delete *i;
    }
    DragPoints.clear();
}

wxsDragWindow::DragPointData* wxsDragWindow::BuildDragPoints(wxsWidget* Widget)
{
	if ( !Widget ) return NULL;

    if ( Widget->GetPreview() )
    {
        DragPointData* WidgetPoints[DragBoxTypeCnt];

        for ( int i=0; i<DragBoxTypeCnt; ++i )
        {
            WidgetPoints[i] = new DragPointData;
            WidgetPoints[i]->Inactive = false;
        }

        UpdateDragPointData(Widget,WidgetPoints);

        for ( int i=0; i<DragBoxTypeCnt; ++i )
        {
            DragPoints.push_back(WidgetPoints[i]);
        }

        return WidgetPoints[0];
    }

    return NULL;
}

void wxsDragWindow::UpdateDragPointData(wxsWidget* Widget,DragPointData** WidgetPoints)
{
    int PosX, PosY;
    int SizeX, SizeY;
    bool NoAction = false;// ! ( Widget->GetBPType() & ( wxsWidget::bptSize | wxsWidget::bptPosition ) );

    FindAbsolutePosition(Widget,&PosX,&PosY);

    ScreenToClient(&PosX,&PosY);
    Widget->GetPreview()->GetSize(&SizeX,&SizeY);

    for ( int i=0; i<DragBoxTypeCnt; ++i )
    {
        WidgetPoints[i]->Widget = Widget;
        WidgetPoints[i]->Type = (DragBoxType)i;
        WidgetPoints[i]->PosX = PosX;
        WidgetPoints[i]->PosY = PosY;
        WidgetPoints[i]->NoAction = NoAction;

        if ( i == Top || i == Btm )
        {
            WidgetPoints[i]->PosX += SizeX / 2;
        }
        else if ( i == RightTop || i == Right || i == RightBtm )
        {
            WidgetPoints[i]->PosX += SizeX;
        }

        if ( i==Left || i == Right )
        {
            WidgetPoints[i]->PosY += SizeY / 2;
        }
        else if ( i == LeftBtm || i == Btm || i == RightBtm )
        {
            WidgetPoints[i]->PosY += SizeY;
        }

        WidgetPoints[i]->KillMe = false;
        memcpy(WidgetPoints[i]->WidgetPoints,WidgetPoints,sizeof(WidgetPoints[0]->WidgetPoints));
    }
}

void wxsDragWindow::RecalculateDragPoints()
{
    // If there are no dragpoints we jujst build new array
	if ( DragPoints.empty() ) return;

	// Setting KillMe flag for all points
	for ( DragPointsI i = DragPoints.begin(); i != DragPoints.end(); ++i )
	{
		(*i)->KillMe = true;
	}

	// Processing all widget in this window
	int HintIndex = 0;
	RecalculateDragPointsReq(RootWidget,HintIndex);

    // Deleting invalid drag points
    for ( size_t i=0; i<DragPoints.size(); )
    {
    	if ( DragPoints[i]->KillMe )
    	{
    		delete DragPoints[i];
    		DragPoints.erase(DragPoints.begin()+i);
    	}
    	else
    	{
    		i++;
       	}
    }
}

void wxsDragWindow::RecalculateDragPointsReq(wxsWidget* Widget,int& HintIndex)
{
    for ( int i = 0; i<Widget->GetChildCount(); i++ )
    {
    	RecalculateDragPointsReq(Widget->GetChild(i),HintIndex);
    }

    if ( Widget->GetPreview() )
    {
        int Index = HintIndex;
        while ( DragPoints[Index]->Widget != Widget )
        {
            Index = (Index+1) % DragPoints.size();
            if ( Index == HintIndex )
            {
                Index = -1;
                break;
            }
        }

        if ( Index != -1 )
        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -