📄 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_PROLOGIOstatic void IntToHex(unsigned int dec, wxChar *buf);static unsigned long HexToInt(wxChar *buf);#endifextern 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 positionvoid 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 schemebool 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_PROLOGIOvoid 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 objectvoid 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); dc.SetTextForeground(col); break; } case DRAWOP_SET_BK_COLOUR: { wxColour col(m_r,m_g,m_b); dc.SetTextBackground(col); break; } case DRAWOP_SET_BK_MODE: { dc.SetBackgroundMode(m_mode); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -