/** * @file Picture.cpp * @author Charles B. Owen */ #include "pch.h" #include <wx/stdpaths.h> #include "Picture.h" #include "PictureObserver.h" #include "Actor.h" using namespace std; /** * Constructor */ Picture::Picture() { } /** * Set the current animation time * * This forces the animation of all * objects to the current animation location. * @param time The new time. */ void Picture::SetAnimationTime(double time) { mTimeline.SetCurrentTime(time); UpdateObservers(); for (auto actor : mActors) { actor->GetKeyframe(); } } /** * Get the current animation time. * @return The current animation time */ double Picture::GetAnimationTime() { return mTimeline.GetCurrentTime(); } /** * Add an observer to this picture. * @param observer The observer to add */ void Picture::AddObserver(PictureObserver* observer) { mObservers.push_back(observer); } /** * Remove an observer from this picture * @param observer The observer to remove */ void Picture::RemoveObserver(PictureObserver* observer) { auto loc = find(std::begin(mObservers), std::end(mObservers), observer); if (loc != std::end(mObservers)) { mObservers.erase(loc); } } /** * Update all observers to indicate the picture has changed. */ void Picture::UpdateObservers() { for (auto observer : mObservers) { observer->UpdateObserver(); } } /** * Draw this picture on a device context * @param graphics The device context to draw on */ void Picture::Draw(std::shared_ptr<wxGraphicsContext> graphics) { for (auto actor : mActors) { actor->Draw(graphics); } } /** * Add an actor to this drawable. * @param actor Actor to add */ void Picture::AddActor(std::shared_ptr<Actor> actor) { mActors.push_back(actor); actor->SetPicture(this); } /** * Save the picture animation to a file * @param filename File to save to. */ void Picture::Save(const wxString& filename) { wxXmlDocument xmlDoc; auto root = new wxXmlNode(wxXML_ELEMENT_NODE, L"anim"); xmlDoc.SetRoot(root); // Save the timeline animation into the XML mTimeline.Save(root); // // It is possible to add attributes to the root node here // // create a new child node auto machine1 = new wxXmlNode(wxXML_ELEMENT_NODE, L"Machine1"); machine1->AddAttribute(L"Number", wxString::Format(wxT("%i"), mMachine1->GetMachineNumber())); machine1->AddAttribute(L"StartTime", wxString::Format(wxT("%i"), mMachine1->GetStartTime())); machine1->AddAttribute(L"EndTime", wxString::Format(wxT("%i"), mMachine1->GetEndTime())); auto machine2 = new wxXmlNode(wxXML_ELEMENT_NODE, L"Machine2"); machine2->AddAttribute(L"Number", wxString::Format(wxT("%i"), mMachine2->GetMachineNumber())); machine2->AddAttribute(L"StartTime", wxString::Format(wxT("%i"), mMachine2->GetStartTime())); machine2->AddAttribute(L"EndTime", wxString::Format(wxT("%i"), mMachine2->GetEndTime())); root->AddChild(machine1); root->AddChild(machine2); if(!xmlDoc.Save(filename, wxXML_NO_INDENTATION)) { wxMessageBox(L"Write to XML failed"); return; } } /** * Load a picture animation from a file * @param filename file to load from */ void Picture::Load(const wxString& filename) { wxXmlDocument xmlDoc; if(!xmlDoc.Load(filename)) { wxMessageBox(L"Unable to load Animation file"); return; } // Get the XML document root node auto root = xmlDoc.GetRoot(); // Load the animation from the XML mTimeline.Load(root); // // It is possible to load attributes from the root node here // // mSomething = root->GetAttribute(L"something", L"default"); auto child = root->GetChildren(); for( ; child; child=child->GetNext()) { auto name = child->GetName(); if(name == L"Machine1") { mMachine1->SetNumber(wxAtoi(child->GetAttribute(L"Number", L"1"))); mMachine1->SetStartTime(wxAtoi(child->GetAttribute(L"StartTime", L"30"))); mMachine1->SetEndTime(wxAtoi(child->GetAttribute(L"EndTime", L"150"))); } else if(name == L"Machine2") { mMachine2->SetNumber(wxAtoi(child->GetAttribute(L"Number", L"2"))); mMachine2->SetStartTime(wxAtoi(child->GetAttribute(L"StartTime", L"150"))); mMachine2->SetEndTime(wxAtoi(child->GetAttribute(L"EndTime", L"300"))); } } SetAnimationTime(0); UpdateObservers(); }