예제 #1
0
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");
        }
    }
}
예제 #2
0
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);
                }
            }
        }
    }
}