gtring.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 964 行 · 第 1/2 页

CPP
964
字号
        }
    } while( joinMore );
}

void TreeRing::joinTo( TreeRing * other )
//---------------------------------------
{
    int i;

    for( i = other->_children.count(); i > 0; i -= 1 ) {
        other->_children[ i - 1 ]->setTo( this );

        TreeNode * node = other->_children[ i - 1 ]->getFrom();
        if( !isChild( node ) ) {
            _children.add( other->_children[ i - 1 ] );
            other->_children[ i - 1 ]->setTo( this );
        } else {
            node->removeNode( ParentList, other->_children[ i - 1 ]->getTo() );
        }
    }

    for( i = other->_parents.count(); i > 0; i -= 1 ) {
        TreeNode * node = other->_parents[ i - 1 ]->getTo();
        if( !isParent( node ) ) {
            TreePtr * ptr = other->_parents[ i - 1 ]->makeClone();
            ptr->setFrom( this );
            _parents.add( ptr );
            node->swapNode( ChildList, other, this );

            _level = maxInt( _level, node->getLevel() );
        } else {
            node->removeNode( ChildList, other->_parents[ i - 1 ]->getFrom() );
        }
    }
}

bool TreeRing::sameRing( TreeRing * other )
//-----------------------------------------
// Check if the other ring can be joined to this ring.
//
// Rings can be joined only if all the parents are the same, or
// if all the children are the same.
//
{
    int i;
    bool allMatch = TRUE;

    if( _parents.count() == other->_parents.count() ) {
        for( i = _parents.count(); i > 0 && allMatch; i -= 1 ) {
            if( !other->isParent( _parents[ i - 1 ]->getTo() ) ) {
                allMatch = FALSE;
            }
        }
        if( allMatch ) return TRUE;
    }

    if( _children.count() == other->_children.count() ) {
        allMatch = TRUE;

        for( i = _children.count(); i > 0 && allMatch; i -= 1 ) {
            if( !other->isChild( _children[ i - 1 ]->getFrom() ) ) {
                allMatch = FALSE;
            }
        }
        if( allMatch ) return TRUE;
    }

    return FALSE;
}

bool TreeRing::canJoin( TreeNode * parnt, TreeNode * child )
//----------------------------------------------------------
// Checks to see if, given a parent and child node, they can be linked
// using this ring
//
// Returns :
//  TRUE if there is a common parent between the child and the ring AND
//          there is a common child between the parent and the ring
//  FALSE if there are no common parents OR no common children
//
{
    int  i;
    bool found;

    /*
     * Check if any of the child's parents are in this ring's parent list
     */
    for( i = _parents.count(); i > 0; i -= 1 ) {
        found = FALSE;
        for( int j = child->getCount( ParentList ); j > 0 && !found; j -= 1 ) {
            if( child->getNode( ParentList, j - 1 ) == _parents[ i - 1 ]->getTo() ) {
                found = TRUE;
            }
        }
        if( !found ) return FALSE;      // no common parents
    }


    for( i = _children.count(); i > 0; i -= 1 ) {
        found = FALSE;
        for( int j = parnt->getCount( ChildList ); j > 0 && !found; j -= 1 ) {
            if( parnt->getNode( ChildList, j - 1 ) == _children[ i - 1 ]->getFrom() ) {
                found = TRUE;
            }
        }
        if( !found ) return FALSE;      // no common children
    }

    return TRUE;
}

bool TreeRing::isRelated( TreeNode * node )
//-----------------------------------------
{
    return isParent( node ) || isChild( node );
}

bool TreeRing::isParent( TreeNode * node )
//----------------------------------------
{
    for( int i = _parents.count(); i > 0; i -= 1 ) {
        if( _parents[ i - 1 ]->getTo() == node ) {
            return TRUE;
        }
    }
    return FALSE;
}

bool TreeRing::isChild( TreeNode * node )
//----------------------------------------
{
    for( int i = _children.count(); i > 0; i -= 1 ) {
        if( _children[ i - 1 ]->getFrom() == node ) {
            return TRUE;
        }
    }

    return FALSE;
}

static int CompareChildren( const TreePtr ** lhs, const TreePtr ** rhs )
//----------------------------------------------------------------------
{
    const TreeNode * lhN = (*lhs)->getFrom();
    const TreeNode * rhN = (*rhs)->getFrom();

    return TreeNode::compareNodes( lhN, rhN );
}

