summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Qt3DStudio/DragAndDrop/TimelineDropTarget.cpp
blob: f0dc9c85b60085b58f2169af416786a51c2a3cb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/****************************************************************************
**
** Copyright (C) 1999-2002 NVIDIA Corporation.
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt 3D Studio.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "Qt3DSCommonPrecompile.h"
#include "TimelineDropTarget.h"
#include "StudioApp.h"
#include "DropSource.h"
#include "HotKeys.h"
#include "Core.h"
#include "Doc.h"
#include "IDropTargetHelper.h"
#include "GraphUtils.h"
#include "Qt3DSDMStudioSystem.h"
#include "ClientDataModelBridge.h"
#include "Qt3DSDMSlides.h"

// Timeline stuff

//===============================================================================
/**
 * 	This get called on every DragWithin.
 *	Note: the source will validate the target instead of the otherway around.
 *	This is because the DropSource knows how to get information from itself without
 *	creating an asset. This is mainly for DropSources that have a lazy creation idiom.
 *  like files.
 *	@param the DropSource in question.
 *	@return true if the DropSource likes the DropTarget.
 */
bool CTimeLineDropTarget::Accept(CDropSource &inSource)
{
    bool theDropFlag = inSource.ValidateTarget(this);
    return theDropFlag;
}

//===============================================================================
/**
 *  This is where it actually happens.
 *  Note: At this point either everything should be verified, and setup in the dropsource.
 *  Then the only thing left to do is to get the Assets and move/copy or connect them.
 *  Or the dropsource needs the target to perform the actual drop.
 *  Note that if the Control key is depressed, the start time follows the current view time(
 *i.e. playhead position )
 *
 *  @param inSource the Object in question.
 *  @return true if the drop was successful .
 */
bool CTimeLineDropTarget::Drop(CDropSource &inSource)
{
    qt3dsdm::Qt3DSDMInstanceHandle theTargetInstance = GetInstance();

    if (theTargetInstance.Valid()) {
        CDoc *theDoc = g_StudioApp.GetCore()->GetDoc();
        qt3dsdm::ISlideSystem *theSlideSystem = theDoc->GetStudioSystem()->GetSlideSystem();
        qt3dsdm::Qt3DSDMSlideHandle theSlide = theDoc->GetActiveSlide();
        if (!theSlideSystem->IsMasterSlide(theSlide)
            && (inSource.GetCurrentFlags() & CHotKeys::MODIFIER_ALT)) {
            if (CanAddToMaster()) {
                qt3dsdm::Qt3DSDMSlideHandle theMasterSlideHandle =
                    theSlideSystem->GetMasterSlide(theSlide);
                if (theMasterSlideHandle.Valid())
                    theSlide = theMasterSlideHandle;
            }
        }
        CCmd *theCmd = inSource.GenerateAssetCommand(theTargetInstance, m_Destination, theSlide);
        if (theCmd)
            g_StudioApp.GetCore()->ExecuteCommand(theCmd);
    }

    return true;
}

//===============================================================================
/**
 * 	 This will get the objec ttype from the Asset.
 *	 Note: The asset can change all of the time, so i always ask the asset for its type.
 *	@return the Studio object type.
 */
long CTimeLineDropTarget::GetObjectType()
{
    qt3dsdm::Qt3DSDMInstanceHandle theTargetInstance = GetTargetInstance();
    if (theTargetInstance.Valid()) {
        CClientDataModelBridge *theBridge =
            g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetClientDataModelBridge();
        return theBridge->GetObjectType(theTargetInstance);
    }

    return m_ObjectType;
}

//===============================================================================
/**
 *		Check to see if the Asset is a relative of our asset.
 * 		@return true if the inAsset is a parent grandparent...etc. of this asset.
 */
bool CTimeLineDropTarget::IsRelative(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
{
    bool theReturn = false; ///< Default return value.
    qt3dsdm::Qt3DSDMInstanceHandle theThisInstance = GetInstance();

    // This will check to see if the inAsset is already some sort of parent grandparent....etc.
    if (theThisInstance.Valid())
        theReturn = IsAscendant(theThisInstance, inInstance,
                                g_StudioApp.GetCore()->GetDoc()->GetAssetGraph());

    return theReturn;
}

//===============================================================================
/**
 * 	 Check to see if the inAsset is our asset.
 *	 @param inAsset The Asset to check.
 *	 @return true if we are the same.
 */
bool CTimeLineDropTarget::IsSelf(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
{
    qt3dsdm::Qt3DSDMInstanceHandle theThisInstance = GetInstance();
    // true if self.....
    return (theThisInstance == inInstance);
}

//===============================================================================
/**
 *	This method is used to detirmine validity for dropping on Master items.
 *	We do not allow Master items to be dropped on non-master targets because
 *	it does not make any hierarchical sense.  Also checks for NULL and Scene object.
 *	(The scene object reports as a master object so that we can re-arrange layers (On the master
 *slide).)
 * Changed checking for scene to checking for root object, which may be a component. This
 * would allow for the root component (as in edit component) to re-arrange its children, even if
 *either
 * party is not a master.
 *	@param inAsset The Asset to check.
 *	@return true if we are the same.
 */
bool CTimeLineDropTarget::IsMaster()
{
    if (!m_Instance.Valid())
        return true;
    else if (m_Instance == g_StudioApp.GetCore()->GetDoc()->GetActiveRootInstance())
        return true;
    else {
        qt3dsdm::ISlideSystem *theSlideSystem =
            g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetSlideSystem();
        qt3dsdm::Qt3DSDMSlideHandle theSlide = theSlideSystem->GetAssociatedSlide(m_Instance);
        return theSlideSystem->IsMasterSlide(theSlide);
    }
}

void CTimeLineDropTarget::SetDestination(EDROPDESTINATION inDestination)
{
    m_Destination = inDestination;
}

EDROPDESTINATION CTimeLineDropTarget::GetDestination() const
{
    return m_Destination;
}

//===============================================================================
/**
 *	Figure out the destination (parent) asset that the drop is to occur.
 *	In the case that the drop occurs ON this asset, then the to-be-dropped asset becomes a child
 *of m_Asset
 *	Otherwise, this m_Asset ends up being a sibling
 */
qt3dsdm::Qt3DSDMInstanceHandle CTimeLineDropTarget::GetTargetInstance()
{
    qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
    if (!theInstance.Valid())
        return 0;

    CClientDataModelBridge *theBridge =
        g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetClientDataModelBridge();
    bool theIsActiveComponent = false;
    bool theIsComponent = (theBridge->GetObjectType(theInstance) == OBJTYPE_COMPONENT);
    if (theIsComponent)
        theIsActiveComponent = theBridge->IsActiveComponent(theInstance);

    // If the drop destination is ON, it will be valid if this is not a component or it's in the
    // component timeline
    if (m_Destination == EDROPDESTINATION_ON) {
        if (!theIsComponent || theIsActiveComponent)
            return theInstance;
        else
            return 0;
    }

    // if target is a component, and we want to insert it above/below, and we are viewing this
    // component, then it's an invalid operation
    // thus set the target to 0.
    if (theIsActiveComponent)
        return 0;

    return theBridge->GetParentInstance(theInstance);
}

// LASTTIMELINE RELATED CODE