📄 drawn.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: drawn.cpp
// Purpose: wxDrawnShape
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id: drawn.cpp,v 1.21 2006/04/18 22:26:26 PC Exp $
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#if wxUSE_PROLOGIO
#include "wx/deprecated/wxexpr.h"
#endif
#include "wx/ogl/ogl.h"
#if wxUSE_PROLOGIO
static void IntToHex(unsigned int dec, wxChar *buf);
static unsigned long HexToInt(wxChar *buf);
#endif
extern wxChar *oglBuffer;
#define gyTYPE_PEN 40
#define gyTYPE_BRUSH 41
#define gyTYPE_FONT 42
/*
* Drawn object
*
*/
IMPLEMENT_DYNAMIC_CLASS(wxDrawnShape, wxRectangleShape)
wxDrawnShape::wxDrawnShape():wxRectangleShape(100.0, 50.0)
{
m_saveToFile = true;
m_currentAngle = oglDRAWN_ANGLE_0;
}
wxDrawnShape::~wxDrawnShape()
{
}
void wxDrawnShape::OnDraw(wxDC& dc)
{
// Pass pen and brush in case we have force outline
// and fill colours
if (m_shadowMode != SHADOW_NONE)
{
if (m_shadowBrush)
m_metafiles[m_currentAngle].m_fillBrush = m_shadowBrush;
m_metafiles[m_currentAngle].m_outlinePen = g_oglTransparentPen;
m_metafiles[m_currentAngle].Draw(dc, m_xpos + m_shadowOffsetX, m_ypos + m_shadowOffsetY);
}
m_metafiles[m_currentAngle].m_outlinePen = m_pen;
m_metafiles[m_currentAngle].m_fillBrush = m_brush;
m_metafiles[m_currentAngle].Draw(dc, m_xpos, m_ypos);
}
void wxDrawnShape::SetSize(double w, double h, bool WXUNUSED(recursive))
{
SetAttachmentSize(w, h);
double scaleX;
double scaleY;
if (GetWidth() == 0.0)
scaleX = 1.0;
else scaleX = w/GetWidth();
if (GetHeight() == 0.0)
scaleY = 1.0;
else scaleY = h/GetHeight();
for (int i = 0; i < 4; i++)
{
if (m_metafiles[i].IsValid())
m_metafiles[i].Scale(scaleX, scaleY);
}
m_width = w;
m_height = h;
SetDefaultRegionSize();
}
void wxDrawnShape::Scale(double sx, double sy)
{
int i;
for (i = 0; i < 4; i++)
{
if (m_metafiles[i].IsValid())
{
m_metafiles[i].Scale(sx, sy);
m_metafiles[i].CalculateSize(this);
}
}
}
void wxDrawnShape::Translate(double x, double y)
{
int i;
for (i = 0; i < 4; i++)
{
if (m_metafiles[i].IsValid())
{
m_metafiles[i].Translate(x, y);
m_metafiles[i].CalculateSize(this);
}
}
}
// theta is absolute rotation from the zero position
void wxDrawnShape::Rotate(double x, double y, double theta)
{
m_currentAngle = DetermineMetaFile(theta);
if (m_currentAngle == 0)
{
// Rotate metafile
if (!m_metafiles[0].GetRotateable())
return;
m_metafiles[0].Rotate(x, y, theta);
}
double actualTheta = theta-m_rotation;
// Rotate attachment points
double sinTheta = (double)sin(actualTheta);
double cosTheta = (double)cos(actualTheta);
wxNode *node = m_attachmentPoints.GetFirst();
while (node)
{
wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData();
double x1 = point->m_x;
double y1 = point->m_y;
point->m_x = x1*cosTheta - y1*sinTheta + x*(1.0 - cosTheta) + y*sinTheta;
point->m_y = x1*sinTheta + y1*cosTheta + y*(1.0 - cosTheta) + x*sinTheta;
node = node->GetNext();
}
m_rotation = theta;
m_metafiles[m_currentAngle].CalculateSize(this);
}
// Which metafile do we use now? Based on current rotation and validity
// of metafiles.
int wxDrawnShape::DetermineMetaFile(double rotation)
{
double tolerance = 0.0001;
const double pi = M_PI ;
double angle1 = 0.0;
double angle2 = pi/2.0;
double angle3 = pi;
double angle4 = 3.0*pi/2.0;
int whichMetafile = 0;
if (oglRoughlyEqual(rotation, angle1, tolerance))
{
whichMetafile = 0;
}
else if (oglRoughlyEqual(rotation, angle2, tolerance))
{
whichMetafile = 1;
}
else if (oglRoughlyEqual(rotation, angle3, tolerance))
{
whichMetafile = 2;
}
else if (oglRoughlyEqual(rotation, angle4, tolerance))
{
whichMetafile = 3;
}
if ((whichMetafile > 0) && !m_metafiles[whichMetafile].IsValid())
whichMetafile = 0;
return whichMetafile;
}
void wxDrawnShape::OnDrawOutline(wxDC& dc, double x, double y, double w, double h)
{
if (m_metafiles[m_currentAngle].GetOutlineOp() != -1)
{
wxNode* node = m_metafiles[m_currentAngle].GetOps().Item(m_metafiles[m_currentAngle].GetOutlineOp());
wxASSERT (node != NULL);
wxDrawOp* op = (wxDrawOp*) node->GetData();
if (op->OnDrawOutline(dc, x, y, w, h, m_width, m_height))
return;
}
// Default... just use a rectangle
wxRectangleShape::OnDrawOutline(dc, x, y, w, h);
}
// Get the perimeter point using the special outline op, if there is one,
// otherwise use default wxRectangleShape scheme
bool wxDrawnShape::GetPerimeterPoint(double x1, double y1,
double x2, double y2,
double *x3, double *y3)
{
if (m_metafiles[m_currentAngle].GetOutlineOp() != -1)
{
wxNode* node = m_metafiles[m_currentAngle].GetOps().Item(m_metafiles[m_currentAngle].GetOutlineOp());
wxASSERT (node != NULL);
wxDrawOp* op = (wxDrawOp*) node->GetData();
if (op->GetPerimeterPoint(x1, y1, x2, y2, x3, y3, GetX(), GetY(), GetAttachmentMode()))
return true;
}
// Default... just use a rectangle
return wxRectangleShape::GetPerimeterPoint(x1, y1, x2, y2, x3, y3);
}
#if wxUSE_PROLOGIO
void wxDrawnShape::WriteAttributes(wxExpr *clause)
{
wxRectangleShape::WriteAttributes(clause);
clause->AddAttributeValue(_T("current_angle"), (long)m_currentAngle);
clause->AddAttributeValue(_T("save_metafile"), (long)m_saveToFile);
if (m_saveToFile)
{
for (int i = 0; i < 4; i++)
{
if (m_metafiles[i].IsValid())
m_metafiles[i].WriteAttributes(clause, i);
}
}
}
void wxDrawnShape::ReadAttributes(wxExpr *clause)
{
wxRectangleShape::ReadAttributes(clause);
int iVal = (int) m_saveToFile;
clause->GetAttributeValue(_T("save_metafile"), iVal);
clause->GetAttributeValue(_T("current_angle"), m_currentAngle);
m_saveToFile = (iVal != 0);
if (m_saveToFile)
{
for (int i = 0; i < 4; i++)
{
m_metafiles[i].ReadAttributes(clause, i);
}
}
}
#endif
// Does the copying for this object
void wxDrawnShape::Copy(wxShape& copy)
{
wxRectangleShape::Copy(copy);
wxASSERT( copy.IsKindOf(CLASSINFO(wxDrawnShape)) ) ;
wxDrawnShape& drawnCopy = (wxDrawnShape&) copy;
for (int i = 0; i < 4; i++)
{
m_metafiles[i].Copy(drawnCopy.m_metafiles[i]);
}
drawnCopy.m_saveToFile = m_saveToFile;
drawnCopy.m_currentAngle = m_currentAngle;
}
bool wxDrawnShape::LoadFromMetaFile(const wxString& filename)
{
return m_metafiles[0].LoadFromMetaFile(filename, &m_width, &m_height);
}
// Set of functions for drawing into a pseudo metafile.
// They use integers, but doubles are used internally for accuracy
// when scaling.
void wxDrawnShape::DrawLine(const wxPoint& pt1, const wxPoint& pt2)
{
m_metafiles[m_currentAngle].DrawLine(pt1, pt2);
}
void wxDrawnShape::DrawRectangle(const wxRect& rect)
{
m_metafiles[m_currentAngle].DrawRectangle(rect);
}
void wxDrawnShape::DrawRoundedRectangle(const wxRect& rect, double radius)
{
m_metafiles[m_currentAngle].DrawRoundedRectangle(rect, radius);
}
void wxDrawnShape::DrawEllipse(const wxRect& rect)
{
m_metafiles[m_currentAngle].DrawEllipse(rect);
}
void wxDrawnShape::DrawArc(const wxPoint& centrePt, const wxPoint& startPt, const wxPoint& endPt)
{
m_metafiles[m_currentAngle].DrawArc(centrePt, startPt, endPt);
}
void wxDrawnShape::DrawEllipticArc(const wxRect& rect, double startAngle, double endAngle)
{
m_metafiles[m_currentAngle].DrawEllipticArc(rect, startAngle, endAngle);
}
void wxDrawnShape::DrawPoint(const wxPoint& pt)
{
m_metafiles[m_currentAngle].DrawPoint(pt);
}
void wxDrawnShape::DrawText(const wxString& text, const wxPoint& pt)
{
m_metafiles[m_currentAngle].DrawText(text, pt);
}
void wxDrawnShape::DrawLines(int n, wxPoint pts[])
{
m_metafiles[m_currentAngle].DrawLines(n, pts);
}
void wxDrawnShape::DrawPolygon(int n, wxPoint pts[], int flags)
{
if (flags & oglMETAFLAGS_ATTACHMENTS)
{
ClearAttachments();
int i;
for (i = 0; i < n; i++)
m_attachmentPoints.Append(new wxAttachmentPoint(i, pts[i].x, pts[i].y));
}
m_metafiles[m_currentAngle].DrawPolygon(n, pts, flags);
}
void wxDrawnShape::DrawSpline(int n, wxPoint pts[])
{
m_metafiles[m_currentAngle].DrawSpline(n, pts);
}
void wxDrawnShape::SetClippingRect(const wxRect& rect)
{
m_metafiles[m_currentAngle].SetClippingRect(rect);
}
void wxDrawnShape::DestroyClippingRect()
{
m_metafiles[m_currentAngle].DestroyClippingRect();
}
void wxDrawnShape::SetDrawnPen(const wxPen* pen, bool isOutline)
{
m_metafiles[m_currentAngle].SetPen(pen, isOutline);
}
void wxDrawnShape::SetDrawnBrush(const wxBrush* brush, bool isFill)
{
m_metafiles[m_currentAngle].SetBrush(brush, isFill);
}
void wxDrawnShape::SetDrawnFont(wxFont* font)
{
m_metafiles[m_currentAngle].SetFont(font);
}
void wxDrawnShape::SetDrawnTextColour(const wxColour& colour)
{
m_metafiles[m_currentAngle].SetTextColour(colour);
}
void wxDrawnShape::SetDrawnBackgroundColour(const wxColour& colour)
{
m_metafiles[m_currentAngle].SetBackgroundColour(colour);
}
void wxDrawnShape::SetDrawnBackgroundMode(int mode)
{
m_metafiles[m_currentAngle].SetBackgroundMode(mode);
}
/*
* Individual operations
*
*/
/*
* Set font, brush, text colour
*
*/
wxOpSetGDI::wxOpSetGDI(int theOp, wxPseudoMetaFile *theImage, int theGdiIndex, int theMode):
wxDrawOp(theOp)
{
m_gdiIndex = theGdiIndex;
m_image = theImage;
m_mode = theMode;
}
void wxOpSetGDI::Do(wxDC& dc, double WXUNUSED(xoffset), double WXUNUSED(yoffset))
{
switch (m_op)
{
case DRAWOP_SET_PEN:
{
// Check for overriding this operation for outline
// colour
if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex))
{
if (m_image->m_outlinePen)
dc.SetPen(* m_image->m_outlinePen);
}
else
{
wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex);
if (node)
{
wxPen *pen = (wxPen *)node->GetData();
if (pen)
dc.SetPen(* pen);
}
}
break;
}
case DRAWOP_SET_BRUSH:
{
// Check for overriding this operation for outline or fill
// colour
if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex))
{
// Need to construct a brush to match the outline pen's colour
if (m_image->m_outlinePen)
{
wxBrush *br = wxTheBrushList->FindOrCreateBrush(m_image->m_outlinePen->GetColour(), wxSOLID);
if (br)
dc.SetBrush(* br);
}
}
else if (m_image->m_fillColours.Member((wxObject *)m_gdiIndex))
{
if (m_image->m_fillBrush)
{
dc.SetBrush(* m_image->m_fillBrush);
}
}
else
{
wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex);
if (node)
{
wxBrush *brush = (wxBrush *)node->GetData();
if (brush)
dc.SetBrush(* brush);
}
}
break;
}
case DRAWOP_SET_FONT:
{
wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex);
if (node)
{
wxFont *font = (wxFont *)node->GetData();
if (font)
dc.SetFont(* font);
}
break;
}
case DRAWOP_SET_TEXT_COLOUR:
{
wxColour col(m_r,m_g,m_b);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -