示例#1
0
int qxgeditScale::nodeIndex ( const QPoint& pos ) const
{
	if (nodeRect(4).contains(pos))
		return 4; // Break4/Offset4

	if (nodeRect(3).contains(pos))
		return 3; // Break3/Offset3

	if (nodeRect(2).contains(pos))
		return 2; // Break2/Offset2

	if (nodeRect(1).contains(pos))
		return 1; // Break1/Offset1

	return -1;
}
示例#2
0
文件: Shunt.cpp 项目: Thales1330/PSP
bool Shunt::SetNodeParent(Element* parent)
{
    if(parent && m_activeNodeID != 0) {
        wxRect2DDouble nodeRect(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
                                10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);

        if(parent->Intersects(nodeRect)) {
            m_parentList[0] = parent;

            // Centralize the node on bus.
            wxPoint2DDouble parentPt =
                parent->RotateAtPosition(m_pointList[0], -parent->GetAngle());  // Rotate click to horizontal position.
            parentPt.m_y = parent->GetPosition().m_y;                           // Centralize on bus.
            parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
            m_pointList[0] = parentPt;

            UpdateSwitchesPosition();
            UpdatePowerFlowArrowsPosition();
            return true;
        } else {
            m_parentList[0] = NULL;
            m_online = false;
        }
    }
    return false;
}
示例#3
0
文件: Shunt.cpp 项目: Thales1330/PSP
bool Shunt::NodeContains(wxPoint2DDouble position)
{
    wxRect2DDouble nodeRect(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
                            10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);

    if(nodeRect.Contains(position)) {
        m_activeNodeID = 1;
        return true;
    }

    m_activeNodeID = 0;
    return false;
}
示例#4
0
void GestureApplet::paintEvent(QPaintEvent *)
{
    QPainter painter( this );

    painter.setRenderHint( QPainter::Antialiasing );

    //
    // Draw lines
    //
    QPen linePen( Qt::blue );
    linePen.setWidthF( 5.0 );

    QPen shadowLinePen( Qt::black );
    shadowLinePen.setWidthF( 10 );

    QRectF nodeRect( QPointF(0, 0), QSizeF(10, 10) );
    QPen nodePen( Qt::black );
    nodePen.setWidthF( 3.0 );
    QBrush nodeBrush( Qt::white );

    if( mPoints.size() > 1 )
    {
        QList< QPoint >::iterator it;
        int n = 0;
        for(it = mPoints.begin(); it != mPoints.end(); ++it)
        {
            QList< QPoint >::iterator next = it + 1;
            if( next == mPoints.end() ) break;

            // Opacity increases for newer samples
            double opactiy = qMin(1.0, 0.15 + (double)n++ / mPoints.size());
            painter.setOpacity( opactiy/2.0 );

            // Draw shadow first
            painter.setPen( shadowLinePen );
            painter.drawLine(*it, *next);

            // Draw line
            painter.setOpacity( opactiy );
            painter.setPen( linePen );
            painter.drawLine(*it, *next);

            // Draw connection between lines
            painter.setPen( nodePen );
            painter.setBrush( nodeBrush );
            nodeRect.moveCenter( *it );
            painter.drawEllipse( nodeRect );
        }
    }
}
示例#5
0
文件: Shunt.cpp 项目: Thales1330/PSP
void Shunt::UpdateNodes()
{
    if(m_parentList[0]) {
        wxRect2DDouble nodeRect(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
                                10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);

        if(!m_parentList[0]->Intersects(nodeRect)) {
            m_parentList[0]->RemoveChild(this);
            m_parentList[0] = NULL;
            m_online = false;
            UpdateSwitchesPosition();
            UpdatePowerFlowArrowsPosition();
        }
    }
}
示例#6
0
void GraphInfo::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
{
	QRect nodeRect(0, 0, 200, 70);
	painter->setBrush(Qt::white);
	painter->setPen(QPen(Qt::white, 0));
	painter->setOpacity(0.4);
	painter->drawRect(nodeRect);

	QString str  = "Стоимость решения:___________" + QString::number(m_solutionCost)    + "\n";
	        str += "Количество раскрытых вершин:_" + QString::number(m_numOfOpenNodes)  + "\n";
	        str += "Количество вершин в графе:___" + QString::number(m_totalNumOfNodes) + "\n";

	painter->setOpacity(1.);
	painter->setPen(QPen(Qt::black, 0));
	painter->drawText(nodeRect, Qt::AlignLeft, str);
}
示例#7
0
void GuiRoadEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
{
   if ( !isFirstResponder() )
      setFirstResponder();

   // Get the clicked terrain position.
   Point3F tPos;
   if ( !getTerrainPos( event, tPos ) )
      return;      

   mouseLock();

   // Find any road / node at the clicked position.
   // TODO: handle overlapping roads/nodes somehow, cycle through them.
   
   DecalRoad *roadPtr = NULL;
   S32 closestNodeIdx = -1;
   F32 closestDist = F32_MAX;
   DecalRoad *closestNodeRoad = NULL;

   // First, find the closest node in any road to the clicked position.
   for ( SimSetIterator iter(mRoadSet); *iter; ++iter )
   {
      roadPtr = static_cast<DecalRoad*>( *iter );
      U32 idx;
      if ( roadPtr->getClosestNode( tPos, idx ) )
      {
         Point3F nodePos = roadPtr->getNodePosition(idx);
         F32 dist = ( nodePos - tPos ).len();
         if ( dist < closestDist )
         {
            closestNodeIdx = idx;
            closestDist = dist;
            closestNodeRoad = roadPtr;
         }
      }
   }

   //
   // Second, determine if the screen-space node rectangle
   // contains the clicked position.

   bool nodeClicked = false;
   S32 clickedNodeIdx = -1;

   if ( closestNodeIdx != -1 )
   {
      Point3F nodePos = closestNodeRoad->getNodePosition( closestNodeIdx );

      Point3F temp;
      project( nodePos, &temp );
      Point2I screenPos( temp.x, temp.y );

      RectI nodeRect( screenPos - mNodeHalfSize, mNodeHalfSize * 2 );
      
      nodeClicked = nodeRect.pointInRect( event.mousePoint );
      if ( nodeClicked )
         clickedNodeIdx = closestNodeIdx;
   }

   //
   // Determine the clickedRoad
   //
   DecalRoad *clickedRoadPtr = NULL;
   U32 insertNodeIdx = 0;

   if ( nodeClicked && (mSelRoad == NULL || closestNodeRoad == mSelRoad) )
   {
      // If a node was clicked, the owning road is always
      // considered the clicked road.
      clickedRoadPtr = closestNodeRoad;
   }
   else
   {
      // check the selected road first
      if ( mSelRoad != NULL && mSelRoad->containsPoint( tPos, &insertNodeIdx ) )
      {
         clickedRoadPtr = mSelRoad;
         nodeClicked = false;
         clickedNodeIdx = -1;
      }
      else
      {
         // Otherwise, we must ask each road if it contains
         // the clicked pos.
         for ( SimSetIterator iter(mRoadSet); *iter; ++iter )
         {
            roadPtr = static_cast<DecalRoad*>( *iter );
            if ( roadPtr->containsPoint( tPos, &insertNodeIdx ) )
            {
               clickedRoadPtr = roadPtr;
               break;            
            }
         }
      }
   }

	// shortcuts
   bool dblClick = ( event.mouseClickCount > 1 );
	if( dblClick )
   { 
		if( mMode == mSelectRoadMode )
		{
			setMode( mAddRoadMode, true );
			return;
		}
		if( mMode == mAddNodeMode )
		{
			// Delete the node attached to the cursor.
			deleteSelectedNode();
			mMode = mAddRoadMode;
			return;
		}
	}

	//this check is here in order to bounce back from deleting a whole road with ctrl+z
	//this check places the editor back into addroadmode
	if ( mMode == mAddNodeMode )
	{
      if ( !mSelRoad )
         mMode = mAddRoadMode;
	}

	if ( mMode == mSelectRoadMode )
	{
      // Did not click on a road or a node.
      if ( !clickedRoadPtr  )
      {
         setSelectedRoad( NULL );
         setSelectedNode( -1 );
         
         return;
      }

      // Clicked on a road that wasn't the currently selected road.
      if ( clickedRoadPtr != mSelRoad )
      {
         setSelectedRoad( clickedRoadPtr );
         setSelectedNode( -1 );
         return;
      }

      // Clicked on a node in the currently selected road that wasn't
      // the currently selected node.
      if ( nodeClicked )
      {
         setSelectedNode( clickedNodeIdx );
         return;
      }

      
      // Clicked a position on the currently selected road
      // that did not contain a node.
      //U32 newNode = clickedRoadPtr->insertNode( tPos, mDefaultWidth, insertNodeIdx );                  
      //setSelectedNode( newNode );
	}
   else if ( mMode == mAddRoadMode )
   {
		if ( nodeClicked && clickedRoadPtr )
      {
			// A double-click on a node in Normal mode means set AddNode mode.  
         if ( clickedNodeIdx == 0 )
         {
				setSelectedRoad( clickedRoadPtr );
				setSelectedNode( clickedNodeIdx );

				mAddNodeIdx = clickedNodeIdx;
            mMode = mAddNodeMode;
            mSelNode = mSelRoad->insertNode( tPos, mDefaultWidth, mAddNodeIdx );
            mIsDirty = true;

				return;
         }
			else if ( clickedNodeIdx == clickedRoadPtr->mNodes.size() - 1 )
         {
				setSelectedRoad( clickedRoadPtr );
				setSelectedNode( clickedNodeIdx );

            mAddNodeIdx = U32_MAX;
            mMode = mAddNodeMode;
            mSelNode = mSelRoad->addNode( tPos, mDefaultWidth );
            mIsDirty = true;
				setSelectedNode( mSelNode );

				return;
         } 
		}

		DecalRoad *newRoad = new DecalRoad;
		

		newRoad->mMaterialName = mMaterialName;

      newRoad->registerObject();

      // Add to MissionGroup                              
      SimGroup *missionGroup;
      if ( !Sim::findObject( "MissionGroup", missionGroup ) )               
         Con::errorf( "GuiDecalRoadEditorCtrl - could not find MissionGroup to add new DecalRoad" );
      else
         missionGroup->addObject( newRoad );               

      newRoad->insertNode( tPos, mDefaultWidth, 0 );
      U32 newNode = newRoad->insertNode( tPos, mDefaultWidth, 1 );

      // Always add to the end of the road, the first node is the start.
      mAddNodeIdx = U32_MAX;
      
      setSelectedRoad( newRoad );      
      setSelectedNode( newNode );

      mMode = mAddNodeMode;

      // Disable the hover node while in addNodeMode, we
      // don't want some random node enlarged.
      mHoverNode = -1;

      // Grab the mission editor undo manager.
      UndoManager *undoMan = NULL;
      if ( !Sim::findObject( "EUndoManager", undoMan ) )
      {
         Con::errorf( "GuiRoadEditorCtrl::on3DMouseDown() - EUndoManager not found!" );
         return;           
      }

      // Create the UndoAction.
      MECreateUndoAction *action = new MECreateUndoAction("Create Road");
      action->addObject( newRoad );
      
      // Submit it.               
      undoMan->addAction( action );
		
		//send a callback to script after were done here if one exists
		if ( isMethod( "onRoadCreation" ) )
         Con::executef( this, "onRoadCreation" );

		return;
   }
	else if ( mMode == mAddNodeMode )
	{
		// Oops the road got deleted, maybe from an undo action?
      // Back to NormalMode.
      if ( mSelRoad )
      {
			// A double-click on a node in Normal mode means set AddNode mode.  
         if ( clickedNodeIdx == 0 )
         {
				submitUndo( "Add Node" );
				mAddNodeIdx = clickedNodeIdx;
            mMode = mAddNodeMode;
            mSelNode = mSelRoad->insertNode( tPos, mDefaultWidth, mAddNodeIdx );
            mIsDirty = true;
				setSelectedNode( mSelNode );

				return;
         }
			else
         {
				if( clickedRoadPtr && clickedNodeIdx == clickedRoadPtr->mNodes.size() - 1 )
				{
					submitUndo( "Add Node" );
					mAddNodeIdx = U32_MAX;
					mMode = mAddNodeMode;
					mSelNode = mSelRoad->addNode( tPos, mDefaultWidth );
               mIsDirty = true;
					setSelectedNode( mSelNode );

					return;
				}
				else
				{
					submitUndo( "Insert Node" );
					// A single-click on empty space while in
					// AddNode mode means insert / add a node.
					//submitUndo( "Add Node" );
					//F32 width = mSelRoad->getNodeWidth( mSelNode );
					U32 newNode = mSelRoad->insertNode( tPos, mDefaultWidth, mAddNodeIdx);
               mIsDirty = true;
					setSelectedNode( newNode );

					return;
				}
         } 
      }
	}
	else if ( mMode == mInsertPointMode  && mSelRoad != NULL)
	{
		if ( clickedRoadPtr == mSelRoad )
      {
			F32 w0 = mSelRoad->getNodeWidth( insertNodeIdx );
         F32 w1 = mSelRoad->getNodeWidth( insertNodeIdx + 1 );               
         F32 width = ( w0 + w1 ) * 0.5f;

         submitUndo( "Insert Node" );
         U32 newNode = mSelRoad->insertNode( tPos, width, insertNodeIdx + 1);  
         mIsDirty = true;
         setSelectedNode( newNode );

			return;
       }
	}
	else if ( mMode == mRemovePointMode  && mSelRoad != NULL)
	{
		if ( nodeClicked && clickedRoadPtr == mSelRoad )
      {
			setSelectedNode( clickedNodeIdx );
         deleteSelectedNode();
         return;
      }
	}
	else if ( mMode == mMovePointMode )
	{
		if ( nodeClicked && clickedRoadPtr == mSelRoad )
      {
			setSelectedNode( clickedNodeIdx );
         return;
      }
	}
	else if ( mMode == mScalePointMode )
	{
		if ( nodeClicked && clickedRoadPtr == mSelRoad )
      {
			setSelectedNode( clickedNodeIdx );
         return;
      }
	}
}
示例#8
0
// Draw curve.
void qxgeditScale::paintEvent ( QPaintEvent *pPaintEvent )
{
	QPainter painter(this);

	const int h  = height();
	const int w  = width();

	const int h2 = h >> 1;

	const int x1 = 6 + int((m_iBreak1 * (w - 12)) >> 7);
	const int x2 = 6 + int((m_iBreak2 * (w - 12)) >> 7);
	const int x3 = 6 + int((m_iBreak3 * (w - 12)) >> 7);
	const int x4 = 6 + int((m_iBreak4 * (w - 12)) >> 7);

	const int y1 = h2 - ((int(m_iOffset1) - 64) * (h - 12) >> 7);
	const int y2 = h2 - ((int(m_iOffset2) - 64) * (h - 12) >> 7);
	const int y3 = h2 - ((int(m_iOffset3) - 64) * (h - 12) >> 7);
	const int y4 = h2 - ((int(m_iOffset4) - 64) * (h - 12) >> 7);

	m_poly.putPoints(0, 6,
		0,  y1,
		x1, y1,
		x2, y2,
		x3, y3,
		x4, y4,
		w,  y4);

	const QPalette& pal = palette();
	const bool bDark = (pal.window().color().value() < 0x7f);
	const QColor& rgbLite = (bDark ? Qt::darkYellow : Qt::yellow);
	if (bDark)
		painter.fillRect(0, 0, w, h, pal.dark().color());

	painter.setRenderHint(QPainter::Antialiasing, true);
	painter.setPen(bDark ? Qt::gray : Qt::darkGray);

	const QPen oldpen(painter.pen());
	QPen dotpen(oldpen);
	dotpen.setStyle(Qt::DotLine);
	painter.setPen(dotpen);
	painter.drawLine(0, h2, w, h2);
	painter.setPen(oldpen);

	painter.drawPolyline(m_poly);

	painter.setBrush(rgbLite); // pal.midlight().color()
	painter.drawRect(nodeRect(1));
	painter.drawRect(nodeRect(2));
	painter.drawRect(nodeRect(3));
	painter.drawRect(nodeRect(4));

#ifdef CONFIG_DEBUG_0
	painter.drawText(QFrame::rect(),
		Qt::AlignTop|Qt::AlignHCenter,
		tr("Break (%1,%2,%3,%4) Offset(%5,%6,%7,%8)")
		.arg(int(break1()))
		.arg(int(break2()))
		.arg(int(break3()))
		.arg(int(break4()))
		.arg(int(offset1()) - 64)
		.arg(int(offset2()) - 64)
		.arg(int(offset3()) - 64)
		.arg(int(offset4()) - 64));
#endif

	painter.setRenderHint(QPainter::Antialiasing, false);
	painter.end();

	QFrame::paintEvent(pPaintEvent);
}
void TranscriptWindow::OnDraw(CDC* pDC)
{
    CRect clientRect;
    GetClientRect(clientRect);

    CDC dc;
    dc.CreateCompatibleDC(pDC);

    // Create an off-screen bitmap for drawing
    CDibSection bitmap;
    if (bitmap.CreateBitmap(pDC->GetSafeHdc(),clientRect.Width(),clientRect.Height()) == FALSE)
        return;
    CBitmap* oldBitmap = CDibSection::SelectDibSection(dc,&bitmap);

    dc.SetBkMode(TRANSPARENT);
    dc.FillSolidRect(clientRect,theApp.GetColour(InformApp::ColourBack));

    if (m_skein->IsActive())
    {
        CFont* oldFont = dc.SelectObject(theApp.GetFont(InformApp::FontDisplay));
        CPen linePen(PS_SOLID,1,theApp.GetColour(InformApp::ColourBorder));
        CPen* oldPen = dc.SelectObject(&linePen);

        int y = 0;
        int yinput = m_layout.fontSize.cy+(2*m_layout.margin.cy);

        // If the transcript is taller than the window, work out the drawing origin
        if (GetHeight() > clientRect.Height())
        {
            SCROLLINFO scroll;
            ::ZeroMemory(&scroll,sizeof scroll);
            scroll.cbSize = sizeof scroll;
            GetScrollInfo(SB_VERT,&scroll);
            y -= scroll.nPos;
        }

        // Clear the map of visible buttons and expected texts
        m_buttons.clear();
        m_expecteds.clear();

        // Loop over the transcript nodes
        std::deque<NodeLayout>::const_iterator nodeIt;
        for (nodeIt = m_layout.nodes.begin(); nodeIt != m_layout.nodes.end(); ++nodeIt)
        {
            const NodeLayout& nl = *nodeIt;

            // Is this node visible?
            CRect nodeRect(0,y,1,y+m_layout.fontSize.cy+nl.height+(4*m_layout.margin.cy)+1);
            CRect intersection;
            if (intersection.IntersectRect(nodeRect,clientRect) == FALSE)
            {
                // Not visible, so increase the y position and try the next node
                y += yinput+nl.height+(2*m_layout.margin.cy);
                continue;
            }

            // Get the text associated with the node
            const CStringW& transcript = nl.node->GetTranscriptText();
            const CStringW& expected = nl.node->GetExpectedText();
            const CStringW& line = nl.node->GetLine();

            // Fill in the background of the input line
            dc.FillSolidRect(0,y+1,clientRect.Width(),yinput,
                             theApp.GetColour(InformApp::ColourTransInput));

            // Fill in the background of the transcript text
            COLORREF back;
            if (transcript.IsEmpty())
                back = theApp.GetColour(InformApp::ColourTransUnset);
            else
            {
                back = theApp.GetColour(nl.node->GetChanged() ?
                                        InformApp::ColourTransDiffers : InformApp::ColourTransSame);
            }
            CRect backRect(0,y+yinput,m_layout.columnWidth,
                           y+m_layout.fontSize.cy+nl.height+(4*m_layout.margin.cy));
            dc.FillSolidRect(backRect,back);

            // Fill in the background of the expected text
            if (expected.IsEmpty())
                back = theApp.GetColour(InformApp::ColourTransUnset);
            else
            {
                switch (nl.node->GetDiffers())
                {
                case Skein::Node::ExpectedSame:
                    back = theApp.GetColour(InformApp::ColourTransSame);
                    break;
                case Skein::Node::ExpectedNearlySame:
                    back = RGB(255,255,127);
                    break;
                case Skein::Node::ExpectedDifferent:
                    back = theApp.GetColour(InformApp::ColourTransDiffers);
                    break;
                default:
                    ASSERT(FALSE);
                    back = theApp.GetColour(InformApp::ColourTransDiffers);
                    break;
                }
            }
            backRect.OffsetRect(m_layout.columnWidth+1,0);
            dc.FillSolidRect(backRect,Brighter(back));

            // If this is the first node in the transcript, draw a horizontal line at the top
            if (nl.node == m_skein->GetRoot())
            {
                dc.MoveTo(0,y);
                dc.LineTo(clientRect.Width(),y);
            }

            // Draw a horizontal line below the node's input
            dc.MoveTo(0,y+yinput);
            dc.LineTo(clientRect.Width(),y+yinput);

            // Draw a final horizontal line below the text boxes
            dc.MoveTo(0,y+yinput+nl.height+(2*m_layout.margin.cy));
            dc.LineTo(clientRect.Width(),y+yinput+nl.height+(2*m_layout.margin.cy));

            // Draw a dividing line between the two text boxes
            dc.MoveTo(m_layout.columnWidth,y+yinput);
            dc.LineTo(m_layout.columnWidth,y+yinput+nl.height+(2*m_layout.margin.cy));

            // If this is the last played knot in the skein, draw a yellow border around it
            if (nl.node == m_skeinPlayed)
            {
                CRect backRect(0,y,clientRect.Width(),
                               y+m_layout.fontSize.cy+nl.height+(4*m_layout.margin.cy));
                DrawInsideRect(dc,backRect,CSize(m_layout.margin.cx*3/4,m_layout.margin.cy*7/8),
                               theApp.GetColour(InformApp::ColourTransPlayed));
            }

            // If this is the knot selected in the skein, draw a blue border around it
            if (nl.node == m_skeinSelected)
            {
                CRect backRect(0,y,clientRect.Width(),
                               y+m_layout.fontSize.cy+nl.height+(4*m_layout.margin.cy));
                DrawInsideRect(dc,backRect,CSize(m_layout.margin.cx*3/8,m_layout.margin.cy*7/16),
                               theApp.GetColour(InformApp::ColourTransSelect));
            }

            // Draw the buttons at the end of the input line, and store their positions
            int btnHeight = m_layout.fontSize.cy+m_layout.margin.cy;
            CRect btnRect(
                CPoint(clientRect.Width()-(m_layout.margin.cy/2),y+(m_layout.margin.cy/2)),
                CSize(0,btnHeight));
            btnRect = DrawButton(dc,btnRect,false,"Show knot",Button(nl.node,ButtonShow),true);
            btnRect.right = btnRect.left-(m_layout.margin.cy/2);
            DrawButton(dc,btnRect,false,"Play to here",Button(nl.node,ButtonPlay),true);

            // Write the node's input
            dc.SetTextColor(theApp.GetColour(InformApp::ColourText));
            CRect textRect(m_layout.margin.cx,y+m_layout.margin.cy,
                           btnRect.left-m_layout.margin.cx,y+yinput);
            theOS.DrawText(&dc,line,line.GetLength(),textRect,DT_SINGLELINE|DT_NOPREFIX|DT_END_ELLIPSIS);

            // Draw the 'bless' button, and store its position
            y += yinput;
            btnRect.right = m_layout.columnWidth;
            btnRect.top = y+(((nl.height+(2*m_layout.margin.cy))-btnHeight)/2);
            btnRect.bottom = btnRect.top+btnHeight;
            DrawButton(dc,btnRect,true,"Bless",Button(nl.node,ButtonBless),nl.node->CanBless());

            // Write the text in the text boxes
            textRect = CRect(m_layout.margin.cx,y+m_layout.margin.cy,
                             m_layout.columnWidth-m_layout.centreMargin,y+m_layout.margin.cy+nl.height);
            DrawText(dc,textRect,transcript,nl.node->GetTranscriptDiffs());
            textRect.OffsetRect(m_layout.columnWidth+m_layout.centreMargin-m_layout.margin.cx,0);
            DrawText(dc,textRect,expected,nl.node->GetExpectedDiffs());
            textRect.InflateRect(theApp.MeasureFont(m_edit.GetFont()).cx/4,0);
            m_expecteds.push_back(std::make_pair(backRect,Expected(nl.node,textRect)));

            // Advance the y position
            y += nl.height+(2*m_layout.margin.cy);
        }

        dc.SelectObject(oldPen);
        dc.SelectObject(oldFont);

        // If the edit window is visible, exclude the area under it to reduce flicker
        if (m_edit.IsWindowVisible())
        {
            CRect editRect;
            m_edit.GetWindowRect(&editRect);
            ScreenToClient(&editRect);
            pDC->ExcludeClipRect(editRect);
        }
    }

    // Copy to the on-screen device context
    pDC->BitBlt(0,0,clientRect.Width(),clientRect.Height(),&dc,0,0,SRCCOPY);
    dc.SelectObject(oldBitmap);
}