static int CompareParents( const TreePtr ** lhs, const TreePtr ** rhs )
//---------------------------------------------------------------------
{
    const TreeNode * lhN = (*lhs)->getTo();
    const TreeNode * rhN = (*rhs)->getTo();

    return TreeNode::compareNodes( lhN, rhN );
}

void TreeRing::sortPrtKids( void )
//--------------------------------
{
    _parents.sort( (TComp) CompareParents );
    _children.sort( (TComp) CompareChildren );
    _sorted = TRUE;
}

void TreeRing::getToCoord( TreePtr * ptr, TreeCoord& x, TreeCoord& y )
//----------------------------------------------------------------
{
    TreeCoord  tmpX, tmpY;
    bool vert = (_parent->getDirection() == TreeVertical);

    setChildWard();

    ptr->getFrom()->getFromCoord( ptr, tmpX, tmpY );

    x = (vert) ? tmpX : _bounding.x() + _bounding.w() + 1;
    y = (vert) ? _bounding.y() + _bounding.h() + 1: tmpY;
}

void TreeRing::getFromCoord( TreePtr * ptr, TreeCoord& x, TreeCoord& y )
//------------------------------------------------------------------
{
    TreeCoord  tmpX, tmpY;
    bool vert = (_parent->getDirection() == TreeVertical);

    setChildWard();

    ptr->getTo()->getToCoord( ptr, tmpX, tmpY );

    x = (vert) ? tmpX          : _bounding.x();
    y = (vert) ? _bounding.y() : tmpY;
}

void TreeRing::getMinCoord( TreeCoord & x, TreeCoord & y )
//--------------------------------------------------------
{
    TreeRect r;
    bool     set;

    if( !_sorted ) {
        sortPrtKids();
    }

    for( int i = _children.count(); i > 0; i -= 1 ) {
        TreeNode * child = _children[ i - 1 ]->getFrom();

        if( child->getEnable() > Hidden ) {
            TreeCoord tryX;
            TreeCoord tryY;

            child->getMinCoord( tryX, tryY );
            if( !set ) {
                set = TRUE;

                x = tryX;
                y = tryY;
            } else {
                x = minCoord( x, tryX );
                y = minCoord( y, tryY );
            }
        }
    }
}

void TreeRing::getMinSibCoord( TreeCoord & x, TreeCoord & y )
//-----------------------------------------------------------
{
    TreeRect  r;
    bool     set = FALSE;

    if( !_sorted ) {
        sortPrtKids();
    }

    for( int i = _children.count(); i > 0; i -= 1 ) {
        TreeNode * child = _children[ i - 1 ]->getFrom();

        if( child->getEnable() > Hidden ) {
            TreeCoord tryX;
            TreeCoord tryY;

            child->getMinSibCoord( tryX, tryY );
            if( !set ) {
                set = TRUE;

                x = tryX;
                y = tryY;
            } else {
                x = minCoord( x, tryX );
                y = minCoord( y, tryY );
            }
        }
    }
}

void TreeRing::getMaxCoord( TreeCoord & x, TreeCoord & y )
//--------------------------------------------------------
{
    TreeRect r;
    bool     set = FALSE;

    if( !_sorted ) {
        sortPrtKids();
    }

    for( int i = _children.count(); i > 0; i -= 1 ) {
        TreeNode * child = _children[ i - 1 ]->getFrom();

        if( child->getEnable() > Hidden ) {
            TreeCoord tryX;
            TreeCoord tryY;

            child->getMaxCoord( tryX, tryY );
            if( !set ) {
                set = TRUE;

                x = tryX;
                y = tryY;
            } else {
                x = maxCoord( x, tryX );
                y = maxCoord( y, tryY );
            }
        }
    }
}

TreeNode * TreeRing::getNode( TreeList_T lst, int index )
//-------------------------------------------------------
{
    switch( lst ) {
    case ParentList:
        return _parents[ index ]->getTo();
    case ChildList:
        return _children[ index ]->getFrom();
    default:
        REQUIRE( 0, "TreeRing::getNode -- bad list" );
    }
    return NULL;
}

