In this Engineering Notebook post I'll discuss the the code that draws Leo's outline pane. This post will explain why this code is complex and how it might possibly be improved.
*Present status* 1. Leo's tree code never drops data. This is crucial! It's all too easy to lose data when switching from one node to another. 2. Leo's tree code has good-to-excellent performance when few nodes are visible. In such situations, moving nodes can be done very quickly. The present code will slow significantly when large numbers of nodes are (potentially) visible. 3. The interface between Leo's code is minimal. Leo's core code can cause a full redraw (of only the *visible* tree nodes) merely by calling c.redraw(). The code can also schedule a redraw at idle time, but this is typically not needed. *Complicating factors* A major motivation for this post was "pyzo envy". Pyzo's tree drawing code, for example the PyzoSourceStructure class, is *much* simpler than Leo's code in qt_tree.py. Why is this so? #1585 <https://github.com/leo-editor/leo-editor/issues/1585> lists the features that complicate Leo's code base. I keep adding to the list! For this discussion, the following factors are most important: 1. The outline must support clones. Adding, moving or deleting a node may cause arbitrarily many changes to visible outline nodes! 2. Leonine scripts can add, move or delete nodes. The present code uses *lockouts *to ensure that scripting changes don't cause unwanted gui events. 3. Leo's core is (almost) completely separate from Leo's gui code. Because of these complicating factors, #1576 <https://github.com/leo-editor/leo-editor/issues/1576>seems moot. I have closed it. *Alternatives and trade offs* The present redraw code takes time proportional the number of *potentially visible* outline nodes. In other words, the code draws all visible nodes regardless of whether they are actually scrolled into view. This makes scrolling the outline pane trivial. It would be possible to draw only the *actually visible* outline nodes. This would speed the redraw code at the expense of extra code complexity, especially when scrolling the outline pane. At present, Leo completely redraws all (potentially) visible nodes when redrawing the screen. So the Qt code suffers a (usually mild) form of *tree thrashing*, the continual allocation/deallocation of Qt tree nodes. There are two possible ways to reduce this thrashing: 1. Leo could allocate Qt nodes for *all* outline nodes, visible or not, just once. Alas, because of clones, inserting, deleting and (especially) moving nodes can affect *arbitrarily many* other nodes! The code to do this would be difficult and error prone. Early versions of Leo used this technique. Back then (ca. 1990), the performance hit was substantial. 2. Leo could use difflib to minimize the amount of Qt nodes to be inserted or deleted. See #1068 <https://github.com/leo-editor/leo-editor/issues/1068>. This post <https://groups.google.com/d/msg/leo-editor/hpHyHU2sWtM/r-F-qwONAwAJ> discusses this idea in detail. Preliminary code already exists in leo/core/leoFastRedraw.py. Note: screen thrashing would be unimportant if only actually visible nodes were allocated. *Summary* It's easy for anyone, including myself, to get confused about the code and how it might (or might not) be improved. This post lists what I think are the most important considerations. The present code is reasonable and rock solid. There is no great need to revise it, and I have no plans to do so. Having said that, it's fine with me if someone wants to attempt improvements. Just make sure that the code remains rock solid. I'll be happy to discuss changes in more detail if you like. Comments are welcome, but please do so in a separate thread. I want this post to remain unchanged. 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/leo-editor/c3946795-de07-47b1-b489-c96aa0103288%40googlegroups.com.
