Code-style consistency improvement:

Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files.
make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type.
This commit contains no other changes aside from adding and applying clang-format-all.sh
This commit is contained in:
erwincoumans
2018-09-23 14:17:31 -07:00
parent b73b05e9fb
commit ab8f16961e
1773 changed files with 1081087 additions and 474249 deletions

View File

@@ -30,7 +30,6 @@ subject to the following restrictions:
#include <iostream>
using namespace std;
#include "Jacobian.h"
void Arrow(const VectorR3& tail, const VectorR3& head);
@@ -39,15 +38,15 @@ void Arrow(const VectorR3& tail, const VectorR3& head);
//extern VectorR3 target1[];
// Optimal damping values have to be determined in an ad hoc manner (Yuck!)
const double Jacobian::DefaultDampingLambda = 0.6; // Optimal for the "Y" shape (any lower gives jitter)
const double Jacobian::DefaultDampingLambda = 0.6; // Optimal for the "Y" shape (any lower gives jitter)
//const double Jacobian::DefaultDampingLambda = 1.1; // Optimal for the DLS "double Y" shape (any lower gives jitter)
// const double Jacobian::DefaultDampingLambda = 0.7; // Optimal for the DLS "double Y" shape with distance clamping (lower gives jitter)
const double Jacobian::PseudoInverseThresholdFactor = 0.01;
const double Jacobian::MaxAngleJtranspose = 30.0*DegreesToRadians;
const double Jacobian::MaxAnglePseudoinverse = 5.0*DegreesToRadians;
const double Jacobian::MaxAngleDLS = 45.0*DegreesToRadians;
const double Jacobian::MaxAngleSDLS = 45.0*DegreesToRadians;
const double Jacobian::MaxAngleJtranspose = 30.0 * DegreesToRadians;
const double Jacobian::MaxAnglePseudoinverse = 5.0 * DegreesToRadians;
const double Jacobian::MaxAngleDLS = 45.0 * DegreesToRadians;
const double Jacobian::MaxAngleSDLS = 45.0 * DegreesToRadians;
const double Jacobian::BaseMaxTargetDist = 0.4;
Jacobian::Jacobian(Tree* tree)
@@ -55,86 +54,85 @@ Jacobian::Jacobian(Tree* tree)
m_tree = tree;
m_nEffector = tree->GetNumEffector();
nJoint = tree->GetNumJoint();
nRow = 3 * m_nEffector; // Include only the linear part
nRow = 3 * m_nEffector; // Include only the linear part
nCol = nJoint;
Jend.SetSize(nRow, nCol); // The Jocobian matrix
Jend.SetSize(nRow, nCol); // The Jocobian matrix
Jend.SetZero();
Jtarget.SetSize(nRow, nCol); // The Jacobian matrix based on target positions
Jtarget.SetSize(nRow, nCol); // The Jacobian matrix based on target positions
Jtarget.SetZero();
SetJendActive();
U.SetSize(nRow, nRow); // The U matrix for SVD calculations
w .SetLength(Min(nRow, nCol));
V.SetSize(nCol, nCol); // The V matrix for SVD calculations
U.SetSize(nRow, nRow); // The U matrix for SVD calculations
w.SetLength(Min(nRow, nCol));
V.SetSize(nCol, nCol); // The V matrix for SVD calculations
dS.SetLength(nRow); // (Target positions) - (End effector positions)
dTheta.SetLength(nCol); // Changes in joint angles
dS.SetLength(nRow); // (Target positions) - (End effector positions)
dTheta.SetLength(nCol); // Changes in joint angles
dPreTheta.SetLength(nCol);
// Used by Jacobian transpose method & DLS & SDLS
dT1.SetLength(nRow); // Linearized change in end effector positions based on dTheta
dT1.SetLength(nRow); // Linearized change in end effector positions based on dTheta
// Used by the Selectively Damped Least Squares Method
//dT.SetLength(nRow);
dSclamp.SetLength(m_nEffector);
errorArray.SetLength(m_nEffector);
Jnorms.SetSize(m_nEffector, nCol); // Holds the norms of the active J matrix
Jnorms.SetSize(m_nEffector, nCol); // Holds the norms of the active J matrix
Reset();
}
Jacobian::Jacobian(bool useAngularJacobian,int nDof)
Jacobian::Jacobian(bool useAngularJacobian, int nDof)
{
m_tree = 0;
m_nEffector = 1;
if (useAngularJacobian)
{
nRow = 2 * 3 * m_nEffector; // Include both linear and angular part
} else
nRow = 2 * 3 * m_nEffector; // Include both linear and angular part
}
else
{
nRow = 3 * m_nEffector; // Include only the linear part
nRow = 3 * m_nEffector; // Include only the linear part
}
nCol = nDof;
Jend.SetSize(nRow, nCol); // The Jocobian matrix
Jend.SetSize(nRow, nCol); // The Jocobian matrix
Jend.SetZero();
Jtarget.SetSize(nRow, nCol); // The Jacobian matrix based on target positions
Jtarget.SetSize(nRow, nCol); // The Jacobian matrix based on target positions
Jtarget.SetZero();
SetJendActive();
U.SetSize(nRow, nRow); // The U matrix for SVD calculations
w .SetLength(Min(nRow, nCol));
V.SetSize(nCol, nCol); // The V matrix for SVD calculations
U.SetSize(nRow, nRow); // The U matrix for SVD calculations
w.SetLength(Min(nRow, nCol));
V.SetSize(nCol, nCol); // The V matrix for SVD calculations
dS.SetLength(nRow); // (Target positions) - (End effector positions)
dTheta.SetLength(nCol); // Changes in joint angles
dS.SetLength(nRow); // (Target positions) - (End effector positions)
dTheta.SetLength(nCol); // Changes in joint angles
dPreTheta.SetLength(nCol);
// Used by Jacobian transpose method & DLS & SDLS
dT1.SetLength(nRow); // Linearized change in end effector positions based on dTheta
dT1.SetLength(nRow); // Linearized change in end effector positions based on dTheta
// Used by the Selectively Damped Least Squares Method
//dT.SetLength(nRow);
dSclamp.SetLength(m_nEffector);
errorArray.SetLength(m_nEffector);
Jnorms.SetSize(m_nEffector, nCol); // Holds the norms of the active J matrix
Jnorms.SetSize(m_nEffector, nCol); // Holds the norms of the active J matrix
Reset();
}
void Jacobian::Reset()
void Jacobian::Reset()
{
// Used by Damped Least Squares Method
DampingLambda = DefaultDampingLambda;
DampingLambdaSq = Square(DampingLambda);
// DampingLambdaSDLS = 1.5*DefaultDampingLambda;
dSclamp.Fill(HUGE_VAL);
}
@@ -142,14 +140,16 @@ void Jacobian::Reset()
// Compute the J and K matrices (the Jacobians)
void Jacobian::ComputeJacobian(VectorR3* targets)
{
if (m_tree==0)
if (m_tree == 0)
return;
// Traverse tree to find all end effectors
VectorR3 temp;
Node* n = m_tree->GetRoot();
while ( n ) {
if ( n->IsEffector() ) {
while (n)
{
if (n->IsEffector())
{
int i = n->GetEffectorNum();
const VectorR3& targetPos = targets[i];
@@ -161,86 +161,92 @@ void Jacobian::ComputeJacobian(VectorR3* targets)
// Find all ancestors (they will usually all be joints)
// Set the corresponding entries in the Jacobians J, K.
Node* m = m_tree->GetParent(n);
while ( m ) {
while (m)
{
int j = m->GetJointNum();
assert ( 0 <=i && i<m_nEffector && 0<=j && j<nJoint );
if ( m->IsFrozen() ) {
assert(0 <= i && i < m_nEffector && 0 <= j && j < nJoint);
if (m->IsFrozen())
{
Jend.SetTriple(i, j, VectorR3::Zero);
Jtarget.SetTriple(i, j, VectorR3::Zero);
}
else {
temp = m->GetS(); // joint pos.
temp -= n->GetS(); // -(end effector pos. - joint pos.)
temp *= m->GetW(); // cross product with joint rotation axis
Jend.SetTriple(i, j, temp);
temp = m->GetS(); // joint pos.
temp -= targetPos; // -(target pos. - joint pos.)
temp *= m->GetW(); // cross product with joint rotation axis
Jtarget.SetTriple(i, j, temp);
else
{
temp = m->GetS(); // joint pos.
temp -= n->GetS(); // -(end effector pos. - joint pos.)
temp *= m->GetW(); // cross product with joint rotation axis
Jend.SetTriple(i, j, temp);
temp = m->GetS(); // joint pos.
temp -= targetPos; // -(target pos. - joint pos.)
temp *= m->GetW(); // cross product with joint rotation axis
Jtarget.SetTriple(i, j, temp);
}
m = m_tree->GetParent( m );
m = m_tree->GetParent(m);
}
}
n = m_tree->GetSuccessor( n );
n = m_tree->GetSuccessor(n);
}
}
void Jacobian::SetJendTrans(MatrixRmn& J)
{
Jend.SetSize(J.GetNumRows(), J.GetNumColumns());
Jend.LoadAsSubmatrix(J);
Jend.SetSize(J.GetNumRows(), J.GetNumColumns());
Jend.LoadAsSubmatrix(J);
}
void Jacobian::SetDeltaS(VectorRn& S)
{
dS.Set(S);
dS.Set(S);
}
// The delta theta values have been computed in dTheta array
// Apply the delta theta values to the joints
// Nothing is done about joint limits for now.
void Jacobian::UpdateThetas()
void Jacobian::UpdateThetas()
{
// Traverse the tree to find all joints
// Update the joint angles
Node* n = m_tree->GetRoot();
while ( n ) {
if ( n->IsJoint() ) {
while (n)
{
if (n->IsJoint())
{
int i = n->GetJointNum();
n->AddToTheta( dTheta[i] );
n->AddToTheta(dTheta[i]);
}
n = m_tree->GetSuccessor( n );
n = m_tree->GetSuccessor(n);
}
// Update the positions and rotation axes of all joints/effectors
m_tree->Compute();
}
void Jacobian::UpdateThetaDot()
{
if (m_tree==0)
if (m_tree == 0)
return;
// Traverse the tree to find all joints
// Update the joint angles
Node* n = m_tree->GetRoot();
while ( n ) {
if ( n->IsJoint() ) {
int i = n->GetJointNum();
n->UpdateTheta( dTheta[i] );
}
n = m_tree->GetSuccessor( n );
}
// Update the positions and rotation axes of all joints/effectors
m_tree->Compute();
// Traverse the tree to find all joints
// Update the joint angles
Node* n = m_tree->GetRoot();
while (n)
{
if (n->IsJoint())
{
int i = n->GetJointNum();
n->UpdateTheta(dTheta[i]);
}
n = m_tree->GetSuccessor(n);
}
// Update the positions and rotation axes of all joints/effectors
m_tree->Compute();
}
void Jacobian::CalcDeltaThetas()
void Jacobian::CalcDeltaThetas()
{
switch (CurrentUpdateMode) {
switch (CurrentUpdateMode)
{
case JACOB_Undefined:
ZeroDeltaThetas();
break;
@@ -270,162 +276,165 @@ void Jacobian::CalcDeltaThetasTranspose()
{
const MatrixRmn& J = ActiveJacobian();
J.MultiplyTranspose( dS, dTheta );
J.MultiplyTranspose(dS, dTheta);
// Scale back the dTheta values greedily
J.Multiply ( dTheta, dT1 ); // dT = J * dTheta
double alpha = Dot(dS,dT1) / dT1.NormSq();
assert ( alpha>0.0 );
// Scale back the dTheta values greedily
J.Multiply(dTheta, dT1); // dT = J * dTheta
double alpha = Dot(dS, dT1) / dT1.NormSq();
assert(alpha > 0.0);
// Also scale back to be have max angle change less than MaxAngleJtranspose
double maxChange = dTheta.MaxAbs();
double beta = MaxAngleJtranspose/maxChange;
double beta = MaxAngleJtranspose / maxChange;
dTheta *= Min(alpha, beta);
}
void Jacobian::CalcDeltaThetasPseudoinverse()
{
void Jacobian::CalcDeltaThetasPseudoinverse()
{
MatrixRmn& J = const_cast<MatrixRmn&>(ActiveJacobian());
// Compute Singular Value Decomposition
// Compute Singular Value Decomposition
// This an inefficient way to do Pseudoinverse, but it is convenient since we need SVD anyway
J.ComputeSVD( U, w, V );
J.ComputeSVD(U, w, V);
// Next line for debugging only
assert(J.DebugCheckSVD(U, w , V));
assert(J.DebugCheckSVD(U, w, V));
// Calculate response vector dTheta that is the DLS solution.
// Delta target values are the dS values
// We multiply by Moore-Penrose pseudo-inverse of the J matrix
double pseudoInverseThreshold = PseudoInverseThresholdFactor*w.MaxAbs();
double pseudoInverseThreshold = PseudoInverseThresholdFactor * w.MaxAbs();
long diagLength = w.GetLength();
double* wPtr = w.GetPtr();
dTheta.SetZero();
for ( long i=0; i<diagLength; i++ ) {
double dotProdCol = U.DotProductColumn( dS, i ); // Dot product with i-th column of U
for (long i = 0; i < diagLength; i++)
{
double dotProdCol = U.DotProductColumn(dS, i); // Dot product with i-th column of U
double alpha = *(wPtr++);
if ( fabs(alpha)>pseudoInverseThreshold ) {
alpha = 1.0/alpha;
MatrixRmn::AddArrayScale(V.GetNumRows(), V.GetColumnPtr(i), 1, dTheta.GetPtr(), 1, dotProdCol*alpha );
if (fabs(alpha) > pseudoInverseThreshold)
{
alpha = 1.0 / alpha;
MatrixRmn::AddArrayScale(V.GetNumRows(), V.GetColumnPtr(i), 1, dTheta.GetPtr(), 1, dotProdCol * alpha);
}
}
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if ( maxChange>MaxAnglePseudoinverse ) {
dTheta *= MaxAnglePseudoinverse/maxChange;
if (maxChange > MaxAnglePseudoinverse)
{
dTheta *= MaxAnglePseudoinverse / maxChange;
}
}
void Jacobian::CalcDeltaThetasDLSwithNullspace(const VectorRn& desiredV)
{
{
const MatrixRmn& J = ActiveJacobian();
MatrixRmn::MultiplyTranspose(J, J, U); // U = J * (J^T)
U.AddToDiagonal( DampingLambdaSq );
MatrixRmn::MultiplyTranspose(J, J, U); // U = J * (J^T)
U.AddToDiagonal(DampingLambdaSq);
// Use the next four lines instead of the succeeding two lines for the DLS method with clamped error vector e.
// CalcdTClampedFromdS();
// VectorRn dTextra(3*m_nEffector);
// U.Solve( dT, &dTextra );
// J.MultiplyTranspose( dTextra, dTheta );
// Use these two lines for the traditional DLS method
U.Solve( dS, &dT1 );
J.MultiplyTranspose( dT1, dTheta );
// Compute JInv in damped least square form
MatrixRmn UInv(U.GetNumRows(),U.GetNumColumns());
U.ComputeInverse(UInv);
assert(U.DebugCheckInverse(UInv));
MatrixRmn JInv(J.GetNumColumns(), J.GetNumRows());
MatrixRmn::TransposeMultiply(J, UInv, JInv);
// Compute null space projection
MatrixRmn JInvJ(J.GetNumColumns(), J.GetNumColumns());
MatrixRmn::Multiply(JInv, J, JInvJ);
MatrixRmn P(J.GetNumColumns(), J.GetNumColumns());
P.SetIdentity();
P -= JInvJ;
// Compute null space velocity
VectorRn nullV(J.GetNumColumns());
P.Multiply(desiredV, nullV);
U.Solve(dS, &dT1);
J.MultiplyTranspose(dT1, dTheta);
// Compute JInv in damped least square form
MatrixRmn UInv(U.GetNumRows(), U.GetNumColumns());
U.ComputeInverse(UInv);
assert(U.DebugCheckInverse(UInv));
MatrixRmn JInv(J.GetNumColumns(), J.GetNumRows());
MatrixRmn::TransposeMultiply(J, UInv, JInv);
// Compute null space projection
MatrixRmn JInvJ(J.GetNumColumns(), J.GetNumColumns());
MatrixRmn::Multiply(JInv, J, JInvJ);
MatrixRmn P(J.GetNumColumns(), J.GetNumColumns());
P.SetIdentity();
P -= JInvJ;
// Compute null space velocity
VectorRn nullV(J.GetNumColumns());
P.Multiply(desiredV, nullV);
// Compute residual
VectorRn residual(J.GetNumRows());
J.Multiply(nullV, residual);
// TODO: Use residual to set the null space term coefficient adaptively.
//printf("residual: %f\n", residual.Norm());
// Add null space velocity
dTheta += nullV;
// Add null space velocity
dTheta += nullV;
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if ( maxChange>MaxAngleDLS ) {
dTheta *= MaxAngleDLS/maxChange;
if (maxChange > MaxAngleDLS)
{
dTheta *= MaxAngleDLS / maxChange;
}
}
void Jacobian::CalcDeltaThetasDLS()
{
const MatrixRmn& J = ActiveJacobian();
MatrixRmn::MultiplyTranspose(J, J, U); // U = J * (J^T)
U.AddToDiagonal( DampingLambdaSq );
// Use the next four lines instead of the succeeding two lines for the DLS method with clamped error vector e.
// CalcdTClampedFromdS();
// VectorRn dTextra(3*m_nEffector);
// U.Solve( dT, &dTextra );
// J.MultiplyTranspose( dTextra, dTheta );
// Use these two lines for the traditional DLS method
U.Solve( dS, &dT1 );
J.MultiplyTranspose( dT1, dTheta );
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if ( maxChange>MaxAngleDLS ) {
dTheta *= MaxAngleDLS/maxChange;
}
const MatrixRmn& J = ActiveJacobian();
MatrixRmn::MultiplyTranspose(J, J, U); // U = J * (J^T)
U.AddToDiagonal(DampingLambdaSq);
// Use the next four lines instead of the succeeding two lines for the DLS method with clamped error vector e.
// CalcdTClampedFromdS();
// VectorRn dTextra(3*m_nEffector);
// U.Solve( dT, &dTextra );
// J.MultiplyTranspose( dTextra, dTheta );
// Use these two lines for the traditional DLS method
U.Solve(dS, &dT1);
J.MultiplyTranspose(dT1, dTheta);
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if (maxChange > MaxAngleDLS)
{
dTheta *= MaxAngleDLS / maxChange;
}
}
void Jacobian::CalcDeltaThetasDLS2(const VectorRn& dVec)
{
const MatrixRmn& J = ActiveJacobian();
U.SetSize(J.GetNumColumns(), J.GetNumColumns());
MatrixRmn::TransposeMultiply(J, J, U);
U.AddToDiagonal( dVec );
dT1.SetLength(J.GetNumColumns());
J.MultiplyTranspose(dS, dT1);
U.Solve(dT1, &dTheta);
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if ( maxChange>MaxAngleDLS ) {
dTheta *= MaxAngleDLS/maxChange;
}
}
void Jacobian::CalcDeltaThetasDLSwithSVD()
{
const MatrixRmn& J = ActiveJacobian();
// Compute Singular Value Decomposition
U.SetSize(J.GetNumColumns(), J.GetNumColumns());
MatrixRmn::TransposeMultiply(J, J, U);
U.AddToDiagonal(dVec);
dT1.SetLength(J.GetNumColumns());
J.MultiplyTranspose(dS, dT1);
U.Solve(dT1, &dTheta);
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if (maxChange > MaxAngleDLS)
{
dTheta *= MaxAngleDLS / maxChange;
}
}
void Jacobian::CalcDeltaThetasDLSwithSVD()
{
const MatrixRmn& J = ActiveJacobian();
// Compute Singular Value Decomposition
// This an inefficient way to do DLS, but it is convenient since we need SVD anyway
J.ComputeSVD( U, w, V );
J.ComputeSVD(U, w, V);
// Next line for debugging only
assert(J.DebugCheckSVD(U, w , V));
assert(J.DebugCheckSVD(U, w, V));
// Calculate response vector dTheta that is the DLS solution.
// Delta target values are the dS values
@@ -433,31 +442,32 @@ void Jacobian::CalcDeltaThetasDLSwithSVD()
long diagLength = w.GetLength();
double* wPtr = w.GetPtr();
dTheta.SetZero();
for ( long i=0; i<diagLength; i++ ) {
double dotProdCol = U.DotProductColumn( dS, i ); // Dot product with i-th column of U
for (long i = 0; i < diagLength; i++)
{
double dotProdCol = U.DotProductColumn(dS, i); // Dot product with i-th column of U
double alpha = *(wPtr++);
alpha = alpha/(Square(alpha)+DampingLambdaSq);
MatrixRmn::AddArrayScale(V.GetNumRows(), V.GetColumnPtr(i), 1, dTheta.GetPtr(), 1, dotProdCol*alpha );
alpha = alpha / (Square(alpha) + DampingLambdaSq);
MatrixRmn::AddArrayScale(V.GetNumRows(), V.GetColumnPtr(i), 1, dTheta.GetPtr(), 1, dotProdCol * alpha);
}
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if ( maxChange>MaxAngleDLS ) {
dTheta *= MaxAngleDLS/maxChange;
if (maxChange > MaxAngleDLS)
{
dTheta *= MaxAngleDLS / maxChange;
}
}
void Jacobian::CalcDeltaThetasSDLS()
{
void Jacobian::CalcDeltaThetasSDLS()
{
const MatrixRmn& J = ActiveJacobian();
// Compute Singular Value Decomposition
// Compute Singular Value Decomposition
J.ComputeSVD( U, w, V );
J.ComputeSVD(U, w, V);
// Next line for debugging only
assert(J.DebugCheckSVD(U, w , V));
assert(J.DebugCheckSVD(U, w, V));
// Calculate response vector dTheta that is the SDLS solution.
// Delta target values are the dS values
@@ -469,9 +479,10 @@ void Jacobian::CalcDeltaThetasSDLS()
// Calculate the norms of the 3-vectors in the Jacobian
long i;
const double *jx = J.GetPtr();
double *jnx = Jnorms.GetPtr();
for ( i=nCols*numEndEffectors; i>0; i-- ) {
const double* jx = J.GetPtr();
double* jnx = Jnorms.GetPtr();
for (i = nCols * numEndEffectors; i > 0; i--)
{
double accumSq = Square(*(jx++));
accumSq += Square(*(jx++));
accumSq += Square(*(jx++));
@@ -482,27 +493,29 @@ void Jacobian::CalcDeltaThetasSDLS()
CalcdTClampedFromdS();
// Loop over each singular vector
for ( i=0; i<nRows; i++ ) {
for (i = 0; i < nRows; i++)
{
double wiInv = w[i];
if ( NearZero(wiInv,1.0e-10) ) {
if (NearZero(wiInv, 1.0e-10))
{
continue;
}
wiInv = 1.0/wiInv;
wiInv = 1.0 / wiInv;
double N = 0.0; // N is the quasi-1-norm of the i-th column of U
double alpha = 0.0; // alpha is the dot product of dT and the i-th column of U
double N = 0.0; // N is the quasi-1-norm of the i-th column of U
double alpha = 0.0; // alpha is the dot product of dT and the i-th column of U
const double *dTx = dT1.GetPtr();
const double *ux = U.GetColumnPtr(i);
const double* dTx = dT1.GetPtr();
const double* ux = U.GetColumnPtr(i);
long j;
for ( j=numEndEffectors; j>0; j-- ) {
for (j = numEndEffectors; j > 0; j--)
{
double tmp;
alpha += (*ux)*(*(dTx++));
tmp = Square( *(ux++) );
alpha += (*ux)*(*(dTx++));
alpha += (*ux) * (*(dTx++));
tmp = Square(*(ux++));
alpha += (*ux) * (*(dTx++));
tmp += Square(*(ux++));
alpha += (*ux)*(*(dTx++));
alpha += (*ux) * (*(dTx++));
tmp += Square(*(ux++));
N += sqrt(tmp);
}
@@ -510,29 +523,32 @@ void Jacobian::CalcDeltaThetasSDLS()
// M is the quasi-1-norm of the response to angles changing according to the i-th column of V
// Then is multiplied by the wiInv value.
double M = 0.0;
double *vx = V.GetColumnPtr(i);
double* vx = V.GetColumnPtr(i);
jnx = Jnorms.GetPtr();
for ( j=nCols; j>0; j-- ) {
double accum=0.0;
for ( long k=numEndEffectors; k>0; k-- ) {
for (j = nCols; j > 0; j--)
{
double accum = 0.0;
for (long k = numEndEffectors; k > 0; k--)
{
accum += *(jnx++);
}
M += fabs((*(vx++)))*accum;
M += fabs((*(vx++))) * accum;
}
M *= fabs(wiInv);
double gamma = MaxAngleSDLS;
if ( N<M ) {
gamma *= N/M; // Scale back maximum permissable joint angle
if (N < M)
{
gamma *= N / M; // Scale back maximum permissable joint angle
}
// Calculate the dTheta from pure pseudoinverse considerations
double scale = alpha*wiInv; // This times i-th column of V is the psuedoinverse response
dPreTheta.LoadScaled( V.GetColumnPtr(i), scale );
double scale = alpha * wiInv; // This times i-th column of V is the psuedoinverse response
dPreTheta.LoadScaled(V.GetColumnPtr(i), scale);
// Now rescale the dTheta values.
double max = dPreTheta.MaxAbs();
double rescale = (gamma)/(gamma+max);
dTheta.AddScaled(dPreTheta,rescale);
double rescale = (gamma) / (gamma + max);
dTheta.AddScaled(dPreTheta, rescale);
/*if ( gamma<max) {
dTheta.AddScaled( dPreTheta, gamma/max );
}
@@ -543,28 +559,32 @@ void Jacobian::CalcDeltaThetasSDLS()
// Scale back to not exceed maximum angle changes
double maxChange = dTheta.MaxAbs();
if ( maxChange>MaxAngleSDLS ) {
dTheta *= MaxAngleSDLS/(MaxAngleSDLS+maxChange);
if (maxChange > MaxAngleSDLS)
{
dTheta *= MaxAngleSDLS / (MaxAngleSDLS + maxChange);
//dTheta *= MaxAngleSDLS/maxChange;
}
}
void Jacobian::CalcdTClampedFromdS()
void Jacobian::CalcdTClampedFromdS()
{
long len = dS.GetLength();
long j = 0;
for ( long i=0; i<len; i+=3, j++ ) {
double normSq = Square(dS[i])+Square(dS[i+1])+Square(dS[i+2]);
if ( normSq>Square(dSclamp[j]) ) {
double factor = dSclamp[j]/sqrt(normSq);
dT1[i] = dS[i]*factor;
dT1[i+1] = dS[i+1]*factor;
dT1[i+2] = dS[i+2]*factor;
for (long i = 0; i < len; i += 3, j++)
{
double normSq = Square(dS[i]) + Square(dS[i + 1]) + Square(dS[i + 2]);
if (normSq > Square(dSclamp[j]))
{
double factor = dSclamp[j] / sqrt(normSq);
dT1[i] = dS[i] * factor;
dT1[i + 1] = dS[i + 1] * factor;
dT1[i + 2] = dS[i + 2] * factor;
}
else {
else
{
dT1[i] = dS[i];
dT1[i+1] = dS[i+1];
dT1[i+2] = dS[i+2];
dT1[i + 1] = dS[i + 1];
dT1[i + 2] = dS[i + 2];
}
}
}
@@ -576,8 +596,10 @@ double Jacobian::UpdateErrorArray(VectorR3* targets)
// Traverse tree to find all end effectors
VectorR3 temp;
Node* n = m_tree->GetRoot();
while ( n ) {
if ( n->IsEffector() ) {
while (n)
{
if (n->IsEffector())
{
int i = n->GetEffectorNum();
const VectorR3& targetPos = targets[i];
temp = targetPos;
@@ -586,7 +608,7 @@ double Jacobian::UpdateErrorArray(VectorR3* targets)
errorArray[i] = err;
totalError += err;
}
n = m_tree->GetSuccessor( n );
n = m_tree->GetSuccessor(n);
}
return totalError;
}
@@ -596,8 +618,10 @@ void Jacobian::UpdatedSClampValue(VectorR3* targets)
// Traverse tree to find all end effectors
VectorR3 temp;
Node* n = m_tree->GetRoot();
while ( n ) {
if ( n->IsEffector() ) {
while (n)
{
if (n->IsEffector())
{
int i = n->GetEffectorNum();
const VectorR3& targetPos = targets[i];
@@ -605,40 +629,44 @@ void Jacobian::UpdatedSClampValue(VectorR3* targets)
// While we are at it, also update the clamping values in dSclamp;
temp = targetPos;
temp -= n->GetS();
double normSi = sqrt(Square(dS[i])+Square(dS[i+1])+Square(dS[i+2]));
double changedDist = temp.Norm()-normSi;
if ( changedDist>0.0 ) {
double normSi = sqrt(Square(dS[i]) + Square(dS[i + 1]) + Square(dS[i + 2]));
double changedDist = temp.Norm() - normSi;
if (changedDist > 0.0)
{
dSclamp[i] = BaseMaxTargetDist + changedDist;
}
else {
else
{
dSclamp[i] = BaseMaxTargetDist;
}
}
n = m_tree->GetSuccessor( n );
n = m_tree->GetSuccessor(n);
}
}
void Jacobian::CompareErrors( const Jacobian& j1, const Jacobian& j2, double* weightedDist1, double* weightedDist2 )
void Jacobian::CompareErrors(const Jacobian& j1, const Jacobian& j2, double* weightedDist1, double* weightedDist2)
{
const VectorRn& e1 = j1.errorArray;
const VectorRn& e2 = j2.errorArray;
double ret1 = 0.0;
double ret2 = 0.0;
int len = e1.GetLength();
for ( long i=0; i<len; i++ ) {
for (long i = 0; i < len; i++)
{
double v1 = e1[i];
double v2 = e2[i];
if ( v1<v2 ) {
ret1 += v1/v2;
if (v1 < v2)
{
ret1 += v1 / v2;
ret2 += 1.0;
}
else if ( v1 != 0.0 ) {
else if (v1 != 0.0)
{
ret1 += 1.0;
ret2 += v2/v1;
ret2 += v2 / v1;
}
else {
else
{
ret1 += 0.0;
ret2 += 0.0;
}
@@ -647,22 +675,26 @@ void Jacobian::CompareErrors( const Jacobian& j1, const Jacobian& j2, double* we
*weightedDist2 = ret2;
}
void Jacobian::CountErrors( const Jacobian& j1, const Jacobian& j2, int* numBetter1, int* numBetter2, int* numTies )
void Jacobian::CountErrors(const Jacobian& j1, const Jacobian& j2, int* numBetter1, int* numBetter2, int* numTies)
{
const VectorRn& e1 = j1.errorArray;
const VectorRn& e2 = j2.errorArray;
int b1=0, b2=0, tie=0;
int b1 = 0, b2 = 0, tie = 0;
int len = e1.GetLength();
for ( long i=0; i<len; i++ ) {
for (long i = 0; i < len; i++)
{
double v1 = e1[i];
double v2 = e2[i];
if ( v1<v2 ) {
if (v1 < v2)
{
b1++;
}
else if ( v2<v1 ) {
else if (v2 < v1)
{
b2++;
}
else {
else
{
tie++;
}
}
@@ -756,7 +788,3 @@ void Jacobian::CalcDeltaThetasSDLSrev2()
dTheta *= MaxAngleSDLS/maxChange;
}
} */

View File

@@ -38,103 +38,109 @@ subject to the following restrictions:
#ifdef _DYNAMIC
const double BASEMAXDIST = 0.02;
#else
const double MAXDIST = 0.08; // optimal value for double Y shape : 0.08
const double MAXDIST = 0.08; // optimal value for double Y shape : 0.08
#endif
const double DELTA = 0.4;
const long double LAMBDA = 2.0; // only for DLS. optimal : 0.24
const long double LAMBDA = 2.0; // only for DLS. optimal : 0.24
const double NEARZERO = 0.0000000001;
enum UpdateMode {
enum UpdateMode
{
JACOB_Undefined = 0,
JACOB_JacobianTranspose = 1,
JACOB_PseudoInverse = 2,
JACOB_DLS = 3,
JACOB_SDLS = 4 };
JACOB_SDLS = 4
};
class Jacobian {
class Jacobian
{
public:
Jacobian(Tree*);
Jacobian(bool useAngularJacobian, int nDof);
void ComputeJacobian(VectorR3* targets);
const MatrixRmn& ActiveJacobian() const { return *Jactive; }
void SetJendActive() { Jactive = &Jend; } // The default setting is Jend.
const MatrixRmn& ActiveJacobian() const { return *Jactive; }
void SetJendActive() { Jactive = &Jend; } // The default setting is Jend.
void SetJtargetActive() { Jactive = &Jtarget; }
void SetJendTrans(MatrixRmn& J);
void SetDeltaS(VectorRn& S);
void SetJendTrans(MatrixRmn& J);
void SetDeltaS(VectorRn& S);
void CalcDeltaThetas(); // Use this only if the Current Mode has been set.
void CalcDeltaThetas(); // Use this only if the Current Mode has been set.
void ZeroDeltaThetas();
void CalcDeltaThetasTranspose();
void CalcDeltaThetasPseudoinverse();
void CalcDeltaThetasDLS();
void CalcDeltaThetasDLS2(const VectorRn& dVec);
void CalcDeltaThetasDLS2(const VectorRn& dVec);
void CalcDeltaThetasDLSwithSVD();
void CalcDeltaThetasSDLS();
void CalcDeltaThetasDLSwithNullspace( const VectorRn& desiredV);
void CalcDeltaThetasDLSwithNullspace(const VectorRn& desiredV);
void UpdateThetas();
void UpdateThetaDot();
double UpdateErrorArray(VectorR3* targets); // Returns sum of errors
void UpdateThetaDot();
double UpdateErrorArray(VectorR3* targets); // Returns sum of errors
const VectorRn& GetErrorArray() const { return errorArray; }
void UpdatedSClampValue(VectorR3* targets);
void SetCurrentMode( UpdateMode mode ) { CurrentUpdateMode = mode; }
void SetCurrentMode(UpdateMode mode) { CurrentUpdateMode = mode; }
UpdateMode GetCurrentMode() const { return CurrentUpdateMode; }
void SetDampingDLS( double lambda ) { DampingLambda = lambda; DampingLambdaSq = Square(lambda); }
void SetDampingDLS(double lambda)
{
DampingLambda = lambda;
DampingLambdaSq = Square(lambda);
}
void Reset();
static void CompareErrors( const Jacobian& j1, const Jacobian& j2, double* weightedDist1, double* weightedDist2 );
static void CountErrors( const Jacobian& j1, const Jacobian& j2, int* numBetter1, int* numBetter2, int* numTies );
static void CompareErrors(const Jacobian& j1, const Jacobian& j2, double* weightedDist1, double* weightedDist2);
static void CountErrors(const Jacobian& j1, const Jacobian& j2, int* numBetter1, int* numBetter2, int* numTies);
int GetNumRows() { return nRow; }
int GetNumCols() { return nCol; }
int GetNumRows() {return nRow;}
int GetNumCols() {return nCol;}
public:
Tree* m_tree; // tree associated with this Jacobian matrix
int m_nEffector; // Number of end effectors
int nJoint; // Number of joints
int nRow; // Total number of rows the real J (= 3*number of end effectors for now)
int nCol; // Total number of columns in the real J (= number of joints for now)
Tree* m_tree; // tree associated with this Jacobian matrix
int m_nEffector; // Number of end effectors
int nJoint; // Number of joints
int nRow; // Total number of rows the real J (= 3*number of end effectors for now)
int nCol; // Total number of columns in the real J (= number of joints for now)
MatrixRmn Jend; // Jacobian matrix based on end effector positions
MatrixRmn Jtarget; // Jacobian matrix based on target positions
MatrixRmn Jnorms; // Norms of 3-vectors in active Jacobian (SDLS only)
MatrixRmn Jend; // Jacobian matrix based on end effector positions
MatrixRmn Jtarget; // Jacobian matrix based on target positions
MatrixRmn Jnorms; // Norms of 3-vectors in active Jacobian (SDLS only)
MatrixRmn U; // J = U * Diag(w) * V^T (Singular Value Decomposition)
VectorRn w;
MatrixRmn U; // J = U * Diag(w) * V^T (Singular Value Decomposition)
VectorRn w;
MatrixRmn V;
UpdateMode CurrentUpdateMode;
VectorRn dS; // delta s
VectorRn dT1; // delta t -- these are delta S values clamped to smaller magnitude
VectorRn dSclamp; // Value to clamp magnitude of dT at.
VectorRn dTheta; // delta theta
VectorRn dPreTheta; // delta theta for single eigenvalue (SDLS only)
VectorRn dS; // delta s
VectorRn dT1; // delta t -- these are delta S values clamped to smaller magnitude
VectorRn dSclamp; // Value to clamp magnitude of dT at.
VectorRn dTheta; // delta theta
VectorRn dPreTheta; // delta theta for single eigenvalue (SDLS only)
VectorRn errorArray; // Distance of end effectors from target after updating
VectorRn errorArray; // Distance of end effectors from target after updating
// Parameters for pseudoinverses
static const double PseudoInverseThresholdFactor; // Threshold for treating eigenvalue as zero (fraction of largest eigenvalue)
static const double PseudoInverseThresholdFactor; // Threshold for treating eigenvalue as zero (fraction of largest eigenvalue)
// Parameters for damped least squares
static const double DefaultDampingLambda;
double DampingLambda;
double DampingLambdaSq;
//double DampingLambdaSDLS;
// Cap on max. value of changes in angles in single update step
static const double MaxAngleJtranspose;
static const double MaxAnglePseudoinverse;
static const double MaxAngleDLS;
static const double MaxAngleSDLS;
static const double MaxAngleDLS;
static const double MaxAngleSDLS;
MatrixRmn* Jactive;
void CalcdTClampedFromdS();
static const double BaseMaxTargetDist;
};
#endif

View File

@@ -1,4 +1,4 @@
/*
/*
*
* Mathematics Subpackage (VrMath)
*
@@ -22,7 +22,6 @@
#include "LinearR2.h"
#include <assert.h>
// ******************************************************
@@ -30,10 +29,10 @@
// * * * * * * * * * * * * * * * * * * * * * * * * * * **
const VectorR2 VectorR2::Zero(0.0, 0.0);
const VectorR2 VectorR2::UnitX( 1.0, 0.0);
const VectorR2 VectorR2::UnitY( 0.0, 1.0);
const VectorR2 VectorR2::UnitX(1.0, 0.0);
const VectorR2 VectorR2::UnitY(0.0, 1.0);
const VectorR2 VectorR2::NegUnitX(-1.0, 0.0);
const VectorR2 VectorR2::NegUnitY( 0.0,-1.0);
const VectorR2 VectorR2::NegUnitY(0.0, -1.0);
const Matrix2x2 Matrix2x2::Identity(1.0, 0.0, 0.0, 1.0);
@@ -41,61 +40,50 @@ const Matrix2x2 Matrix2x2::Identity(1.0, 0.0, 0.0, 1.0);
// * Matrix2x2 class - math library functions *
// * * * * * * * * * * * * * * * * * * * * * * * * * * **
// ******************************************************
// * LinearMapR2 class - math library functions *
// * * * * * * * * * * * * * * * * * * * * * * * * * * **
LinearMapR2 LinearMapR2::Inverse() const // Returns inverse
LinearMapR2 LinearMapR2::Inverse() const // Returns inverse
{
double detInv = 1.0 / (m11 * m22 - m12 * m21);
double detInv = 1.0/(m11*m22 - m12*m21) ;
return( LinearMapR2( m22*detInv, -m21*detInv, -m12*detInv, m11*detInv ) );
return (LinearMapR2(m22 * detInv, -m21 * detInv, -m12 * detInv, m11 * detInv));
}
LinearMapR2& LinearMapR2::Invert() // Converts into inverse.
LinearMapR2& LinearMapR2::Invert() // Converts into inverse.
{
double detInv = 1.0/(m11*m22 - m12*m21) ;
double detInv = 1.0 / (m11 * m22 - m12 * m21);
double temp;
temp = m11*detInv;
m11= m22*detInv;
m22=temp;
m12 = -m12*detInv;
m21 = -m22*detInv;
temp = m11 * detInv;
m11 = m22 * detInv;
m22 = temp;
m12 = -m12 * detInv;
m21 = -m22 * detInv;
return ( *this );
return (*this);
}
VectorR2 LinearMapR2::Solve(const VectorR2& u) const // Returns solution
{
VectorR2 LinearMapR2::Solve(const VectorR2& u) const // Returns solution
{
// Just uses Inverse() for now.
return ( Inverse()*u );
return (Inverse() * u);
}
// ******************************************************
// * RotationMapR2 class - math library functions *
// * * * * * * * * * * * * * * * * * * * * * * * * * * **
// ***************************************************************
// * 2-space vector and matrix utilities *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// ***************************************************************
// Stream Output Routines *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ostream& operator<< ( ostream& os, const VectorR2& u )
ostream& operator<<(ostream& os, const VectorR2& u)
{
return (os << "<" << u.x << "," << u.y << ">");
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -20,39 +20,43 @@ subject to the following restrictions:
*
*/
#include "LinearR4.h"
#include <assert.h>
const VectorR4 VectorR4::Zero(0.0, 0.0, 0.0, 0.0);
const VectorR4 VectorR4::UnitX( 1.0, 0.0, 0.0, 0.0);
const VectorR4 VectorR4::UnitY( 0.0, 1.0, 0.0, 0.0);
const VectorR4 VectorR4::UnitZ( 0.0, 0.0, 1.0, 0.0);
const VectorR4 VectorR4::UnitW( 0.0, 0.0, 0.0, 1.0);
const VectorR4 VectorR4::UnitX(1.0, 0.0, 0.0, 0.0);
const VectorR4 VectorR4::UnitY(0.0, 1.0, 0.0, 0.0);
const VectorR4 VectorR4::UnitZ(0.0, 0.0, 1.0, 0.0);
const VectorR4 VectorR4::UnitW(0.0, 0.0, 0.0, 1.0);
const VectorR4 VectorR4::NegUnitX(-1.0, 0.0, 0.0, 0.0);
const VectorR4 VectorR4::NegUnitY( 0.0,-1.0, 0.0, 0.0);
const VectorR4 VectorR4::NegUnitZ( 0.0, 0.0,-1.0, 0.0);
const VectorR4 VectorR4::NegUnitW( 0.0, 0.0, 0.0,-1.0);
const VectorR4 VectorR4::NegUnitY(0.0, -1.0, 0.0, 0.0);
const VectorR4 VectorR4::NegUnitZ(0.0, 0.0, -1.0, 0.0);
const VectorR4 VectorR4::NegUnitW(0.0, 0.0, 0.0, -1.0);
const Matrix4x4 Matrix4x4::Identity(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
// ******************************************************
// * VectorR4 class - math library functions *
// * * * * * * * * * * * * * * * * * * * * * * * * * * **
double VectorR4::MaxAbs() const
{
double m;
m = (x>0.0) ? x : -x;
if ( y>m ) m=y;
else if ( -y >m ) m = -y;
if ( z>m ) m=z;
else if ( -z>m ) m = -z;
if ( w>m ) m=w;
else if ( -w>m ) m = -w;
double m;
m = (x > 0.0) ? x : -x;
if (y > m)
m = y;
else if (-y > m)
m = -y;
if (z > m)
m = z;
else if (-z > m)
m = -z;
if (w > m)
m = w;
else if (-w > m)
m = -w;
return m;
}
@@ -60,90 +64,90 @@ double VectorR4::MaxAbs() const
// * Matrix4x4 class - math library functions *
// * * * * * * * * * * * * * * * * * * * * * * * * * * **
void Matrix4x4::operator*= (const Matrix4x4& B) // Matrix product
void Matrix4x4::operator*=(const Matrix4x4& B) // Matrix product
{
double t1, t2, t3; // temporary values
t1 = m11*B.m11 + m12*B.m21 + m13*B.m31 + m14*B.m41;
t2 = m11*B.m12 + m12*B.m22 + m13*B.m32 + m14*B.m42;
t3 = m11*B.m13 + m12*B.m23 + m13*B.m33 + m14*B.m43;
m14 = m11*B.m14 + m12*B.m24 + m13*B.m34 + m14*B.m44;
double t1, t2, t3; // temporary values
t1 = m11 * B.m11 + m12 * B.m21 + m13 * B.m31 + m14 * B.m41;
t2 = m11 * B.m12 + m12 * B.m22 + m13 * B.m32 + m14 * B.m42;
t3 = m11 * B.m13 + m12 * B.m23 + m13 * B.m33 + m14 * B.m43;
m14 = m11 * B.m14 + m12 * B.m24 + m13 * B.m34 + m14 * B.m44;
m11 = t1;
m12 = t2;
m13 = t3;
t1 = m21*B.m11 + m22*B.m21 + m23*B.m31 + m24*B.m41;
t2 = m21*B.m12 + m22*B.m22 + m23*B.m32 + m24*B.m42;
t3 = m21*B.m13 + m22*B.m23 + m23*B.m33 + m24*B.m43;
m24 = m21*B.m14 + m22*B.m24 + m23*B.m34 + m24*B.m44;
t1 = m21 * B.m11 + m22 * B.m21 + m23 * B.m31 + m24 * B.m41;
t2 = m21 * B.m12 + m22 * B.m22 + m23 * B.m32 + m24 * B.m42;
t3 = m21 * B.m13 + m22 * B.m23 + m23 * B.m33 + m24 * B.m43;
m24 = m21 * B.m14 + m22 * B.m24 + m23 * B.m34 + m24 * B.m44;
m21 = t1;
m22 = t2;
m23 = t3;
t1 = m31*B.m11 + m32*B.m21 + m33*B.m31 + m34*B.m41;
t2 = m31*B.m12 + m32*B.m22 + m33*B.m32 + m34*B.m42;
t3 = m31*B.m13 + m32*B.m23 + m33*B.m33 + m34*B.m43;
m34 = m31*B.m14 + m32*B.m24 + m33*B.m34 + m34*B.m44;
t1 = m31 * B.m11 + m32 * B.m21 + m33 * B.m31 + m34 * B.m41;
t2 = m31 * B.m12 + m32 * B.m22 + m33 * B.m32 + m34 * B.m42;
t3 = m31 * B.m13 + m32 * B.m23 + m33 * B.m33 + m34 * B.m43;
m34 = m31 * B.m14 + m32 * B.m24 + m33 * B.m34 + m34 * B.m44;
m31 = t1;
m32 = t2;
m33 = t3;
t1 = m41*B.m11 + m42*B.m21 + m43*B.m31 + m44*B.m41;
t2 = m41*B.m12 + m42*B.m22 + m43*B.m32 + m44*B.m42;
t3 = m41*B.m13 + m42*B.m23 + m43*B.m33 + m44*B.m43;
m44 = m41*B.m14 + m42*B.m24 + m43*B.m34 + m44*B.m44;
t1 = m41 * B.m11 + m42 * B.m21 + m43 * B.m31 + m44 * B.m41;
t2 = m41 * B.m12 + m42 * B.m22 + m43 * B.m32 + m44 * B.m42;
t3 = m41 * B.m13 + m42 * B.m23 + m43 * B.m33 + m44 * B.m43;
m44 = m41 * B.m14 + m42 * B.m24 + m43 * B.m34 + m44 * B.m44;
m41 = t1;
m42 = t2;
m43 = t3;
}
inline void ReNormalizeHelper ( double &a, double &b, double &c, double &d )
inline void ReNormalizeHelper(double& a, double& b, double& c, double& d)
{
double scaleF = a*a+b*b+c*c+d*d; // Inner product of Vector-R4
scaleF = 1.0-0.5*(scaleF-1.0);
double scaleF = a * a + b * b + c * c + d * d; // Inner product of Vector-R4
scaleF = 1.0 - 0.5 * (scaleF - 1.0);
a *= scaleF;
b *= scaleF;
c *= scaleF;
d *= scaleF;
}
Matrix4x4& Matrix4x4::ReNormalize() {
ReNormalizeHelper( m11, m21, m31, m41 ); // Renormalize first column
ReNormalizeHelper( m12, m22, m32, m42 ); // Renormalize second column
ReNormalizeHelper( m13, m23, m33, m43 ); // Renormalize third column
ReNormalizeHelper( m14, m24, m34, m44 ); // Renormalize fourth column
double alpha = 0.5*(m11*m12 + m21*m22 + m31*m32 + m41*m42); //1st and 2nd cols
double beta = 0.5*(m11*m13 + m21*m23 + m31*m33 + m41*m43); //1st and 3rd cols
double gamma = 0.5*(m11*m14 + m21*m24 + m31*m34 + m41*m44); //1st and 4nd cols
double delta = 0.5*(m12*m13 + m22*m23 + m32*m33 + m42*m43); //2nd and 3rd cols
double eps = 0.5*(m12*m14 + m22*m24 + m32*m34 + m42*m44); //2nd and 4nd cols
double phi = 0.5*(m13*m14 + m23*m24 + m33*m34 + m43*m44); //3rd and 4nd cols
Matrix4x4& Matrix4x4::ReNormalize()
{
ReNormalizeHelper(m11, m21, m31, m41); // Renormalize first column
ReNormalizeHelper(m12, m22, m32, m42); // Renormalize second column
ReNormalizeHelper(m13, m23, m33, m43); // Renormalize third column
ReNormalizeHelper(m14, m24, m34, m44); // Renormalize fourth column
double alpha = 0.5 * (m11 * m12 + m21 * m22 + m31 * m32 + m41 * m42); //1st and 2nd cols
double beta = 0.5 * (m11 * m13 + m21 * m23 + m31 * m33 + m41 * m43); //1st and 3rd cols
double gamma = 0.5 * (m11 * m14 + m21 * m24 + m31 * m34 + m41 * m44); //1st and 4nd cols
double delta = 0.5 * (m12 * m13 + m22 * m23 + m32 * m33 + m42 * m43); //2nd and 3rd cols
double eps = 0.5 * (m12 * m14 + m22 * m24 + m32 * m34 + m42 * m44); //2nd and 4nd cols
double phi = 0.5 * (m13 * m14 + m23 * m24 + m33 * m34 + m43 * m44); //3rd and 4nd cols
double temp1, temp2, temp3;
temp1 = m11 - alpha*m12 - beta*m13 - gamma*m14;
temp2 = m12 - alpha*m11 - delta*m13 - eps*m14;
temp3 = m13 - beta*m11 - delta*m12 - phi*m14;
m14 -= (gamma*m11 + eps*m12 + phi*m13);
temp1 = m11 - alpha * m12 - beta * m13 - gamma * m14;
temp2 = m12 - alpha * m11 - delta * m13 - eps * m14;
temp3 = m13 - beta * m11 - delta * m12 - phi * m14;
m14 -= (gamma * m11 + eps * m12 + phi * m13);
m11 = temp1;
m12 = temp2;
m13 = temp3;
temp1 = m21 - alpha*m22 - beta*m23 - gamma*m24;
temp2 = m22 - alpha*m21 - delta*m23 - eps*m24;
temp3 = m23 - beta*m21 - delta*m22 - phi*m24;
m24 -= (gamma*m21 + eps*m22 + phi*m23);
temp1 = m21 - alpha * m22 - beta * m23 - gamma * m24;
temp2 = m22 - alpha * m21 - delta * m23 - eps * m24;
temp3 = m23 - beta * m21 - delta * m22 - phi * m24;
m24 -= (gamma * m21 + eps * m22 + phi * m23);
m21 = temp1;
m22 = temp2;
m23 = temp3;
temp1 = m31 - alpha*m32 - beta*m33 - gamma*m34;
temp2 = m32 - alpha*m31 - delta*m33 - eps*m34;
temp3 = m33 - beta*m31 - delta*m32 - phi*m34;
m34 -= (gamma*m31 + eps*m32 + phi*m33);
temp1 = m31 - alpha * m32 - beta * m33 - gamma * m34;
temp2 = m32 - alpha * m31 - delta * m33 - eps * m34;
temp3 = m33 - beta * m31 - delta * m32 - phi * m34;
m34 -= (gamma * m31 + eps * m32 + phi * m33);
m31 = temp1;
m32 = temp2;
m33 = temp3;
temp1 = m41 - alpha*m42 - beta*m43 - gamma*m44;
temp2 = m42 - alpha*m41 - delta*m43 - eps*m44;
temp3 = m43 - beta*m41 - delta*m42 - phi*m44;
m44 -= (gamma*m41 + eps*m42 + phi*m43);
temp1 = m41 - alpha * m42 - beta * m43 - gamma * m44;
temp2 = m42 - alpha * m41 - delta * m43 - eps * m44;
temp3 = m43 - beta * m41 - delta * m42 - phi * m44;
m44 -= (gamma * m41 + eps * m42 + phi * m43);
m41 = temp1;
m42 = temp2;
m43 = temp3;
@@ -154,223 +158,221 @@ Matrix4x4& Matrix4x4::ReNormalize() {
// * LinearMapR4 class - math library functions *
// * * * * * * * * * * * * * * * * * * * * * * * * * * **
double LinearMapR4::Determinant () const // Returns the determinant
double LinearMapR4::Determinant() const // Returns the determinant
{
double Tbt34C12 = m31*m42-m32*m41; // 2x2 subdeterminants
double Tbt34C13 = m31*m43-m33*m41;
double Tbt34C14 = m31*m44-m34*m41;
double Tbt34C23 = m32*m43-m33*m42;
double Tbt34C24 = m32*m44-m34*m42;
double Tbt34C34 = m33*m44-m34*m43;
double Tbt34C12 = m31 * m42 - m32 * m41; // 2x2 subdeterminants
double Tbt34C13 = m31 * m43 - m33 * m41;
double Tbt34C14 = m31 * m44 - m34 * m41;
double Tbt34C23 = m32 * m43 - m33 * m42;
double Tbt34C24 = m32 * m44 - m34 * m42;
double Tbt34C34 = m33 * m44 - m34 * m43;
double sd11 = m22*Tbt34C34 - m23*Tbt34C24 + m24*Tbt34C23; // 3x3 subdeterminants
double sd12 = m21*Tbt34C34 - m23*Tbt34C14 + m24*Tbt34C13;
double sd13 = m21*Tbt34C24 - m22*Tbt34C14 + m24*Tbt34C12;
double sd14 = m21*Tbt34C23 - m22*Tbt34C13 + m23*Tbt34C12;
double sd11 = m22 * Tbt34C34 - m23 * Tbt34C24 + m24 * Tbt34C23; // 3x3 subdeterminants
double sd12 = m21 * Tbt34C34 - m23 * Tbt34C14 + m24 * Tbt34C13;
double sd13 = m21 * Tbt34C24 - m22 * Tbt34C14 + m24 * Tbt34C12;
double sd14 = m21 * Tbt34C23 - m22 * Tbt34C13 + m23 * Tbt34C12;
return ( m11*sd11 - m12*sd12 + m13*sd13 - m14*sd14 );
return (m11 * sd11 - m12 * sd12 + m13 * sd13 - m14 * sd14);
}
LinearMapR4 LinearMapR4::Inverse() const // Returns inverse
LinearMapR4 LinearMapR4::Inverse() const // Returns inverse
{
double Tbt34C12 = m31 * m42 - m32 * m41; // 2x2 subdeterminants
double Tbt34C13 = m31 * m43 - m33 * m41;
double Tbt34C14 = m31 * m44 - m34 * m41;
double Tbt34C23 = m32 * m43 - m33 * m42;
double Tbt34C24 = m32 * m44 - m34 * m42;
double Tbt34C34 = m33 * m44 - m34 * m43;
double Tbt24C12 = m21 * m42 - m22 * m41; // 2x2 subdeterminants
double Tbt24C13 = m21 * m43 - m23 * m41;
double Tbt24C14 = m21 * m44 - m24 * m41;
double Tbt24C23 = m22 * m43 - m23 * m42;
double Tbt24C24 = m22 * m44 - m24 * m42;
double Tbt24C34 = m23 * m44 - m24 * m43;
double Tbt23C12 = m21 * m32 - m22 * m31; // 2x2 subdeterminants
double Tbt23C13 = m21 * m33 - m23 * m31;
double Tbt23C14 = m21 * m34 - m24 * m31;
double Tbt23C23 = m22 * m33 - m23 * m32;
double Tbt23C24 = m22 * m34 - m24 * m32;
double Tbt23C34 = m23 * m34 - m24 * m33;
double Tbt34C12 = m31*m42-m32*m41; // 2x2 subdeterminants
double Tbt34C13 = m31*m43-m33*m41;
double Tbt34C14 = m31*m44-m34*m41;
double Tbt34C23 = m32*m43-m33*m42;
double Tbt34C24 = m32*m44-m34*m42;
double Tbt34C34 = m33*m44-m34*m43;
double Tbt24C12 = m21*m42-m22*m41; // 2x2 subdeterminants
double Tbt24C13 = m21*m43-m23*m41;
double Tbt24C14 = m21*m44-m24*m41;
double Tbt24C23 = m22*m43-m23*m42;
double Tbt24C24 = m22*m44-m24*m42;
double Tbt24C34 = m23*m44-m24*m43;
double Tbt23C12 = m21*m32-m22*m31; // 2x2 subdeterminants
double Tbt23C13 = m21*m33-m23*m31;
double Tbt23C14 = m21*m34-m24*m31;
double Tbt23C23 = m22*m33-m23*m32;
double Tbt23C24 = m22*m34-m24*m32;
double Tbt23C34 = m23*m34-m24*m33;
double sd11 = m22 * Tbt34C34 - m23 * Tbt34C24 + m24 * Tbt34C23; // 3x3 subdeterminants
double sd12 = m21 * Tbt34C34 - m23 * Tbt34C14 + m24 * Tbt34C13;
double sd13 = m21 * Tbt34C24 - m22 * Tbt34C14 + m24 * Tbt34C12;
double sd14 = m21 * Tbt34C23 - m22 * Tbt34C13 + m23 * Tbt34C12;
double sd21 = m12 * Tbt34C34 - m13 * Tbt34C24 + m14 * Tbt34C23; // 3x3 subdeterminants
double sd22 = m11 * Tbt34C34 - m13 * Tbt34C14 + m14 * Tbt34C13;
double sd23 = m11 * Tbt34C24 - m12 * Tbt34C14 + m14 * Tbt34C12;
double sd24 = m11 * Tbt34C23 - m12 * Tbt34C13 + m13 * Tbt34C12;
double sd31 = m12 * Tbt24C34 - m13 * Tbt24C24 + m14 * Tbt24C23; // 3x3 subdeterminants
double sd32 = m11 * Tbt24C34 - m13 * Tbt24C14 + m14 * Tbt24C13;
double sd33 = m11 * Tbt24C24 - m12 * Tbt24C14 + m14 * Tbt24C12;
double sd34 = m11 * Tbt24C23 - m12 * Tbt24C13 + m13 * Tbt24C12;
double sd41 = m12 * Tbt23C34 - m13 * Tbt23C24 + m14 * Tbt23C23; // 3x3 subdeterminants
double sd42 = m11 * Tbt23C34 - m13 * Tbt23C14 + m14 * Tbt23C13;
double sd43 = m11 * Tbt23C24 - m12 * Tbt23C14 + m14 * Tbt23C12;
double sd44 = m11 * Tbt23C23 - m12 * Tbt23C13 + m13 * Tbt23C12;
double sd11 = m22*Tbt34C34 - m23*Tbt34C24 + m24*Tbt34C23; // 3x3 subdeterminants
double sd12 = m21*Tbt34C34 - m23*Tbt34C14 + m24*Tbt34C13;
double sd13 = m21*Tbt34C24 - m22*Tbt34C14 + m24*Tbt34C12;
double sd14 = m21*Tbt34C23 - m22*Tbt34C13 + m23*Tbt34C12;
double sd21 = m12*Tbt34C34 - m13*Tbt34C24 + m14*Tbt34C23; // 3x3 subdeterminants
double sd22 = m11*Tbt34C34 - m13*Tbt34C14 + m14*Tbt34C13;
double sd23 = m11*Tbt34C24 - m12*Tbt34C14 + m14*Tbt34C12;
double sd24 = m11*Tbt34C23 - m12*Tbt34C13 + m13*Tbt34C12;
double sd31 = m12*Tbt24C34 - m13*Tbt24C24 + m14*Tbt24C23; // 3x3 subdeterminants
double sd32 = m11*Tbt24C34 - m13*Tbt24C14 + m14*Tbt24C13;
double sd33 = m11*Tbt24C24 - m12*Tbt24C14 + m14*Tbt24C12;
double sd34 = m11*Tbt24C23 - m12*Tbt24C13 + m13*Tbt24C12;
double sd41 = m12*Tbt23C34 - m13*Tbt23C24 + m14*Tbt23C23; // 3x3 subdeterminants
double sd42 = m11*Tbt23C34 - m13*Tbt23C14 + m14*Tbt23C13;
double sd43 = m11*Tbt23C24 - m12*Tbt23C14 + m14*Tbt23C12;
double sd44 = m11*Tbt23C23 - m12*Tbt23C13 + m13*Tbt23C12;
double detInv = 1.0 / (m11 * sd11 - m12 * sd12 + m13 * sd13 - m14 * sd14);
double detInv = 1.0/(m11*sd11 - m12*sd12 + m13*sd13 - m14*sd14);
return( LinearMapR4( sd11*detInv, -sd12*detInv, sd13*detInv, -sd14*detInv,
-sd21*detInv, sd22*detInv, -sd23*detInv, sd24*detInv,
sd31*detInv, -sd32*detInv, sd33*detInv, -sd34*detInv,
-sd41*detInv, sd42*detInv, -sd43*detInv, sd44*detInv ) );
return (LinearMapR4(sd11 * detInv, -sd12 * detInv, sd13 * detInv, -sd14 * detInv,
-sd21 * detInv, sd22 * detInv, -sd23 * detInv, sd24 * detInv,
sd31 * detInv, -sd32 * detInv, sd33 * detInv, -sd34 * detInv,
-sd41 * detInv, sd42 * detInv, -sd43 * detInv, sd44 * detInv));
}
LinearMapR4& LinearMapR4::Invert() // Converts into inverse.
LinearMapR4& LinearMapR4::Invert() // Converts into inverse.
{
double Tbt34C12 = m31*m42-m32*m41; // 2x2 subdeterminants
double Tbt34C13 = m31*m43-m33*m41;
double Tbt34C14 = m31*m44-m34*m41;
double Tbt34C23 = m32*m43-m33*m42;
double Tbt34C24 = m32*m44-m34*m42;
double Tbt34C34 = m33*m44-m34*m43;
double Tbt24C12 = m21*m42-m22*m41; // 2x2 subdeterminants
double Tbt24C13 = m21*m43-m23*m41;
double Tbt24C14 = m21*m44-m24*m41;
double Tbt24C23 = m22*m43-m23*m42;
double Tbt24C24 = m22*m44-m24*m42;
double Tbt24C34 = m23*m44-m24*m43;
double Tbt23C12 = m21*m32-m22*m31; // 2x2 subdeterminants
double Tbt23C13 = m21*m33-m23*m31;
double Tbt23C14 = m21*m34-m24*m31;
double Tbt23C23 = m22*m33-m23*m32;
double Tbt23C24 = m22*m34-m24*m32;
double Tbt23C34 = m23*m34-m24*m33;
double Tbt34C12 = m31 * m42 - m32 * m41; // 2x2 subdeterminants
double Tbt34C13 = m31 * m43 - m33 * m41;
double Tbt34C14 = m31 * m44 - m34 * m41;
double Tbt34C23 = m32 * m43 - m33 * m42;
double Tbt34C24 = m32 * m44 - m34 * m42;
double Tbt34C34 = m33 * m44 - m34 * m43;
double Tbt24C12 = m21 * m42 - m22 * m41; // 2x2 subdeterminants
double Tbt24C13 = m21 * m43 - m23 * m41;
double Tbt24C14 = m21 * m44 - m24 * m41;
double Tbt24C23 = m22 * m43 - m23 * m42;
double Tbt24C24 = m22 * m44 - m24 * m42;
double Tbt24C34 = m23 * m44 - m24 * m43;
double Tbt23C12 = m21 * m32 - m22 * m31; // 2x2 subdeterminants
double Tbt23C13 = m21 * m33 - m23 * m31;
double Tbt23C14 = m21 * m34 - m24 * m31;
double Tbt23C23 = m22 * m33 - m23 * m32;
double Tbt23C24 = m22 * m34 - m24 * m32;
double Tbt23C34 = m23 * m34 - m24 * m33;
double sd11 = m22*Tbt34C34 - m23*Tbt34C24 + m24*Tbt34C23; // 3x3 subdeterminants
double sd12 = m21*Tbt34C34 - m23*Tbt34C14 + m24*Tbt34C13;
double sd13 = m21*Tbt34C24 - m22*Tbt34C14 + m24*Tbt34C12;
double sd14 = m21*Tbt34C23 - m22*Tbt34C13 + m23*Tbt34C12;
double sd21 = m12*Tbt34C34 - m13*Tbt34C24 + m14*Tbt34C23; // 3x3 subdeterminants
double sd22 = m11*Tbt34C34 - m13*Tbt34C14 + m14*Tbt34C13;
double sd23 = m11*Tbt34C24 - m12*Tbt34C14 + m14*Tbt34C12;
double sd24 = m11*Tbt34C23 - m12*Tbt34C13 + m13*Tbt34C12;
double sd31 = m12*Tbt24C34 - m13*Tbt24C24 + m14*Tbt24C23; // 3x3 subdeterminants
double sd32 = m11*Tbt24C34 - m13*Tbt24C14 + m14*Tbt24C13;
double sd33 = m11*Tbt24C24 - m12*Tbt24C14 + m14*Tbt24C12;
double sd34 = m11*Tbt24C23 - m12*Tbt24C13 + m13*Tbt24C12;
double sd41 = m12*Tbt23C34 - m13*Tbt23C24 + m14*Tbt23C23; // 3x3 subdeterminants
double sd42 = m11*Tbt23C34 - m13*Tbt23C14 + m14*Tbt23C13;
double sd43 = m11*Tbt23C24 - m12*Tbt23C14 + m14*Tbt23C12;
double sd44 = m11*Tbt23C23 - m12*Tbt23C13 + m13*Tbt23C12;
double sd11 = m22 * Tbt34C34 - m23 * Tbt34C24 + m24 * Tbt34C23; // 3x3 subdeterminants
double sd12 = m21 * Tbt34C34 - m23 * Tbt34C14 + m24 * Tbt34C13;
double sd13 = m21 * Tbt34C24 - m22 * Tbt34C14 + m24 * Tbt34C12;
double sd14 = m21 * Tbt34C23 - m22 * Tbt34C13 + m23 * Tbt34C12;
double sd21 = m12 * Tbt34C34 - m13 * Tbt34C24 + m14 * Tbt34C23; // 3x3 subdeterminants
double sd22 = m11 * Tbt34C34 - m13 * Tbt34C14 + m14 * Tbt34C13;
double sd23 = m11 * Tbt34C24 - m12 * Tbt34C14 + m14 * Tbt34C12;
double sd24 = m11 * Tbt34C23 - m12 * Tbt34C13 + m13 * Tbt34C12;
double sd31 = m12 * Tbt24C34 - m13 * Tbt24C24 + m14 * Tbt24C23; // 3x3 subdeterminants
double sd32 = m11 * Tbt24C34 - m13 * Tbt24C14 + m14 * Tbt24C13;
double sd33 = m11 * Tbt24C24 - m12 * Tbt24C14 + m14 * Tbt24C12;
double sd34 = m11 * Tbt24C23 - m12 * Tbt24C13 + m13 * Tbt24C12;
double sd41 = m12 * Tbt23C34 - m13 * Tbt23C24 + m14 * Tbt23C23; // 3x3 subdeterminants
double sd42 = m11 * Tbt23C34 - m13 * Tbt23C14 + m14 * Tbt23C13;
double sd43 = m11 * Tbt23C24 - m12 * Tbt23C14 + m14 * Tbt23C12;
double sd44 = m11 * Tbt23C23 - m12 * Tbt23C13 + m13 * Tbt23C12;
double detInv = 1.0/(m11*sd11 - m12*sd12 + m13*sd13 - m14*sd14);
double detInv = 1.0 / (m11 * sd11 - m12 * sd12 + m13 * sd13 - m14 * sd14);
m11 = sd11*detInv;
m12 = -sd21*detInv;
m13 = sd31*detInv;
m14 = -sd41*detInv;
m21 = -sd12*detInv;
m22 = sd22*detInv;
m23 = -sd32*detInv;
m24 = sd42*detInv;
m31 = sd13*detInv;
m32 = -sd23*detInv;
m33 = sd33*detInv;
m34 = -sd43*detInv;
m41 = -sd14*detInv;
m42 = sd24*detInv;
m43 = -sd34*detInv;
m44 = sd44*detInv;
m11 = sd11 * detInv;
m12 = -sd21 * detInv;
m13 = sd31 * detInv;
m14 = -sd41 * detInv;
m21 = -sd12 * detInv;
m22 = sd22 * detInv;
m23 = -sd32 * detInv;
m24 = sd42 * detInv;
m31 = sd13 * detInv;
m32 = -sd23 * detInv;
m33 = sd33 * detInv;
m34 = -sd43 * detInv;
m41 = -sd14 * detInv;
m42 = sd24 * detInv;
m43 = -sd34 * detInv;
m44 = sd44 * detInv;
return ( *this );
return (*this);
}
VectorR4 LinearMapR4::Solve(const VectorR4& u) const // Returns solution
{
VectorR4 LinearMapR4::Solve(const VectorR4& u) const // Returns solution
{
// Just uses Inverse() for now.
return ( Inverse()*u );
return (Inverse() * u);
}
// ******************************************************
// * RotationMapR4 class - math library functions *
// * * * * * * * * * * * * * * * * * * * * * * * * * * **
// ***************************************************************
// * 4-space vector and matrix utilities *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Returns u * v^T
LinearMapR4 TimesTranspose( const VectorR4& u, const VectorR4& v)
LinearMapR4 TimesTranspose(const VectorR4& u, const VectorR4& v)
{
LinearMapR4 result;
TimesTranspose( u, v, result );
TimesTranspose(u, v, result);
return result;
}
// The following routines are use to obtain
// The following routines are use to obtain
// a righthanded orthonormal basis to complement vectors u,v,w.
// The vectors u,v,w must be unit and orthonormal.
// The value is returned in "rotmat" with the first column(s) of
// rotmat equal to u,v,w as appropriate.
void GetOrtho( const VectorR4& u, RotationMapR4& rotmat )
void GetOrtho(const VectorR4& u, RotationMapR4& rotmat)
{
rotmat.SetColumn1(u);
GetOrtho( 1, rotmat );
GetOrtho(1, rotmat);
}
void GetOrtho( const VectorR4& u, const VectorR4& v, RotationMapR4& rotmat )
void GetOrtho(const VectorR4& u, const VectorR4& v, RotationMapR4& rotmat)
{
rotmat.SetColumn1(u);
rotmat.SetColumn2(v);
GetOrtho( 2, rotmat );
GetOrtho(2, rotmat);
}
void GetOrtho( const VectorR4& u, const VectorR4& v, const VectorR4& s,
RotationMapR4& rotmat )
void GetOrtho(const VectorR4& u, const VectorR4& v, const VectorR4& s,
RotationMapR4& rotmat)
{
rotmat.SetColumn1(u);
rotmat.SetColumn2(v);
rotmat.SetColumn3(s);
GetOrtho( 3, rotmat );
GetOrtho(3, rotmat);
}
// This final version of GetOrtho is mainly for internal use.
// It uses a Gram-Schmidt procedure to extend a partial orthonormal
// basis to a complete orthonormal basis.
// j = number of columns of rotmat that have already been set.
void GetOrtho( int j, RotationMapR4& rotmat)
void GetOrtho(int j, RotationMapR4& rotmat)
{
if ( j==0 ) {
if (j == 0)
{
rotmat.SetIdentity();
return;
}
if ( j==1 ) {
rotmat.SetColumn2( -rotmat.m21, rotmat.m11, -rotmat.m41, rotmat.m31 );
if (j == 1)
{
rotmat.SetColumn2(-rotmat.m21, rotmat.m11, -rotmat.m41, rotmat.m31);
j = 2;
}
assert ( rotmat.Column1().Norm()<1.0001 && 0.9999<rotmat.Column1().Norm()
&& rotmat.Column1().Norm()<1.0001 && 0.9999<rotmat.Column1().Norm()
&& (rotmat.Column1()^rotmat.Column2()) < 0.001
&& (rotmat.Column1()^rotmat.Column2()) > -0.001 );
assert(rotmat.Column1().Norm() < 1.0001 && 0.9999 < rotmat.Column1().Norm() && rotmat.Column1().Norm() < 1.0001 && 0.9999 < rotmat.Column1().Norm() && (rotmat.Column1() ^ rotmat.Column2()) < 0.001 && (rotmat.Column1() ^ rotmat.Column2()) > -0.001);
// 2x2 subdeterminants in first 2 columns
double d12 = rotmat.m11*rotmat.m22-rotmat.m12*rotmat.m21;
double d13 = rotmat.m11*rotmat.m32-rotmat.m12*rotmat.m31;
double d14 = rotmat.m11*rotmat.m42-rotmat.m12*rotmat.m41;
double d23 = rotmat.m21*rotmat.m32-rotmat.m22*rotmat.m31;
double d24 = rotmat.m21*rotmat.m42-rotmat.m22*rotmat.m41;
double d34 = rotmat.m31*rotmat.m42-rotmat.m32*rotmat.m41;
double d12 = rotmat.m11 * rotmat.m22 - rotmat.m12 * rotmat.m21;
double d13 = rotmat.m11 * rotmat.m32 - rotmat.m12 * rotmat.m31;
double d14 = rotmat.m11 * rotmat.m42 - rotmat.m12 * rotmat.m41;
double d23 = rotmat.m21 * rotmat.m32 - rotmat.m22 * rotmat.m31;
double d24 = rotmat.m21 * rotmat.m42 - rotmat.m22 * rotmat.m41;
double d34 = rotmat.m31 * rotmat.m42 - rotmat.m32 * rotmat.m41;
VectorR4 vec3;
if ( j==2 ) {
if ( d12>0.4 || d12<-0.4 || d13>0.4 || d13<-0.4
|| d23>0.4 || d23<-0.4 ) {
vec3.Set( d23, -d13, d12, 0.0);
if (j == 2)
{
if (d12 > 0.4 || d12 < -0.4 || d13 > 0.4 || d13 < -0.4 || d23 > 0.4 || d23 < -0.4)
{
vec3.Set(d23, -d13, d12, 0.0);
}
else if ( d24>0.4 || d24<-0.4 || d14>0.4 || d14<-0.4 ) {
vec3.Set( d24, -d14, 0.0, d12 );
else if (d24 > 0.4 || d24 < -0.4 || d14 > 0.4 || d14 < -0.4)
{
vec3.Set(d24, -d14, 0.0, d12);
}
else {
vec3.Set( d34, 0.0, -d14, d13 );
else
{
vec3.Set(d34, 0.0, -d14, d13);
}
vec3.Normalize();
rotmat.SetColumn3(vec3);
@@ -378,90 +380,88 @@ void GetOrtho( int j, RotationMapR4& rotmat)
// Do the final column
rotmat.SetColumn4 (
-rotmat.m23*d34 + rotmat.m33*d24 - rotmat.m43*d23,
rotmat.m13*d34 - rotmat.m33*d14 + rotmat.m43*d13,
-rotmat.m13*d24 + rotmat.m23*d14 - rotmat.m43*d12,
rotmat.m13*d23 - rotmat.m23*d13 + rotmat.m33*d12 );
assert ( 0.99 < (((LinearMapR4)rotmat)).Determinant()
&& (((LinearMapR4)rotmat)).Determinant() < 1.01 );
rotmat.SetColumn4(
-rotmat.m23 * d34 + rotmat.m33 * d24 - rotmat.m43 * d23,
rotmat.m13 * d34 - rotmat.m33 * d14 + rotmat.m43 * d13,
-rotmat.m13 * d24 + rotmat.m23 * d14 - rotmat.m43 * d12,
rotmat.m13 * d23 - rotmat.m23 * d13 + rotmat.m33 * d12);
assert(0.99 < (((LinearMapR4)rotmat)).Determinant() && (((LinearMapR4)rotmat)).Determinant() < 1.01);
}
// *********************************************************************
// Rotation routines *
// *********************************************************************
// Rotate unit vector x in the direction of "dir": length of dir is rotation angle.
// x must be a unit vector. dir must be perpindicular to x.
VectorR4& VectorR4::RotateUnitInDirection ( const VectorR4& dir)
{
assert ( this->Norm()<1.0001 && this->Norm()>0.9999 &&
(dir^(*this))<0.0001 && (dir^(*this))>-0.0001 );
VectorR4& VectorR4::RotateUnitInDirection(const VectorR4& dir)
{
assert(this->Norm() < 1.0001 && this->Norm() > 0.9999 &&
(dir ^ (*this)) < 0.0001 && (dir ^ (*this)) > -0.0001);
double theta = dir.NormSq();
if ( theta==0.0 ) {
if (theta == 0.0)
{
return *this;
}
else {
else
{
theta = sqrt(theta);
double costheta = cos(theta);
double sintheta = sin(theta);
VectorR4 dirUnit = dir/theta;
*this = costheta*(*this) + sintheta*dirUnit;
VectorR4 dirUnit = dir / theta;
*this = costheta * (*this) + sintheta * dirUnit;
// this->NormalizeFast();
return ( *this );
return (*this);
}
}
// RotateToMap returns a RotationMapR4 that rotates fromVec to toVec,
// leaving the orthogonal subspace fixed.
// fromVec and toVec should be unit vectors
RotationMapR4 RotateToMap( const VectorR4& fromVec, const VectorR4& toVec)
RotationMapR4 RotateToMap(const VectorR4& fromVec, const VectorR4& toVec)
{
LinearMapR4 result;
LinearMapR4 result;
result.SetIdentity();
LinearMapR4 temp;
VectorR4 vPerp = ProjectPerpUnitDiff( toVec, fromVec );
double sintheta = vPerp.Norm(); // theta = angle between toVec and fromVec
VectorR4 vProj = toVec-vPerp;
double costheta = vProj^fromVec;
if ( sintheta == 0.0 ) {
VectorR4 vPerp = ProjectPerpUnitDiff(toVec, fromVec);
double sintheta = vPerp.Norm(); // theta = angle between toVec and fromVec
VectorR4 vProj = toVec - vPerp;
double costheta = vProj ^ fromVec;
if (sintheta == 0.0)
{
// The vectors either coincide (return identity) or directly oppose
if ( costheta < 0.0 ) {
result = -result; // Vectors directly oppose: return -identity.
if (costheta < 0.0)
{
result = -result; // Vectors directly oppose: return -identity.
}
}
else {
vPerp /= sintheta; // Normalize
VectorProjectMap ( fromVec, temp ); // project in fromVec direction
temp *= (costheta-1.0);
else
{
vPerp /= sintheta; // Normalize
VectorProjectMap(fromVec, temp); // project in fromVec direction
temp *= (costheta - 1.0);
result += temp;
VectorProjectMap ( vPerp, temp ); // Project in vPerp direction
temp *= (costheta-1.0);
VectorProjectMap(vPerp, temp); // Project in vPerp direction
temp *= (costheta - 1.0);
result += temp;
TimesTranspose ( vPerp, fromVec, temp ); // temp = (vPerp)*(fromVec^T)
TimesTranspose(vPerp, fromVec, temp); // temp = (vPerp)*(fromVec^T)
temp *= sintheta;
result += temp;
temp.MakeTranspose();
result -= temp; // (-sintheta)*(fromVec)*(vPerp^T)
result -= temp; // (-sintheta)*(fromVec)*(vPerp^T)
}
RotationMapR4 rotationResult;
rotationResult.Set(result); // Make explicitly a RotationMapR4
rotationResult.Set(result); // Make explicitly a RotationMapR4
return rotationResult;
}
// ***************************************************************
// Stream Output Routines *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ostream& operator<< ( ostream& os, const VectorR4& u )
ostream& operator<<(ostream& os, const VectorR4& u)
{
return (os << "<" << u.x << "," << u.y << "," << u.z << "," << u.w << ">");
}

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,6 @@ subject to the following restrictions:
*
*/
#ifndef MATH_MISC_H
#define MATH_MISC_H
@@ -31,41 +30,41 @@ subject to the following restrictions:
//
const double PI = 3.1415926535897932384626433832795028841972;
const double PI2 = 2.0*PI;
const double PI4 = 4.0*PI;
const double PISq = PI*PI;
const double PIhalves = 0.5*PI;
const double PIthirds = PI/3.0;
const double PItwothirds = PI2/3.0;
const double PIfourths = 0.25*PI;
const double PIsixths = PI/6.0;
const double PIsixthsSq = PIsixths*PIsixths;
const double PItwelfths = PI/12.0;
const double PItwelfthsSq = PItwelfths*PItwelfths;
const double PIinv = 1.0/PI;
const double PI2inv = 0.5/PI;
const double PIhalfinv = 2.0/PI;
const double PI2 = 2.0 * PI;
const double PI4 = 4.0 * PI;
const double PISq = PI * PI;
const double PIhalves = 0.5 * PI;
const double PIthirds = PI / 3.0;
const double PItwothirds = PI2 / 3.0;
const double PIfourths = 0.25 * PI;
const double PIsixths = PI / 6.0;
const double PIsixthsSq = PIsixths * PIsixths;
const double PItwelfths = PI / 12.0;
const double PItwelfthsSq = PItwelfths * PItwelfths;
const double PIinv = 1.0 / PI;
const double PI2inv = 0.5 / PI;
const double PIhalfinv = 2.0 / PI;
const double RadiansToDegrees = 180.0/PI;
const double DegreesToRadians = PI/180;
const double RadiansToDegrees = 180.0 / PI;
const double DegreesToRadians = PI / 180;
const double OneThird = 1.0/3.0;
const double TwoThirds = 2.0/3.0;
const double OneSixth = 1.0/6.0;
const double OneEighth = 1.0/8.0;
const double OneTwelfth = 1.0/12.0;
const double OneThird = 1.0 / 3.0;
const double TwoThirds = 2.0 / 3.0;
const double OneSixth = 1.0 / 6.0;
const double OneEighth = 1.0 / 8.0;
const double OneTwelfth = 1.0 / 12.0;
const double Root2 = sqrt(2.0);
const double Root3 = sqrt(3.0);
const double Root2Inv = 1.0/Root2; // sqrt(2)/2
const double HalfRoot3 = sqrtf(3)/2.0;
const double Root2Inv = 1.0 / Root2; // sqrt(2)/2
const double HalfRoot3 = sqrtf(3) / 2.0;
const double LnTwo = log(2.0);
const double LnTwoInv = 1.0/log(2.0);
const double LnTwoInv = 1.0 / log(2.0);
// Special purpose constants
const double OnePlusEpsilon15 = 1.0+1.0e-15;
const double OneMinusEpsilon15 = 1.0-1.0e-15;
const double OnePlusEpsilon15 = 1.0 + 1.0e-15;
const double OneMinusEpsilon15 = 1.0 - 1.0e-15;
inline double ZeroValue(const double& x)
{
@@ -76,156 +75,191 @@ inline double ZeroValue(const double& x)
// Comparisons
//
template<class T> inline T Min ( T x, T y )
template <class T>
inline T Min(T x, T y)
{
return (x<y ? x : y);
return (x < y ? x : y);
}
template<class T> inline T Max ( T x, T y )
template <class T>
inline T Max(T x, T y)
{
return (y<x ? x : y);
return (y < x ? x : y);
}
template<class T> inline T ClampRange ( T x, T min, T max)
template <class T>
inline T ClampRange(T x, T min, T max)
{
if ( x<min ) {
if (x < min)
{
return min;
}
if ( x>max ) {
if (x > max)
{
return max;
}
return x;
}
template<class T> inline bool ClampRange ( T *x, T min, T max)
template <class T>
inline bool ClampRange(T* x, T min, T max)
{
if ( (*x)<min ) {
if ((*x) < min)
{
(*x) = min;
return false;
}
else if ( (*x)>max ) {
else if ((*x) > max)
{
(*x) = max;
return false;
}
else {
else
{
return true;
}
}
template<class T> inline bool ClampMin ( T *x, T min)
{
if ( (*x)<min ) {
(*x) = min;
return false;
}
return true;
}
template<class T> inline bool ClampMax ( T *x, T max)
{
if ( (*x)>max ) {
(*x) = max;
return false;
}
return true;
}
template<class T> inline T& UpdateMin ( const T& x, T& y )
{
if ( x<y ) {
y = x;
}
return y;
}
template<class T> inline T& UpdateMax ( const T& x, T& y )
{
if ( x>y ) {
y = x;
}
return y;
}
template<class T> inline bool SameSignNonzero( T x, T y )
{
if ( x<0 ) {
return (y<0);
}
else if ( 0<x ) {
return (0<y);
}
else {
return false;
}
}
inline double Mag ( double x ) {
return fabs(x);
}
inline double Dist ( double x, double y ) {
return fabs(x-y);
}
template <class T>
inline bool NearEqual( T a, T b, double tolerance ) {
a -= b;
return ( Mag(a)<=tolerance );
}
inline bool EqualZeroFuzzy( double x ) {
return ( fabs(x)<=1.0e-14 );
}
inline bool NearZero( double x, double tolerance ) {
return ( fabs(x)<=tolerance );
}
inline bool LessOrEqualFuzzy( double x, double y )
inline bool ClampMin(T* x, T min)
{
if ( x <= y ) {
if ((*x) < min)
{
(*x) = min;
return false;
}
return true;
}
template <class T>
inline bool ClampMax(T* x, T max)
{
if ((*x) > max)
{
(*x) = max;
return false;
}
return true;
}
template <class T>
inline T& UpdateMin(const T& x, T& y)
{
if (x < y)
{
y = x;
}
return y;
}
template <class T>
inline T& UpdateMax(const T& x, T& y)
{
if (x > y)
{
y = x;
}
return y;
}
template <class T>
inline bool SameSignNonzero(T x, T y)
{
if (x < 0)
{
return (y < 0);
}
else if (0 < x)
{
return (0 < y);
}
else
{
return false;
}
}
inline double Mag(double x)
{
return fabs(x);
}
inline double Dist(double x, double y)
{
return fabs(x - y);
}
template <class T>
inline bool NearEqual(T a, T b, double tolerance)
{
a -= b;
return (Mag(a) <= tolerance);
}
inline bool EqualZeroFuzzy(double x)
{
return (fabs(x) <= 1.0e-14);
}
inline bool NearZero(double x, double tolerance)
{
return (fabs(x) <= tolerance);
}
inline bool LessOrEqualFuzzy(double x, double y)
{
if (x <= y)
{
return true;
}
if ( y > 0.0 ) {
if ( x>0.0 ) {
return ( x*OneMinusEpsilon15 < y*OnePlusEpsilon15 );
if (y > 0.0)
{
if (x > 0.0)
{
return (x * OneMinusEpsilon15 < y * OnePlusEpsilon15);
}
else {
return ( y<1.0e-15 ); // x==0 in this case
else
{
return (y < 1.0e-15); // x==0 in this case
}
}
else if ( y < 0.0 ) {
if ( x<0.0 ) {
return ( x*OnePlusEpsilon15 < y*OneMinusEpsilon15 );
else if (y < 0.0)
{
if (x < 0.0)
{
return (x * OnePlusEpsilon15 < y * OneMinusEpsilon15);
}
else {
return ( y>-1.0e-15 ); // x==0 in this case
else
{
return (y > -1.0e-15); // x==0 in this case
}
}
else {
return ( -1.0e-15<x && x<1.0e-15 );
else
{
return (-1.0e-15 < x && x < 1.0e-15);
}
}
inline bool GreaterOrEqualFuzzy ( double x, double y )
inline bool GreaterOrEqualFuzzy(double x, double y)
{
return LessOrEqualFuzzy( y, x );
return LessOrEqualFuzzy(y, x);
}
inline bool UpdateMaxAbs( double *maxabs, double updateval )
inline bool UpdateMaxAbs(double* maxabs, double updateval)
{
if ( updateval > *maxabs ) {
if (updateval > *maxabs)
{
*maxabs = updateval;
return true;
}
else if ( -updateval > *maxabs ) {
else if (-updateval > *maxabs)
{
*maxabs = -updateval;
return true;
}
else {
else
{
return false;
}
}
@@ -235,33 +269,38 @@ inline bool UpdateMaxAbs( double *maxabs, double updateval )
// **********************************************************
template <class T>
void averageOf ( const T& a, const T &b, T&c ) {
void averageOf(const T& a, const T& b, T& c)
{
c = a;
c += b;
c *= 0.5;
}
template <class T>
void Lerp( const T& a, const T&b, double alpha, T&c ) {
double beta = 1.0-alpha;
if ( beta>alpha ) {
void Lerp(const T& a, const T& b, double alpha, T& c)
{
double beta = 1.0 - alpha;
if (beta > alpha)
{
c = b;
c *= alpha/beta;
c *= alpha / beta;
c += a;
c *= beta;
}
else {
else
{
c = a;
c *= beta/alpha;
c *= beta / alpha;
c += b;
c *= alpha;
}
}
template <class T>
T Lerp( const T& a, const T&b, double alpha ) {
T Lerp(const T& a, const T& b, double alpha)
{
T ret;
Lerp( a, b, alpha, ret );
Lerp(a, b, alpha, ret);
return ret;
}
@@ -270,115 +309,139 @@ T Lerp( const T& a, const T&b, double alpha ) {
// **********************************************************
// TimesCot(x) returns x*cot(x)
inline double TimesCot ( double x ) {
if ( -1.0e-5 < x && x < 1.0e-5 ) {
return 1.0+x*OneThird;
inline double TimesCot(double x)
{
if (-1.0e-5 < x && x < 1.0e-5)
{
return 1.0 + x * OneThird;
}
else {
return ( x*cos(x)/sin(x) );
else
{
return (x * cos(x) / sin(x));
}
}
// SineOver(x) returns sin(x)/x.
inline double SineOver( double x ) {
if ( -1.0e-5 < x && x < 1.0e-5 ) {
return 1.0-x*x*OneSixth;
inline double SineOver(double x)
{
if (-1.0e-5 < x && x < 1.0e-5)
{
return 1.0 - x * x * OneSixth;
}
else {
return sin(x)/x;
else
{
return sin(x) / x;
}
}
// OverSine(x) returns x/sin(x).
inline double OverSine( double x ) {
if ( -1.0e-5 < x && x < 1.0e-5 ) {
return 1.0+x*x*OneSixth;
inline double OverSine(double x)
{
if (-1.0e-5 < x && x < 1.0e-5)
{
return 1.0 + x * x * OneSixth;
}
else {
return x/sin(x);
else
{
return x / sin(x);
}
}
inline double SafeAsin( double x ) {
if ( x <= -1.0 ) {
inline double SafeAsin(double x)
{
if (x <= -1.0)
{
return -PIhalves;
}
else if ( x >= 1.0 ) {
else if (x >= 1.0)
{
return PIhalves;
}
else {
else
{
return asin(x);
}
}
inline double SafeAcos( double x ) {
if ( x <= -1.0 ) {
inline double SafeAcos(double x)
{
if (x <= -1.0)
{
return PI;
}
else if ( x >= 1.0 ) {
else if (x >= 1.0)
{
return 0.0;
}
else {
else
{
return acos(x);
}
}
// **********************************************************************
// Roots and powers *
// **********************************************************************
// Square(x) returns x*x, of course!
template<class T> inline T Square ( T x )
template <class T>
inline T Square(T x)
{
return (x*x);
return (x * x);
}
// Cube(x) returns x*x*x, of course!
template<class T> inline T Cube ( T x )
template <class T>
inline T Cube(T x)
{
return (x*x*x);
return (x * x * x);
}
// SafeSqrt(x) = returns sqrt(max(x, 0.0));
inline double SafeSqrt( double x ) {
if ( x<=0.0 ) {
inline double SafeSqrt(double x)
{
if (x <= 0.0)
{
return 0.0;
}
else {
else
{
return sqrt(x);
}
}
// SignedSqrt(a, s) returns (sign(s)*sqrt(a)).
inline double SignedSqrt( double a, double sgn )
inline double SignedSqrt(double a, double sgn)
{
if ( sgn==0.0 ) {
if (sgn == 0.0)
{
return 0.0;
}
else {
return ( sgn>0.0 ? sqrt(a) : -sqrt(a) );
else
{
return (sgn > 0.0 ? sqrt(a) : -sqrt(a));
}
}
// Template version of Sign function
template<class T> inline int Sign( T x)
template <class T>
inline int Sign(T x)
{
if ( x<0 ) {
if (x < 0)
{
return -1;
}
else if ( x==0 ) {
else if (x == 0)
{
return 0;
}
else {
else
{
return 1;
}
}
#endif // #ifndef MATH_MISC_H
#endif // #ifndef MATH_MISC_H

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,6 @@ subject to the following restrictions:
*
*/
//
// MatrixRmn: Matrix over reals (Variable dimensional vector)
//
@@ -36,21 +35,21 @@ subject to the following restrictions:
#include "LinearR3.h"
#include "VectorRn.h"
class MatrixRmn {
class MatrixRmn
{
public:
MatrixRmn(); // Null constructor
MatrixRmn( long numRows, long numCols ); // Constructor with length
~MatrixRmn(); // Destructor
MatrixRmn(); // Null constructor
MatrixRmn(long numRows, long numCols); // Constructor with length
~MatrixRmn(); // Destructor
void SetSize( long numRows, long numCols );
long GetNumRows() const { return NumRows; }
long GetNumColumns() const { return NumCols; }
void SetZero();
void SetSize(long numRows, long numCols);
long GetNumRows() const { return NumRows; }
long GetNumColumns() const { return NumCols; }
void SetZero();
// Return entry in row i and column j.
double Get( long i, long j ) const;
void GetTriple( long i, long j, VectorR3 *retValue ) const;
double Get(long i, long j) const;
void GetTriple(long i, long j, VectorR3* retValue) const;
// Use GetPtr to get pointer into the array (efficient)
// Is friendly in that anyone can change the array contents (be careful!)
@@ -59,115 +58,124 @@ public:
// within the matrix. I do not expect these values to ever change.
const double* GetPtr() const;
double* GetPtr();
const double* GetPtr( long i, long j ) const;
double* GetPtr( long i, long j );
const double* GetColumnPtr( long j ) const;
double* GetColumnPtr( long j );
const double* GetRowPtr( long i ) const;
double* GetRowPtr( long i );
long GetRowStride() const { return NumRows; } // Step size (stride) along a row
long GetColStride() const { return 1; } // Step size (stide) along a column
const double* GetPtr(long i, long j) const;
double* GetPtr(long i, long j);
const double* GetColumnPtr(long j) const;
double* GetColumnPtr(long j);
const double* GetRowPtr(long i) const;
double* GetRowPtr(long i);
long GetRowStride() const { return NumRows; } // Step size (stride) along a row
long GetColStride() const { return 1; } // Step size (stide) along a column
void Set( long i, long j, double val );
void SetTriple( long i, long c, const VectorR3& u );
void Set(long i, long j, double val);
void SetTriple(long i, long c, const VectorR3& u);
void SetIdentity();
void SetDiagonalEntries( double d );
void SetDiagonalEntries( const VectorRn& d );
void SetSuperDiagonalEntries( double d );
void SetSuperDiagonalEntries( const VectorRn& d );
void SetSubDiagonalEntries( double d );
void SetSubDiagonalEntries( const VectorRn& d );
void SetColumn(long i, const VectorRn& d );
void SetRow(long i, const VectorRn& d );
void SetSequence( const VectorRn& d, long startRow, long startCol, long deltaRow, long deltaCol );
void SetDiagonalEntries(double d);
void SetDiagonalEntries(const VectorRn& d);
void SetSuperDiagonalEntries(double d);
void SetSuperDiagonalEntries(const VectorRn& d);
void SetSubDiagonalEntries(double d);
void SetSubDiagonalEntries(const VectorRn& d);
void SetColumn(long i, const VectorRn& d);
void SetRow(long i, const VectorRn& d);
void SetSequence(const VectorRn& d, long startRow, long startCol, long deltaRow, long deltaCol);
// Loads matrix in as a sub-matrix. (i,j) is the base point. Defaults to (0,0).
// The "Tranpose" versions load the transpose of A.
void LoadAsSubmatrix( const MatrixRmn& A );
void LoadAsSubmatrix( long i, long j, const MatrixRmn& A );
void LoadAsSubmatrixTranspose( const MatrixRmn& A );
void LoadAsSubmatrixTranspose( long i, long j, const MatrixRmn& A );
void LoadAsSubmatrix(const MatrixRmn& A);
void LoadAsSubmatrix(long i, long j, const MatrixRmn& A);
void LoadAsSubmatrixTranspose(const MatrixRmn& A);
void LoadAsSubmatrixTranspose(long i, long j, const MatrixRmn& A);
// Norms
double FrobeniusNormSq() const;
double FrobeniusNorm() const;
// Operations on VectorRn's
void Multiply( const VectorRn& v, VectorRn& result ) const; // result = (this)*(v)
void MultiplyTranspose( const VectorRn& v, VectorRn& result ) const; // Equivalent to mult by row vector on left
double DotProductColumn( const VectorRn& v, long colNum ) const; // Returns dot product of v with i-th column
void Multiply(const VectorRn& v, VectorRn& result) const; // result = (this)*(v)
void MultiplyTranspose(const VectorRn& v, VectorRn& result) const; // Equivalent to mult by row vector on left
double DotProductColumn(const VectorRn& v, long colNum) const; // Returns dot product of v with i-th column
// Operations on MatrixRmn's
MatrixRmn& operator*=( double );
MatrixRmn& operator/=( double d ) { assert(d!=0.0); *this *= (1.0/d); return *this; }
MatrixRmn& AddScaled( const MatrixRmn& B, double factor );
MatrixRmn& operator+=( const MatrixRmn& B );
MatrixRmn& operator-=( const MatrixRmn& B );
static MatrixRmn& Multiply( const MatrixRmn& A, const MatrixRmn& B, MatrixRmn& dst ); // Sets dst = A*B.
static MatrixRmn& MultiplyTranspose( const MatrixRmn& A, const MatrixRmn& B, MatrixRmn& dst ); // Sets dst = A*(B-tranpose).
static MatrixRmn& TransposeMultiply( const MatrixRmn& A, const MatrixRmn& B, MatrixRmn& dst ); // Sets dst = (A-transpose)*B.
MatrixRmn& operator*=(double);
MatrixRmn& operator/=(double d)
{
assert(d != 0.0);
*this *= (1.0 / d);
return *this;
}
MatrixRmn& AddScaled(const MatrixRmn& B, double factor);
MatrixRmn& operator+=(const MatrixRmn& B);
MatrixRmn& operator-=(const MatrixRmn& B);
static MatrixRmn& Multiply(const MatrixRmn& A, const MatrixRmn& B, MatrixRmn& dst); // Sets dst = A*B.
static MatrixRmn& MultiplyTranspose(const MatrixRmn& A, const MatrixRmn& B, MatrixRmn& dst); // Sets dst = A*(B-tranpose).
static MatrixRmn& TransposeMultiply(const MatrixRmn& A, const MatrixRmn& B, MatrixRmn& dst); // Sets dst = (A-transpose)*B.
// Miscellaneous operation
MatrixRmn& AddToDiagonal( double d ); // Adds d to each diagonal
MatrixRmn& AddToDiagonal( const VectorRn& dVec);
MatrixRmn& AddToDiagonal(double d); // Adds d to each diagonal
MatrixRmn& AddToDiagonal(const VectorRn& dVec);
// Solving systems of linear equations
void Solve( const VectorRn& b, VectorRn* x ) const; // Solves the equation (*this)*x = b; Uses row operations. Assumes *this is invertible.
void Solve(const VectorRn& b, VectorRn* x) const; // Solves the equation (*this)*x = b; Uses row operations. Assumes *this is invertible.
// Row Echelon Form and Reduced Row Echelon Form routines
// Row echelon form here allows non-negative entries (instead of 1's) in the positions of lead variables.
void ConvertToRefNoFree(); // Converts the matrix in place to row echelon form -- assumption is no free variables will be found
void ConvertToRef( int numVars); // Converts the matrix in place to row echelon form -- numVars is number of columns to work with.
void ConvertToRef( int numVars, double eps); // Same, but eps is the measure of closeness to zero
void ConvertToRefNoFree(); // Converts the matrix in place to row echelon form -- assumption is no free variables will be found
void ConvertToRef(int numVars); // Converts the matrix in place to row echelon form -- numVars is number of columns to work with.
void ConvertToRef(int numVars, double eps); // Same, but eps is the measure of closeness to zero
// Givens transformation
static void CalcGivensValues( double a, double b, double *c, double *s );
void PostApplyGivens( double c, double s, long idx ); // Applies Givens transform to columns idx and idx+1.
void PostApplyGivens( double c, double s, long idx1, long idx2 ); // Applies Givens transform to columns idx1 and idx2.
static void CalcGivensValues(double a, double b, double* c, double* s);
void PostApplyGivens(double c, double s, long idx); // Applies Givens transform to columns idx and idx+1.
void PostApplyGivens(double c, double s, long idx1, long idx2); // Applies Givens transform to columns idx1 and idx2.
// Singular value decomposition
void ComputeSVD( MatrixRmn& U, VectorRn& w, MatrixRmn& V ) const;
void ComputeSVD(MatrixRmn& U, VectorRn& w, MatrixRmn& V) const;
// Good for debugging SVD computations (I recommend this be used for any new application to check for bugs/instability).
bool DebugCheckSVD( const MatrixRmn& U, const VectorRn& w, const MatrixRmn& V ) const;
// Compute inverse of a matrix, the result is written in R
void ComputeInverse( MatrixRmn& R) const;
// Debug matrix inverse computation
bool DebugCheckInverse( const MatrixRmn& MInv ) const;
bool DebugCheckSVD(const MatrixRmn& U, const VectorRn& w, const MatrixRmn& V) const;
// Compute inverse of a matrix, the result is written in R
void ComputeInverse(MatrixRmn& R) const;
// Debug matrix inverse computation
bool DebugCheckInverse(const MatrixRmn& MInv) const;
// Some useful routines for experts who understand the inner workings of these classes.
inline static double DotArray( long length, const double* ptrA, long strideA, const double* ptrB, long strideB );
inline static void CopyArrayScale( long length, const double* from, long fromStride, double *to, long toStride, double scale );
inline static void AddArrayScale( long length, const double* from, long fromStride, double *to, long toStride, double scale );
inline static double DotArray(long length, const double* ptrA, long strideA, const double* ptrB, long strideB);
inline static void CopyArrayScale(long length, const double* from, long fromStride, double* to, long toStride, double scale);
inline static void AddArrayScale(long length, const double* from, long fromStride, double* to, long toStride, double scale);
private:
long NumRows; // Number of rows
long NumCols; // Number of columns
double *x; // Array of vector entries - stored in column order
long AllocSize; // Allocated size of the x array
long NumRows; // Number of rows
long NumCols; // Number of columns
double* x; // Array of vector entries - stored in column order
long AllocSize; // Allocated size of the x array
static MatrixRmn WorkMatrix; // Temporary work matrix
static MatrixRmn WorkMatrix; // Temporary work matrix
static MatrixRmn& GetWorkMatrix() { return WorkMatrix; }
static MatrixRmn& GetWorkMatrix(long numRows, long numCols) { WorkMatrix.SetSize( numRows, numCols ); return WorkMatrix; }
static MatrixRmn& GetWorkMatrix(long numRows, long numCols)
{
WorkMatrix.SetSize(numRows, numCols);
return WorkMatrix;
}
// Internal helper routines for SVD calculations
static void CalcBidiagonal( MatrixRmn& U, MatrixRmn& V, VectorRn& w, VectorRn& superDiag );
void ConvertBidiagToDiagonal( MatrixRmn& U, MatrixRmn& V, VectorRn& w, VectorRn& superDiag ) const;
static void SvdHouseholder( double* basePt,
long colLength, long numCols, long colStride, long rowStride,
double* retFirstEntry );
void ExpandHouseholders( long numXforms, int numZerosSkipped, const double* basePt, long colStride, long rowStride );
static bool UpdateBidiagIndices( long *firstDiagIdx, long *lastBidiagIdx, VectorRn& w, VectorRn& superDiag, double eps );
static void ApplyGivensCBTD( double cosine, double sine, double *a, double *b, double *c, double *d );
static void ApplyGivensCBTD( double cosine, double sine, double *a, double *b, double *c,
double d, double *e, double *f );
static void ClearRowWithDiagonalZero( long firstBidiagIdx, long lastBidiagIdx,
MatrixRmn& U, double *wPtr, double *sdPtr, double eps );
static void ClearColumnWithDiagonalZero( long endIdx, MatrixRmn& V, double *wPtr, double *sdPtr, double eps );
bool DebugCalcBidiagCheck( const MatrixRmn& U, const VectorRn& w, const VectorRn& superDiag, const MatrixRmn& V ) const;
static void CalcBidiagonal(MatrixRmn& U, MatrixRmn& V, VectorRn& w, VectorRn& superDiag);
void ConvertBidiagToDiagonal(MatrixRmn& U, MatrixRmn& V, VectorRn& w, VectorRn& superDiag) const;
static void SvdHouseholder(double* basePt,
long colLength, long numCols, long colStride, long rowStride,
double* retFirstEntry);
void ExpandHouseholders(long numXforms, int numZerosSkipped, const double* basePt, long colStride, long rowStride);
static bool UpdateBidiagIndices(long* firstDiagIdx, long* lastBidiagIdx, VectorRn& w, VectorRn& superDiag, double eps);
static void ApplyGivensCBTD(double cosine, double sine, double* a, double* b, double* c, double* d);
static void ApplyGivensCBTD(double cosine, double sine, double* a, double* b, double* c,
double d, double* e, double* f);
static void ClearRowWithDiagonalZero(long firstBidiagIdx, long lastBidiagIdx,
MatrixRmn& U, double* wPtr, double* sdPtr, double eps);
static void ClearColumnWithDiagonalZero(long endIdx, MatrixRmn& V, double* wPtr, double* sdPtr, double eps);
bool DebugCalcBidiagCheck(const MatrixRmn& U, const VectorRn& w, const VectorRn& superDiag, const MatrixRmn& V) const;
};
inline MatrixRmn::MatrixRmn()
inline MatrixRmn::MatrixRmn()
{
NumRows = 0;
NumCols = 0;
@@ -175,185 +183,192 @@ inline MatrixRmn::MatrixRmn()
AllocSize = 0;
}
inline MatrixRmn::MatrixRmn( long numRows, long numCols )
inline MatrixRmn::MatrixRmn(long numRows, long numCols)
{
NumRows = 0;
NumCols = 0;
x = 0;
AllocSize = 0;
SetSize( numRows, numCols );
SetSize(numRows, numCols);
}
inline MatrixRmn::~MatrixRmn()
inline MatrixRmn::~MatrixRmn()
{
delete[] x;
}
// Resize.
// Resize.
// If the array space is decreased, the information about the allocated length is lost.
inline void MatrixRmn::SetSize( long numRows, long numCols )
inline void MatrixRmn::SetSize(long numRows, long numCols)
{
assert ( numRows>0 && numCols>0 );
long newLength = numRows*numCols;
if ( newLength>AllocSize ) {
assert(numRows > 0 && numCols > 0);
long newLength = numRows * numCols;
if (newLength > AllocSize)
{
delete[] x;
AllocSize = Max(newLength, AllocSize<<1);
AllocSize = Max(newLength, AllocSize << 1);
x = new double[AllocSize];
}
NumRows = numRows;
NumCols = numCols;
}
}
// Zero out the entire vector
inline void MatrixRmn::SetZero()
{
double* target = x;
for ( long i=NumRows*NumCols; i>0; i-- ) {
for (long i = NumRows * NumCols; i > 0; i--)
{
*(target++) = 0.0;
}
}
// Return entry in row i and column j.
inline double MatrixRmn::Get( long i, long j ) const {
assert ( i<NumRows && j<NumCols );
return *(x+j*NumRows+i);
inline double MatrixRmn::Get(long i, long j) const
{
assert(i < NumRows && j < NumCols);
return *(x + j * NumRows + i);
}
// Return a VectorR3 out of a column. Starts at row 3*i, in column j.
inline void MatrixRmn::GetTriple( long i, long j, VectorR3 *retValue ) const
inline void MatrixRmn::GetTriple(long i, long j, VectorR3* retValue) const
{
long ii = 3*i;
assert ( 0<=i && ii+2<NumRows && 0<=j && j<NumCols );
retValue->Load( x+j*NumRows + ii );
long ii = 3 * i;
assert(0 <= i && ii + 2 < NumRows && 0 <= j && j < NumCols);
retValue->Load(x + j * NumRows + ii);
}
// Get a pointer to the (0,0) entry.
// The entries are in column order.
// The entries are in column order.
// This version gives read-only pointer
inline const double* MatrixRmn::GetPtr( ) const
{
return x;
inline const double* MatrixRmn::GetPtr() const
{
return x;
}
// Get a pointer to the (0,0) entry.
// The entries are in column order.
inline double* MatrixRmn::GetPtr( )
{
return x;
// The entries are in column order.
inline double* MatrixRmn::GetPtr()
{
return x;
}
// Get a pointer to the (i,j) entry.
// The entries are in column order.
// The entries are in column order.
// This version gives read-only pointer
inline const double* MatrixRmn::GetPtr( long i, long j ) const
{
assert ( 0<=i && i<NumRows && 0<=j &&j<NumCols );
return (x+j*NumRows+i);
inline const double* MatrixRmn::GetPtr(long i, long j) const
{
assert(0 <= i && i < NumRows && 0 <= j && j < NumCols);
return (x + j * NumRows + i);
}
// Get a pointer to the (i,j) entry.
// The entries are in column order.
// The entries are in column order.
// This version gives pointer to writable data
inline double* MatrixRmn::GetPtr( long i, long j )
{
assert ( i<NumRows && j<NumCols );
return (x+j*NumRows+i);
inline double* MatrixRmn::GetPtr(long i, long j)
{
assert(i < NumRows && j < NumCols);
return (x + j * NumRows + i);
}
// Get a pointer to the j-th column.
// The entries are in column order.
// The entries are in column order.
// This version gives read-only pointer
inline const double* MatrixRmn::GetColumnPtr( long j ) const
{
assert ( 0<=j && j<NumCols );
return (x+j*NumRows);
inline const double* MatrixRmn::GetColumnPtr(long j) const
{
assert(0 <= j && j < NumCols);
return (x + j * NumRows);
}
// Get a pointer to the j-th column.
// This version gives pointer to writable data
inline double* MatrixRmn::GetColumnPtr( long j )
{
assert ( 0<=j && j<NumCols );
return (x+j*NumRows);
inline double* MatrixRmn::GetColumnPtr(long j)
{
assert(0 <= j && j < NumCols);
return (x + j * NumRows);
}
/// Get a pointer to the i-th row
// The entries are in column order.
// The entries are in column order.
// This version gives read-only pointer
inline const double* MatrixRmn::GetRowPtr( long i ) const
{
assert ( 0<=i && i<NumRows );
return (x+i);
inline const double* MatrixRmn::GetRowPtr(long i) const
{
assert(0 <= i && i < NumRows);
return (x + i);
}
// Get a pointer to the i-th row
// This version gives pointer to writable data
inline double* MatrixRmn::GetRowPtr( long i )
{
assert ( 0<=i && i<NumRows );
return (x+i);
inline double* MatrixRmn::GetRowPtr(long i)
{
assert(0 <= i && i < NumRows);
return (x + i);
}
// Set the (i,j) entry of the matrix
inline void MatrixRmn::Set( long i, long j, double val )
{
assert( i<NumRows && j<NumCols );
*(x+j*NumRows+i) = val;
inline void MatrixRmn::Set(long i, long j, double val)
{
assert(i < NumRows && j < NumCols);
*(x + j * NumRows + i) = val;
}
// Set the i-th triple in the j-th column to u's three values
inline void MatrixRmn::SetTriple( long i, long j, const VectorR3& u )
inline void MatrixRmn::SetTriple(long i, long j, const VectorR3& u)
{
long ii = 3*i;
assert ( 0<=i && ii+2<NumRows && 0<=j && j<NumCols );
u.Dump( x+j*NumRows + ii );
long ii = 3 * i;
assert(0 <= i && ii + 2 < NumRows && 0 <= j && j < NumCols);
u.Dump(x + j * NumRows + ii);
}
// Set to be equal to the identity matrix
inline void MatrixRmn::SetIdentity()
{
assert ( NumRows==NumCols );
assert(NumRows == NumCols);
SetZero();
SetDiagonalEntries(1.0);
}
inline MatrixRmn& MatrixRmn::operator*=( double mult )
inline MatrixRmn& MatrixRmn::operator*=(double mult)
{
double* aPtr = x;
for ( long i=NumRows*NumCols; i>0; i-- ) {
for (long i = NumRows * NumCols; i > 0; i--)
{
(*(aPtr++)) *= mult;
}
return (*this);
}
inline MatrixRmn& MatrixRmn::AddScaled( const MatrixRmn& B, double factor )
inline MatrixRmn& MatrixRmn::AddScaled(const MatrixRmn& B, double factor)
{
assert (NumRows==B.NumRows && NumCols==B.NumCols);
assert(NumRows == B.NumRows && NumCols == B.NumCols);
double* aPtr = x;
double* bPtr = B.x;
for ( long i=NumRows*NumCols; i>0; i-- ) {
(*(aPtr++)) += (*(bPtr++))*factor;
for (long i = NumRows * NumCols; i > 0; i--)
{
(*(aPtr++)) += (*(bPtr++)) * factor;
}
return (*this);
}
inline MatrixRmn& MatrixRmn::operator+=( const MatrixRmn& B )
inline MatrixRmn& MatrixRmn::operator+=(const MatrixRmn& B)
{
assert (NumRows==B.NumRows && NumCols==B.NumCols);
assert(NumRows == B.NumRows && NumCols == B.NumCols);
double* aPtr = x;
double* bPtr = B.x;
for ( long i=NumRows*NumCols; i>0; i-- ) {
for (long i = NumRows * NumCols; i > 0; i--)
{
(*(aPtr++)) += *(bPtr++);
}
return (*this);
}
inline MatrixRmn& MatrixRmn::operator-=( const MatrixRmn& B )
inline MatrixRmn& MatrixRmn::operator-=(const MatrixRmn& B)
{
assert (NumRows==B.NumRows && NumCols==B.NumCols);
assert(NumRows == B.NumRows && NumCols == B.NumCols);
double* aPtr = x;
double* bPtr = B.x;
for ( long i=NumRows*NumCols; i>0; i-- ) {
for (long i = NumRows * NumCols; i > 0; i--)
{
(*(aPtr++)) -= *(bPtr++);
}
return (*this);
@@ -363,18 +378,20 @@ inline double MatrixRmn::FrobeniusNormSq() const
{
double* aPtr = x;
double result = 0.0;
for ( long i=NumRows*NumCols; i>0; i-- ) {
result += Square( *(aPtr++) );
for (long i = NumRows * NumCols; i > 0; i--)
{
result += Square(*(aPtr++));
}
return result;
}
// Helper routine to calculate dot product
inline double MatrixRmn::DotArray( long length, const double* ptrA, long strideA, const double* ptrB, long strideB )
inline double MatrixRmn::DotArray(long length, const double* ptrA, long strideA, const double* ptrB, long strideB)
{
double result = 0.0;
for ( ; length>0 ; length-- ) {
result += (*ptrA)*(*ptrB);
for (; length > 0; length--)
{
result += (*ptrA) * (*ptrB);
ptrA += strideA;
ptrB += strideB;
}
@@ -382,26 +399,26 @@ inline double MatrixRmn::DotArray( long length, const double* ptrA, long strideA
}
// Helper routine: copies and scales an array (src and dest may be equal, or overlap)
inline void MatrixRmn::CopyArrayScale( long length, const double* from, long fromStride, double *to, long toStride, double scale )
inline void MatrixRmn::CopyArrayScale(long length, const double* from, long fromStride, double* to, long toStride, double scale)
{
for ( ; length>0; length-- ) {
*to = (*from)*scale;
for (; length > 0; length--)
{
*to = (*from) * scale;
from += fromStride;
to += toStride;
}
}
// Helper routine: adds a scaled array
// Helper routine: adds a scaled array
// fromArray = toArray*scale.
inline void MatrixRmn::AddArrayScale( long length, const double* from, long fromStride, double *to, long toStride, double scale )
inline void MatrixRmn::AddArrayScale(long length, const double* from, long fromStride, double* to, long toStride, double scale)
{
for ( ; length>0; length-- ) {
*to += (*from)*scale;
for (; length > 0; length--)
{
*to += (*from) * scale;
from += fromStride;
to += toStride;
}
}
#endif //MATRIX_RMN_H
#endif //MATRIX_RMN_H

View File

@@ -66,9 +66,8 @@ static int zorder[] = {
1, 2, 3, 4, -5, 6
};
#endif
#define LENFRAC 0.10
#define BASEFRAC 1.10
#define LENFRAC 0.10
#define BASEFRAC 1.10
/****************************************************************
Arrow
@@ -76,15 +75,13 @@ static int zorder[] = {
/* size of wings as fraction of length: */
#define WINGS 0.10
#define WINGS 0.10
/* axes: */
#define X 1
#define Y 2
#define Z 3
#define X 1
#define Y 2
#define Z 3
/* x, y, z, axes: */
@@ -92,51 +89,39 @@ static int zorder[] = {
//static float ayy[3] = { 0., 1., 0. };
//static float azz[3] = { 0., 0., 1. };
/* function declarations: */
void cross( float [3], float [3], float [3] );
float dot( float [3], float [3] );
float unit( float [3], float [3] );
void cross(float[3], float[3], float[3]);
float dot(float[3], float[3]);
float unit(float[3], float[3]);
float dot( float v1[3], float v2[3] )
float dot(float v1[3], float v2[3])
{
return( v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] );
return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
}
void
cross( float v1[3], float v2[3], float vout[3] )
void cross(float v1[3], float v2[3], float vout[3])
{
float tmp[3];
tmp[0] = v1[1]*v2[2] - v2[1]*v1[2];
tmp[1] = v2[0]*v1[2] - v1[0]*v2[2];
tmp[2] = v1[0]*v2[1] - v2[0]*v1[1];
tmp[0] = v1[1] * v2[2] - v2[1] * v1[2];
tmp[1] = v2[0] * v1[2] - v1[0] * v2[2];
tmp[2] = v1[0] * v2[1] - v2[0] * v1[1];
vout[0] = tmp[0];
vout[1] = tmp[1];
vout[2] = tmp[2];
}
float
unit( float vin[3], float vout[3] )
float unit(float vin[3], float vout[3])
{
float dist, f ;
float dist, f;
dist = vin[0]*vin[0] + vin[1]*vin[1] + vin[2]*vin[2];
dist = vin[0] * vin[0] + vin[1] * vin[1] + vin[2] * vin[2];
if( dist > 0.0 )
if (dist > 0.0)
{
dist = sqrt( dist );
dist = sqrt(dist);
f = 1. / dist;
vout[0] = f * vin[0];
vout[1] = f * vin[1];
@@ -149,5 +134,5 @@ unit( float vin[3], float vout[3] )
vout[2] = vin[2];
}
return( dist );
return (dist);
}

View File

@@ -20,10 +20,8 @@ subject to the following restrictions:
*
*/
#include <math.h>
#include "LinearR3.h"
#include "MathMisc.h"
#include "Node.h"
@@ -37,9 +35,9 @@ Node::Node(const VectorR3& attach, const VectorR3& v, double size, Purpose purpo
Node::purpose = purpose;
seqNumJoint = -1;
seqNumEffector = -1;
Node::attach = attach; // Global attachment point when joints are at zero angle
r.Set(0.0, 0.0, 0.0); // r will be updated when this node is inserted into tree
Node::v = v; // Rotation axis when joints at zero angles
Node::attach = attach; // Global attachment point when joints are at zero angle
r.Set(0.0, 0.0, 0.0); // r will be updated when this node is inserted into tree
Node::v = v; // Rotation axis when joints at zero angles
theta = 0.0;
Node::minTheta = minTheta;
Node::maxTheta = maxTheta;
@@ -52,9 +50,10 @@ void Node::ComputeS(void)
{
Node* y = this->realparent;
Node* w = this;
s = r; // Initialize to local (relative) position
while ( y ) {
s.Rotate( y->theta, y->v );
s = r; // Initialize to local (relative) position
while (y)
{
s.Rotate(y->theta, y->v);
y = y->realparent;
w = w->realparent;
s += w->r;
@@ -65,15 +64,14 @@ void Node::ComputeS(void)
void Node::ComputeW(void)
{
Node* y = this->realparent;
w = v; // Initialize to local rotation axis
while (y) {
w = v; // Initialize to local rotation axis
while (y)
{
w.Rotate(y->theta, y->v);
y = y->realparent;
}
}
void Node::PrintNode()
{
cerr << "Attach : (" << attach << ")\n";
@@ -83,7 +81,6 @@ void Node::PrintNode()
cerr << "realparent : " << realparent->seqNumJoint << "\n";
}
void Node::InitNode()
{
theta = 0.0;

View File

@@ -20,31 +20,34 @@ subject to the following restrictions:
*
*/
#ifndef _CLASS_NODE
#define _CLASS_NODE
#include "LinearR3.h"
enum Purpose {JOINT, EFFECTOR};
enum Purpose
{
JOINT,
EFFECTOR
};
class VectorR3;
class Node {
class Node
{
friend class Tree;
public:
Node(const VectorR3&, const VectorR3&, double, Purpose, double minTheta=-PI, double maxTheta=PI, double restAngle=0.);
Node(const VectorR3&, const VectorR3&, double, Purpose, double minTheta = -PI, double maxTheta = PI, double restAngle = 0.);
void PrintNode();
void InitNode();
const VectorR3& GetAttach() const { return attach; }
double GetTheta() const { return theta; }
double AddToTheta( double& delta ) {
double AddToTheta(double& delta)
{
//double orgTheta = theta;
theta += delta;
#if 0
@@ -55,24 +58,27 @@ public:
double actualDelta = theta - orgTheta;
delta = actualDelta;
#endif
return theta; }
double UpdateTheta( double& delta ) {
theta = delta;
return theta; }
return theta;
}
double UpdateTheta(double& delta)
{
theta = delta;
return theta;
}
const VectorR3& GetS() const { return s; }
const VectorR3& GetW() const { return w; }
double GetMinTheta() const { return minTheta; }
double GetMaxTheta() const { return maxTheta; }
double GetRestAngle() const { return restAngle; } ;
double GetMaxTheta() const { return maxTheta; }
double GetRestAngle() const { return restAngle; };
void SetTheta(double newTheta) { theta = newTheta; }
void ComputeS(void);
void ComputeW(void);
bool IsEffector() const { return purpose==EFFECTOR; }
bool IsJoint() const { return purpose==JOINT; }
bool IsEffector() const { return purpose == EFFECTOR; }
bool IsJoint() const { return purpose == JOINT; }
int GetEffectorNum() const { return seqNumEffector; }
int GetJointNum() const { return seqNumJoint; }
@@ -80,26 +86,24 @@ public:
void Freeze() { freezed = true; }
void UnFreeze() { freezed = false; }
//private:
bool freezed; // Is this node frozen?
int seqNumJoint; // sequence number if this node is a joint
int seqNumEffector; // sequence number if this node is an effector
double size; // size
Purpose purpose; // joint / effector / both
VectorR3 attach; // attachment point
VectorR3 r; // relative position vector
VectorR3 v; // rotation axis
double theta; // joint angle (radian)
double minTheta; // lower limit of joint angle
double maxTheta; // upper limit of joint angle
double restAngle; // rest position angle
VectorR3 s; // GLobal Position
VectorR3 w; // Global rotation axis
Node* left; // left child
Node* right; // right sibling
Node* realparent; // pointer to real parent
//private:
bool freezed; // Is this node frozen?
int seqNumJoint; // sequence number if this node is a joint
int seqNumEffector; // sequence number if this node is an effector
double size; // size
Purpose purpose; // joint / effector / both
VectorR3 attach; // attachment point
VectorR3 r; // relative position vector
VectorR3 v; // rotation axis
double theta; // joint angle (radian)
double minTheta; // lower limit of joint angle
double maxTheta; // upper limit of joint angle
double restAngle; // rest position angle
VectorR3 s; // GLobal Position
VectorR3 w; // Global rotation axis
Node* left; // left child
Node* right; // right sibling
Node* realparent; // pointer to real parent
};
#endif

View File

@@ -20,8 +20,6 @@ subject to the following restrictions:
*
*/
//
// Spherical Operations Classes
//
@@ -30,7 +28,7 @@ subject to the following restrictions:
//
// OrientationR3
//
// A. Quaternion
// A. Quaternion
//
// B. RotationMapR3 // Elsewhere
//
@@ -48,80 +46,76 @@ subject to the following restrictions:
#include "LinearR4.h"
#include "MathMisc.h"
class SphericalInterpolator; // Spherical linear interpolation of vectors
class SphericalBSpInterpolator; // Spherical Bspline interpolation of vector
class Quaternion; // Quaternion (x,y,z,w) values.
class EulerAnglesR3; // Euler Angles
class SphericalInterpolator; // Spherical linear interpolation of vectors
class SphericalBSpInterpolator; // Spherical Bspline interpolation of vector
class Quaternion; // Quaternion (x,y,z,w) values.
class EulerAnglesR3; // Euler Angles
// *****************************************************
// SphericalInterpolator class *
// - Does linear interpolation (slerp-ing) *
// * * * * * * * * * * * * * * * * * * * * * * * * * * *
class SphericalInterpolator {
class SphericalInterpolator
{
private:
VectorR3 startDir, endDir; // Unit vectors (starting and ending)
double startLen, endLen; // Magnitudes of the vectors
double rotRate; // Angle between start and end vectors
VectorR3 startDir, endDir; // Unit vectors (starting and ending)
double startLen, endLen; // Magnitudes of the vectors
double rotRate; // Angle between start and end vectors
public:
SphericalInterpolator( const VectorR3& u, const VectorR3& v );
SphericalInterpolator(const VectorR3& u, const VectorR3& v);
VectorR3 InterValue ( double frac ) const;
VectorR3 InterValue(double frac) const;
};
// ***************************************************************
// * Quaternion class - prototypes *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
class Quaternion {
class Quaternion
{
public:
double x, y, z, w;
public:
Quaternion() :x(0.0), y(0.0), z(0.0), w(1.0) {};
Quaternion( double, double, double, double );
Quaternion() : x(0.0), y(0.0), z(0.0), w(1.0){};
Quaternion(double, double, double, double);
inline Quaternion& Set( double xx, double yy, double zz, double ww );
inline Quaternion& Set( const VectorR4& );
Quaternion& Set( const EulerAnglesR3& );
Quaternion& Set( const RotationMapR3& );
Quaternion& SetRotate( const VectorR3& );
inline Quaternion& Set(double xx, double yy, double zz, double ww);
inline Quaternion& Set(const VectorR4&);
Quaternion& Set(const EulerAnglesR3&);
Quaternion& Set(const RotationMapR3&);
Quaternion& SetRotate(const VectorR3&);
Quaternion& SetIdentity(); // Set to the identity map
Quaternion Inverse() const; // Return the Inverse
Quaternion& Invert(); // Invert this quaternion
Quaternion& SetIdentity(); // Set to the identity map
Quaternion Inverse() const; // Return the Inverse
Quaternion& Invert(); // Invert this quaternion
double Angle(); // Angle of rotation
double Norm(); // Norm of x,y,z component
double Angle(); // Angle of rotation
double Norm(); // Norm of x,y,z component
Quaternion& operator*=(const Quaternion&);
};
Quaternion operator*(const Quaternion&, const Quaternion&);
inline Quaternion ToQuat( const VectorR4& v)
{
return Quaternion(v.x,v.y,v.z,v.w);
}
inline double Quaternion::Norm()
inline Quaternion ToQuat(const VectorR4& v)
{
return sqrt( x*x + y*y + z*z );
return Quaternion(v.x, v.y, v.z, v.w);
}
inline double Quaternion::Angle ()
inline double Quaternion::Norm()
{
return sqrt(x * x + y * y + z * z);
}
inline double Quaternion::Angle()
{
double halfAngle = asin(Norm());
return halfAngle+halfAngle;
return halfAngle + halfAngle;
}
// ****************************************************************
// Solid Geometry Routines *
// ****************************************************************
@@ -130,116 +124,118 @@ inline double Quaternion::Angle ()
// Three unit vectors u,v,w specify the geodesics u-v and v-w which
// meet at vertex uv. The angle from v-w to v-u is returned. This
// is always in the range [0, 2PI).
double SphereAngle( const VectorR3& u, const VectorR3& v, const VectorR3& w );
double SphereAngle(const VectorR3& u, const VectorR3& v, const VectorR3& w);
// Compute the area of a triangle on the unit sphere. Three unit vectors
// specify the corners of the triangle in COUNTERCLOCKWISE order.
inline double SphericalTriangleArea(
const VectorR3& u, const VectorR3& v, const VectorR3& w )
inline double SphericalTriangleArea(
const VectorR3& u, const VectorR3& v, const VectorR3& w)
{
double AngleA = SphereAngle( u,v,w );
double AngleB = SphereAngle( v,w,u );
double AngleC = SphereAngle( w,u,v );
return ( AngleA+AngleB+AngleC - PI );
double AngleA = SphereAngle(u, v, w);
double AngleB = SphereAngle(v, w, u);
double AngleC = SphereAngle(w, u, v);
return (AngleA + AngleB + AngleC - PI);
}
// ****************************************************************
// Spherical Mean routines *
// ****************************************************************
// Weighted sum of vectors
VectorR3 WeightedSum( long Num, const VectorR3 vv[], const double weights[] );
VectorR4 WeightedSum( long Num, const VectorR4 vv[], const double weights[] );
VectorR3 WeightedSum(long Num, const VectorR3 vv[], const double weights[]);
VectorR4 WeightedSum(long Num, const VectorR4 vv[], const double weights[]);
// Weighted average of vectors on the sphere.
// Weighted average of vectors on the sphere.
// Sum of weights should equal one (but no checking is done)
VectorR3 ComputeMeanSphere( long Num, const VectorR3 vv[], const double weights[],
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13 );
VectorR3 ComputeMeanSphere( long Num, const VectorR3 vv[], const double weights[],
const VectorR3& InitialVec,
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13 );
VectorR4 ComputeMeanSphere( long Num, const VectorR4 vv[], const double weights[],
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13 );
Quaternion ComputeMeanQuat( long Num, const Quaternion qq[], const double weights[],
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13 );
VectorR3 ComputeMeanSphere(long Num, const VectorR3 vv[], const double weights[],
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13);
VectorR3 ComputeMeanSphere(long Num, const VectorR3 vv[], const double weights[],
const VectorR3& InitialVec,
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13);
VectorR4 ComputeMeanSphere(long Num, const VectorR4 vv[], const double weights[],
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13);
Quaternion ComputeMeanQuat(long Num, const Quaternion qq[], const double weights[],
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13);
// Next functions mostly for internal use.
// It takes an initial estimate InitialVec (and a flag for
// indicating quaternions).
VectorR4 ComputeMeanSphere( long Num, const VectorR4 vv[], const double weights[],
const VectorR4& InitialVec, int QuatFlag=0,
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13 );
const int SPHERICAL_NOTQUAT=0;
const int SPHERICAL_QUAT=1;
VectorR4 ComputeMeanSphere(long Num, const VectorR4 vv[], const double weights[],
const VectorR4& InitialVec, int QuatFlag = 0,
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13);
const int SPHERICAL_NOTQUAT = 0;
const int SPHERICAL_QUAT = 1;
// Slow version, mostly for testing
VectorR3 ComputeMeanSphereSlow( long Num, const VectorR3 vv[], const double weights[],
double tolerance = 1.0e-16, double bkuptolerance = 5.0e-16 );
VectorR4 ComputeMeanSphereSlow( long Num, const VectorR4 vv[], const double weights[],
double tolerance = 1.0e-16, double bkuptolerance = 5.0e-16 );
VectorR3 ComputeMeanSphereOld( long Num, const VectorR3 vv[], const double weights[],
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13 );
VectorR4 ComputeMeanSphereOld( long Num, const VectorR4 vv[], const double weights[],
const VectorR4& InitialVec, int QuatFlag,
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13 );
VectorR3 ComputeMeanSphereSlow(long Num, const VectorR3 vv[], const double weights[],
double tolerance = 1.0e-16, double bkuptolerance = 5.0e-16);
VectorR4 ComputeMeanSphereSlow(long Num, const VectorR4 vv[], const double weights[],
double tolerance = 1.0e-16, double bkuptolerance = 5.0e-16);
VectorR3 ComputeMeanSphereOld(long Num, const VectorR3 vv[], const double weights[],
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13);
VectorR4 ComputeMeanSphereOld(long Num, const VectorR4 vv[], const double weights[],
const VectorR4& InitialVec, int QuatFlag,
double tolerance = 1.0e-15, double bkuptolerance = 1.0e-13);
// Solves a system of spherical-mean equalities, where the system is
// given as a tridiagonal matrix.
void SolveTriDiagSphere ( int numPoints,
const double* tridiagvalues, const VectorR3* c,
VectorR3* p,
double accuracy=1.0e-15, double bkupaccuracy=1.0e-13 );
void SolveTriDiagSphere ( int numPoints,
const double* tridiagvalues, const VectorR4* c,
VectorR4* p,
double accuracy=1.0e-15, double bkupaccuracy=1.0e-13 );
void SolveTriDiagSphere(int numPoints,
const double* tridiagvalues, const VectorR3* c,
VectorR3* p,
double accuracy = 1.0e-15, double bkupaccuracy = 1.0e-13);
void SolveTriDiagSphere(int numPoints,
const double* tridiagvalues, const VectorR4* c,
VectorR4* p,
double accuracy = 1.0e-15, double bkupaccuracy = 1.0e-13);
// The "Slow" version uses a simpler but slower iteration with a linear rate of
// convergence. The base version uses a Newton iteration with a quadratic
// rate of convergence.
void SolveTriDiagSphereSlow ( int numPoints,
const double* tridiagvalues, const VectorR3* c,
VectorR3* p,
double accuracy=1.0e-15, double bkupaccuracy=5.0e-15 );
void SolveTriDiagSphereSlow ( int numPoints,
const double* tridiagvalues, const VectorR4* c,
VectorR4* p,
double accuracy=1.0e-15, double bkupaccuracy=5.0e-15 );
void SolveTriDiagSphereSlow(int numPoints,
const double* tridiagvalues, const VectorR3* c,
VectorR3* p,
double accuracy = 1.0e-15, double bkupaccuracy = 5.0e-15);
void SolveTriDiagSphereSlow(int numPoints,
const double* tridiagvalues, const VectorR4* c,
VectorR4* p,
double accuracy = 1.0e-15, double bkupaccuracy = 5.0e-15);
// The "Unstable" version probably shouldn't be used except for very short sequences
// of knots. Mostly it's used for testing purposes now.
void SolveTriDiagSphereUnstable ( int numPoints,
const double* tridiagvalues, const VectorR3* c,
VectorR3* p,
double accuracy=1.0e-15, double bkupaccuracy=1.0e-13 );
void SolveTriDiagSphereHelperUnstable ( int numPoints,
const double* tridiagvalues, const VectorR3 *c,
const VectorR3& p0value,
VectorR3 *p,
double accuracy=1.0e-15, double bkupaccuracy=1.0e-13 );
void SolveTriDiagSphereUnstable(int numPoints,
const double* tridiagvalues, const VectorR3* c,
VectorR3* p,
double accuracy = 1.0e-15, double bkupaccuracy = 1.0e-13);
void SolveTriDiagSphereHelperUnstable(int numPoints,
const double* tridiagvalues, const VectorR3* c,
const VectorR3& p0value,
VectorR3* p,
double accuracy = 1.0e-15, double bkupaccuracy = 1.0e-13);
// ***************************************************************
// * Quaternion class - inlined member functions *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
inline VectorR4::VectorR4 ( const Quaternion& q )
: x(q.x), y(q.y), z(q.z), w(q.w)
{}
inline VectorR4& VectorR4::Set ( const Quaternion& q )
inline VectorR4::VectorR4(const Quaternion& q)
: x(q.x), y(q.y), z(q.z), w(q.w)
{
x = q.x; y = q.y; z = q.z; w = q.w;
}
inline VectorR4& VectorR4::Set(const Quaternion& q)
{
x = q.x;
y = q.y;
z = q.z;
w = q.w;
return *this;
}
inline Quaternion::Quaternion( double xx, double yy, double zz, double ww)
: x(xx), y(yy), z(zz), w(ww)
{}
inline Quaternion& Quaternion::Set( double xx, double yy, double zz, double ww )
inline Quaternion::Quaternion(double xx, double yy, double zz, double ww)
: x(xx), y(yy), z(zz), w(ww)
{
}
inline Quaternion& Quaternion::Set(double xx, double yy, double zz, double ww)
{
x = xx;
y = yy;
@@ -248,7 +244,7 @@ inline Quaternion& Quaternion::Set( double xx, double yy, double zz, double ww )
return *this;
}
inline Quaternion& Quaternion::Set( const VectorR4& u)
inline Quaternion& Quaternion::Set(const VectorR4& u)
{
x = u.x;
y = u.y;
@@ -271,28 +267,27 @@ inline Quaternion operator*(const Quaternion& q1, const Quaternion& q2)
return q;
}
inline Quaternion& Quaternion::operator*=( const Quaternion& q )
inline Quaternion& Quaternion::operator*=(const Quaternion& q)
{
double wnew = w*q.w - (x*q.x + y*q.y + z*q.z);
double xnew = w*q.x + q.w*x + (y*q.z - z*q.y);
double ynew = w*q.y + q.w*y + (z*q.x - x*q.z);
z = w*q.z + q.w*z + (x*q.y - y*q.x);
double wnew = w * q.w - (x * q.x + y * q.y + z * q.z);
double xnew = w * q.x + q.w * x + (y * q.z - z * q.y);
double ynew = w * q.y + q.w * y + (z * q.x - x * q.z);
z = w * q.z + q.w * z + (x * q.y - y * q.x);
w = wnew;
x = xnew;
y = ynew;
return *this;
}
inline Quaternion Quaternion::Inverse() const // Return the Inverse
inline Quaternion Quaternion::Inverse() const // Return the Inverse
{
return ( Quaternion( x, y, z, -w ) );
return (Quaternion(x, y, z, -w));
}
inline Quaternion& Quaternion::Invert() // Invert this quaternion
inline Quaternion& Quaternion::Invert() // Invert this quaternion
{
w = -w;
return *this;
}
#endif // SPHERICAL_H
#endif // SPHERICAL_H

View File

@@ -31,9 +31,6 @@ subject to the following restrictions:
#include <iostream>
using namespace std;
#include "LinearR3.h"
#include "Tree.h"
#include "Node.h"
@@ -46,25 +43,26 @@ Tree::Tree()
void Tree::SetSeqNum(Node* node)
{
switch (node->purpose) {
case JOINT:
node->seqNumJoint = nJoint++;
node->seqNumEffector = -1;
break;
case EFFECTOR:
node->seqNumJoint = -1;
node->seqNumEffector = nEffector++;
break;
switch (node->purpose)
{
case JOINT:
node->seqNumJoint = nJoint++;
node->seqNumEffector = -1;
break;
case EFFECTOR:
node->seqNumJoint = -1;
node->seqNumEffector = nEffector++;
break;
}
}
void Tree::InsertRoot(Node* root)
{
assert( nNode==0 );
assert(nNode == 0);
nNode++;
Tree::root = root;
root->r = root->attach;
assert( !(root->left || root->right) );
assert(!(root->left || root->right));
SetSeqNum(root);
}
@@ -75,7 +73,7 @@ void Tree::InsertLeftChild(Node* parent, Node* child)
parent->left = child;
child->realparent = parent;
child->r = child->attach - child->realparent->attach;
assert( !(child->left || child->right) );
assert(!(child->left || child->right));
SetSeqNum(child);
}
@@ -86,7 +84,7 @@ void Tree::InsertRightSibling(Node* parent, Node* child)
parent->right = child;
child->realparent = parent->realparent;
child->r = child->attach - child->realparent->attach;
assert( !(child->left || child->right) );
assert(!(child->left || child->right));
SetSeqNum(child);
}
@@ -94,25 +92,31 @@ void Tree::InsertRightSibling(Node* parent, Node* child)
Node* Tree::SearchJoint(Node* node, int index)
{
Node* ret;
if (node != 0) {
if (node->seqNumJoint == index) {
if (node != 0)
{
if (node->seqNumJoint == index)
{
return node;
} else {
if ((ret = SearchJoint(node->left, index))) {
}
else
{
if ((ret = SearchJoint(node->left, index)))
{
return ret;
}
if ((ret = SearchJoint(node->right, index))) {
if ((ret = SearchJoint(node->right, index)))
{
return ret;
}
return NULL;
}
}
else {
}
else
{
return NULL;
}
}
// Get the joint with the index value
Node* Tree::GetJoint(int index)
{
@@ -123,24 +127,31 @@ Node* Tree::GetJoint(int index)
Node* Tree::SearchEffector(Node* node, int index)
{
Node* ret;
if (node != 0) {
if (node->seqNumEffector == index) {
if (node != 0)
{
if (node->seqNumEffector == index)
{
return node;
} else {
if ((ret = SearchEffector(node->left, index))) {
}
else
{
if ((ret = SearchEffector(node->left, index)))
{
return ret;
}
if ((ret = SearchEffector(node->right, index))) {
if ((ret = SearchEffector(node->right, index)))
{
return ret;
}
return NULL;
}
} else {
}
else
{
return NULL;
}
}
// Get the end effector for the index value
Node* Tree::GetEffector(int index)
{
@@ -152,12 +163,13 @@ const VectorR3& Tree::GetEffectorPosition(int index)
{
Node* effector = GetEffector(index);
assert(effector);
return (effector->s);
return (effector->s);
}
void Tree::ComputeTree(Node* node)
{
if (node != 0) {
if (node != 0)
{
node->ComputeS();
node->ComputeW();
ComputeTree(node->left);
@@ -166,30 +178,31 @@ void Tree::ComputeTree(Node* node)
}
void Tree::Compute(void)
{
ComputeTree(root);
{
ComputeTree(root);
}
void Tree::PrintTree(Node* node)
{
if (node != 0) {
if (node != 0)
{
node->PrintNode();
PrintTree(node->left);
PrintTree(node->right);
}
}
void Tree::Print(void)
{
PrintTree(root);
void Tree::Print(void)
{
PrintTree(root);
cout << "\n";
}
// Recursively initialize tree below the node
void Tree::InitTree(Node* node)
{
if (node != 0) {
if (node != 0)
{
node->InitNode();
InitTree(node->left);
InitTree(node->right);
@@ -204,7 +217,8 @@ void Tree::Init(void)
void Tree::UnFreezeTree(Node* node)
{
if (node != 0) {
if (node != 0)
{
node->UnFreeze();
UnFreezeTree(node->left);
UnFreezeTree(node->right);

View File

@@ -30,8 +30,8 @@ subject to the following restrictions:
#ifndef _CLASS_TREE
#define _CLASS_TREE
class Tree {
class Tree
{
public:
Tree();
@@ -49,43 +49,47 @@ public:
// Accessors for tree traversal
Node* GetRoot() const { return root; }
Node* GetSuccessor ( const Node* ) const;
Node* GetParent( const Node* node ) const { return node->realparent; }
Node* GetSuccessor(const Node*) const;
Node* GetParent(const Node* node) const { return node->realparent; }
void Compute();
void Print();
void Init();
void UnFreeze();
private:
Node* root;
int nNode; // nNode = nEffector + nJoint
int nNode; // nNode = nEffector + nJoint
int nEffector;
int nJoint;
void SetSeqNum(Node*);
Node* SearchJoint(Node*, int);
Node* SearchEffector(Node*, int);
void ComputeTree(Node*);
void PrintTree(Node*);
void InitTree(Node*);
void UnFreezeTree(Node*);
};
inline Node* Tree::GetSuccessor ( const Node* node ) const
inline Node* Tree::GetSuccessor(const Node* node) const
{
if ( node->left ) {
if (node->left)
{
return node->left;
}
while ( true ) {
if ( node->right ) {
return ( node->right );
while (true)
{
if (node->right)
{
return (node->right);
}
node = node->realparent;
if ( !node ) {
return 0; // Back to root, finished traversal
}
if (!node)
{
return 0; // Back to root, finished traversal
}
}
}

View File

@@ -20,7 +20,6 @@ subject to the following restrictions:
*
*/
//
// VectorRn: Vector over Rn (Variable length vector)
//
@@ -29,15 +28,18 @@ subject to the following restrictions:
VectorRn VectorRn::WorkVector;
double VectorRn::MaxAbs () const
double VectorRn::MaxAbs() const
{
double result = 0.0;
double* t = x;
for ( long i = length; i>0; i-- ) {
if ( (*t) > result ) {
for (long i = length; i > 0; i--)
{
if ((*t) > result)
{
result = *t;
}
else if ( -(*t) > result ) {
else if (-(*t) > result)
{
result = -(*t);
}
t++;

View File

@@ -34,205 +34,242 @@ subject to the following restrictions:
#include <assert.h>
#include "LinearR3.h"
class VectorRn {
class VectorRn
{
friend class MatrixRmn;
public:
VectorRn(); // Null constructor
VectorRn( long length ); // Constructor with length
~VectorRn(); // Destructor
VectorRn(); // Null constructor
VectorRn(long length); // Constructor with length
~VectorRn(); // Destructor
void SetLength( long newLength );
long GetLength() const { return length; }
void SetLength(long newLength);
long GetLength() const { return length; }
void SetZero();
void Fill( double d );
void Load( const double* d );
void LoadScaled( const double* d, double scaleFactor );
void Set ( const VectorRn& src );
void SetZero();
void Fill(double d);
void Load(const double* d);
void LoadScaled(const double* d, double scaleFactor);
void Set(const VectorRn& src);
// Two access methods identical in functionality
// Subscripts are ZERO-BASED!!
const double& operator[]( long i ) const { assert ( 0<=i && i<length ); return *(x+i); }
double& operator[]( long i ) { assert ( 0<=i && i<length ); return *(x+i); }
double Get( long i ) const { assert ( 0<=i && i<length ); return *(x+i); }
const double& operator[](long i) const
{
assert(0 <= i && i < length);
return *(x + i);
}
double& operator[](long i)
{
assert(0 <= i && i < length);
return *(x + i);
}
double Get(long i) const
{
assert(0 <= i && i < length);
return *(x + i);
}
// Use GetPtr to get pointer into the array (efficient)
// Is friendly in that anyone can change the array contents (be careful!)
const double* GetPtr( long i ) const { assert(0<=i && i<length); return (x+i); }
double* GetPtr( long i ) { assert(0<=i && i<length); return (x+i); }
const double* GetPtr(long i) const
{
assert(0 <= i && i < length);
return (x + i);
}
double* GetPtr(long i)
{
assert(0 <= i && i < length);
return (x + i);
}
const double* GetPtr() const { return x; }
double* GetPtr() { return x; }
void Set( long i, double val ) { assert(0<=i && i<length), *(x+i) = val; }
void SetTriple( long i, const VectorR3& u );
void Set(long i, double val) { assert(0 <= i && i < length), *(x + i) = val; }
void SetTriple(long i, const VectorR3& u);
VectorRn& operator+=( const VectorRn& src );
VectorRn& operator-=( const VectorRn& src );
void AddScaled (const VectorRn& src, double scaleFactor );
VectorRn& operator+=(const VectorRn& src);
VectorRn& operator-=(const VectorRn& src);
void AddScaled(const VectorRn& src, double scaleFactor);
VectorRn& operator*=( double f );
VectorRn& operator*=(double f);
double NormSq() const;
double Norm() const { return sqrt(NormSq()); }
double MaxAbs() const;
private:
long length; // Logical or actual length
long AllocLength; // Allocated length
double *x; // Array of vector entries
static VectorRn WorkVector; // Serves as a temporary vector
private:
long length; // Logical or actual length
long AllocLength; // Allocated length
double* x; // Array of vector entries
static VectorRn WorkVector; // Serves as a temporary vector
static VectorRn& GetWorkVector() { return WorkVector; }
static VectorRn& GetWorkVector( long len ) { WorkVector.SetLength(len); return WorkVector; }
static VectorRn& GetWorkVector(long len)
{
WorkVector.SetLength(len);
return WorkVector;
}
};
inline VectorRn::VectorRn()
inline VectorRn::VectorRn()
{
length = 0;
AllocLength = 0;
x = 0;
}
inline VectorRn::VectorRn( long initLength )
inline VectorRn::VectorRn(long initLength)
{
length = 0;
AllocLength = 0;
x = 0;
SetLength( initLength );
SetLength(initLength);
}
inline VectorRn::~VectorRn()
inline VectorRn::~VectorRn()
{
delete[] x;
}
// Resize.
// Resize.
// If the array is shortened, the information about the allocated length is lost.
inline void VectorRn::SetLength( long newLength )
inline void VectorRn::SetLength(long newLength)
{
assert ( newLength>0 );
if ( newLength>AllocLength ) {
assert(newLength > 0);
if (newLength > AllocLength)
{
delete[] x;
AllocLength = Max( newLength, AllocLength<<1 );
AllocLength = Max(newLength, AllocLength << 1);
x = new double[AllocLength];
}
length = newLength;
}
}
// Zero out the entire vector
inline void VectorRn::SetZero()
{
double* target = x;
for ( long i=length; i>0; i-- ) {
for (long i = length; i > 0; i--)
{
*(target++) = 0.0;
}
}
// Set the value of the i-th triple of entries in the vector
inline void VectorRn::SetTriple( long i, const VectorR3& u )
inline void VectorRn::SetTriple(long i, const VectorR3& u)
{
long j = 3*i;
assert ( 0<=j && j+2 < length );
u.Dump( x+j );
long j = 3 * i;
assert(0 <= j && j + 2 < length);
u.Dump(x + j);
}
inline void VectorRn::Fill( double d )
inline void VectorRn::Fill(double d)
{
double *to = x;
for ( long i=length; i>0; i-- ) {
double* to = x;
for (long i = length; i > 0; i--)
{
*(to++) = d;
}
}
inline void VectorRn::Load( const double* d )
inline void VectorRn::Load(const double* d)
{
double *to = x;
for ( long i=length; i>0; i-- ) {
double* to = x;
for (long i = length; i > 0; i--)
{
*(to++) = *(d++);
}
}
inline void VectorRn::LoadScaled( const double* d, double scaleFactor )
inline void VectorRn::LoadScaled(const double* d, double scaleFactor)
{
double *to = x;
for ( long i=length; i>0; i-- ) {
*(to++) = (*(d++))*scaleFactor;
double* to = x;
for (long i = length; i > 0; i--)
{
*(to++) = (*(d++)) * scaleFactor;
}
}
inline void VectorRn::Set( const VectorRn& src )
inline void VectorRn::Set(const VectorRn& src)
{
assert ( src.length == this->length );
assert(src.length == this->length);
double* to = x;
double* from = src.x;
for ( long i=length; i>0; i-- ) {
for (long i = length; i > 0; i--)
{
*(to++) = *(from++);
}
}
inline VectorRn& VectorRn::operator+=( const VectorRn& src )
inline VectorRn& VectorRn::operator+=(const VectorRn& src)
{
assert ( src.length == this->length );
assert(src.length == this->length);
double* to = x;
double* from = src.x;
for ( long i=length; i>0; i-- ) {
for (long i = length; i > 0; i--)
{
*(to++) += *(from++);
}
return *this;
}
inline VectorRn& VectorRn::operator-=( const VectorRn& src )
inline VectorRn& VectorRn::operator-=(const VectorRn& src)
{
assert ( src.length == this->length );
assert(src.length == this->length);
double* to = x;
double* from = src.x;
for ( long i=length; i>0; i-- ) {
for (long i = length; i > 0; i--)
{
*(to++) -= *(from++);
}
return *this;
}
inline void VectorRn::AddScaled (const VectorRn& src, double scaleFactor )
inline void VectorRn::AddScaled(const VectorRn& src, double scaleFactor)
{
assert ( src.length == this->length );
assert(src.length == this->length);
double* to = x;
double* from = src.x;
for ( long i=length; i>0; i-- ) {
*(to++) += (*(from++))*scaleFactor;
for (long i = length; i > 0; i--)
{
*(to++) += (*(from++)) * scaleFactor;
}
}
inline VectorRn& VectorRn::operator*=( double f )
inline VectorRn& VectorRn::operator*=(double f)
{
double* target = x;
for ( long i=length; i>0; i-- ) {
for (long i = length; i > 0; i--)
{
*(target++) *= f;
}
return *this;
}
inline double VectorRn::NormSq() const
inline double VectorRn::NormSq() const
{
double* target = x;
double res = 0.0;
for ( long i=length; i>0; i-- ) {
res += (*target)*(*target);
for (long i = length; i > 0; i--)
{
res += (*target) * (*target);
target++;
}
return res;
}
inline double Dot( const VectorRn& u, const VectorRn& v )
inline double Dot(const VectorRn& u, const VectorRn& v)
{
assert ( u.GetLength() == v.GetLength() );
assert(u.GetLength() == v.GetLength());
double res = 0.0;
const double* p = u.GetPtr();
const double* q = v.GetPtr();
for ( long i = u.GetLength(); i>0; i-- ) {
res += (*(p++))*(*(q++));
for (long i = u.GetLength(); i > 0; i--)
{
res += (*(p++)) * (*(q++));
}
return res;
}
#endif //VECTOR_RN_H
#endif //VECTOR_RN_H

View File

@@ -9,71 +9,69 @@
#define GWEN_ALIGN_H
#include "Gwen/Controls/Base.h"
namespace Gwen
namespace Gwen
{
namespace Align
{
inline void Center( Controls::Base* ctrl )
{
Controls::Base* parent = ctrl->GetParent();
if ( !parent ) return;
namespace Align
{
inline void Center(Controls::Base* ctrl)
{
Controls::Base* parent = ctrl->GetParent();
if (!parent) return;
ctrl->SetPos( parent->GetPadding().left + (((parent->Width()-parent->GetPadding().left-parent->GetPadding().right) - ctrl->Width()) / 2),
(parent->Height() - ctrl->Height()) / 2 );
}
inline void AlignLeft( Controls::Base* ctrl )
{
Controls::Base* parent = ctrl->GetParent();
if ( !parent ) return;
ctrl->SetPos( parent->GetPadding().left, ctrl->Y() );
}
inline void CenterHorizontally( Controls::Base* ctrl )
{
Controls::Base* parent = ctrl->GetParent();
if ( !parent ) return;
ctrl->SetPos( parent->GetPadding().left + (((parent->Width()-parent->GetPadding().left-parent->GetPadding().right) - ctrl->Width()) / 2), ctrl->Y() );
}
inline void AlignRight( Controls::Base* ctrl )
{
Controls::Base* parent = ctrl->GetParent();
if ( !parent ) return;
ctrl->SetPos( parent->Width() - ctrl->Width() - parent->GetPadding().right, ctrl->Y() );
}
inline void AlignTop( Controls::Base* ctrl )
{
ctrl->SetPos( ctrl->X(), 0 );
}
inline void CenterVertically( Controls::Base* ctrl )
{
Controls::Base* parent = ctrl->GetParent();
if ( !parent ) return;
ctrl->SetPos( ctrl->X(), (parent->Height() - ctrl->Height()) / 2 );
}
inline void AlignBottom( Controls::Base* ctrl )
{
Controls::Base* parent = ctrl->GetParent();
if ( !parent ) return;
ctrl->SetPos( ctrl->X(), parent->Height() - ctrl->Height() );
}
inline void PlaceBelow( Controls::Base* ctrl, Controls::Base* below, int iBorder = 0 )
{
ctrl->SetPos( ctrl->X(), below->Bottom() + iBorder );
}
}
ctrl->SetPos(parent->GetPadding().left + (((parent->Width() - parent->GetPadding().left - parent->GetPadding().right) - ctrl->Width()) / 2),
(parent->Height() - ctrl->Height()) / 2);
}
inline void AlignLeft(Controls::Base* ctrl)
{
Controls::Base* parent = ctrl->GetParent();
if (!parent) return;
ctrl->SetPos(parent->GetPadding().left, ctrl->Y());
}
inline void CenterHorizontally(Controls::Base* ctrl)
{
Controls::Base* parent = ctrl->GetParent();
if (!parent) return;
ctrl->SetPos(parent->GetPadding().left + (((parent->Width() - parent->GetPadding().left - parent->GetPadding().right) - ctrl->Width()) / 2), ctrl->Y());
}
inline void AlignRight(Controls::Base* ctrl)
{
Controls::Base* parent = ctrl->GetParent();
if (!parent) return;
ctrl->SetPos(parent->Width() - ctrl->Width() - parent->GetPadding().right, ctrl->Y());
}
inline void AlignTop(Controls::Base* ctrl)
{
ctrl->SetPos(ctrl->X(), 0);
}
inline void CenterVertically(Controls::Base* ctrl)
{
Controls::Base* parent = ctrl->GetParent();
if (!parent) return;
ctrl->SetPos(ctrl->X(), (parent->Height() - ctrl->Height()) / 2);
}
inline void AlignBottom(Controls::Base* ctrl)
{
Controls::Base* parent = ctrl->GetParent();
if (!parent) return;
ctrl->SetPos(ctrl->X(), parent->Height() - ctrl->Height());
}
inline void PlaceBelow(Controls::Base* ctrl, Controls::Base* below, int iBorder = 0)
{
ctrl->SetPos(ctrl->X(), below->Bottom() + iBorder);
}
} // namespace Align
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Anim.h"
#include "Gwen/Utility.h"
#include <math.h>
@@ -13,17 +12,17 @@ using namespace Gwen;
#ifndef GWEN_NO_ANIMATION
static Gwen::Anim::Animation::List g_Animations;
static Gwen::Anim::Animation::List g_Animations;
static Gwen::Anim::Animation::ChildList g_AnimationsListed;
void Gwen::Anim::Add( Gwen::Controls::Base* control, Animation* animation )
void Gwen::Anim::Add(Gwen::Controls::Base* control, Animation* animation)
{
animation->m_Control = control;
g_Animations[control].push_back( animation );
g_Animations[control].push_back(animation);
}
void Gwen::Anim::Cancel( Gwen::Controls::Base* control )
void Gwen::Anim::Cancel(Gwen::Controls::Base* control)
{
/* cannot use std::list iterator with algoryhtmns based on pointers
struct AnimDeletePredicate
@@ -46,14 +45,14 @@ void Gwen::Anim::Cancel( Gwen::Controls::Base* control )
Gwen::Anim::Animation::List::iterator iAnimations;
if ((iAnimations = g_Animations.find(control)) != g_Animations.end())
{
Gwen::Anim::Animation::ChildList &ChildAnimationsForControl = iAnimations->second;
Gwen::Anim::Animation::ChildList& ChildAnimationsForControl = iAnimations->second;
Gwen::Anim::Animation::ChildList::iterator iAnimationChild = ChildAnimationsForControl.begin();
if (iAnimationChild != ChildAnimationsForControl.end())
{
do
{
delete (*iAnimationChild);
}while(++iAnimationChild != ChildAnimationsForControl.end());
} while (++iAnimationChild != ChildAnimationsForControl.end());
}
g_Animations.erase(iAnimations);
}
@@ -63,10 +62,10 @@ void Gwen::Anim::Think()
{
Gwen::Anim::Animation::List::iterator it = g_Animations.begin();
if ( it != g_Animations.end() )
if (it != g_Animations.end())
{
Gwen::Anim::Animation::ChildList::iterator itChild;
Gwen::Anim::Animation* anim;
do
@@ -79,9 +78,9 @@ void Gwen::Anim::Think()
anim->Think();
if ( anim->Finished() )
if (anim->Finished())
{
itChild = it->second.erase( itChild );
itChild = it->second.erase(itChild);
delete anim;
}
@@ -90,15 +89,14 @@ void Gwen::Anim::Think()
++itChild;
}
}while(itChild != it->second.end());
} while (itChild != it->second.end());
}
}while(++it != g_Animations.end());
}
} while (++it != g_Animations.end());
}
}
Gwen::Anim::TimedAnimation::TimedAnimation( float fLength, float fDelay, float fEase )
Gwen::Anim::TimedAnimation::TimedAnimation(float fLength, float fDelay, float fEase)
{
m_fStart = Platform::GetTimeInSeconds() + fDelay;
m_fEnd = m_fStart + fLength;
@@ -109,25 +107,25 @@ Gwen::Anim::TimedAnimation::TimedAnimation( float fLength, float fDelay, float f
void Gwen::Anim::TimedAnimation::Think()
{
if ( m_bFinished ) return;
if (m_bFinished) return;
float fCurrent = Platform::GetTimeInSeconds();
float fSecondsIn = fCurrent - m_fStart;
if ( fSecondsIn < 0.0f ) return;
if (fSecondsIn < 0.0f) return;
if ( !m_bStarted )
if (!m_bStarted)
{
m_bStarted = true;
OnStart();
}
float fDelta = fSecondsIn / ( m_fEnd - m_fStart );
if ( fDelta < 0.0f ) fDelta = 0.0f;
if ( fDelta > 1.0f ) fDelta = 1.0f;
float fDelta = fSecondsIn / (m_fEnd - m_fStart);
if (fDelta < 0.0f) fDelta = 0.0f;
if (fDelta > 1.0f) fDelta = 1.0f;
Run( pow( fDelta, m_fEase ) );
Run(pow(fDelta, m_fEase));
if ( fDelta == 1.0f )
if (fDelta == 1.0f)
{
m_bFinished = true;
OnFinish();

View File

@@ -13,118 +13,117 @@
#ifndef GWEN_NO_ANIMATION
namespace Gwen
namespace Gwen
{
namespace Anim
namespace Anim
{
class GWEN_EXPORT Animation
{
public:
typedef std::list<Animation*> ChildList;
typedef std::map<Gwen::Controls::Base*, ChildList> List;
virtual void Think() = 0;
virtual bool Finished() = 0;
virtual ~Animation() {}
Gwen::Controls::Base* m_Control;
};
GWEN_EXPORT void Add(Gwen::Controls::Base* control, Animation* animation);
GWEN_EXPORT void Cancel(Gwen::Controls::Base* control);
GWEN_EXPORT void Think();
//
// Timed animation. Provides a useful base for animations.
//
class GWEN_EXPORT TimedAnimation : public Animation
{
public:
TimedAnimation(float fLength, float fDelay = 0.0f, float fEase = 1.0f);
virtual void Think();
virtual bool Finished();
//
// These are the magic functions you should be overriding
//
virtual void OnStart() {}
virtual void Run(float /*delta*/) {}
virtual void OnFinish() {}
protected:
bool m_bStarted;
bool m_bFinished;
float m_fStart;
float m_fEnd;
float m_fEase;
};
namespace Size
{
class GWEN_EXPORT Height : public TimedAnimation
{
public:
Height(int iStartSize, int iEndSize, float fLength, bool bHide = false, float fDelay = 0.0f, float fEase = 1.0f) : TimedAnimation(fLength, fDelay, fEase)
{
class GWEN_EXPORT Animation
{
public:
typedef std::list<Animation*> ChildList;
typedef std::map< Gwen::Controls::Base *, ChildList > List;
virtual void Think() = 0;
virtual bool Finished() = 0;
virtual ~Animation() {}
Gwen::Controls::Base* m_Control;
};
GWEN_EXPORT void Add( Gwen::Controls::Base* control, Animation* animation );
GWEN_EXPORT void Cancel( Gwen::Controls::Base* control );
GWEN_EXPORT void Think();
//
// Timed animation. Provides a useful base for animations.
//
class GWEN_EXPORT TimedAnimation : public Animation
{
public:
TimedAnimation( float fLength, float fDelay = 0.0f, float fEase = 1.0f );
virtual void Think();
virtual bool Finished();
//
// These are the magic functions you should be overriding
//
virtual void OnStart(){}
virtual void Run( float /*delta*/ ){}
virtual void OnFinish(){}
protected:
bool m_bStarted;
bool m_bFinished;
float m_fStart;
float m_fEnd;
float m_fEase;
};
namespace Size
{
class GWEN_EXPORT Height : public TimedAnimation
{
public:
Height( int iStartSize, int iEndSize, float fLength, bool bHide = false, float fDelay = 0.0f, float fEase = 1.0f ) : TimedAnimation( fLength, fDelay, fEase )
{
m_iStartSize = iStartSize;
m_iDelta = iEndSize - m_iStartSize;
m_bHide = bHide;
}
virtual void OnStart(){ m_Control->SetHeight( m_iStartSize ); }
virtual void Run( float delta ){ m_Control->SetHeight( m_iStartSize + (((float)m_iDelta) * delta) ); }
virtual void OnFinish(){ m_Control->SetHeight( m_iStartSize + m_iDelta ); m_Control->SetHidden( m_bHide ); }
protected:
int m_iStartSize;
int m_iDelta;
bool m_bHide;
};
class Width : public TimedAnimation
{
public:
Width( int iStartSize, int iEndSize, float fLength, bool bHide = false, float fDelay = 0.0f, float fEase = 1.0f ) : TimedAnimation( fLength, fDelay, fEase )
{
m_iStartSize = iStartSize;
m_iDelta = iEndSize - m_iStartSize;
m_bHide = bHide;
}
virtual void OnStart(){ m_Control->SetWidth( m_iStartSize ); }
virtual void Run( float delta ){ m_Control->SetWidth( m_iStartSize + (((float)m_iDelta) * delta) ); }
virtual void OnFinish(){ m_Control->SetWidth( m_iStartSize + m_iDelta ); m_Control->SetHidden( m_bHide ); }
protected:
int m_iStartSize;
int m_iDelta;
bool m_bHide;
};
}
namespace Tools
{
class Remove : public TimedAnimation
{
public:
Remove( float fDelay = 0.0f ) : TimedAnimation( 0.0f, fDelay ){}
virtual void OnFinish(){ m_Control->DelayedDelete(); }
};
}
m_iStartSize = iStartSize;
m_iDelta = iEndSize - m_iStartSize;
m_bHide = bHide;
}
}
virtual void OnStart() { m_Control->SetHeight(m_iStartSize); }
virtual void Run(float delta) { m_Control->SetHeight(m_iStartSize + (((float)m_iDelta) * delta)); }
virtual void OnFinish()
{
m_Control->SetHeight(m_iStartSize + m_iDelta);
m_Control->SetHidden(m_bHide);
}
protected:
int m_iStartSize;
int m_iDelta;
bool m_bHide;
};
class Width : public TimedAnimation
{
public:
Width(int iStartSize, int iEndSize, float fLength, bool bHide = false, float fDelay = 0.0f, float fEase = 1.0f) : TimedAnimation(fLength, fDelay, fEase)
{
m_iStartSize = iStartSize;
m_iDelta = iEndSize - m_iStartSize;
m_bHide = bHide;
}
virtual void OnStart() { m_Control->SetWidth(m_iStartSize); }
virtual void Run(float delta) { m_Control->SetWidth(m_iStartSize + (((float)m_iDelta) * delta)); }
virtual void OnFinish()
{
m_Control->SetWidth(m_iStartSize + m_iDelta);
m_Control->SetHidden(m_bHide);
}
protected:
int m_iStartSize;
int m_iDelta;
bool m_bHide;
};
} // namespace Size
namespace Tools
{
class Remove : public TimedAnimation
{
public:
Remove(float fDelay = 0.0f) : TimedAnimation(0.0f, fDelay) {}
virtual void OnFinish() { m_Control->DelayedDelete(); }
};
} // namespace Tools
} // namespace Anim
} // namespace Gwen
#endif
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/BaseRender.h"
#include "Gwen/Utility.h"
@@ -14,208 +13,205 @@
namespace Gwen
{
namespace Renderer
namespace Renderer
{
Base::Base()
{
m_RenderOffset = Gwen::Point(0, 0);
m_fScale = 1.0f;
}
Base::~Base()
{
if (GetCTT())
GetCTT()->ShutDown();
}
void Base::RenderText(Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text)
{
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(text);
RenderText(pFont, pos, str);
}
Gwen::Point Base::MeasureText(Gwen::Font* pFont, const Gwen::String& text)
{
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(text);
return MeasureText(pFont, str);
}
void Base::DrawLinedRect(Gwen::Rect rect)
{
DrawFilledRect(Gwen::Rect(rect.x, rect.y, rect.w, 1));
DrawFilledRect(Gwen::Rect(rect.x, rect.y + rect.h - 1, rect.w, 1));
DrawFilledRect(Gwen::Rect(rect.x, rect.y, 1, rect.h));
DrawFilledRect(Gwen::Rect(rect.x + rect.w - 1, rect.y, 1, rect.h));
};
void Base::DrawPixel(int x, int y)
{
DrawFilledRect(Gwen::Rect(x, y, 1, 1));
}
void Base::DrawShavedCornerRect(Gwen::Rect rect, bool bSlight)
{
// Draw INSIDE the w/h.
rect.w -= 1;
rect.h -= 1;
if (bSlight)
{
DrawFilledRect(Gwen::Rect(rect.x + 1, rect.y, rect.w - 1, 1));
DrawFilledRect(Gwen::Rect(rect.x + 1, rect.y + rect.h, rect.w - 1, 1));
Base::Base()
{
m_RenderOffset = Gwen::Point( 0, 0 );
m_fScale = 1.0f;
}
DrawFilledRect(Gwen::Rect(rect.x, rect.y + 1, 1, rect.h - 1));
DrawFilledRect(Gwen::Rect(rect.x + rect.w, rect.y + 1, 1, rect.h - 1));
return;
}
Base::~Base()
{
if ( GetCTT() )
GetCTT()->ShutDown();
}
DrawPixel(rect.x + 1, rect.y + 1);
DrawPixel(rect.x + rect.w - 1, rect.y + 1);
void Base::RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text )
{
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode( text );
RenderText( pFont, pos, str );
}
DrawPixel(rect.x + 1, rect.y + rect.h - 1);
DrawPixel(rect.x + rect.w - 1, rect.y + rect.h - 1);
Gwen::Point Base::MeasureText( Gwen::Font* pFont, const Gwen::String& text )
{
Gwen::UnicodeString str = Gwen::Utility::StringToUnicode( text );
return MeasureText( pFont, str );
}
void Base::DrawLinedRect( Gwen::Rect rect )
{
DrawFilledRect( Gwen::Rect( rect.x, rect.y, rect.w, 1 ) );
DrawFilledRect( Gwen::Rect( rect.x, rect.y + rect.h-1, rect.w, 1 ) );
DrawFilledRect(Gwen::Rect(rect.x + 2, rect.y, rect.w - 3, 1));
DrawFilledRect(Gwen::Rect(rect.x + 2, rect.y + rect.h, rect.w - 3, 1));
DrawFilledRect( Gwen::Rect( rect.x, rect.y, 1, rect.h ) );
DrawFilledRect( Gwen::Rect( rect.x + rect.w-1, rect.y, 1, rect.h ) );
};
DrawFilledRect(Gwen::Rect(rect.x, rect.y + 2, 1, rect.h - 3));
DrawFilledRect(Gwen::Rect(rect.x + rect.w, rect.y + 2, 1, rect.h - 3));
}
void Base::DrawPixel( int x, int y )
{
DrawFilledRect( Gwen::Rect( x, y, 1, 1 ) );
}
void Base::Translate(int& x, int& y)
{
x += m_RenderOffset.x;
y += m_RenderOffset.y;
void Base::DrawShavedCornerRect( Gwen::Rect rect, bool bSlight )
{
// Draw INSIDE the w/h.
rect.w -= 1;
rect.h -= 1;
x = ceil(((float)x) * m_fScale);
y = ceil(((float)y) * m_fScale);
}
if ( bSlight )
{
DrawFilledRect( Gwen::Rect( rect.x+1, rect.y, rect.w-1, 1 ) );
DrawFilledRect( Gwen::Rect( rect.x+1, rect.y + rect.h, rect.w-1, 1 ) );
void Base::Translate(Gwen::Rect& rect)
{
Translate(rect.x, rect.y);
DrawFilledRect( Gwen::Rect( rect.x, rect.y+1, 1, rect.h-1 ) );
DrawFilledRect( Gwen::Rect( rect.x + rect.w, rect.y+1, 1, rect.h-1 ) );
return;
}
rect.w = ceil(((float)rect.w) * m_fScale);
rect.h = ceil(((float)rect.h) * m_fScale);
}
DrawPixel( rect.x+1, rect.y+1 );
DrawPixel( rect.x+rect.w-1, rect.y+1 );
void Gwen::Renderer::Base::SetClipRegion(Gwen::Rect rect)
{
m_rectClipRegion = rect;
}
DrawPixel( rect.x+1, rect.y+rect.h-1 );
DrawPixel( rect.x+rect.w-1, rect.y+rect.h-1 );
void Base::AddClipRegion(Gwen::Rect rect)
{
rect.x = m_RenderOffset.x;
rect.y = m_RenderOffset.y;
DrawFilledRect( Gwen::Rect( rect.x+2, rect.y, rect.w-3, 1 ) );
DrawFilledRect( Gwen::Rect( rect.x+2, rect.y + rect.h, rect.w-3, 1 ) );
Gwen::Rect out = rect;
if (rect.x < m_rectClipRegion.x)
{
out.w -= (m_rectClipRegion.x - out.x);
out.x = m_rectClipRegion.x;
}
DrawFilledRect( Gwen::Rect( rect.x, rect.y+2, 1, rect.h-3 ) );
DrawFilledRect( Gwen::Rect( rect.x + rect.w, rect.y+2, 1, rect.h-3 ) );
}
if (rect.y < m_rectClipRegion.y)
{
out.h -= (m_rectClipRegion.y - out.y);
out.y = m_rectClipRegion.y;
}
void Base::Translate( int& x, int& y )
{
x += m_RenderOffset.x;
y += m_RenderOffset.y;
if (rect.x + rect.w > m_rectClipRegion.x + m_rectClipRegion.w)
{
out.w = (m_rectClipRegion.x + m_rectClipRegion.w) - out.x;
}
x = ceil( ((float) x ) * m_fScale );
y = ceil( ((float) y ) * m_fScale );
}
if (rect.y + rect.h > m_rectClipRegion.y + m_rectClipRegion.h)
{
out.h = (m_rectClipRegion.y + m_rectClipRegion.h) - out.y;
}
void Base::Translate( Gwen::Rect& rect )
{
Translate( rect.x, rect.y );
m_rectClipRegion = out;
}
rect.w = ceil(((float) rect.w ) * m_fScale);
rect.h = ceil(((float) rect.h ) * m_fScale);
}
const Gwen::Rect& Base::ClipRegion() const
{
return m_rectClipRegion;
}
void Gwen::Renderer::Base::SetClipRegion( Gwen::Rect rect )
{
m_rectClipRegion = rect;
}
bool Base::ClipRegionVisible()
{
if (m_rectClipRegion.w <= 0 || m_rectClipRegion.h <= 0)
return false;
void Base::AddClipRegion( Gwen::Rect rect )
{
rect.x = m_RenderOffset.x;
rect.y = m_RenderOffset.y;
return true;
}
Gwen::Rect out = rect;
if ( rect.x < m_rectClipRegion.x )
{
out.w -= ( m_rectClipRegion.x - out.x );
out.x = m_rectClipRegion.x;
}
void Base::DrawMissingImage(Gwen::Rect pTargetRect)
{
SetDrawColor(Colors::Red);
DrawFilledRect(pTargetRect);
}
if ( rect.y < m_rectClipRegion.y )
{
out.h -= ( m_rectClipRegion.y - out.y );
out.y = m_rectClipRegion.y;
}
if ( rect.x + rect.w > m_rectClipRegion.x + m_rectClipRegion.w )
{
out.w = (m_rectClipRegion.x + m_rectClipRegion.w) - out.x;
}
if ( rect.y + rect.h > m_rectClipRegion.y + m_rectClipRegion.h )
{
out.h = (m_rectClipRegion.y + m_rectClipRegion.h) - out.y;
}
m_rectClipRegion = out;
}
const Gwen::Rect& Base::ClipRegion() const
{
return m_rectClipRegion;
}
bool Base::ClipRegionVisible()
{
if ( m_rectClipRegion.w <= 0 || m_rectClipRegion.h <= 0 )
return false;
return true;
}
void Base::DrawMissingImage( Gwen::Rect pTargetRect )
{
SetDrawColor( Colors::Red );
DrawFilledRect( pTargetRect );
}
/*
/*
If they haven't defined these font functions in their renderer code
we just draw some rects where the letters would be to give them an idea.
*/
void Base::RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text )
{
float fSize = pFont->size * Scale();
void Base::RenderText(Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text)
{
float fSize = pFont->size * Scale();
for ( float i=0; i<text.length(); i++ )
{
wchar_t chr = text[i];
for (float i = 0; i < text.length(); i++)
{
wchar_t chr = text[i];
if ( chr == ' ' ) continue;
if (chr == ' ') continue;
Gwen::Rect r( pos.x + i * fSize * 0.4, pos.y, fSize * 0.4 -1, fSize );
Gwen::Rect r(pos.x + i * fSize * 0.4, pos.y, fSize * 0.4 - 1, fSize);
/*
/*
This isn't important, it's just me messing around changing the
shape of the rect based on the letter.. just for fun.
*/
if ( chr == 'l' || chr == 'i' || chr == '!' || chr == 't' )
{
r.w = 1;
}
else if ( chr >= 'a' && chr <= 'z' )
{
r.y += fSize * 0.5f;
r.h -= fSize * 0.4f;
}
else if ( chr == '.' || chr == ',' )
{
r.x += 2;
r.y += r.h - 2;
r.w = 2;
r.h = 2;
}
else if ( chr == '\'' || chr == '`' || chr == '"' )
{
r.x += 3;
r.w = 2;
r.h = 2;
}
if ( chr == 'o' || chr == 'O' || chr == '0' )
DrawLinedRect( r );
else
DrawFilledRect( r );
}
}
Gwen::Point Base::MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text )
if (chr == 'l' || chr == 'i' || chr == '!' || chr == 't')
{
Gwen::Point p;
p.x = pFont->size * Scale() * (float)text.length() * 0.4;
p.y = pFont->size * Scale();
return p;
r.w = 1;
}
else if (chr >= 'a' && chr <= 'z')
{
r.y += fSize * 0.5f;
r.h -= fSize * 0.4f;
}
else if (chr == '.' || chr == ',')
{
r.x += 2;
r.y += r.h - 2;
r.w = 2;
r.h = 2;
}
else if (chr == '\'' || chr == '`' || chr == '"')
{
r.x += 3;
r.w = 2;
r.h = 2;
}
if (chr == 'o' || chr == 'O' || chr == '0')
DrawLinedRect(r);
else
DrawFilledRect(r);
}
}
}
Gwen::Point Base::MeasureText(Gwen::Font* pFont, const Gwen::UnicodeString& text)
{
Gwen::Point p;
p.x = pFont->size * Scale() * (float)text.length() * 0.4;
p.y = pFont->size * Scale();
return p;
}
} // namespace Renderer
} // namespace Gwen

View File

@@ -10,110 +10,108 @@
#include "Gwen/Structures.h"
namespace Gwen
namespace Gwen
{
struct Font;
struct Texture;
namespace Renderer
struct Font;
struct Texture;
namespace Renderer
{
class Base;
class ICacheToTexture
{
public:
virtual void Initialize() = 0;
virtual void ShutDown() = 0;
virtual void SetupCacheTexture(Gwen::Controls::Base* control) = 0;
virtual void FinishCacheTexture(Gwen::Controls::Base* control) = 0;
virtual void DrawCachedControlTexture(Gwen::Controls::Base* control) = 0;
virtual void CreateControlCacheTexture(Gwen::Controls::Base* control) = 0;
virtual void UpdateControlCacheTexture(Gwen::Controls::Base* control) = 0;
virtual void SetRenderer(Gwen::Renderer::Base* renderer) = 0;
};
class GWEN_EXPORT Base
{
public:
Base();
virtual ~Base();
virtual void Begin(){};
virtual void End(){};
virtual void SetDrawColor(Color color){};
virtual void DrawLine(int x, int y, int a, int b){};
virtual void DrawFilledRect(Gwen::Rect rect){};
;
virtual void StartClip(){};
virtual void EndClip(){};
virtual void LoadTexture(Gwen::Texture* pTexture){};
virtual void FreeTexture(Gwen::Texture* pTexture){};
virtual void DrawTexturedRect(Gwen::Texture* pTexture, Gwen::Rect pTargetRect, float u1 = 0.0f, float v1 = 0.0f, float u2 = 1.0f, float v2 = 1.0f){};
virtual void DrawMissingImage(Gwen::Rect pTargetRect);
virtual ICacheToTexture* GetCTT() { return NULL; }
virtual void LoadFont(Gwen::Font* pFont){};
virtual void FreeFont(Gwen::Font* pFont){};
virtual void RenderText(Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text);
virtual Gwen::Point MeasureText(Gwen::Font* pFont, const Gwen::UnicodeString& text);
//
// No need to implement these functions in your derived class, but if
// you can do them faster than the default implementation it's a good idea to.
//
virtual void DrawLinedRect(Gwen::Rect rect);
virtual void DrawPixel(int x, int y);
virtual void DrawShavedCornerRect(Gwen::Rect rect, bool bSlight = false);
virtual Gwen::Point MeasureText(Gwen::Font* pFont, const Gwen::String& text);
virtual void RenderText(Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text);
virtual void Resize(int width, int height) = 0;
public:
//
// Translate a panel's local drawing coordinate
// into view space, taking Offset's into account.
//
void Translate(int& x, int& y);
void Translate(Gwen::Rect& rect);
//
// Set the rendering offset. You shouldn't have to
// touch these, ever.
//
void SetRenderOffset(const Gwen::Point& offset) { m_RenderOffset = offset; }
void AddRenderOffset(const Gwen::Rect& offset)
{
class Base;
class ICacheToTexture
{
public:
virtual void Initialize() = 0;
virtual void ShutDown() = 0;
virtual void SetupCacheTexture( Gwen::Controls::Base* control ) = 0;
virtual void FinishCacheTexture( Gwen::Controls::Base* control ) = 0;
virtual void DrawCachedControlTexture( Gwen::Controls::Base* control ) = 0;
virtual void CreateControlCacheTexture( Gwen::Controls::Base* control ) = 0;
virtual void UpdateControlCacheTexture( Gwen::Controls::Base* control ) = 0;
virtual void SetRenderer( Gwen::Renderer::Base* renderer ) = 0;
};
class GWEN_EXPORT Base
{
public:
Base();
virtual ~Base();
virtual void Begin(){};
virtual void End(){};
virtual void SetDrawColor( Color color ){};
virtual void DrawLine( int x, int y, int a, int b ){};
virtual void DrawFilledRect( Gwen::Rect rect ){};;
virtual void StartClip(){};
virtual void EndClip(){};
virtual void LoadTexture( Gwen::Texture* pTexture ){};
virtual void FreeTexture( Gwen::Texture* pTexture ){};
virtual void DrawTexturedRect( Gwen::Texture* pTexture, Gwen::Rect pTargetRect, float u1=0.0f, float v1=0.0f, float u2=1.0f, float v2=1.0f ){};
virtual void DrawMissingImage( Gwen::Rect pTargetRect );
virtual ICacheToTexture* GetCTT() { return NULL; }
virtual void LoadFont( Gwen::Font* pFont ){};
virtual void FreeFont( Gwen::Font* pFont ){};
virtual void RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text );
virtual Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text );
//
// No need to implement these functions in your derived class, but if
// you can do them faster than the default implementation it's a good idea to.
//
virtual void DrawLinedRect( Gwen::Rect rect );
virtual void DrawPixel( int x, int y );
virtual void DrawShavedCornerRect( Gwen::Rect rect, bool bSlight = false );
virtual Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::String& text );
virtual void RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text );
virtual void Resize(int width, int height)=0;
public:
//
// Translate a panel's local drawing coordinate
// into view space, taking Offset's into account.
//
void Translate( int& x, int& y );
void Translate( Gwen::Rect& rect );
//
// Set the rendering offset. You shouldn't have to
// touch these, ever.
//
void SetRenderOffset( const Gwen::Point& offset ){ m_RenderOffset = offset; }
void AddRenderOffset( const Gwen::Rect& offset ){ m_RenderOffset.x += offset.x; m_RenderOffset.y += offset.y; }
const Gwen::Point& GetRenderOffset() const { return m_RenderOffset; }
private:
Gwen::Point m_RenderOffset;
public:
void SetClipRegion( Gwen::Rect rect );
void AddClipRegion( Gwen::Rect rect );
bool ClipRegionVisible();
const Gwen::Rect& ClipRegion() const;
private:
Gwen::Rect m_rectClipRegion;
public:
void SetScale( float fScale ){ m_fScale = fScale; }
float Scale() const { return m_fScale; }
float m_fScale;
};
m_RenderOffset.x += offset.x;
m_RenderOffset.y += offset.y;
}
}
const Gwen::Point& GetRenderOffset() const { return m_RenderOffset; }
private:
Gwen::Point m_RenderOffset;
public:
void SetClipRegion(Gwen::Rect rect);
void AddClipRegion(Gwen::Rect rect);
bool ClipRegionVisible();
const Gwen::Rect& ClipRegion() const;
private:
Gwen::Rect m_rectClipRegion;
public:
void SetScale(float fScale) { m_fScale = fScale; }
float Scale() const { return m_fScale; }
float m_fScale;
};
} // namespace Renderer
} // namespace Gwen
#endif

View File

@@ -11,6 +11,6 @@
//
// Disables animation functions.
//
//#define GWEN_NO_ANIMATION
//#define GWEN_NO_ANIMATION
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
#include "Gwen/Controls/Button.h"
@@ -13,54 +12,53 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( Button )
GWEN_CONTROL_CONSTRUCTOR(Button)
{
m_Image = NULL;
m_bDepressed = false;
m_bCenterImage = false;
SetSize( 100, 20 );
SetMouseInputEnabled( true );
SetIsToggle( false );
SetAlignment( Gwen::Pos::Center );
SetTextPadding( Padding( 3, 0, 3, 0 ) );
SetSize(100, 20);
SetMouseInputEnabled(true);
SetIsToggle(false);
SetAlignment(Gwen::Pos::Center);
SetTextPadding(Padding(3, 0, 3, 0));
m_bToggleStatus = false;
SetKeyboardInputEnabled( false );
SetTabable( false );
SetKeyboardInputEnabled(false);
SetTabable(false);
}
void Button::Render( Skin::Base* skin )
void Button::Render(Skin::Base* skin)
{
if ( ShouldDrawBackground() )
if (ShouldDrawBackground())
{
bool bDrawDepressed = IsDepressed() && IsHovered();
if ( IsToggle() ) bDrawDepressed = bDrawDepressed || GetToggleState();
if (IsToggle()) bDrawDepressed = bDrawDepressed || GetToggleState();
bool bDrawHovered = IsHovered() && ShouldDrawHover();
skin->DrawButton( this, bDrawDepressed, bDrawHovered );
skin->DrawButton(this, bDrawDepressed, bDrawHovered);
}
}
void Button::OnMouseClickLeft( int /*x*/, int /*y*/, bool bDown )
void Button::OnMouseClickLeft(int /*x*/, int /*y*/, bool bDown)
{
if ( bDown )
if (bDown)
{
m_bDepressed = true;
Gwen::MouseFocus = this;
onDown.Call( this );
onDown.Call(this);
}
else
{
if ( IsHovered() && m_bDepressed )
if (IsHovered() && m_bDepressed)
{
OnPress();
}
m_bDepressed = false;
Gwen::MouseFocus = NULL;
onUp.Call( this );
onUp.Call(this);
}
Redraw();
@@ -68,60 +66,59 @@ void Button::OnMouseClickLeft( int /*x*/, int /*y*/, bool bDown )
void Button::OnPress()
{
if ( IsToggle() )
if (IsToggle())
{
SetToggleState( !GetToggleState() );
SetToggleState(!GetToggleState());
}
onPress.Call( this );
onPress.Call(this);
}
void Button::SetImage( const TextObject& strName, bool bCenter )
void Button::SetImage(const TextObject& strName, bool bCenter)
{
if ( strName.GetUnicode() == L"" )
if (strName.GetUnicode() == L"")
{
if ( m_Image )
if (m_Image)
{
delete m_Image;
m_Image= NULL;
m_Image = NULL;
}
return;
}
if ( !m_Image )
if (!m_Image)
{
m_Image = new ImagePanel( this );
m_Image = new ImagePanel(this);
}
m_Image->SetImage( strName );
m_Image->SetImage(strName);
m_Image->SizeToContents();
m_Image->SetPos( m_Padding.left, 2 );
m_Image->SetPos(m_Padding.left, 2);
m_bCenterImage = bCenter;
int IdealTextPadding = m_Image->Right() + m_Padding.left + 4;
if ( m_rTextPadding.left < IdealTextPadding )
if (m_rTextPadding.left < IdealTextPadding)
{
m_rTextPadding.left = IdealTextPadding;
}
}
void Button::SetToggleState( bool b )
{
if ( m_bToggleStatus == b ) return;
void Button::SetToggleState(bool b)
{
if (m_bToggleStatus == b) return;
m_bToggleStatus = b;
onToggle.Call( this );
onToggle.Call(this);
if ( m_bToggleStatus )
if (m_bToggleStatus)
{
onToggleOn.Call( this );
onToggleOn.Call(this);
}
else
{
onToggleOff.Call( this );
onToggleOff.Call(this);
}
}
@@ -129,19 +126,19 @@ void Button::SizeToContents()
{
BaseClass::SizeToContents();
if ( m_Image )
if (m_Image)
{
int height = m_Image->Height() + 4;
if ( Height() < height )
if (Height() < height)
{
SetHeight( height );
SetHeight(height);
}
}
}
bool Button::OnKeySpace( bool bDown )
bool Button::OnKeySpace(bool bDown)
{
OnMouseClickLeft( 0, 0, bDown );
OnMouseClickLeft(0, 0, bDown);
return true;
}
@@ -150,20 +147,20 @@ void Button::AcceleratePressed()
OnPress();
}
void Button::Layout( Skin::Base* pSkin )
{
BaseClass::Layout( pSkin );
if ( m_Image )
{
Gwen::Align::CenterVertically( m_Image );
void Button::Layout(Skin::Base* pSkin)
{
BaseClass::Layout(pSkin);
if (m_Image)
{
Gwen::Align::CenterVertically(m_Image);
if ( m_bCenterImage )
Gwen::Align::CenterHorizontally( m_Image );
if (m_bCenterImage)
Gwen::Align::CenterHorizontally(m_Image);
}
}
void Button::OnMouseDoubleClickLeft( int x, int y )
{
OnMouseClickLeft( x, y, true );
onDoubleClick.Call( this );
void Button::OnMouseDoubleClickLeft(int x, int y)
{
OnMouseClickLeft(x, y, true);
onDoubleClick.Call(this);
};

View File

@@ -12,79 +12,75 @@
#include "Gwen/Controls/Base.h"
#include "Gwen/Controls/Label.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class ImagePanel;
class GWEN_EXPORT Button : public Label
{
public:
GWEN_CONTROL(Button, Label);
virtual void Render(Skin::Base* skin);
virtual void OnMouseClickLeft(int x, int y, bool bDown);
virtual void OnMouseDoubleClickLeft(int x, int y);
virtual bool OnKeySpace(bool bDown);
virtual void OnPress();
virtual void AcceleratePressed();
virtual bool IsDepressed() const { return m_bDepressed; }
//
// Buttons can be toggle type, which means that it is
// toggled on and off. Its toggle status is in IsDepressed.
//
virtual void SetIsToggle(bool b) { m_bToggle = b; }
virtual bool IsToggle() const { return m_bToggle; }
virtual bool GetToggleState() const { return m_bToggleStatus; }
virtual void SetToggleState(bool b);
virtual void Toggle() { SetToggleState(!GetToggleState()); }
virtual void SetImage(const TextObject& strName, bool bCenter = false);
// You can use this to trigger OnPress directly from other controls using GWEN_CALL_EX
virtual void ReceiveEventPress(Base* /*pControl*/)
{
class ImagePanel;
class GWEN_EXPORT Button : public Label
{
public:
GWEN_CONTROL( Button, Label );
virtual void Render( Skin::Base* skin );
virtual void OnMouseClickLeft( int x, int y, bool bDown );
virtual void OnMouseDoubleClickLeft( int x, int y );
virtual bool OnKeySpace( bool bDown );
virtual void OnPress();
virtual void AcceleratePressed();
virtual bool IsDepressed() const { return m_bDepressed; }
//
// Buttons can be toggle type, which means that it is
// toggled on and off. Its toggle status is in IsDepressed.
//
virtual void SetIsToggle( bool b ){ m_bToggle = b; }
virtual bool IsToggle() const { return m_bToggle; }
virtual bool GetToggleState() const { return m_bToggleStatus; }
virtual void SetToggleState( bool b );
virtual void Toggle(){ SetToggleState( !GetToggleState() ); }
virtual void SetImage( const TextObject& strName, bool bCenter = false );
// You can use this to trigger OnPress directly from other controls using GWEN_CALL_EX
virtual void ReceiveEventPress( Base* /*pControl*/ )
{
OnPress();
}
virtual void SizeToContents();
virtual void Layout( Skin::Base* pSkin );
virtual bool OnKeyReturn(bool bDown)
{
onKeyboardReturn.Call(this);
return true;
}
public:
Gwen::Event::Caller onPress;
Gwen::Event::Caller onDown;
Gwen::Event::Caller onUp;
Gwen::Event::Caller onDoubleClick;
Gwen::Event::Caller onKeyboardReturn;
Gwen::Event::Caller onToggle;
Gwen::Event::Caller onToggleOn;
Gwen::Event::Caller onToggleOff;
protected:
ImagePanel* m_Image;
bool m_bDepressed;
bool m_bToggle;
bool m_bToggleStatus;
bool m_bCenterImage;
};
OnPress();
}
}
virtual void SizeToContents();
virtual void Layout(Skin::Base* pSkin);
virtual bool OnKeyReturn(bool bDown)
{
onKeyboardReturn.Call(this);
return true;
}
public:
Gwen::Event::Caller onPress;
Gwen::Event::Caller onDown;
Gwen::Event::Caller onUp;
Gwen::Event::Caller onDoubleClick;
Gwen::Event::Caller onKeyboardReturn;
Gwen::Event::Caller onToggle;
Gwen::Event::Caller onToggleOn;
Gwen::Event::Caller onToggleOff;
protected:
ImagePanel* m_Image;
bool m_bDepressed;
bool m_bToggle;
bool m_bToggleStatus;
bool m_bCenterImage;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Controls/Canvas.h"
#include "Gwen/Skin.h"
@@ -18,14 +17,13 @@
using namespace Gwen::Controls;
Canvas::Canvas( Gwen::Skin::Base* pSkin ) : BaseClass( NULL ), m_bAnyDelete( false ),m_fScale(-1)
Canvas::Canvas(Gwen::Skin::Base* pSkin) : BaseClass(NULL), m_bAnyDelete(false), m_fScale(-1)
{
SetBounds( 0, 0, 10000, 10000 );
SetSkin( pSkin );
SetScale( 1.0f );
SetBackgroundColor( Color( 255, 255, 255, 255 ) );
SetDrawBackground( false );
SetBounds(0, 0, 10000, 10000);
SetSkin(pSkin);
SetScale(1.0f);
SetBackgroundColor(Color(255, 255, 255, 255));
SetDrawBackground(false);
}
void Canvas::RenderCanvas()
@@ -35,51 +33,48 @@ void Canvas::RenderCanvas()
Gwen::Renderer::Base* render = m_Skin->GetRender();
render->Begin();
RecurseLayout( m_Skin );
RecurseLayout(m_Skin);
render->SetClipRegion( GetBounds() );
render->SetRenderOffset( Gwen::Point( 0, 0 ) );
render->SetScale( Scale() );
render->SetClipRegion(GetBounds());
render->SetRenderOffset(Gwen::Point(0, 0));
render->SetScale(Scale());
if ( m_bDrawBackground )
{
render->SetDrawColor( m_BackgroundColor );
render->DrawFilledRect( GetRenderBounds() );
}
if (m_bDrawBackground)
{
render->SetDrawColor(m_BackgroundColor);
render->DrawFilledRect(GetRenderBounds());
}
DoRender( m_Skin );
DoRender(m_Skin);
DragAndDrop::RenderOverlay( this, m_Skin );
DragAndDrop::RenderOverlay(this, m_Skin);
ToolTip::RenderToolTip( m_Skin );
ToolTip::RenderToolTip(m_Skin);
render->EndClip();
render->EndClip();
render->End();
ProcessDelayedDeletes();
}
void Canvas::Render( Gwen::Skin::Base* /*pRender*/ )
void Canvas::Render(Gwen::Skin::Base* /*pRender*/)
{
m_bNeedsRedraw = false;
}
void Canvas::OnBoundsChanged( Gwen::Rect oldBounds )
void Canvas::OnBoundsChanged(Gwen::Rect oldBounds)
{
BaseClass::OnBoundsChanged( oldBounds );
InvalidateChildren( true );
BaseClass::OnBoundsChanged(oldBounds);
InvalidateChildren(true);
}
void Canvas::DoThink()
{
if ( Hidden() ) return;
if (Hidden()) return;
#ifndef GWEN_NO_ANIMATION
#ifndef GWEN_NO_ANIMATION
Gwen::Anim::Think();
#endif
#endif
// Reset tabbing
{
@@ -89,48 +84,47 @@ void Canvas::DoThink()
ProcessDelayedDeletes();
// Check has focus etc..
RecurseLayout( m_Skin );
RecurseLayout(m_Skin);
// If we didn't have a next tab, cycle to the start.
if ( NextTab == NULL )
if (NextTab == NULL)
NextTab = FirstTab;
Gwen::Input::OnCanvasThink( this );
Gwen::Input::OnCanvasThink(this);
}
void Canvas::SetScale( float f )
{
if ( m_fScale == f ) return;
void Canvas::SetScale(float f)
{
if (m_fScale == f) return;
m_fScale = f;
if ( m_Skin && m_Skin->GetRender() )
m_Skin->GetRender()->SetScale( m_fScale );
if (m_Skin && m_Skin->GetRender())
m_Skin->GetRender()->SetScale(m_fScale);
OnScaleChanged();
Redraw();
}
void Canvas::AddDelayedDelete( Gwen::Controls::Base* pControl )
void Canvas::AddDelayedDelete(Gwen::Controls::Base* pControl)
{
if ( !m_bAnyDelete || m_DeleteSet.find( pControl ) == m_DeleteSet.end() )
if (!m_bAnyDelete || m_DeleteSet.find(pControl) == m_DeleteSet.end())
{
m_bAnyDelete = true;
m_DeleteSet.insert( pControl );
m_DeleteList.push_back( pControl );
m_DeleteSet.insert(pControl);
m_DeleteList.push_back(pControl);
}
}
void Canvas::PreDelete( Controls::Base * pControl )
void Canvas::PreDelete(Controls::Base* pControl)
{
if ( m_bAnyDelete )
if (m_bAnyDelete)
{
std::set< Controls::Base * >::iterator itFind;
if ( ( itFind = m_DeleteSet.find( pControl ) ) != m_DeleteSet.end() )
std::set<Controls::Base*>::iterator itFind;
if ((itFind = m_DeleteSet.find(pControl)) != m_DeleteSet.end())
{
m_DeleteList.remove( pControl );
m_DeleteSet.erase( pControl );
m_DeleteList.remove(pControl);
m_DeleteSet.erase(pControl);
m_bAnyDelete = !m_DeleteSet.empty();
}
}
@@ -138,7 +132,7 @@ void Canvas::PreDelete( Controls::Base * pControl )
void Canvas::ProcessDelayedDeletes()
{
while( m_bAnyDelete )
while (m_bAnyDelete)
{
m_bAnyDelete = false;
@@ -147,7 +141,7 @@ void Canvas::ProcessDelayedDeletes()
m_DeleteList.clear();
m_DeleteSet.clear();
for ( Gwen::Controls::Base::List::iterator it = deleteList.begin(); it != deleteList.end(); ++it )
for (Gwen::Controls::Base::List::iterator it = deleteList.begin(); it != deleteList.end(); ++it)
{
Gwen::Controls::Base* pControl = *it;
delete pControl;
@@ -158,76 +152,76 @@ void Canvas::ProcessDelayedDeletes()
void Canvas::Release()
{
Base::List::iterator iter = Children.begin();
while ( iter != Children.end() )
while (iter != Children.end())
{
Base* pChild = *iter;
iter = Children.erase( iter );
iter = Children.erase(iter);
delete pChild;
}
delete this;
}
bool Canvas::InputMouseMoved( int x, int y, int deltaX, int deltaY )
bool Canvas::InputMouseMoved(int x, int y, int deltaX, int deltaY)
{
if ( Hidden() ) return false;
if (Hidden()) return false;
// Todo: Handle scaling here..
//float fScale = 1.0f / Scale();
Gwen::Input::OnMouseMoved( this, x, y, deltaX, deltaY );
Gwen::Input::OnMouseMoved(this, x, y, deltaX, deltaY);
if ( !Gwen::HoveredControl ) return false;
if ( Gwen::HoveredControl == this ) return false;
if ( Gwen::HoveredControl->GetCanvas() != this ) return false;
if (!Gwen::HoveredControl) return false;
if (Gwen::HoveredControl == this) return false;
if (Gwen::HoveredControl->GetCanvas() != this) return false;
Gwen::HoveredControl->OnMouseMoved( x, y, deltaX, deltaY );
Gwen::HoveredControl->OnMouseMoved(x, y, deltaX, deltaY);
Gwen::HoveredControl->UpdateCursor();
DragAndDrop::OnMouseMoved( Gwen::HoveredControl, x, y );
DragAndDrop::OnMouseMoved(Gwen::HoveredControl, x, y);
return true;
}
bool Canvas::InputMouseButton( int iButton, bool bDown )
bool Canvas::InputMouseButton(int iButton, bool bDown)
{
if ( Hidden() ) return false;
if (Hidden()) return false;
return Gwen::Input::OnMouseClicked( this, iButton, bDown );
return Gwen::Input::OnMouseClicked(this, iButton, bDown);
}
bool Canvas::InputKey( int iKey, bool bDown )
bool Canvas::InputKey(int iKey, bool bDown)
{
if ( Hidden() ) return false;
if ( iKey <= Gwen::Key::Invalid ) return false;
if ( iKey >= Gwen::Key::Count ) return false;
if (Hidden()) return false;
if (iKey <= Gwen::Key::Invalid) return false;
if (iKey >= Gwen::Key::Count) return false;
return Gwen::Input::OnKeyEvent( this, iKey, bDown );
return Gwen::Input::OnKeyEvent(this, iKey, bDown);
}
bool Canvas::InputCharacter( Gwen::UnicodeChar chr )
bool Canvas::InputCharacter(Gwen::UnicodeChar chr)
{
if ( Hidden() ) return false;
if ( !iswprint( chr ) ) return false;
if (Hidden()) return false;
if (!iswprint(chr)) return false;
//Handle Accelerators
if ( Gwen::Input::HandleAccelerator( this, chr ) )
if (Gwen::Input::HandleAccelerator(this, chr))
return true;
//Handle characters
if ( !Gwen::KeyboardFocus ) return false;
if ( Gwen::KeyboardFocus->GetCanvas() != this ) return false;
if ( !Gwen::KeyboardFocus->Visible() ) return false;
if ( Gwen::Input::IsControlDown() ) return false;
if (!Gwen::KeyboardFocus) return false;
if (Gwen::KeyboardFocus->GetCanvas() != this) return false;
if (!Gwen::KeyboardFocus->Visible()) return false;
if (Gwen::Input::IsControlDown()) return false;
return KeyboardFocus->OnChar( chr );
return KeyboardFocus->OnChar(chr);
}
bool Canvas::InputMouseWheel( int val )
bool Canvas::InputMouseWheel(int val)
{
if ( Hidden() ) return false;
if ( !Gwen::HoveredControl ) return false;
if ( Gwen::HoveredControl == this ) return false;
if ( Gwen::HoveredControl->GetCanvas() != this ) return false;
if (Hidden()) return false;
if (!Gwen::HoveredControl) return false;
if (Gwen::HoveredControl == this) return false;
if (Gwen::HoveredControl->GetCanvas() != this) return false;
return Gwen::HoveredControl->OnMouseWheeled( val );
return Gwen::HoveredControl->OnMouseWheeled(val);
}

View File

@@ -12,96 +12,92 @@
#include "Gwen/Controls/Base.h"
#include "Gwen/InputHandler.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT Canvas : public Base
{
public:
namespace Controls
{
class GWEN_EXPORT Canvas : public Base
{
public:
typedef Controls::Base BaseClass;
typedef Controls::Base BaseClass;
Canvas(Skin::Base* pSkin);
Canvas( Skin::Base* pSkin );
//
// For additional initialization
// (which is sometimes not appropriate in the constructor)
//
virtual void Initialize(){};
//
// For additional initialization
// (which is sometimes not appropriate in the constructor)
//
virtual void Initialize(){};
//
// You should call this to render your canvas.
//
virtual void RenderCanvas();
//
// You should call this to render your canvas.
//
virtual void RenderCanvas();
//
// Call this whenever you want to process input. This
// is usually once a frame..
//
virtual void DoThink();
//
// Call this whenever you want to process input. This
// is usually once a frame..
//
virtual void DoThink();
//
// In most situations you will be rendering the canvas
// every frame. But in some situations you will only want
// to render when there have been changes. You can do this
// by checking NeedsRedraw().
//
virtual bool NeedsRedraw() { return m_bNeedsRedraw; }
virtual void Redraw() { m_bNeedsRedraw = true; }
//
// In most situations you will be rendering the canvas
// every frame. But in some situations you will only want
// to render when there have been changes. You can do this
// by checking NeedsRedraw().
//
virtual bool NeedsRedraw(){ return m_bNeedsRedraw; }
virtual void Redraw(){ m_bNeedsRedraw = true; }
// Internal. Do not call directly.
virtual void Render(Skin::Base* pRender);
// Internal. Do not call directly.
virtual void Render( Skin::Base* pRender );
// Childpanels call parent->GetCanvas() until they get to
// this top level function.
virtual Controls::Canvas* GetCanvas() { return this; }
// Childpanels call parent->GetCanvas() until they get to
// this top level function.
virtual Controls::Canvas* GetCanvas(){ return this; }
virtual void SetScale(float f);
virtual float Scale() const { return m_fScale; }
virtual void SetScale( float f );
virtual float Scale() const { return m_fScale; }
virtual void OnBoundsChanged(Gwen::Rect oldBounds);
virtual void OnBoundsChanged( Gwen::Rect oldBounds );
//
// Call this to delete the canvas, and its children
// in the right order.
//
virtual void Release();
//
// Call this to delete the canvas, and its children
// in the right order.
//
virtual void Release();
// Delayed deletes
virtual void AddDelayedDelete(Controls::Base* pControl);
virtual void ProcessDelayedDeletes();
// Delayed deletes
virtual void AddDelayedDelete( Controls::Base* pControl );
virtual void ProcessDelayedDeletes();
Controls::Base* FirstTab;
Controls::Base* NextTab;
Controls::Base* FirstTab;
Controls::Base* NextTab;
// Input
virtual bool InputMouseMoved(int x, int y, int deltaX, int deltaY);
virtual bool InputMouseButton(int iButton, bool bDown);
virtual bool InputKey(int iKey, bool bDown);
virtual bool InputCharacter(Gwen::UnicodeChar chr);
virtual bool InputMouseWheel(int val);
// Input
virtual bool InputMouseMoved( int x, int y, int deltaX, int deltaY );
virtual bool InputMouseButton( int iButton, bool bDown );
virtual bool InputKey( int iKey, bool bDown );
virtual bool InputCharacter( Gwen::UnicodeChar chr );
virtual bool InputMouseWheel( int val );
// Background
virtual void SetBackgroundColor(const Gwen::Color& color) { m_BackgroundColor = color; }
virtual void SetDrawBackground(bool bShouldDraw) { m_bDrawBackground = bShouldDraw; }
// Background
virtual void SetBackgroundColor( const Gwen::Color& color ){ m_BackgroundColor = color; }
virtual void SetDrawBackground( bool bShouldDraw ){ m_bDrawBackground = bShouldDraw; }
private:
bool m_bNeedsRedraw;
bool m_bAnyDelete;
float m_fScale;
private:
Controls::Base::List m_DeleteList;
std::set<Controls::Base*> m_DeleteSet;
friend class Controls::Base;
void PreDelete(Controls::Base*);
bool m_bNeedsRedraw;
bool m_bAnyDelete;
float m_fScale;
Controls::Base::List m_DeleteList;
std::set< Controls::Base* > m_DeleteSet;
friend class Controls::Base;
void PreDelete( Controls::Base * );
bool m_bDrawBackground;
Gwen::Color m_BackgroundColor;
};
}
}
bool m_bDrawBackground;
Gwen::Color m_BackgroundColor;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,31 +4,27 @@
See license in Gwen.h
*/
#include "Gwen/Controls/CheckBox.h"
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( CheckBox )
GWEN_CONTROL_CONSTRUCTOR(CheckBox)
{
SetSize( 13, 13 );
SetSize(13, 13);
m_bChecked = true;
Toggle();
}
void CheckBox::Render( Skin::Base* skin )
void CheckBox::Render(Skin::Base* skin)
{
skin->DrawCheckBox( this, m_bChecked, IsDepressed() );
skin->DrawCheckBox(this, m_bChecked, IsDepressed());
}
void CheckBox::OnPress()
{
if ( IsChecked() && !AllowUncheck() )
if (IsChecked() && !AllowUncheck())
return;
Toggle();
@@ -36,22 +32,22 @@ void CheckBox::OnPress()
void CheckBox::OnCheckStatusChanged()
{
if ( IsChecked() )
if (IsChecked())
{
onChecked.Call( this );
onChecked.Call(this);
}
else
{
onUnChecked.Call( this );
onUnChecked.Call(this);
}
onCheckChanged.Call( this );
onCheckChanged.Call(this);
}
void CheckBox::SetChecked( bool bChecked )
{
if ( m_bChecked == bChecked ) return;
void CheckBox::SetChecked(bool bChecked)
{
if (m_bChecked == bChecked) return;
m_bChecked = bChecked;
OnCheckStatusChanged();
m_bChecked = bChecked;
OnCheckStatusChanged();
}

View File

@@ -15,68 +15,67 @@
#include "Gwen/Controls/Symbol.h"
#include "Gwen/Controls/LabelClickable.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class GWEN_EXPORT CheckBox : public Button
{
public:
GWEN_CONTROL(CheckBox, Button);
virtual void Render(Skin::Base* skin);
virtual void OnPress();
virtual void SetChecked(bool Checked);
virtual void Toggle() { SetChecked(!IsChecked()); }
virtual bool IsChecked() { return m_bChecked; }
Gwen::Event::Caller onChecked;
Gwen::Event::Caller onUnChecked;
Gwen::Event::Caller onCheckChanged;
private:
// For derived controls
virtual bool AllowUncheck() { return true; }
void OnCheckStatusChanged();
bool m_bChecked;
};
class GWEN_EXPORT CheckBoxWithLabel : public Base
{
public:
GWEN_CONTROL_INLINE(CheckBoxWithLabel, Base)
{
SetSize(200, 19);
class GWEN_EXPORT CheckBox : public Button
{
public:
m_Checkbox = new CheckBox(this);
m_Checkbox->Dock(Pos::Left);
m_Checkbox->SetMargin(Margin(0, 3, 3, 3));
m_Checkbox->SetTabable(false);
GWEN_CONTROL( CheckBox, Button );
m_Label = new LabelClickable(this);
m_Label->Dock(Pos::Fill);
m_Label->onPress.Add(m_Checkbox, &CheckBox::ReceiveEventPress);
m_Label->SetTabable(false);
virtual void Render( Skin::Base* skin );
virtual void OnPress();
virtual void SetChecked( bool Checked );
virtual void Toggle() { SetChecked( !IsChecked() ); }
virtual bool IsChecked() { return m_bChecked; }
Gwen::Event::Caller onChecked;
Gwen::Event::Caller onUnChecked;
Gwen::Event::Caller onCheckChanged;
private:
// For derived controls
virtual bool AllowUncheck(){ return true; }
void OnCheckStatusChanged();
bool m_bChecked;
};
class GWEN_EXPORT CheckBoxWithLabel : public Base
{
public:
GWEN_CONTROL_INLINE( CheckBoxWithLabel, Base )
{
SetSize( 200, 19 );
m_Checkbox = new CheckBox( this );
m_Checkbox->Dock( Pos::Left );
m_Checkbox->SetMargin( Margin( 0, 3, 3, 3 ) );
m_Checkbox->SetTabable( false );
m_Label = new LabelClickable( this );
m_Label->Dock( Pos::Fill );
m_Label->onPress.Add( m_Checkbox, &CheckBox::ReceiveEventPress );
m_Label->SetTabable( false );
SetTabable( false );
}
virtual CheckBox* Checkbox() { return m_Checkbox; }
virtual LabelClickable* Label() { return m_Label; }
virtual bool OnKeySpace( bool bDown ) { if ( bDown ) m_Checkbox->SetChecked( !m_Checkbox->IsChecked() ); return true; }
private:
CheckBox* m_Checkbox;
LabelClickable* m_Label;
};
SetTabable(false);
}
}
virtual CheckBox* Checkbox() { return m_Checkbox; }
virtual LabelClickable* Label() { return m_Label; }
virtual bool OnKeySpace(bool bDown)
{
if (bDown) m_Checkbox->SetChecked(!m_Checkbox->IsChecked());
return true;
}
private:
CheckBox* m_Checkbox;
LabelClickable* m_Label;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Utility.h"
#include "Gwen/Controls/ColorControls.h"
@@ -12,7 +11,7 @@ using namespace Gwen;
using namespace Gwen::Controls;
//Find a place to put these...
Color HSVToColor( float h, float s, float v )
Color HSVToColor(float h, float s, float v)
{
if (h < 0.0f) h += 360.0f;
if (h > 360.0f) h -= 360.0f;
@@ -26,10 +25,10 @@ Color HSVToColor( float h, float s, float v )
{
r = g = b = v;
}
double min,max,delta,hue;
double min, max, delta, hue;
max = v;
delta = (max * s)/255.0;
delta = (max * s) / 255.0;
min = max - delta;
hue = h;
@@ -39,7 +38,7 @@ Color HSVToColor( float h, float s, float v )
if (h > 300)
{
g = (int)min;
hue = (hue - 360.0)/60.0;
hue = (hue - 360.0) / 60.0;
b = (int)((hue * delta - min) * -1);
}
else
@@ -55,13 +54,13 @@ Color HSVToColor( float h, float s, float v )
if (h < 120)
{
b = (int)min;
hue = (hue/60.0 - 2.0 ) * delta;
hue = (hue / 60.0 - 2.0) * delta;
r = (int)(min - hue);
}
else
{
r = (int)min;
hue = (hue/60 - 2.0) * delta;
hue = (hue / 60 - 2.0) * delta;
b = (int)(min + hue);
}
}
@@ -71,25 +70,25 @@ Color HSVToColor( float h, float s, float v )
if (h < 240)
{
r = (int)min;
hue = (hue/60.0 - 4.0 ) * delta;
hue = (hue / 60.0 - 4.0) * delta;
g = (int)(min - hue);
}
else
{
g = (int)min;
hue = (hue/60 - 4.0) * delta;
hue = (hue / 60 - 4.0) * delta;
r = (int)(min + hue);
}
}
return Color( r, g, b, 255);
return Color(r, g, b, 255);
}
HSV RGBtoHSV( int r, int g, int b )
HSV RGBtoHSV(int r, int g, int b)
{
double min,max,delta,temp;
min = GwenUtil_Min(r,GwenUtil_Min(g,b));
max = GwenUtil_Max(r,GwenUtil_Max(g,b));
double min, max, delta, temp;
min = GwenUtil_Min(r, GwenUtil_Min(g, b));
max = GwenUtil_Max(r, GwenUtil_Max(g, b));
delta = max - min;
HSV hsv;
@@ -100,52 +99,49 @@ HSV RGBtoHSV( int r, int g, int b )
}
else
{
temp = delta/max;
hsv.s = (int)(temp*255);
temp = delta / max;
hsv.s = (int)(temp * 255);
if (r == (int)max)
{
temp = (double)(g-b)/delta;
temp = (double)(g - b) / delta;
}
else if (g == (int)max)
{
temp = 2.0 + ((double)(b - r) / delta);
}
else
if (g == (int)max)
{
temp = 2.0 + ((double)(b-r)/delta);
}
else
{
temp = 4.0 + ((double)(r-g)/delta);
}
temp *= 60;
if (temp < 0)
{
temp+=360;
}
if (temp == 360)
{
temp = 0;
}
hsv.h = (int)temp;
{
temp = 4.0 + ((double)(r - g) / delta);
}
temp *= 60;
if (temp < 0)
{
temp += 360;
}
if (temp == 360)
{
temp = 0;
}
hsv.h = (int)temp;
}
hsv.s /= 255.0f;
hsv.v /= 255.0f;
return hsv;
}
GWEN_CONTROL_CONSTRUCTOR( ColorLerpBox )
GWEN_CONTROL_CONSTRUCTOR(ColorLerpBox)
{
SetColor( Gwen::Color(255, 128, 0, 255) );
SetSize( 128, 128 );
SetMouseInputEnabled( true );
SetColor(Gwen::Color(255, 128, 0, 255));
SetSize(128, 128);
SetMouseInputEnabled(true);
m_bDepressed = false;
}
}
//Find a place to put this? color member?
Gwen::Color LerpColor( Gwen::Color &toColor, Gwen::Color &fromColor, float amount )
Gwen::Color LerpColor(Gwen::Color& toColor, Gwen::Color& fromColor, float amount)
{
Gwen::Color colorDelta = toColor - fromColor;
@@ -159,29 +155,29 @@ Gwen::Color LerpColor( Gwen::Color &toColor, Gwen::Color &fromColor, float amoun
Gwen::Color ColorLerpBox::GetSelectedColor()
{
return GetColorAtPos( cursorPos.x, cursorPos.y );
return GetColorAtPos(cursorPos.x, cursorPos.y);
}
void ColorLerpBox::SetColor( Gwen::Color color, bool onlyHue )
void ColorLerpBox::SetColor(Gwen::Color color, bool onlyHue)
{
HSV hsv = RGBtoHSV(color.r, color.g, color.b);
m_Hue = hsv.h;
if ( !onlyHue )
if (!onlyHue)
{
cursorPos.x = hsv.s * Width();
cursorPos.y = (1 - hsv.v) * Height();
}
onSelectionChanged.Call( this );
onSelectionChanged.Call(this);
}
void ColorLerpBox::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
void ColorLerpBox::OnMouseMoved(int x, int y, int /*deltaX*/, int /*deltaY*/)
{
if ( m_bDepressed )
if (m_bDepressed)
{
cursorPos = CanvasPosToLocal( Gwen::Point( x, y ) );
cursorPos = CanvasPosToLocal(Gwen::Point(x, y));
//Do we have clamp?
if ( cursorPos.x < 0)
if (cursorPos.x < 0)
cursorPos.x = 0;
if (cursorPos.x > Width())
cursorPos.x = Width();
@@ -191,97 +187,14 @@ void ColorLerpBox::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
if (cursorPos.y > Height())
cursorPos.y = Height();
onSelectionChanged.Call( this );
onSelectionChanged.Call(this);
}
}
void ColorLerpBox::OnMouseClickLeft( int x, int y, bool bDown )
void ColorLerpBox::OnMouseClickLeft(int x, int y, bool bDown)
{
m_bDepressed = bDown;
if ( bDown )
Gwen::MouseFocus = this;
else
Gwen::MouseFocus = NULL;
OnMouseMoved( x, y, 0, 0);
}
Gwen::Color ColorLerpBox::GetColorAtPos( int x, int y )
{
float xPercent = ( (float)x / (float)Width() );
float yPercent = 1 - ( (float)y / (float)Height() );
Gwen::Color result = HSVToColor( m_Hue, xPercent, yPercent );
result.a = 255;
return result;
}
void ColorLerpBox::Render( Gwen::Skin::Base* skin )
{
//Is there any way to move this into skin? Not for now, no idea how we'll "actually" render these
BaseClass::Render( skin );
for ( int x = 0; x<Width(); x++)
{
for ( int y = 0; y<Height(); y++)
{
skin->GetRender()->SetDrawColor( GetColorAtPos( x, y ) );
skin->GetRender()->DrawPixel( x, y );
}
}
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ) );
skin->GetRender()->DrawLinedRect( GetRenderBounds() );
Gwen::Color selected = GetSelectedColor();
if ( (selected.r + selected.g + selected.b) / 3 < 170 )
skin->GetRender()->SetDrawColor( Gwen::Color( 255, 255, 255, 255 ) );
else
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ) );
Gwen::Rect testRect = Gwen::Rect( cursorPos.x -3, cursorPos.y -3, 6, 6);
skin->GetRender()->DrawShavedCornerRect( testRect );
}
GWEN_CONTROL_CONSTRUCTOR( ColorSlider )
{
SetSize( 32, 128 );
SetMouseInputEnabled( true );
m_bDepressed = false;
}
void ColorSlider::Render( Gwen::Skin::Base* skin )
{
//Is there any way to move this into skin? Not for now, no idea how we'll "actually" render these
int y = 0;
for ( y = 0; y < Height(); y++)
{
float yPercent = (float)y / (float)Height();
skin->GetRender()->SetDrawColor( HSVToColor( yPercent * 360, 1, 1 ) );
skin->GetRender()->DrawFilledRect( Gwen::Rect( 5, y, Width() - 10, 1 ) );
}
int drawHeight = m_iSelectedDist - 3;
//Draw our selectors
skin->GetRender()->SetDrawColor( Gwen::Color( 0, 0, 0, 255 ));
skin->GetRender()->DrawFilledRect( Gwen::Rect( 0, drawHeight + 2, Width(), 1));
skin->GetRender()->DrawFilledRect( Gwen::Rect( 0, drawHeight, 5, 5) );
skin->GetRender()->DrawFilledRect( Gwen::Rect( Width() - 5, drawHeight, 5, 5) );
skin->GetRender()->SetDrawColor( Gwen::Color( 255, 255, 255, 255 ) );
skin->GetRender()->DrawFilledRect( Gwen::Rect( 1, drawHeight + 1, 3, 3 ) );
skin->GetRender()->DrawFilledRect( Gwen::Rect( Width() - 4, drawHeight + 1, 3, 3 ) );
}
void ColorSlider::OnMouseClickLeft( int x, int y, bool bDown )
{
m_bDepressed = bDown;
if ( bDown)
if (bDown)
Gwen::MouseFocus = this;
else
Gwen::MouseFocus = NULL;
@@ -289,17 +202,95 @@ void ColorSlider::OnMouseClickLeft( int x, int y, bool bDown )
OnMouseMoved(x, y, 0, 0);
}
Gwen::Color ColorSlider::GetColorAtHeight( int y )
Gwen::Color ColorLerpBox::GetColorAtPos(int x, int y)
{
float xPercent = ((float)x / (float)Width());
float yPercent = 1 - ((float)y / (float)Height());
Gwen::Color result = HSVToColor(m_Hue, xPercent, yPercent);
result.a = 255;
return result;
}
void ColorLerpBox::Render(Gwen::Skin::Base* skin)
{
//Is there any way to move this into skin? Not for now, no idea how we'll "actually" render these
BaseClass::Render(skin);
for (int x = 0; x < Width(); x++)
{
for (int y = 0; y < Height(); y++)
{
skin->GetRender()->SetDrawColor(GetColorAtPos(x, y));
skin->GetRender()->DrawPixel(x, y);
}
}
skin->GetRender()->SetDrawColor(Gwen::Color(0, 0, 0, 255));
skin->GetRender()->DrawLinedRect(GetRenderBounds());
Gwen::Color selected = GetSelectedColor();
if ((selected.r + selected.g + selected.b) / 3 < 170)
skin->GetRender()->SetDrawColor(Gwen::Color(255, 255, 255, 255));
else
skin->GetRender()->SetDrawColor(Gwen::Color(0, 0, 0, 255));
Gwen::Rect testRect = Gwen::Rect(cursorPos.x - 3, cursorPos.y - 3, 6, 6);
skin->GetRender()->DrawShavedCornerRect(testRect);
}
GWEN_CONTROL_CONSTRUCTOR(ColorSlider)
{
SetSize(32, 128);
SetMouseInputEnabled(true);
m_bDepressed = false;
}
void ColorSlider::Render(Gwen::Skin::Base* skin)
{
//Is there any way to move this into skin? Not for now, no idea how we'll "actually" render these
int y = 0;
for (y = 0; y < Height(); y++)
{
float yPercent = (float)y / (float)Height();
skin->GetRender()->SetDrawColor(HSVToColor(yPercent * 360, 1, 1));
skin->GetRender()->DrawFilledRect(Gwen::Rect(5, y, Width() - 10, 1));
}
int drawHeight = m_iSelectedDist - 3;
//Draw our selectors
skin->GetRender()->SetDrawColor(Gwen::Color(0, 0, 0, 255));
skin->GetRender()->DrawFilledRect(Gwen::Rect(0, drawHeight + 2, Width(), 1));
skin->GetRender()->DrawFilledRect(Gwen::Rect(0, drawHeight, 5, 5));
skin->GetRender()->DrawFilledRect(Gwen::Rect(Width() - 5, drawHeight, 5, 5));
skin->GetRender()->SetDrawColor(Gwen::Color(255, 255, 255, 255));
skin->GetRender()->DrawFilledRect(Gwen::Rect(1, drawHeight + 1, 3, 3));
skin->GetRender()->DrawFilledRect(Gwen::Rect(Width() - 4, drawHeight + 1, 3, 3));
}
void ColorSlider::OnMouseClickLeft(int x, int y, bool bDown)
{
m_bDepressed = bDown;
if (bDown)
Gwen::MouseFocus = this;
else
Gwen::MouseFocus = NULL;
OnMouseMoved(x, y, 0, 0);
}
Gwen::Color ColorSlider::GetColorAtHeight(int y)
{
float yPercent = (float)y / (float)Height();
return HSVToColor( yPercent * 360, 1, 1);
return HSVToColor(yPercent * 360, 1, 1);
}
void ColorSlider::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
void ColorSlider::OnMouseMoved(int x, int y, int /*deltaX*/, int /*deltaY*/)
{
if ( m_bDepressed )
if (m_bDepressed)
{
Gwen::Point cursorPos = CanvasPosToLocal( Gwen::Point( x, y ) );
Gwen::Point cursorPos = CanvasPosToLocal(Gwen::Point(x, y));
if (cursorPos.y < 0)
cursorPos.y = 0;
@@ -307,20 +298,20 @@ void ColorSlider::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
cursorPos.y = Height();
m_iSelectedDist = cursorPos.y;
onSelectionChanged.Call( this );
onSelectionChanged.Call(this);
}
}
void ColorSlider::SetColor( Gwen::Color color)
void ColorSlider::SetColor(Gwen::Color color)
{
HSV hsv = RGBtoHSV( color.r, color.g, color.b );
HSV hsv = RGBtoHSV(color.r, color.g, color.b);
m_iSelectedDist = hsv.h / 360 * Height();
onSelectionChanged.Call( this );
onSelectionChanged.Call(this);
}
Gwen::Color ColorSlider::GetSelectedColor()
{
return GetColorAtHeight( m_iSelectedDist );
return GetColorAtHeight(m_iSelectedDist);
}

View File

@@ -3,7 +3,7 @@
Copyright (c) 2010 Facepunch Studios
See license in Gwen.h
*/
#pragma once
#ifndef GWEN_CONTROLS_COLORCONTROLS_H
#define GWEN_CONTROLS_COLORCONTROLS_H
@@ -12,50 +12,47 @@
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
namespace Controls
{
class GWEN_EXPORT ColorLerpBox : public Controls::Base
{
public:
GWEN_CONTROL(ColorLerpBox, Controls::Base);
virtual void Render(Gwen::Skin::Base* skin);
Gwen::Color GetColorAtPos(int x, int y);
void SetColor(Gwen::Color color, bool onlyHue = true);
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
virtual void OnMouseClickLeft(int x, int y, bool bDown);
Gwen::Color GetSelectedColor();
class GWEN_EXPORT ColorLerpBox : public Controls::Base
{
public:
GWEN_CONTROL( ColorLerpBox, Controls::Base );
virtual void Render( Gwen::Skin::Base* skin );
Gwen::Color GetColorAtPos(int x, int y );
void SetColor( Gwen::Color color, bool onlyHue = true );
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
virtual void OnMouseClickLeft( int x, int y, bool bDown );
Gwen::Color GetSelectedColor();
Event::Caller onSelectionChanged;
Event::Caller onSelectionChanged;
protected:
Gwen::Point cursorPos;
bool m_bDepressed;
int m_Hue;
};
protected:
Gwen::Point cursorPos;
bool m_bDepressed;
int m_Hue;
};
class GWEN_EXPORT ColorSlider : public Controls::Base
{
public:
GWEN_CONTROL( ColorSlider, Controls::Base );
virtual void Render( Gwen::Skin::Base* skin );
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
virtual void OnMouseClickLeft( int x, int y, bool bDown );
Gwen::Color GetSelectedColor();
Gwen::Color GetColorAtHeight(int y );
void SetColor( Gwen::Color color );
class GWEN_EXPORT ColorSlider : public Controls::Base
{
public:
GWEN_CONTROL(ColorSlider, Controls::Base);
virtual void Render(Gwen::Skin::Base* skin);
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
virtual void OnMouseClickLeft(int x, int y, bool bDown);
Gwen::Color GetSelectedColor();
Gwen::Color GetColorAtHeight(int y);
void SetColor(Gwen::Color color);
Event::Caller onSelectionChanged;
Event::Caller onSelectionChanged;
protected:
int m_iSelectedDist;
bool m_bDepressed;
protected:
int m_iSelectedDist;
bool m_bDepressed;
};
} // namespace Controls
};
}
}
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Controls/ColorPicker.h"
#include "Gwen/Controls/HorizontalSlider.h"
#include "Gwen/Controls/GroupBox.h"
@@ -15,45 +14,45 @@ using namespace Gwen;
using namespace Gwen::Controls;
using namespace Gwen::ControlsInternal;
GWEN_CONTROL_CONSTRUCTOR( ColorPicker )
GWEN_CONTROL_CONSTRUCTOR(ColorPicker)
{
SetMouseInputEnabled( true );
SetMouseInputEnabled(true);
SetKeyboardInputEnabled(true);
SetSize( 256, 150 );
SetSize(256, 150);
CreateControls();
SetColor( Gwen::Color( 50, 60, 70, 255 ) );
SetColor(Gwen::Color(50, 60, 70, 255));
}
void ColorPicker::CreateColorControl( Gwen::String name, int y )
void ColorPicker::CreateColorControl(Gwen::String name, int y)
{
int colorSize = 12;
GroupBox* colorGroup = new GroupBox( this );
colorGroup->SetPos( 10, y );
colorGroup->SetText( name );
colorGroup->SetSize( 160, 35 );
colorGroup->SetName( name + "groupbox" );
GroupBox* colorGroup = new GroupBox(this);
colorGroup->SetPos(10, y);
colorGroup->SetText(name);
colorGroup->SetSize(160, 35);
colorGroup->SetName(name + "groupbox");
ColorDisplay* disp = new ColorDisplay( colorGroup );
ColorDisplay* disp = new ColorDisplay(colorGroup);
disp->SetName(name);
disp->SetBounds( 0 , 10, colorSize, colorSize );
disp->SetBounds(0, 10, colorSize, colorSize);
TextBoxNumeric* numeric = new TextBoxNumeric( colorGroup );
numeric->SetName( name + "Box" );
numeric->SetPos( 105, 7 );
numeric->SetSize( 26, 16 );
numeric->SetSelectAllOnFocus( true );
numeric->onTextChanged.Add( this, &ColorPicker::NumericTyped );
TextBoxNumeric* numeric = new TextBoxNumeric(colorGroup);
numeric->SetName(name + "Box");
numeric->SetPos(105, 7);
numeric->SetSize(26, 16);
numeric->SetSelectAllOnFocus(true);
numeric->onTextChanged.Add(this, &ColorPicker::NumericTyped);
HorizontalSlider* slider = new HorizontalSlider( colorGroup );
slider->SetPos( colorSize + 5 , 10 );
slider->SetRange( 0, 255 );
slider->SetSize( 80, colorSize );
slider->SetName( name + "Slider");
slider->onValueChanged.Add( this, &ColorPicker::SlidersMoved );
HorizontalSlider* slider = new HorizontalSlider(colorGroup);
slider->SetPos(colorSize + 5, 10);
slider->SetRange(0, 255);
slider->SetSize(80, colorSize);
slider->SetName(name + "Slider");
slider->onValueChanged.Add(this, &ColorPicker::SlidersMoved);
}
void ColorPicker::NumericTyped( Gwen::Controls::Base* control )
void ColorPicker::NumericTyped(Gwen::Controls::Base* control)
{
if (!control)
return;
@@ -62,32 +61,32 @@ void ColorPicker::NumericTyped( Gwen::Controls::Base* control )
if (!box)
return;
if ( box->GetText() == L"")
if (box->GetText() == L"")
return;
int textValue = atoi( Utility::UnicodeToString( box->GetText()).c_str() );
if ( textValue < 0) textValue = 0;
if ( textValue > 255) textValue = 255;
int textValue = atoi(Utility::UnicodeToString(box->GetText()).c_str());
if (textValue < 0) textValue = 0;
if (textValue > 255) textValue = 255;
if ( box->GetName().find("Red") != Gwen::String::npos )
SetRed( textValue );
if (box->GetName().find("Red") != Gwen::String::npos)
SetRed(textValue);
if ( box->GetName().find("Green") != Gwen::String::npos )
SetGreen( textValue );
if (box->GetName().find("Green") != Gwen::String::npos)
SetGreen(textValue);
if ( box->GetName().find("Blue") != Gwen::String::npos )
SetBlue( textValue );
if (box->GetName().find("Blue") != Gwen::String::npos)
SetBlue(textValue);
if ( box->GetName().find("Alpha") != Gwen::String::npos )
SetAlpha( textValue );
if (box->GetName().find("Alpha") != Gwen::String::npos)
SetAlpha(textValue);
UpdateControls();
}
void ColorPicker::SetColor( Gwen::Color color )
void ColorPicker::SetColor(Gwen::Color color)
{
m_Color = color;
UpdateControls();
m_Color = color;
UpdateControls();
}
void ColorPicker::CreateControls()
@@ -95,128 +94,124 @@ void ColorPicker::CreateControls()
int startY = 5;
int height = 35;
CreateColorControl( "Red", startY );
CreateColorControl( "Green", startY + height );
CreateColorControl( "Blue", startY + height * 2 );
CreateColorControl( "Alpha", startY + height * 3 );
CreateColorControl("Red", startY);
CreateColorControl("Green", startY + height);
CreateColorControl("Blue", startY + height * 2);
CreateColorControl("Alpha", startY + height * 3);
GroupBox* finalGroup = new GroupBox( this );
finalGroup->SetPos( 180, 40 );
finalGroup->SetSize( 60, 60 );
finalGroup->SetText( "Result" );
finalGroup->SetName( "ResultGroupBox" );
GroupBox* finalGroup = new GroupBox(this);
finalGroup->SetPos(180, 40);
finalGroup->SetSize(60, 60);
finalGroup->SetText("Result");
finalGroup->SetName("ResultGroupBox");
ColorDisplay* disp = new ColorDisplay( finalGroup );
disp->SetName( "Result" );
disp->SetBounds( 0 , 10, 32, 32 );
disp->SetDrawCheckers( true );
ColorDisplay* disp = new ColorDisplay(finalGroup);
disp->SetName("Result");
disp->SetBounds(0, 10, 32, 32);
disp->SetDrawCheckers(true);
//UpdateControls();
}
void ColorPicker::UpdateColorControls( Gwen::String name, Gwen::Color col, int sliderVal )
void ColorPicker::UpdateColorControls(Gwen::String name, Gwen::Color col, int sliderVal)
{
Base* el = FindChildByName( name, true );
Base* el = FindChildByName(name, true);
ColorDisplay* disp = el ? el->DynamicCastColorDisplay() : 0;
disp->SetColor( col );
disp->SetColor(col);
HorizontalSlider* slider = FindChildByName( name + "Slider", true )->DynamicCastHorizontalSlider();
slider->SetValue( sliderVal );
HorizontalSlider* slider = FindChildByName(name + "Slider", true)->DynamicCastHorizontalSlider();
slider->SetValue(sliderVal);
TextBoxNumeric* box = FindChildByName( name + "Box", true )->DynamicCastTextBoxNumeric();
box->SetText( Gwen::Utility::ToString( sliderVal ) );
TextBoxNumeric* box = FindChildByName(name + "Box", true)->DynamicCastTextBoxNumeric();
box->SetText(Gwen::Utility::ToString(sliderVal));
}
void ColorPicker::UpdateControls()
{
//This is a little weird, but whatever for now
UpdateColorControls( "Red", Color( GetColor().r, 0, 0, 255 ), GetColor().r );
UpdateColorControls( "Green", Color( 0, GetColor().g, 0, 255 ), GetColor().g );
UpdateColorControls( "Blue", Color( 0, 0, GetColor().b, 255 ), GetColor().b );
UpdateColorControls( "Alpha", Color( 255, 255, 255, GetColor().a ), GetColor().a );
UpdateColorControls("Red", Color(GetColor().r, 0, 0, 255), GetColor().r);
UpdateColorControls("Green", Color(0, GetColor().g, 0, 255), GetColor().g);
UpdateColorControls("Blue", Color(0, 0, GetColor().b, 255), GetColor().b);
UpdateColorControls("Alpha", Color(255, 255, 255, GetColor().a), GetColor().a);
ColorDisplay* disp = FindChildByName( "Result", true )->DynamicCastColorDisplay();
disp->SetColor( Color( GetColor().r, GetColor().g, GetColor().b, GetColor().a ) );
ColorDisplay* disp = FindChildByName("Result", true)->DynamicCastColorDisplay();
disp->SetColor(Color(GetColor().r, GetColor().g, GetColor().b, GetColor().a));
onColorChanged.Call( this );
onColorChanged.Call(this);
}
void ColorPicker::SlidersMoved( Gwen::Controls::Base* control )
void ColorPicker::SlidersMoved(Gwen::Controls::Base* control)
{
HorizontalSlider* slider = control->DynamicCastHorizontalSlider();
if (slider)
SetColorByName( GetColorFromName( slider->GetName() ), slider->GetValue() );
SetColorByName(GetColorFromName(slider->GetName()), slider->GetValue());
UpdateControls();
//SetColor( Gwen::Color( redSlider->GetValue(), greenSlider->GetValue(), blueSlider->GetValue(), alphaSlider->GetValue() ) );
}
void ColorPicker::Layout( Skin::Base* skin )
void ColorPicker::Layout(Skin::Base* skin)
{
BaseClass::Layout( skin );
BaseClass::Layout(skin);
SizeToChildren( false, true );
SetSize( Width(), Height() + 5 );
SizeToChildren(false, true);
SetSize(Width(), Height() + 5);
GroupBox* groupBox = FindChildByName( "ResultGroupBox", true )->DynamicCastGroupBox();
if ( groupBox )
groupBox->SetPos( groupBox->X(), Height() * 0.5f - groupBox->Height() * 0.5f );
GroupBox* groupBox = FindChildByName("ResultGroupBox", true)->DynamicCastGroupBox();
if (groupBox)
groupBox->SetPos(groupBox->X(), Height() * 0.5f - groupBox->Height() * 0.5f);
UpdateControls();
}
void ColorPicker::Render( Skin::Base* skin )
void ColorPicker::Render(Skin::Base* skin)
{
skin->DrawBackground( this );
skin->DrawBackground(this);
}
int ColorPicker::GetColorByName( Gwen::String colorName )
int ColorPicker::GetColorByName(Gwen::String colorName)
{
if ( colorName == "Red")
if (colorName == "Red")
return GetColor().r;
else if ( colorName == "Green")
else if (colorName == "Green")
return GetColor().g;
else if ( colorName == "Blue")
else if (colorName == "Blue")
return GetColor().b;
else if ( colorName == "Alpha")
else if (colorName == "Alpha")
return GetColor().a;
else
return 0;
}
Gwen::String ColorPicker::GetColorFromName( Gwen::String name )
Gwen::String ColorPicker::GetColorFromName(Gwen::String name)
{
if ( name.find("Red") != Gwen::String::npos )
if (name.find("Red") != Gwen::String::npos)
return "Red";
if ( name.find("Green") != Gwen::String::npos )
if (name.find("Green") != Gwen::String::npos)
return "Green";
if ( name.find("Blue") != Gwen::String::npos )
if (name.find("Blue") != Gwen::String::npos)
return "Blue";
if ( name.find("Alpha") != Gwen::String::npos )
if (name.find("Alpha") != Gwen::String::npos)
return "Alpha";
else
return "";
}
void ColorPicker::SetColorByName( Gwen::String colorName, int colorValue )
void ColorPicker::SetColorByName(Gwen::String colorName, int colorValue)
{
if ( colorName == "Red")
SetRed( colorValue );
else if ( colorName == "Green")
SetGreen( colorValue );
else if ( colorName == "Blue")
SetBlue( colorValue );
else if ( colorName == "Alpha")
SetAlpha( colorValue );
if (colorName == "Red")
SetRed(colorValue);
else if (colorName == "Green")
SetGreen(colorValue);
else if (colorName == "Blue")
SetBlue(colorValue);
else if (colorName == "Alpha")
SetAlpha(colorValue);
}
void ColorPicker::SetAlphaVisible( bool visible )
void ColorPicker::SetAlphaVisible(bool visible)
{
GroupBox* groupBox = FindChildByName( "Alphagroupbox", true )->DynamicCastGroupBox();
groupBox->SetHidden( !visible );
GroupBox* groupBox = FindChildByName("Alphagroupbox", true)->DynamicCastGroupBox();
groupBox->SetHidden(!visible);
Invalidate();
}

View File

@@ -12,78 +12,74 @@
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace ControlsInternal
namespace ControlsInternal
{
class GWEN_EXPORT ColorDisplay : public Controls::Base
{
public:
GWEN_CONTROL_INLINE(ColorDisplay, Controls::Base)
{
class GWEN_EXPORT ColorDisplay : public Controls::Base
{
public:
GWEN_CONTROL_INLINE( ColorDisplay, Controls::Base )
{
SetSize( 32, 32 );
m_Color = Color( 255, 0, 0, 255 );
m_DrawCheckers = true;
}
virtual void Render( Gwen::Skin::Base* skin )
{
skin->DrawColorDisplay( this, m_Color );
}
virtual void SetColor( Gwen::Color color ) { m_Color = color; }
virtual Gwen::Color GetColor() { return m_Color; }
virtual void SetRed( int red ) { m_Color.r = red; }
virtual void SetGreen( int green ) { m_Color.g = green;}
virtual void SetBlue( int blue ) { m_Color.b = blue; }
virtual void SetAlpha( int alpha ) { m_Color.a = alpha;}
virtual void SetDrawCheckers( bool should ) { m_DrawCheckers = should; }
protected:
Gwen::Color m_Color;
bool m_DrawCheckers;
};
SetSize(32, 32);
m_Color = Color(255, 0, 0, 255);
m_DrawCheckers = true;
}
namespace Controls
virtual void Render(Gwen::Skin::Base* skin)
{
class GWEN_EXPORT ColorPicker : public Base
{
public:
GWEN_CONTROL( ColorPicker, Base );
virtual void Render( Skin::Base* skin );
virtual void Layout( Skin::Base* skin );
virtual void CreateControls();
virtual void SlidersMoved( Gwen::Controls::Base* control );
virtual void NumericTyped( Gwen::Controls::Base* control );
virtual void UpdateControls();
virtual void UpdateColorControls( Gwen::String name, Gwen::Color col, int sliderVal );
virtual void CreateColorControl( Gwen::String name, int y );
virtual void SetColor( Gwen::Color color );
virtual Gwen::Color GetColor() { return m_Color; }
int GetColorByName( Gwen::String colorName );
void SetColorByName( Gwen::String colorName, int colorValue );
Gwen::String GetColorFromName( Gwen::String name );
virtual void SetAlphaVisible( bool visible );
virtual void SetRed( int red ) { m_Color.r = red; }
virtual void SetGreen( int green ) { m_Color.g = green;}
virtual void SetBlue( int blue ) { m_Color.b = blue; }
virtual void SetAlpha( int alpha ) { m_Color.a = alpha;}
Event::Caller onColorChanged;
protected:
Gwen::Color m_Color;
};
skin->DrawColorDisplay(this, m_Color);
}
}
virtual void SetColor(Gwen::Color color) { m_Color = color; }
virtual Gwen::Color GetColor() { return m_Color; }
virtual void SetRed(int red) { m_Color.r = red; }
virtual void SetGreen(int green) { m_Color.g = green; }
virtual void SetBlue(int blue) { m_Color.b = blue; }
virtual void SetAlpha(int alpha) { m_Color.a = alpha; }
virtual void SetDrawCheckers(bool should) { m_DrawCheckers = should; }
protected:
Gwen::Color m_Color;
bool m_DrawCheckers;
};
} // namespace ControlsInternal
namespace Controls
{
class GWEN_EXPORT ColorPicker : public Base
{
public:
GWEN_CONTROL(ColorPicker, Base);
virtual void Render(Skin::Base* skin);
virtual void Layout(Skin::Base* skin);
virtual void CreateControls();
virtual void SlidersMoved(Gwen::Controls::Base* control);
virtual void NumericTyped(Gwen::Controls::Base* control);
virtual void UpdateControls();
virtual void UpdateColorControls(Gwen::String name, Gwen::Color col, int sliderVal);
virtual void CreateColorControl(Gwen::String name, int y);
virtual void SetColor(Gwen::Color color);
virtual Gwen::Color GetColor() { return m_Color; }
int GetColorByName(Gwen::String colorName);
void SetColorByName(Gwen::String colorName, int colorValue);
Gwen::String GetColorFromName(Gwen::String name);
virtual void SetAlphaVisible(bool visible);
virtual void SetRed(int red) { m_Color.r = red; }
virtual void SetGreen(int green) { m_Color.g = green; }
virtual void SetBlue(int blue) { m_Color.b = blue; }
virtual void SetAlpha(int alpha) { m_Color.a = alpha; }
Event::Caller onColorChanged;
protected:
Gwen::Color m_Color;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,89 +4,81 @@
See license in Gwen.h
*/
#include "Gwen/Controls/ComboBox.h"
#include "Gwen/Controls/Menu.h"
using namespace Gwen;
using namespace Gwen::Controls;
using namespace Gwen::ControlsInternal;
class GWEN_EXPORT DownArrow : public Controls::Base
{
public:
public:
GWEN_CONTROL_INLINE(DownArrow, Controls::Base)
{
SetMouseInputEnabled(true);
SetSize(15, 15);
}
GWEN_CONTROL_INLINE( DownArrow, Controls::Base )
{
SetMouseInputEnabled( true );
SetSize( 15, 15 );
void Render(Skin::Base* skin)
{
skin->DrawArrowDown(this->m_Bounds);
}
}
void SetComboBox(ComboBox* p) { m_ComboBox = p; }
void Render( Skin::Base* skin )
{
skin->DrawArrowDown(this->m_Bounds);
}
void SetComboBox( ComboBox* p ){ m_ComboBox = p; }
protected:
ComboBox* m_ComboBox;
protected:
ComboBox* m_ComboBox;
};
GWEN_CONTROL_CONSTRUCTOR( ComboBox )
GWEN_CONTROL_CONSTRUCTOR(ComboBox)
{
SetSize( 100, 20 );
SetMouseInputEnabled( true );
SetSize(100, 20);
SetMouseInputEnabled(true);
m_Menu = new Menu( this );
m_Menu->SetHidden( true );
m_Menu->SetDisableIconMargin( true );
m_Menu->SetTabable( false );
m_Menu = new Menu(this);
m_Menu->SetHidden(true);
m_Menu->SetDisableIconMargin(true);
m_Menu->SetTabable(false);
ComboBoxButton* m_OpenButton = new ComboBoxButton( this );
ComboBoxButton* m_OpenButton = new ComboBoxButton(this);
m_OpenButton->onDown.Add( this, &ComboBox::OpenButtonPressed );
m_OpenButton->Dock( Pos::Right );
m_OpenButton->SetMargin( Margin( 2, 2, 2, 2 ) );
m_OpenButton->SetWidth( 16 );
m_OpenButton->SetTabable( false );
m_OpenButton->onDown.Add(this, &ComboBox::OpenButtonPressed);
m_OpenButton->Dock(Pos::Right);
m_OpenButton->SetMargin(Margin(2, 2, 2, 2));
m_OpenButton->SetWidth(16);
m_OpenButton->SetTabable(false);
m_SelectedItem = NULL;
SetAlignment( Gwen::Pos::Left | Gwen::Pos::CenterV );
SetText( L"" );
SetMargin( Margin( 3, 0, 0, 0 ) );
SetTabable( true );
SetAlignment(Gwen::Pos::Left | Gwen::Pos::CenterV);
SetText(L"");
SetMargin(Margin(3, 0, 0, 0));
SetTabable(true);
}
MenuItem* ComboBox::AddItem( const UnicodeString& strLabel, const String& strName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn )
MenuItem* ComboBox::AddItem(const UnicodeString& strLabel, const String& strName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn)
{
MenuItem* pItem = m_Menu->AddItem( strLabel, L"", pHandler, fn );
pItem->SetName( strName );
MenuItem* pItem = m_Menu->AddItem(strLabel, L"", pHandler, fn);
pItem->SetName(strName);
pItem->onMenuItemSelected.Add( this, &ComboBox::OnItemSelected );
pItem->onMenuItemSelected.Add(this, &ComboBox::OnItemSelected);
//Default
if ( m_SelectedItem == NULL )
OnItemSelected( pItem );
if (m_SelectedItem == NULL)
OnItemSelected(pItem);
return pItem;
}
void ComboBox::Render( Skin::Base* skin )
void ComboBox::Render(Skin::Base* skin)
{
skin->DrawComboBox( this );
skin->DrawComboBox(this);
}
void ComboBox::OpenButtonPressed( Controls::Base* /*pControl*/ )
void ComboBox::OpenButtonPressed(Controls::Base* /*pControl*/)
{
OnPress();
}
@@ -97,34 +89,34 @@ void ComboBox::OnPress()
GetCanvas()->CloseMenus();
if ( bWasMenuHidden )
if (bWasMenuHidden)
{
OpenList();
}
else
else
{
m_Menu->SetHidden( true );
m_Menu->SetHidden(true);
}
}
void ComboBox::ClearItems()
{
if ( m_Menu )
if (m_Menu)
{
m_Menu->ClearItems();
}
}
void ComboBox::OnItemSelected( Controls::Base* pControl )
void ComboBox::OnItemSelected(Controls::Base* pControl)
{
//Convert selected to a menu item
MenuItem* pItem = pControl->DynamicCastMenuItem();
if ( !pItem ) return;
MenuItem* pItem = pControl->DynamicCastMenuItem();
if (!pItem) return;
m_SelectedItem = pItem;
SetText( m_SelectedItem->GetText() );
m_Menu->SetHidden( true );
SetText(m_SelectedItem->GetText());
m_Menu->SetHidden(true);
onSelection.Call( this );
onSelection.Call(this);
Focus();
Invalidate();
@@ -132,19 +124,18 @@ void ComboBox::OnItemSelected( Controls::Base* pControl )
void ComboBox::OnLostKeyboardFocus()
{
SetTextColor( Color( 0, 0, 0, 255 ) );
SetTextColor(Color(0, 0, 0, 255));
}
void ComboBox::OnKeyboardFocus()
{
//Until we add the blue highlighting again
SetTextColor( Color( 0, 0, 0, 255 ) );
SetTextColor(Color(0, 0, 0, 255));
//m_SelectedText->SetTextColor( Color( 255, 255, 255, 255 ) );
}
Gwen::Controls::Label* ComboBox::GetSelectedItem()
{
{
return m_SelectedItem;
}
@@ -155,54 +146,52 @@ bool ComboBox::IsMenuOpen()
void ComboBox::OpenList()
{
if ( !m_Menu ) return;
if (!m_Menu) return;
m_Menu->SetParent( GetCanvas() );
m_Menu->SetHidden( false );
m_Menu->SetParent(GetCanvas());
m_Menu->SetHidden(false);
m_Menu->BringToFront();
Gwen::Point p = LocalPosToCanvas( Gwen::Point( 0, 0 ) );
Gwen::Point p = LocalPosToCanvas(Gwen::Point(0, 0));
m_Menu->SetBounds( Gwen::Rect ( p.x, p.y + Height(), Width(), m_Menu->Height()) );
m_Menu->SetBounds(Gwen::Rect(p.x, p.y + Height(), Width(), m_Menu->Height()));
}
void ComboBox::CloseList()
{
}
bool ComboBox::OnKeyUp( bool bDown )
bool ComboBox::OnKeyUp(bool bDown)
{
if ( bDown )
if (bDown)
{
Base::List & children = m_Menu->GetChildren();
Base::List::reverse_iterator it = std::find( children.rbegin(), children.rend(), m_SelectedItem );
Base::List& children = m_Menu->GetChildren();
Base::List::reverse_iterator it = std::find(children.rbegin(), children.rend(), m_SelectedItem);
if ( it != children.rend() && ( ++it != children.rend() ) )
if (it != children.rend() && (++it != children.rend()))
{
Base* pUpElement = *it;
OnItemSelected( pUpElement );
OnItemSelected(pUpElement);
}
}
return true;
}
bool ComboBox::OnKeyDown( bool bDown )
bool ComboBox::OnKeyDown(bool bDown)
{
if ( bDown )
if (bDown)
{
Base::List & children = m_Menu->GetChildren();
Base::List::iterator it = std::find( children.begin(), children.end(), m_SelectedItem );
Base::List& children = m_Menu->GetChildren();
Base::List::iterator it = std::find(children.begin(), children.end(), m_SelectedItem);
if ( it != children.end() && ( ++it != children.end() ) )
if (it != children.end() && (++it != children.end()))
{
Base* pDownElement = *it;
OnItemSelected( pDownElement );
OnItemSelected(pDownElement);
}
}
return true;
}
void ComboBox::RenderFocus( Gwen::Skin::Base* /*skin*/ )
void ComboBox::RenderFocus(Gwen::Skin::Base* /*skin*/)
{
}

View File

@@ -15,73 +15,69 @@
#include "Gwen/Controls/TextBox.h"
#include "Gwen/Controls/Menu.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class GWEN_EXPORT ComboBoxButton : public Button
{
GWEN_CONTROL_INLINE(ComboBoxButton, Button) {}
virtual void Render(Skin::Base* skin)
{
class GWEN_EXPORT ComboBoxButton : public Button
{
GWEN_CONTROL_INLINE( ComboBoxButton, Button ){}
virtual void Render( Skin::Base* skin )
{
skin->DrawComboBoxButton( this, m_bDepressed );
}
};
class GWEN_EXPORT ComboBox : public Button
{
public:
GWEN_CONTROL( ComboBox, Button );
virtual void Render( Skin::Base* skin );
virtual Gwen::Controls::Label* GetSelectedItem();
virtual void OnPress();
void OpenButtonPressed( Controls::Base* /*pControl*/ );
virtual void OnItemSelected( Controls::Base* pControl );
virtual void OpenList();
virtual void CloseList();
virtual Controls::Base* GetControlAt( int x, int y )
{
if ( x < 0 || y < 0 || x >= Width() || y >= Height() )
return NULL;
return this;
}
virtual bool IsMenuComponent()
{
return true;
}
virtual void ClearItems();
virtual MenuItem* AddItem( const UnicodeString& strLabel, const String& strName = "", Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL );
virtual bool OnKeyUp( bool bDown );
virtual bool OnKeyDown( bool bDown );
virtual void RenderFocus( Gwen::Skin::Base* skin );
virtual void OnLostKeyboardFocus();
virtual void OnKeyboardFocus();
virtual bool IsMenuOpen();
Gwen::Event::Caller onSelection;
protected:
Menu* m_Menu;
MenuItem* m_SelectedItem;
Controls::Base* m_Button;
};
skin->DrawComboBoxButton(this, m_bDepressed);
}
}
};
class GWEN_EXPORT ComboBox : public Button
{
public:
GWEN_CONTROL(ComboBox, Button);
virtual void Render(Skin::Base* skin);
virtual Gwen::Controls::Label* GetSelectedItem();
virtual void OnPress();
void OpenButtonPressed(Controls::Base* /*pControl*/);
virtual void OnItemSelected(Controls::Base* pControl);
virtual void OpenList();
virtual void CloseList();
virtual Controls::Base* GetControlAt(int x, int y)
{
if (x < 0 || y < 0 || x >= Width() || y >= Height())
return NULL;
return this;
}
virtual bool IsMenuComponent()
{
return true;
}
virtual void ClearItems();
virtual MenuItem* AddItem(const UnicodeString& strLabel, const String& strName = "", Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL);
virtual bool OnKeyUp(bool bDown);
virtual bool OnKeyDown(bool bDown);
virtual void RenderFocus(Gwen::Skin::Base* skin);
virtual void OnLostKeyboardFocus();
virtual void OnKeyboardFocus();
virtual bool IsMenuOpen();
Gwen::Event::Caller onSelection;
protected:
Menu* m_Menu;
MenuItem* m_SelectedItem;
Controls::Base* m_Button;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -5,48 +5,48 @@
using namespace Gwen;
using namespace Controls;
GWEN_CONTROL_CONSTRUCTOR( CrossSplitter )
GWEN_CONTROL_CONSTRUCTOR(CrossSplitter)
{
m_VSplitter = new SplitterBar( this );
m_VSplitter->SetPos( 0, 128 );
m_VSplitter->onDragged.Add( this, &CrossSplitter::OnVerticalMoved );
m_VSplitter->SetCursor( Gwen::CursorType::SizeNS );
m_VSplitter = new SplitterBar(this);
m_VSplitter->SetPos(0, 128);
m_VSplitter->onDragged.Add(this, &CrossSplitter::OnVerticalMoved);
m_VSplitter->SetCursor(Gwen::CursorType::SizeNS);
m_HSplitter = new SplitterBar( this );
m_HSplitter->SetPos( 128, 0 );
m_HSplitter->onDragged.Add( this, &CrossSplitter::OnHorizontalMoved );
m_HSplitter->SetCursor( Gwen::CursorType::SizeWE );
m_HSplitter = new SplitterBar(this);
m_HSplitter->SetPos(128, 0);
m_HSplitter->onDragged.Add(this, &CrossSplitter::OnHorizontalMoved);
m_HSplitter->SetCursor(Gwen::CursorType::SizeWE);
m_CSplitter = new SplitterBar( this );
m_CSplitter->SetPos( 128, 128 );
m_CSplitter->onDragged.Add( this, &CrossSplitter::OnCenterMoved );
m_CSplitter->SetCursor( Gwen::CursorType::SizeAll );
m_CSplitter = new SplitterBar(this);
m_CSplitter->SetPos(128, 128);
m_CSplitter->onDragged.Add(this, &CrossSplitter::OnCenterMoved);
m_CSplitter->SetCursor(Gwen::CursorType::SizeAll);
m_fHVal = 0.5f;
m_fVVal = 0.5f;
SetPanel( 0, NULL );
SetPanel( 1, NULL );
SetPanel( 2, NULL );
SetPanel( 3, NULL );
SetPanel(0, NULL);
SetPanel(1, NULL);
SetPanel(2, NULL);
SetPanel(3, NULL);
SetSplitterSize( 5 );
SetSplittersVisible( false );
SetSplitterSize(5);
SetSplittersVisible(false);
m_iZoomedSection = -1;
}
void CrossSplitter::UpdateVSplitter()
{
m_VSplitter->MoveTo( m_VSplitter->X(), ( Height() - m_VSplitter->Height() ) * ( m_fVVal ));
m_VSplitter->MoveTo(m_VSplitter->X(), (Height() - m_VSplitter->Height()) * (m_fVVal));
}
void CrossSplitter::UpdateHSplitter()
{
m_HSplitter->MoveTo( ( Width() - m_HSplitter->Width() ) * ( m_fHVal ), m_HSplitter->Y() );
m_HSplitter->MoveTo((Width() - m_HSplitter->Width()) * (m_fHVal), m_HSplitter->Y());
}
void CrossSplitter::OnCenterMoved( Controls::Base * /*control*/ )
{
void CrossSplitter::OnCenterMoved(Controls::Base* /*control*/)
{
//Move the other two bars into position
CalculateValueCenter();
Invalidate();
@@ -54,111 +54,110 @@ void CrossSplitter::OnCenterMoved( Controls::Base * /*control*/ )
void CrossSplitter::UpdateCSplitter()
{
m_CSplitter->MoveTo( ( Width() - m_CSplitter->Width() ) * ( m_fHVal ), ( Height() - m_CSplitter->Height() ) * ( m_fVVal ));
m_CSplitter->MoveTo((Width() - m_CSplitter->Width()) * (m_fHVal), (Height() - m_CSplitter->Height()) * (m_fVVal));
}
void CrossSplitter::OnHorizontalMoved( Controls::Base * /*control*/ )
{
void CrossSplitter::OnHorizontalMoved(Controls::Base* /*control*/)
{
m_fHVal = CalculateValueHorizontal();
Invalidate();
}
void CrossSplitter::OnVerticalMoved( Controls::Base * /*control*/ )
void CrossSplitter::OnVerticalMoved(Controls::Base* /*control*/)
{
m_fVVal = CalculateValueVertical();
m_fVVal = CalculateValueVertical();
Invalidate();
}
void CrossSplitter::CalculateValueCenter()
{
m_fHVal = (float)m_CSplitter->X() / (float)( Width() - m_CSplitter->Width() );
m_fVVal = (float)m_CSplitter->Y() / (float)( Height() - m_CSplitter->Height() );
m_fHVal = (float)m_CSplitter->X() / (float)(Width() - m_CSplitter->Width());
m_fVVal = (float)m_CSplitter->Y() / (float)(Height() - m_CSplitter->Height());
}
float CrossSplitter::CalculateValueHorizontal()
{
return (float)m_HSplitter->X() / (float)( Width() - m_HSplitter->Width() );
return (float)m_HSplitter->X() / (float)(Width() - m_HSplitter->Width());
}
float CrossSplitter::CalculateValueVertical()
{
return (float)m_VSplitter->Y() / (float)( Height() - m_VSplitter->Height() );
return (float)m_VSplitter->Y() / (float)(Height() - m_VSplitter->Height());
}
void CrossSplitter::Layout( Skin::Base* /*skin*/ )
void CrossSplitter::Layout(Skin::Base* /*skin*/)
{
m_VSplitter->SetSize( Width(), m_fBarSize );
m_HSplitter->SetSize( m_fBarSize, Height() );
m_CSplitter->SetSize( m_fBarSize, m_fBarSize );
m_VSplitter->SetSize(Width(), m_fBarSize);
m_HSplitter->SetSize(m_fBarSize, Height());
m_CSplitter->SetSize(m_fBarSize, m_fBarSize);
UpdateVSplitter();
UpdateHSplitter();
UpdateCSplitter();
if ( m_iZoomedSection == -1 )
if (m_iZoomedSection == -1)
{
if ( m_Sections[0] )
m_Sections[0]->SetBounds( 0, 0, m_HSplitter->X(), m_VSplitter->Y() );
if (m_Sections[0])
m_Sections[0]->SetBounds(0, 0, m_HSplitter->X(), m_VSplitter->Y());
if ( m_Sections[1] )
m_Sections[1]->SetBounds( m_HSplitter->X() + m_fBarSize, 0, Width() - ( m_HSplitter->X() + m_fBarSize ), m_VSplitter->Y() );
if (m_Sections[1])
m_Sections[1]->SetBounds(m_HSplitter->X() + m_fBarSize, 0, Width() - (m_HSplitter->X() + m_fBarSize), m_VSplitter->Y());
if ( m_Sections[2] )
m_Sections[2]->SetBounds( 0, m_VSplitter->Y() + m_fBarSize, m_HSplitter->X(), Height() - ( m_VSplitter->Y() + m_fBarSize ) );
if (m_Sections[2])
m_Sections[2]->SetBounds(0, m_VSplitter->Y() + m_fBarSize, m_HSplitter->X(), Height() - (m_VSplitter->Y() + m_fBarSize));
if ( m_Sections[3] )
m_Sections[3]->SetBounds( m_HSplitter->X() + m_fBarSize, m_VSplitter->Y() + m_fBarSize, Width() - ( m_HSplitter->X() + m_fBarSize ), Height() - ( m_VSplitter->Y() + m_fBarSize ) );
if (m_Sections[3])
m_Sections[3]->SetBounds(m_HSplitter->X() + m_fBarSize, m_VSplitter->Y() + m_fBarSize, Width() - (m_HSplitter->X() + m_fBarSize), Height() - (m_VSplitter->Y() + m_fBarSize));
}
else
{
//This should probably use Fill docking instead
m_Sections[(int)m_iZoomedSection]->SetBounds( 0, 0, Width(), Height() );
m_Sections[(int)m_iZoomedSection]->SetBounds(0, 0, Width(), Height());
}
}
void CrossSplitter::SetPanel( int index, Controls::Base* pPanel)
void CrossSplitter::SetPanel(int index, Controls::Base* pPanel)
{
Debug::AssertCheck( index >= 0 && index <= 3, "CrossSplitter::SetPanel out of range" );
Debug::AssertCheck(index >= 0 && index <= 3, "CrossSplitter::SetPanel out of range");
m_Sections[index] = pPanel;
if ( pPanel )
if (pPanel)
{
pPanel->Dock( Pos::None );
pPanel->SetParent( this );
pPanel->Dock(Pos::None);
pPanel->SetParent(this);
}
Invalidate();
}
Controls::Base* CrossSplitter::GetPanel( int i )
Controls::Base* CrossSplitter::GetPanel(int i)
{
return m_Sections[i];
}
void CrossSplitter::ZoomChanged()
{
onZoomChange.Call( this );
if ( m_iZoomedSection == -1 )
onZoomChange.Call(this);
if (m_iZoomedSection == -1)
{
onUnZoomed.Call( this );
onUnZoomed.Call(this);
}
else
{
onZoomed.Call( this );
onZoomed.Call(this);
}
}
void CrossSplitter::Zoom( int section )
void CrossSplitter::Zoom(int section)
{
UnZoom();
if ( m_Sections[section] )
if (m_Sections[section])
{
for (int i = 0; i < 4; i++)
{
if ( i != section && m_Sections[i] )
m_Sections[i]->SetHidden( true );
if (i != section && m_Sections[i])
m_Sections[i]->SetHidden(true);
}
m_iZoomedSection = section;
@@ -171,10 +170,10 @@ void CrossSplitter::UnZoom()
{
m_iZoomedSection = -1;
for ( int i = 0; i < 4; i++ )
for (int i = 0; i < 4; i++)
{
if ( m_Sections[i] )
m_Sections[i]->SetHidden( false );
if (m_Sections[i])
m_Sections[i]->SetHidden(false);
}
Invalidate();

View File

@@ -6,58 +6,66 @@
#include "Gwen/Controls/Base.h"
#include "Gwen/Controls/SplitterBar.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class GWEN_EXPORT CrossSplitter : public Controls::Base
{
public:
GWEN_CONTROL(CrossSplitter, Controls::Base);
void Layout(Skin::Base* skin);
virtual float CalculateValueVertical();
virtual float CalculateValueHorizontal();
virtual void CalculateValueCenter();
virtual void UpdateHSplitter();
virtual void UpdateVSplitter();
virtual void UpdateCSplitter();
virtual void OnVerticalMoved(Controls::Base* control);
virtual void OnHorizontalMoved(Controls::Base* control);
virtual void OnCenterMoved(Controls::Base* control);
virtual void SetPanel(int i, Controls::Base* pPanel);
virtual Controls::Base* GetPanel(int i);
virtual bool IsZoomed() { return m_iZoomedSection != -1; }
virtual void Zoom(int section);
virtual void UnZoom();
virtual void ZoomChanged();
virtual void CenterPanels()
{
class GWEN_EXPORT CrossSplitter : public Controls::Base
{
public:
GWEN_CONTROL( CrossSplitter, Controls::Base );
void Layout( Skin::Base* skin );
virtual float CalculateValueVertical();
virtual float CalculateValueHorizontal();
virtual void CalculateValueCenter();
virtual void UpdateHSplitter();
virtual void UpdateVSplitter();
virtual void UpdateCSplitter();
virtual void OnVerticalMoved( Controls::Base * control );
virtual void OnHorizontalMoved( Controls::Base * control );
virtual void OnCenterMoved( Controls::Base * control );
virtual void SetPanel( int i, Controls::Base* pPanel );
virtual Controls::Base* GetPanel( int i );
virtual bool IsZoomed(){ return m_iZoomedSection != -1; }
virtual void Zoom( int section );
virtual void UnZoom();
virtual void ZoomChanged();
virtual void CenterPanels() { m_fHVal = 0.5f; m_fVVal = 0.5f; Invalidate(); }
virtual void SetSplittersVisible( bool b ){ m_VSplitter->SetShouldDrawBackground( b ); m_HSplitter->SetShouldDrawBackground( b ); m_CSplitter->SetShouldDrawBackground( b ); }
virtual void SetSplitterSize( int size ) { m_fBarSize = size; }
private:
SplitterBar* m_VSplitter;
SplitterBar* m_HSplitter;
SplitterBar* m_CSplitter;
Controls::Base* m_Sections[4];
float m_fHVal;
float m_fVVal;
int m_fBarSize;
int m_iZoomedSection;
Gwen::Event::Caller onZoomed;
Gwen::Event::Caller onUnZoomed;
Gwen::Event::Caller onZoomChange;
};
m_fHVal = 0.5f;
m_fVVal = 0.5f;
Invalidate();
}
}
virtual void SetSplittersVisible(bool b)
{
m_VSplitter->SetShouldDrawBackground(b);
m_HSplitter->SetShouldDrawBackground(b);
m_CSplitter->SetShouldDrawBackground(b);
}
virtual void SetSplitterSize(int size) { m_fBarSize = size; }
private:
SplitterBar* m_VSplitter;
SplitterBar* m_HSplitter;
SplitterBar* m_CSplitter;
Controls::Base* m_Sections[4];
float m_fHVal;
float m_fVVal;
int m_fBarSize;
int m_iZoomedSection;
Gwen::Event::Caller onZoomed;
Gwen::Event::Caller onUnZoomed;
Gwen::Event::Caller onZoomChange;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -11,9 +11,9 @@
using namespace Gwen;
using namespace Gwen::Dialogs;
void Gwen::Dialogs::FileOpenEx( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::FunctionStr fnCallback )
void Gwen::Dialogs::FileOpenEx(bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::FunctionStr fnCallback)
{
if ( bUseSystem && Gwen::Platform::FileOpen( Name, StartPath, Extension, pHandler, fnCallback ) )
if (bUseSystem && Gwen::Platform::FileOpen(Name, StartPath, Extension, pHandler, fnCallback))
{
return;
}

View File

@@ -11,9 +11,9 @@
using namespace Gwen;
using namespace Gwen::Dialogs;
void Gwen::Dialogs::FileSaveEx( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::FunctionStr fnCallback )
void Gwen::Dialogs::FileSaveEx(bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::FunctionStr fnCallback)
{
if ( bUseSystem && Gwen::Platform::FileSave( Name, StartPath, Extension, pHandler, fnCallback ) )
if (bUseSystem && Gwen::Platform::FileSave(Name, StartPath, Extension, pHandler, fnCallback))
{
return;
}

View File

@@ -9,4 +9,3 @@
using namespace Gwen;
using namespace Gwen::Controls;

View File

@@ -4,32 +4,31 @@
#include "Gwen/Gwen.h"
namespace Gwen
namespace Gwen
{
namespace Dialogs
{
// Usage:
//
// Gwen::Dialogs::FileOpen( true, "Open Map", "C:\my\folder\", "My Map Format|*.bmf", this, &MyClass::OpenFilename );
//
namespace Dialogs
{
// Usage:
//
// Gwen::Dialogs::FileOpen( true, "Open Map", "C:\my\folder\", "My Map Format|*.bmf", this, &MyClass::OpenFilename );
//
//
// The REAL function.
// If bUseSystem is used, it may use the system's modal dialog - which
// will steal focus and pause the rest of GWEN until it's continued.
//
void GWEN_EXPORT FileOpenEx( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::FunctionStr fnCallback = NULL );
//
// The REAL function.
// If bUseSystem is used, it may use the system's modal dialog - which
// will steal focus and pause the rest of GWEN until it's continued.
//
void GWEN_EXPORT FileOpenEx(bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::FunctionStr fnCallback = NULL);
//
// Templated function simply to avoid having to manually cast the callback function.
//
template< typename A>
void FileOpen( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, A fnCallback = NULL )
{
FileOpenEx( bUseSystem, Name, StartPath, Extension, pHandler, (Gwen::Event::Handler::FunctionStr)fnCallback );
}
}
//
// Templated function simply to avoid having to manually cast the callback function.
//
template <typename A>
void FileOpen(bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, A fnCallback = NULL)
{
FileOpenEx(bUseSystem, Name, StartPath, Extension, pHandler, (Gwen::Event::Handler::FunctionStr)fnCallback);
}
} // namespace Dialogs
} // namespace Gwen
#endif

View File

@@ -4,37 +4,36 @@
#include "Gwen/Gwen.h"
namespace Gwen
namespace Gwen
{
namespace Dialogs
{
// Usage:
//
// Gwen::Dialogs::FileOpen( true, "Open Map", "C:\my\folder\", "My Map Format|*.bmf", this, &MyClass::OpenFilename );
//
namespace Dialogs
{
// Usage:
//
// Gwen::Dialogs::FileOpen( true, "Open Map", "C:\my\folder\", "My Map Format|*.bmf", this, &MyClass::OpenFilename );
//
//
// Callback function, for success
//
typedef void (Event::Handler::*FileSaveSuccessCallback)( const String& filename );
//
// Callback function, for success
//
typedef void (Event::Handler::*FileSaveSuccessCallback)(const String& filename);
//
// The REAL function.
// If bUseSystem is used, it may use the system's modal dialog - which
// will steal focus and pause the rest of GWEN until it's continued.
//
void GWEN_EXPORT FileSaveEx( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::FunctionStr fnCallback = NULL );
//
// The REAL function.
// If bUseSystem is used, it may use the system's modal dialog - which
// will steal focus and pause the rest of GWEN until it's continued.
//
void GWEN_EXPORT FileSaveEx(bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::FunctionStr fnCallback = NULL);
//
// Templated function simply to avoid having to manually cast the callback function.
//
template< typename A>
void FileSave( bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, A fnCallback = NULL )
{
FileSaveEx( bUseSystem, Name, StartPath, Extension, pHandler, (Gwen::Event::Handler::FunctionStr)fnCallback );
}
}
//
// Templated function simply to avoid having to manually cast the callback function.
//
template <typename A>
void FileSave(bool bUseSystem, const String& Name, const String& StartPath, const String& Extension, Gwen::Event::Handler* pHandler = NULL, A fnCallback = NULL)
{
FileSaveEx(bUseSystem, Name, StartPath, Extension, pHandler, (Gwen::Event::Handler::FunctionStr)fnCallback);
}
} // namespace Dialogs
} // namespace Gwen
#endif

View File

@@ -4,11 +4,11 @@
#include "Gwen/Gwen.h"
namespace Gwen
namespace Gwen
{
namespace Dialogs
{
//TODO. YesNo, Ok etc
}
namespace Dialogs
{
//TODO. YesNo, Ok etc
}
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
#include "Gwen/Controls/DockBase.h"
@@ -16,11 +15,10 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( DockBase )
GWEN_CONTROL_CONSTRUCTOR(DockBase)
{
SetPadding( Padding( 1, 1, 1, 1 ) );
SetSize( 200, 200 );
SetPadding(Padding(1, 1, 1, 1));
SetSize(200, 200);
m_DockedTabControl = NULL;
m_Left = NULL;
@@ -32,139 +30,141 @@ GWEN_CONTROL_CONSTRUCTOR( DockBase )
}
TabControl* DockBase::GetTabControl()
{
return m_DockedTabControl;
{
return m_DockedTabControl;
}
void DockBase::SetupChildDock( int iPos )
void DockBase::SetupChildDock(int iPos)
{
if ( !m_DockedTabControl )
if (!m_DockedTabControl)
{
m_DockedTabControl = new DockedTabControl( this );
m_DockedTabControl->onLoseTab.Add( this, &DockBase::OnTabRemoved );
m_DockedTabControl->SetTabStripPosition( Pos::Bottom );
m_DockedTabControl->SetShowTitlebar( true );
m_DockedTabControl = new DockedTabControl(this);
m_DockedTabControl->onLoseTab.Add(this, &DockBase::OnTabRemoved);
m_DockedTabControl->SetTabStripPosition(Pos::Bottom);
m_DockedTabControl->SetShowTitlebar(true);
}
Dock( iPos );
Dock(iPos);
int iSizeDirection = Pos::Left;
if ( iPos == Pos::Left ) iSizeDirection = Pos::Right;
if ( iPos == Pos::Top ) iSizeDirection = Pos::Bottom;
if ( iPos == Pos::Bottom ) iSizeDirection = Pos::Top;
if (iPos == Pos::Left) iSizeDirection = Pos::Right;
if (iPos == Pos::Top) iSizeDirection = Pos::Bottom;
if (iPos == Pos::Bottom) iSizeDirection = Pos::Top;
ControlsInternal::Resizer* sizer = new ControlsInternal::Resizer( this );
sizer->Dock( iSizeDirection );
sizer->SetResizeDir( iSizeDirection );
sizer->SetSize( 2, 2 );
sizer->SetTarget( this );
ControlsInternal::Resizer* sizer = new ControlsInternal::Resizer(this);
sizer->Dock(iSizeDirection);
sizer->SetResizeDir(iSizeDirection);
sizer->SetSize(2, 2);
sizer->SetTarget(this);
}
void DockBase::Render( Skin::Base* /*skin*/ )
void DockBase::Render(Skin::Base* /*skin*/)
{
//Gwen::Render->SetDrawColor( Colors::Black );
//Gwen::Render->DrawLinedRect( GetRenderBounds() );
}
DockBase** DockBase::GetChildDockPtr( int iPos )
DockBase** DockBase::GetChildDockPtr(int iPos)
{
if ( iPos == Pos::Left ) return &m_Left;
if ( iPos == Pos::Right ) return &m_Right;
if ( iPos == Pos::Top ) return &m_Top;
if ( iPos == Pos::Bottom ) return &m_Bottom;
if (iPos == Pos::Left) return &m_Left;
if (iPos == Pos::Right) return &m_Right;
if (iPos == Pos::Top) return &m_Top;
if (iPos == Pos::Bottom) return &m_Bottom;
return NULL;
}
DockBase* DockBase::GetChildDock( int iPos )
DockBase* DockBase::GetChildDock(int iPos)
{
DockBase** pDock = GetChildDockPtr( iPos );
if ( !(*pDock) )
DockBase** pDock = GetChildDockPtr(iPos);
if (!(*pDock))
{
(*pDock) = new DockBase( this );
(*pDock)->SetupChildDock( iPos );
(*pDock) = new DockBase(this);
(*pDock)->SetupChildDock(iPos);
}
else
{
(*pDock)->SetHidden( false );
(*pDock)->SetHidden(false);
}
return *pDock;
}
int DockBase::GetDroppedTabDirection( int x, int y )
int DockBase::GetDroppedTabDirection(int x, int y)
{
int w = Width();
int h = Height();
float top = (float)y / (float) h;
float left = (float)x / (float) w;
float right = (float)(w - x) /(float) w;
float bottom = (float)(h - y) / (float) h;
float top = (float)y / (float)h;
float left = (float)x / (float)w;
float right = (float)(w - x) / (float)w;
float bottom = (float)(h - y) / (float)h;
float minimum = GwenUtil_Min( GwenUtil_Min( GwenUtil_Min( top, left ), right ), bottom );
m_bDropFar = ( minimum < 0.2f );
if ( minimum > 0.3 ) return Pos::Fill;
float minimum = GwenUtil_Min(GwenUtil_Min(GwenUtil_Min(top, left), right), bottom);
m_bDropFar = (minimum < 0.2f);
if (minimum > 0.3) return Pos::Fill;
if ( top == minimum && (!m_Top || m_Top->Hidden()) ) return Pos::Top;
if ( left == minimum && (!m_Left || m_Left->Hidden()) ) return Pos::Left;
if ( right == minimum && (!m_Right || m_Right->Hidden()) ) return Pos::Right;
if ( bottom == minimum && (!m_Bottom || m_Bottom->Hidden()) ) return Pos::Bottom;
if (top == minimum && (!m_Top || m_Top->Hidden())) return Pos::Top;
if (left == minimum && (!m_Left || m_Left->Hidden())) return Pos::Left;
if (right == minimum && (!m_Right || m_Right->Hidden())) return Pos::Right;
if (bottom == minimum && (!m_Bottom || m_Bottom->Hidden())) return Pos::Bottom;
return Pos::Fill;
}
bool DockBase::DragAndDrop_CanAcceptPackage( Gwen::DragAndDrop::Package* pPackage )
bool DockBase::DragAndDrop_CanAcceptPackage(Gwen::DragAndDrop::Package* pPackage)
{
// A TAB button dropped
if ( pPackage->name == "TabButtonMove" )
// A TAB button dropped
if (pPackage->name == "TabButtonMove")
return true;
// a TAB window dropped
if ( pPackage->name == "TabWindowMove" )
if (pPackage->name == "TabWindowMove")
return true;
return false;
}
void AddTabToDock( TabButton* pTabButton, DockedTabControl* pControl )
void AddTabToDock(TabButton* pTabButton, DockedTabControl* pControl)
{
pControl->AddPage( pTabButton );
pControl->AddPage(pTabButton);
}
bool DockBase::DragAndDrop_HandleDrop( Gwen::DragAndDrop::Package* pPackage, int x, int y )
bool DockBase::DragAndDrop_HandleDrop(Gwen::DragAndDrop::Package* pPackage, int x, int y)
{
Gwen::Point pPos = CanvasPosToLocal( Gwen::Point( x, y ) );
int dir = GetDroppedTabDirection( pPos.x, pPos.y );
Gwen::Point pPos = CanvasPosToLocal(Gwen::Point(x, y));
int dir = GetDroppedTabDirection(pPos.x, pPos.y);
DockedTabControl* pAddTo = m_DockedTabControl;
if ( dir == Pos::Fill && pAddTo == NULL ) return false;
if (dir == Pos::Fill && pAddTo == NULL) return false;
if ( dir != Pos::Fill )
if (dir != Pos::Fill)
{
DockBase* pDock = GetChildDock( dir );
DockBase* pDock = GetChildDock(dir);
pAddTo = pDock->m_DockedTabControl;
if ( !m_bDropFar ) pDock->BringToFront();
else pDock->SendToBack();
if (!m_bDropFar)
pDock->BringToFront();
else
pDock->SendToBack();
}
if ( pPackage->name == "TabButtonMove" )
if (pPackage->name == "TabButtonMove")
{
TabButton* pTabButton = DragAndDrop::SourceControl->DynamicCastTabButton();
if ( !pTabButton ) return false;
if (!pTabButton) return false;
AddTabToDock( pTabButton, pAddTo );
AddTabToDock(pTabButton, pAddTo);
}
if ( pPackage->name == "TabWindowMove" )
if (pPackage->name == "TabWindowMove")
{
DockedTabControl* pTabControl = DragAndDrop::SourceControl->DynamicCastDockedTabControl();
if ( !pTabControl ) return false;
if ( pTabControl == pAddTo ) return false;
if (!pTabControl) return false;
if (pTabControl == pAddTo) return false;
pTabControl->MoveTabsTo( pAddTo );
pTabControl->MoveTabsTo(pAddTo);
}
Invalidate();
@@ -174,17 +174,17 @@ bool DockBase::DragAndDrop_HandleDrop( Gwen::DragAndDrop::Package* pPackage, int
bool DockBase::IsEmpty()
{
if ( m_DockedTabControl && m_DockedTabControl->TabCount() > 0 ) return false;
if (m_DockedTabControl && m_DockedTabControl->TabCount() > 0) return false;
if ( m_Left && !m_Left->IsEmpty() ) return false;
if ( m_Right && !m_Right->IsEmpty() ) return false;
if ( m_Top && !m_Top->IsEmpty() ) return false;
if ( m_Bottom && !m_Bottom->IsEmpty() ) return false;
if (m_Left && !m_Left->IsEmpty()) return false;
if (m_Right && !m_Right->IsEmpty()) return false;
if (m_Top && !m_Top->IsEmpty()) return false;
if (m_Bottom && !m_Bottom->IsEmpty()) return false;
return true;
}
void DockBase::OnTabRemoved( Gwen::Controls::Base* /*pControl*/ )
void DockBase::OnTabRemoved(Gwen::Controls::Base* /*pControl*/)
{
DoRedundancyCheck();
DoConsolidateCheck();
@@ -192,72 +192,72 @@ void DockBase::OnTabRemoved( Gwen::Controls::Base* /*pControl*/ )
void DockBase::DoRedundancyCheck()
{
if ( !IsEmpty() ) return;
if (!IsEmpty()) return;
DockBase* pDockParent = GetParent()->DynamicCastDockBase();
if ( !pDockParent ) return;
if (!pDockParent) return;
pDockParent->OnRedundantChildDock( this );
pDockParent->OnRedundantChildDock(this);
}
void DockBase::DoConsolidateCheck()
{
if ( IsEmpty() ) return;
if ( !m_DockedTabControl ) return;
if ( m_DockedTabControl->TabCount() > 0 ) return;
if (IsEmpty()) return;
if (!m_DockedTabControl) return;
if (m_DockedTabControl->TabCount() > 0) return;
if ( m_Bottom && !m_Bottom->IsEmpty() )
if (m_Bottom && !m_Bottom->IsEmpty())
{
m_Bottom->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
m_Bottom->m_DockedTabControl->MoveTabsTo(m_DockedTabControl);
return;
}
if ( m_Top && !m_Top->IsEmpty() )
if (m_Top && !m_Top->IsEmpty())
{
m_Top->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
m_Top->m_DockedTabControl->MoveTabsTo(m_DockedTabControl);
return;
}
if ( m_Left && !m_Left->IsEmpty() )
if (m_Left && !m_Left->IsEmpty())
{
m_Left->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
m_Left->m_DockedTabControl->MoveTabsTo(m_DockedTabControl);
return;
}
if ( m_Right && !m_Right->IsEmpty() )
if (m_Right && !m_Right->IsEmpty())
{
m_Right->m_DockedTabControl->MoveTabsTo( m_DockedTabControl );
m_Right->m_DockedTabControl->MoveTabsTo(m_DockedTabControl);
return;
}
}
void DockBase::OnRedundantChildDock( DockBase* pDockBase )
void DockBase::OnRedundantChildDock(DockBase* pDockBase)
{
pDockBase->SetHidden( true );
pDockBase->SetHidden(true);
DoRedundancyCheck();
DoConsolidateCheck();
}
void DockBase::DragAndDrop_HoverEnter( Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/ )
void DockBase::DragAndDrop_HoverEnter(Gwen::DragAndDrop::Package* /*pPackage*/, int /*x*/, int /*y*/)
{
m_bDrawHover = true;
}
void DockBase::DragAndDrop_HoverLeave( Gwen::DragAndDrop::Package* /*pPackage*/ )
void DockBase::DragAndDrop_HoverLeave(Gwen::DragAndDrop::Package* /*pPackage*/)
{
m_bDrawHover = false;
}
void DockBase::DragAndDrop_Hover( Gwen::DragAndDrop::Package* /*pPackage*/, int x, int y )
void DockBase::DragAndDrop_Hover(Gwen::DragAndDrop::Package* /*pPackage*/, int x, int y)
{
Gwen::Point pPos = CanvasPosToLocal( Gwen::Point( x, y ) );
int dir = GetDroppedTabDirection( pPos.x, pPos.y );
Gwen::Point pPos = CanvasPosToLocal(Gwen::Point(x, y));
int dir = GetDroppedTabDirection(pPos.x, pPos.y);
if ( dir == Pos::Fill )
if (dir == Pos::Fill)
{
if ( !m_DockedTabControl )
if (!m_DockedTabControl)
{
m_HoverRect = Gwen::Rect( 0, 0, 0, 0 );
m_HoverRect = Gwen::Rect(0, 0, 0, 0);
return;
}
@@ -269,75 +269,75 @@ void DockBase::DragAndDrop_Hover( Gwen::DragAndDrop::Package* /*pPackage*/, int
int HelpBarWidth = 0;
if ( dir == Pos::Left )
if (dir == Pos::Left)
{
HelpBarWidth = m_HoverRect.w * 0.25f;
m_HoverRect.w = HelpBarWidth;
}
if ( dir == Pos::Right )
if (dir == Pos::Right)
{
HelpBarWidth = m_HoverRect.w * 0.25f;
m_HoverRect.x = m_HoverRect.w - HelpBarWidth;
m_HoverRect.w = HelpBarWidth;
}
if ( dir == Pos::Top )
if (dir == Pos::Top)
{
HelpBarWidth = m_HoverRect.h * 0.25f;
m_HoverRect.h = HelpBarWidth;
}
if ( dir == Pos::Bottom )
if (dir == Pos::Bottom)
{
HelpBarWidth = m_HoverRect.h * 0.25f;
m_HoverRect.y = m_HoverRect.h - HelpBarWidth;
m_HoverRect.h = HelpBarWidth;
}
if ( (dir == Pos::Top || dir == Pos::Bottom ) && !m_bDropFar )
if ((dir == Pos::Top || dir == Pos::Bottom) && !m_bDropFar)
{
if ( m_Left && m_Left->Visible() )
if (m_Left && m_Left->Visible())
{
m_HoverRect.x += m_Left->Width();
m_HoverRect.w -= m_Left->Width();
}
if ( m_Right && m_Right->Visible() )
if (m_Right && m_Right->Visible())
{
m_HoverRect.w -= m_Right->Width();
}
}
if ( (dir == Pos::Left || dir == Pos::Right ) && !m_bDropFar )
if ((dir == Pos::Left || dir == Pos::Right) && !m_bDropFar)
{
if ( m_Top && m_Top->Visible() )
if (m_Top && m_Top->Visible())
{
m_HoverRect.y += m_Top->Height();
m_HoverRect.h -= m_Top->Height();
}
if ( m_Bottom && m_Bottom->Visible() )
if (m_Bottom && m_Bottom->Visible())
{
m_HoverRect.h -= m_Bottom->Height();
}
}
}
void DockBase::RenderOver( Skin::Base* skin )
void DockBase::RenderOver(Skin::Base* skin)
{
if ( !m_bDrawHover ) return;
if (!m_bDrawHover) return;
Gwen::Renderer::Base* render = skin->GetRender();
render->SetDrawColor( Gwen::Color( 255, 100, 255, 20 ) );
render->DrawFilledRect( GetRenderBounds() );
render->SetDrawColor(Gwen::Color(255, 100, 255, 20));
render->DrawFilledRect(GetRenderBounds());
if ( m_HoverRect.w == 0 ) return;
if (m_HoverRect.w == 0) return;
render->SetDrawColor( Gwen::Color( 255, 100, 255, 100 ) );
render->DrawFilledRect( m_HoverRect );
render->SetDrawColor(Gwen::Color(255, 100, 255, 100));
render->DrawFilledRect(m_HoverRect);
render->SetDrawColor( Gwen::Color( 255, 100, 255, 200 ) );
render->DrawLinedRect( m_HoverRect );
render->SetDrawColor(Gwen::Color(255, 100, 255, 200));
render->DrawLinedRect(m_HoverRect);
}

View File

@@ -11,67 +11,64 @@
#include "Gwen/Controls/Base.h"
#include "Gwen/Controls/Button.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class DockedTabControl;
class TabControl;
namespace Controls
{
class DockedTabControl;
class TabControl;
class GWEN_EXPORT DockBase : public Base
{
public:
class GWEN_EXPORT DockBase : public Base
{
public:
GWEN_CONTROL(DockBase, Base);
GWEN_CONTROL( DockBase, Base );
virtual void Render(Skin::Base* skin);
virtual void RenderOver(Skin::Base* skin);
virtual bool IsEmpty();
virtual void Render( Skin::Base* skin );
virtual void RenderOver( Skin::Base* skin );
virtual bool IsEmpty();
virtual TabControl* GetTabControl();
virtual TabControl* GetTabControl();
virtual DockBase* GetRight() { return GetChildDock(Pos::Right); }
virtual DockBase* GetLeft() { return GetChildDock(Pos::Left); }
virtual DockBase* GetTop() { return GetChildDock(Pos::Top); }
virtual DockBase* GetBottom() { return GetChildDock(Pos::Bottom); }
virtual DockBase* GetRight(){ return GetChildDock( Pos::Right ); }
virtual DockBase* GetLeft(){ return GetChildDock( Pos::Left ); }
virtual DockBase* GetTop(){ return GetChildDock( Pos::Top ); }
virtual DockBase* GetBottom(){ return GetChildDock( Pos::Bottom ); }
// No action on space (default button action is to press)
virtual bool OnKeySpace(bool /*bDown*/) { return false; }
// No action on space (default button action is to press)
virtual bool OnKeySpace( bool /*bDown*/ ){ return false; }
private:
private:
// Drag n Drop
virtual bool DragAndDrop_HandleDrop(Gwen::DragAndDrop::Package* pPackage, int x, int y);
virtual bool DragAndDrop_CanAcceptPackage(Gwen::DragAndDrop::Package* pPackage);
virtual void DragAndDrop_HoverEnter(Gwen::DragAndDrop::Package* pPackage, int x, int y);
virtual void DragAndDrop_HoverLeave(Gwen::DragAndDrop::Package* pPackage);
virtual void DragAndDrop_Hover(Gwen::DragAndDrop::Package* pPackage, int x, int y);
// Drag n Drop
virtual bool DragAndDrop_HandleDrop( Gwen::DragAndDrop::Package* pPackage, int x, int y );
virtual bool DragAndDrop_CanAcceptPackage( Gwen::DragAndDrop::Package* pPackage );
virtual void DragAndDrop_HoverEnter( Gwen::DragAndDrop::Package* pPackage, int x, int y );
virtual void DragAndDrop_HoverLeave( Gwen::DragAndDrop::Package* pPackage );
virtual void DragAndDrop_Hover( Gwen::DragAndDrop::Package* pPackage, int x, int y );
virtual void SetupChildDock(int iPos);
virtual void SetupChildDock( int iPos );
virtual void DoRedundancyCheck();
virtual void DoConsolidateCheck();
virtual void OnRedundantChildDock(DockBase* pDockBase);
virtual void DoRedundancyCheck();
virtual void DoConsolidateCheck();
virtual void OnRedundantChildDock( DockBase* pDockBase );
virtual int GetDroppedTabDirection(int x, int y);
virtual void OnTabRemoved(Gwen::Controls::Base* pControl);
virtual int GetDroppedTabDirection( int x, int y );
virtual void OnTabRemoved( Gwen::Controls::Base* pControl );
DockBase* GetChildDock(int iPos);
DockBase** GetChildDockPtr(int iPos);
DockBase* GetChildDock( int iPos );
DockBase** GetChildDockPtr( int iPos );
DockBase* m_Left;
DockBase* m_Right;
DockBase* m_Top;
DockBase* m_Bottom;
DockBase* m_Left;
DockBase* m_Right;
DockBase* m_Top;
DockBase* m_Bottom;
// Only CHILD dockpanels have a tabcontrol.
DockedTabControl* m_DockedTabControl;
// Only CHILD dockpanels have a tabcontrol.
DockedTabControl* m_DockedTabControl;
bool m_bDrawHover;
bool m_bDropFar;
Gwen::Rect m_HoverRect;
};
}
}
bool m_bDrawHover;
bool m_bDropFar;
Gwen::Rect m_HoverRect;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
#include "Gwen/Controls/DockedTabControl.h"
@@ -15,51 +14,50 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( DockedTabControl )
GWEN_CONTROL_CONSTRUCTOR(DockedTabControl)
{
m_WindowControl = NULL;
Dock( Pos::Fill );
m_pTitleBar = new TabTitleBar( this );
m_pTitleBar->Dock( Pos::Top );
m_pTitleBar->SetHidden( true );
Dock(Pos::Fill);
m_pTitleBar = new TabTitleBar(this);
m_pTitleBar->Dock(Pos::Top);
m_pTitleBar->SetHidden(true);
}
void DockedTabControl::Layout( Skin::Base* skin )
void DockedTabControl::Layout(Skin::Base* skin)
{
GetTabStrip()->SetHidden( TabCount() <= 1 );
GetTabStrip()->SetHidden(TabCount() <= 1);
UpdateTitleBar();
BaseClass::Layout( skin );
BaseClass::Layout(skin);
}
void DockedTabControl::UpdateTitleBar()
{
if ( !GetCurrentButton() ) return;
{
if (!GetCurrentButton()) return;
m_pTitleBar->UpdateFromTab( GetCurrentButton() );
m_pTitleBar->UpdateFromTab(GetCurrentButton());
}
void DockedTabControl::DragAndDrop_StartDragging( Gwen::DragAndDrop::Package* pPackage, int x, int y )
void DockedTabControl::DragAndDrop_StartDragging(Gwen::DragAndDrop::Package* pPackage, int x, int y)
{
BaseClass::DragAndDrop_StartDragging( pPackage, x, y );
BaseClass::DragAndDrop_StartDragging(pPackage, x, y);
SetHidden( true );
SetHidden(true);
// This hiding our parent thing is kind of lousy.
GetParent()->SetHidden( true );
GetParent()->SetHidden(true);
}
void DockedTabControl::DragAndDrop_EndDragging( bool bSuccess, int /*x*/, int /*y*/ )
void DockedTabControl::DragAndDrop_EndDragging(bool bSuccess, int /*x*/, int /*y*/)
{
SetHidden( false );
SetHidden(false);
if ( !bSuccess )
if (!bSuccess)
{
GetParent()->SetHidden( false );
GetParent()->SetHidden(false);
}
/*
/*
if ( !bSuccess )
{
// Create our window control
@@ -77,15 +75,15 @@ void DockedTabControl::DragAndDrop_EndDragging( bool bSuccess, int /*x*/, int /*
*/
}
void DockedTabControl::MoveTabsTo( DockedTabControl* pTarget )
void DockedTabControl::MoveTabsTo(DockedTabControl* pTarget)
{
Base::List Children = GetTabStrip()->Children;
for (Base::List::iterator iter = Children.begin(); iter != Children.end(); ++iter)
{
TabButton* pButton = (*iter)->DynamicCastTabButton();
if ( !pButton ) continue;
if (!pButton) continue;
pTarget->AddPage( pButton );
pTarget->AddPage(pButton);
}
Invalidate();

View File

@@ -11,32 +11,29 @@
#include "Gwen/Controls/Base.h"
#include "Gwen/Controls/TabControl.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT DockedTabControl : public TabControl
{
public:
namespace Controls
{
class GWEN_EXPORT DockedTabControl : public TabControl
{
public:
GWEN_CONTROL(DockedTabControl, TabControl);
GWEN_CONTROL( DockedTabControl, TabControl );
void SetShowTitlebar(bool bShow) { m_pTitleBar->SetHidden(!bShow); }
void SetShowTitlebar( bool bShow ){ m_pTitleBar->SetHidden( !bShow ); }
void Layout(Skin::Base* skin);
void UpdateTitleBar();
void Layout( Skin::Base* skin );
void UpdateTitleBar();
virtual void DragAndDrop_StartDragging(Gwen::DragAndDrop::Package* pPackage, int x, int y);
virtual void DragAndDrop_EndDragging(bool bSuccess, int x, int y);
virtual void DragAndDrop_StartDragging( Gwen::DragAndDrop::Package* pPackage, int x, int y );
virtual void DragAndDrop_EndDragging( bool bSuccess, int x, int y );
void MoveTabsTo(DockedTabControl* pTarget);
void MoveTabsTo( DockedTabControl* pTarget );
private:
TabTitleBar* m_pTitleBar;
Base* m_WindowControl;
};
}
}
private:
TabTitleBar* m_pTitleBar;
Base* m_WindowControl;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,29 +4,26 @@
See license in Gwen.h
*/
#include "Gwen/Controls/Dragger.h"
using namespace Gwen;
using namespace Gwen::ControlsInternal;
GWEN_CONTROL_CONSTRUCTOR( Dragger )
GWEN_CONTROL_CONSTRUCTOR(Dragger)
{
m_pTarget = NULL;
SetMouseInputEnabled( true );
SetMouseInputEnabled(true);
m_bDepressed = false;
}
void Dragger::OnMouseClickLeft( int x, int y, bool bDown )
void Dragger::OnMouseClickLeft(int x, int y, bool bDown)
{
if ( !m_pTarget ) return;
if (!m_pTarget) return;
if ( bDown )
if (bDown)
{
m_bDepressed = true;
m_HoldPos = m_pTarget->CanvasPosToLocal( Gwen::Point( x, y ) );
m_HoldPos = m_pTarget->CanvasPosToLocal(Gwen::Point(x, y));
Gwen::MouseFocus = this;
}
else
@@ -37,23 +34,23 @@ void Dragger::OnMouseClickLeft( int x, int y, bool bDown )
}
}
void Dragger::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
void Dragger::OnMouseMoved(int x, int y, int /*deltaX*/, int /*deltaY*/)
{
if ( !m_pTarget ) return;
if ( !m_bDepressed ) return;
if (!m_pTarget) return;
if (!m_bDepressed) return;
Gwen::Point p = Gwen::Point(x - m_HoldPos.x, y - m_HoldPos.y);
Gwen::Point p = Gwen::Point( x - m_HoldPos.x, y - m_HoldPos.y );
// Translate to parent
if ( m_pTarget->GetParent() )
p = m_pTarget->GetParent()->CanvasPosToLocal( p );
if (m_pTarget->GetParent())
p = m_pTarget->GetParent()->CanvasPosToLocal(p);
//m_pTarget->SetPosition( p.x, p.y );
m_pTarget->MoveTo( p.x, p.y );
onDragged.Call( this );
m_pTarget->MoveTo(p.x, p.y);
onDragged.Call(this);
}
void Dragger::Render( Skin::Base* /*skin*/ )
void Dragger::Render(Skin::Base* /*skin*/)
{
//skin->DrawButton(this,false,false);
}

View File

@@ -12,32 +12,29 @@
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace ControlsInternal
{
class GWEN_EXPORT Dragger : public Controls::Base
{
public:
namespace ControlsInternal
{
class GWEN_EXPORT Dragger : public Controls::Base
{
public:
GWEN_CONTROL(Dragger, Controls::Base);
GWEN_CONTROL( Dragger, Controls::Base );
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
virtual void OnMouseClickLeft(int x, int y, bool bDown);
virtual void Render(Skin::Base* skin);
virtual void OnMouseClickLeft( int x, int y, bool bDown );
virtual void Render( Skin::Base* skin );
virtual void SetTarget(Controls::Base* pBase) { m_pTarget = pBase; }
virtual void SetTarget( Controls::Base* pBase ){ m_pTarget = pBase; }
Gwen::Event::Caller onDragged;
Gwen::Event::Caller onDragged;
protected:
bool m_bDepressed;
Gwen::Point m_HoldPos;
Controls::Base* m_pTarget;
};
}
}
protected:
bool m_bDepressed;
Gwen::Point m_HoldPos;
Controls::Base* m_pTarget;
};
} // namespace ControlsInternal
} // namespace Gwen
#endif

View File

@@ -4,39 +4,35 @@
See license in Gwen.h
*/
#include "Gwen/Controls/GroupBox.h"
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( GroupBox )
GWEN_CONTROL_CONSTRUCTOR(GroupBox)
{
// Set to true, because it's likely that our
// Set to true, because it's likely that our
// children will want mouse input, and they
// can't get it without us..
SetMouseInputEnabled( true );
SetMouseInputEnabled(true);
SetTextPadding( Padding( 10, 0, 0, 0 ) );
SetTextPadding(Padding(10, 0, 0, 0));
SetAlignment( Pos::Top | Pos::Left );
SetAlignment(Pos::Top | Pos::Left);
Invalidate();
m_InnerPanel = new Base( this );
m_InnerPanel->Dock( Pos::Fill );
m_InnerPanel = new Base(this);
m_InnerPanel->Dock(Pos::Fill);
}
void GroupBox::Layout( Skin::Base* skin )
void GroupBox::Layout(Skin::Base* skin)
{
m_InnerPanel->SetMargin( Margin( TextHeight() + 3, 6, 6, 6 ) );
m_InnerPanel->SetMargin(Margin(TextHeight() + 3, 6, 6, 6));
BaseClass::Layout( skin );
BaseClass::Layout(skin);
}
void GroupBox::Render( Skin::Base* skin )
void GroupBox::Render(Skin::Base* skin)
{
skin->DrawGroupBox( this, TextX(), TextHeight(), TextWidth() );
skin->DrawGroupBox(this, TextX(), TextHeight(), TextWidth());
}

View File

@@ -13,22 +13,18 @@
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
namespace Controls
{
class GWEN_EXPORT GroupBox : public Label
{
public:
GWEN_CONTROL(GroupBox, Label);
class GWEN_EXPORT GroupBox : public Label
{
public:
GWEN_CONTROL( GroupBox, Label );
virtual void Render( Skin::Base* skin );
virtual void Layout( Skin::Base* skin );
};
}
}
virtual void Render(Skin::Base* skin);
virtual void Layout(Skin::Base* skin);
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Controls/HSVColorPicker.h"
#include "Gwen/Controls/ColorControls.h"
#include "Gwen/Controls/ColorPicker.h"
@@ -16,141 +15,134 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( HSVColorPicker )
GWEN_CONTROL_CONSTRUCTOR(HSVColorPicker)
{
SetMouseInputEnabled( true );
SetSize( 256, 128 );
SetMouseInputEnabled(true);
SetSize(256, 128);
SetCacheToTexture();
m_LerpBox = new Gwen::Controls::ColorLerpBox( this );
m_LerpBox->onSelectionChanged.Add( this, &HSVColorPicker::ColorBoxChanged );
m_LerpBox->SetPos( 5, 5 );
m_LerpBox = new Gwen::Controls::ColorLerpBox(this);
m_LerpBox->onSelectionChanged.Add(this, &HSVColorPicker::ColorBoxChanged);
m_LerpBox->SetPos(5, 5);
m_ColorSlider = new Gwen::Controls::ColorSlider( this );
m_ColorSlider->SetPos( m_LerpBox->Width() + 15, 5 );
m_ColorSlider->onSelectionChanged.Add( this, &HSVColorPicker::ColorSliderChanged );
m_ColorSlider = new Gwen::Controls::ColorSlider(this);
m_ColorSlider->SetPos(m_LerpBox->Width() + 15, 5);
m_ColorSlider->onSelectionChanged.Add(this, &HSVColorPicker::ColorSliderChanged);
m_After = new Gwen::ControlsInternal::ColorDisplay( this );
m_After->SetSize( 48, 24 );
m_After->SetPos( m_ColorSlider->X() + m_ColorSlider->Width() + 15, 5 );
m_After = new Gwen::ControlsInternal::ColorDisplay(this);
m_After->SetSize(48, 24);
m_After->SetPos(m_ColorSlider->X() + m_ColorSlider->Width() + 15, 5);
m_Before = new Gwen::ControlsInternal::ColorDisplay( this );
m_Before->SetSize( 48, 24 );
m_Before->SetPos( m_After->X(), 28 );
m_Before = new Gwen::ControlsInternal::ColorDisplay(this);
m_Before->SetSize(48, 24);
m_Before->SetPos(m_After->X(), 28);
int x = m_Before->X();
int y = m_Before->Y() + 30;
{
Label* label = new Label( this );
Label* label = new Label(this);
label->SetText(L"R:");
label->SizeToContents();
label->SetPos( x, y );
TextBoxNumeric* numeric = new TextBoxNumeric( this );
numeric->SetName( "RedBox" );
numeric->SetPos( x + 15, y -1 );
numeric->SetSize( 26, 16 );
numeric->SetSelectAllOnFocus( true );
numeric->onTextChanged.Add( this, &HSVColorPicker::NumericTyped );
label->SetPos(x, y);
TextBoxNumeric* numeric = new TextBoxNumeric(this);
numeric->SetName("RedBox");
numeric->SetPos(x + 15, y - 1);
numeric->SetSize(26, 16);
numeric->SetSelectAllOnFocus(true);
numeric->onTextChanged.Add(this, &HSVColorPicker::NumericTyped);
}
y+= 20;
y += 20;
{
Label* label = new Label( this );
Label* label = new Label(this);
label->SetText(L"G:");
label->SizeToContents();
label->SetPos( x, y );
label->SetPos(x, y);
TextBoxNumeric* numeric = new TextBoxNumeric( this );
numeric->SetName( "GreenBox" );
numeric->SetPos( x + 15, y -1 );
numeric->SetSize( 26, 16 );
numeric->SetSelectAllOnFocus( true );
numeric->onTextChanged.Add( this, &HSVColorPicker::NumericTyped );
TextBoxNumeric* numeric = new TextBoxNumeric(this);
numeric->SetName("GreenBox");
numeric->SetPos(x + 15, y - 1);
numeric->SetSize(26, 16);
numeric->SetSelectAllOnFocus(true);
numeric->onTextChanged.Add(this, &HSVColorPicker::NumericTyped);
}
y+= 20;
y += 20;
{
Label* label = new Label( this );
Label* label = new Label(this);
label->SetText(L"B:");
label->SizeToContents();
label->SetPos( x, y );
label->SetPos(x, y);
TextBoxNumeric* numeric = new TextBoxNumeric( this );
numeric->SetName( "BlueBox" );
numeric->SetPos( x + 15, y -1 );
numeric->SetSize( 26, 16 );
numeric->SetSelectAllOnFocus( true );
numeric->onTextChanged.Add( this, &HSVColorPicker::NumericTyped );
TextBoxNumeric* numeric = new TextBoxNumeric(this);
numeric->SetName("BlueBox");
numeric->SetPos(x + 15, y - 1);
numeric->SetSize(26, 16);
numeric->SetSelectAllOnFocus(true);
numeric->onTextChanged.Add(this, &HSVColorPicker::NumericTyped);
}
}
void HSVColorPicker::NumericTyped( Gwen::Controls::Base* control )
void HSVColorPicker::NumericTyped(Gwen::Controls::Base* control)
{
TextBoxNumeric* box = control->DynamicCastTextBoxNumeric();
if ( !box ) return;
if (!box) return;
if ( box->GetText() == L"" ) return;
if (box->GetText() == L"") return;
int textValue = atoi( Gwen::Utility::UnicodeToString( box->GetText()).c_str() );
if ( textValue < 0 ) textValue = 0;
if ( textValue > 255 ) textValue = 255;
int textValue = atoi(Gwen::Utility::UnicodeToString(box->GetText()).c_str());
if (textValue < 0) textValue = 0;
if (textValue > 255) textValue = 255;
Gwen::Color newColor = GetColor();
if ( box->GetName().find( "Red" ) != Gwen::String::npos )
if (box->GetName().find("Red") != Gwen::String::npos)
{
newColor.r = textValue;
}
else if ( box->GetName().find( "Green" ) != Gwen::String::npos )
else if (box->GetName().find("Green") != Gwen::String::npos)
{
newColor.g = textValue;
}
else if ( box->GetName().find( "Blue" ) != Gwen::String::npos )
else if (box->GetName().find("Blue") != Gwen::String::npos)
{
newColor.b = textValue;
}
else if ( box->GetName().find( "Alpha" ) != Gwen::String::npos )
else if (box->GetName().find("Alpha") != Gwen::String::npos)
{
newColor.a = textValue;
}
SetColor( newColor );
SetColor(newColor);
}
void HSVColorPicker::UpdateControls(Gwen::Color color)
{
TextBoxNumeric* redBox = FindChildByName( "RedBox", false )->DynamicCastTextBoxNumeric();
if ( redBox ) redBox->SetText( Gwen::Utility::ToString( (int)color.r), false );
TextBoxNumeric* redBox = FindChildByName("RedBox", false)->DynamicCastTextBoxNumeric();
if (redBox) redBox->SetText(Gwen::Utility::ToString((int)color.r), false);
TextBoxNumeric* greenBox = FindChildByName( "GreenBox", false )->DynamicCastTextBoxNumeric();
if ( greenBox ) greenBox->SetText( Gwen::Utility::ToString( (int)color.g ), false );
TextBoxNumeric* greenBox = FindChildByName("GreenBox", false)->DynamicCastTextBoxNumeric();
if (greenBox) greenBox->SetText(Gwen::Utility::ToString((int)color.g), false);
TextBoxNumeric* blueBox = FindChildByName( "BlueBox", false )->DynamicCastTextBoxNumeric();
if ( blueBox ) blueBox->SetText( Gwen::Utility::ToString( (int)color.b ), false );
TextBoxNumeric* blueBox = FindChildByName("BlueBox", false)->DynamicCastTextBoxNumeric();
if (blueBox) blueBox->SetText(Gwen::Utility::ToString((int)color.b), false);
m_After->SetColor( color );
m_After->SetColor(color);
}
void HSVColorPicker::SetColor( Gwen::Color color, bool onlyHue, bool reset )
void HSVColorPicker::SetColor(Gwen::Color color, bool onlyHue, bool reset)
{
UpdateControls(color);
UpdateControls( color );
if (reset)
m_Before->SetColor(color);
if ( reset )
m_Before->SetColor( color );
m_ColorSlider->SetColor( color );
m_LerpBox->SetColor( color, onlyHue );
m_After->SetColor( color );
m_ColorSlider->SetColor(color);
m_LerpBox->SetColor(color, onlyHue);
m_After->SetColor(color);
}
Gwen::Color HSVColorPicker::GetColor()
@@ -158,15 +150,15 @@ Gwen::Color HSVColorPicker::GetColor()
return m_LerpBox->GetSelectedColor();
}
void HSVColorPicker::ColorBoxChanged( Gwen::Controls::Base* /*pControl*/ )
void HSVColorPicker::ColorBoxChanged(Gwen::Controls::Base* /*pControl*/)
{
onColorChanged.Call( this );
UpdateControls( GetColor() );
onColorChanged.Call(this);
UpdateControls(GetColor());
Invalidate();
}
void HSVColorPicker::ColorSliderChanged( Gwen::Controls::Base* /*pControl*/ )
void HSVColorPicker::ColorSliderChanged(Gwen::Controls::Base* /*pControl*/)
{
if ( m_LerpBox )
m_LerpBox->SetColor( m_ColorSlider->GetSelectedColor(), true );
if (m_LerpBox)
m_LerpBox->SetColor(m_ColorSlider->GetSelectedColor(), true);
Invalidate();
}

View File

@@ -14,34 +14,33 @@
#include "Gwen/Controls/ColorControls.h"
#include "Gwen/Controls/ColorPicker.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT HSVColorPicker : public Controls::Base
{
public:
GWEN_CONTROL( HSVColorPicker, Controls::Base );
namespace Controls
{
class GWEN_EXPORT HSVColorPicker : public Controls::Base
{
public:
GWEN_CONTROL(HSVColorPicker, Controls::Base);
Gwen::Color GetColor();
Gwen::Color GetDefaultColor() { return m_Before->GetColor(); }
void SetColor( Gwen::Color color, bool onlyHue = false, bool reset = false );
Gwen::Color GetColor();
Gwen::Color GetDefaultColor() { return m_Before->GetColor(); }
void SetColor(Gwen::Color color, bool onlyHue = false, bool reset = false);
void ColorBoxChanged( Gwen::Controls::Base* pControl );
void ColorSliderChanged( Gwen::Controls::Base* pControl );
void NumericTyped( Gwen::Controls::Base* control );
void ColorBoxChanged(Gwen::Controls::Base* pControl);
void ColorSliderChanged(Gwen::Controls::Base* pControl);
void NumericTyped(Gwen::Controls::Base* control);
void UpdateControls( Gwen::Color newColor );
Event::Caller onColorChanged;
void UpdateControls(Gwen::Color newColor);
protected:
ColorLerpBox* m_LerpBox;
ColorSlider* m_ColorSlider;
ControlsInternal::ColorDisplay* m_Before;
ControlsInternal::ColorDisplay* m_After;
};
}
}
Event::Caller onColorChanged;
protected:
ColorLerpBox* m_LerpBox;
ColorSlider* m_ColorSlider;
ControlsInternal::ColorDisplay* m_Before;
ControlsInternal::ColorDisplay* m_After;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -12,25 +12,23 @@
#include "Gwen/Controls/Base.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace ControlsInternal
namespace ControlsInternal
{
class GWEN_EXPORT Highlight : public Controls::Base
{
public:
GWEN_CONTROL_INLINE(Highlight, Controls::Base)
{
class GWEN_EXPORT Highlight : public Controls::Base
{
public:
GWEN_CONTROL_INLINE( Highlight, Controls::Base )
{
}
void Render( Skin::Base* skin )
{
skin->DrawHighlight( this );
}
};
}
}
void Render(Skin::Base* skin)
{
skin->DrawHighlight(this);
}
};
} // namespace ControlsInternal
} // namespace Gwen
#endif

View File

@@ -4,99 +4,96 @@
See license in Gwen.h
*/
#include "Gwen/Controls/ScrollBar.h"
#include "Gwen/Controls/HorizontalScrollBar.h"
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( HorizontalScrollBar )
GWEN_CONTROL_CONSTRUCTOR(HorizontalScrollBar)
{
m_Bar->SetHorizontal();
m_ScrollButton[SCROLL_BUTTON_LEFT]->SetDirectionLeft();
m_ScrollButton[SCROLL_BUTTON_LEFT]->onPress.Add( this, &HorizontalScrollBar::NudgeLeft );
m_ScrollButton[SCROLL_BUTTON_LEFT]->onPress.Add(this, &HorizontalScrollBar::NudgeLeft);
m_ScrollButton[SCROLL_BUTTON_RIGHT]->SetDirectionRight();
m_ScrollButton[SCROLL_BUTTON_RIGHT]->onPress.Add( this, &HorizontalScrollBar::NudgeRight );
m_ScrollButton[SCROLL_BUTTON_RIGHT]->onPress.Add(this, &HorizontalScrollBar::NudgeRight);
m_Bar->onDragged.Add( this, &HorizontalScrollBar::OnBarMoved );
m_Bar->onDragged.Add(this, &HorizontalScrollBar::OnBarMoved);
}
void HorizontalScrollBar::Layout( Skin::Base* skin )
void HorizontalScrollBar::Layout(Skin::Base* skin)
{
BaseClass::Layout( skin );
BaseClass::Layout(skin);
m_ScrollButton[SCROLL_BUTTON_LEFT]->SetWidth( Height() );
m_ScrollButton[SCROLL_BUTTON_LEFT]->SetWidth(Height());
m_ScrollButton[SCROLL_BUTTON_LEFT]->Dock(Pos::Left);
m_ScrollButton[SCROLL_BUTTON_RIGHT]->SetWidth( Height() );
m_ScrollButton[SCROLL_BUTTON_RIGHT]->SetWidth(Height());
m_ScrollButton[SCROLL_BUTTON_RIGHT]->Dock(Pos::Right);
m_Bar->SetHeight( GetButtonSize() );
m_Bar->SetPadding( Padding( GetButtonSize(), 0, GetButtonSize(), 0 ) );
m_Bar->SetHeight(GetButtonSize());
m_Bar->SetPadding(Padding(GetButtonSize(), 0, GetButtonSize(), 0));
float barWidth = (m_fViewableContentSize / m_fContentSize) * (Width() - (GetButtonSize() * 2));
if ( barWidth < GetButtonSize() * 0.5 )
if (barWidth < GetButtonSize() * 0.5)
barWidth = GetButtonSize() * 0.5;
m_Bar->SetWidth(barWidth);
m_Bar->SetHidden( Width() - (GetButtonSize() * 2) <= barWidth );
m_Bar->SetHidden(Width() - (GetButtonSize() * 2) <= barWidth);
//Based on our last scroll amount, produce a position for the bar
if ( !m_Bar->IsDepressed() )
if (!m_Bar->IsDepressed())
{
SetScrolledAmount( GetScrolledAmount(), true );
SetScrolledAmount(GetScrolledAmount(), true);
}
}
void HorizontalScrollBar::NudgeLeft( Base* /*control*/ )
void HorizontalScrollBar::NudgeLeft(Base* /*control*/)
{
if ( !IsDisabled() )
SetScrolledAmount( GetScrolledAmount() - GetNudgeAmount(), true);
if (!IsDisabled())
SetScrolledAmount(GetScrolledAmount() - GetNudgeAmount(), true);
}
void HorizontalScrollBar::NudgeRight( Base* /*control*/ )
void HorizontalScrollBar::NudgeRight(Base* /*control*/)
{
if ( !IsDisabled() )
SetScrolledAmount( GetScrolledAmount() + GetNudgeAmount(), true);
if (!IsDisabled())
SetScrolledAmount(GetScrolledAmount() + GetNudgeAmount(), true);
}
void HorizontalScrollBar::ScrollToLeft()
{
SetScrolledAmount( 0, true);
SetScrolledAmount(0, true);
}
void HorizontalScrollBar::ScrollToRight()
{
SetScrolledAmount( 1, true);
SetScrolledAmount(1, true);
}
float HorizontalScrollBar::GetNudgeAmount()
{
if ( m_bDepressed )
if (m_bDepressed)
return m_fViewableContentSize / m_fContentSize;
else
else
return BaseClass::GetNudgeAmount();
}
void HorizontalScrollBar::OnMouseClickLeft( int x, int y, bool bDown )
void HorizontalScrollBar::OnMouseClickLeft(int x, int y, bool bDown)
{
if ( bDown )
if (bDown)
{
m_bDepressed = true;
Gwen::MouseFocus = this;
}
else
{
Gwen::Point clickPos = CanvasPosToLocal( Gwen::Point( x, y ) );
if ( clickPos.x < m_Bar->X() )
NudgeLeft( this );
else if ( clickPos.x > m_Bar->X() + m_Bar->Width() )
NudgeRight( this );
Gwen::Point clickPos = CanvasPosToLocal(Gwen::Point(x, y));
if (clickPos.x < m_Bar->X())
NudgeLeft(this);
else if (clickPos.x > m_Bar->X() + m_Bar->Width())
NudgeRight(this);
m_bDepressed = false;
Gwen::MouseFocus = NULL;
@@ -105,30 +102,30 @@ void HorizontalScrollBar::OnMouseClickLeft( int x, int y, bool bDown )
float HorizontalScrollBar::CalculateScrolledAmount()
{
return (float)(m_Bar->X() - GetButtonSize()) / (float)(Width() - m_Bar->Width() - (GetButtonSize() * 2 ));
return (float)(m_Bar->X() - GetButtonSize()) / (float)(Width() - m_Bar->Width() - (GetButtonSize() * 2));
}
bool HorizontalScrollBar::SetScrolledAmount( float amount, bool forceUpdate )
bool HorizontalScrollBar::SetScrolledAmount(float amount, bool forceUpdate)
{
amount = Gwen::Clamp( amount, 0, 1 );
amount = Gwen::Clamp(amount, 0, 1);
if ( !BaseClass::SetScrolledAmount( amount, forceUpdate ) )
if (!BaseClass::SetScrolledAmount(amount, forceUpdate))
return false;
if ( forceUpdate )
if (forceUpdate)
{
int newX = GetButtonSize() + (amount * ((Width() - m_Bar->Width()) - (GetButtonSize()*2)));
m_Bar->MoveTo( newX, m_Bar->Y() );
int newX = GetButtonSize() + (amount * ((Width() - m_Bar->Width()) - (GetButtonSize() * 2)));
m_Bar->MoveTo(newX, m_Bar->Y());
}
return true;
}
void HorizontalScrollBar::OnBarMoved( Controls::Base* control )
void HorizontalScrollBar::OnBarMoved(Controls::Base* control)
{
if ( m_Bar->IsDepressed() )
if (m_Bar->IsDepressed())
{
SetScrolledAmount( CalculateScrolledAmount(), false );
SetScrolledAmount(CalculateScrolledAmount(), false);
BaseClass::OnBarMoved(control);
}
else

View File

@@ -15,35 +15,34 @@
#include "Gwen/Controls/Dragger.h"
#include "Gwen/Controls/ScrollBar.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT HorizontalScrollBar : public BaseScrollBar
{
public:
namespace Controls
{
class GWEN_EXPORT HorizontalScrollBar : public BaseScrollBar
{
public:
GWEN_CONTROL(HorizontalScrollBar, BaseScrollBar);
GWEN_CONTROL( HorizontalScrollBar, BaseScrollBar );
virtual void Layout(Skin::Base* skin);
virtual void Layout( Skin::Base* skin );
virtual void OnMouseClickLeft(int x, int y, bool bDown);
virtual void OnBarMoved(Controls::Base* control);
virtual void OnMouseClickLeft( int x, int y, bool bDown );
virtual void OnBarMoved( Controls::Base* control );
virtual int GetBarSize() { return m_Bar->Width(); }
virtual int GetBarPos() { return m_Bar->X() - Height(); }
virtual void SetBarSize(int size) { m_Bar->SetWidth(size); }
virtual int GetButtonSize() { return Height(); }
virtual int GetBarSize() { return m_Bar->Width(); }
virtual int GetBarPos() { return m_Bar->X() - Height(); }
virtual void SetBarSize( int size ) { m_Bar->SetWidth( size ); }
virtual int GetButtonSize() { return Height(); }
virtual void ScrollToLeft();
virtual void ScrollToRight();
virtual void NudgeLeft(Base* control);
virtual void NudgeRight(Base* control);
virtual float GetNudgeAmount();
virtual void ScrollToLeft();
virtual void ScrollToRight();
virtual void NudgeLeft( Base* control );
virtual void NudgeRight( Base* control );
virtual float GetNudgeAmount();
virtual float CalculateScrolledAmount();
virtual bool SetScrolledAmount(float amount, bool forceUpdate);
};
}
}
virtual float CalculateScrolledAmount();
virtual bool SetScrolledAmount(float amount, bool forceUpdate);
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Controls/Slider.h"
#include "Gwen/Controls/HorizontalSlider.h"
@@ -12,34 +11,33 @@ using namespace Gwen;
using namespace Gwen::Controls;
using namespace Gwen::ControlsInternal;
GWEN_CONTROL_CONSTRUCTOR( HorizontalSlider )
GWEN_CONTROL_CONSTRUCTOR(HorizontalSlider)
{
}
float HorizontalSlider::CalculateValue()
{
return (float)m_SliderBar->X() / (float)( Width() - m_SliderBar->Width() );
return (float)m_SliderBar->X() / (float)(Width() - m_SliderBar->Width());
}
void HorizontalSlider::UpdateBarFromValue()
{
m_SliderBar->MoveTo( ( Width() - m_SliderBar->Width() ) * ( m_fValue ), m_SliderBar->Y() );
m_SliderBar->MoveTo((Width() - m_SliderBar->Width()) * (m_fValue), m_SliderBar->Y());
}
void HorizontalSlider::OnMouseClickLeft( int x, int y, bool bDown )
void HorizontalSlider::OnMouseClickLeft(int x, int y, bool bDown)
{
m_SliderBar->MoveTo( CanvasPosToLocal( Gwen::Point( x, y ) ).x - m_SliderBar->Width() * 0.5, m_SliderBar->Y() );
m_SliderBar->OnMouseClickLeft( x, y, bDown );
OnMoved( m_SliderBar );
m_SliderBar->MoveTo(CanvasPosToLocal(Gwen::Point(x, y)).x - m_SliderBar->Width() * 0.5, m_SliderBar->Y());
m_SliderBar->OnMouseClickLeft(x, y, bDown);
OnMoved(m_SliderBar);
}
void HorizontalSlider::Layout(Skin::Base* /*skin*/)
{
m_SliderBar->SetSize( 10, Height() );
m_SliderBar->SetSize(10, Height());
}
void HorizontalSlider::Render( Skin::Base* skin )
void HorizontalSlider::Render(Skin::Base* skin)
{
skin->DrawSlider( this, true, m_bClampToNotches ? m_iNumNotches : 0, m_SliderBar->Width() );
skin->DrawSlider(this, true, m_bClampToNotches ? m_iNumNotches : 0, m_SliderBar->Width());
}

View File

@@ -15,21 +15,21 @@
#include "Gwen/Skin.h"
#include "Gwen/Controls/Slider.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT HorizontalSlider : public Slider
{
GWEN_CONTROL( HorizontalSlider, Slider );
namespace Controls
{
class GWEN_EXPORT HorizontalSlider : public Slider
{
GWEN_CONTROL(HorizontalSlider, Slider);
virtual void Layout( Skin::Base* skin );
virtual void Render( Skin::Base* skin );
virtual void Layout(Skin::Base* skin);
virtual void Render(Skin::Base* skin);
virtual float CalculateValue();
virtual void UpdateBarFromValue();
virtual void OnMouseClickLeft( int x, int y, bool bDown );
};
}
}
virtual float CalculateValue();
virtual void UpdateBarFromValue();
virtual void OnMouseClickLeft(int x, int y, bool bDown);
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,5 +4,4 @@
See license in Gwen.h
*/
#include "Gwen/Controls/ImagePanel.h"

View File

@@ -13,66 +13,63 @@
#include "Gwen/BaseRender.h"
#include "Gwen/Texture.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class GWEN_EXPORT ImagePanel : public Controls::Base
{
public:
GWEN_CONTROL_INLINE(ImagePanel, Controls::Base)
{
class GWEN_EXPORT ImagePanel : public Controls::Base
{
public:
GWEN_CONTROL_INLINE( ImagePanel, Controls::Base )
{
SetUV( 0, 0, 1, 1 );
SetMouseInputEnabled( false );
m_DrawColor = Colors::White;
}
virtual ~ImagePanel()
{
m_Texture.Release( GetSkin()->GetRender() );
}
virtual void SetUV( float u1, float v1, float u2, float v2 )
{
m_uv[0] = u1;
m_uv[1] = v1;
m_uv[2] = u2;
m_uv[3] = v2;
}
virtual void SetImage( const TextObject& imageName )
{
m_Texture.Load( imageName, GetSkin()->GetRender() );
}
virtual const TextObject& GetImageName()
{
return m_Texture.name;
}
virtual void Render( Skin::Base* skin )
{
skin->GetRender()->SetDrawColor( m_DrawColor );
skin->GetRender()->DrawTexturedRect( &m_Texture, GetRenderBounds(), m_uv[0], m_uv[1], m_uv[2], m_uv[3] );
}
virtual void SizeToContents()
{
SetSize( m_Texture.width, m_Texture.height );
}
virtual void SetDrawColor( Gwen::Color& color )
{
m_DrawColor = color;
}
Texture m_Texture;
float m_uv[4];
Gwen::Color m_DrawColor;
};
SetUV(0, 0, 1, 1);
SetMouseInputEnabled(false);
m_DrawColor = Colors::White;
}
}
virtual ~ImagePanel()
{
m_Texture.Release(GetSkin()->GetRender());
}
virtual void SetUV(float u1, float v1, float u2, float v2)
{
m_uv[0] = u1;
m_uv[1] = v1;
m_uv[2] = u2;
m_uv[3] = v2;
}
virtual void SetImage(const TextObject& imageName)
{
m_Texture.Load(imageName, GetSkin()->GetRender());
}
virtual const TextObject& GetImageName()
{
return m_Texture.name;
}
virtual void Render(Skin::Base* skin)
{
skin->GetRender()->SetDrawColor(m_DrawColor);
skin->GetRender()->DrawTexturedRect(&m_Texture, GetRenderBounds(), m_uv[0], m_uv[1], m_uv[2], m_uv[3]);
}
virtual void SizeToContents()
{
SetSize(m_Texture.width, m_Texture.height);
}
virtual void SetDrawColor(Gwen::Color& color)
{
m_DrawColor = color;
}
Texture m_Texture;
float m_uv[4];
Gwen::Color m_DrawColor;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Controls/Label.h"
#include "Gwen/Utility.h"
@@ -12,62 +11,59 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( Label )
GWEN_CONTROL_CONSTRUCTOR(Label)
{
m_Text = new ControlsInternal::Text( this );
m_Text->SetFont( GetSkin()->GetDefaultFont() );
m_Text = new ControlsInternal::Text(this);
m_Text->SetFont(GetSkin()->GetDefaultFont());
SetMouseInputEnabled( false );
SetBounds( 0, 0, 100, 10 );
SetAlignment( Gwen::Pos::Left | Gwen::Pos::Top );
SetMouseInputEnabled(false);
SetBounds(0, 0, 100, 10);
SetAlignment(Gwen::Pos::Left | Gwen::Pos::Top);
}
void Label::Layout( Skin::Base* /*skin*/ )
void Label::Layout(Skin::Base* /*skin*/)
{
int iAlign = m_iAlign;
int x = m_rTextPadding.left + m_Padding.left;
int y = m_rTextPadding.top + m_Padding.top;
if ( iAlign & Pos::Right ) x = Width() - m_Text->Width() - m_rTextPadding.right - m_Padding.right;
if ( iAlign & Pos::CenterH ) x = (m_rTextPadding.left + m_Padding.left) + ((Width() - m_Text->Width() ) * 0.5f) - m_rTextPadding.right - m_Padding.right;
if (iAlign & Pos::Right) x = Width() - m_Text->Width() - m_rTextPadding.right - m_Padding.right;
if (iAlign & Pos::CenterH) x = (m_rTextPadding.left + m_Padding.left) + ((Width() - m_Text->Width()) * 0.5f) - m_rTextPadding.right - m_Padding.right;
if ( iAlign & Pos::CenterV ) y = (m_rTextPadding.top + m_Padding.top) + ((Height() - m_Text->Height()) * 0.5f) - m_rTextPadding.bottom - m_Padding.bottom;
if ( iAlign & Pos::Bottom ) y = Height() - m_Text->Height() - m_rTextPadding.bottom - m_Padding.bottom;
if (iAlign & Pos::CenterV) y = (m_rTextPadding.top + m_Padding.top) + ((Height() - m_Text->Height()) * 0.5f) - m_rTextPadding.bottom - m_Padding.bottom;
if (iAlign & Pos::Bottom) y = Height() - m_Text->Height() - m_rTextPadding.bottom - m_Padding.bottom;
m_Text->SetPos( x, y );
m_Text->SetPos(x, y);
}
void Label::SetText( const UnicodeString& str, bool bDoEvents )
{
if ( m_Text->GetText() == str ) return;
void Label::SetText(const UnicodeString& str, bool bDoEvents)
{
if (m_Text->GetText() == str) return;
m_Text->SetString( str );
m_Text->SetString(str);
Redraw();
if ( bDoEvents )
if (bDoEvents)
OnTextChanged();
}
void Label::SetText( const String& str, bool bDoEvents )
{
SetText( Gwen::Utility::StringToUnicode( str ), bDoEvents );
void Label::SetText(const String& str, bool bDoEvents)
{
SetText(Gwen::Utility::StringToUnicode(str), bDoEvents);
}
void Label::SizeToContents()
{
m_Text->SetPos( m_rTextPadding.left + m_Padding.left, m_rTextPadding.top + m_Padding.top );
m_Text->SetPos(m_rTextPadding.left + m_Padding.left, m_rTextPadding.top + m_Padding.top);
m_Text->RefreshSize();
SetSize( m_Text->Width() + m_Padding.left + m_Padding.right + m_rTextPadding.left + m_rTextPadding.right, m_Text->Height() + m_Padding.top + m_Padding.bottom + m_rTextPadding.top + m_rTextPadding.bottom );
SetSize(m_Text->Width() + m_Padding.left + m_Padding.right + m_rTextPadding.left + m_rTextPadding.right, m_Text->Height() + m_Padding.top + m_Padding.bottom + m_rTextPadding.top + m_rTextPadding.bottom);
}
Gwen::Point Label::GetCharacterPosition( int iChar )
{
Gwen::Point p = m_Text->GetCharacterPosition( iChar );
Gwen::Point Label::GetCharacterPosition(int iChar)
{
Gwen::Point p = m_Text->GetCharacterPosition(iChar);
p.x += m_Text->X();
p.y += m_Text->Y();

View File

@@ -12,59 +12,61 @@
#include "Gwen/Controls/Base.h"
#include "Gwen/Controls/Text.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class GWEN_EXPORT Label : public Controls::Base
{
public:
GWEN_CONTROL(Label, Controls::Base);
virtual void SetText(const UnicodeString& str, bool bDoEvents = true);
virtual void SetText(const String& str, bool bDoEvents = true);
virtual const UnicodeString& GetText() const { return m_Text->GetText(); }
virtual void Render(Skin::Base* /*skin*/) {}
virtual void Layout(Skin::Base* skin);
virtual void SizeToContents();
virtual void SetAlignment(int iAlign) { m_iAlign = iAlign; }
virtual void SetFont(Gwen::Font* pFont) { m_Text->SetFont(pFont); }
virtual Gwen::Font* GetFont() { return m_Text->GetFont(); }
virtual void SetTextColor(const Gwen::Color& col) { m_Text->SetTextColor(col); }
inline const Gwen::Color& TextColor() const { return m_Text->TextColor(); }
virtual int TextWidth() { return m_Text->Width(); }
virtual int TextRight() { return m_Text->Right(); }
virtual int TextHeight() { return m_Text->Height(); }
virtual int TextX() { return m_Text->X(); }
virtual int TextY() { return m_Text->Y(); }
virtual int TextLength() { return m_Text->Length(); }
Gwen::Point GetCharacterPosition(int iChar);
virtual void SetTextPadding(const Padding& padding)
{
class GWEN_EXPORT Label : public Controls::Base
{
public:
GWEN_CONTROL( Label, Controls::Base );
virtual void SetText( const UnicodeString& str, bool bDoEvents = true );
virtual void SetText( const String& str, bool bDoEvents = true );
virtual const UnicodeString& GetText() const { return m_Text->GetText(); }
virtual void Render( Skin::Base* /*skin*/ ){}
virtual void Layout( Skin::Base* skin );
virtual void SizeToContents();
virtual void SetAlignment( int iAlign ){ m_iAlign = iAlign; }
virtual void SetFont( Gwen::Font* pFont ){ m_Text->SetFont( pFont ); }
virtual Gwen::Font* GetFont(){ return m_Text->GetFont(); }
virtual void SetTextColor( const Gwen::Color& col ){ m_Text->SetTextColor( col ); }
inline const Gwen::Color &TextColor() const { return m_Text->TextColor(); }
virtual int TextWidth() { return m_Text->Width(); }
virtual int TextRight() { return m_Text->Right(); }
virtual int TextHeight() { return m_Text->Height(); }
virtual int TextX() { return m_Text->X(); }
virtual int TextY() { return m_Text->Y(); }
virtual int TextLength() { return m_Text->Length(); }
Gwen::Point GetCharacterPosition( int iChar );
virtual void SetTextPadding( const Padding& padding ){ m_rTextPadding = padding; Invalidate(); InvalidateParent(); }
virtual const Padding& GetTextPadding(){ return m_rTextPadding; }
virtual Gwen::UnicodeString GetText() { return m_Text->GetText(); }
inline int Alignment() const { return m_iAlign; }
protected:
virtual void OnTextChanged(){};
Padding m_rTextPadding;
ControlsInternal::Text* m_Text;
int m_iAlign;
};
m_rTextPadding = padding;
Invalidate();
InvalidateParent();
}
}
virtual const Padding& GetTextPadding() { return m_rTextPadding; }
virtual Gwen::UnicodeString GetText() { return m_Text->GetText(); }
inline int Alignment() const { return m_iAlign; }
protected:
virtual void OnTextChanged(){};
Padding m_rTextPadding;
ControlsInternal::Text* m_Text;
int m_iAlign;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
#include "Gwen/Controls/LabelClickable.h"
@@ -12,14 +11,14 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( LabelClickable )
GWEN_CONTROL_CONSTRUCTOR(LabelClickable)
{
SetIsToggle( false );
SetIsToggle(false);
SetAlignment( Gwen::Pos::Left | Gwen::Pos::CenterV );
SetAlignment(Gwen::Pos::Left | Gwen::Pos::CenterV);
}
void LabelClickable::Render( Skin::Base* /*skin*/ )
void LabelClickable::Render(Skin::Base* /*skin*/)
{
//skin->DrawButton( this, IsDepressed(), IsToggle() && GetToggleState() );
}

View File

@@ -11,19 +11,17 @@
#include "Gwen/Controls/Base.h"
#include "Gwen/Controls/Button.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT LabelClickable : public Button
{
public:
namespace Controls
{
class GWEN_EXPORT LabelClickable : public Button
{
public:
GWEN_CONTROL(LabelClickable, Button);
GWEN_CONTROL( LabelClickable, Button );
virtual void Render( Skin::Base* skin );
};
}
}
virtual void Render(Skin::Base* skin);
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,84 +4,79 @@
See license in Gwen.h
*/
#pragma once
#ifndef GWEN_CONTROLS_LAYOUT_SPLITTER_H
#define GWEN_CONTROLS_LAYOUT_SPLITTER_H
#include "Gwen/Controls/Base.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
namespace Layout
{
class GWEN_EXPORT Splitter : public Base
{
public:
typedef Base BaseClass;
Splitter(Base* pParent) : BaseClass(pParent)
{
namespace Layout
for (int i = 0; i < 2; i++)
m_pPanel[i] = NULL;
}
void SetPanel(int i, Base* pPanel)
{
if (i < 0 || i > 1) return;
m_pPanel[i] = pPanel;
if (m_pPanel[i])
{
class GWEN_EXPORT Splitter : public Base
{
public:
typedef Base BaseClass;
Splitter( Base* pParent ) : BaseClass( pParent )
{
for ( int i=0; i<2; i++ )
m_pPanel[i] = NULL;
}
void SetPanel( int i, Base* pPanel )
{
if ( i < 0 || i > 1 ) return;
m_pPanel[i] = pPanel;
if ( m_pPanel[i] )
{
m_pPanel[i] ->SetParent( this );
}
}
Base* GetPanel( int i ) const
{
if ( i < 0 || i > 1 ) return NULL;
return m_pPanel[i];
}
void Layout( Skin::Base* skin )
{
LayoutVertical( skin );
}
private:
void LayoutVertical( Skin::Base* /*skin*/ )
{
int w = Width();
int h = Height();
if ( m_pPanel[0] )
{
const Margin& m = m_pPanel[0]->GetMargin();
m_pPanel[0]->SetBounds( m.left, m.top, w-m.left-m.right, (h * 0.5) - m.top - m.bottom );
}
if ( m_pPanel[1] )
{
const Margin& m = m_pPanel[1]->GetMargin();
m_pPanel[1]->SetBounds( m.left, m.top + (h * 0.5f), w-m.left-m.right, (h * 0.5f) - m.top - m.bottom );
}
}
void LayoutHorizontal( Skin::Base* /*skin*/ )
{
// Todo.
}
Base* m_pPanel[2];
};
m_pPanel[i]->SetParent(this);
}
}
}
Base* GetPanel(int i) const
{
if (i < 0 || i > 1) return NULL;
return m_pPanel[i];
}
void Layout(Skin::Base* skin)
{
LayoutVertical(skin);
}
private:
void LayoutVertical(Skin::Base* /*skin*/)
{
int w = Width();
int h = Height();
if (m_pPanel[0])
{
const Margin& m = m_pPanel[0]->GetMargin();
m_pPanel[0]->SetBounds(m.left, m.top, w - m.left - m.right, (h * 0.5) - m.top - m.bottom);
}
if (m_pPanel[1])
{
const Margin& m = m_pPanel[1]->GetMargin();
m_pPanel[1]->SetBounds(m.left, m.top + (h * 0.5f), w - m.left - m.right, (h * 0.5f) - m.top - m.bottom);
}
}
void LayoutHorizontal(Skin::Base* /*skin*/)
{
// Todo.
}
Base* m_pPanel[2];
};
} // namespace Layout
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -11,307 +11,299 @@
#include "Gwen/Controls/Label.h"
#include "Gwen/Utility.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
namespace Layout
{
class Table;
class GWEN_EXPORT TableRow : public Base
{
static const int MaxColumns = 5;
GWEN_CONTROL_INLINE(TableRow, Base)
{
namespace Layout
for (int i = 0; i < MaxColumns; i++)
m_Columns[i] = NULL;
m_ColumnCount = 0;
}
virtual class TableRow* DynamicCastLayoutTableRow()
{
return this;
}
virtual const class TableRow* DynamicCastLayoutTableRow() const
{
return this;
}
void SetColumnCount(int iCount)
{
if (iCount == m_ColumnCount) return;
if (iCount >= MaxColumns)
m_ColumnCount = MaxColumns;
for (int i = 0; i < MaxColumns; i++)
{
class Table;
class GWEN_EXPORT TableRow : public Base
if (i < iCount)
{
static const int MaxColumns = 5;
GWEN_CONTROL_INLINE( TableRow, Base )
if (!m_Columns[i])
{
for ( int i=0; i<MaxColumns; i++ )
m_Columns[i] = NULL;
m_ColumnCount = 0;
m_Columns[i] = new Label(this);
m_Columns[i]->Dock(Pos::Left);
m_Columns[i]->SetPadding(Padding(3, 3, 3, 3));
}
virtual class TableRow* DynamicCastLayoutTableRow()
{
return this;
}
virtual const class TableRow* DynamicCastLayoutTableRow() const
{
return this;
}
void SetColumnCount( int iCount )
{
if ( iCount == m_ColumnCount ) return;
if ( iCount >= MaxColumns )
m_ColumnCount = MaxColumns;
for ( int i=0; i<MaxColumns; i++ )
{
if ( i < iCount )
{
if ( !m_Columns[i] )
{
m_Columns[i] = new Label( this );
m_Columns[i]->Dock( Pos::Left );
m_Columns[i]->SetPadding( Padding( 3, 3, 3, 3 ) );
}
}
else if ( m_Columns[i] )
{
m_Columns[i]->DelayedDelete();
m_Columns[i] = NULL;
}
m_ColumnCount = iCount;
}
}
void SetColumnWidth( int i, int iWidth )
{
if ( !m_Columns[i] ) return;
if ( m_Columns[i]->Width() == iWidth ) return;
m_Columns[i]->SetWidth( iWidth );
}
template <typename T>
void SetCellText( int i, const T& strString )
{
if ( !m_Columns[i] ) return;
m_Columns[i]->SetText( strString );
}
void SetCellContents( int i, Base* pControl, bool bEnableMouseInput = false )
{
if ( !m_Columns[i] ) return;
pControl->SetParent( m_Columns[i] );
m_Columns[i]->SetMouseInputEnabled( bEnableMouseInput );
}
Label* GetCellContents( int i )
{
return m_Columns[i];
}
void SizeToContents()
{
int iHeight = 0;
for ( int i=0; i<m_ColumnCount; i++ )
{
if ( !m_Columns[i] ) continue;
// Note, more than 1 child here, because the
// label has a child built in ( The Text )
if ( m_Columns[i]->NumChildren() > 1 )
{
m_Columns[i]->SizeToChildren();
}
else
{
m_Columns[i]->SizeToContents();
}
iHeight = Utility::Max( iHeight, m_Columns[i]->Height() );
}
SetHeight( iHeight );
}
void SetTextColor( const Gwen::Color& color )
{
for ( int i=0; i<m_ColumnCount; i++ )
{
if ( !m_Columns[i] ) continue;
m_Columns[i]->SetTextColor( color );
}
}
//You might hate this. Actually I know you will
virtual UnicodeString GetText( int i )
{
return m_Columns[i]->GetText();
}
virtual void SetSelected( bool /*b*/ ) {}
//
// This is sometimes called by derivatives.
//
Gwen::Event::Caller onRowSelected;
private:
int m_ColumnCount;
Label* m_Columns[MaxColumns];
friend class Table;
};
class GWEN_EXPORT Table : public Base
}
else if (m_Columns[i])
{
public:
m_Columns[i]->DelayedDelete();
m_Columns[i] = NULL;
}
GWEN_CONTROL_INLINE( Table, Base )
{
m_iColumnCount = 1;
m_iDefaultRowHeight = 22;
for (int i=0; i<TableRow::MaxColumns; i++)
{
m_ColumnWidth[i] = 20;
}
m_bSizeToContents = false;
}
void SetColumnCount( int i )
{
if ( m_iColumnCount == i ) return;
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
{
if (!*it)
continue;
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
if ( !pRow ) continue;
pRow->SetColumnCount( i );
}
m_iColumnCount = i;
}
void SetColumnWidth( int i, int iWidth )
{
if ( m_ColumnWidth[i] == iWidth ) return;
m_ColumnWidth[i] = iWidth;
Invalidate();
}
TableRow* AddRow()
{
TableRow* row = new TableRow( this );
row->SetColumnCount( m_iColumnCount );
row->SetHeight( m_iDefaultRowHeight );
row->Dock( Pos::Top );
return row;
}
void AddRow( TableRow* pRow )
{
pRow->SetParent( this );
pRow->SetColumnCount( m_iColumnCount );
pRow->SetHeight( m_iDefaultRowHeight );
pRow->Dock( Pos::Top );
}
void Remove( TableRow* pRow )
{
pRow->DelayedDelete();
}
void Clear()
{
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
{
if (!(*it))
continue;
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
if ( !pRow ) continue;
Remove( pRow );
}
}
void Layout( Skin::Base* skin )
{
BaseClass::Layout( skin );
if ( m_bSizeToContents )
{
DoSizeToContents();
}
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
{
if (!*it)
continue;
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
if ( !pRow ) continue;
for (int i=0; i<TableRow::MaxColumns && i < m_iColumnCount; i++)
{
pRow->SetColumnWidth( i, m_ColumnWidth[i] );
}
}
}
void PostLayout( Skin::Base* /*skin*/ )
{
if ( m_bSizeToContents )
{
SizeToChildren();
m_bSizeToContents = false;
}
}
void SizeToContents()
{
m_bSizeToContents = true;
Invalidate();
}
void DoSizeToContents()
{
for (int i=0; i<TableRow::MaxColumns; i++)
{
m_ColumnWidth[i] = 10;
}
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
{
if (!*it)
continue;
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
if ( !pRow ) continue;
pRow->SizeToContents();
for (int i=0; i<TableRow::MaxColumns; i++)
{
if ( pRow->m_Columns[i] )
{
m_ColumnWidth[i] = Utility::Max( m_ColumnWidth[i], pRow->m_Columns[i]->Width() );
}
}
//iBottom += pRow->Height();
}
InvalidateParent();
}
private:
bool m_bSizeToContents;
int m_iColumnCount;
int m_iDefaultRowHeight;
int m_ColumnWidth[ TableRow::MaxColumns ];
};
m_ColumnCount = iCount;
}
}
}
void SetColumnWidth(int i, int iWidth)
{
if (!m_Columns[i]) return;
if (m_Columns[i]->Width() == iWidth) return;
m_Columns[i]->SetWidth(iWidth);
}
template <typename T>
void SetCellText(int i, const T& strString)
{
if (!m_Columns[i]) return;
m_Columns[i]->SetText(strString);
}
void SetCellContents(int i, Base* pControl, bool bEnableMouseInput = false)
{
if (!m_Columns[i]) return;
pControl->SetParent(m_Columns[i]);
m_Columns[i]->SetMouseInputEnabled(bEnableMouseInput);
}
Label* GetCellContents(int i)
{
return m_Columns[i];
}
void SizeToContents()
{
int iHeight = 0;
for (int i = 0; i < m_ColumnCount; i++)
{
if (!m_Columns[i]) continue;
// Note, more than 1 child here, because the
// label has a child built in ( The Text )
if (m_Columns[i]->NumChildren() > 1)
{
m_Columns[i]->SizeToChildren();
}
else
{
m_Columns[i]->SizeToContents();
}
iHeight = Utility::Max(iHeight, m_Columns[i]->Height());
}
SetHeight(iHeight);
}
void SetTextColor(const Gwen::Color& color)
{
for (int i = 0; i < m_ColumnCount; i++)
{
if (!m_Columns[i]) continue;
m_Columns[i]->SetTextColor(color);
}
}
//You might hate this. Actually I know you will
virtual UnicodeString GetText(int i)
{
return m_Columns[i]->GetText();
}
virtual void SetSelected(bool /*b*/) {}
//
// This is sometimes called by derivatives.
//
Gwen::Event::Caller onRowSelected;
private:
int m_ColumnCount;
Label* m_Columns[MaxColumns];
friend class Table;
};
class GWEN_EXPORT Table : public Base
{
public:
GWEN_CONTROL_INLINE(Table, Base)
{
m_iColumnCount = 1;
m_iDefaultRowHeight = 22;
for (int i = 0; i < TableRow::MaxColumns; i++)
{
m_ColumnWidth[i] = 20;
}
m_bSizeToContents = false;
}
void SetColumnCount(int i)
{
if (m_iColumnCount == i) return;
for (Base::List::iterator it = Children.begin(); it != Children.end(); ++it)
{
if (!*it)
continue;
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
if (!pRow) continue;
pRow->SetColumnCount(i);
}
m_iColumnCount = i;
}
void SetColumnWidth(int i, int iWidth)
{
if (m_ColumnWidth[i] == iWidth) return;
m_ColumnWidth[i] = iWidth;
Invalidate();
}
TableRow* AddRow()
{
TableRow* row = new TableRow(this);
row->SetColumnCount(m_iColumnCount);
row->SetHeight(m_iDefaultRowHeight);
row->Dock(Pos::Top);
return row;
}
void AddRow(TableRow* pRow)
{
pRow->SetParent(this);
pRow->SetColumnCount(m_iColumnCount);
pRow->SetHeight(m_iDefaultRowHeight);
pRow->Dock(Pos::Top);
}
void Remove(TableRow* pRow)
{
pRow->DelayedDelete();
}
void Clear()
{
for (Base::List::iterator it = Children.begin(); it != Children.end(); ++it)
{
if (!(*it))
continue;
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
if (!pRow) continue;
Remove(pRow);
}
}
void Layout(Skin::Base* skin)
{
BaseClass::Layout(skin);
if (m_bSizeToContents)
{
DoSizeToContents();
}
for (Base::List::iterator it = Children.begin(); it != Children.end(); ++it)
{
if (!*it)
continue;
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
if (!pRow) continue;
for (int i = 0; i < TableRow::MaxColumns && i < m_iColumnCount; i++)
{
pRow->SetColumnWidth(i, m_ColumnWidth[i]);
}
}
}
void PostLayout(Skin::Base* /*skin*/)
{
if (m_bSizeToContents)
{
SizeToChildren();
m_bSizeToContents = false;
}
}
void SizeToContents()
{
m_bSizeToContents = true;
Invalidate();
}
void DoSizeToContents()
{
for (int i = 0; i < TableRow::MaxColumns; i++)
{
m_ColumnWidth[i] = 10;
}
for (Base::List::iterator it = Children.begin(); it != Children.end(); ++it)
{
if (!*it)
continue;
TableRow* pRow = (*it)->DynamicCastLayoutTableRow();
if (!pRow) continue;
pRow->SizeToContents();
for (int i = 0; i < TableRow::MaxColumns; i++)
{
if (pRow->m_Columns[i])
{
m_ColumnWidth[i] = Utility::Max(m_ColumnWidth[i], pRow->m_Columns[i]->Width());
}
}
//iBottom += pRow->Height();
}
InvalidateParent();
}
private:
bool m_bSizeToContents;
int m_iColumnCount;
int m_iDefaultRowHeight;
int m_ColumnWidth[TableRow::MaxColumns];
};
} // namespace Layout
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Controls/ListBox.h"
#include "Gwen/Controls/ScrollControl.h"
#include "Gwen/InputHandler.h"
@@ -14,15 +13,15 @@ using namespace Gwen::Controls;
class ListBoxRow : public Layout::TableRow
{
GWEN_CONTROL_INLINE( ListBoxRow, Layout::TableRow )
GWEN_CONTROL_INLINE(ListBoxRow, Layout::TableRow)
{
SetMouseInputEnabled( true );
SetSelected( false );
SetMouseInputEnabled(true);
SetSelected(false);
}
void Render( Skin::Base* skin )
void Render(Skin::Base* skin)
{
skin->DrawListBoxLine( this, IsSelected() );
skin->DrawListBoxLine(this, IsSelected());
}
bool IsSelected() const
@@ -30,108 +29,106 @@ class ListBoxRow : public Layout::TableRow
return m_bSelected;
}
void OnMouseClickLeft( int /*x*/, int /*y*/, bool bDown )
void OnMouseClickLeft(int /*x*/, int /*y*/, bool bDown)
{
if ( bDown && !m_bSelected )
if (bDown && !m_bSelected)
{
SetSelected( true );
onRowSelected.Call( this );
SetSelected(true);
onRowSelected.Call(this);
}
}
void SetSelected( bool b )
void SetSelected(bool b)
{
m_bSelected = b;
// TODO: Get these values from the skin.
if ( b )
SetTextColor( Gwen::Colors::White );
if (b)
SetTextColor(Gwen::Colors::White);
else
SetTextColor( Gwen::Colors::Black );
SetTextColor(Gwen::Colors::Black);
}
private:
bool m_bSelected;
private:
bool m_bSelected;
};
GWEN_CONTROL_CONSTRUCTOR( ListBox )
GWEN_CONTROL_CONSTRUCTOR(ListBox)
{
m_ScrollControl = new ScrollControl( this );
m_ScrollControl->Dock( Pos::Fill );
m_ScrollControl->SetScroll( false, true );
m_ScrollControl->SetAutoHideBars( true );
m_ScrollControl->SetMargin( Margin( 1, 1, 1, 1 ) );
m_ScrollControl = new ScrollControl(this);
m_ScrollControl->Dock(Pos::Fill);
m_ScrollControl->SetScroll(false, true);
m_ScrollControl->SetAutoHideBars(true);
m_ScrollControl->SetMargin(Margin(1, 1, 1, 1));
m_InnerPanel = m_ScrollControl;
m_Table = new Controls::Layout::Table( this );
m_Table->Dock( Pos::Top );
m_Table->SetColumnCount( 1 );
m_Table = new Controls::Layout::Table(this);
m_Table->Dock(Pos::Top);
m_Table->SetColumnCount(1);
m_bMultiSelect = false;
}
void ListBox::OnChildBoundsChanged( Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/ )
void ListBox::OnChildBoundsChanged(Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/)
{
m_ScrollControl->UpdateScrollBars();
}
Layout::TableRow* ListBox::AddItem( const String& strLabel, const String& strName )
Layout::TableRow* ListBox::AddItem(const String& strLabel, const String& strName)
{
return AddItem( Utility::StringToUnicode( strLabel ), strName );
return AddItem(Utility::StringToUnicode(strLabel), strName);
}
Layout::TableRow* ListBox::AddItem( const UnicodeString& strLabel, const String& strName )
Layout::TableRow* ListBox::AddItem(const UnicodeString& strLabel, const String& strName)
{
ListBoxRow* pRow = new ListBoxRow( this );
m_Table->AddRow( pRow );
ListBoxRow* pRow = new ListBoxRow(this);
m_Table->AddRow(pRow);
pRow->SetCellText( 0, strLabel );
pRow->SetName( strName );
pRow->SetCellText(0, strLabel);
pRow->SetName(strName);
pRow->onRowSelected.Add( this, &ListBox::OnRowSelected );
pRow->onRowSelected.Add(this, &ListBox::OnRowSelected);
m_Table->SizeToContents();
return pRow;
}
void ListBox::Render( Skin::Base* skin )
void ListBox::Render(Skin::Base* skin)
{
skin->DrawListBox( this );
skin->DrawListBox(this);
}
void ListBox::UnselectAll()
{
std::list<Layout::TableRow*>::iterator it = m_SelectedRows.begin();
while ( it != m_SelectedRows.end() )
while (it != m_SelectedRows.end())
{
ListBoxRow* pRow = static_cast<ListBoxRow*>(*it);
it = m_SelectedRows.erase( it );
it = m_SelectedRows.erase(it);
pRow->SetSelected( false );
pRow->SetSelected(false);
}
}
void ListBox::OnRowSelected( Base* pControl )
void ListBox::OnRowSelected(Base* pControl)
{
ListBoxRow* pRow = static_cast<ListBoxRow*>(pControl);
if ( !AllowMultiSelect() || !Gwen::Input::IsShiftDown() )
if (!AllowMultiSelect() || !Gwen::Input::IsShiftDown())
{
UnselectAll();
}
m_SelectedRows.push_back( pRow );
onRowSelected.Call( this );
m_SelectedRows.push_back(pRow);
onRowSelected.Call(this);
}
Layout::TableRow* ListBox::GetSelectedRow()
{
if ( m_SelectedRows.empty() ) return NULL;
{
if (m_SelectedRows.empty()) return NULL;
return *m_SelectedRows.begin();
}

View File

@@ -12,56 +12,52 @@
#include "Gwen/Controls/Layout/Table.h"
#include "Gwen/Controls/ScrollControl.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class ScrollControl;
namespace Controls
{
class ScrollControl;
class GWEN_EXPORT ListBox : public Base
{
public:
GWEN_CONTROL( ListBox, Base );
class GWEN_EXPORT ListBox : public Base
{
public:
GWEN_CONTROL(ListBox, Base);
typedef std::list<Layout::TableRow*> Rows;
typedef std::list<Layout::TableRow*> Rows;
Layout::TableRow* AddItem( const String& strLabel, const String& strName = "" );
Layout::TableRow* AddItem( const UnicodeString& strLabel, const String& strName = "" );
Layout::TableRow* AddItem(const String& strLabel, const String& strName = "");
Layout::TableRow* AddItem(const UnicodeString& strLabel, const String& strName = "");
void Render( Skin::Base* skin );
void Render(Skin::Base* skin);
void UnselectAll();
void UnselectAll();
void SetColumnCount( int iCount ) { m_Table->SetColumnCount( iCount ); }
void SetColumnCount(int iCount) { m_Table->SetColumnCount(iCount); }
void SetAllowMultiSelect( bool bMultiSelect ){ m_bMultiSelect = bMultiSelect; }
bool AllowMultiSelect() const { return m_bMultiSelect; }
void SetAllowMultiSelect(bool bMultiSelect) { m_bMultiSelect = bMultiSelect; }
bool AllowMultiSelect() const { return m_bMultiSelect; }
const ListBox::Rows& GetSelectedRows(){ return m_SelectedRows; }
Layout::TableRow* GetSelectedRow();
const ListBox::Rows& GetSelectedRows() { return m_SelectedRows; }
Layout::TableRow* GetSelectedRow();
Gwen::Controls::ScrollControl* Scroller() { return m_ScrollControl; }
Gwen::Controls::ScrollControl* Scroller() { return m_ScrollControl; }
void OnChildBoundsChanged( Gwen::Rect oldChildBounds, Base* pChild );
Gwen::Event::Caller onRowSelected;
void OnChildBoundsChanged(Gwen::Rect oldChildBounds, Base* pChild);
Controls::Layout::Table* GetTable() { return m_Table; }
virtual void Clear();
Gwen::Event::Caller onRowSelected;
protected:
Controls::Layout::Table* GetTable() { return m_Table; }
virtual void Clear();
void OnRowSelected( Base* pControl );
Controls::Layout::Table* m_Table;
ListBox::Rows m_SelectedRows;
Controls::ScrollControl* m_ScrollControl;
protected:
void OnRowSelected(Base* pControl);
bool m_bMultiSelect;
};
}
}
Controls::Layout::Table* m_Table;
ListBox::Rows m_SelectedRows;
Controls::ScrollControl* m_ScrollControl;
bool m_bMultiSelect;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Controls/Menu.h"
#include "Gwen/Skin.h"
@@ -13,107 +12,102 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( Menu )
GWEN_CONTROL_CONSTRUCTOR(Menu)
{
SetBounds( 0, 0, 10, 10 );
SetPadding( Padding( 2, 2, 2, 2 ) );
SetBounds(0, 0, 10, 10);
SetPadding(Padding(2, 2, 2, 2));
SetDisableIconMargin( false );
SetDisableIconMargin(false);
SetAutoHideBars( true );
SetScroll( false, true );
SetAutoHideBars(true);
SetScroll(false, true);
}
void Menu::Render( Skin::Base* skin )
void Menu::Render(Skin::Base* skin)
{
skin->DrawMenu( this, IconMarginDisabled() );
skin->DrawMenu(this, IconMarginDisabled());
}
void Menu::RenderUnder( Skin::Base* skin )
void Menu::RenderUnder(Skin::Base* skin)
{
BaseClass::RenderUnder( skin );
skin->DrawShadow( this );
BaseClass::RenderUnder(skin);
skin->DrawShadow(this);
}
void Menu::Layout( Skin::Base* skin )
void Menu::Layout(Skin::Base* skin)
{
int childrenHeight = 0;
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it)
{
Base* pChild = (*it);
if ( !pChild )
if (!pChild)
continue;
childrenHeight += pChild->Height();
}
if ( Y() + childrenHeight > GetCanvas()->Height() )
if (Y() + childrenHeight > GetCanvas()->Height())
childrenHeight = GetCanvas()->Height() - Y();
SetSize( Width(), childrenHeight );
SetSize(Width(), childrenHeight);
BaseClass::Layout( skin );
BaseClass::Layout(skin);
}
MenuItem* Menu::AddItem( const Gwen::UnicodeString& strName, const UnicodeString& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn )
MenuItem* Menu::AddItem(const Gwen::UnicodeString& strName, const UnicodeString& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn)
{
MenuItem* pItem = new MenuItem( this );
pItem->SetText( strName );
pItem->SetImage( strIconName );
MenuItem* pItem = new MenuItem(this);
pItem->SetText(strName);
pItem->SetImage(strIconName);
if ( fn && pHandler )
{
pItem->onMenuItemSelected.Add( pHandler, fn );
}
OnAddItem( pItem );
if (fn && pHandler)
{
pItem->onMenuItemSelected.Add(pHandler, fn);
}
OnAddItem(pItem);
return pItem;
}
void Menu::OnAddItem( MenuItem* item )
void Menu::OnAddItem(MenuItem* item)
{
item->Dock( Pos::Top );
item->SetTextPadding( Padding( IconMarginDisabled() ? 0 : 24, 0, 16, 0 ) );
item->SetPadding( Padding( 4, 4, 4, 4 ) );
item->Dock(Pos::Top);
item->SetTextPadding(Padding(IconMarginDisabled() ? 0 : 24, 0, 16, 0));
item->SetPadding(Padding(4, 4, 4, 4));
item->SizeToContents();
item->SetAlignment( Pos::CenterV | Pos::Left );
item->onHoverEnter.Add( this, &Menu::OnHoverItem );
item->SetAlignment(Pos::CenterV | Pos::Left);
item->onHoverEnter.Add(this, &Menu::OnHoverItem);
// Do this here - after Top Docking these values mean nothing in layout
int w = item->Width() + 10 + 32;
if ( w < Width() ) w = Width();
SetSize( w, Height() );
if (w < Width()) w = Width();
SetSize(w, Height());
}
void Menu::ClearItems()
{
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it)
{
Base* pChild = *it;
if ( !pChild ) continue;
if (!pChild) continue;
pChild->DelayedDelete();
}
}
MenuItem* Menu::AddItem( const Gwen::String& strName, const String& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn )
MenuItem* Menu::AddItem(const Gwen::String& strName, const String& strIconName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn)
{
return AddItem( Gwen::Utility::StringToUnicode( strName ), Gwen::Utility::StringToUnicode( strIconName ), pHandler, fn );
return AddItem(Gwen::Utility::StringToUnicode(strName), Gwen::Utility::StringToUnicode(strIconName), pHandler, fn);
}
void Menu::CloseAll()
{
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it)
{
Base* pChild = *it;
MenuItem* pItem = pChild->DynamicCastMenuItem();
if ( !pItem ) continue;
if (!pItem) continue;
pItem->CloseMenu();
}
@@ -121,26 +115,26 @@ void Menu::CloseAll()
bool Menu::IsMenuOpen()
{
for ( Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it )
for (Base::List::iterator it = m_InnerPanel->Children.begin(); it != m_InnerPanel->Children.end(); ++it)
{
Base* pChild = *it;
MenuItem* pItem = pChild->DynamicCastMenuItem();
if ( !pItem ) continue;
if (!pItem) continue;
if ( pItem->IsMenuOpen() )
if (pItem->IsMenuOpen())
return true;
}
return false;
}
void Menu::OnHoverItem( Gwen::Controls::Base* pControl )
void Menu::OnHoverItem(Gwen::Controls::Base* pControl)
{
if ( !ShouldHoverOpenMenu() ) return;
if (!ShouldHoverOpenMenu()) return;
MenuItem* pItem = pControl->DynamicCastMenuItem();
if (!pItem) return;
if ( pItem->IsMenuOpen() ) return;
if (pItem->IsMenuOpen()) return;
CloseAll();
pItem->OpenMenu();
@@ -148,7 +142,7 @@ void Menu::OnHoverItem( Gwen::Controls::Base* pControl )
void Menu::Close()
{
SetHidden( true );
SetHidden(true);
}
void Menu::CloseMenus()
@@ -161,12 +155,12 @@ void Menu::CloseMenus()
void Menu::AddDivider()
{
MenuDivider* divider = new MenuDivider( this );
divider->Dock( Pos::Top );
divider->SetMargin( Margin( IconMarginDisabled() ? 0 : 24, 0, 4, 0 ) );
MenuDivider* divider = new MenuDivider(this);
divider->Dock(Pos::Top);
divider->SetMargin(Margin(IconMarginDisabled() ? 0 : 24, 0, 4, 0));
}
void MenuDivider::Render( Gwen::Skin::Base* skin )
void MenuDivider::Render(Gwen::Skin::Base* skin)
{
skin->DrawMenuDivider( this );
skin->DrawMenuDivider(this);
}

View File

@@ -13,74 +13,71 @@
#include "Gwen/Controls/MenuItem.h"
#include "Gwen/Controls/ScrollControl.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class MenuItem;
class GWEN_EXPORT Menu : public ScrollControl
{
public:
GWEN_CONTROL(Menu, ScrollControl);
virtual void Render(Skin::Base* skin);
virtual void RenderUnder(Skin::Base* skin);
virtual void Layout(Skin::Base* skin);
virtual MenuItem* AddItem(const Gwen::UnicodeString& strName, const UnicodeString& strIconName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL);
virtual MenuItem* AddItem(const Gwen::UnicodeString& strName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL)
{
class MenuItem;
class GWEN_EXPORT Menu : public ScrollControl
{
public:
GWEN_CONTROL( Menu, ScrollControl );
virtual void Render( Skin::Base* skin );
virtual void RenderUnder( Skin::Base* skin );
virtual void Layout( Skin::Base* skin );
virtual MenuItem* AddItem( const Gwen::UnicodeString& strName, const UnicodeString& strIconName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL );
virtual MenuItem* AddItem( const Gwen::UnicodeString& strName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL )
{
return AddItem( strName, L"", pHandler, fn );
}
virtual MenuItem* AddItem( const Gwen::String& strName, const String& strIconName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL );
virtual MenuItem* AddItem( const Gwen::String& strName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL )
{
return AddItem( strName, "", pHandler, fn );
}
virtual void AddDivider();
void OnHoverItem( Gwen::Controls::Base* pControl );
void CloseAll();
bool IsMenuOpen();
void ClearItems();
virtual void Close();
virtual bool IsMenuComponent(){ return true; }
virtual void CloseMenus();
bool IconMarginDisabled() { return m_bDisableIconMargin; }
void SetDisableIconMargin( bool bDisable ) { m_bDisableIconMargin = bDisable; }
virtual bool ShouldClip(){ return false; }
protected:
virtual bool ShouldHoverOpenMenu(){ return true; }
virtual void OnAddItem( MenuItem* item );
bool m_bDisableIconMargin;
};
class GWEN_EXPORT MenuDivider : public Base
{
public:
GWEN_CONTROL_INLINE( MenuDivider, Base )
{
SetHeight( 1 );
}
void Render( Gwen::Skin::Base* skin );
};
return AddItem(strName, L"", pHandler, fn);
}
}
virtual MenuItem* AddItem(const Gwen::String& strName, const String& strIconName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL);
virtual MenuItem* AddItem(const Gwen::String& strName, Gwen::Event::Handler* pHandler = NULL, Gwen::Event::Handler::Function fn = NULL)
{
return AddItem(strName, "", pHandler, fn);
}
virtual void AddDivider();
void OnHoverItem(Gwen::Controls::Base* pControl);
void CloseAll();
bool IsMenuOpen();
void ClearItems();
virtual void Close();
virtual bool IsMenuComponent() { return true; }
virtual void CloseMenus();
bool IconMarginDisabled() { return m_bDisableIconMargin; }
void SetDisableIconMargin(bool bDisable) { m_bDisableIconMargin = bDisable; }
virtual bool ShouldClip() { return false; }
protected:
virtual bool ShouldHoverOpenMenu() { return true; }
virtual void OnAddItem(MenuItem* item);
bool m_bDisableIconMargin;
};
class GWEN_EXPORT MenuDivider : public Base
{
public:
GWEN_CONTROL_INLINE(MenuDivider, Base)
{
SetHeight(1);
}
void Render(Gwen::Skin::Base* skin);
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Controls/MenuItem.h"
#include "Gwen/Skin.h"
@@ -12,44 +11,42 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( MenuItem )
GWEN_CONTROL_CONSTRUCTOR(MenuItem)
{
m_Menu = NULL;
m_bOnStrip = false;
m_SubmenuArrow = NULL;
SetTabable( false );
SetCheckable( false );
SetCheck( false );
SetTabable(false);
SetCheckable(false);
SetCheck(false);
}
MenuItem::~MenuItem()
{
}
void MenuItem::Render( Skin::Base* skin )
void MenuItem::Render(Skin::Base* skin)
{
skin->DrawMenuItem( this, IsMenuOpen(), m_bCheckable ? m_bChecked : false );
skin->DrawMenuItem(this, IsMenuOpen(), m_bCheckable ? m_bChecked : false);
}
void MenuItem::Layout( Skin::Base* skin )
void MenuItem::Layout(Skin::Base* skin)
{
BaseClass::Layout( skin );
BaseClass::Layout(skin);
}
Menu* MenuItem::GetMenu()
{
if ( !m_Menu )
if (!m_Menu)
{
m_Menu = new Menu( GetCanvas() );
m_Menu->SetHidden( true );
m_Menu = new Menu(GetCanvas());
m_Menu->SetHidden(true);
if ( !m_bOnStrip )
if (!m_bOnStrip)
{
m_SubmenuArrow = new Symbol::Arrow( this );
m_SubmenuArrow->Dock( Pos::Right );
m_SubmenuArrow->SetSize( 20, 20 );
m_SubmenuArrow = new Symbol::Arrow(this);
m_SubmenuArrow->Dock(Pos::Right);
m_SubmenuArrow->SetSize(20, 20);
}
Invalidate();
@@ -58,31 +55,31 @@ Menu* MenuItem::GetMenu()
return m_Menu;
}
void MenuItem::SetCheck( bool bCheck )
void MenuItem::SetCheck(bool bCheck)
{
if ( bCheck == m_bChecked)
if (bCheck == m_bChecked)
return;
m_bChecked = bCheck;
onCheckChange.Call( this );
onCheckChange.Call(this);
if ( bCheck )
onChecked.Call( this );
if (bCheck)
onChecked.Call(this);
else
onUnChecked.Call( this );
onUnChecked.Call(this);
}
void MenuItem::OnPress()
{
if ( m_Menu )
if (m_Menu)
{
ToggleMenu();
}
else if ( !m_bOnStrip )
else if (!m_bOnStrip)
{
SetCheck( !GetChecked() );
onMenuItemSelected.Call( this );
SetCheck(!GetChecked());
onMenuItemSelected.Call(this);
GetCanvas()->CloseMenus();
}
@@ -91,47 +88,47 @@ void MenuItem::OnPress()
void MenuItem::ToggleMenu()
{
if ( IsMenuOpen() ) CloseMenu();
else OpenMenu();
if (IsMenuOpen())
CloseMenu();
else
OpenMenu();
}
bool MenuItem::IsMenuOpen()
{
if ( !m_Menu ) return false;
if (!m_Menu) return false;
return !m_Menu->Hidden();
}
void MenuItem::OpenMenu()
{
if ( !m_Menu ) return;
if (!m_Menu) return;
m_Menu->SetHidden( false );
m_Menu->SetHidden(false);
m_Menu->BringToFront();
Gwen::Point p = LocalPosToCanvas( Gwen::Point( 0, 0 ) );
Gwen::Point p = LocalPosToCanvas(Gwen::Point(0, 0));
// Strip menus open downwards
if ( m_bOnStrip )
if (m_bOnStrip)
{
m_Menu->SetPos( p.x, p.y + Height() + 1 );
m_Menu->SetPos(p.x, p.y + Height() + 1);
}
// Submenus open sidewards
else
{
m_Menu->SetPos( p.x + Width(), p.y);
m_Menu->SetPos(p.x + Width(), p.y);
}
// TODO: Option this.
// TODO: Make sure on screen, open the other side of the
// TODO: Make sure on screen, open the other side of the
// parent if it's better...
}
void MenuItem::CloseMenu()
{
if ( !m_Menu ) return;
if (!m_Menu) return;
m_Menu->Close();
m_Menu->CloseAll();
}

View File

@@ -14,56 +14,52 @@
#include "Gwen/Controls/Menu.h"
#include "Gwen/Controls/Symbol.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class Menu;
namespace Controls
{
class Menu;
class GWEN_EXPORT MenuItem : public Button
{
public:
class GWEN_EXPORT MenuItem : public Button
{
public:
GWEN_CONTROL(MenuItem, Button);
GWEN_CONTROL( MenuItem, Button );
virtual ~MenuItem();
virtual ~MenuItem();
virtual void Render(Skin::Base* skin);
virtual void Layout(Skin::Base* skin);
virtual void Render( Skin::Base* skin );
virtual void Layout( Skin::Base* skin );
virtual void OnPress();
virtual void OnPress();
Menu* GetMenu();
Menu* GetMenu();
bool IsMenuOpen();
void OpenMenu();
void CloseMenu();
void ToggleMenu();
bool IsMenuOpen();
void OpenMenu();
void CloseMenu();
void ToggleMenu();
void SetOnStrip(bool b) { m_bOnStrip = b; }
bool OnStrip() { return m_bOnStrip; }
void SetOnStrip( bool b ){ m_bOnStrip = b;}
bool OnStrip(){ return m_bOnStrip; }
virtual void SetCheckable(bool bCheck) { m_bCheckable = bCheck; }
virtual void SetCheck(bool bCheck);
virtual bool GetChecked() { return m_bChecked; }
virtual void SetCheckable( bool bCheck ) { m_bCheckable = bCheck; }
virtual void SetCheck( bool bCheck );
virtual bool GetChecked() { return m_bChecked; }
Gwen::Event::Caller onMenuItemSelected;
Gwen::Event::Caller onChecked;
Gwen::Event::Caller onUnChecked;
Gwen::Event::Caller onCheckChange;
Gwen::Event::Caller onMenuItemSelected;
Gwen::Event::Caller onChecked;
Gwen::Event::Caller onUnChecked;
Gwen::Event::Caller onCheckChange;
private:
Menu* m_Menu;
bool m_bOnStrip;
bool m_bCheckable;
bool m_bChecked;
private:
Symbol::Arrow* m_SubmenuArrow;
};
} // namespace Controls
Menu* m_Menu;
bool m_bOnStrip;
bool m_bCheckable;
bool m_bChecked;
Symbol::Arrow * m_SubmenuArrow;
};
}
}
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Controls/MenuStrip.h"
#include "Gwen/Skin.h"
@@ -12,30 +11,30 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( MenuStrip )
GWEN_CONTROL_CONSTRUCTOR(MenuStrip)
{
SetBounds( 0, 0, 200, 22 );
Dock( Pos::Top );
m_InnerPanel->SetPadding( Padding( 5, 2, 2, 2 ) );
SetBounds(0, 0, 200, 22);
Dock(Pos::Top);
m_InnerPanel->SetPadding(Padding(5, 2, 2, 2));
}
void MenuStrip::Render( Skin::Base* skin )
void MenuStrip::Render(Skin::Base* skin)
{
skin->DrawMenuStrip( this );
skin->DrawMenuStrip(this);
}
void MenuStrip::Layout( Skin::Base* /*skin*/ )
void MenuStrip::Layout(Skin::Base* /*skin*/)
{
//TODO: We don't want to do vertical sizing the same as Menu, do nothing for now
}
void MenuStrip::OnAddItem( MenuItem* item )
void MenuStrip::OnAddItem(MenuItem* item)
{
item->Dock( Pos::Left );
item->SetPadding( Padding( 5, 0, 5, 0 ) );
item->Dock(Pos::Left);
item->SetPadding(Padding(5, 0, 5, 0));
item->SizeToContents();
item->SetOnStrip( true );
item->onHoverEnter.Add( this, &Menu::OnHoverItem );
item->SetOnStrip(true);
item->onHoverEnter.Add(this, &Menu::OnHoverItem);
}
bool MenuStrip::ShouldHoverOpenMenu()

View File

@@ -13,27 +13,24 @@
#include "Gwen/Controls/Menu.h"
#include "Gwen/Controls/MenuItem.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT MenuStrip : public Menu
{
GWEN_CONTROL( MenuStrip, Menu );
namespace Controls
{
class GWEN_EXPORT MenuStrip : public Menu
{
GWEN_CONTROL(MenuStrip, Menu);
virtual void Render( Skin::Base* skin );
virtual void RenderUnder( Skin::Base* /*skin*/ ){}
virtual void Layout( Skin::Base* skin );
virtual void Render(Skin::Base* skin);
virtual void RenderUnder(Skin::Base* /*skin*/) {}
virtual void Layout(Skin::Base* skin);
protected:
protected:
virtual void OnAddItem(MenuItem* item);
virtual bool ShouldHoverOpenMenu();
virtual void Close() {}
};
} // namespace Controls
virtual void OnAddItem( MenuItem* item );
virtual bool ShouldHoverOpenMenu();
virtual void Close() {}
};
}
}
} // namespace Gwen
#endif

View File

@@ -6,32 +6,31 @@
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace ControlsInternal
namespace ControlsInternal
{
class Modal : public Controls::Base
{
GWEN_CONTROL_INLINE(Modal, Controls::Base)
{
class Modal : public Controls::Base
{
GWEN_CONTROL_INLINE( Modal, Controls::Base )
{
SetKeyboardInputEnabled( true );
SetMouseInputEnabled( true );
SetShouldDrawBackground( true );
}
virtual void Layout( Skin::Base* /*skin*/ )
{
SetBounds( 0, 0, GetCanvas()->Width(), GetCanvas()->Height() );
}
virtual void Render( Skin::Base* skin )
{
if ( !ShouldDrawBackground() ) return;
skin->DrawModalControl( this );
}
};
SetKeyboardInputEnabled(true);
SetMouseInputEnabled(true);
SetShouldDrawBackground(true);
}
}
virtual void Layout(Skin::Base* /*skin*/)
{
SetBounds(0, 0, GetCanvas()->Width(), GetCanvas()->Height());
}
virtual void Render(Skin::Base* skin)
{
if (!ShouldDrawBackground()) return;
skin->DrawModalControl(this);
}
};
} // namespace ControlsInternal
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Utility.h"
#include "Gwen/Skin.h"
@@ -14,83 +13,79 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( NumericUpDown )
GWEN_CONTROL_CONSTRUCTOR(NumericUpDown)
{
SetSize( 100, 20 );
SetSize(100, 20);
Layout::Splitter* pSplitter = new Layout::Splitter( this );
pSplitter->Dock( Pos::Right );
pSplitter->SetSize( 13, 13 );
Layout::Splitter* pSplitter = new Layout::Splitter(this);
pSplitter->Dock(Pos::Right);
pSplitter->SetSize(13, 13);
NumericUpDownButton_Up* pButtonUp = new NumericUpDownButton_Up( pSplitter );
pButtonUp->onPress.Add( this, &NumericUpDown::OnButtonUp );
pButtonUp->SetTabable( false );
NumericUpDownButton_Up* pButtonUp = new NumericUpDownButton_Up(pSplitter);
pButtonUp->onPress.Add(this, &NumericUpDown::OnButtonUp);
pButtonUp->SetTabable(false);
pSplitter->SetPanel( 0, pButtonUp );
pSplitter->SetPanel(0, pButtonUp);
NumericUpDownButton_Down* pButtonDown = new NumericUpDownButton_Down( pSplitter );
pButtonDown->onPress.Add( this, &NumericUpDown::OnButtonDown );
pButtonDown->SetTabable( false );
pButtonUp->SetPadding( Padding( 0, 1, 1, 0 ) );
NumericUpDownButton_Down* pButtonDown = new NumericUpDownButton_Down(pSplitter);
pButtonDown->onPress.Add(this, &NumericUpDown::OnButtonDown);
pButtonDown->SetTabable(false);
pButtonUp->SetPadding(Padding(0, 1, 1, 0));
pSplitter->SetPanel( 1, pButtonDown );
pSplitter->SetPanel(1, pButtonDown);
m_iMax = 100;
m_iMin = 0;
m_iNumber = 0;
SetText( "0" );
SetText("0");
}
void NumericUpDown::OnButtonUp( Base* /*control*/ )
void NumericUpDown::OnButtonUp(Base* /*control*/)
{
SyncNumberFromText();
SetValue( m_iNumber + 1 );
SetValue(m_iNumber + 1);
}
void NumericUpDown::OnButtonDown( Base* /*control*/ )
void NumericUpDown::OnButtonDown(Base* /*control*/)
{
SyncNumberFromText();
SetValue( m_iNumber - 1 );
SetValue(m_iNumber - 1);
}
void NumericUpDown::SyncTextFromNumber()
{
SetText( Utility::ToString( m_iNumber ) );
SetText(Utility::ToString(m_iNumber));
}
void NumericUpDown::SyncNumberFromText()
{
SetValue( (int) GetFloatFromText() );
SetValue((int)GetFloatFromText());
}
void NumericUpDown::SetMin( int i )
void NumericUpDown::SetMin(int i)
{
m_iMin = i;
}
void NumericUpDown::SetMax( int i )
void NumericUpDown::SetMax(int i)
{
m_iMax = i;
}
void NumericUpDown::SetValue( int i )
void NumericUpDown::SetValue(int i)
{
if ( i > m_iMax ) i = m_iMax;
if ( i < m_iMin ) i = m_iMin;
if (i > m_iMax) i = m_iMax;
if (i < m_iMin) i = m_iMin;
if ( m_iNumber == i )
{
if (m_iNumber == i)
{
return;
}
m_iNumber = i;
// Don't update the text if we're typing in it..
if ( !HasFocus() )
if (!HasFocus())
{
SyncTextFromNumber();
}
@@ -100,7 +95,7 @@ void NumericUpDown::SetValue( int i )
void NumericUpDown::OnChange()
{
onChanged.Call( this );
onChanged.Call(this);
}
void NumericUpDown::OnTextChanged()

View File

@@ -12,64 +12,67 @@
#include "Gwen/Controls/Button.h"
#include "Gwen/Controls/TextBox.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class GWEN_EXPORT NumericUpDownButton_Up : public Button
{
GWEN_CONTROL_INLINE(NumericUpDownButton_Up, Button) {}
virtual void Render(Skin::Base* skin)
{
class GWEN_EXPORT NumericUpDownButton_Up : public Button
{
GWEN_CONTROL_INLINE( NumericUpDownButton_Up, Button ){}
virtual void Render( Skin::Base* skin )
{
skin->DrawNumericUpDownButton( this, m_bDepressed, true );
}
};
class GWEN_EXPORT NumericUpDownButton_Down : public Button
{
GWEN_CONTROL_INLINE( NumericUpDownButton_Down, Button ){}
virtual void Render( Skin::Base* skin )
{
skin->DrawNumericUpDownButton( this, m_bDepressed, false );
}
};
class GWEN_EXPORT NumericUpDown : public TextBoxNumeric
{
public:
GWEN_CONTROL( NumericUpDown, TextBoxNumeric );
virtual void SetMin( int i );
virtual void SetMax( int i );
virtual void SetValue( int i );
Event::Caller onChanged;
private:
virtual void OnEnter();
virtual void OnChange();
virtual void OnTextChanged();
virtual void OnButtonUp( Base* control );
virtual void OnButtonDown( Base* control );
virtual bool OnKeyUp( bool bDown ) { if ( bDown ) OnButtonUp( NULL ); return true; }
virtual bool OnKeyDown( bool bDown ){ if ( bDown ) OnButtonDown( NULL ); return true; }
virtual void SyncTextFromNumber();
virtual void SyncNumberFromText();
int m_iNumber;
int m_iMax;
int m_iMin;
};
skin->DrawNumericUpDownButton(this, m_bDepressed, true);
}
}
};
class GWEN_EXPORT NumericUpDownButton_Down : public Button
{
GWEN_CONTROL_INLINE(NumericUpDownButton_Down, Button) {}
virtual void Render(Skin::Base* skin)
{
skin->DrawNumericUpDownButton(this, m_bDepressed, false);
}
};
class GWEN_EXPORT NumericUpDown : public TextBoxNumeric
{
public:
GWEN_CONTROL(NumericUpDown, TextBoxNumeric);
virtual void SetMin(int i);
virtual void SetMax(int i);
virtual void SetValue(int i);
Event::Caller onChanged;
private:
virtual void OnEnter();
virtual void OnChange();
virtual void OnTextChanged();
virtual void OnButtonUp(Base* control);
virtual void OnButtonDown(Base* control);
virtual bool OnKeyUp(bool bDown)
{
if (bDown) OnButtonUp(NULL);
return true;
}
virtual bool OnKeyDown(bool bDown)
{
if (bDown) OnButtonDown(NULL);
return true;
}
virtual void SyncTextFromNumber();
virtual void SyncNumberFromText();
int m_iNumber;
int m_iMax;
int m_iMin;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,7 @@
using namespace Gwen;
using namespace Controls;
GWEN_CONTROL_CONSTRUCTOR( PanelListPanel )
GWEN_CONTROL_CONSTRUCTOR(PanelListPanel)
{
m_bVertical = false;
m_bSizeToChildren = true;
@@ -13,7 +13,7 @@ GWEN_CONTROL_CONSTRUCTOR( PanelListPanel )
m_bWrapping = true;
}
void PanelListPanel::Render( Gwen::Skin::Base* /*skin*/ )
void PanelListPanel::Render(Gwen::Skin::Base* /*skin*/)
{
}
@@ -22,17 +22,17 @@ Gwen::Point PanelListPanel::GetBiggestChildSize()
int width = 0;
int height = 0;
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
for (Base::List::iterator it = Children.begin(); it != Children.end(); ++it)
{
Controls::Base* pChild = *it;
if ( pChild->Width() > width )
if (pChild->Width() > width)
width = pChild->Width();
if ( pChild->Height() > height )
if (pChild->Height() > height)
height = pChild->Height();
}
return Gwen::Point( width, height );
return Gwen::Point(width, height);
}
void PanelListPanel::DoVerticalLayout()
@@ -45,11 +45,11 @@ void PanelListPanel::DoVerticalLayout()
Gwen::Point childSize = GetBiggestChildSize();
//Lay my children out accordingly
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
for (Base::List::iterator it = Children.begin(); it != Children.end(); ++it)
{
Controls::Base* pChild = *it;
testWrap = lastPanelY + m_iControlSpacing + childSize.y;
if ( m_bWrapping && testWrap > Height() - GetPadding().bottom )
if (m_bWrapping && testWrap > Height() - GetPadding().bottom)
{
panelY = GetPadding().top;
panelX = GetPadding().left + panelWidth + m_iLineSpacing;
@@ -61,16 +61,16 @@ void PanelListPanel::DoVerticalLayout()
lastPanelY = testWrap;
}
pChild->SetPos( panelX, panelY );
pChild->SetPos(panelX, panelY);
if (pChild->X() + childSize.x > panelWidth )
if (pChild->X() + childSize.x > panelWidth)
panelWidth = pChild->X() + childSize.x;
}
if ( m_bSizeToChildren )
if (m_bSizeToChildren)
{
Gwen::Point childrenSizeTotal = ChildrenSize();
SetSize( childrenSizeTotal.x, Height());
SetSize(childrenSizeTotal.x, Height());
}
}
@@ -84,40 +84,40 @@ void PanelListPanel::DoHorizontalLayout()
Gwen::Point childSize = GetBiggestChildSize();
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
for (Base::List::iterator it = Children.begin(); it != Children.end(); ++it)
{
Controls::Base* pChild = *it;
testWrap = lastPanelX + m_iControlSpacing + childSize.x;
if ( m_bWrapping && testWrap > Width() - GetPadding().right )
{
panelX = GetPadding().left;
panelY = GetPadding().top + panelHeight + m_iLineSpacing;
lastPanelX = panelX + m_iControlSpacing + childSize.x;
}
else
{
panelX = lastPanelX;
lastPanelX = testWrap;
}
testWrap = lastPanelX + m_iControlSpacing + childSize.x;
if (m_bWrapping && testWrap > Width() - GetPadding().right)
{
panelX = GetPadding().left;
panelY = GetPadding().top + panelHeight + m_iLineSpacing;
lastPanelX = panelX + m_iControlSpacing + childSize.x;
}
else
{
panelX = lastPanelX;
lastPanelX = testWrap;
}
pChild->SetPos( panelX, panelY );
pChild->SetPos(panelX, panelY);
if (pChild->Y() + childSize.y > panelHeight )
panelHeight = pChild->Y() + childSize.y;
if (pChild->Y() + childSize.y > panelHeight)
panelHeight = pChild->Y() + childSize.y;
}
if ( m_bSizeToChildren )
if (m_bSizeToChildren)
{
Gwen::Point childrenSizeTotal = ChildrenSize();
SetSize( Width(), childrenSizeTotal.y);
SetSize(Width(), childrenSizeTotal.y);
}
}
void PanelListPanel::Layout( Skin::Base* skin )
void PanelListPanel::Layout(Skin::Base* skin)
{
BaseClass::Layout( skin );
if ( IsHorizontalLayout() )
BaseClass::Layout(skin);
if (IsHorizontalLayout())
DoHorizontalLayout();
else
DoVerticalLayout();

View File

@@ -5,42 +5,48 @@
#include "Gwen/Gwen.h"
#include "Gwen/Controls/Base.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class GWEN_EXPORT PanelListPanel : public Controls::Base
{
public:
GWEN_CONTROL(PanelListPanel, Controls::Base);
void Render(Gwen::Skin::Base* skin);
void Layout(Skin::Base* skin);
void DoHorizontalLayout();
void DoVerticalLayout();
bool IsVerticalLayout() { return m_bVertical; }
bool IsHorizontalLayout() { return !m_bVertical; }
void SetVertical()
{
class GWEN_EXPORT PanelListPanel : public Controls::Base
{
public:
GWEN_CONTROL( PanelListPanel, Controls::Base );
void Render( Gwen::Skin::Base* skin );
void Layout( Skin::Base* skin );
void DoHorizontalLayout();
void DoVerticalLayout();
bool IsVerticalLayout() { return m_bVertical; }
bool IsHorizontalLayout() { return !m_bVertical; }
void SetVertical() { m_bVertical = true; Invalidate(); }
void SetHorizontal() { m_bVertical = false; Invalidate(); }
void SetSizeToChildren( bool bShould ) { m_bSizeToChildren = bShould; }
void SetControlSpacing( int spacing ) { m_iControlSpacing = spacing; }
void SetLineSpacing( int spacing ) { m_iLineSpacing = spacing; }
void SetWrapping( bool wrap ) { m_bWrapping = wrap; }
Gwen::Point GetBiggestChildSize();
protected:
bool m_bVertical;
bool m_bSizeToChildren;
int m_iControlSpacing;
int m_iLineSpacing;
bool m_bWrapping;
};
m_bVertical = true;
Invalidate();
}
}
void SetHorizontal()
{
m_bVertical = false;
Invalidate();
}
void SetSizeToChildren(bool bShould) { m_bSizeToChildren = bShould; }
void SetControlSpacing(int spacing) { m_iControlSpacing = spacing; }
void SetLineSpacing(int spacing) { m_iLineSpacing = spacing; }
void SetWrapping(bool wrap) { m_bWrapping = wrap; }
Gwen::Point GetBiggestChildSize();
protected:
bool m_bVertical;
bool m_bSizeToChildren;
int m_iControlSpacing;
int m_iLineSpacing;
bool m_bWrapping;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Controls/ScrollControl.h"
#include "Gwen/Controls/ProgressBar.h"
#include "Gwen/Utility.h"
@@ -12,15 +11,14 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( ProgressBar )
GWEN_CONTROL_CONSTRUCTOR(ProgressBar)
{
SetMouseInputEnabled( true );
SetBounds( Gwen::Rect( 0, 0, 128, 32 ) );
SetTextPadding( Padding( 3, 3, 3, 3 ) );
SetMouseInputEnabled(true);
SetBounds(Gwen::Rect(0, 0, 128, 32));
SetTextPadding(Padding(3, 3, 3, 3));
SetHorizontal();
SetAlignment( Gwen::Pos::Center );
SetAlignment(Gwen::Pos::Center);
m_fProgress = 0.0f;
m_bAutoLabel = true;
@@ -28,22 +26,22 @@ GWEN_CONTROL_CONSTRUCTOR( ProgressBar )
void ProgressBar::SetValue(float val)
{
if ( val < 0 )
if (val < 0)
val = 0;
if ( val > 1 )
if (val > 1)
val = 1;
m_fProgress = val;
if ( m_bAutoLabel )
if (m_bAutoLabel)
{
int displayVal = m_fProgress * 100;
SetText( Utility::ToString( displayVal ) + "%" );
SetText(Utility::ToString(displayVal) + "%");
}
}
void ProgressBar::Render( Skin::Base* skin )
void ProgressBar::Render(Skin::Base* skin)
{
skin->DrawProgressBar( this, m_bHorizontal, m_fProgress);
skin->DrawProgressBar(this, m_bHorizontal, m_fProgress);
}

View File

@@ -12,34 +12,31 @@
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT ProgressBar : public Label
{
public:
namespace Controls
{
class GWEN_EXPORT ProgressBar : public Label
{
public:
GWEN_CONTROL(ProgressBar, Label);
GWEN_CONTROL( ProgressBar, Label );
virtual void Render(Skin::Base* skin);
virtual void Render( Skin::Base* skin );
virtual void SetVertical() { m_bHorizontal = false; }
virtual void SetHorizontal() { m_bHorizontal = true; }
virtual void SetVertical() { m_bHorizontal = false; }
virtual void SetHorizontal(){ m_bHorizontal = true; }
virtual void SetValue(float val);
virtual float GetValue() const { return m_fProgress; }
virtual void SetValue( float val );
virtual float GetValue() const { return m_fProgress; }
virtual void SetAutoLabel(bool b) { m_bAutoLabel = b; }
virtual void SetAutoLabel( bool b ){ m_bAutoLabel = b; }
protected:
float m_fProgress;
protected:
float m_fProgress;
bool m_bHorizontal;
bool m_bAutoLabel;
};
}
}
bool m_bHorizontal;
bool m_bAutoLabel;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
#include "Gwen/Controls/Properties.h"
@@ -13,28 +12,28 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( Properties )
GWEN_CONTROL_CONSTRUCTOR(Properties)
{
m_SplitterBar = new SplitterBar( this );
m_SplitterBar->SetPos( 80, 0 );
m_SplitterBar->SetCursor( Gwen::CursorType::SizeWE );
m_SplitterBar->onDragged.Add( this, &Properties::OnSplitterMoved );
m_SplitterBar->SetShouldDrawBackground( false );
m_SplitterBar = new SplitterBar(this);
m_SplitterBar->SetPos(80, 0);
m_SplitterBar->SetCursor(Gwen::CursorType::SizeWE);
m_SplitterBar->onDragged.Add(this, &Properties::OnSplitterMoved);
m_SplitterBar->SetShouldDrawBackground(false);
}
void Properties::PostLayout( Gwen::Skin::Base* /*skin*/ )
void Properties::PostLayout(Gwen::Skin::Base* /*skin*/)
{
m_SplitterBar->SetHeight( 0 );
m_SplitterBar->SetHeight(0);
if ( SizeToChildren( false, true ) )
if (SizeToChildren(false, true))
{
InvalidateParent();
}
m_SplitterBar->SetSize( 3, Height() );
m_SplitterBar->SetSize(3, Height());
}
void Properties::OnSplitterMoved( Controls::Base * /*control*/ )
void Properties::OnSplitterMoved(Controls::Base* /*control*/)
{
InvalidateChildren();
}
@@ -44,82 +43,81 @@ int Properties::GetSplitWidth()
return m_SplitterBar->X();
}
PropertyRow* Properties::Add( const UnicodeString& text, const UnicodeString& value )
PropertyRow* Properties::Add(const UnicodeString& text, const UnicodeString& value)
{
Property::Base* pProp = new Property::Text( this );
pProp->SetPropertyValue( value );
Property::Base* pProp = new Property::Text(this);
pProp->SetPropertyValue(value);
return Add( text, pProp );
return Add(text, pProp);
}
PropertyRow* Properties::Add( const String& text, const String& value )
PropertyRow* Properties::Add(const String& text, const String& value)
{
return Add( Gwen::Utility::StringToUnicode( text ), Gwen::Utility::StringToUnicode( value ) );
return Add(Gwen::Utility::StringToUnicode(text), Gwen::Utility::StringToUnicode(value));
}
PropertyRow* Properties::Add( const UnicodeString& text, Property::Base* pProp )
PropertyRow* Properties::Add(const UnicodeString& text, Property::Base* pProp)
{
PropertyRow* row = new PropertyRow( this );
row->Dock( Pos::Top );
row->GetLabel()->SetText( text );
row->SetProperty( pProp );
PropertyRow* row = new PropertyRow(this);
row->Dock(Pos::Top);
row->GetLabel()->SetText(text);
row->SetProperty(pProp);
m_SplitterBar->BringToFront();
return row;
}
PropertyRow* Properties::Add( const String& text, Property::Base* pProp )
PropertyRow* Properties::Add(const String& text, Property::Base* pProp)
{
return Add( Gwen::Utility::StringToUnicode( text ), pProp );
return Add(Gwen::Utility::StringToUnicode(text), pProp);
}
void Properties::Clear()
{
Base::List ChildListCopy = Children;
for ( Base::List::iterator it = ChildListCopy.begin(); it != ChildListCopy.end(); ++it )
for (Base::List::iterator it = ChildListCopy.begin(); it != ChildListCopy.end(); ++it)
{
PropertyRow* row = (*it)->DynamicCastPropertyRow();
if ( !row ) continue;
if (!row) continue;
row->DelayedDelete();
}
}
GWEN_CONTROL_CONSTRUCTOR( PropertyRow )
GWEN_CONTROL_CONSTRUCTOR(PropertyRow)
{
m_Property = NULL;
m_Label = new Label( this );
m_Label->SetAlignment( Pos::CenterV | Pos::Left );
m_Label->Dock( Pos::Left );
m_Label->SetMargin( Margin( 2, 0, 0, 0 ) );
m_Label = new Label(this);
m_Label->SetAlignment(Pos::CenterV | Pos::Left);
m_Label->Dock(Pos::Left);
m_Label->SetMargin(Margin(2, 0, 0, 0));
SetHeight( 16 );
}
void PropertyRow::Render( Gwen::Skin::Base* skin )
{
skin->DrawPropertyRow( this, m_Label->Right(), m_Property->IsEditing() );
SetHeight(16);
}
void PropertyRow::Layout( Gwen::Skin::Base* /*skin*/ )
void PropertyRow::Render(Gwen::Skin::Base* skin)
{
skin->DrawPropertyRow(this, m_Label->Right(), m_Property->IsEditing());
}
void PropertyRow::Layout(Gwen::Skin::Base* /*skin*/)
{
Properties* pParent = GetParent()->DynamicCastProperties();
if ( !pParent ) return;
if (!pParent) return;
m_Label->SetWidth( pParent->GetSplitWidth() );
m_Label->SetWidth(pParent->GetSplitWidth());
}
void PropertyRow::SetProperty( Property::Base* prop )
void PropertyRow::SetProperty(Property::Base* prop)
{
m_Property = prop;
m_Property->SetParent( this );
m_Property->Dock( Pos::Fill );
m_Property->onChange.Add( this, &ThisClass::OnPropertyValueChanged );
m_Property->SetParent(this);
m_Property->Dock(Pos::Fill);
m_Property->onChange.Add(this, &ThisClass::OnPropertyValueChanged);
}
void PropertyRow::OnPropertyValueChanged( Gwen::Controls::Base* /*control*/ )
void PropertyRow::OnPropertyValueChanged(Gwen::Controls::Base* /*control*/)
{
onChange.Call( this );
onChange.Call(this);
}

View File

@@ -16,62 +16,54 @@
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
namespace Controls
{
class PropertyRow;
class PropertyRow;
class GWEN_EXPORT Properties : public Base
{
public:
GWEN_CONTROL(Properties, Base);
class GWEN_EXPORT Properties : public Base
{
public:
virtual void PostLayout(Gwen::Skin::Base* skin);
GWEN_CONTROL( Properties, Base );
PropertyRow* Add(const UnicodeString& text, const UnicodeString& value = L"");
PropertyRow* Add(const String& text, const String& value = "");
PropertyRow* Add(const UnicodeString& text, Property::Base* pProp);
PropertyRow* Add(const String& text, Property::Base* pProp);
virtual void PostLayout( Gwen::Skin::Base* skin );
virtual int GetSplitWidth();
PropertyRow* Add( const UnicodeString& text, const UnicodeString& value = L"" );
PropertyRow* Add( const String& text, const String& value = "" );
PropertyRow* Add( const UnicodeString& text, Property::Base* pProp );
PropertyRow* Add( const String& text, Property::Base* pProp );
virtual void Clear();
virtual int GetSplitWidth();
protected:
virtual void OnSplitterMoved(Controls::Base* control);
virtual void Clear();
Controls::SplitterBar* m_SplitterBar;
};
protected:
class GWEN_EXPORT PropertyRow : public Base
{
public:
GWEN_CONTROL(PropertyRow, Base);
virtual void OnSplitterMoved( Controls::Base * control );
virtual Label* GetLabel() { return m_Label; }
virtual void SetProperty(Property::Base* prop);
virtual Property::Base* GetProperty() { return m_Property; }
Controls::SplitterBar* m_SplitterBar;
virtual void Layout(Gwen::Skin::Base* skin);
virtual void Render(Gwen::Skin::Base* skin);
};
Event::Caller onChange;
class GWEN_EXPORT PropertyRow : public Base
{
public:
protected:
void OnPropertyValueChanged(Gwen::Controls::Base* control);
GWEN_CONTROL( PropertyRow, Base );
virtual Label* GetLabel(){ return m_Label; }
virtual void SetProperty( Property::Base* prop );
virtual Property::Base* GetProperty(){ return m_Property; }
virtual void Layout( Gwen::Skin::Base* skin );
virtual void Render( Gwen::Skin::Base* skin );
Event::Caller onChange;
protected:
void OnPropertyValueChanged( Gwen::Controls::Base* control );
Label* m_Label;
Property::Base* m_Property;
};
}
}
Label* m_Label;
Property::Base* m_Property;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -13,48 +13,46 @@
#include "Gwen/Skin.h"
#include "Gwen/Utility.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
namespace Property
{
class GWEN_EXPORT Base : public Gwen::Controls::Base
{
public:
GWEN_CONTROL_INLINE(Base, Gwen::Controls::Base) {}
virtual String GetPropertyValueAnsi()
{
namespace Property
{
class GWEN_EXPORT Base : public Gwen::Controls::Base
{
public:
GWEN_CONTROL_INLINE( Base, Gwen::Controls::Base ){}
virtual String GetPropertyValueAnsi()
{
return Gwen::Utility::UnicodeToString( GetPropertyValue() );
}
virtual void SetPropertyValue( const String& v, bool bFireChangeEvents = false )
{
SetPropertyValue( Gwen::Utility::StringToUnicode( v ), bFireChangeEvents );
}
virtual UnicodeString GetPropertyValue() = 0;
virtual void SetPropertyValue( const UnicodeString& v, bool bFireChangeEvents = false ) = 0;
virtual bool IsEditing() = 0;
virtual void DoChanged()
{
onChange.Call( this );
}
virtual void OnPropertyValueChanged( Gwen::Controls::Base* /*control*/ )
{
DoChanged();
}
Event::Caller onChange;
};
}
return Gwen::Utility::UnicodeToString(GetPropertyValue());
}
}
virtual void SetPropertyValue(const String& v, bool bFireChangeEvents = false)
{
SetPropertyValue(Gwen::Utility::StringToUnicode(v), bFireChangeEvents);
}
virtual UnicodeString GetPropertyValue() = 0;
virtual void SetPropertyValue(const UnicodeString& v, bool bFireChangeEvents = false) = 0;
virtual bool IsEditing() = 0;
virtual void DoChanged()
{
onChange.Call(this);
}
virtual void OnPropertyValueChanged(Gwen::Controls::Base* /*control*/)
{
DoChanged();
}
Event::Caller onChange;
};
} // namespace Property
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -6,75 +6,74 @@
#include "Gwen/Controls/WindowControl.h"
#include "Gwen/Controls/HSVColorPicker.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
namespace Property
{
class ColorSelector : public Property::Text
{
public:
GWEN_CONTROL_INLINE(ColorSelector, Property::Text)
{
namespace Property
{
class ColorSelector : public Property::Text
{
public:
GWEN_CONTROL_INLINE( ColorSelector, Property::Text )
{
m_Button = new Button( this );
m_Button->Dock( Pos::Right );
m_Button->SetWidth( 20 );
m_Button->onPress.Add( this, &ThisClass::OnButtonPress );
}
void OnButtonPress( Controls::Base* control )
{
Gwen::Controls::WindowControl* wind = new Gwen::Controls::WindowControl( GetCanvas() );
wind->SetTitle( L"Color Selection" );
wind->SetSize( 256, 180 );
wind->SetPos( GetCanvas()->Width() * 0.5 - 128, GetCanvas()->Height()* 0.5 - 128 );
wind->SetDeleteOnClose( true );
wind->DisableResizing();
wind->MakeModal( true );
Gwen::Controls::HSVColorPicker* picker = new Gwen::Controls::HSVColorPicker( wind );
picker->SetName( "picker" );
float defaultColor[3];
Gwen::Utility::Strings::To::Floats( Gwen::Utility::UnicodeToString( m_TextBox->GetText() ), defaultColor, 3);
picker->SetColor( Gwen::Color( defaultColor[0], defaultColor[1], defaultColor[2], 255 ), false, true );
picker->onColorChanged.Add( this, &ThisClass::ColorChanged );
}
void ColorChanged( Controls::Base* control )
{
Gwen::Controls::HSVColorPicker* picker = control->DynamicCastHSVColorPicker();
Gwen::String colorStr;
colorStr += Gwen::Utility::ToString( ( int )picker->GetColor().r ) + " ";
colorStr += Gwen::Utility::ToString( ( int )picker->GetColor().g ) + " ";
colorStr += Gwen::Utility::ToString( ( int )picker->GetColor().b );
m_TextBox->SetText( colorStr );
DoChanged();
}
virtual UnicodeString GetPropertyValue()
{
return m_TextBox->GetText();
}
virtual void SetPropertyValue( const UnicodeString& v, bool bFireChangeEvents )
{
m_TextBox->SetText( v, bFireChangeEvents );
}
virtual bool IsEditing()
{
return m_TextBox == Gwen::KeyboardFocus;
}
Button* m_Button;
};
}
m_Button = new Button(this);
m_Button->Dock(Pos::Right);
m_Button->SetWidth(20);
m_Button->onPress.Add(this, &ThisClass::OnButtonPress);
}
}
void OnButtonPress(Controls::Base* control)
{
Gwen::Controls::WindowControl* wind = new Gwen::Controls::WindowControl(GetCanvas());
wind->SetTitle(L"Color Selection");
wind->SetSize(256, 180);
wind->SetPos(GetCanvas()->Width() * 0.5 - 128, GetCanvas()->Height() * 0.5 - 128);
wind->SetDeleteOnClose(true);
wind->DisableResizing();
wind->MakeModal(true);
Gwen::Controls::HSVColorPicker* picker = new Gwen::Controls::HSVColorPicker(wind);
picker->SetName("picker");
float defaultColor[3];
Gwen::Utility::Strings::To::Floats(Gwen::Utility::UnicodeToString(m_TextBox->GetText()), defaultColor, 3);
picker->SetColor(Gwen::Color(defaultColor[0], defaultColor[1], defaultColor[2], 255), false, true);
picker->onColorChanged.Add(this, &ThisClass::ColorChanged);
}
void ColorChanged(Controls::Base* control)
{
Gwen::Controls::HSVColorPicker* picker = control->DynamicCastHSVColorPicker();
Gwen::String colorStr;
colorStr += Gwen::Utility::ToString((int)picker->GetColor().r) + " ";
colorStr += Gwen::Utility::ToString((int)picker->GetColor().g) + " ";
colorStr += Gwen::Utility::ToString((int)picker->GetColor().b);
m_TextBox->SetText(colorStr);
DoChanged();
}
virtual UnicodeString GetPropertyValue()
{
return m_TextBox->GetText();
}
virtual void SetPropertyValue(const UnicodeString& v, bool bFireChangeEvents)
{
m_TextBox->SetText(v, bFireChangeEvents);
}
virtual bool IsEditing()
{
return m_TextBox == Gwen::KeyboardFocus;
}
Button* m_Button;
};
} // namespace Property
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -11,42 +11,41 @@
#include "Gwen/Controls/Property/BaseProperty.h"
#include "Gwen/Controls/TextBox.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
namespace Property
{
class GWEN_EXPORT Text : public Property::Base
{
public:
GWEN_CONTROL_INLINE(Text, Property::Base)
{
namespace Property
{
class GWEN_EXPORT Text : public Property::Base
{
public:
GWEN_CONTROL_INLINE( Text, Property::Base )
{
m_TextBox = new TextBox( this );
m_TextBox->Dock( Pos::Fill );
m_TextBox->SetShouldDrawBackground( false );
m_TextBox->onTextChanged.Add( this, &BaseClass::OnPropertyValueChanged );
}
virtual UnicodeString GetPropertyValue()
{
return m_TextBox->GetText();
}
virtual void SetPropertyValue( const UnicodeString& v, bool bFireChangeEvents )
{
m_TextBox->SetText( v, bFireChangeEvents );
}
virtual bool IsEditing()
{
return m_TextBox->HasFocus();
}
TextBox* m_TextBox;
};
}
m_TextBox = new TextBox(this);
m_TextBox->Dock(Pos::Fill);
m_TextBox->SetShouldDrawBackground(false);
m_TextBox->onTextChanged.Add(this, &BaseClass::OnPropertyValueChanged);
}
}
virtual UnicodeString GetPropertyValue()
{
return m_TextBox->GetText();
}
virtual void SetPropertyValue(const UnicodeString& v, bool bFireChangeEvents)
{
m_TextBox->SetText(v, bFireChangeEvents);
}
virtual bool IsEditing()
{
return m_TextBox->HasFocus();
}
TextBox* m_TextBox;
};
} // namespace Property
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -15,48 +15,43 @@
#include "Gwen/Controls/TreeControl.h"
#include "Gwen/Controls/Properties.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class PropertyTreeNode : public TreeNode
{
public:
GWEN_CONTROL_INLINE(PropertyTreeNode, TreeNode)
{
class PropertyTreeNode : public TreeNode
{
public:
GWEN_CONTROL_INLINE( PropertyTreeNode, TreeNode )
{
}
virtual void Render( Skin::Base* skin )
{
skin->DrawPropertyTreeNode( this, m_InnerPanel->X(), m_InnerPanel->Y() );
}
};
class PropertyTree : public TreeControl
{
public:
GWEN_CONTROL_INLINE( PropertyTree, TreeControl )
{
}
Properties* Add( const UnicodeString& text )
{
TreeNode* node = new PropertyTreeNode( this );
node->SetText( text );
node->Dock( Pos::Top );
Properties* props = new Properties( node );
props->Dock( Pos::Top );
return props;
}
};
}
}
virtual void Render(Skin::Base* skin)
{
skin->DrawPropertyTreeNode(this, m_InnerPanel->X(), m_InnerPanel->Y());
}
};
class PropertyTree : public TreeControl
{
public:
GWEN_CONTROL_INLINE(PropertyTree, TreeControl)
{
}
Properties* Add(const UnicodeString& text)
{
TreeNode* node = new PropertyTreeNode(this);
node->SetText(text);
node->Dock(Pos::Top);
Properties* props = new Properties(node);
props->Dock(Pos::Top);
return props;
}
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,21 +4,19 @@
See license in Gwen.h
*/
#include "Gwen/Controls/RadioButton.h"
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( RadioButton )
GWEN_CONTROL_CONSTRUCTOR(RadioButton)
{
SetSize( 11, 11 );
SetMouseInputEnabled( true );
SetTabable( false );
SetSize(11, 11);
SetMouseInputEnabled(true);
SetTabable(false);
}
void RadioButton::Render( Skin::Base* skin )
void RadioButton::Render(Skin::Base* skin)
{
skin->DrawRadioButton( this, IsChecked(), IsDepressed() );
skin->DrawRadioButton(this, IsChecked(), IsDepressed());
}

View File

@@ -16,63 +16,64 @@
#include "Gwen/Controls/CheckBox.h"
#include "Gwen/Controls/LabelClickable.h"
namespace Gwen
namespace Gwen
{
namespace Controls
namespace Controls
{
class GWEN_EXPORT RadioButton : public CheckBox
{
GWEN_CONTROL(RadioButton, CheckBox);
virtual void Render(Skin::Base* skin);
private:
// From CheckBox
virtual bool AllowUncheck() { return false; }
};
class GWEN_EXPORT LabeledRadioButton : public Base
{
public:
GWEN_CONTROL_INLINE(LabeledRadioButton, Base)
{
class GWEN_EXPORT RadioButton : public CheckBox
{
GWEN_CONTROL( RadioButton, CheckBox );
virtual void Render( Skin::Base* skin );
SetSize(200, 19);
private:
m_RadioButton = new RadioButton(this);
m_RadioButton->Dock(Pos::Left);
m_RadioButton->SetMargin(Margin(0, 4, 2, 4));
m_RadioButton->SetTabable(false);
m_RadioButton->SetKeyboardInputEnabled(false);
// From CheckBox
virtual bool AllowUncheck(){ return false; }
};
class GWEN_EXPORT LabeledRadioButton : public Base
{
public:
GWEN_CONTROL_INLINE( LabeledRadioButton, Base )
{
SetSize( 200, 19 );
m_RadioButton = new RadioButton( this );
m_RadioButton->Dock( Pos::Left );
m_RadioButton->SetMargin( Margin( 0, 4, 2, 4 ) );
m_RadioButton->SetTabable( false );
m_RadioButton->SetKeyboardInputEnabled( false );
m_Label = new LabelClickable( this );
m_Label->SetAlignment( Pos::CenterV | Pos::Left );
m_Label->SetText( "Radio Button" );
m_Label->Dock( Pos::Fill );
m_Label->onPress.Add( m_RadioButton, &CheckBox::ReceiveEventPress );
m_Label->SetTabable( false );
m_Label->SetKeyboardInputEnabled( false );
}
void RenderFocus( Gwen::Skin::Base* skin )
{
if ( Gwen::KeyboardFocus != this ) return;
if ( !IsTabable() ) return;
skin->DrawKeyboardHighlight( this, GetRenderBounds(), 0 );
}
virtual RadioButton* GetRadioButton() { return m_RadioButton; }
virtual LabelClickable* GetLabel(){ return m_Label; }
virtual bool OnKeySpace(bool bDown) { if ( bDown ) m_RadioButton->SetChecked( !m_RadioButton->IsChecked() ); return true; }
virtual void Select(){ m_RadioButton->SetChecked( true ); }
private:
RadioButton* m_RadioButton;
LabelClickable* m_Label;
};
m_Label = new LabelClickable(this);
m_Label->SetAlignment(Pos::CenterV | Pos::Left);
m_Label->SetText("Radio Button");
m_Label->Dock(Pos::Fill);
m_Label->onPress.Add(m_RadioButton, &CheckBox::ReceiveEventPress);
m_Label->SetTabable(false);
m_Label->SetKeyboardInputEnabled(false);
}
}
void RenderFocus(Gwen::Skin::Base* skin)
{
if (Gwen::KeyboardFocus != this) return;
if (!IsTabable()) return;
skin->DrawKeyboardHighlight(this, GetRenderBounds(), 0);
}
virtual RadioButton* GetRadioButton() { return m_RadioButton; }
virtual LabelClickable* GetLabel() { return m_Label; }
virtual bool OnKeySpace(bool bDown)
{
if (bDown) m_RadioButton->SetChecked(!m_RadioButton->IsChecked());
return true;
}
virtual void Select() { m_RadioButton->SetChecked(true); }
private:
RadioButton* m_RadioButton;
LabelClickable* m_Label;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Controls/RadioButtonController.h"
#include "Gwen/Controls/RadioButton.h"
#include "Gwen/Utility.h"
@@ -12,15 +11,14 @@
using namespace Gwen;
using namespace Gwen::Controls;
GWEN_CONTROL_CONSTRUCTOR( RadioButtonController )
GWEN_CONTROL_CONSTRUCTOR(RadioButtonController)
{
m_Selected = NULL;
SetTabable( false );
SetKeyboardInputEnabled( false );
SetTabable(false);
SetKeyboardInputEnabled(false);
}
void RadioButtonController::OnRadioClicked( Gwen::Controls::Base* pFromPanel )
void RadioButtonController::OnRadioClicked(Gwen::Controls::Base* pFromPanel)
{
RadioButton* pCheckedRadioButton = pFromPanel->DynamicCastRadioButton();
@@ -29,16 +27,16 @@ void RadioButtonController::OnRadioClicked( Gwen::Controls::Base* pFromPanel )
{
Base* pChild = *iter;
LabeledRadioButton* pLRB = pChild->DynamicCastLabeledRadioButton();
if ( pLRB )
if (pLRB)
{
RadioButton* pChildRadioButton = pLRB->GetRadioButton();
if ( pChildRadioButton == pCheckedRadioButton )
if (pChildRadioButton == pCheckedRadioButton)
{
m_Selected = pLRB;
}
else
{
pLRB->GetRadioButton()->SetChecked( false );
pLRB->GetRadioButton()->SetChecked(false);
}
}
}
@@ -48,25 +46,25 @@ void RadioButtonController::OnRadioClicked( Gwen::Controls::Base* pFromPanel )
void RadioButtonController::OnChange()
{
onSelectionChange.Call( this );
onSelectionChange.Call(this);
}
LabeledRadioButton* RadioButtonController::AddOption( const Gwen::String& strText, const Gwen::String& strOptionName )
LabeledRadioButton* RadioButtonController::AddOption(const Gwen::String& strText, const Gwen::String& strOptionName)
{
return AddOption( Gwen::Utility::StringToUnicode( strText ), strOptionName );
return AddOption(Gwen::Utility::StringToUnicode(strText), strOptionName);
}
LabeledRadioButton* RadioButtonController::AddOption( const Gwen::UnicodeString& strText, const Gwen::String& strOptionName )
LabeledRadioButton* RadioButtonController::AddOption(const Gwen::UnicodeString& strText, const Gwen::String& strOptionName)
{
LabeledRadioButton* lrb = new LabeledRadioButton( this );
LabeledRadioButton* lrb = new LabeledRadioButton(this);
lrb->SetName( strOptionName );
lrb->GetLabel()->SetText( strText );
lrb->GetRadioButton()->onChecked.Add( this, &RadioButtonController::OnRadioClicked );
lrb->Dock( Pos::Top );
lrb->SetMargin( Margin( 0, 1, 0, 1 ) );
lrb->SetKeyboardInputEnabled( false );
lrb->SetTabable( false );
lrb->SetName(strOptionName);
lrb->GetLabel()->SetText(strText);
lrb->GetRadioButton()->onChecked.Add(this, &RadioButtonController::OnRadioClicked);
lrb->Dock(Pos::Top);
lrb->SetMargin(Margin(0, 1, 0, 1));
lrb->SetKeyboardInputEnabled(false);
lrb->SetTabable(false);
Invalidate();

View File

@@ -12,37 +12,33 @@
#include "Gwen/Controls/Label.h"
#include "Gwen/Controls/RadioButton.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
namespace Controls
{
class GWEN_EXPORT RadioButtonController : public Base
{
public:
GWEN_CONTROL(RadioButtonController, Base);
class GWEN_EXPORT RadioButtonController : public Base
{
public:
virtual void Render(Skin::Base* /*skin*/){};
virtual void OnRadioClicked(Base* pFromPanel);
GWEN_CONTROL( RadioButtonController, Base );
virtual void OnChange();
virtual void Render( Skin::Base* /*skin*/ ){};
virtual void OnRadioClicked( Base* pFromPanel );
virtual LabeledRadioButton* AddOption(const Gwen::String& strText, const Gwen::String& strOptionName = "");
virtual LabeledRadioButton* AddOption(const Gwen::UnicodeString& strText, const Gwen::String& strOptionName = "");
virtual void OnChange();
virtual LabeledRadioButton* GetSelected() { return m_Selected; }
virtual LabeledRadioButton* AddOption( const Gwen::String& strText, const Gwen::String& strOptionName = "" );
virtual LabeledRadioButton* AddOption( const Gwen::UnicodeString& strText, const Gwen::String& strOptionName = "" );
virtual String GetSelectedName() { return m_Selected->GetName(); }
virtual UnicodeString GetSelectedLabel() { return m_Selected->GetLabel()->GetText(); }
virtual LabeledRadioButton* GetSelected(){ return m_Selected; }
Event::Caller onSelectionChange;
virtual String GetSelectedName(){ return m_Selected->GetName(); }
virtual UnicodeString GetSelectedLabel(){ return m_Selected->GetLabel()->GetText(); }
Event::Caller onSelectionChange;
private:
LabeledRadioButton* m_Selected;
};
}
}
private:
LabeledRadioButton* m_Selected;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Controls/ImagePanel.h"
#include "Gwen/Controls/Label.h"
#include "Gwen/Controls/Resizer.h"
@@ -14,97 +13,97 @@ using namespace Gwen;
using namespace Gwen::Controls;
using namespace Gwen::ControlsInternal;
GWEN_CONTROL_CONSTRUCTOR( ResizableControl )
GWEN_CONTROL_CONSTRUCTOR(ResizableControl)
{
m_bResizable = true;
m_MinimumSize = Gwen::Point( 5, 5 );
m_MinimumSize = Gwen::Point(5, 5);
m_bClampMovement = false;
Resizer* resizerBottom = new Resizer (this );
resizerBottom->Dock( Pos::Bottom );
resizerBottom->SetResizeDir( Pos::Bottom );
resizerBottom->SetTarget( this );
resizerBottom->onResize.Add( this, &ResizableControl::OnResizedInternal );
Resizer* resizerBottom = new Resizer(this);
resizerBottom->Dock(Pos::Bottom);
resizerBottom->SetResizeDir(Pos::Bottom);
resizerBottom->SetTarget(this);
resizerBottom->onResize.Add(this, &ResizableControl::OnResizedInternal);
Resizer* resizerBottomLeft = new Resizer( resizerBottom );
resizerBottomLeft->Dock( Pos::Left );
resizerBottomLeft->SetResizeDir( Pos::Bottom | Pos::Left );
resizerBottomLeft->SetTarget(this );
resizerBottomLeft->onResize.Add( this, &ResizableControl::OnResizedInternal );
Resizer* resizerBottomLeft = new Resizer(resizerBottom);
resizerBottomLeft->Dock(Pos::Left);
resizerBottomLeft->SetResizeDir(Pos::Bottom | Pos::Left);
resizerBottomLeft->SetTarget(this);
resizerBottomLeft->onResize.Add(this, &ResizableControl::OnResizedInternal);
Resizer* resizerBottomRight = new Resizer( resizerBottom );
resizerBottomRight->Dock( Pos::Right);
resizerBottomRight->SetResizeDir( Pos::Bottom | Pos::Right );
resizerBottomRight->SetTarget( this );
resizerBottomRight->onResize.Add( this, &ResizableControl::OnResizedInternal );
Resizer* resizerBottomRight = new Resizer(resizerBottom);
resizerBottomRight->Dock(Pos::Right);
resizerBottomRight->SetResizeDir(Pos::Bottom | Pos::Right);
resizerBottomRight->SetTarget(this);
resizerBottomRight->onResize.Add(this, &ResizableControl::OnResizedInternal);
Resizer* resizerTop = new Resizer( this );
resizerTop->Dock( Pos::Top );
resizerTop->SetResizeDir( Pos::Top );
resizerTop->SetTarget( this );
resizerTop->onResize.Add( this, &ResizableControl::OnResizedInternal );
Resizer* resizerTop = new Resizer(this);
resizerTop->Dock(Pos::Top);
resizerTop->SetResizeDir(Pos::Top);
resizerTop->SetTarget(this);
resizerTop->onResize.Add(this, &ResizableControl::OnResizedInternal);
Resizer* resizerTopLeft = new Resizer( resizerTop );
resizerTopLeft->Dock( Pos::Left );
resizerTopLeft->SetResizeDir( Pos::Top | Pos::Left );
resizerTopLeft->SetTarget( this );
resizerTopLeft->onResize.Add( this, &ResizableControl::OnResizedInternal );
Resizer* resizerTopLeft = new Resizer(resizerTop);
resizerTopLeft->Dock(Pos::Left);
resizerTopLeft->SetResizeDir(Pos::Top | Pos::Left);
resizerTopLeft->SetTarget(this);
resizerTopLeft->onResize.Add(this, &ResizableControl::OnResizedInternal);
Resizer* resizerTopRight = new Resizer( resizerTop );
resizerTopRight->Dock( Pos::Right );
resizerTopRight->SetResizeDir( Pos::Top| Pos::Right );
resizerTopRight->SetTarget( this );
resizerTopRight->onResize.Add( this, &ResizableControl::OnResizedInternal );
Resizer* resizerTopRight = new Resizer(resizerTop);
resizerTopRight->Dock(Pos::Right);
resizerTopRight->SetResizeDir(Pos::Top | Pos::Right);
resizerTopRight->SetTarget(this);
resizerTopRight->onResize.Add(this, &ResizableControl::OnResizedInternal);
Resizer* resizerLeft = new Resizer( this );
resizerLeft->Dock( Pos::Left );
resizerLeft->SetResizeDir( Pos::Left );
resizerLeft->SetTarget( this );
resizerLeft->onResize.Add( this, &ResizableControl::OnResizedInternal );
Resizer* resizerLeft = new Resizer(this);
resizerLeft->Dock(Pos::Left);
resizerLeft->SetResizeDir(Pos::Left);
resizerLeft->SetTarget(this);
resizerLeft->onResize.Add(this, &ResizableControl::OnResizedInternal);
Resizer* resizerRight = new Resizer( this );
resizerRight->Dock( Pos::Right );
resizerRight->SetResizeDir( Pos::Right );
resizerRight->SetTarget( this );
resizerRight->onResize.Add( this, &ResizableControl::OnResizedInternal );
Resizer* resizerRight = new Resizer(this);
resizerRight->Dock(Pos::Right);
resizerRight->SetResizeDir(Pos::Right);
resizerRight->SetTarget(this);
resizerRight->onResize.Add(this, &ResizableControl::OnResizedInternal);
}
void ResizableControl::DisableResizing()
{
for ( Base::List::iterator it = Children.begin(); it != Children.end(); ++it )
for (Base::List::iterator it = Children.begin(); it != Children.end(); ++it)
{
Resizer* resizer = (*it)->DynamicCastResizer();
if ( !resizer ) continue;
resizer->SetMouseInputEnabled( false );
resizer->SetHidden( true );
SetPadding( Padding( resizer->Width(), resizer->Width(), resizer->Width(), resizer->Width() ) );
if (!resizer) continue;
resizer->SetMouseInputEnabled(false);
resizer->SetHidden(true);
SetPadding(Padding(resizer->Width(), resizer->Width(), resizer->Width(), resizer->Width()));
}
}
bool ResizableControl::SetBounds( int x, int y, int w, int h )
bool ResizableControl::SetBounds(int x, int y, int w, int h)
{
Gwen::Point minSize = GetMinimumSize();
// Clamp Minimum Size
if ( w < minSize.x ) w = minSize.x;
if ( h < minSize.y ) h = minSize.y;
if (w < minSize.x) w = minSize.x;
if (h < minSize.y) h = minSize.y;
// Clamp to parent's window
Base* pParent = GetParent();
if ( pParent && m_bClampMovement )
if (pParent && m_bClampMovement)
{
if ( x + w > pParent->Width() ) x = pParent->Width() - w;
if ( x < 0 ) x = 0;
if ( y + h > pParent->Height() ) y = pParent->Height() - h;
if ( y < 0 ) y = 0;
if (x + w > pParent->Width()) x = pParent->Width() - w;
if (x < 0) x = 0;
if (y + h > pParent->Height()) y = pParent->Height() - h;
if (y < 0) y = 0;
}
return BaseClass::SetBounds( x, y, w, h );
return BaseClass::SetBounds(x, y, w, h);
}
void ResizableControl::OnResizedInternal( Controls::Base* /*pControl*/ )
void ResizableControl::OnResizedInternal(Controls::Base* /*pControl*/)
{
onResize.Call( this );
onResize.Call(this);
OnResized();
}

View File

@@ -16,40 +16,36 @@
#include "Gwen/Gwen.h"
#include "Gwen/Skin.h"
namespace Gwen
namespace Gwen
{
namespace Controls
{
class GWEN_EXPORT ResizableControl : public Base
{
public:
namespace Controls
{
class GWEN_EXPORT ResizableControl : public Base
{
public:
GWEN_CONTROL(ResizableControl, Base);
GWEN_CONTROL( ResizableControl, Base );
virtual void SetClampMovement(bool shouldClamp) { m_bClampMovement = shouldClamp; }
virtual bool GetClampMovement() { return m_bClampMovement; }
virtual void SetClampMovement( bool shouldClamp ) { m_bClampMovement = shouldClamp; }
virtual bool GetClampMovement() { return m_bClampMovement; }
virtual void SetMinimumSize(const Gwen::Point& minSize) { m_MinimumSize = minSize; }
virtual Gwen::Point GetMinimumSize() { return m_MinimumSize; }
virtual void SetMinimumSize( const Gwen::Point& minSize ) { m_MinimumSize = minSize; }
virtual Gwen::Point GetMinimumSize() { return m_MinimumSize; }
virtual void DisableResizing();
virtual void DisableResizing();
virtual bool SetBounds(int x, int y, int w, int h);
virtual bool SetBounds( int x, int y, int w, int h );
virtual void OnResized(){};
virtual void OnResized(){};
Event::Caller onResize;
Event::Caller onResize;
protected:
void OnResizedInternal(Controls::Base* pControl);
protected:
void OnResizedInternal( Controls::Base* pControl );
Gwen::Point m_MinimumSize;
bool m_bClampMovement;
bool m_bResizable;
};
}
}
Gwen::Point m_MinimumSize;
bool m_bClampMovement;
bool m_bResizable;
};
} // namespace Controls
} // namespace Gwen
#endif

View File

@@ -4,37 +4,35 @@
See license in Gwen.h
*/
#include "Gwen/Controls/Resizer.h"
using namespace Gwen;
using namespace Gwen::ControlsInternal;
GWEN_CONTROL_CONSTRUCTOR( Resizer )
GWEN_CONTROL_CONSTRUCTOR(Resizer)
{
m_iResizeDir = Pos::Left;
SetMouseInputEnabled( true );
SetSize( 6, 6 );
SetMouseInputEnabled(true);
SetSize(6, 6);
}
void Resizer::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
void Resizer::OnMouseMoved(int x, int y, int /*deltaX*/, int /*deltaY*/)
{
if ( !m_pTarget ) return;
if ( !m_bDepressed ) return;
if (!m_pTarget) return;
if (!m_bDepressed) return;
// Gwen::Rect oldBounds = m_pTarget->GetBounds();
// Gwen::Rect oldBounds = m_pTarget->GetBounds();
Gwen::Rect pBounds = m_pTarget->GetBounds();
Gwen::Point pntMin = m_pTarget->GetMinimumSize();
Gwen::Point pCursorPos = m_pTarget->CanvasPosToLocal( Gwen::Point( x, y ) );
Gwen::Point pCursorPos = m_pTarget->CanvasPosToLocal(Gwen::Point(x, y));
Gwen::Point pDelta = m_pTarget->LocalPosToCanvas( m_HoldPos );
pDelta.x -= x;
pDelta.y -= y;
Gwen::Point pDelta = m_pTarget->LocalPosToCanvas(m_HoldPos);
pDelta.x -= x;
pDelta.y -= y;
if ( m_iResizeDir & Pos::Left )
if (m_iResizeDir & Pos::Left)
{
pBounds.x -= pDelta.x;
pBounds.w += pDelta.x;
@@ -42,16 +40,15 @@ void Resizer::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
// Conform to minimum size here so we don't
// go all weird when we snap it in the base conrt
if ( pBounds.w < pntMin.x )
if (pBounds.w < pntMin.x)
{
int diff = pntMin.x - pBounds.w;
pBounds.w += diff;
pBounds.x -= diff;
}
}
if ( m_iResizeDir & Pos::Top )
if (m_iResizeDir & Pos::Top)
{
pBounds.y -= pDelta.y;
pBounds.h += pDelta.y;
@@ -59,16 +56,15 @@ void Resizer::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
// Conform to minimum size here so we don't
// go all weird when we snap it in the base conrt
if ( pBounds.h < pntMin.y )
if (pBounds.h < pntMin.y)
{
int diff = pntMin.y - pBounds.h;
pBounds.h += diff;
pBounds.y -= diff;
}
}
if ( m_iResizeDir & Pos::Right )
if (m_iResizeDir & Pos::Right)
{
// This is complicated.
// Basically we want to use the HoldPos, so it doesn't snap to the edge of the control
@@ -78,43 +74,42 @@ void Resizer::OnMouseMoved( int x, int y, int /*deltaX*/, int /*deltaY*/ )
int woff = pBounds.w - m_HoldPos.x;
int diff = pBounds.w;
pBounds.w = pCursorPos.x + woff;
if ( pBounds.w < pntMin.x ) pBounds.w = pntMin.x;
pBounds.w = pCursorPos.x + woff;
if (pBounds.w < pntMin.x) pBounds.w = pntMin.x;
diff -= pBounds.w;
m_HoldPos.x -= diff;
}
if ( m_iResizeDir & Pos::Bottom )
if (m_iResizeDir & Pos::Bottom)
{
int hoff = pBounds.h - m_HoldPos.y;
int diff = pBounds.h;
pBounds.h = pCursorPos.y + hoff;
if ( pBounds.h < pntMin.y ) pBounds.h = pntMin.y;
pBounds.h = pCursorPos.y + hoff;
if (pBounds.h < pntMin.y) pBounds.h = pntMin.y;
diff -= pBounds.h;
m_HoldPos.y -= diff;
}
m_pTarget->SetBounds( pBounds );
m_pTarget->SetBounds(pBounds);
onResize.Call( this );
onResize.Call(this);
}
void Resizer::SetResizeDir( int dir )
void Resizer::SetResizeDir(int dir)
{
m_iResizeDir = dir;
if ( (dir & Pos::Left && dir & Pos::Top) || (dir & Pos::Right && dir & Pos::Bottom) )
return SetCursor( Gwen::CursorType::SizeNWSE );
if ((dir & Pos::Left && dir & Pos::Top) || (dir & Pos::Right && dir & Pos::Bottom))
return SetCursor(Gwen::CursorType::SizeNWSE);
if ( (dir & Pos::Right && dir & Pos::Top) || (dir & Pos::Left && dir & Pos::Bottom) )
return SetCursor( Gwen::CursorType::SizeNESW );
if ((dir & Pos::Right && dir & Pos::Top) || (dir & Pos::Left && dir & Pos::Bottom))
return SetCursor(Gwen::CursorType::SizeNESW);
if ( dir & Pos::Right || dir & Pos::Left )
return SetCursor( Gwen::CursorType::SizeWE );
if (dir & Pos::Right || dir & Pos::Left)
return SetCursor(Gwen::CursorType::SizeWE);
if ( dir & Pos::Top || dir & Pos::Bottom )
return SetCursor( Gwen::CursorType::SizeNS );
if (dir & Pos::Top || dir & Pos::Bottom)
return SetCursor(Gwen::CursorType::SizeNS);
}

View File

@@ -13,27 +13,23 @@
#include "Gwen/Skin.h"
#include "Gwen/Controls/Dragger.h"
namespace Gwen
namespace Gwen
{
namespace ControlsInternal
{
class GWEN_EXPORT Resizer : public Dragger
{
public:
namespace ControlsInternal
{
class GWEN_EXPORT Resizer : public Dragger
{
public:
GWEN_CONTROL(Resizer, Dragger);
GWEN_CONTROL( Resizer, Dragger );
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
virtual void SetResizeDir(int dir);
virtual void OnMouseMoved( int x, int y, int deltaX, int deltaY );
virtual void SetResizeDir( int dir );
Event::Caller onResize;
Event::Caller onResize;
protected:
int m_iResizeDir;
};
}
}
protected:
int m_iResizeDir;
};
} // namespace ControlsInternal
} // namespace Gwen
#endif

View File

@@ -4,7 +4,6 @@
See license in Gwen.h
*/
#include "Gwen/Gwen.h"
#include "Gwen/Controls/RichLabel.h"
#include "Gwen/Controls/Label.h"
@@ -16,7 +15,7 @@ using namespace Gwen::Controls;
const unsigned char Type_Text = 0;
const unsigned char Type_Newline = 1;
GWEN_CONTROL_CONSTRUCTOR( RichLabel )
GWEN_CONTROL_CONSTRUCTOR(RichLabel)
{
m_bNeedsRebuild = false;
}
@@ -26,19 +25,19 @@ void RichLabel::AddLineBreak()
DividedText t;
t.type = Type_Newline;
m_TextBlocks.push_back( t );
m_TextBlocks.push_back(t);
}
void RichLabel::AddText( const Gwen::TextObject& text, Gwen::Color color, Gwen::Font* font )
void RichLabel::AddText(const Gwen::TextObject& text, Gwen::Color color, Gwen::Font* font)
{
if ( text.m_Data.size() == 0 ) return;
if (text.m_Data.size() == 0) return;
Gwen::Utility::Strings::UnicodeList lst;
Gwen::Utility::Strings::Split( text.GetUnicode(), L"\n", lst, false );
Gwen::Utility::Strings::Split(text.GetUnicode(), L"\n", lst, false);
for (size_t i=0; i<lst.size(); i++ )
for (size_t i = 0; i < lst.size(); i++)
{
if ( i > 0 ) AddLineBreak();
if (i > 0) AddLineBreak();
DividedText t;
t.type = Type_Text;
@@ -46,120 +45,120 @@ void RichLabel::AddText( const Gwen::TextObject& text, Gwen::Color color, Gwen::
t.color = color;
t.font = font;
m_TextBlocks.push_back( t );
m_TextBlocks.push_back(t);
m_bNeedsRebuild = true;
Invalidate();
}
}
bool RichLabel::SizeToChildren( bool w, bool h )
bool RichLabel::SizeToChildren(bool w, bool h)
{
Rebuild();
return BaseClass::SizeToChildren( w, h );
return BaseClass::SizeToChildren(w, h);
}
void RichLabel::SplitLabel( const Gwen::UnicodeString& text, Gwen::Font* pFont, const DividedText& txt, int& x, int& y, int& lineheight )
void RichLabel::SplitLabel(const Gwen::UnicodeString& text, Gwen::Font* pFont, const DividedText& txt, int& x, int& y, int& lineheight)
{
Gwen::Utility::Strings::UnicodeList lst;
Gwen::Utility::Strings::Split( text, L" ", lst, true );
if ( lst.size() == 0 ) return;
Gwen::Utility::Strings::Split(text, L" ", lst, true);
if (lst.size() == 0) return;
int iSpaceLeft = Width() - x;
// Does the whole word fit in?
{
Gwen::Point StringSize = GetSkin()->GetRender()->MeasureText( pFont, text );
if ( iSpaceLeft > StringSize.x )
Gwen::Point StringSize = GetSkin()->GetRender()->MeasureText(pFont, text);
if (iSpaceLeft > StringSize.x)
{
return CreateLabel( text, txt, x, y, lineheight, true );
return CreateLabel(text, txt, x, y, lineheight, true);
}
}
// If the first word is bigger than the line, just give up.
{
Gwen::Point WordSize = GetSkin()->GetRender()->MeasureText( pFont, lst[0] );
if ( WordSize.x >= iSpaceLeft )
Gwen::Point WordSize = GetSkin()->GetRender()->MeasureText(pFont, lst[0]);
if (WordSize.x >= iSpaceLeft)
{
CreateLabel( lst[0], txt, x, y, lineheight, true );
if ( lst[0].size() >= text.size() ) return;
CreateLabel(lst[0], txt, x, y, lineheight, true);
if (lst[0].size() >= text.size()) return;
Gwen::UnicodeString LeftOver = text.substr( lst[0].size() + 1 );
return SplitLabel( LeftOver, pFont, txt, x, y, lineheight );
Gwen::UnicodeString LeftOver = text.substr(lst[0].size() + 1);
return SplitLabel(LeftOver, pFont, txt, x, y, lineheight);
}
}
Gwen::UnicodeString strNewString = L"";
for ( size_t i=0; i<lst.size(); i++ )
for (size_t i = 0; i < lst.size(); i++)
{
Gwen::Point WordSize = GetSkin()->GetRender()->MeasureText( pFont, strNewString + lst[i] );
if ( WordSize.x > iSpaceLeft )
Gwen::Point WordSize = GetSkin()->GetRender()->MeasureText(pFont, strNewString + lst[i]);
if (WordSize.x > iSpaceLeft)
{
CreateLabel( strNewString, txt, x, y, lineheight, true );
CreateLabel(strNewString, txt, x, y, lineheight, true);
x = 0;
y += lineheight;
break;;
break;
;
}
strNewString += lst[i];
}
Gwen::UnicodeString LeftOver = text.substr( strNewString.size() + 1 );
return SplitLabel( LeftOver, pFont, txt, x, y, lineheight );
Gwen::UnicodeString LeftOver = text.substr(strNewString.size() + 1);
return SplitLabel(LeftOver, pFont, txt, x, y, lineheight);
}
void RichLabel::CreateLabel( const Gwen::UnicodeString& text, const DividedText& txt, int& x, int& y, int& lineheight, bool NoSplit )
void RichLabel::CreateLabel(const Gwen::UnicodeString& text, const DividedText& txt, int& x, int& y, int& lineheight, bool NoSplit)
{
//
// Use default font or is one set?
//
Gwen::Font* pFont = GetSkin()->GetDefaultFont();
if ( txt.font ) pFont = txt.font;
if (txt.font) pFont = txt.font;
//
// This string is too long for us, split it up.
//
Gwen::Point p = GetSkin()->GetRender()->MeasureText( pFont, text );
Gwen::Point p = GetSkin()->GetRender()->MeasureText(pFont, text);
if ( lineheight == -1 )
if (lineheight == -1)
{
lineheight = p.y;
}
if ( !NoSplit )
if (!NoSplit)
{
if ( x + p.x > Width() )
if (x + p.x > Width())
{
return SplitLabel( text, pFont, txt, x, y, lineheight );
return SplitLabel(text, pFont, txt, x, y, lineheight);
}
}
//
// Wrap
//
if ( x + p.x >= Width() )
if (x + p.x >= Width())
{
CreateNewline( x, y, lineheight );
CreateNewline(x, y, lineheight);
}
Gwen::Controls::Label* pLabel = new Gwen::Controls::Label( this );
pLabel->SetText( x == 0 ? Gwen::Utility::Strings::TrimLeft<Gwen::UnicodeString>( text, L" " ) : text );
pLabel->SetTextColor( txt.color );
pLabel->SetFont( pFont );
Gwen::Controls::Label* pLabel = new Gwen::Controls::Label(this);
pLabel->SetText(x == 0 ? Gwen::Utility::Strings::TrimLeft<Gwen::UnicodeString>(text, L" ") : text);
pLabel->SetTextColor(txt.color);
pLabel->SetFont(pFont);
pLabel->SizeToContents();
pLabel->SetPos( x, y );
pLabel->SetPos(x, y);
//lineheight = (lineheight + pLabel->Height()) / 2;
//lineheight = (lineheight + pLabel->Height()) / 2;
x += pLabel->Width();
if ( x >= Width() )
if (x >= Width())
{
CreateNewline( x, y, lineheight );
CreateNewline(x, y, lineheight);
}
}
void RichLabel::CreateNewline( int& x, int& y, int& lineheight )
void RichLabel::CreateNewline(int& x, int& y, int& lineheight)
{
x = 0;
y += lineheight;
@@ -172,37 +171,36 @@ void RichLabel::Rebuild()
int x = 0;
int y = 0;
int lineheight = -1;
for ( DividedText::List::iterator it = m_TextBlocks.begin(); it != m_TextBlocks.end(); ++it )
for (DividedText::List::iterator it = m_TextBlocks.begin(); it != m_TextBlocks.end(); ++it)
{
if ( it->type == Type_Newline )
if (it->type == Type_Newline)
{
CreateNewline( x, y, lineheight );
CreateNewline(x, y, lineheight);
continue;
}
if ( it->type == Type_Text )
if (it->type == Type_Text)
{
CreateLabel( (*it).text, *it, x, y, lineheight, false );
CreateLabel((*it).text, *it, x, y, lineheight, false);
continue;
}
}
m_bNeedsRebuild = false;
}
void RichLabel::OnBoundsChanged( Gwen::Rect oldBounds )
void RichLabel::OnBoundsChanged(Gwen::Rect oldBounds)
{
BaseClass::OnBoundsChanged( oldBounds );
BaseClass::OnBoundsChanged(oldBounds);
Rebuild();
}
void RichLabel::Layout( Gwen::Skin::Base* skin )
void RichLabel::Layout(Gwen::Skin::Base* skin)
{
BaseClass::Layout( skin );
BaseClass::Layout(skin);
if ( m_bNeedsRebuild )
if (m_bNeedsRebuild)
{
Rebuild();
}

Some files were not shown because too many files have changed in this diff Show More