| 185 | } |
| 186 | |
| 187 | bool Selector::Matches( Widget::PtrConst widget ) const { |
| 188 | if( !widget ) { |
| 189 | return false; |
| 190 | } |
| 191 | |
| 192 | // Recursion is your friend ;) |
| 193 | |
| 194 | // Check if current stage is a pass... |
| 195 | if( ( !m_widget.compare( "*" ) && m_id.empty() && m_class.empty() && !m_state ) || // Wildcard |
| 196 | ( ( m_widget.empty() || !m_widget.compare( "*" ) || m_widget == widget->GetName() ) && // |
| 197 | ( m_id.empty() || m_id == widget->GetId() ) && // Selector and widget match |
| 198 | ( m_class.empty() || m_class == widget->GetClass() ) && // |
| 199 | ( !m_state || *m_state == widget->GetState() ) ) ) { // |
| 200 | // Current stage is a pass... |
| 201 | |
| 202 | // Differentiate between different hierarchy types |
| 203 | switch( m_hierarchy_type ) { |
| 204 | case HierarchyType::ROOT: { |
| 205 | // No parent, matching success |
| 206 | return true; |
| 207 | } break; |
| 208 | case HierarchyType::CHILD: { |
| 209 | // This is a child, check direct parent only |
| 210 | return ( GetParent() && GetParent()->Matches( widget->GetParent() ) ); |
| 211 | } break; |
| 212 | case HierarchyType::DESCENDANT: { |
| 213 | // This is a descendant, check all parents and try to match to all of widgets parents |
| 214 | for( PtrConst parent = GetParent(); parent; parent = parent->GetParent() ) { |
| 215 | for( Widget::PtrConst widget_parent = widget->GetParent(); widget_parent; widget_parent = widget_parent->GetParent() ) { |
| 216 | if( parent->Matches( widget_parent ) ) { |
| 217 | return true; |
| 218 | } |
| 219 | } |
| 220 | } |
| 221 | } break; |
| 222 | default: break; |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | // Not wildcard and doesn't match, fail... :( |
| 227 | return false; |
| 228 | } |
| 229 | |
| 230 | int Selector::GetScore() const { |
| 231 | int score = 0; |