|Author:||Tuomas J. Lukka|
Goals: get the xupdf and pp functionality under one model.
How do we do non-regeneration of vobscenes on mouse events?
RESOLVED: Pass the old VobScene to the mouse event handler method and use the boolean return value to determine whether regeneration is needed.
This also fixes the idea that the BuoyViewMainNode is really a single view in a single VobScene.
Should we let keystrokes also not-regenerate the vobscene?
Who creates the nodes? What about when a node contains a link to itself? Are all nodes really the same?
RESOLVED: A-ha! There was confusion because the first design treated buoy nodes and main nodes the same, when they are not at all the same.
The buoy nodes know how to render themselves at a given anchor.
The main node has a cursor and handles events etc.
The buoy node objects can be static objects; the main node objects must be created for each view.
First of all, define the abstract buoyview model as follows:
In PP, a node is a 2D canvas on which there are cells, and Anchors are zz cells and links are connections between clones of anchor cells on a particular dimension.
In xupdf, a node is a cell containing a PDF document, and the anchors and links are defined implicitly by the xanalogical transclusions and xulinks.
A PDF scrollblock, on the other hand, is very different: no cell, no cellview! The architecture needs to support all these.
Now, the picture gets clearer: the whole structure of the current buoy view should be defined by a single facade:
Important Invariant (a la ZZstructure dimension): if node A, anchor A.1 shows a link X to node B anchor B.4, hen after B.setFocus(B.4), node B will show the link X as well.
The linkId passed to BuoyLinkListener must be unique for each node and the identifies the link -- it must be the same in both directions. The previous invariant in code is an invariant which these interfaces must obey:
// mainnode1's BuoyLinkListener set to l. mainnode1.renderMain(...); // l.link(d, *, nodetype2, L, A) got called as callback mainnode2 = nodetype2.createMainNode(L, A, l) mainnode2.renderMain(...); // l.link(-d, *, nodetype1, L, B) MUST GET CALLED
Of course, if the underlying data structure is modified between the calls to renderMain, the invariant need no longer hold.
The coordsys the main view is being rendered into defines the extent by its (modified) unit square; this extent is not binding but more like a hint.
Matcher structure can separate left&right links and know which way
Now, to make things clear, the call sequence for RealBuoyViewManager is
In the diagram, we first see RealBuoyViewManager render the view, calling BuoyViewMainNodeA to render the main node and getting a callback through the BuoyLinkListener interface about a link. This causes it to call BuoyViewNodeTypeB to render the buoy.
Then, the mouse click comes which takes the focus to the buoy of type B. Its node type object is called to create the new focus object. Then, the render pattern is repeated, but now with BuoyViewMainNodeB in the focus.
In this implementation of the BuoyViewMainNode and BuoyViewNodeType interfaces, the node and link types are almost pluggable. There are naturally some problems with full pluggability, due to the bidirectionality of the links: some node types will only match some other node types, etc.
As the main example, consider the above case with ZZ cell nodes, PP canvases and scrollblocks. The ZZ cell nodes and PP canvases are both in ZZstructure and use cellviews so they can be handled by the same linking managers, but the scrollblocks cannot.
The following diagram shows the current arrangement, where the pluggability is handled through the interfaces CellBuoyViewNodeType (where the concrete cbvnodetypes create their respective mainnodes) and CellBuoyViewLinker.
There are two different types of links that this part of the systme needs to know: Cell to Cell and Cell to PermaScroll. ...
In the next diagram, the classes that implement the pagespan nodes and their associations to the rest of the system are shown. The cellNodeType BuoyViewNodeType is the node type that is to be used for xanalogical links to cells.
As seen, ScrollblockCellLinker is the class implementing CellBuoyViewLinker, and when asked to make links for a given cell, it looks for both enfiladeoverlaps (transclusions) and xu links. Different types of pagespannodetypes are used for these: for transclusions seeing the whole original pagespan scrollblock is good, and for xu links, seeing only the anchor part of the target is good.
class PPCanvasNode inherit CellBuoyViewNodeType class PPCanvasCursor fields float x, y float zoom inherit BuoyViewMainNode dep "create" PPCanvasNode PPCanvasCursor