void CGUI::Xeromyces_ReadStyle(XMBElement Element, CXeromyces* pFile) { // style object we're adding SGUIStyle style; CStr name; // // Read Attributes // // Now we can iterate all attributes and store XMBAttributeList attributes = Element.GetAttributes(); for (int i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); CStr attr_name (pFile->GetAttributeString(attr.Name)); // The "name" setting is actually the name of the style // and not a new default if (attr_name == "name") name = attr.Value; else style.m_SettingsDefaults[attr_name] = attr.Value.FromUTF8(); } // // Add to CGUI // m_Styles[name] = style; }
void CGUI::Xeromyces_ReadTooltip(XMBElement Element, CXeromyces* pFile) { // Read the tooltip, and store it as a specially-named object IGUIObject* object = new CTooltip; XMBAttributeList attributes = Element.GetAttributes(); for (int i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); CStr attr_name (pFile->GetAttributeString(attr.Name)); CStr attr_value (attr.Value); if (attr_name == "name") { object->SetName("__tooltip_" + attr_value); } else { object->SetSetting(attr_name, attr_value.FromUTF8()); } } AddObject(object); }
void CGUI::Xeromyces_ReadEffects(XMBElement Element, CXeromyces* pFile, SGUIImageEffects &effects) { XMBAttributeList attributes = Element.GetAttributes(); for (int i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); CStr attr_name (pFile->GetAttributeString(attr.Name)); CStrW attr_value (attr.Value.FromUTF8()); if (attr_name == "add_color") { CColor color; if (!GUI<int>::ParseColor(attr_value, color, 0.f)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else effects.m_AddColor = color; } else if (attr_name == "grayscale") { effects.m_Greyscale = true; } else { debug_warn(L"Invalid data - DTD shouldn't allow this"); } } }
void CGUI::Xeromyces_ReadIcon(XMBElement Element, CXeromyces* pFile) { // Icon we're adding SGUIIcon icon; CStr name; XMBAttributeList attributes = Element.GetAttributes(); for (int i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); CStr attr_name (pFile->GetAttributeString(attr.Name)); CStr attr_value (attr.Value); if (attr_value == "null") continue; if (attr_name == "name") name = attr_value; else if (attr_name == "sprite") icon.m_SpriteName = attr_value; else if (attr_name == "size") { CSize size; if (!GUI<CSize>::ParseString(attr_value.FromUTF8(), size)) LOGERROR(L"Error parsing '%hs' (\"%hs\") inside <icon>.", attr_name.c_str(), attr_value.c_str()); else icon.m_Size = size; } else if (attr_name == "cell_id") { int cell_id; if (!GUI<int>::ParseString(attr_value.FromUTF8(), cell_id)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\") inside <icon>.", attr_name.c_str(), attr_value.c_str()); else icon.m_CellID = cell_id; } else { debug_warn(L"Invalid data - DTD shouldn't allow this"); } } m_Icons[name] = icon; }
void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) { // style object we're adding SGUIScrollBarStyle scrollbar; CStr name; // // Read Attributes // // Now we can iterate all attributes and store XMBAttributeList attributes = Element.GetAttributes(); for (int i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); CStr attr_name = pFile->GetAttributeString(attr.Name); CStr attr_value (attr.Value); if (attr_value == "null") continue; if (attr_name == "name") name = attr_value; else if (attr_name == "show_edge_buttons") { bool b; if (!GUI<bool>::ParseString(attr_value.FromUTF8(), b)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else scrollbar.m_UseEdgeButtons = b; } if (attr_name == "width") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else scrollbar.m_Width = f; } else if (attr_name == "minimum_bar_size") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else scrollbar.m_MinimumBarSize = f; } else if (attr_name == "maximum_bar_size") { float f; if (!GUI<float>::ParseString(attr_value.FromUTF8(), f)) LOGERROR(L"GUI: Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else scrollbar.m_MaximumBarSize = f; } else if (attr_name == "sprite_button_top") scrollbar.m_SpriteButtonTop = attr_value; else if (attr_name == "sprite_button_top_pressed") scrollbar.m_SpriteButtonTopPressed = attr_value; else if (attr_name == "sprite_button_top_disabled") scrollbar.m_SpriteButtonTopDisabled = attr_value; else if (attr_name == "sprite_button_top_over") scrollbar.m_SpriteButtonTopOver = attr_value; else if (attr_name == "sprite_button_bottom") scrollbar.m_SpriteButtonBottom = attr_value; else if (attr_name == "sprite_button_bottom_pressed") scrollbar.m_SpriteButtonBottomPressed = attr_value; else if (attr_name == "sprite_button_bottom_disabled") scrollbar.m_SpriteButtonBottomDisabled = attr_value; else if (attr_name == "sprite_button_bottom_over") scrollbar.m_SpriteButtonBottomOver = attr_value; else if (attr_name == "sprite_back_vertical") scrollbar.m_SpriteBackVertical = attr_value; else if (attr_name == "sprite_bar_vertical") scrollbar.m_SpriteBarVertical = attr_value; else if (attr_name == "sprite_bar_vertical_over") scrollbar.m_SpriteBarVerticalOver = attr_value; else if (attr_name == "sprite_bar_vertical_pressed") scrollbar.m_SpriteBarVerticalPressed = attr_value; } // // Add to CGUI // m_ScrollBarStyles[name] = scrollbar; }
void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite &parent) { // Image object we're adding SGUIImage* Image = new SGUIImage; // Set defaults to "0 0 100% 100%" Image->m_TextureSize = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); Image->m_Size = CClientArea(CRect(0, 0, 0, 0), CRect(0, 0, 100, 100)); // TODO Gee: Setup defaults here (or maybe they are in the SGUIImage ctor) // // Read Attributes // // Now we can iterate all attributes and store XMBAttributeList attributes = Element.GetAttributes(); for (int i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); CStr attr_name (pFile->GetAttributeString(attr.Name)); CStrW attr_value (attr.Value.FromUTF8()); if (attr_name == "texture") { Image->m_TextureName = VfsPath("art/textures/ui") / attr_value; } else if (attr_name == "size") { CClientArea ca; if (!GUI<CClientArea>::ParseString(attr_value, ca)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_Size = ca; } else if (attr_name == "texture_size") { CClientArea ca; if (!GUI<CClientArea>::ParseString(attr_value, ca)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_TextureSize = ca; } else if (attr_name == "real_texture_placement") { CRect rect; if (!GUI<CRect>::ParseString(attr_value, rect)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_TexturePlacementInFile = rect; } else if (attr_name == "cell_size") { CSize size; if (!GUI<CSize>::ParseString(attr_value, size)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_CellSize = size; } else if (attr_name == "fixed_h_aspect_ratio") { float val; if (!GUI<float>::ParseString(attr_value, val)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_FixedHAspectRatio = val; } else if (attr_name == "round_coordinates") { bool b; if (!GUI<bool>::ParseString(attr_value, b)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_RoundCoordinates = b; } else if (attr_name == "wrap_mode") { if (attr_value == L"repeat") Image->m_WrapMode = GL_REPEAT; else if (attr_value == L"mirrored_repeat") Image->m_WrapMode = GL_MIRRORED_REPEAT; else if (attr_value == L"clamp_to_edge") Image->m_WrapMode = GL_CLAMP_TO_EDGE; else LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); } else if (attr_name == "z_level") { float z_level; if (!GUI<float>::ParseString(attr_value, z_level)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_DeltaZ = z_level/100.f; } else if (attr_name == "backcolor") { CColor color; if (!GUI<CColor>::ParseString(attr_value, color)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_BackColor = color; } else if (attr_name == "bordercolor") { CColor color; if (!GUI<CColor>::ParseString(attr_value, color)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_BorderColor = color; } else if (attr_name == "border") { bool b; if (!GUI<bool>::ParseString(attr_value, b)) LOGERROR(L"GUI: Error parsing '%hs' (\"%ls\")", attr_name.c_str(), attr_value.c_str()); else Image->m_Border = b; } else { debug_warn(L"Invalid data - DTD shouldn't allow this"); } } // Look for effects XMBElementList children = Element.GetChildNodes(); for (int i=0; i<children.Count; ++i) { XMBElement child = children.Item(i); CStr ElementName (pFile->GetElementString(child.GetNodeName())); if (ElementName == "effect") { if (Image->m_Effects) { LOGERROR(L"GUI <image> must not have more than one <effect>"); } else { Image->m_Effects = new SGUIImageEffects; Xeromyces_ReadEffects(child, pFile, *Image->m_Effects); } } else { debug_warn(L"Invalid data - DTD shouldn't allow this"); } } // // Input // parent.AddImage(Image); }
void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObject *pParent, const std::vector<std::pair<CStr, CStr> >& NameSubst, boost::unordered_set<VfsPath>& Paths) { ENSURE(pParent); int i; // Our object we are going to create IGUIObject *object = NULL; XMBAttributeList attributes = Element.GetAttributes(); // Well first of all we need to determine the type CStr type (attributes.GetNamedItem(pFile->GetAttributeID("type"))); if (type.empty()) type = "empty"; // Construct object from specified type // henceforth, we need to do a rollback before aborting. // i.e. releasing this object object = ConstructObject(type); if (!object) { // Report error that object was unsuccessfully loaded LOGERROR(L"GUI: Unrecognized object type \"%hs\"", type.c_str()); return; } // Cache some IDs for element attribute names, to avoid string comparisons #define ELMT(x) int elmt_##x = pFile->GetElementID(#x) #define ATTR(x) int attr_##x = pFile->GetAttributeID(#x) ELMT(object); ELMT(action); ELMT(repeat); ATTR(style); ATTR(type); ATTR(name); ATTR(hotkey); ATTR(z); ATTR(on); ATTR(file); // // Read Style and set defaults // // If the setting "style" is set, try loading that setting. // // Always load default (if it's available) first! // CStr argStyle (attributes.GetNamedItem(attr_style)); if (m_Styles.count("default") == 1) object->LoadStyle(*this, "default"); if (! argStyle.empty()) { // additional check if (m_Styles.count(argStyle) == 0) { LOGERROR(L"GUI: Trying to use style '%hs' that doesn't exist.", argStyle.c_str()); } else object->LoadStyle(*this, argStyle); } // // Read Attributes // bool NameSet = false; bool ManuallySetZ = false; // if z has been manually set, this turn true CStr hotkeyTag; // Now we can iterate all attributes and store for (i=0; i<attributes.Count; ++i) { XMBAttribute attr = attributes.Item(i); // If value is "null", then it is equivalent as never being entered if (CStr(attr.Value) == "null") continue; // Ignore "type" and "style", we've already checked it if (attr.Name == attr_type || attr.Name == attr_style) continue; // Also the name needs some special attention if (attr.Name == attr_name) { CStr name (attr.Value); // Apply the requested substitutions for (size_t j = 0; j < NameSubst.size(); ++j) name.Replace(NameSubst[j].first, NameSubst[j].second); object->SetName(name); NameSet = true; continue; } // Wire up the hotkey tag, if it has one if (attr.Name == attr_hotkey) hotkeyTag = attr.Value; if (attr.Name == attr_z) ManuallySetZ = true; // Try setting the value if (object->SetSetting(pFile->GetAttributeString(attr.Name), attr.Value.FromUTF8(), true) != PSRETURN_OK) { LOGERROR(L"GUI: (object: %hs) Can't set \"%hs\" to \"%ls\"", object->GetPresentableName().c_str(), pFile->GetAttributeString(attr.Name).c_str(), attr.Value.FromUTF8().c_str()); // This is not a fatal error } } // Check if name isn't set, generate an internal name in that case. if (!NameSet) { object->SetName("__internal(" + CStr::FromInt(m_InternalNameNumber) + ")"); ++m_InternalNameNumber; } // Attempt to register the hotkey tag, if one was provided if (! hotkeyTag.empty()) m_HotkeyObjects[hotkeyTag].push_back(object); CStrW caption (Element.GetText().FromUTF8()); if (! caption.empty()) { // Set the setting caption to this object->SetSetting("caption", caption, true); // There is no harm if the object didn't have a "caption" } // // Read Children // // Iterate children XMBElementList children = Element.GetChildNodes(); for (i=0; i<children.Count; ++i) { // Get node XMBElement child = children.Item(i); // Check what name the elements got int element_name = child.GetNodeName(); if (element_name == elmt_object) { // Call this function on the child Xeromyces_ReadObject(child, pFile, object, NameSubst, Paths); } else if (element_name == elmt_action) { // Scripted <action> element // Check for a 'file' parameter CStrW filename (child.GetAttributes().GetNamedItem(attr_file).FromUTF8()); CStr code; // If there is a file, open it and use it as the code if (! filename.empty()) { Paths.insert(filename); CVFSFile scriptfile; if (scriptfile.Load(g_VFS, filename) != PSRETURN_OK) { LOGERROR(L"Error opening GUI script action file '%ls'", filename.c_str()); throw PSERROR_GUI_JSOpenFailed(); } code = scriptfile.DecodeUTF8(); // assume it's UTF-8 } // Read the inline code (concatenating to the file code, if both are specified) code += CStr(child.GetText()); CStr action = CStr(child.GetAttributes().GetNamedItem(attr_on)); // We need to set the GUI this object belongs to because RegisterScriptHandler requires an associated GUI. object->SetGUI(this); object->RegisterScriptHandler(action.LowerCase(), code, this); } else if (element_name == elmt_repeat) { Xeromyces_ReadRepeat(child, pFile, object, Paths); } else { // Try making the object read the tag. if (!object->HandleAdditionalChildren(child, pFile)) { LOGERROR(L"GUI: (object: %hs) Reading unknown children for its type", object->GetPresentableName().c_str()); } } } // // Check if Z wasn't manually set // if (!ManuallySetZ) { // Set it automatically to 10 plus its parents bool absolute; GUI<bool>::GetSetting(object, "absolute", absolute); // If the object is absolute, we'll have to get the parent's Z buffered, // and add to that! if (absolute) { GUI<float>::SetSetting(object, "z", pParent->GetBufferedZ() + 10.f, true); } else // If the object is relative, then we'll just store Z as "10" { GUI<float>::SetSetting(object, "z", 10.f, true); } } // // Input Child // try { if (pParent == m_BaseObject) AddObject(object); else pParent->AddChild(object); } catch (PSERROR_GUI& e) { LOGERROR(L"GUI error: %hs", e.what()); } }