/** * Slot for the Controller's add_frame_signal_ signal. * * Updates the onionskin texture */ void Gui::on_frame_added(unsigned int clip_number, unsigned int image_number) { if (owner_->get_configuration()->get_verbose()) std::cout << "Gui::on_frame_added" << std::endl; // Rotate the textures ClutterActor* _tmp = onionskin_textures_.back(); onionskin_textures_.insert(onionskin_textures_.begin() + 0, _tmp); onionskin_textures_.pop_back(); // Get image file name Clip* clip = owner_->get_clip(clip_number); Image* image = clip->get_image(image_number); if (image == 0) std::cout << __FUNCTION__ << ": Could not get a handle to any image!" << std::endl; else { GError *error = NULL; gboolean success; std::string file_name = clip->get_image_full_path(image); // Load file //std::cout << "Loading " << file_name << " for onion skin" << std::endl; success = clutter_texture_set_from_file(CLUTTER_TEXTURE(onionskin_textures_.at(0)), file_name.c_str(), &error); // If ever we have many onion skins, we might raise the latest one: // //clutter_container_raise_child(CLUTTER_CONTAINER(onionskin_group_), CLUTTER_ACTOR(onionskin_textures_.at(0)), NULL); if (!success) { std::cerr << "Failed to load pixbuf file: " << file_name << " " << error->message << std::endl; g_error_free(error); } else { //std::cout << "Loaded image " << image_full_path << std::endl; } } animate_flash(); }
void ClipBoard::readTrack( QDomElement &element, QList<Clip*> *track, QList<Source*> *sourcesList, Scene *scene ) { bool readError = false; QDomNodeList nodes = element.childNodes(); for ( int i = 0; i < nodes.count(); ++i ) { QDomElement e = nodes.at( i ).toElement(); if ( e.isNull() ) continue; if ( e.tagName() == "Clip" ) { Clip *clip = XMLizer::readClip( e, sourcesList, scene, readError ); if (clip) { int k = 0, tc = track->count(); // sort clips by position while ( k < tc ) { Clip *c = track->at( k ); if ( clip->position() < c->position() ) { track->insert( k, clip ); break; } ++k; } if ( k == tc ) { track->append( clip ); } } } } }
// WouldAcceptDragMessage bool InsertClipsDropState::WouldAcceptDragMessage(const BMessage* dragMessage) { if (dragMessage->what != MSG_DRAG_CLIP) return false; // inspect the message to retrieve the clip duration ServerObjectManager* library; if (dragMessage->FindPointer("library", (void**)&library) != B_OK) return false; if (!library || !library->ReadLock()) return false; fDraggedClipDuration = 0; Clip* clip; for (int32 i = 0; dragMessage->FindPointer("clip", i, (void**)&clip) == B_OK; i++) { if (!library->HasObject(clip)) continue; fDraggedClipDuration += ClipPlaylistItem::DefaultDuration(clip->Duration()); } library->ReadUnlock(); fSnapFrames.CollectSnapFrames(fView->Playlist(), fDraggedClipDuration); fSnapFrames.AddSnapFrame(0, fDraggedClipDuration); if (fView->IsPaused()) fSnapFrames.AddSnapFrame(fView->CurrentFrame(), fDraggedClipDuration); return true; }
void Scene::move( Clip *clip, int clipTrack, double newPos, int newTrack ) { QMutexLocker ml( &mutex ); if ( clip->position() == newPos && clipTrack == newTrack ) return; double margin = profile.getVideoFrameDuration() / 4.0; int insert, self = 0; Track *t = tracks[newTrack]; insert = t->clipCount(); for ( int i = 0; i < t->clipCount(); ++i ) { Clip *c = t->clipAt( i ); if ( c == clip ) { ++self; continue; } if ( newPos < c->position() ) { insert = i; break; } } insert -= self; removeTransitions( clip, clipTrack, newTrack, insert, newPos, clip->length(), margin ); tracks[clipTrack]->removeClip( clip ); t->insertClipAt( clip, insert ); clip->setPosition( newPos ); updateTransitions( clip, newTrack, margin ); clip->setInput( NULL ); update = true; }
void Scene::moveMulti( Clip *clip, int clipTrack, double newPos ) { QMutexLocker ml( &mutex ); if ( clip->position() == newPos ) return; double delta = newPos - clip->position(); double margin = profile.getVideoFrameDuration() / 4.0; Track *t = tracks[clipTrack]; int count = t->clipCount(); int clipIndex = 0; int k = 0; while ( k < count ) { Clip *c = t->clipAt( k ); // find clip if ( c == clip ) { clipIndex = k; break; } ++k; } removeTransitions( clip, clipTrack, clipTrack, clipIndex, newPos, clip->length(), margin, true ); clip->setPosition( clip->position() + delta ); while ( ++k < count ) { Clip *c = t->clipAt( k ); c->setPosition( c->position() + delta ); } updateTransitions( clip, clipTrack, margin ); clip->setInput( NULL ); update = true; }
void InfoWindow::update_thumbnail_for_clip(unsigned int clip_number) { if (clip_number >= clips_.size()) { g_critical("%s: Clip number bigger than size of known clips.", __FUNCTION__); return; } Clip *clip = app_->get_clip(clip_number); ClipInfoBox *clip_info = clips_.at(clip_number).get(); unsigned int frames = clip->size(); if (frames == 0) clutter_actor_hide(clip_info->image_); else { clutter_actor_show(clip_info->image_); Image *image = clip->get_image(0); if (image == 0) std::cout << __FUNCTION__ << ": Could not get a handle to any image!" << std::endl; else { std::string file_name = clip->get_image_full_path(image); load_thumbnail_from_file(CLUTTER_TEXTURE(clip_info->image_), file_name, 80, 60); } } }
int main(int argc, char**argv) { BaseOscillator* BaseOsc = new BaseOscillator(); WaveLoader* loader = new WaveLoader(); LPSLoader* lps = new LPSLoader(); Clip* clipper = new Clip(); ModuleLogger::enable(); ModuleLogger::setConsole(); clipper->setClipMode(Clip::CLIP_MODE_BOTH); clipper->setClipLevel(0.5); loader->Load("./TestData/testwave_32bit_stereo.wav"); for (int i = 0; i < 100; i++) { double d = BaseOsc->Process(50); d = clipper->Process(d); } loader->Unload(); delete lps; delete loader; delete clipper; delete BaseOsc; return 0; }
virtual void MessageReceived(BMessage* message) { if (message->WasDropped()) _SetAnticipateDrop(false); switch (message->what) { case MSG_DRAG_CLIP: { Clip* clip; if (message->FindPointer("clip", (void**)&clip) != B_OK) break; if (dynamic_cast<Playlist*>(clip) == NULL) { BAlert* alert = new BAlert("error", "The navigation " "target clip needs to be a playlist.\n", "Ok"); alert->Go(); break; } fWindow->SetTargetID(clip->ID().String()); fWindow->PostMessage(MSG_INVOKE); break; } default: BView::MessageReceived(message); } }
/** * Adds an image to the current clip. * TODO: should be moved out of here, to application. */ void Pipeline::remove_frame() { Clip *thisclip = owner_->get_current_clip(); //int num_deleted; //num_deleted = thisclip->frame_remove(); //if (num_deleted > 0) // std::cout << "Deleted " << num_deleted << " frames in clip " << thisclip->get_id() << std::endl; }
bool Weapon::reload(Clip& clip) { if (acceptable_ammo(clip) && !clip.empty()) { loaded_cliptype_ = clip.get_itemtypename(); ammo_ = clip.get_ammoamount(); clip.decrease_number(1); return true; } else return false; }
int main(int argc, char *argv[]) { QApplication a(argc, argv); a.setApplicationName("Clip"); a.setOrganizationDomain("clip4.sf.net"); a.setOrganizationName("O.J.Schumann"); Clip* w = Clip::getInstance(); w->show(); int r = a.exec(); Clip::clearInstance(); return r; }
void Scene::removeTransitions( Clip *clip, int oldTrack, int newTrack, int newIndex, double clipPos, double clipLength, double margin, bool multi ) { Track *ot = tracks[oldTrack]; int index = ot->indexOf( clip ); if ( newTrack != oldTrack || index != newIndex ) { clip->removeTransition(); if ( index < ot->clipCount() - 1 ) { Clip *c = ot->clipAt( index + 1 ); c->removeTransition(); } } else { if ( !multi && index < ot->clipCount() - 1 ) { Clip *c = ot->clipAt( index + 1 ); if ( clipPos + clipLength - margin < c->position() ) c->removeTransition(); } if ( index > 0 ) { Clip *c = ot->clipAt( index - 1 ); if ( c->position() + c->length() - margin < clipPos ) clip->removeTransition(); } } }
Clip* MediaContainer::clip( const QString &uuid ) { MediaContainer *mc = this; Clip *clip = NULL; QStringList ids = uuid.split( '/' ); foreach ( QString id, ids ) { clip = mc->clip( QUuid( id ) ); if ( clip == NULL ) return NULL; mc = clip->getChilds(); }
void InfoWindow::update_num_frames(unsigned int clip_number) { if (clip_number >= clips_.size()) { g_critical("%s: Clip number bigger than size of known clips.", __FUNCTION__); return; } Clip *clip = app_->get_clip(clip_number); ClipInfoBox *clip_info = clips_.at(clip_number).get(); unsigned int frames = clip->size(); std::ostringstream os; os << " # <b>" << clip_number << "</b>" << std::endl; os << "images: " << frames; clutter_text_set_markup(CLUTTER_TEXT(clip_info->label_), os.str().c_str()); }
/** * Saves a GdkPixbuf image to the current clip. * * Needed, because the image might come from the last grabbed * frame, or the recording of every frame might be automatic. (video) * * The gdkpixbufsink element posts messages containing the pixbuf. */ void Pipeline::save_image_to_current_clip(GdkPixbuf *pixbuf) { Clip *thisclip = owner_->get_current_clip(); bool is_verbose = owner_->get_configuration()->get_verbose(); int current_clip_id = thisclip->get_id(); int w = gdk_pixbuf_get_width(pixbuf); int h = gdk_pixbuf_get_height(pixbuf); /* if this is the first frame grabbed, set frame properties in clip */ // TODO:2010-08-27:aalex:Use image size, not clip size. // A clip may contain images that are not the same size. if (! thisclip->get_has_recorded_frame()) { // TODO: each image should be a different size, if that's what it is. thisclip->set_width(w); thisclip->set_height(h); thisclip->set_has_recorded_frame(); } int new_image_number = thisclip->frame_add(); Image *new_image = thisclip->get_image(new_image_number); if (new_image == 0) { // This is very unlikely to happen std::cerr << "No image at " << new_image_number << std::endl; g_object_unref(pixbuf); return; } if (is_verbose) std::cout << "Grab a frame. Current clip: " << current_clip_id << ". Image number: " << new_image_number << std::endl; std::string file_name = thisclip->get_image_full_path(new_image); // We need 3 textures: // * the onionskin of the last frame grabbed. (or at the writehead position) // * the frame at the playhead position // * the current live input. (GST gives us this one) if (!gdk_pixbuf_save(pixbuf, file_name.c_str(), "jpeg", NULL, "quality", "100", NULL)) { g_print("Image %s could not be saved. Error\n", file_name.c_str()); } else { if (is_verbose) g_print("Image %s saved\n", file_name.c_str()); owner_->get_controller()->add_frame_signal_(current_clip_id, new_image_number); thisclip->remove_first_if_more_than(owner_->get_configuration()->get_max_images_per_clip()); } }
void CBasinSadlListView::pasteClip(const Clip& clp) { Elev_intvl prom; Elevation omp; CPromDoc *doc=GetDocument(); Basin_saddle *new_bs; list_fmt.set(GetDocument()->data); doc->tree_flip_drain(); int old_size=GetListCtrl().GetItemCount(); unsigned i,n=clp.ftr_count(); doc->update_sadl_prom_info(); if (list_filter.ridge) doc->update_ridge_info(); for (i=0; i<n; ++i) { new_bs=(Basin_saddle *)clp.list[i]; list_filter.get_prom(new_bs->prom,prom.high,omp); prom.low=new_bs->extreme_prom(LO_END); bs_list.push_back(PromListItem(*new_bs,prom)); if (list_filter.offmap) bs_list.back().offmap_prom=omp; if (doc->is_drainage) bs_list.back().transform(-1); AddBlankItem(*new_bs,clp.type[i]); } doc->tree_flip_drain(); for (i=0; i<n; ++i) UpdateItem(i+old_size); setItemIndicators(); }
bool CBasinSadlListView::CanPaste(const Clip& clp) const { unsigned n=clp.ftr_count(); for (unsigned i=0; i<n; ++i) if (clp.type[i]!=FT_BASINSADL) return false; return true; }
void Shop::ShopItem::choose(squadst& customers, int& buyer) const { if (is_available()) { ledger.subtract_funds(adjusted_price(), EXPENSE_SHOPPING); switch (itemclass_) { case WEAPON: { Weapon* i = new Weapon(*weapontype[getweapontype(itemtypename_)]); customers.squad[buyer]->give_weapon(*i, &location[customers.squad[0]->base]->loot); if (i->empty()) delete i; else location[customers.squad[0]->base]->loot.push_back(i); break; } case CLIP: { Clip* i = new Clip(*cliptype[getcliptype(itemtypename_)]); customers.squad[buyer]->take_clips(*i, 1); if (i->empty()) delete i; else location[customers.squad[0]->base]->loot.push_back(i); break; } case ARMOR: { Armor* i = new Armor(*armortype[getarmortype(itemtypename_)]); customers.squad[buyer]->give_armor(*i, &location[customers.squad[0]->base]->loot); if (i->empty()) delete i; else location[customers.squad[0]->base]->loot.push_back(i); break; } case LOOT: { Loot* i = new Loot(*loottype[getloottype(itemtypename_)]); location[customers.squad[0]->base]->loot.push_back(i); break; } } } }
void ImportDatabase::Load( const QString& file ) { QFile databaseFile(URI("workgfx:"+file).AsString()); if (databaseFile.open(QIODevice::ReadOnly)) { QDomDocument document; document.setContent(&databaseFile); QDomElement rootElement = document.documentElement(); QDomNodeList importerList = rootElement.childNodes(); for (int optionsIndex = 0; optionsIndex < importerList.size(); optionsIndex++) { ImportOptions* options = new ImportOptions(); QDomElement optionsNode = importerList.at(optionsIndex).toElement(); options->name = optionsNode.attribute("name", ""); Q_ASSERT_X(!options->name.isEmpty(), "ImportDatabase.cpp", "Corrupt batch info file!"); ImportOptions::MeshFlag meshFlags = (ImportOptions::MeshFlag)optionsNode.attribute("flags", "0").toInt(); ImportOptions::ImportMode importMode = (ImportOptions::ImportMode)optionsNode.attribute("mode", "0").toInt(); options->SetExportFlags(meshFlags); options->SetExportMode(importMode); QDomNodeList takeNodes = optionsNode.childNodes(); for (int takeIndex = 0; takeIndex < takeNodes.size(); takeIndex++) { QDomElement takeElement = takeNodes.at(takeIndex).toElement(); if (takeElement.tagName() == "Take") { Take* take = new Take; take->SetName(takeElement.attribute("name", "")); QDomNodeList clipElements = takeElement.childNodes(); for (int clipIndex = 0; clipIndex < clipElements.size(); clipIndex++) { Clip* clip = new Clip; QDomElement clipElement = clipElements.at(clipIndex).toElement(); clip->SetName(clipElement.attribute("name", "")); clip->SetStart(clipElement.attribute("start", "0").toInt()); clip->SetEnd(clipElement.attribute("end", "0").toInt()); clip->SetPreInfinity((Clip::InfinityType)clipElement.attribute("pre", "0").toInt()); clip->SetPostInfinity((Clip::InfinityType)clipElement.attribute("post", "0").toInt()); Q_ASSERT_X(!clip->GetName().isEmpty(), "BatchAttributes.cpp", "Corrupt batch info file!"); take->AddClip(clip); } options->AddTake(take); } } this->importOptions[options->name] = options; } } }
void Scene::addClip( Clip *clip, int track ) { QMutexLocker ml( &mutex ); double margin = profile.getVideoFrameDuration() / 4.0; Track *t = tracks[track]; int i = 0, cc = t->clipCount(); while ( i < cc ) { Clip *c = t->clipAt( i ); if ( clip->position() < c->position() ) { t->insertClipAt( clip, i ); updateTransitions( clip, track, margin ); update = true; return; } ++i; } t->insertClipAt( clip, i ); updateTransitions( clip, track, margin ); }
/** * Called on every frame. * * (Clutter Timeline handler) * Times the playback frames and display it if it's time to do so. * * Prints the rendering FPS information. * Calls Controller::update_playback_image * We could draw some stuff using OpenGL in this callback. */ void Gui::on_render_frame(ClutterTimeline * /*timeline*/, gint /*msecs*/, gpointer user_data) { // Prints rendering FPS information Gui *context = static_cast<Gui*>(user_data); context->owner_->check_for_messages(); bool verbose = context->owner_->get_configuration()->get_verbose(); Clip *thisclip = context->owner_->get_current_clip(); // calculate rendering FPS context->fps_calculation_timer_.tick(); ++context->number_of_frames_in_last_second_; if (context->fps_calculation_timer_.get_elapsed() >= 1.0f) { if (verbose) std::cout << "Rendering FPS: " << context->number_of_frames_in_last_second_ << std::endl; context->rendering_fps_ = context->number_of_frames_in_last_second_; context->number_of_frames_in_last_second_ = 0; context->fps_calculation_timer_.reset(); } // Display info: if (context->enable_info_) context->update_info_text(); context->info_window_.update_info_window(); context->owner_->get_controller()->update_playback_image(); //TODO:2010-08-26:aalex:connect to Controller's on_no_image_to_play if(thisclip->size() > 0) { if (context->current_layout_ != LAYOUT_LIVEFEED_ONLY) clutter_actor_show_all(CLUTTER_ACTOR(context->playback_group_)); else clutter_actor_hide_all(CLUTTER_ACTOR(context->playback_group_)); } else { clutter_actor_hide_all(CLUTTER_ACTOR(context->playback_group_)); } // // This is just a test // static float rot = 0.0f; // rot += 1.0f; // clutter_actor_set_rotation(CLUTTER_ACTOR(context->live_input_texture_), CLUTTER_Z_AXIS, rot, 160.0f, 120.0f, 0.0f); }
Clip* Scene::duplicateClip(Clip *c) { Clip *nc = createClip( c->getSource(), c->position(), c->start(), c->length() ); nc->setFrameDuration( profile.getVideoFrameDuration() ); nc->setSpeed( c->getSpeed() ); Transition *t = c->getTransition(); nc->setTransition( t ? new Transition(t) : NULL ); FilterCollection *fc = FilterCollection::getGlobalInstance(); for ( int i = 0; i < c->videoFilters.count(); ++i ) { QSharedPointer<GLFilter> f = c->videoFilters.at( i ); for ( int j = 0; j < fc->videoFilters.count(); ++j ) { if ( fc->videoFilters[ j ].identifier == f->getIdentifier() ) { QSharedPointer<Filter> nf = fc->videoFilters[ j ].create(); f->duplicateFilter( nf ); GLFilter *gf = (GLFilter*)nf.data(); if ( nf->getIdentifier() == "GLCustom" ) { GLCustom *gc = (GLCustom*)gf; gc->setCustomParams( f->getParameters().last()->value.toString() ); } else if ( nf->getIdentifier() == "GLStabilize" ) { GLStabilize *gs = (GLStabilize*)gf; gs->setSource( nc->getSource() ); } nc->videoFilters.append( nf.staticCast<GLFilter>() ); break; } } } for ( int i = 0; i < c->audioFilters.count(); ++i ) { QSharedPointer<AudioFilter> f = c->audioFilters.at( i ); for ( int j = 0; j < fc->audioFilters.count(); ++j ) { if ( fc->audioFilters[ j ].identifier == f->getIdentifier() ) { QSharedPointer<Filter> nf = fc->audioFilters[ j ].create(); f->duplicateFilter( nf ); nc->audioFilters.append( nf.staticCast<AudioFilter>() ); break; } } } return nc; }
void Scene::updateTransitions( Clip *clip, int track, double margin ) { Track *t = tracks[track]; int index = t->indexOf( clip ); if ( index > 0 ) { Clip *c = t->clipAt( index - 1 ); if ( clip->position() < c->position() + c->length() - margin ) clip->setTransition( c->position() + c->length() - clip->position() ); } if ( index < t->clipCount() - 1 ) { Clip *c = t->clipAt( index + 1 ); if ( c->position() < clip->position() + clip->length() - margin ) c->setTransition( clip->position() + clip->length() - c->position() ); } }
void print(int divx, int divy, int red, int green, int blue, Clip clip, int*** buffer) { for(int i = 0; i < lines.size(); i++){ Line temp( lines[i].getFirstPoint().getAxis(), lines[i].getFirstPoint().getOrdinat(), lines[i].getSecondPoint().getAxis(), lines[i].getSecondPoint().getOrdinat() ); bool print = clip.clipLine(temp); if (print) temp.print(divx, divy, red, green, blue, buffer); } }
double Scene::nextEdge(double pts) { double margin = profile.getVideoFrameDuration() / 4.0; double npts = 0, max = 0; for ( int i = 0; i < tracks.count(); ++i ) { if ( !tracks[ i ]->clipCount() ) continue; Clip *c = tracks[ i ]->clipAt( tracks[ i ]->clipCount() - 1 ); double d = c->position() + c->length(); if ( d > max ) max = d; } npts = max; for ( int i = 0; i < tracks.count(); ++i ) { Track *t = tracks[ i ]; for ( int j = 0; j < t->clipCount(); ++j ) { Clip *c = t->clipAt( j ); double pos = c->position() - margin; if ( pos > pts && pos < npts ) { npts = pos + margin; } else { pos += c->length(); if ( pos > pts && pos < npts ) { npts = pos + margin; } } } } return (qAbs(npts - max) < 1) ? max - profile.getVideoFrameDuration() : npts; }
WFMath::Polygon<2> sutherlandHodgmanKernel(const WFMath::Polygon<2>& inpoly, Clip clipper) { WFMath::Polygon<2> outpoly; if (!inpoly.isValid()) return inpoly; std::size_t points = inpoly.numCorners(); if (points < 3) return outpoly; // i.e an invalid result Point2 lastPt = inpoly.getCorner(points - 1); bool lastInside = clipper.inside(lastPt); for (std::size_t p = 0; p < points; ++p) { Point2 curPt = inpoly.getCorner(p); bool inside = clipper.inside(curPt); if (lastInside) { if (inside) { // emit curPt outpoly.addCorner(outpoly.numCorners(), curPt); } else { // emit intersection of edge with clip line outpoly.addCorner(outpoly.numCorners(), clipper.clip(lastPt, curPt)); } } else { if (inside) { // emit both outpoly.addCorner(outpoly.numCorners(), clipper.clip(lastPt, curPt)); outpoly.addCorner(outpoly.numCorners(), curPt); } else { // don't emit anything } } // last was outside lastPt = curPt; lastInside = inside; } return outpoly; }
bool Scene::canSplitClip(Clip *clip, int track, double pts) { double margin = profile.getVideoFrameDuration() / 4.0; pts = nearestPTS( pts, profile.getVideoFrameDuration() ); double start = clip->position(); if (clip->getTransition()) { start += clip->getTransition()->length(); } double end = clip->position() + clip->length(); Track *t = tracks[track]; int cc = t->clipCount(); int index = t->indexOf(clip); if (index > -1 && index < cc - 1) { Clip *next = t->clipAt(index + 1); if (next->getTransition()) { end -= next->getTransition()->length() + profile.getVideoFrameDuration(); } } return (pts > start + profile.getVideoFrameDuration() - margin && pts < end - profile.getVideoFrameDuration() + margin ); }
void Scene::resizeStart( Clip *clip, double newPos, double newLength, int track ) { QMutexLocker ml( &mutex ); if ( clip->position() == newPos && clip->length() == newLength ) return; double margin = profile.getVideoFrameDuration() / 4.0; int insert, self = 0; Track *t = tracks[track]; insert = t->clipCount(); for ( int i = 0; i < t->clipCount(); ++i ) { Clip *c = t->clipAt( i ); if ( c == clip ) { ++self; continue; } if ( newPos < c->position() ) { insert = i; break; } } insert -= self; double old = clip->position(); removeTransitions( clip, track, track, insert, newPos, newLength, margin ); t->removeClip( clip ); t->insertClipAt( clip, insert ); if ( clip->getSource()->getType() == InputBase::FFMPEG && clip->getSpeed() >= 0 ) clip->setStart( clip->start() + ((clip->length() - newLength) * qAbs(clip->getSpeed())) ); clip->setLength( newLength ); clip->setPosition( newPos ); updateTransitions( clip, track, margin ); clip->setInput( NULL ); update = updateCurrentPosition( qMin( old, clip->position() ), qMax( old, clip->position() ) ); }
double Scene::previousEdge(double pts) { double margin = profile.getVideoFrameDuration() / 4.0; double npts = 0; for ( int i = 0; i < tracks.count(); ++i ) { Track *t = tracks[ i ]; for ( int j = t->clipCount() -1; j > -1; --j ) { Clip *c = t->clipAt( j ); double pos = c->position() + c->length() + margin; if ( pos < pts && pos > npts ) { npts = pos; } else { pos -= c->length(); if ( pos < pts && pos > npts ) { npts = pos; } } } } return npts; }
bool Application::save_project(std::string &file_name) { namespace ss = statesaving; char buff[256]; // buff for node names and int properties xmlDocPtr doc = xmlNewDoc(XMLSTR "1.0"); // "project" node with its "name" attribute xmlNodePtr root_node = xmlNewNode(NULL, XMLSTR ss::ROOT_NODE); xmlDocSetRootElement(doc, root_node); xmlNewProp(root_node, XMLSTR ss::PROJECT_NAME_ATTR, XMLSTR ss::DEFAULT_PROJECT_NAME); xmlNewProp(root_node, XMLSTR ss::PROJECT_VERSION_ATTR, XMLSTR PACKAGE_VERSION); sprintf(buff, "%d", get_current_clip_number()); xmlNewProp(root_node, XMLSTR ss::CURRENT_CLIP_ATTR, XMLSTR buff); // "clips" node xmlNodePtr clips_node = xmlNewChild(root_node, NULL, XMLSTR ss::CLIPS_NODE, NULL); // No text contents for (ClipIterator iter = clips_.begin(); iter != clips_.end(); ++iter) { Clip *clip = iter->second.get(); if (clip->size() > 0) // do not save empty clips { xmlNodePtr clip_node = xmlNewChild(clips_node, NULL, XMLSTR ss::CLIP_NODE, NULL); // clip ID: sprintf(buff, "%d", clip->get_id()); xmlNewProp(clip_node, XMLSTR ss::CLIP_ID_PROPERTY, XMLSTR buff); // clip FPS: sprintf(buff, "%d", clip->get_playhead_fps()); xmlNewProp(clip_node, XMLSTR ss::CLIP_FPS_PROPERTY, XMLSTR buff); // clip direction: xmlNewProp(clip_node, XMLSTR ss::CLIP_DIRECTION_PROPERTY, XMLSTR clip->get_direction().c_str()); // images: xmlNodePtr images_node = xmlNewChild(clip_node, NULL, XMLSTR ss::IMAGES_NODE, NULL); for (unsigned int image_num = 0; image_num < clip->size(); image_num++) { Image *image = clip->get_image(image_num); xmlNodePtr image_node = xmlNewChild(images_node, NULL, XMLSTR ss::IMAGE_NODE, NULL); xmlNewProp(image_node, XMLSTR ss::IMAGE_NAME_ATTR, XMLSTR image->get_name().c_str()); } } } // Save document to file xmlSaveFormatFileEnc(file_name.c_str(), doc, "UTF-8", 1); if (config_->get_verbose()) std::cout << "Saved the project to " << file_name << std::endl; // Free the document + global variables that may have been allocated by the parser. xmlFreeDoc(doc); xmlCleanupParser(); return true; }