⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drawn.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
// 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 + -