soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SSkinPool.cpp
1#include "souistd.h"
2#include "res.mgr/SSkinPool.h"
3#include "core/SSkin.h"
4#include "SApp.h"
5#include "helper/SDpiScale.h"
6
7SNSBEGIN
8
9//////////////////////////////////////////////////////////////////////////
10// SSkinPool
11
12SSkinPool::SSkinPool(BOOL bAutoScale)
13 : m_bAutoScale(bAutoScale)
14{
16}
17
19{
20#ifdef _DEBUG
21 //查询哪些皮肤运行过程中没有使用过,将结果用输出到Output
22 SSLOGD() << "####Detecting Defined Skin Usage BEGIN";
23 SPOSITION pos = m_mapNamedObj->GetStartPosition();
24 while (pos)
25 {
26 SkinKey skinKey = m_mapNamedObj->GetNextKey(pos);
27 if (!m_mapSkinUseCount.Lookup(skinKey))
28 {
29 SSLOGD() << "skin of [" << skinKey.strName.c_str() << "." << skinKey.scale << "] was not used.";
30 }
31 }
32 SSLOGD() << "!!!!Detecting Defined Skin Usage END";
33#endif
34}
35
37{
38 SStringW strTypeName = xmlSkin.name();
39 SStringW strSkinName = xmlSkin.attribute(L"name").value();
40
41 if (strSkinName.IsEmpty() || strTypeName.IsEmpty())
42 {
43 return NULL;
44 }
45
47 if (pSkin)
48 {
49 pSkin->InitFromXml(&xmlSkin);
50 if (nScale != -1 && pSkin->GetScale() == 100)
51 {
52 pSkin->SetScale(nScale);
53 }
54 SkinKey key = { strSkinName, pSkin->GetScale() };
55 if (HasKey(key))
56 {
57 SSLOGW() << "load skin duplicated found,type=" << strTypeName << "name=" << strSkinName;
58 pSkin->Release();
59 return NULL;
60 }
61 AddKeyObject(key, pSkin);
62 }
63 else
64 {
65 SSLOGW() << "load skin error,type=" << strTypeName << "name=" << strSkinName;
66 }
67 return pSkin;
68}
69
71{
72 int nLoaded = 0;
73 SStringW strSkinName, strTypeName;
74
75 int scale = xmlNode.attribute(L"scale").as_int(-1);
76 SXmlNode xmlSkin = xmlNode.first_child();
77 while (xmlSkin)
78 {
79 SStringW strName = xmlSkin.name();
80 if (strName.CompareNoCase(L"skin") == 0)
81 {
82 nLoaded += _LoadSkins(xmlSkin);
83 }
84 else
85 {
86 ISkinObj *pSkin = _LoadSkin(xmlSkin, scale);
87 if (pSkin)
88 nLoaded++;
89 }
90 xmlSkin = xmlSkin.next_sibling();
91 }
92 return nLoaded;
93}
94
96{
97 if (!xmlNode)
98 return 0;
99 // loadSkins前把this加入到poolmgr,便于在skin中引用其它skin
100 GETUIDEF->PushSkinPool(this);
101 int nLoaded = _LoadSkins(SXmlNode(xmlNode));
102 GETUIDEF->PopSkinPool(this);
103 return nLoaded;
104}
105
107{
108 SkinKey key = { pSkin->GetName(), pSkin->GetScale() };
109 if (HasKey(key))
110 return FALSE;
111 AddKeyObject(key, pSkin);
112 pSkin->AddRef();
113 return TRUE;
114}
115
117{
118 SkinKey key = { pSkin->GetName(), pSkin->GetScale() };
119 return !!RemoveKeyObject(key);
120}
121
122ISkinObj *SSkinPool::GetSkin(LPCWSTR strSkinName, int nScale)
123{
124 SkinKey key = { strSkinName, nScale };
125
126 if (!HasKey(key))
127 {
128 if (!m_bAutoScale)
129 return NULL;
130
131 nScale = SDpiScale::NormalizeScale(nScale);
132 key.scale = nScale;
133 if (!HasKey(key))
134 {
135 const int kMaxBuiltinScales = 20;
136 SASSERT(SDpiScale::GetBuiltinScaleCount() <= kMaxBuiltinScales);
137 int nScales[kMaxBuiltinScales] = { 0 };
138 int findScales = 0;
139 int bestScale = 0;
140 for (int i = SDpiScale::GetBuiltinScaleCount() - 1; i >= 0; i--)
141 {
142 key.scale = SDpiScale::GetBuiltinScales()[i];
143 if (HasKey(key))
144 {
145 nScales[findScales++] = key.scale;
146 if (nScale > key.scale)
147 {
148 if (nScale % key.scale == 0)
149 {
150 bestScale = key.scale;
151 break;
152 }
153 }
154 else
155 {
156 if (key.scale % nScale == 0)
157 {
158 bestScale = key.scale;
159 break;
160 }
161 }
162 }
163 }
164 if (findScales == 0)
165 return NULL;
166 if (bestScale == 0)
167 bestScale = nScales[0];
168 key.scale = bestScale;
169 ISkinObj *pSkinSrc = GetKeyObject(key);
170 SASSERT(pSkinSrc);
171 ISkinObj *pSkin = pSkinSrc->Scale(nScale);
172 if (pSkin)
173 {
174 key.scale = nScale;
175 AddKeyObject(key, pSkin);
176 }
177 }
178 }
179#ifdef _DEBUG
180 m_mapSkinUseCount[key]++;
181#endif
182 return GetKeyObject(key);
183}
184
185void SSkinPool::OnKeyRemoved(const SSkinPtr &obj)
186{
187 obj->Release();
188}
189
194
195SNSEND
Skin Classes for SOUI.
Skin Object Pool Management.
virtual ISkinObj * CreateSkinByName(LPCWSTR pszSkinClass) const
Create a skin by name.
Definition SApp.cpp:644
void RemoveAll()
Removes all key-object pairs from the map.
Definition SCmnMap.h:141
bool GetKeyObject(const SkinKey &key, SSkinPtr &obj) const
Definition SCmnMap.h:65
SMap< SkinKey, SSkinPtr > * m_mapNamedObj
Definition SCmnMap.h:168
bool AddKeyObject(const SkinKey &key, const SSkinPtr &obj)
Definition SCmnMap.h:94
bool RemoveKeyObject(const SkinKey &key)
Definition SCmnMap.h:123
bool HasKey(const SkinKey &key) const
Definition SCmnMap.h:52
void(* m_pFunOnKeyRemoved)(const SSkinPtr &obj)
Definition SCmnMap.h:167
static const int * GetBuiltinScales()
获取内置的缩放比例数组
Definition SDpiScale.cpp:12
static int NormalizeScale(int nScale)
标准化放大比例
Definition SDpiScale.cpp:18
static int GetBuiltinScaleCount()
获取内置的缩放比例数量
Definition SDpiScale.cpp:7
static SApplication & getSingleton(void)
Definition SSingleton.h:63
int _LoadSkins(SXmlNode xmlNode)
Loads skins from an XML node.
Definition SSkinPool.cpp:70
BOOL RemoveSkin(ISkinObj *skin) OVERRIDE
Removes a skin object from the pool.
static void OnKeyRemoved(const SSkinPtr &obj)
Callback function called when a skin object is removed from the pool.
ISkinObj * GetSkin(LPCWSTR strSkinName, int nScale) OVERRIDE
Retrieves a skin object by name and scale.
ISkinObj * _LoadSkin(SXmlNode xmlNode, int nScale)
Loads a single skin from an XML node.
Definition SSkinPool.cpp:36
void RemoveAll() OVERRIDE
Removes all skin objects from the pool.
BOOL AddSkin(ISkinObj *skin) OVERRIDE
Adds a skin object to the pool.
virtual ~SSkinPool()
Destructor.
Definition SSkinPool.cpp:18
SSkinPool(BOOL bAutoScale=TRUE)
Constructor.
Definition SSkinPool.cpp:12
int LoadSkins(IXmlNode *xmlNode) OVERRIDE
Loads skins from an XML node.
Definition SSkinPool.cpp:95
A class representing an ASCII string.
Definition sstringw.h:96
int CompareNoCase(const wchar_t *psz) SCONST
Compares the string with another string, ignoring case.
Definition sstringw.cpp:929
const wchar_t * c_str() SCONST
Retrieves a C-style string representation of the string.
BOOL IsEmpty() SCONST
Checks if the string is empty.
int as_int(int def=0) const
Converts the attribute value to an integer.
Definition SXml.cpp:100
const wchar_t * value() const
Gets the attribute value.
Definition SXml.cpp:90
Class representing an XML node.
Definition SXml.h:352
SXmlNode next_sibling() const
Gets the next sibling node in the children list of the parent node.
Definition SXml.cpp:393
SXmlNode first_child() const
Gets the first child node of the node.
Definition SXml.cpp:383
const wchar_t * name() const
Gets the name of the node.
Definition SXml.cpp:363
SXmlAttr attribute(const wchar_t *name, bool bCaseSensitive=false) const
Gets the attribute with the specified name.
Definition SXml.cpp:428
Key for identifying a skin object in the pool.
Definition SSkinPool.h:74
Interface for Skin Objects.
Definition SSkinobj-i.h:29
int GetScale() SCONST PURE
Retrieves the scaling factor of the skin object.
long AddRef() PURE
Add reference.
BOOL InitFromXml(IXmlNode *xmlNode) PURE
Initializes the object from an XML node.
long Release() PURE
Release reference.
void SetScale(int scale) PURE
Sets the scaling factor of the skin object.
ISkinObj * Scale(int nScale) PURE
Scales the skin object by a specified factor.
LPCWSTR GetName() SCONST PURE
Retrieves the name of the object.
Interface for XML nodes.
Definition sxml-i.h:128