00001 #ifndef ANIMATIONMODEL_QT_C 00002 #define ANIMATIONMODEL_QT_C 00003 00004 #include "NeovisionII/NeoAnnotate/AnnotationObject.qt.H" 00005 #include "NeovisionII/NeoAnnotate/ObjectAnimation.qt.H" 00006 #include "NeovisionII/NeoAnnotate/AnimationDelegate.qt.H" 00007 00008 00009 AnimationModel::AnimationModel(AnnotationObject *parent) 00010 { 00011 itsParent = parent; 00012 itsVertices = itsParent->getVertices(); 00013 00014 setSupportedDragActions(Qt::MoveAction); 00015 } 00016 00017 QVariant AnimationModel::headerData(int section, Qt::Orientation orientation, int role) const 00018 { 00019 if(role != Qt::DisplayRole) 00020 return QVariant(); 00021 00022 //Show a small header on the side of the animation view 00023 if(orientation == Qt::Vertical) 00024 { 00025 //The first row is always the object, and all subsequent rows are vertices 00026 if(section == 0) 00027 return QString("Object"); 00028 00029 return QString("Vertex"); 00030 } 00031 00032 return QString(); 00033 } 00034 00035 int AnimationModel::rowCount(const QModelIndex &parent) const 00036 { 00037 return itsVertices->size()+1; 00038 } 00039 00040 int AnimationModel::columnCount(const QModelIndex &parent) const 00041 { 00042 FrameRange range = itsParent->getAnimation()->getFrameRange(); 00043 int numFrames = range.getLast() - range.getFirst()+1; 00044 00045 return numFrames; 00046 } 00047 00048 QVariant AnimationModel::data(const QModelIndex &index, int role) const 00049 { 00050 FrameRange range = itsParent->getAnimation()->getFrameRange(); 00051 00052 //Make sure we are trying to grab data from a valid table cell 00053 if(role != Qt::DisplayRole || !index.isValid()) 00054 return QVariant(); 00055 if(index.column() > range.getLast() - range.getFirst() || index.column() < 0) 00056 return QVariant(); 00057 if(index.row() > itsVertices->size()) 00058 return QVariant(); 00059 00060 int frameNum = index.column() - range.getFirst(); 00061 00062 //Grab the animation that is related to the requested row 00063 ObjectAnimation* animation; 00064 if(index.row() == 0) 00065 animation = itsParent->getAnimation(); 00066 else 00067 animation = itsVertices->at(index.row()-1)->getAnimation(); 00068 00069 //Get the frametype from the animation 00070 return animation->getFrameType(frameNum); 00071 } 00072 00073 bool AnimationModel::setData(const QModelIndex &index, const QVariant &value, int role) 00074 { 00075 return false; 00076 } 00077 00078 Qt::ItemFlags AnimationModel::flags(const QModelIndex &index) const 00079 { 00080 if(!index.isValid()) return 0; 00081 00082 FrameRange range = itsParent->getAnimation()->getFrameRange(); 00083 int frameNum = index.column() - range.getFirst(); 00084 00085 //Grab the animation that is related to the requested row 00086 ObjectAnimation* animation; 00087 if(index.row() == 0) 00088 animation = itsParent->getAnimation(); 00089 else 00090 animation = itsVertices->at(index.row()-1)->getAnimation(); 00091 00092 //Get the frametype from the animation 00093 AnimationDelegate::FrameType type = animation->getFrameType(frameNum); 00094 00095 //If the frame is a keyframe, make it drag-and-dropable 00096 if(type == AnimationDelegate::VisibleKeyframe || type == AnimationDelegate::InvisibleKeyframe) 00097 return Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | QAbstractTableModel::flags(index); 00098 00099 //If the index doesn't have a keyframe, then let Qt know we can select it, and drop things on it 00100 return QAbstractTableModel::flags(index) | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; 00101 } 00102 00103 Qt::DropActions AnimationModel::supportedDropActions() const 00104 { 00105 return Qt::MoveAction; 00106 } 00107 00108 bool AnimationModel::dropMimeData(const QMimeData * data, 00109 Qt::DropAction action, 00110 int row, int col, 00111 const QModelIndex & parent) 00112 { 00113 //Grab the destination for the drag 00114 int dstRow = parent.row(); 00115 int dstColumn = parent.column(); 00116 00117 //If the destination is invalid, then don't allow the drop 00118 if(dstRow == -1) return false; 00119 00120 //Get the source from the last reported mouse click 00121 //Unfortunately, Qt just sorts the source coordinates by their coordinates, so we 00122 //have no idea which of the possibly multiple items the user clicked on to drag, 00123 //and thus no hints as to how to shift the new items. To get around this, we just 00124 //record every mouse click on the view, and pass it downstream until it gets to this 00125 //animation model. 00126 int srcRow = itsLastClick.row(); 00127 int srcColumn = itsLastClick.column(); 00128 00129 //If we're trying to drop an animation state onto different object, then 00130 //don't allow the drop 00131 if(srcRow != dstRow) 00132 return false; 00133 00134 int columnDelta = dstColumn - srcColumn; 00135 00136 //Unpack the MIME data to retrieve the source coordinates of the drag 00137 QStringList formats = data->formats(); 00138 QByteArray encodedData = data->data(formats[0]); 00139 QDataStream stream(&encodedData, QIODevice::ReadOnly); 00140 while(!stream.atEnd()) 00141 { 00142 //Each r,c coordinate is the original position of an item to be dragged 00143 int r, c; 00144 QMap<int, QVariant> roles; 00145 stream >> r >> c >> roles; 00146 00147 //Grab the animation that is related to the requested row 00148 ObjectAnimation* animation; 00149 if(r == 0) 00150 animation = itsParent->getAnimation(); 00151 else 00152 animation = itsVertices->at(r-1)->getAnimation(); 00153 00154 int oldFrameNum = c + animation->getFrameRange().getFirst(); 00155 int newFrameNum = oldFrameNum + columnDelta; 00156 00157 //If the drag is actually to drag a keyframe to a new location, then execute 00158 //the move 00159 animation->moveKeyframe(oldFrameNum, newFrameNum); 00160 } 00161 return true; 00162 } 00163 00164 void AnimationModel::animationChanged() 00165 { 00166 //When any of the animations have changed, just update the whole table. We 00167 //can get more clever later if need be. 00168 00169 FrameRange range = itsParent->getAnimation()->getFrameRange(); 00170 00171 00172 QModelIndex tl = this->index(0, 0); 00173 QModelIndex br = this->index(itsVertices->size(), range.getLast()-range.getFirst()); 00174 emit(QAbstractItemModel::dataChanged(tl, br)); 00175 } 00176 00177 void AnimationModel::beginInsertRow(int row) 00178 { 00179 this->beginInsertRows(QModelIndex(), row, row); 00180 } 00181 00182 void AnimationModel::endInsertRow() 00183 { 00184 this->endInsertRows(); 00185 } 00186 00187 void AnimationModel::beginRemoveRow(int row) 00188 { 00189 00190 this->beginRemoveRows(QModelIndex(), row, row); 00191 } 00192 00193 void AnimationModel::beginRemoveRowsPub(const QModelIndex & i, int first, int last) 00194 { 00195 this->beginRemoveRows(i, first, last); 00196 } 00197 00198 void AnimationModel::endRemoveRow() 00199 { 00200 this->endRemoveRows(); 00201 } 00202 00203 00204 #endif //ANIMATIONMODEL_QT_C 00205 00206