The attached is a screen shot. It demonstrates the present layout. Almost
nothing is functional.
There are quite a few details below. Feel free to ignore or skim.
*The outline pane*
I was a bit worried about getting MLTree to work. There's no docs.
Happily, some really easy patterns appear in the code, and I was able to
use them. Here is the code that creates the outline pane as you see it in
the screen shot:
def createCursesTree(self, c, form):
'''Create the curses tree widget in the given curses Form.'''
class BoxTitleTree(npyscreen.BoxTitle):
_contained_widget = npyscreen.MLTree
data = npyscreen.TreeData(ignore_root=True)
for i in range(4):
data.new_child(content='child %s' % (i))
w = form.add(
BoxTitleTree,
max_height=8, # Subtract 4 lines
name='Tree Pane',
footer="Press i or o to insert text",
values=data,
slow_scroll=False,
)
assert hasattr(c.frame, 'tree_widget')
c.frame.body_widget = w
As you can see, subclassing BoxTitle is the way to go. Just this is enough
to tell npyscreen to put the MLTree in the Boxed area. It's slick. I
don't really know how it works, but then that's not important...
class BoxTitleTree(npyscreen.BoxTitle):
_contained_widget = npyscreen.MLTree
At present, the tree contains dummy data, created with these lines:
data = npyscreen.TreeData(ignore_root=True)
for i in range(4):
data.new_child(content='child %s' % (i))
I'm not yet sure how to create nested data. A bit of experimentation is
needed.
*Key handling*
Leo now handles F-keys and Control keys passed to it. Ctrl-Q quits, Ctrl-S
goes through the save logic. etc. F4 invokes my local binding:
run-selected-unit-tests-locally = F4. This required a special case in
IH.handle_input in npyscreen/wgwidget.py. Apparently npyscreen handles
(eats) all F-keys before Leo has a chance to handle them.
*Unit testing*
unitTest.leo now loads from the curses pane without any problem. Some unit
tests are working, and mostly they do not interfere with (write into) the
curses pane. More work is needed in this regard, but it's not necessary.
*Still to do*
1. Complete the linkage between wrapper classes and the curses widgets they
wrap. A few ivars are still bound to g.NullObject. These are about to
disappear. This work is a bit tricky, but there isn't much of it.
2. Make all high-level interface methods work. The high-level interface
involves wrapper classes. The wrapper class then call widget (curses)
methods to actually do the work. This could be difficult work. Happily,
however, all of the widgets, including MLTree are subclasses of the
MultiLine class in npyscreen/wgmultiline.py. Subclasses override stuff like
key bindings, so only MultiLine needs to be studied in detail. It's not yet
clear how capable MultiLine is, but I suspect it can do the job just as it
is.
3. Complete "the circle". This typically is the trickiest phase. I said in
Ashland that Leo's tree code probably stresses outline classes more than
any other app in the world. The high-level interface is one part of
completing the circle--control flows from Leo's core (commands or scripts)
to the gui. Conversely, changes to the gui must call crucial methods in
Leo's core, like LeoTree.select, LeoBody.onBodyChanged, etc. In such cases,
control flows from the gui to Leo's core. This is the circle of
control/events that can't be allowed to loop endlessly.
*Important*: LeoTree.select and LeoBody.onBodyChanged are members of *base*
classes. They *should not* be overridden in subclasses. Indeed, these
methods are very tricky and should be left alone. So it suffices that the
gui manages to *call* these methods.
*Schedule*
Work has gone quickly so far. My energy level is high. Still, it's hard
to say how much work remains. I would say at least another week, but it
could be much longer.
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 post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.