Beispiel #1
0
void DesignerWindow::HighlightSelection( wxDC& dc )
{
    // do not highlight if AUI is used in floating mode
    VisualEditor *editor = wxDynamicCast( GetParent(), VisualEditor );
    if( editor && editor->m_auimgr )
    {
        wxWindow *windowItem =  wxDynamicCast( m_selItem, wxWindow );
        while( windowItem )
        {
            wxAuiPaneInfo info = editor->m_auimgr->GetPane( windowItem );
            if( info.IsOk() )
            {
                if( info.IsFloating() ) return;
                else break;
            }
            windowItem = windowItem->GetParent();
        }
    }

    wxSize size;
    PObjectBase object = m_selObj.lock();
    if ( m_selSizer )
    {
        wxPoint point = m_selSizer->GetPosition();
        size = m_selSizer->GetSize();
        wxPen bluePen( *wxBLUE, 1, wxSOLID );
        dc.SetPen( bluePen );
        dc.SetBrush( *wxTRANSPARENT_BRUSH );
        PObjectBase sizerParent = object->FindNearAncestorByBaseClass( wxT("sizer") );
        if( !sizerParent ) sizerParent = object->FindNearAncestorByBaseClass( wxT("gbsizer") );
        if ( sizerParent && sizerParent->GetParent() )
        {
            DrawRectangle( dc, point, size, sizerParent );
        }
    }

    if ( m_selItem )
    {
        wxPoint point;
        bool shown;

        wxWindow* windowItem = wxDynamicCast( m_selItem, wxWindow );
        wxSizer* sizerItem = wxDynamicCast( m_selItem, wxSizer );
        if ( NULL != windowItem )
        {
            point = windowItem->GetPosition();
            size = windowItem->GetSize();
            shown = windowItem->IsShown();
        }
        else if ( NULL != sizerItem )
        {
            point = sizerItem->GetPosition();
            size = sizerItem->GetSize();
            shown = true;
        }
        else
        {
            return;
        }

        if ( shown )
        {
            wxPen redPen( *wxRED, 1, wxSOLID );
            dc.SetPen( redPen );
            dc.SetBrush( *wxTRANSPARENT_BRUSH );
            DrawRectangle( dc, point, size, object );
        }
    }
}
Beispiel #2
0
wxBitmap BacklashGraph::CreateGraph(int bmpWidth, int bmpHeight)
{
    wxMemoryDC dc;
    wxBitmap bmp(bmpWidth, bmpHeight, -1);
    wxPen axisPen("BLACK", 3, wxCROSS_HATCH);
    wxPen redPen("RED", 3, wxSOLID);
    wxPen bluePen("BLUE", 3, wxSOLID);
    wxBrush redBrush("RED", wxSOLID);
    wxBrush blueBrush("BLUE", wxSOLID);
    //double fakeNorthPoints[] = 
    //{152.04, 164.77, 176.34, 188.5, 200.25, 212.36, 224.21, 236.89, 248.62, 260.25, 271.34, 283.54, 294.79, 307.56, 319.22, 330.87, 343.37, 355.75, 367.52, 379.7, 391.22, 403.89, 415.34, 427.09, 439.41, 450.36, 462.6};
    //double fakeSouthPoints[] = 
    //{474.84, 474.9, 464.01, 451.83, 438.08, 426, 414.68, 401.15, 390.39, 377.22, 366.17, 353.45, 340.75, 328.31, 316.93, 304.55, 292.42, 280.45, 269.03, 255.02, 243.76, 231.53, 219.43, 207.35, 195.22, 183.06, 169.47};
    //std::vector <double> northSteps(fakeNorthPoints, fakeNorthPoints + 27);
    //std::vector <double> southSteps(fakeSouthPoints, fakeSouthPoints + 27);
    std::vector <double> northSteps = m_BLT->GetNorthSteps();
    std::vector <double> southSteps = m_BLT->GetSouthSteps();

    double xScaleFactor;
    double yScaleFactor;
    int xOrigin;
    int yOrigin;
    int ptRadius;
    int graphWindowWidth;
    int graphWindowHeight;
    int numNorth;
    double northInc;
    int numSouth;

    // Find the max excursion from the origin in order to scale the points to fit the bitmap
    double maxDec = -9999.0;
    double minDec = 9999.0;
    for (std::vector<double>::const_iterator it = northSteps.begin(); it != northSteps.end(); ++it)
    {
        maxDec = wxMax(maxDec, *it);
        minDec = wxMin(minDec, *it);
    }

    for (std::vector<double>::const_iterator it = southSteps.begin(); it != southSteps.end(); ++it)
    {
        maxDec = wxMax(maxDec, *it);
        minDec = wxMin(minDec, *it);
    }

    graphWindowWidth = bmpWidth;
    graphWindowHeight = 0.7 * bmpHeight;
    yScaleFactor = (graphWindowHeight) / (maxDec - minDec + 1);
    xScaleFactor = (graphWindowWidth) / (northSteps.size() + southSteps.size());

    // Since we get mount coordinates, north steps will always be in ascending order
    numNorth = northSteps.size();
    northInc = (northSteps.at(numNorth - 1) - northSteps.at(0)) / numNorth;
    numSouth = southSteps.size();       // Should be same as numNorth but be careful

    dc.SelectObject(bmp);
    dc.SetBackground(*wxLIGHT_GREY_BRUSH);

    dc.SetFont(wxFont(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
    dc.Clear();

    // Bottom and top labels
    dc.SetTextForeground("BLUE");
    dc.DrawText(_("Ideal"), 0.7 * graphWindowWidth, bmpHeight - 25);
    dc.SetTextForeground("RED");
    dc.DrawText(_("Measured"), 0.2 * graphWindowWidth, bmpHeight - 25);
    dc.DrawText(_("North"), 0.1 * graphWindowWidth, 10);
    dc.DrawText(_("South"), 0.8 * graphWindowWidth, 10);
    // Draw the axes
    dc.SetPen(axisPen);
    xOrigin = graphWindowWidth / 2;
    yOrigin = graphWindowHeight + 40;           // Leave room at the top for labels and such
    dc.DrawLine(0, yOrigin, graphWindowWidth, yOrigin);    // x
    dc.DrawLine(xOrigin, yOrigin, xOrigin, 0);             // y

    // Draw the north steps
    dc.SetPen(redPen);
    dc.SetBrush(redBrush);
    ptRadius = 2;

    for (int i = 0; i < numNorth; i++)
    {
        wxPoint where = wxPoint(i * xScaleFactor, round(yOrigin - (northSteps.at(i) - minDec) * yScaleFactor));
        dc.DrawCircle(wxPoint(i * xScaleFactor, round(yOrigin - (northSteps.at(i) - minDec) * yScaleFactor)), ptRadius);
    }

    // Draw the south steps
    for (int i = 0; i < numSouth; i++)
    {
        dc.DrawCircle(wxPoint((i + numNorth) * xScaleFactor, round(yOrigin - (southSteps.at(i) - minDec) * yScaleFactor)), ptRadius);
    }

    // Now show an ideal south recovery line
    dc.SetPen(bluePen);
    dc.SetBrush(blueBrush);

    double peakSouth = southSteps.at(0);
    for (int i = 1; i <= numNorth; i++)
    {
        wxPoint where = wxPoint((i + numNorth)* xScaleFactor, round(yOrigin - (peakSouth - i * northInc - minDec) * yScaleFactor));
        dc.DrawCircle(where, ptRadius);
    }

    dc.SelectObject(wxNullBitmap);
    return bmp;

}
Beispiel #3
0
void
MFCClipItemView::Draw(Graphics &dc, CRect &clipBox)
{
// !!!??? need to clip properly for short instances with long names
	cerr << "clip item draw " << item->sym->name << endl;
	Pen blackPen(Color(250, 0, 0, 0), 1);
	Pen redPen(Color(250, 238, 100, 100), 1);
	Pen orangePen(Color(200, 250, 150, 10), 1);
	SolidBrush blueBrush(Color(100, 100, 100, 238));
	SolidBrush blackBrush(Color(200, 0, 0, 0));
	SolidBrush orangeBrush(Color(190, 250, 150, 10));

	dc.DrawLine( &orangePen, bounds.left, 0, bounds.left, bounds.bottom);
	bool	isMarker = false;
	if (item != NULL && item->duration.ticks <= 0) {
		isMarker = true;
	}
	if (!isMarker) {
		dc.DrawLine( &orangePen, bounds.right, 0, bounds.right, bounds.bottom);
	}

	PointF	tri[3];

	Font	labelFont(L"Arial", 8.0, FontStyleRegular, UnitPoint, NULL);
	wstring nm;
	const char *cp = item->sym->uniqueName();
	while (*cp) {
		nm.push_back(*cp++);
	}
	PointF	p;
	UINT py = 0;
	do {
		if (!isMarker) {
			// a triangle bit
			tri[0].X = bounds.left; tri[0].Y = py;
			tri[1].X = bounds.left+6; tri[1].Y = py+3;
			tri[2].X = bounds.left; tri[2].Y = py+6;
			dc.FillPolygon(&orangeBrush, tri, 3);
		}

		p.X = bounds.left-1;
		p.Y = py+5;
		RectF	box;
		StringFormat	sff = StringFormatFlagsDirectionVertical;
		dc.MeasureString(nm.c_str(), -1, &labelFont, p, &sff, &box);
		dc.DrawString(nm.c_str(), -1, &labelFont, box,	&sff, &blackBrush);

		if (!isMarker) {
			// a nother triangle bit
			tri[0].X = bounds.right;
			tri[1].X = bounds.right-6;
			tri[2].X = bounds.right;
			dc.FillPolygon(&orangeBrush, tri, 3);

			p.X = bounds.right-10;
			p.Y = py+5;
			dc.MeasureString(nm.c_str(), -1, &labelFont, p, &sff, &box);
			dc.DrawString(nm.c_str(), -1, &labelFont, box,	&sff, &blackBrush);
		}
		py += editor->bounds.bottom;
	} while (py < bounds.bottom);

}
void QCompass::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    QBrush bgGround(QColor(48,172,220));

    QPen   whitePen(Qt::white);
    QPen   blackPen(Qt::black);
    QPen   redPen(Qt::red);
    QPen   bluePen(Qt::blue);
    QPen   greenPen(Qt::green);

    whitePen.setWidth(1);
    blackPen.setWidth(2);
    redPen.setWidth(2);
    bluePen.setWidth(2);
    greenPen.setWidth(2);

    painter.setRenderHint(QPainter::Antialiasing);

    painter.translate(width() / 2, height() / 2);


    // draw background
    {
        painter.setPen(blackPen);
        painter.setBrush(bgGround);

        painter.drawEllipse(-m_size/2, -m_size/2, m_size, m_size);
    }


    // draw yaw lines
    {
        int     nyawLines = 36;
        float   rotAng = 360.0 / nyawLines;
        int     yawLineLeng = m_size/25;
        double  fx1, fy1, fx2, fy2;
        int     fontSize = 8;
        QString s;

        blackPen.setWidth(1);
        painter.setPen(blackPen);

        for(int i=0; i<nyawLines; i++) {

            if( i == 0 ) {
                s = "N";
                painter.setPen(bluePen);

                painter.setFont(QFont("", fontSize*1.3));
            } else if ( i == 9 ) {
                s = "W";
                painter.setPen(blackPen);

                painter.setFont(QFont("", fontSize*1.3));
            } else if ( i == 18 ) {
                s = "S";
                painter.setPen(redPen);

                painter.setFont(QFont("", fontSize*1.3));
            } else if ( i == 27 ) {
                s = "E";
                painter.setPen(blackPen);

                painter.setFont(QFont("", fontSize*1.3));
            } else {
                s = QString("%1").arg(i*rotAng);
                painter.setPen(blackPen);

                painter.setFont(QFont("", fontSize));
            }

            fx1 = 0;
            fy1 = -m_size/2 + m_offset;
            fx2 = 0;

            if( i % 3 == 0 ) {
                fy2 = fy1 + yawLineLeng;
                painter.drawLine(QPointF(fx1, fy1), QPointF(fx2, fy2));

                fy2 = fy1 + yawLineLeng+4;
                painter.drawText(QRectF(-50, fy2, 100, fontSize+2),
                                 Qt::AlignCenter, s);
            } else {
                fy2 = fy1 + yawLineLeng/2;
                painter.drawLine(QPointF(fx1, fy1), QPointF(fx2, fy2));
            }

            painter.rotate(-rotAng);
        }
    }

    // draw S/N arrow
    {
        int     arrowWidth = m_size/5;
        double  fx1, fy1, fx2, fy2, fx3, fy3;

        fx1 = 0;
        fy1 = -m_size/2 + m_offset + m_size/25 + 15;
        fx2 = -arrowWidth/2;
        fy2 = 0;
        fx3 = arrowWidth/2;
        fy3 = 0;

        painter.setPen(Qt::NoPen);

        painter.setBrush(QBrush(Qt::blue));
        QPointF pointsN[3] = {
            QPointF(fx1, fy1),
            QPointF(fx2, fy2),
            QPointF(fx3, fy3)
        };
        painter.drawPolygon(pointsN, 3);


        fx1 = 0;
        fy1 = m_size/2 - m_offset - m_size/25 - 15;
        fx2 = -arrowWidth/2;
        fy2 = 0;
        fx3 = arrowWidth/2;
        fy3 = 0;

        painter.setBrush(QBrush(Qt::red));
        QPointF pointsS[3] = {
            QPointF(fx1, fy1),
            QPointF(fx2, fy2),
            QPointF(fx3, fy3)
        };
        painter.drawPolygon(pointsS, 3);
    }


    // draw yaw marker
    {
        int     yawMarkerSize = m_size/12;
        double  fx1, fy1, fx2, fy2, fx3, fy3;

        painter.rotate(-m_yaw);
        painter.setBrush(QBrush(QColor(0xFF, 0x00, 0x00, 0xE0)));

        fx1 = 0;
        fy1 = -m_size/2 + m_offset;
        fx2 = fx1 - yawMarkerSize/2;
        fy2 = fy1 + yawMarkerSize;
        fx3 = fx1 + yawMarkerSize/2;
        fy3 = fy1 + yawMarkerSize;

        QPointF points[3] = {
            QPointF(fx1, fy1),
            QPointF(fx2, fy2),
            QPointF(fx3, fy3)
        };
        painter.drawPolygon(points, 3);

        painter.rotate(m_yaw);
    }

    // draw altitude
    {
        int     altFontSize = 13;
        int     fx, fy, w, h;
        QString s;
        char    buf[200];

        w  = 130;
        h  = 2*(altFontSize + 8);
        fx = -w/2;
        fy = -h/2;

        blackPen.setWidth(2);
        painter.setPen(blackPen);
        painter.setBrush(QBrush(Qt::white));
        painter.setFont(QFont("", altFontSize));

        painter.drawRoundedRect(fx, fy, w, h, 6, 6);

        painter.setPen(bluePen);
        sprintf(buf, "ALT: %6.1f m", m_alt);
        s = buf;
        painter.drawText(QRectF(fx, fy+2, w, h/2), Qt::AlignCenter, s);

        sprintf(buf, "H: %6.1f m", m_h);
        s = buf;
        painter.drawText(QRectF(fx, fy+h/2, w, h/2), Qt::AlignCenter, s);
    }
}
Beispiel #5
0
void TimeBar::paintEvent( QPaintEvent * event )
{
	QPen pen(QColor(0,0,0));
	QPen GrayPen(QColor(0,0,0,50));
	QBrush bush(QColor(0,0,0,70));
	QPainter painter(this);
	pen.setWidth(1);
	painter.setPen(pen);
	painter.setBrush(bush);

	for(int i=0;i<100;i++)
	{
		if (mZoom*i<=event->rect().right())
		{
			//绘制大刻度
			painter.drawLine(QPointF(mZoom*i,15),QPointF(mZoom*i,25));
			painter.drawText(QPointF(mZoom*i,10),QString("%1.0S").arg(i));
			
			//绘制小刻度
			for (int j=1;j<mZoom/MIN_SCALE_SIZE;j++)
			{
				painter.drawLine(QPointF(MIN_SCALE_SIZE*j+mZoom*i,20),QPointF(MIN_SCALE_SIZE*j+mZoom*i,25));
			}

			//绘制TimeLine
			QMapIterator<int,QVector<TimeLine*>*> mapIt(mTimeLine);
			while (mapIt.hasNext()) 
			{
				mapIt.next();
				
				for (QVector<TimeLine*>::const_iterator it=mapIt.value()->begin();it!=mapIt.value()->end();it++)
				{
					if ((*it)->startTime>=i*1000 && (*it)->startTime<=(i+1)*1000)
					{
						//计算TimeLine起始位置
						
						float startX=mZoom*((*it)->startTime/1000.0);
						painter.drawRoundedRect (QRectF(startX,28+mapIt.key()*15+mapIt.key()*3,mZoom*((*it)->len()/1000.0),15),5,3);
					}
				}
				
			}

			//绘制对齐线
			painter.setPen(GrayPen);
			painter.drawLine(QPointF(mZoom*i,15),QPointF(mZoom*i,event->rect().bottom()));
			painter.setPen(pen);
		}
		else
		{
			break;
		}
	}
	
	//绘制当前位置
	QPen redPen(QColor(255,0,0,125));
	painter.setPen(redPen);
	painter.setBrush(QBrush(QColor(255,0,0,125)));
	float startX=mZoom*(mCurrTime/1000.0);
	
	painter.drawLine(QPointF(startX,25),QPointF(startX,event->rect().bottom()));
	painter.drawRect(QRect(startX-3,10,6,15));

	//绘制工具提示
	
	if(!mToopTip.isEmpty())
	{
		redPen.setColor(QColor(255,0,0));
		painter.setBrush(QBrush(QColor(255,255,255)));
		painter.setPen(redPen);
		QFontMetrics fm(painter.font());
		painter.drawRect(QRect(mToolTipX-3,mToolTipY-fm.height(),fm.width(mToopTip)+3,fm.height()+6));
		painter.drawText(mToolTipX,mToolTipY,mToopTip);
	}

		
}
Beispiel #6
0
// Build the calibration "step" graph which will appear on the lefthand side of the panels
wxBitmap CalReviewDialog::CreateGraph(bool AO)
{
    wxMemoryDC memDC;
    wxBitmap bmp(CALREVIEW_BITMAP_SIZE, CALREVIEW_BITMAP_SIZE, -1);
    wxPen axisPen("BLACK", 3, wxCROSS_HATCH);
    wxPen redPen("RED", 3, wxSOLID);
    wxPen bluePen("BLUE", 3, wxSOLID);
    wxBrush redBrush("RED", wxSOLID);
    wxBrush blueBrush("BLUE", wxSOLID);
    CalibrationDetails calDetails;
    double scaleFactor;
    int ptRadius;

    if (!pSecondaryMount)
    {
        pMount->GetCalibrationDetails(&calDetails);                              // Normal case, no AO
    }
    else
    {
        if (AO)
        {
            pMount->GetCalibrationDetails(&calDetails);                          // AO tab, use AO details
        }
        else
        {
            pSecondaryMount->GetCalibrationDetails(&calDetails);                 // Mount tab, use mount details
        }
    }

    // Find the max excursion from the origin in order to scale the points to fit the bitmap
    double biggestVal = -100.0;
    for (std::vector<wxRealPoint>::const_iterator it = calDetails.raSteps.begin(); it != calDetails.raSteps.end(); ++it)
    {
        biggestVal = wxMax(biggestVal, fabs(it->x));
        biggestVal = wxMax(biggestVal, fabs(it->y));
    }

    for (std::vector<wxRealPoint>::const_iterator it = calDetails.decSteps.begin(); it != calDetails.decSteps.end(); ++it)
    {
        biggestVal = wxMax(biggestVal, fabs(it->x));
        biggestVal = wxMax(biggestVal, fabs(it->y));
    }

    if (biggestVal > 0.0)
        scaleFactor = ((CALREVIEW_BITMAP_SIZE - 5) / 2) / biggestVal;           // Leave room for circular point
    else
        scaleFactor = 1.0;

    memDC.SelectObject(bmp);
    memDC.SetBackground(*wxLIGHT_GREY_BRUSH);
    memDC.Clear();
    memDC.SetPen(axisPen);
    // Draw the axes
    memDC.SetDeviceOrigin(wxCoord(CALREVIEW_BITMAP_SIZE / 2), wxCoord(CALREVIEW_BITMAP_SIZE / 2));
    memDC.DrawLine(-CALREVIEW_BITMAP_SIZE / 2, 0, CALREVIEW_BITMAP_SIZE / 2, 0);               // x
    memDC.DrawLine(0, -CALREVIEW_BITMAP_SIZE / 2, 0, CALREVIEW_BITMAP_SIZE / 2);               // y

    if (calDetails.raStepCount > 0)
    {
        // Draw the RA data
        memDC.SetPen(redPen);
        memDC.SetBrush(redBrush);
        ptRadius = 2;

        // Scale the points, then plot them individually
        for (int i = 0; i < (int) calDetails.raSteps.size(); i++)
        {
            if (i == calDetails.raStepCount + 2)        // Valid even for "single-step" calibration
            {
                memDC.SetPen(wxPen("Red", 1));         // 1-pixel-thick red outline
                memDC.SetBrush(wxNullBrush);           // Outline only for "return" data points
                ptRadius = 3;
            }
            memDC.DrawCircle(IntPoint(calDetails.raSteps.at(i), scaleFactor), ptRadius);
        }
        // Show the line PHD2 will use for the rate
        memDC.SetPen(redPen);
        if ((int)calDetails.raSteps.size() > calDetails.raStepCount)         // New calib, includes return values
            memDC.DrawLine(IntPoint(calDetails.raSteps.at(0), scaleFactor), IntPoint(calDetails.raSteps.at(calDetails.raStepCount), scaleFactor));
        else
            memDC.DrawLine(IntPoint(calDetails.raSteps.at(0), scaleFactor), IntPoint(calDetails.raSteps.at(calDetails.raStepCount - 1), scaleFactor));
    }

    // Handle the Dec data
    memDC.SetPen(bluePen);
    memDC.SetBrush(blueBrush);
    ptRadius = 2;
    if (calDetails.decStepCount > 0)
    {
    for (int i = 0; i < (int) calDetails.decSteps.size(); i++)
        {
            if (i == calDetails.decStepCount + 2)
            {
                memDC.SetPen(wxPen("Blue", 1));         // 1-pixel-thick red outline
                memDC.SetBrush(wxNullBrush);           // Outline only for "return" data points
                ptRadius = 3;
            }
            memDC.DrawCircle(IntPoint(calDetails.decSteps.at(i), scaleFactor), ptRadius);
        }
        // Show the line PHD2 will use for the rate
        memDC.SetPen(bluePen);
        if ((int)calDetails.decSteps.size() > calDetails.decStepCount)         // New calib, includes return values
            memDC.DrawLine(IntPoint(calDetails.decSteps.at(0), scaleFactor), IntPoint(calDetails.decSteps.at(calDetails.decStepCount), scaleFactor));
        else
        memDC.DrawLine(IntPoint(calDetails.decSteps.at(0), scaleFactor), IntPoint(calDetails.decSteps.at(calDetails.decStepCount - 1), scaleFactor));
    }

    memDC.SelectObject(wxNullBitmap);
    return bmp;
}
Beispiel #7
0
void CPDObjectFrameSelected::DrawThreadRects(Gdiplus::Graphics* pGraphics, Gdiplus::Color& color, IPDMatrix* matrix)
{
	Gdiplus::Pen pen(color);
	Gdiplus::SolidBrush brush(color);

	CComQIPtr<IPDObjectFrame> frame = m_object;

	if (frame)
	{
		CComPtr<IPDObject> content;
		frame->get_content(&content);

		CComQIPtr<IPDContentText> contentText = content;
		if (contentText)
		{
			PointD m_threadPtLeft;
			PointD m_threadPtRight;

			contentText->get_threadPtIn(&m_threadPtLeft);
			contentText->get_threadPtOut(&m_threadPtRight);

			double rotation;
			matrix->getRotation(&rotation);

			CComPtr<IPDObjectText> previousContentText;
			contentText->get_previousTextThread(&previousContentText);

			CComPtr<IPDObjectText> nextContentText;
			contentText->get_nextTextThread(&nextContentText);

			Gdiplus::SolidBrush whiteBrush(Gdiplus::Color(255, 255, 255));

			{
				PointD xpt;
				matrix->transformPoint(&m_threadPtLeft, &xpt);

				Gdiplus::Rect rc(xpt.x-4, xpt.y-4, 9, 9);
				pGraphics->FillRectangle(&whiteBrush, rc);
				pGraphics->DrawRectangle(&pen, rc);

				if (previousContentText != NULL)
				{
					DrawThreadRectArrow(pGraphics, &brush, rc, rotation);
				}
			}

			{
				PointD xpt;
				matrix->transformPoint(&m_threadPtRight, &xpt);

				Gdiplus::Rect rc(xpt.x-4, xpt.y-4, 9, 9);

				pGraphics->FillRectangle(&whiteBrush, rc);

				VARIANT_BOOL overflow;
				contentText->get_overflow(&overflow);

				if (nextContentText != NULL)
				{
					pGraphics->DrawRectangle(&pen, rc);
					DrawThreadRectArrow(pGraphics, &brush, rc, rotation);
				}
				else
				{
					if (overflow)
					{
						Gdiplus::Pen redPen(Gdiplus::Color(255, 0, 0), 1);
						pGraphics->DrawRectangle(&redPen, rc);

						pGraphics->DrawLine(&redPen, rc.X+rc.Width/2, rc.Y+2, rc.X+rc.Width/2, rc.GetBottom()-1);
						pGraphics->DrawLine(&redPen, rc.X+2, rc.Y+rc.Height/2, rc.GetRight()-1, rc.Y+rc.Height/2);
					}
					else
					{
						pGraphics->DrawRectangle(&pen, rc);
					}
				}
			}
		}

		CComPtr<IPDPathText> pathText;
		frame->get_pathText(&pathText);

		if (pathText)
		{
			CComPtr<IPDMatrix> mat0;
			mat0.CoCreateInstance(CLSID_PDMatrix);

			CComPtr<IPDMatrix> mat1;
			mat0->translate(-m_pthreadPtLeft.x, -m_pthreadPtLeft.y, &mat1);

			CComPtr<IPDMatrix> mat2;
			mat1->rotate(m_pthreadRotationLeft, &mat2);

			CComPtr<IPDMatrix> mat3;
			mat2->translate(m_pthreadPtLeft.x, m_pthreadPtLeft.y, &mat3);

			CComPtr<IPDMatrix> mat;
			mat3->multiply(matrix, &mat);

			double x = m_pthreadPtLeft.x;
			double y = m_pthreadPtLeft.y;
		//
			{
				PointD xpt1;
				mat->transformPoint((PointD*)&CDblPoint(x, y), &xpt1);

				PointD xpt2;
				mat->transformPoint((PointD*)&CDblPoint(x, y+20), &xpt2);

				pGraphics->DrawLine(&pen, (float)xpt1.x, (float)xpt1.y, (float)xpt2.x, (float)xpt2.y);
			}

			{
				PointD pts[4] =
				{
					x, y,
					x-12, y,
					x-12, y+12,
					x, y+12
				};

				PointD xpts[4];
				for (int i = 0; i < 4; i++)
				{
					mat->transformPoint(&pts[i], &xpts[i]);
				}

				pGraphics->DrawLine(&pen, (float)xpts[0].x, (float)xpts[0].y, (float)xpts[1].x, (float)xpts[1].y);
				pGraphics->DrawLine(&pen, (float)xpts[1].x, (float)xpts[1].y, (float)xpts[2].x, (float)xpts[2].y);
				pGraphics->DrawLine(&pen, (float)xpts[2].x, (float)xpts[2].y, (float)xpts[3].x, (float)xpts[3].y);
				pGraphics->DrawLine(&pen, (float)xpts[3].x, (float)xpts[3].y, (float)xpts[0].x, (float)xpts[0].y);
			}
		}
	}
}
void BpDocument::composeFireCharacteristicsDiagram( void )
{
    // Surface Module must be active and using fuel model inputs
    PropertyDict *prop = m_eqTree->m_propDict;
    if ( ! prop->boolean( "surfaceModuleActive" )
      || ! prop->boolean( "surfaceCalcFireCharacteristicsDiagram" ) )
    {
        return;
    }

    // Graph fonts.
    QFont  textFont( property()->string( "graphTextFontFamily" ),
                     property()->integer( "graphTextFontSize" ) );
    QColor textColor( property()->color( "graphTextFontColor" ) );
    QPen   textPen( textColor );
    QFont  subTitleFont( property()->string( "graphSubtitleFontFamily" ),
                    property()->integer( "graphSubtitleFontSize" ) );
    QColor subTitleColor( property()->color( "graphSubtitleFontColor" ) );

    // Open the result file
    QString resultFile = m_eqTree->m_resultFile;
    FILE *fptr = 0;
    if ( ! ( fptr = fopen( resultFile.latin1(), "r" ) ) )
    // This code block should never be executed!
    {
        QString text("");
        translate( text, "BpDocument:FireCharacteristicsDiagram:NoLogOpen",
            resultFile );
        error( text );
        return;
    }
    // Allocate ros and hpua data arrays
    int rows  = tableRows();
    int cols  = tableCols();
    int cells = rows * cols;
    double *hpua = new double[ cells ];
    checkmem( __FILE__, __LINE__, hpua, "double hpua", cells );
    double *ros = new double[ cells ];
    checkmem( __FILE__, __LINE__, ros, "double ros", cells );
    // Set the variable names we're looking for
    const char* hpuaName = "vSurfaceFireHeatPerUnitArea";
    const char* rosName = "vSurfaceFireSpreadAtHead";
    if ( prop->boolean( "surfaceConfSpreadDirInput" ) )
    {
        rosName = "vSurfaceFireSpreadAtVector";
    }
    // Read and store the ros and hpua values
    char   buffer[1024], varName[128], varUnits[128];
    int    row, col, cell;
    double value;
    double rosMax = 0.0;
    double hpuaMax = 0.0;
    while ( fgets( buffer, sizeof(buffer), fptr ) )
    {
        if ( strncmp( buffer, "CELL", 4 ) == 0 )
        {
            if ( strstr( buffer, hpuaName ) )
            {
                sscanf( buffer, "CELL %d %d %s cont %lf %s",
                    &row, &col, varName, &value, varUnits );
                cell = ( col - 1 ) + ( cols * ( row - 1) );
                if ( ( hpua[ cell ] = value ) > hpuaMax )
                {
                    hpuaMax = value;
                }
            }
            else if ( strstr( buffer, rosName ) )
            {
                sscanf( buffer, "CELL %d %d %s cont %lf %s",
                    &row, &col, varName, &value, varUnits );
                cell = ( col - 1 ) + ( cols * ( row - 1) );
                if ( ( ros[ cell ] = value ) > rosMax )
                {
                    rosMax = value;
                }
            }
        }
    }
    fclose( fptr );

    // Get variable pointers
    EqVar *hpuaVar = m_eqTree->m_varDict->find( "vSurfaceFireHeatPerUnitArea" );
    EqVar *rosVar = m_eqTree->m_varDict->find( "vSurfaceFireSpreadAtHead" );
    EqVar *fliVar = m_eqTree->m_varDict->find( "vSurfaceFireLineIntAtHead" );
    EqVar *flVar = m_eqTree->m_varDict->find( "vSurfaceFireFlameLengAtHead" );

    // Conversion factor
    double flFactor, fliFactor, rosFactor, hpuaFactor, offset;
    appSiUnits()->conversionFactorOffset(
        flVar->m_nativeUnits, flVar->m_displayUnits, &flFactor, &offset );
    appSiUnits()->conversionFactorOffset(
        fliVar->m_nativeUnits, fliVar->m_displayUnits, &fliFactor, &offset );
    appSiUnits()->conversionFactorOffset(
        hpuaVar->m_nativeUnits, hpuaVar->m_displayUnits, &hpuaFactor, &offset );
    appSiUnits()->conversionFactorOffset(
        rosVar->m_nativeUnits, rosVar->m_displayUnits, &rosFactor, &offset );

    // Determine which of four different chart scales to use
    static const int Scales = 4;
    static double RosScale[Scales] = { 100., 200., 400., 800. };        // ft/min
    static double HpuaScale[Scales] = { 2000., 4000., 8000., 16000. };  // Btu/ft2
    double rosScale = 0.;       // Max y-axis ros
    double hpuaScale = 0.;      // Max x-axis hpua
    int scale;
    for ( scale=0; scale<Scales; scale++ )
    {
        if ( rosMax < ( rosScale = RosScale[ scale ] ) )
        {
            break;
        }
    }
    for ( scale=0; scale<Scales; scale++ )
    {
        if ( hpuaMax < ( hpuaScale = HpuaScale[scale] ) )
        {
            break;
        }
    }
    // Set axis maximums to appropriate predefined scale in display units
    rosMax  = rosFactor * rosScale;
    hpuaMax = hpuaFactor * hpuaScale;
    double ratio = rosMax / hpuaMax;

    // Create the graph
    Graph  graph;
    GraphLine *graphLine;
    GraphMarker *graphMarker;
    static const int Points = 100;
    double l_x[Points];
    double l_y[Points];

    // Draw the four standard hauling chart fli-fl levels
    static const int Lines = 4;
    static const double Fli[Lines] = { 100., 500., 1000., 2000. };  // Btu/ft/s
    static const double Fl[Lines] = { 4., 8., 11., 15. };           // ft

    // Create the hauling chart lines
    // Put Fireline Int label 65% of the way along the HPUA axis (display units)
    double  xPosFli = 0.65 * hpuaMax;
    // Put Flame Length label 85% of the way along the HPUA axis (display units)
    double  xPosFl  = 0.85 * hpuaMax;
    // Fireline Int and Flame Length label Y positions (display units)
    double  yPosFl[Lines], yPosFli[Lines];
    // Icon locations (in display units)
    double xIcon[Lines+1], yIcon[Lines+1];
    double diff, minDiff;
    QString label;
    QPen    redPen( "red", 1 );
    QColor  blackColor( "black" );
    int     alignCenter = Qt::AlignHCenter | Qt::AlignVCenter;
    // Fireline intensity - flame length curves
    int     line, point;
    for ( line = 0; line < Lines; line++ )
    {
        minDiff = 999999999.;
        for ( point = 0; point < Points; point++ )
        {
            // Hpua value in native units (Btu/ft2)
            l_x[point] = ( (point+1) * hpuaScale ) / (double) Points;
            // Ros value in native units (ft/min)
            l_y[point] = 60. * Fli[line] / l_x[point];
            // Convert to display units
            l_x[point] *= hpuaFactor;
            l_y[point] *= rosFactor;
            // Check for curve inflection point (for icon placement)
            if ( ( diff = fabs( l_y[point]/l_x[point] - ratio ) ) < minDiff )
            {
                minDiff = diff;
                xIcon[line+1] = l_x[point];
                yIcon[line+1] = l_y[point];
            }
        }
        // Create a graph line (with its own copy of the data).
        graphLine = graph.addGraphLine( Points, l_x, l_y, redPen );

        // Fireline intensity label
        label = QString( "%1" ).arg( ( Fli[line] * fliFactor ), 0, 'f', 0 );
        yPosFli[line] = rosFactor * ( 60. * Fli[line] / ( xPosFli / hpuaFactor ) );
        graph.addGraphMarker( xPosFli, yPosFli[line], label, textFont,
            blackColor, alignCenter );

        // Flame length label
        label = QString( "%1" ).arg( ( Fl[line] * flFactor ), 0, 'f', 0 );
        yPosFl[line] = rosFactor * ( 60. * Fli[line] / ( xPosFl / hpuaFactor ) );
        graph.addGraphMarker( xPosFl, yPosFl[line], label, textFont,
            blackColor, alignCenter );
    } // Next line

    // Fireline intensity label and units
    translate( label, "BpDocument:FireCharacteristicsDiagram:FLI" );
    graph.addGraphMarker( xPosFli, ( yPosFli[Lines-1] + 0.10 * rosMax ),
        label, textFont, blackColor, alignCenter );
    graph.addGraphMarker( xPosFli, ( yPosFli[Lines-1] + 0.05 * rosMax ),
        fliVar->m_displayUnits, textFont, blackColor, alignCenter );

    // Flame length label and units
    translate( label, "BpDocument:FireCharacteristicsDiagram:FL" );
    graph.addGraphMarker( xPosFl, ( yPosFl[Lines-1] + 0.10 * rosMax ),
        label, textFont, blackColor, alignCenter );
    graph.addGraphMarker( xPosFl, ( yPosFl[Lines-1] + 0.05 * rosMax ),
        flVar->m_displayUnits, textFont, blackColor, alignCenter );

    // Add icons
    QPixmap pixmap[Lines];
    pixmap[0] = QPixmap( fireman_xpm );
    pixmap[1] = QPixmap( dozer_xpm );
    pixmap[2] = QPixmap( torchtree_xpm );
    pixmap[3] = QPixmap( mtnfire_xpm );
    xIcon[0] = yIcon[0] = 0.0;
    for ( line=0; line<Lines; line++ )
    {
        graphMarker = graph.addGraphMarker(
            xIcon[line] + ( 0.5 * ( xIcon[line+1] - xIcon[line] ) ),
            yIcon[line] + ( 0.5 * ( yIcon[line+1] - yIcon[line] ) ),
            "", textFont, blackColor, alignCenter );
        graphMarker->setGraphMarkerPixmap( pixmap[line] );
    }

    // Finally, add a marker for each output result
    QColor  bluePen( "blue" );
    for ( cell=0; cell<cells; cell++ )
    {
        //fprintf( stderr, "%02d: %3.2f  %3.2f\n", i, hpua[i], ros[i] );
        graph.addGraphMarker( hpua[cell], ros[cell],
            QString( "%1" ).arg( cell + 1 ), textFont, bluePen, alignCenter );
    }
    // Compose the graph
    EqVar *zVar = 0;
    GraphAxleParms xParms( 0.0, hpuaMax, 11 );
    GraphAxleParms yParms( 0.0, rosMax, 11 );
    composeGraphBasics( &graph, true, hpuaVar, rosVar, zVar, Lines,
        &xParms, &yParms );

    // Create a separate page for this graph.
    translate( label, "BpDocument:FireCharacteristicsDiagram:Caption" );
    graph.setSubTitle( label, subTitleFont, subTitleColor );
    startNewPage( label, TocHaulChart );

    // This is how we save the graph and its composer.
    m_composer->graph( graph,
        m_pageSize->m_marginLeft
            + m_pageSize->m_bodyWd * property()->real( "graphXOffset" ),
        m_pageSize->m_marginTop
            + m_pageSize->m_bodyHt * property()->real( "graphYOffset" ),
        m_pageSize->m_bodyWd * property()->real( "graphScaleWidth" ),
        m_pageSize->m_bodyHt * property()->real( "graphScaleHeight" )
    );
    // Be polite and stop the composer.
    m_composer->end();
    delete[] ros;   ros  = 0;
    delete[] hpua;  hpua = 0;
    return;
}
Beispiel #9
0
void BehavePlusApp::drawSplashPage( void )
{
    // If unable to load the picture, make a plain cyan backdrop instead
    if ( m_pixmap.isNull() )
    // This code block should never be executed!
    {
        m_pixmap.resize( 700, 500 );
        QPainter paint( &m_pixmap );
        paint.fillRect( 0, 0, 700, 500, QBrush( "cyan", SolidPattern ) );
        paint.end();
    }

    // Painter attributes
    int align = Qt::AlignHCenter | Qt::AlignTop ;
    //static QString fontName( "Times New Roman" );
    static QString fontName( "Arial" );
    QFont fnt1( fontName, 48, QFont::Bold, false );
    QFont fnt2( fontName, 24, QFont::Bold, false );
    QFont fnt3( fontName, 16, QFont::Bold, false );
    QFontMetrics fm1( fnt1 );
    QFontMetrics fm2( fnt2 );
    QFontMetrics fm3( fnt3 );
    QPen blackPen( black );
    QPen grayPen( gray );
    QPen redPen( red );
    QPen whitePen( white );

    // Draw shadowed name
    QPainter paint( &m_pixmap );
    int wd = m_pixmap.width();
    int ht = m_pixmap.height() + 3 * fm3.lineSpacing();
    paint.setFont( fnt1 );
    paint.setPen( grayPen );
    int y0 = fm1.lineSpacing()/8;
    paint.drawText( 4, y0+4, wd, ht, align, m_program );
    paint.setPen( blackPen );
    paint.drawText( 2, y0+2, wd, ht, align, m_program );
    paint.setPen( whitePen );
    paint.drawText( 0, y0,   wd, ht, align, m_program );

    // Draw sub name and version
    y0 += 3*fm1.lineSpacing()/4;
    paint.setFont( fnt2 );
    paint.drawText( 0, y0, wd, ht-y0, align, "fire modeling system" );
    y0 += 3*fm2.lineSpacing()/4;
    paint.drawText( 0, y0, wd, ht-y0, align, "Version " + m_version );

    // Warning
    if ( ShowWarning )
    {
        y0 += 3 * fm2.lineSpacing();
        paint.setFont( fnt2 );
        paint.setPen( redPen );
        paint.drawText( 0, y0, wd, ht-y0, align,
            "This is pre-release software" );
        y0 += fm2.lineSpacing();
        paint.drawText( 0, y0, wd, ht-y0, align,
            "for testing purposes only!" );
        y0 += fm2.lineSpacing();
        paint.drawText( 0, y0, wd, ht-y0, align,
            "Use at Your Own Risk!" );
    }

    // Authors
    y0 = ht - 6 * fm3.lineSpacing();
    paint.setFont( fnt3 );
    paint.setPen( whitePen );
    paint.drawText( 0, y0, wd, ht-y0, align,
        "US Forest Service, Rocky Mountain Research Station" );
    y0 += fm3.lineSpacing();
    paint.drawText( 0, y0, wd, ht-y0, align,
        "& Systems for Environmental Management" );
    paint.end();

    // Status message display area
    m_statusLine = ht - 2 * fm3.lineSpacing();
    return;
}