TreePtr * TreeRing::getPtr( TreeList_T lst, int index )
//-----------------------------------------------------
{
    switch( lst ) {
    case ParentList:
        return _parents[ index ];
    case ChildList:
        return _children[ index ];
    default:
        REQUIRE( 0, "TreeRing::getPtr -- bad list" );
    }
    return NULL;
}

void TreeRing::addPtr( TreeList_T, TreePtr * )
//--------------------------------------------
{
}

TreeNode* TreeRing::removeNode( TreeList_T, TreeNode * )
//------------------------------------------------------
{
    return NULL;
}

int TreeRing::getCount( TreeList_T lst )
//--------------------------------------
{
    switch( lst ) {
    case ParentList:
        return _parents.count();
    case ChildList:
        return _children.count();
    case FlatList:
        return 0;
    default:
        REQUIRE( 0, "TreeRing::getCount -- bad list" );
    }
    return -1;
}

int TreeRing::getLevel( void ) const
//----------------------------------
{
    return _level;
}

void TreeRing::setBounding( OutputDevice *dev )
//---------------------------------------------
{
    TreeNode::setBounding( dev );

    setChildWard();
}

void TreeRing::setChildWard()
//---------------------------
{
    TreeRect   r;
    int     idx = 0;
    int     maxLevel = 0;

    for( int i = _parents.count(); i > 0; i -= 1 ) {
        TreeNode * prNode = _parents[ i - 1 ]->getTo();

        if( prNode->getEnable() > Hidden ) {
            int tstLvl = prNode->getLevel();
            if( tstLvl > maxLevel ) {
                maxLevel = tstLvl;
                idx = i - 1;
            }
        }
    }

    _parents[ idx ]->getTo()->myRect( r );

    if( _parent->getDirection() == TreeVertical ) {
        _bounding.y( r.y() + r.h() + ChildOff );
        _bounding.h( ChildH );
        _bounding.w( 0 );
    } else {
        _bounding.x( r.x() + r.w() + ChildOff );
        _bounding.w( ChildW );
        _bounding.h( 0 );
    }
}

TreeCoord TreeRing::getSibContrib( TreeNode * child, bool & sepInc )
//------------------------------------------------------------------
{
    TreeCoord ret = 0;
    int       divisor = 0;
    int       i;

    for( i = _parents.count(); i > 0; i -= 1 ) {
        TreeNode * prNode = _parents[ i - 1 ]->getTo();

        if( prNode->getEnable() > Hidden &&
            prNode->getLevel() == child->getLevel() - 1 ) {

            // find the number of immediate children of prNode, looking in
            // all of its child rings

            divisor = 0;
            for( int j = prNode->getCount( ChildList ); j > 0; j -= 1 ) {
                TreeNode * ring = prNode->getNode( ChildList, j - 1 );

                for( int k = ring->getCount( ChildList ); k > 0; k -= 1 ) {
                    TreeNode * chNode = ring->getNode( ChildList, k - 1 );

                    if( chNode->getEnable() > Hidden &&
                        chNode->getLevel() == child->getLevel() ) {

                        divisor += 1;
                    }
                }
            }

            divisor = maxInt( 1, divisor );             // prevent div by 0
            ret += prNode->getSibWidth() / divisor;

            if( !sepInc ) {
                sepInc = TRUE;
            } else {
                ret += sibSep / divisor;
            }
        }
    }

    return ret;
}

void TreeRing::setEnableStatus( void )
//------------------------------------
{
    bool enabled = ( getNumEnabled( ChildList ) > 0 ) &&
                   ( getNumEnabled( ParentList ) > 0 );

    setEnable( enabled ? Visible : Hidden );
}

bool TreeRing::childrenEnabled( void )
//------------------------------------
{
    int i;
    bool rc;

    rc = TRUE;
    for( i = 0; i < _children.count(); i += 1 ) {
        TreeNode * pNode;

        pNode = _children[ i ]->getFrom();
        if( !pNode->getEnable() ) {
            rc = FALSE;
            break;
        }
    }

    return rc;
}

bool TreeRing::parentsEnabled( void )
//-----------------------------------
{
    int i;
    bool rc;

    rc = TRUE;
    for( i = 0; i < _parents.count(); i += 1 ) {
        TreeNode * pNode;

        pNode = _parents[ i ]->getTo();
        if( !pNode->getEnable() ) {
            rc = FALSE;
            break;
        }
    }

    return rc;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?