void AXRController::add(HSSDisplayObject::p newElement) { newElement->setController(this); if(!this->root){ HSSContainer::p cont = HSSContainer::asContainer(newElement); if (cont){ this->setRoot(cont); } else { std_log1("############## HSSController: cannot add non-controller as root"); } } else { if(this->currentContext.size() != 0){ HSSContainer::p theCurrent = this->currentContext.top(); theCurrent->add(newElement); } else { std_log1("############## HSSController: tried to add a container to nonexistent current"); } } }
void AXRController::recursiveMatchRulesToDisplayObjects(const HSSRule::p & rule, const std::vector<HSSDisplayObject::p> & scope, HSSContainer::p container, bool applyingInstructions) { HSSInstruction::p instruction = rule->getInstruction(); if (instruction && applyingInstructions) { switch (instruction->getInstructionType()) { case HSSNewInstruction: { if(container){ std::string elementName = rule->selectorChainsLast()->subject()->getElementName(); unsigned i; unsigned argssize = 1; HSSParserNode::p argument = instruction->getArgument(); if(argument){ if (argument->isA(HSSParserNodeTypeNumberConstant)) { HSSNumberConstant::p argnum = boost::static_pointer_cast<HSSNumberConstant>(argument); argssize = (int)argnum->getValue(); } } for (i=0; i<argssize; i++) { HSSContainer::p newContainer = HSSContainer::p(new HSSContainer()); newContainer->setName(elementName); newContainer->setElementName(elementName); rule->setThisObj(newContainer); newContainer->setController(this); newContainer->rulesAdd(rule, (rule->getActiveByDefault() ? HSSRuleStateOn : HSSRuleStateOff )); std_log1("created "+newContainer->getElementName()); this->add(newContainer); newContainer->setNeedsRereadRules(true); newContainer->setNeedsSurface(true); newContainer->setDirty(true); unsigned i, size; this->currentContext.push(newContainer); for (i=0, size=rule->childrenSize(); i<size; i++) { const HSSRule::p childRule = rule->childrenGet(i); this->recursiveMatchRulesToDisplayObjects(childRule, newContainer->getChildren(), newContainer, applyingInstructions); } newContainer->setNeedsRereadRules(true); //newContainer->fireEvent(HSSEventTypeLoad); this->currentContext.pop(); } } else { AXRWarning::p(new AXRWarning("AXRController", "You cannot use the #new instruction at root level"))->raise(); } break; } case HSSMoveInstruction: { if(container){ HSSContainer::p parent = container->getParent(); if (parent) { std::vector<HSSDisplayObject::p> moveScope = parent->getChildren(); std::vector< std::vector<HSSDisplayObject::p> > selection = this->select(rule->getSelectorChains(), moveScope, container); unsigned i, j, k, size, size2, size3; this->currentContext.push(container); //move the children over for (i=0, size=selection.size(); i<size; i++) { std::vector<HSSDisplayObject::p> inner = selection[i]; for (j=0, size2=inner.size(); j<size2; j++) { HSSDisplayObject::p theDO = inner[j]; if(theDO != container){ theDO->removeFromParent(); rule->setThisObj(theDO); theDO->setController(this); theDO->rulesAdd(rule, (rule->getActiveByDefault() ? HSSRuleStateOn : HSSRuleStateOff )); std_log1("moved "+theDO->getElementName()); this->add(theDO); theDO->setNeedsRereadRules(true); theDO->setNeedsSurface(true); theDO->setDirty(true); if(theDO->isA(HSSObjectTypeContainer)){ HSSContainer::p theContainer = boost::static_pointer_cast<HSSContainer>(theDO); this->currentContext.push(theContainer); //assign more rules for (k=0, size3=rule->childrenSize(); k<size3; k++) { const HSSRule::p childRule = rule->childrenGet(k); this->recursiveMatchRulesToDisplayObjects(childRule, theContainer->getChildren(), theContainer, applyingInstructions); } this->currentContext.pop(); } theDO->setNeedsRereadRules(true); //theDO->fireEvent(HSSEventTypeLoad); } } } this->currentContext.pop(); } else { AXRWarning::p(new AXRWarning("AXRController", "You cannot use the #move instruction at root level"))->raise(); } } break; } case HSSDeleteInstruction: { if(container){ //select the items to be deleted std::vector< std::vector<HSSDisplayObject::p> > selection = this->select(rule->getSelectorChains(), scope, container); unsigned i, j, size, size2; for (i=0, size=selection.size(); i<size; i++) { std::vector<HSSDisplayObject::p> inner = selection[i]; for (j=0, size2=inner.size(); j<size2; j++) { inner[j]->removeFromParent(); } } } else { AXRWarning::p(new AXRWarning("AXRController", "You cannot use the #delete instruction at root level"))->raise(); } break; } default: break; } } else if(!instruction) { std::vector<HSSSelectorChain::p> selectorChains = rule->getSelectorChains(); if(selectorChains.size() > 0){ std::vector< std::vector<HSSDisplayObject::p> > selection; if (container){ //if it starts with a combinator, adjust the scope and selector chain bool useAdjustedScope = false; std::vector<HSSDisplayObject::p> adjustedScope; if(this->currentSelectorNode->isA(HSSParserNodeTypeCombinator)){ useAdjustedScope = true; adjustedScope.push_back(container); this->currentChain->prepend(HSSSelector::p(new HSSSelector(container->getElementName()))); this->currentChainSize ++; this->currentSelectorNode = this->currentChain->get(0); } if (applyingInstructions) { //we observe the parent for dom changes container->observe(HSSObservablePropertyTreeChange, HSSObservablePropertyValue, rule.get(), new HSSValueChangedCallback<HSSRule>(rule.get(), &HSSRule::treeChanged)); rule->setObservedTreeChanger(container.get()); rule->setThisObj(container); rule->setOriginalScope(scope); } selection = this->select(selectorChains, (useAdjustedScope ? adjustedScope : scope), container); } else { selection = this->select(selectorChains, scope, this->getRoot()); } unsigned i, j, k, size, size2, size3; for (i=0, size=selection.size(); i<size; i++) { std::vector<HSSDisplayObject::p> inner = selection[i]; for (j=0, size2=inner.size(); j<size2; j++) { const HSSDisplayObject::p & displayObject = inner[j]; std_log1("match "+displayObject->getElementName()); displayObject->rulesAdd(rule, (rule->getActiveByDefault() ? HSSRuleStateOn : HSSRuleStateOff )); displayObject->setNeedsRereadRules(true); displayObject->setNeedsSurface(true); displayObject->setDirty(true); //if it is a container it may have children if(displayObject->isA(HSSObjectTypeContainer)){ HSSContainer::p selectedContainer = boost::static_pointer_cast<HSSContainer>(displayObject); this->currentContext.push(selectedContainer); for (k=0, size3=rule->childrenSize(); k<size3; k++) { const HSSRule::p childRule = rule->childrenGet(k); this->recursiveMatchRulesToDisplayObjects(childRule, selectedContainer->getChildren(), selectedContainer, applyingInstructions); } this->currentContext.pop(); } displayObject->setNeedsRereadRules(true); } } } } }