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:
@@ -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;
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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*/)
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -9,4 +9,3 @@
|
||||
|
||||
using namespace Gwen;
|
||||
using namespace Gwen::Controls;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -4,5 +4,4 @@
|
||||
See license in Gwen.h
|
||||
*/
|
||||
|
||||
|
||||
#include "Gwen/Controls/ImagePanel.h"
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() );
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user