[dasher: 18/27] Redo output handling, DasherView::Render returns node covering crosshair
- From: Patrick Welche <pwelche src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dasher: 18/27] Redo output handling, DasherView::Render returns node covering crosshair
- Date: Wed, 18 Aug 2010 15:11:11 +0000 (UTC)
commit 545796a25af8627785af0a42c5403735073e6be0
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date: Sat Aug 14 18:56:02 2010 +0100
Redo output handling, DasherView::Render returns node covering crosshair
Implemented for rects, {trunc,}tris, circles.
RecursiveOutput and HandleOutput combined into OutputTo, taking leaf as param
Src/DasherCore/DasherModel.cpp | 97 +++++++++++------------------------
Src/DasherCore/DasherModel.h | 22 +-------
Src/DasherCore/DasherView.cpp | 5 +-
Src/DasherCore/DasherView.h | 33 ++++++------
Src/DasherCore/DasherViewSquare.cpp | 90 ++++++++++++++++++++++++---------
Src/DasherCore/DasherViewSquare.h | 9 ++--
6 files changed, 123 insertions(+), 133 deletions(-)
---
diff --git a/Src/DasherCore/DasherModel.cpp b/Src/DasherCore/DasherModel.cpp
index 2ee0f95..d79c477 100644
--- a/Src/DasherCore/DasherModel.cpp
+++ b/Src/DasherCore/DasherModel.cpp
@@ -222,12 +222,6 @@ void CDasherModel::ClearRootQueue() {
}
}
-CDasherNode *CDasherModel::Get_node_under_crosshair() {
- DASHER_ASSERT(m_Root != NULL);
-
- return m_Root->Get_node_under(GetLongParameter(LP_NORMALIZATION), m_Rootmin + m_iDisplayOffset, m_Rootmax + m_iDisplayOffset, GetLongParameter(LP_OX), GetLongParameter(LP_OY));
-}
-
void CDasherModel::SetOffset(int iOffset, CAlphabetManager *pMgr, CDasherView *pView, bool bForce) {
//if we don't have a root, always "re"build the tree!
// (if we have a root, only rebuild to move location or if bForce says to)
@@ -391,15 +385,6 @@ void CDasherModel::UpdateBounds(myint iNewMin, myint iNewMax, unsigned long iTim
// Now actually zoom to the new location
NewGoTo(iNewMin, iNewMax, pAdded, pNumDeleted);
-
-
- // Check whether new nodes need to be created
- ExpandNode(Get_node_under_crosshair());
-
-// This'll get done again when we render the frame, later, but we use NF_SEEN
-// (set here) to ensure the node under the cursor can never be collapsed
-// (even when the node budget is exceeded) when we do the rendering...
- HandleOutput(pAdded, pNumDeleted);
}
void CDasherModel::RecordFrame(unsigned long Time) {
@@ -410,27 +395,6 @@ void CDasherModel::RecordFrame(unsigned long Time) {
pTeacher->NewFrame(Time);
}
-void CDasherModel::RecursiveOutput(CDasherNode *pNode, Dasher::VECTOR_SYMBOL_PROB* pAdded) {
- if(pNode->Parent()) {
- if (!pNode->Parent()->GetFlag(NF_SEEN))
- RecursiveOutput(pNode->Parent(), pAdded);
-
- pNode->Parent()->Leave();
- }
-
- pNode->Enter();
-
- m_pLastOutput = pNode;
- pNode->SetFlag(NF_SEEN, true);
- pNode->Output(pAdded, GetLongParameter(LP_NORMALIZATION));
-
- // If the node we are outputting is the last one in a game target sentence, then
- // notify the game mode teacher.
- if(m_bGameMode)
- if(pNode->GetFlag(NF_END_GAME))
- GameMode::CDasherGameMode::GetTeacher()->SentenceFinished();
-}
-
void CDasherModel::NewGoTo(myint newRootmin, myint newRootmax, Dasher::VECTOR_SYMBOL_PROB* pAdded, int* pNumDeleted) {
// Update the max and min of the root node to make iTargetMin and
@@ -487,27 +451,35 @@ void CDasherModel::NewGoTo(myint newRootmin, myint newRootmax, Dasher::VECTOR_SY
}
}
-void CDasherModel::HandleOutput(Dasher::VECTOR_SYMBOL_PROB* pAdded, int* pNumDeleted) {
- CDasherNode *pNewNode = Get_node_under_crosshair();
- DASHER_ASSERT(pNewNode != NULL);
-
- // std::cout << "HandleOutput: " << m_pLastOutput << " => " << pNewNode << std::endl;
-
- CDasherNode *pLastSeen = pNewNode;
- while (pLastSeen && !pLastSeen->GetFlag(NF_SEEN))
- pLastSeen = pLastSeen->Parent();
-
- while (m_pLastOutput != pLastSeen) {
- m_pLastOutput->Undo(pNumDeleted);
- m_pLastOutput->Leave(); //Should we? I think so, but the old code didn't...?
- m_pLastOutput->SetFlag(NF_SEEN, false);
+void CDasherModel::OutputTo(CDasherNode *pNewNode, Dasher::VECTOR_SYMBOL_PROB* pAdded, int* pNumDeleted) {
+ //first, recurse back up to last seen node (must be processed ancestor-first)
+ if (pNewNode && !pNewNode->GetFlag(NF_SEEN)) {
+ OutputTo(pNewNode->Parent(), pAdded, pNumDeleted);
+ if (pNewNode->Parent()) pNewNode->Parent()->Leave();
+ pNewNode->Enter();
- m_pLastOutput = m_pLastOutput->Parent();
- if (m_pLastOutput) m_pLastOutput->Enter();
- }
-
- if(!pNewNode->GetFlag(NF_SEEN)) {
- RecursiveOutput(pNewNode, pAdded);
+ m_pLastOutput = pNewNode;
+ pNewNode->SetFlag(NF_SEEN, true);
+ pNewNode->Output(pAdded, GetLongParameter(LP_NORMALIZATION));
+
+ // If the node we are outputting is the last one in a game target sentence, then
+ // notify the game mode teacher.
+ if(m_bGameMode)
+ if(pNewNode->GetFlag(NF_END_GAME))
+ GameMode::CDasherGameMode::GetTeacher()->SentenceFinished();
+ } else {
+ //either pNewNode is null, or else it's been seen. So delete back to that...
+ while (m_pLastOutput != pNewNode) {
+ // if pNewNode is null, m_pLastOutput is not; else, pNewNode has been seen,
+ // so we should encounter it on the way back out to the root, _before_ null
+ m_pLastOutput->Undo(pNumDeleted);
+ m_pLastOutput->Leave(); //Should we? I think so, but the old code didn't...?
+ m_pLastOutput->SetFlag(NF_SEEN, false);
+
+ m_pLastOutput = m_pLastOutput->Parent();
+ if (m_pLastOutput) m_pLastOutput->Enter();
+ else DASHER_ASSERT (!pNewNode); //both null
+ }
}
}
@@ -566,13 +538,10 @@ void CDasherModel::RenderToView(CDasherView *pView, CExpansionPolicy &policy) {
DASHER_ASSERT(pView != NULL);
DASHER_ASSERT(m_Root != NULL);
- // XXX we HandleOutput in RenderToView
- // DASHER_ASSERT(Get_node_under_crosshair() == m_pLastOutput);
-
// The Render routine will fill iGameTargetY with the Dasher Coordinate of the
// youngest node with NF_GAME set. The model is responsible for setting NF_GAME on
// the appropriate Nodes.
- pView->Render(m_Root, m_Rootmin + m_iDisplayOffset, m_Rootmax + m_iDisplayOffset, policy, true);
+ CDasherNode *pOutput = pView->Render(m_Root, m_Rootmin + m_iDisplayOffset, m_Rootmax + m_iDisplayOffset, policy, true);
/////////GAME MODE TEMP//////////////
if(m_bGameMode)
@@ -588,17 +557,13 @@ void CDasherModel::RenderToView(CDasherView *pView, CExpansionPolicy &policy) {
// TODO: Fix up stats
// TODO: Is this the right way to handle this?
- HandleOutput(NULL, NULL);
+ OutputTo(pOutput, NULL, NULL);
}
bool CDasherModel::CheckForNewRoot(CDasherView *pView) {
DASHER_ASSERT(m_Root != NULL);
// TODO: pView is redundant here
-#ifdef DEBUG
- CDasherNode *pOldNode = Get_node_under_crosshair();
-#endif
-
if(!(m_Root->GetFlag(NF_SUPER))) {
CDasherNode *root(m_Root);
Reparent_root();
@@ -622,8 +587,6 @@ bool CDasherModel::CheckForNewRoot(CDasherView *pView) {
Make_root(pNewRoot);
}
- DASHER_ASSERT(Get_node_under_crosshair() == pOldNode);
-
return false;
}
diff --git a/Src/DasherCore/DasherModel.h b/Src/DasherCore/DasherModel.h
index f0050eb..4e20685 100644
--- a/Src/DasherCore/DasherModel.h
+++ b/Src/DasherCore/DasherModel.h
@@ -310,27 +310,11 @@ class Dasher::CDasherModel:public Dasher::CFrameRate, private NoClones
void Reparent_root();
- ///
- /// Return a pointer to the Dasher node which is currently under the
- /// crosshair. Used for output, and apparently needed for game mode.
- ///
-
- CDasherNode *Get_node_under_crosshair();
-
- ///
- /// Output a node, which has not been seen (& first, any ancestors that haven't been seen either),
- /// but which _is_ a descendant of m_pLastOutput.
- ///
-
- void RecursiveOutput(CDasherNode *pNode, Dasher::VECTOR_SYMBOL_PROB* pAdded);
-
- ///
/// Handle the output caused by a change in node over the crosshair. Specifically,
/// deletes from m_pLastOutput back to closest ancestor of pNewNode,
- /// then outputs from that ancestor to the node now under the crosshair (inclusively)
- ///
-
- void HandleOutput(Dasher::VECTOR_SYMBOL_PROB* pAdded, int* pNumDeleted);
+ /// then outputs from that ancestor to that node
+ /// @param pNewNode innermost node now covering the crosshair
+ void OutputTo(CDasherNode *pNewNode, Dasher::VECTOR_SYMBOL_PROB* pAdded, int* pNumDeleted);
///
diff --git a/Src/DasherCore/DasherView.cpp b/Src/DasherCore/DasherView.cpp
index fdde335..f9b9afe 100644
--- a/Src/DasherCore/DasherView.cpp
+++ b/Src/DasherCore/DasherView.cpp
@@ -22,7 +22,6 @@
#include "DasherGameMode.h"
#include "DasherInput.h"
-#include "DasherModel.h"
#include "DasherView.h"
#include "Event.h"
#include "EventHandler.h"
@@ -56,11 +55,11 @@ void CDasherView::ChangeScreen(CDasherScreen *NewScreen) {
/////////////////////////////////////////////////////////////////////////////
-void CDasherView::Render(CDasherNode *pRoot, myint iRootMin, myint iRootMax, CExpansionPolicy &policy, bool bRedrawDisplay) {
+CDasherNode *CDasherView::Render(CDasherNode *pRoot, myint iRootMin, myint iRootMax, CExpansionPolicy &policy, bool bRedrawDisplay) {
m_iRenderCount = 0;
Screen()->SetLoadBackground(false);
- RenderNodes(pRoot, iRootMin, iRootMax, policy);
+ return RenderNodes(pRoot, iRootMin, iRootMax, policy);
}
int CDasherView::GetCoordinateCount() {
diff --git a/Src/DasherCore/DasherView.h b/Src/DasherCore/DasherView.h
index ba7a276..b7b40f7 100644
--- a/Src/DasherCore/DasherView.h
+++ b/Src/DasherCore/DasherView.h
@@ -6,7 +6,6 @@
#define __DasherView_h_
namespace Dasher {
- class CDasherModel;
class CDasherInput; // Why does DasherView care about input? - pconlon
class CDasherComponent;
class CDasherView;
@@ -23,7 +22,7 @@ namespace Dasher {
/// \brief View base class.
///
-/// Dasher views represent the visualisation of a Dasher model on the screen.
+/// Dasher views render the tree of Dasher nodes onto a screen.
///
/// Note that we really should aim to avoid having to try and keep
/// multiple pointers to the same object (model etc.) up-to-date at
@@ -34,13 +33,6 @@ namespace Dasher {
/// notifying this object every time it changes. The same logic can be
/// applied in several other places.
///
-/// We should also attempt to try and remove the need for this class
-/// to know about the model. When we call render we should just pass a
-/// pointer to the root node, which we can obtain elsewhere, and make
-/// sure that the data structure contains all the info we need to do
-/// the rendering (eg make sure it contains strings as well as symbol
-/// IDs).
-///
/// There are really three roles played by CDasherView: providing high
/// level drawing functions, providing a mapping between Dasher
/// co-ordinates and screen co-ordinates and providing a mapping
@@ -70,8 +62,7 @@ public:
void SetInput(CDasherInput * _pInput);
void SetDemoMode(bool);
void SetGameMode(bool);
- /// Translates the screen coordinates to Dasher coordinates and calls
- /// dashermodel.TapOnDisplay
+ /// Translates the screen coordinates to Dasher coordinates
virtual int GetCoordinates(myint &iDasherX, myint &iDasherY);
@@ -119,9 +110,18 @@ public:
/// Drawing more complex structures, generally implemented by derived class
/// @{
- /// Renders Dasher with mouse-dependent items
- /// \todo Clarify relationship between Render functions and probably only expose one
- virtual void Render(CDasherNode *pRoot, myint iRootMin, myint iRootMax, CExpansionPolicy &policy, bool bRedrawDisplay);
+ /// Top-level/public render function - renders all nodes.
+ /// TODO the difference between this and RenderNodes (which gets implemented
+ /// by subclasses) seems to be only that (a) this one sets m_iRenderCount to 0;
+ /// since m_iRenderCount is then only incremented by subclasses, should it
+ /// really be a field of CDasherView at all? and (b) it calls Screen()->SetLoadBackground(true)
+ /// first - a method/call which exists only for Gtk2/CanvasExperimental.{h,cpp}...
+ /// note the experimental, I doubt it works, or tbh whether it's worth making it...!
+ /// @param pRoot outermost node to render. should cover screen if possible;
+ /// function will blank out around it (in white) if not
+ /// @param bRedrawDisplay ignored; purpose unclear - also TODO...
+ /// @return the innermost node covering the crosshair
+ CDasherNode *Render(CDasherNode *pRoot, myint iRootMin, myint iRootMax, CExpansionPolicy &policy, bool bRedrawDisplay);
/// @}
@@ -197,8 +197,9 @@ private:
CDasherScreen *m_pScreen; // provides the graphics (text, lines, rectangles):
CDasherInput *m_pInput; // Input device abstraction
- /// Renders the Dasher node structure
- virtual void RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iRootMax, CExpansionPolicy &policy) = 0;
+ /// Renders the Dasher node structure, including blanking out around the root node if necessary
+ /// @return the innermost node covering the crosshair
+ virtual CDasherNode *RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iRootMax, CExpansionPolicy &policy) = 0;
/// Get the co-ordinates from the input device
diff --git a/Src/DasherCore/DasherViewSquare.cpp b/Src/DasherCore/DasherViewSquare.cpp
index e4c00d1..dfb7fa7 100644
--- a/Src/DasherCore/DasherViewSquare.cpp
+++ b/Src/DasherCore/DasherViewSquare.cpp
@@ -95,7 +95,7 @@ void CDasherViewSquare::HandleEvent(Dasher::CEvent *pEvent) {
}
}
-void CDasherViewSquare::RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iRootMax,
+CDasherNode *CDasherViewSquare::RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iRootMax,
CExpansionPolicy &policy) {
DASHER_ASSERT(pRoot != 0);
myint iDasherMinX;
@@ -114,25 +114,26 @@ void CDasherViewSquare::RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iR
Dasher2Screen(0, iRootMax, iScreenRight, iScreenBottom);
// Blank the region around the root node:
+ if (GetLongParameter(LP_SHAPE_TYPE)==0) { //disjoint rects, so go round root
+ if(iRootMin > iDasherMinY)
+ DasherDrawRectangle(iDasherMaxX, iDasherMinY, iDasherMinX, iRootMin, 0, -1, Nodes1, 0);
- if(iRootMin > iDasherMinY)
- DasherDrawRectangle(iDasherMaxX, iDasherMinY, iDasherMinX, iRootMin, 0, -1, Nodes1, 0);
-
- if(iRootMax < iDasherMaxY)
- DasherDrawRectangle(iDasherMaxX, iRootMax, iDasherMinX, iDasherMaxY, 0, -1, Nodes1, 0);
-
- //to left (greater Dasher X)
- if (iRootMax - iRootMin < iDasherMaxX)
- DasherDrawRectangle(iDasherMaxX, std::max(iRootMin,iDasherMinY), iRootMax-iRootMin, std::min(iRootMax,iDasherMaxY), 0, -1, Nodes1, 0);
+ if(iRootMax < iDasherMaxY)
+ DasherDrawRectangle(iDasherMaxX, iRootMax, iDasherMinX, iDasherMaxY, 0, -1, Nodes1, 0);
- //to right (margin)
- DasherDrawRectangle(0, iDasherMinY, iDasherMinX, iDasherMaxY, 0, -1, Nodes1, 0);
- // Screen()->DrawRectangle(iScreenRight, std::max(0, (int)iScreenTop),
- // Screen()->GetWidth(), std::min(Screen()->GetHeight(), (int)iScreenBottom),
- // 0, -1, Nodes1, false, true, 1);
+ //to left (greater Dasher X)
+ if (iRootMax - iRootMin < iDasherMaxX)
+ DasherDrawRectangle(iDasherMaxX, std::max(iRootMin,iDasherMinY), iRootMax-iRootMin, std::min(iRootMax,iDasherMaxY), 0, -1, Nodes1, 0);
+ //to right (margin)
+ DasherDrawRectangle(0, iDasherMinY, iDasherMinX, iDasherMaxY, 0, -1, Nodes1, 0);
+ } else {
+ //overlapping rects/shapes
+ Screen()->DrawRectangle(0, 0, Screen()->GetWidth(), Screen()->GetHeight(), 0, -1, Nodes1, 0);
+ }
// Render the root node (and children)
- RecursiveRender(pRoot, iRootMin, iRootMax, NULL, policy, std::numeric_limits<double>::infinity(), 0);
+ CDasherNode *pOutput = pRoot->Parent();
+ RecursiveRender(pRoot, iRootMin, iRootMax, NULL, policy, std::numeric_limits<double>::infinity(), 0, pOutput);
// Labels are drawn in a second parse to get the overlapping right
for (vector<CTextString *>::iterator it=m_DelayedTexts.begin(), E=m_DelayedTexts.end(); it!=E; it++)
@@ -141,6 +142,7 @@ void CDasherViewSquare::RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iR
// Finally decorate the view
Crosshair((myint)GetLongParameter(LP_OX));
+ return pOutput;
}
/// Draw text specified in Dasher co-ordinates. The position is
@@ -462,7 +464,7 @@ bool CDasherViewSquare::IsSpaceAroundNode(myint y1, myint y2) {
void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2,
CTextString *pPrevText, CExpansionPolicy &policy, double dMaxCost,
- int parent_color)
+ int parent_color, CDasherNode *&pOutput)
{
DASHER_ASSERT_VALIDPTR_RW(pRender);
@@ -515,16 +517,57 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
}
}
+ //Does node cover crosshair? (quick reject)
+ if (pOutput == pRender->Parent() && Range > GetLongParameter(LP_OX) && y1 < GetLongParameter(LP_OY) && y2 > GetLongParameter(LP_OY)) {
+ bool bCovers;
+ switch (GetLongParameter(LP_SHAPE_TYPE)) {
+ case 0: case 1: //Rectangles
+ bCovers = true;
+ break;
+ case 2: { //Triangles
+ myint iMidY((y1+y2)/2);
+ bCovers = (iMidY > GetLongParameter(LP_OY))
+ ? ((GetLongParameter(LP_OY)-y1)*Range) > (iMidY - y1) * GetLongParameter(LP_OX)
+ : ((y2-GetLongParameter(LP_OY))*Range) > (y2 - iMidY) * GetLongParameter(LP_OX);
+ break;
+ }
+ case 3: { //Truncated tris
+ myint midy1((y1+y1+y2)/3), midy2((y1+y2+y2)/3);
+ if (midy1 > GetLongParameter(LP_OY)) //(0,y1) - (Range,midy1)
+ bCovers = (GetLongParameter(LP_OY)-y1)*Range > (midy1 - y1) * GetLongParameter(LP_OX);
+ else if (midy2 > GetLongParameter(LP_OY)) // (Range,midy1) - (Range,midy2)
+ bCovers = true;
+ else
+ bCovers = (y2 - GetLongParameter(LP_OY))*Range > (y2 - midy2) * GetLongParameter(LP_OX);
+ break;
+ }
+ case 4: //quadrics. We'll approximate with circles, as they're easier...
+ // however, note that the circle is bigger, so this'll output things
+ // too soon/aggressively :-(.
+ // (hence, fallthrough to:)
+ case 5: { //circles - actually ellipses, as x diameter is twice y diameter, hence the *4
+ const myint y_dist(GetLongParameter(LP_OY) - (y1+y2)/2);
+ bCovers = GetLongParameter(LP_OX) * GetLongParameter(LP_OX) + y_dist*y_dist*4 < Range*Range;
+ }
+ }
+ if (bCovers) pOutput = pRender;
+ }
+
if (pRender->ChildCount() == 0) {
- //allow empty node to be expanded, it's big enough.
- policy.pushNode(pRender, y1, y2, true, dMaxCost);
+ if (pOutput==pRender) {
+ //covers crosshair! forcibly populate, now!
+ pRender->PopulateChildren(); //TODO we are bypassing rest of CDasherModel::ExpandNode...
+ pRender->SetFlag(NF_ALLCHILDREN, true);
+ } else //allow empty node to be expanded, it's big enough.
+ policy.pushNode(pRender, y1, y2, true, dMaxCost);
+
//fall through to draw outline
} else {
//Node has children. It can therefore be collapsed...however,
// we don't allow a node covering the crosshair to be collapsed
// (at best this'll mean there's nowhere useful to go forwards;
// at worst, all kinds of crashes trying to do text output!)
- if (!pRender->GetFlag(NF_GAME) && !pRender->GetFlag(NF_SEEN))
+ if (!pRender->GetFlag(NF_GAME) && pRender != pOutput)
dMaxCost = policy.pushNode(pRender, y1, y2, false, dMaxCost);
// Render children
@@ -545,8 +588,7 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
if (newy2-newy1 < iDasherMaxX)
DasherDrawRectangle(std::min(Range,iDasherMaxX), std::max(y1,iDasherMinY), newy2-newy1, std::min(y2,iDasherMaxY), myColor, -1, Nodes1, 0);
RecursiveRender(pChild, newy1, newy2, pPrevText,
- policy, dMaxCost,
- myColor);
+ policy, dMaxCost, myColor, pOutput);
//leave pRender->onlyChildRendered set, so remaining children are skipped
}
else
@@ -568,7 +610,7 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
pRender->onlyChildRendered = pChild;
if (newy2-newy1 < iDasherMaxX)
DasherDrawRectangle(std::min(Range,iDasherMaxX), std::max(y1,iDasherMinY), newy2-newy1, std::min(y2,iDasherMaxY), myColor, -1, Nodes1, 0);
- RecursiveRender(pChild, newy1, newy2, pPrevText, policy, dMaxCost, myColor);
+ RecursiveRender(pChild, newy1, newy2, pPrevText, policy, dMaxCost, myColor, pOutput);
//ensure we don't blank over this child in "finishing off" the parent (!)
lasty=newy2;
break; //no need to render any more children!
@@ -587,7 +629,7 @@ void CDasherViewSquare::RecursiveRender(CDasherNode *pRender, myint y1, myint y2
}
lasty = newy2;
}
- RecursiveRender(pChild, newy1, newy2, pPrevText, policy, dMaxCost, myColor);
+ RecursiveRender(pChild, newy1, newy2, pPrevText, policy, dMaxCost, myColor, pOutput);
} else {
// We get here if the node is too small to render or is off-screen.
// So, collapse it immediately.
diff --git a/Src/DasherCore/DasherViewSquare.h b/Src/DasherCore/DasherViewSquare.h
index da37c67..0962a71 100644
--- a/Src/DasherCore/DasherViewSquare.h
+++ b/Src/DasherCore/DasherViewSquare.h
@@ -140,12 +140,13 @@ private:
///
/// Render the current state of the model.
///
- virtual void RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iRootMax, CExpansionPolicy &policy);
+ virtual CDasherNode *RenderNodes(CDasherNode *pRoot, myint iRootMin, myint iRootMax, CExpansionPolicy &policy);
///
- /// (Recursively) render a node and all contained subnodes. Responsible for rendering exactly the area contained within the node.
- ///
- void RecursiveRender(CDasherNode * Render, myint y1, myint y2, CTextString *prevText, CExpansionPolicy &policy, double dMaxCost,int parent_color);
+ /// (Recursively) render a node and all contained subnodes. Responsible
+ /// for rendering exactly the area contained within the node.
+ /// @param pOutput The innermost node covering the crosshair (if any)
+ void RecursiveRender(CDasherNode * Render, myint y1, myint y2, CTextString *prevText, CExpansionPolicy &policy, double dMaxCost,int parent_color, CDasherNode *&pOutput);
#ifdef _WIN32
///
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]