///////////////////////////////////////////////////////////////////////////// // Name: MenuObject.cpp // Purpose: The class to store a DVD Menu Object // Author: Alex Thuering // Created: 04.11.2006 // RCS-ID: $Id: MenuObject.cpp,v 1.3 2007/06/10 13:24:53 ntalex Exp $ // Copyright: (c) Alex Thuering // Licence: GPL ///////////////////////////////////////////////////////////////////////////// #include "Menu.h" #include #include #include #include #define BUTTONS_DIR wxFindDataDirectory(_T("buttons")) ///////////////////////////// MenuAction ///////////////////////////////////// wxString MenuAction::GetAction() { wxString action = m_action; if (!action.length()) { int tsi = GetActionTsi(); bool menu = GetActionPgci()%2 == 0; int pgci = GetActionPgci()/2; action = _T("jump "); if (tsi == -1) action += _T("vmgm "); else if (tsi >= 0) action += wxString::Format(_T("titleset %d "), tsi+1); if (menu) action += _T("menu"); else action += _T("title"); if (!menu || pgci>0 || tsi == -2) action += wxString::Format(_T(" %d"), pgci+1); if (GetActionChapter() > 0) action += wxString::Format(_T(" chapter %d"), GetActionChapter()+1); action += _T(";"); } return action; } wxXmlNode* MenuAction::GetXML(DVDFileType type, bool button) { wxXmlNode* rootNode = new wxXmlNode(wxXML_ELEMENT_NODE, type == DVDAUTHOR_XML ? wxT("button") : wxT("action")); switch (type) { case DVDSTYLER_XML: if (!button) rootNode->AddProperty(_T("id"), GetId()); if (!GetCustomAction().length()) { if (GetActionTsi()>-2) rootNode->AddProperty(_T("tsi"), wxString::Format(_T("%d"), GetActionTsi())); rootNode->AddProperty(_T("pgci"), wxString::Format(_T("%d"), GetActionPgci())); rootNode->AddProperty(_T("chapter"), wxString::Format(_T("%d"), GetActionChapter())); } else rootNode->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, GetCustomAction())); break; case SPUMUX_XML: rootNode->AddProperty(_T("name"), GetId()); break; case DVDAUTHOR_XML: rootNode->AddProperty(_T("name"), GetId()); rootNode->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, GetAction())); break; default: break; } return rootNode; } bool MenuAction::PutXML(wxXmlNode* node, bool button) { if (!button) node->GetPropVal(_T("id"), &m_id); long lval; wxString val; if (node->GetPropVal(_T("tsi"), &val) && val.ToLong(&lval)) SetActionTsi(lval); if (node->GetPropVal(_T("pgci"), &val) && val.ToLong(&lval)) SetActionPgci(lval); if (node->GetPropVal(_T("chapter"), &val) && val.ToLong(&lval)) SetActionChapter(lval); if (node->GetChildren() && (node->GetChildren()->GetType() == wxXML_TEXT_NODE || node->GetChildren()->GetType() == wxXML_CDATA_SECTION_NODE)) SetCustomAction(node->GetChildren()->GetContent().Strip(wxString::both)); return true; } ///////////////////////////// MenuObject ///////////////////////////////////// MenuObject::MenuObject(Menu* menu, wxString fileName, int x, int y, wxString param) { m_svg = menu->GetSVG(); m_use = NULL; m_symbol = NULL; m_fileName = fileName; m_button = false; m_actionTsi = -2; // current titleset m_actionPgci = 1; m_actionChapter = 0; m_playAll = false; m_audio = -1; m_subtitle = -1; m_defaultSize = true; m_defaultSizeWidth = m_defaultSizeHeight = 0; m_minSizeWidth = m_minSizeHeight = 0; if (fileName.length()) Init(fileName, x, y, param); } MenuObject::~MenuObject() { WX_CLEAR_ARRAY(m_params) if (m_use) m_use->GetParent()->RemoveChild(m_use); if (m_symbol) m_symbol->GetParent()->RemoveChild(m_symbol); } bool MenuObject::Init(wxString fileName, int x, int y, wxString param) { m_fileName = fileName; wxXmlDocument xml; xml.Load(fileName); if (!xml.GetRoot()) return false; wxXmlNode* root = xml.GetRoot(); m_button = root->GetName() == wxT("button"); m_title = XmlReadValue(root, wxT("title")); if (m_id.length()) // load button { m_symbol = (wxSVGSVGElement*) m_svg->GetElementById(wxT("s_") + m_id); m_use = (wxSVGUseElement*) m_svg->GetElementById(m_id); // fix old format (1.5b1 - 1.5b3) if (m_symbol && m_symbol->GetDtd() == wxSVG_SYMBOL_ELEMENT) { // replace symbol element with svg element wxSVGSymbolElement* symbol = (wxSVGSymbolElement*) m_symbol; m_symbol = new wxSVGSVGElement(); m_symbol->SetId(symbol->GetId()); m_symbol->SetViewBox(symbol->GetViewBox()); m_symbol->SetPreserveAspectRatio(symbol->GetPreserveAspectRatio()); wxXmlElement* child = symbol->GetChildren(); while (child) { m_symbol->AddChild(child->CloneNode()); child = child->GetNext(); } wxXmlElement* parent = symbol->GetParent(); parent->RemoveChild(symbol); parent->AddChild(m_symbol); // remove id prefix child = m_symbol->GetChildren(); while (child) { wxSVGElement& elem = *(wxSVGElement*) child; if (elem.GetId().length()) elem.SetId(elem.GetId().AfterFirst(wxT('_')).AfterFirst(wxT('_'))); child = child->GetNext(); } } } else // create new button m_id = GenerateId(m_button ? wxT("button") : wxT("obj")); wxXmlNode* svgNode = XmlFindNode(root, wxT("svg")); if (svgNode) { wxSVGDocument svg; LoadSVG(svg, svgNode); wxSVGSVGElement* root = svg.GetRootElement(); if (root) { m_defaultSizeWidth = root->GetWidth().GetBaseVal(); m_defaultSizeHeight = root->GetHeight().GetBaseVal(); if (!m_symbol) AddSymol(m_id, root); if (!m_use) AddUse(m_id, x, y, m_defaultSizeWidth, m_defaultSizeHeight); } } wxXmlNode* paramsNode = XmlFindNode(root, wxT("parameters")); if (paramsNode) { wxXmlNode* child = paramsNode->GetChildren(); while (child) { if (child->GetType() == wxXML_ELEMENT_NODE && child->GetName() == wxT("parameter")) { MenuObjectParam* param = new MenuObjectParam; param->title = XmlReadValue(child, wxT("title")); param->name = XmlReadValue(child, wxT("name")); param->type = XmlReadValue(child, wxT("type")); param->element = XmlReadValue(child, wxT("element")); param->attribute = XmlReadValue(child, wxT("attribute")); param->changeable = XmlFindNode(child, wxT("changeable")) != NULL && param->type == wxT("colour"); m_params.Add(param); if (param->changeable) { param->changeable = false; param->normalColour = GetParamColour(param->name); wxCSSStyleDeclaration style; style.SetProperty(wxCSS_PROPERTY_STROKE, XmlReadValue(child, wxT("default-value/highlighted"))); param->highlightedColour = style.GetStroke().GetRGBColor(); style.SetProperty(wxCSS_PROPERTY_STROKE, XmlReadValue(child, wxT("default-value/selected"))); param->selectedColour = style.GetStroke().GetRGBColor(); param->changeable = true; } } child = child->GetNext(); } } m_initParameter = XmlReadValue(root, wxT("init-parameter")); if (m_initParameter.length() && param.length()) SetParam(m_initParameter, param); wxXmlNode* defaultSizeNode = XmlFindNode(root, wxT("default-size")); if (defaultSizeNode) { m_defaultSizeElement = XmlReadValue(defaultSizeNode, wxT("element")); long val; if (XmlReadValue(defaultSizeNode, wxT("width")).ToLong(&val)) m_defaultSizeWidth = val; if (XmlReadValue(defaultSizeNode, wxT("height")).ToLong(&val)) m_defaultSizeHeight = val; } wxXmlNode* minSizeNode = XmlFindNode(root, wxT("min-size")); if (minSizeNode) { m_minSizeElement = XmlReadValue(minSizeNode, wxT("element")); long val; if (XmlReadValue(minSizeNode, wxT("width")).ToLong(&val)) m_minSizeWidth = val; if (XmlReadValue(minSizeNode, wxT("height")).ToLong(&val)) m_minSizeHeight = val; } UpdateSize(); return true; } bool MenuObject::LoadSVG(wxSVGDocument& svg, wxXmlNode* node) { bool res; wxXmlDocument xml; xml.SetRoot(node->CloneNode()); wxMemoryOutputStream output; xml.Save(output); #if wxCHECK_VERSION(2,6,0) wxMemoryInputStream input(output); res = svg.Load(input); #else char* data = new char[output.GetSize()]; output.CopyTo(data, output.GetSize()); wxMemoryInputStream input(data, output.GetSize()); res = svg.Load(input); delete[] data; #endif return res; } wxString MenuObject::GenerateId(wxString prefix) { int i = 1; while(1) { wxString id = prefix + wxString::Format(wxT("%02d"), i); if (m_svg->GetElementById(id) == NULL) return id; i++; } return wxT(""); } MenuObjectParam* MenuObject::GetObjectParam(wxString name) { for (int i=0; i<(int)m_params.Count(); i++) { if (m_params[i]->name == name) return m_params[i]; } return NULL; } MenuObjectParam* MenuObject::GetInitParam() { if (!m_initParameter.length()) return NULL; return GetObjectParam(m_initParameter); } wxSVGSVGElement* MenuObject::AddSymol(wxString id, wxSVGElement* content) { m_symbol = new wxSVGSVGElement; m_symbol->SetId(wxT("s_") + id); m_svg->GetElementById(wxT("defs"))->AppendChild(m_symbol); if (content->GetDtd() == wxSVG_SVG_ELEMENT) { m_symbol->SetViewBox(((wxSVGSVGElement*) content)->GetViewBox()); m_symbol->SetPreserveAspectRatio(((wxSVGSVGElement*) content)->GetPreserveAspectRatio()); } else if (content->GetDtd() == wxSVG_SYMBOL_ELEMENT) { m_symbol->SetViewBox(((wxSVGSymbolElement*) content)->GetViewBox()); m_symbol->SetPreserveAspectRatio(((wxSVGSymbolElement*) content)->GetPreserveAspectRatio()); } wxXmlElement* child = content->GetChildren(); while (child) { m_symbol->AppendChild(((wxSVGSVGElement*)child)->CloneNode()); child = child->GetNext(); } return m_symbol; } void MenuObject::AddUse(wxString id, int x, int y, int width, int height) { m_use = new wxSVGUseElement; m_use->SetId(id); m_use->SetHref(wxT("#s_") + id); m_use->SetX(x); m_use->SetY(y); m_use->SetWidth(width); m_use->SetHeight(height); if (IsButton()) m_svg->GetElementById(wxT("buttons"))->AppendChild(m_use); else m_svg->GetElementById(wxT("objects"))->AppendChild(m_use); } int MenuObject::GetX() { return m_use->GetX().GetBaseVal(); } void MenuObject::SetX(int value) { m_use->SetX(value); } int MenuObject::GetY() { return m_use->GetY().GetBaseVal(); } void MenuObject::SetY(int value) { m_use->SetY(value); } int MenuObject::GetWidth() { return m_use->GetWidth().GetBaseVal(); } void MenuObject::SetWidth(int value) { m_use->SetWidth(value); } int MenuObject::GetHeight() { return m_use->GetHeight().GetBaseVal(); } void MenuObject::SetHeight(int value) { m_use->SetHeight(value); } void MenuObject::FixSize(int& width, int& height) { if (m_defaultSize) { width = m_defaultSizeWidth; height = m_defaultSizeHeight; if (m_defaultSizeElement.length()) { wxSVGElement* elem = (wxSVGElement*) m_symbol->GetElementById(m_defaultSizeElement); if (elem) { if (elem->GetDtd() == wxSVG_IMAGE_ELEMENT) { width += ((wxSVGImageElement*)elem)->GetDefaultWidth(); height += ((wxSVGImageElement*)elem)->GetDefaultHeight(); } else { wxSVGRect bbox = wxSVGLocatable::GetElementResultBBox(elem); width += (int)bbox.GetWidth(); height += (int)bbox.GetHeight(); } } } } else { int w = m_minSizeWidth; int h = m_minSizeHeight; if (m_minSizeElement.length()) { wxSVGElement* elem = (wxSVGElement*) m_symbol->GetElementById(m_minSizeElement); if (elem) { wxSVGRect bbox = wxSVGLocatable::GetElementResultBBox(elem); w += (int)bbox.GetWidth(); h += (int)bbox.GetHeight(); } } width = wxMax(width, w); height = wxMax(height, h); } } void MenuObject::UpdateSize() { int width = GetWidth(); int height = GetHeight(); FixSize(width, height); SetWidth(width); SetHeight(height); } wxString MenuObject::GetParam(wxString name, MenuButtonState state) { MenuObjectParam* param = GetObjectParam(name); if (!param) return wxT(""); wxSVGElement* elem = (wxSVGElement*) m_symbol->GetElementById(param->element); if (!elem) return wxT(""); if (param->attribute.length()) return elem->GetAttribute(param->attribute); else if (elem->GetDtd() == wxSVG_TEXT_ELEMENT) return elem->GetChildren() ? elem->GetChildren()->GetContent() : wxT(""); return wxT(""); } void MenuObject::SetParam(wxString name, wxString value, MenuButtonState state) { MenuObjectParam* param = GetObjectParam(name); if (!param) return; wxSVGElement* elem =(wxSVGElement*) m_symbol->GetElementById(param->element); if (!elem) return; if (param->attribute.length()) elem->SetAttribute(param->attribute, value); else if (elem->GetDtd() == wxSVG_TEXT_ELEMENT) { if (!elem->GetChildren()) return; elem->GetChildren()->SetContent(value); ((wxSVGTextElement*)elem)->SetCanvasItem(NULL); } } int MenuObject::GetParamInt(wxString name, MenuButtonState state) { long lval = 0; GetParam(name, state).ToLong(&lval); return lval; } void MenuObject::SetParamInt(wxString name, int value, MenuButtonState state) { SetParam(name, wxString::Format(wxT("%d"), value), state); } wxFont MenuObject::GetParamFont(wxString name, MenuButtonState state) { MenuObjectParam* param = GetObjectParam(name); if (!param) return wxFont(20, wxFONTFAMILY_DEFAULT, wxNORMAL, wxNORMAL, false); wxSVGElement* elem = (wxSVGElement*) m_symbol->GetElementById(param->element); if (!elem) return wxFont(20, wxFONTFAMILY_DEFAULT, wxNORMAL, wxNORMAL, false); int size = 20; double dval; if (elem->GetAttribute(wxT("font-size")).ToDouble(&dval)) size = (int)dval; int style = wxFONTSTYLE_NORMAL; wxString styleStr = elem->GetAttribute(wxT("font-style")); if (styleStr == wxT("italic")) style = wxFONTSTYLE_ITALIC; else if (styleStr == wxT("oblique")) style = wxFONTSTYLE_SLANT; wxFontWeight weight = wxFONTWEIGHT_NORMAL; wxString weightStr = elem->GetAttribute(wxT("font-weight")); if (weightStr == wxT("bold")) weight = wxFONTWEIGHT_BOLD; if (weightStr == wxT("bolder")) weight = wxFONTWEIGHT_MAX; else if (weightStr == wxT("lighter")) weight = wxFONTWEIGHT_LIGHT; wxString faceName = elem->GetAttribute(wxT("font-family")); return wxFont(size, wxFONTFAMILY_DEFAULT, style, weight, false, faceName); } void MenuObject::SetParamFont(wxString name, wxFont value, MenuButtonState state) { MenuObjectParam* param = GetObjectParam(name); if (!param) return; wxSVGElement* elem = (wxSVGElement*) m_symbol->GetElementById(param->element); if (!elem) return; elem->SetAttribute(wxT("font-size"), wxString::Format(wxT("%d"), value.GetPointSize())); wxString styleStr = wxT("normal"); if (value.GetStyle() == wxFONTSTYLE_ITALIC) styleStr = wxT("italic"); else if (value.GetStyle() == wxFONTSTYLE_SLANT) styleStr = wxT("oblique"); elem->SetAttribute(wxT("font-style"), styleStr); wxString weightStr = wxT("normal"); if (value.GetWeight() == wxFONTWEIGHT_BOLD) weightStr = wxT("bold"); if (value.GetWeight() == wxFONTWEIGHT_MAX) weightStr = wxT("bolder"); else if (value.GetWeight() == wxFONTWEIGHT_LIGHT) weightStr = wxT("lighter"); elem->SetAttribute(wxT("font-weight"), weightStr); elem->SetAttribute(wxT("font-family"), value.GetFaceName()); } wxColour MenuObject::GetParamColour(wxString name, MenuButtonState state) { MenuObjectParam* param = GetObjectParam(name); if (!param) return wxT(""); if (param->changeable) { switch (state) { case mbsNORMAL: return param->normalColour; case mbsHIGHLIGHTED: return param->highlightedColour; case mbsSELECTED: return param->selectedColour; } } wxSVGElement* elem = (wxSVGElement*) m_symbol->GetElementById(param->element); if (!elem) return wxT(""); if (param->attribute.length()) { const wxCSSStyleDeclaration& style = wxSVGStylable::GetElementStyle(*elem); const wxCSSValue& value = style.GetPropertyCSSValue(param->attribute); switch (value.GetCSSValueType()) { case wxCSS_PRIMITIVE_VALUE: return ((wxCSSPrimitiveValue&)value).GetRGBColorValue(); case wxCSS_SVG_COLOR: case wxCSS_SVG_PAINT: return ((wxSVGColor&)value).GetRGBColor(); default: break; } } return wxColour(); } void MenuObject::SetParamColour(wxString name, wxColour value, MenuButtonState state) { MenuObjectParam* param = GetObjectParam(name); if (!param) return; if (param->changeable) { switch (state) { case mbsNORMAL: param->normalColour = value; break; case mbsHIGHLIGHTED: param->highlightedColour = value; break; case mbsSELECTED: param->selectedColour = value; break; } } if (state != mbsNORMAL) return; wxSVGElement* elem = (wxSVGElement*) m_symbol->GetElementById(param->element); if (!elem) return; if (param->attribute.length()) { wxSVGPaint paint(value); elem->SetAttribute(param->attribute, paint.GetCSSText()); } } void MenuObject::ToFront() { wxSVGElement* parent = (wxSVGElement*) m_use->GetParent(); parent->RemoveChild(m_use); parent->AppendChild(m_use); } void MenuObject::Forward() { wxSVGElement* parent = (wxSVGElement*) m_use->GetParent(); wxSVGElement* next = (wxSVGElement*) m_use->GetNextSibling(); if (next && next->GetType() == wxXML_ELEMENT_NODE && next->GetDtd() == wxSVG_USE_ELEMENT) { parent->RemoveChild(m_use); parent->InsertChild(m_use, next->GetNextSibling()); } } void MenuObject::Backward() { wxSVGElement* parent = (wxSVGElement*) m_use->GetParent(); wxSVGElement* prev = (wxSVGElement*) m_use->GetPreviousSibling(); if (prev && prev->GetType() == wxXML_ELEMENT_NODE && prev->GetDtd() == wxSVG_USE_ELEMENT) { parent->RemoveChild(m_use); parent->InsertChild(m_use, prev); } } void MenuObject::ToBack() { wxSVGElement* parent = (wxSVGElement*) m_use->GetParent(); wxSVGElement* first = (wxSVGElement*) parent->GetFirstChild(); while (first && (first->GetType() != wxXML_ELEMENT_NODE || first->GetDtd() != wxSVG_USE_ELEMENT)) first = (wxSVGElement*) first->GetNextSibling(); if (first && first != m_use) { parent->RemoveChild(m_use); parent->InsertChild(m_use, first); } } bool MenuObject::IsFirst() { wxSVGElement* prev = (wxSVGElement*) m_use->GetPreviousSibling(); return !prev || prev->GetType() != wxXML_ELEMENT_NODE; } bool MenuObject::IsLast() { wxSVGElement* next = (wxSVGElement*) m_use->GetNextSibling(); return !next || next->GetType() != wxXML_ELEMENT_NODE; } wxImage MenuObject::GetImage(int maxWidth, int maxHeight) { if (!m_use) return wxImage(); m_svg->GetRootElement()->SetWidth(GetWidth()); m_svg->GetRootElement()->SetHeight(GetHeight()); return m_svg->Render(maxWidth, maxHeight); } wxXmlNode* MenuObject::GetXML(DVDFileType type, bool withSVG, int playAllRegister) { wxString rootName = wxT("object"); if (IsButton()) rootName = wxT("button"); wxXmlNode* rootNode = new wxXmlNode(wxXML_ELEMENT_NODE, rootName); switch (type) { case DVDSTYLER_XML: if (IsButton()) { wxXmlNode* actionNode = MenuAction::GetXML(type, true); actionNode->AddProperty(_T("playAll"), IsPlayAll() ? wxT("true") : wxT("false")); actionNode->AddProperty(_T("audio"), wxString::Format(_T("%d"), GetAudio())); actionNode->AddProperty(_T("subtitle"), wxString::Format(_T("%d"), GetSubtitle())); rootNode->AddChild(actionNode); } if (GetDirection(0).length() || GetDirection(1).length() || GetDirection(2).length() || GetDirection(3).length()) { wxXmlNode* directionNode = new wxXmlNode(wxXML_ELEMENT_NODE, _T("direction")); if (GetDirection(0).length()) directionNode->AddProperty(_T("left"), GetDirection(0)); if (GetDirection(1).length()) directionNode->AddProperty(_T("right"), GetDirection(1)); if (GetDirection(2).length()) directionNode->AddProperty(_T("up"), GetDirection(2)); if (GetDirection(3).length()) directionNode->AddProperty(_T("down"), GetDirection(3)); rootNode->AddChild(directionNode); } XmlWriteValue(rootNode, _T("filename"), GetFileName()); for (int i=0; ichangeable) { wxXmlNode* paramNode = new wxXmlNode(wxXML_ELEMENT_NODE, _T("parameter")); paramNode->AddProperty(_T("name"), param->name); paramNode->AddProperty(_T("normal"), wxSVGPaint(param->normalColour).GetCSSText()); paramNode->AddProperty(_T("highlighted"), wxSVGPaint(param->highlightedColour).GetCSSText()); paramNode->AddProperty(_T("selected"), wxSVGPaint(param->selectedColour).GetCSSText()); rootNode->AddChild(paramNode); } } rootNode->AddProperty(_T("id"), GetId()); if (IsDefaultSize()) rootNode->AddProperty(_T("defSize"), _T("true")); break; case SPUMUX_XML: { int mwidth = (int)m_svg->GetRootElement()->GetWidth().GetBaseVal()-1; int mheight = (int)m_svg->GetRootElement()->GetHeight().GetBaseVal()-1; rootNode->AddProperty(_T("name"), GetId()); rootNode->AddProperty(_T("x0"), wxString::Format(_T("%d"), GetX() > 0 ? GetX() : 0)); rootNode->AddProperty(_T("y0"), wxString::Format(_T("%d"), GetY() > 0 ? GetY() : 0)); rootNode->AddProperty(_T("x1"), wxString::Format(_T("%d"), GetX() + GetWidth() < mwidth ? GetX() + GetWidth() : mwidth)); rootNode->AddProperty(_T("y1"), wxString::Format(_T("%d"), GetY() + GetHeight() < mheight ? GetY() + GetHeight() : mheight)); if (GetDirection(0).length()) rootNode->AddProperty(_T("left"), GetDirection(0)); if (GetDirection(1).length()) rootNode->AddProperty(_T("right"), GetDirection(1)); if (GetDirection(2).length()) rootNode->AddProperty(_T("up"), GetDirection(2)); if (GetDirection(3).length()) rootNode->AddProperty(_T("down"), GetDirection(3)); break; } case DVDAUTHOR_XML: { rootNode->AddProperty(_T("name"), GetId()); wxString action = GetAction(); if (playAllRegister != -1) action = wxString::Format(wxT("g%d=%d;"), playAllRegister, IsPlayAll()) + action; rootNode->AddChild(new wxXmlNode(wxXML_TEXT_NODE, wxEmptyString, action)); break; } default: break; } if (withSVG) // used by copy & paste { rootNode->DeleteProperty(wxT("id")); wxXmlNode* svgNode = new wxXmlNode(wxXML_ELEMENT_NODE, _T("svg")); wxXmlNode* defsNode = new wxXmlNode(wxXML_ELEMENT_NODE, _T("defs")); wxSVGElement* symbol = (wxSVGElement*) m_symbol->CloneNode(); symbol->SetId(wxT("")); defsNode->AddChild(symbol); svgNode->AddChild(defsNode); svgNode->AddChild(m_use->CloneNode()); rootNode->AddChild(svgNode); } return rootNode; } bool MenuObject::PutXML(wxXmlNode* node) { m_button = node->GetName() == wxT("button"); long lval; wxString val; if (IsButton()) { wxXmlNode* actionNode = XmlFindNodeSimple(node, _T("action")); if (actionNode) { MenuAction::PutXML(actionNode, true); SetPlayAll(actionNode->GetPropVal(_T("playAll"), &val) && val == wxT("true")); if (actionNode->GetPropVal(_T("audio"), &val) && val.ToLong(&lval)) SetAudio(lval); if (actionNode->GetPropVal(_T("subtitle"), &val) && val.ToLong(&lval)) SetSubtitle(lval); } wxXmlNode* dirNode = XmlFindNodeSimple(node, _T("direction")); if (dirNode) { if (dirNode->GetPropVal(_T("left"), &val)) SetDirection(0, val); if (dirNode->GetPropVal(_T("right"), &val)) SetDirection(1, val); if (dirNode->GetPropVal(_T("up"), &val)) SetDirection(2, val); if (dirNode->GetPropVal(_T("down"), &val)) SetDirection(3, val); } } // deprecated int x = 0, y = 0; if (node->GetPropVal(_T("x"), &val) && val.ToLong(&lval)) x = (int)(lval/m_svg->GetScale()); if (node->GetPropVal(_T("y"), &val) && val.ToLong(&lval)) y = (int)(lval/m_svg->GetScale()); wxString fileName = XmlReadValue(node, _T("type")); if (fileName.length()) { wxString text = XmlReadValue(node, _T("text")); return Init(BUTTONS_DIR + wxT("text.xml"), x, y, text); } fileName = XmlReadValue(node, _T("filename")); if (!fileName.length()) return false; node->GetPropVal(_T("id"), &m_id); if (!node->GetPropVal(_T("defSize"), &val) || (val != wxT("true") && val != wxT("1"))) SetDefaultSize(false); // paste button wxXmlNode* svgNode = XmlFindNode(node, wxT("svg")); if (svgNode) { m_id = GenerateId(m_button ? wxT("button") : wxT("obj")); wxSVGDocument svg; LoadSVG(svg, svgNode); wxSVGSVGElement* root = svg.GetRootElement(); if (root && XmlFindNode(root, wxT("defs")) && XmlFindNode(root, wxT("use"))) { wxSVGElement* defsNode = (wxSVGElement*) XmlFindNode(root, wxT("defs")); wxXmlElement* child = defsNode->GetChildren(); while (child) { AddSymol(m_id, (wxSVGElement*) child); child = child->GetNext(); } wxSVGUseElement* useElem = (wxSVGUseElement*) XmlFindNode(root, wxT("use")); AddUse(m_id, useElem->GetX().GetBaseVal(), useElem->GetY().GetBaseVal(), useElem->GetWidth().GetBaseVal(), useElem->GetHeight().GetBaseVal()); } } if (!Init(fileName, x, y)) return false; wxXmlNode* child = node->GetChildren(); while (child) { if (child->GetName() == wxT("parameter")) { wxString name; wxString normal; wxString selected; wxString highlighted; if (child->GetPropVal(wxT("name"), &name) && child->GetPropVal(wxT("normal"), &normal) && child->GetPropVal(wxT("highlighted"), &highlighted) && child->GetPropVal(wxT("selected"), &selected)) { wxCSSStyleDeclaration style; style.SetProperty(wxT("fill"), normal); SetParamColour(name, style.GetFill().GetRGBColor(), mbsNORMAL); style.SetProperty(wxT("fill"), highlighted); SetParamColour(name, style.GetFill().GetRGBColor(), mbsHIGHLIGHTED); style.SetProperty(wxT("fill"), selected); SetParamColour(name, style.GetFill().GetRGBColor(), mbsSELECTED); } } child = child->GetNext(); } return true; }