📄 constrnt.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: constrnt.cpp
// Purpose: OGL Constraint classes
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id: constrnt.cpp,v 1.11 2005/10/06 18:17:21 ABX 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"
wxList *wxOGLConstraintTypes = NULL;
/*
* Constraint type
*
*/
IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraintType, wxObject)
wxOGLConstraintType::wxOGLConstraintType(int theType, const wxString& theName, const wxString& thePhrase)
{
m_type = theType;
m_name = theName;
m_phrase = thePhrase;
}
wxOGLConstraintType::~wxOGLConstraintType()
{
}
void OGLInitializeConstraintTypes()
{
if (!wxOGLConstraintTypes)
return;
wxOGLConstraintTypes = new wxList(wxKEY_INTEGER);
wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_VERTICALLY,
new wxOGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, wxT("Centre vertically"), wxT("centred vertically w.r.t.")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_HORIZONTALLY,
new wxOGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, wxT("Centre horizontally"), wxT("centred horizontally w.r.t.")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_BOTH,
new wxOGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, wxT("Centre"), wxT("centred w.r.t.")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_LEFT_OF,
new wxOGLConstraintType(gyCONSTRAINT_LEFT_OF, wxT("Left of"), wxT("left of")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_RIGHT_OF,
new wxOGLConstraintType(gyCONSTRAINT_RIGHT_OF, wxT("Right of"), wxT("right of")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_ABOVE,
new wxOGLConstraintType(gyCONSTRAINT_ABOVE, wxT("Above"), wxT("above")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_BELOW,
new wxOGLConstraintType(gyCONSTRAINT_BELOW, wxT("Below"), wxT("below")));
// Alignment
wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_TOP,
new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, wxT("Top-aligned"), wxT("aligned to the top of")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_BOTTOM,
new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, wxT("Bottom-aligned"), wxT("aligned to the bottom of")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_LEFT,
new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, wxT("Left-aligned"), wxT("aligned to the left of")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_RIGHT,
new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, wxT("Right-aligned"), wxT("aligned to the right of")));
// Mid-alignment
wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_TOP,
new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, wxT("Top-midaligned"), wxT("centred on the top of")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_BOTTOM,
new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, wxT("Bottom-midaligned"), wxT("centred on the bottom of")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_LEFT,
new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, wxT("Left-midaligned"), wxT("centred on the left of")));
wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_RIGHT,
new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, wxT("Right-midaligned"), wxT("centred on the right of")));
}
void OGLCleanUpConstraintTypes()
{
if (!wxOGLConstraintTypes)
return;
wxNode* node = wxOGLConstraintTypes->GetFirst();
while (node)
{
wxOGLConstraintType* ct = (wxOGLConstraintType*) node->GetData();
delete ct;
node = node->GetNext();
}
delete wxOGLConstraintTypes;
wxOGLConstraintTypes = NULL;
}
/*
* Constraint Stuff
*
*/
IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraint, wxObject)
wxOGLConstraint::wxOGLConstraint(int type, wxShape *constraining, wxList& constrained)
{
m_xSpacing = 0.0;
m_ySpacing = 0.0;
m_constraintType = type;
m_constrainingObject = constraining;
m_constraintId = 0;
m_constraintName = wxT("noname");
wxNode *node = constrained.GetFirst();
while (node)
{
m_constrainedObjects.Append(node->GetData());
node = node->GetNext();
}
}
wxOGLConstraint::~wxOGLConstraint()
{
}
bool wxOGLConstraint::Equals(double a, double b)
{
double marg = 0.5;
bool eq = ((b <= a + marg) && (b >= a - marg));
return eq;
}
// Return true if anything changed
bool wxOGLConstraint::Evaluate()
{
double maxWidth, maxHeight, minWidth, minHeight, x, y;
m_constrainingObject->GetBoundingBoxMax(&maxWidth, &maxHeight);
m_constrainingObject->GetBoundingBoxMin(&minWidth, &minHeight);
x = m_constrainingObject->GetX();
y = m_constrainingObject->GetY();
wxClientDC dc(m_constrainingObject->GetCanvas());
m_constrainingObject->GetCanvas()->PrepareDC(dc);
switch (m_constraintType)
{
case gyCONSTRAINT_CENTRED_VERTICALLY:
{
int n = m_constrainedObjects.GetCount();
double totalObjectHeight = 0.0;
wxNode *node = m_constrainedObjects.GetFirst();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->GetData();
double width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
totalObjectHeight += height2;
node = node->GetNext();
}
double startY;
double spacingY;
// Check if within the constraining object...
if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
{
spacingY = (double)((minHeight - totalObjectHeight)/(n + 1));
startY = (double)(y - (minHeight/2.0));
}
// Otherwise, use default spacing
else
{
spacingY = m_ySpacing;
startY = (double)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
}
// Now position the objects
bool changed = false;
node = m_constrainedObjects.GetFirst();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->GetData();
double width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
startY += (double)(spacingY + (height2/2.0));
if (!Equals(startY, constrainedObject->GetY()))
{
constrainedObject->Move(dc, constrainedObject->GetX(), startY, false);
changed = true;
}
startY += (double)(height2/2.0);
node = node->GetNext();
}
return changed;
}
case gyCONSTRAINT_CENTRED_HORIZONTALLY:
{
int n = m_constrainedObjects.GetCount();
double totalObjectWidth = 0.0;
wxNode *node = m_constrainedObjects.GetFirst();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->GetData();
double width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
totalObjectWidth += width2;
node = node->GetNext();
}
double startX;
double spacingX;
// Check if within the constraining object...
if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
{
spacingX = (double)((minWidth - totalObjectWidth)/(n + 1));
startX = (double)(x - (minWidth/2.0));
}
// Otherwise, use default spacing
else
{
spacingX = m_xSpacing;
startX = (double)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
}
// Now position the objects
bool changed = false;
node = m_constrainedObjects.GetFirst();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->GetData();
double width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
startX += (double)(spacingX + (width2/2.0));
if (!Equals(startX, constrainedObject->GetX()))
{
constrainedObject->Move(dc, startX, constrainedObject->GetY(), false);
changed = true;
}
startX += (double)(width2/2.0);
node = node->GetNext();
}
return changed;
}
case gyCONSTRAINT_CENTRED_BOTH:
{
int n = m_constrainedObjects.GetCount();
double totalObjectWidth = 0.0;
double totalObjectHeight = 0.0;
wxNode *node = m_constrainedObjects.GetFirst();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->GetData();
double width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
totalObjectWidth += width2;
totalObjectHeight += height2;
node = node->GetNext();
}
double startX;
double spacingX;
double startY;
double spacingY;
// Check if within the constraining object...
if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
{
spacingX = (double)((minWidth - totalObjectWidth)/(n + 1));
startX = (double)(x - (minWidth/2.0));
}
// Otherwise, use default spacing
else
{
spacingX = m_xSpacing;
startX = (double)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
}
// Check if within the constraining object...
if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
{
spacingY = (double)((minHeight - totalObjectHeight)/(n + 1));
startY = (double)(y - (minHeight/2.0));
}
// Otherwise, use default spacing
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -