On Thursday, August 9, 2018 at 12:33:18 PM UTC-5, Edward K. Ream wrote:
>
> On Thu, Aug 9, 2018 at 7:57 AM, vitalije <vitali...@gmail.com> wrote:
>
>>
>>> Great help in quickly traversing tree to the given top position is to 
>>>> now how many nodes are in its subtree. In my model it is the size of a 
>>>> node. 
>>>>
>>>
> This turns out to be more important than I first thought. If the code is 
> to set scroll bars properly, it must compute the number of visible nodes 
> preceding the first *actually drawn* node.
>

The following method uses an inlined version of p.moveToVisNext():

def countPrevVisible(self, target_p):
    """
    Return the number of visible positions preceding the target position.
    """
    def fail():
        g.trace('NOT FOUND:', target_p.h)

    c = self.c
    p = c.hoistStack[-1].p if c.hoistStack else c.rootPosition()
    n = 0
    while p:
        if p == target_p:
            return n
        v = p.v
        # if v.isExpanded() and v.hasChildren():
        if (v.statusBits & v.expandedBit) != 0 and v.children:
            # p.moveToFirstChild()
            p.stack.append((v, p._childIndex),)
            p.v = v.children[0]
            p._childIndex = 0
            n += 1
            continue
        # if p.hasNext():
        parent_v = p.stack[-1][0] if p.stack else c.hiddenRootNode
        if p._childIndex + 1 < len(parent_v.children):
            # p.moveToNext()
            p._childIndex += 1
            p.v = parent_v.children[p._childIndex]
            n += 1
            continue
        #
        # A fast version of p.moveToThreadNext().
        # We look for a parent with a following sibling.
        while p.stack:
            # p.moveToParent()
            p.v, p._childIndex = p.stack.pop()
            # if p.hasNext():
            parent_v = p.stack[-1][0] if p.stack else c.hiddenRootNode
            if p._childIndex + 1 < len(parent_v.children):
                # p.moveToNext()
                p._childIndex += 1
                p.v = parent_v.children[p._childIndex]
                break # found: moveToThreadNext()
        else:
            # No next() at top level.
            fail()
            return n
        # found moveToThreadNext()
        n += 1
        continue
    fail()
    return n

This should be fast enough for now.  It counts 11,000 nodes in about 0.01 
sec.

The code assumes that the target position is already visible, which should 
be true in the redraw code.

Edward

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To post to this group, send email to leo-editor@googlegroups.com.
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.

Reply via email to