mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 08:10:48 +00:00
367 lines
No EOL
12 KiB
Objective-C
367 lines
No EOL
12 KiB
Objective-C
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
|
|
|
By: Benjamin Johnson
|
|
Date: 19-3-2023
|
|
This file is part of the GNUstep Library.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110 USA.
|
|
*/
|
|
|
|
#import "GSCSConstraint.h"
|
|
#import "GSCSFloatComparator.h"
|
|
#import "GSCSVariable.h"
|
|
|
|
@implementation GSCSConstraint
|
|
|
|
- (instancetype) init
|
|
{
|
|
return [self initWithType: GSCSConstraintTypeLinear
|
|
strength: nil
|
|
expression: nil
|
|
variable: nil];
|
|
}
|
|
|
|
- (instancetype) initWithType: (GSCSConstraintType)type
|
|
strength: (GSCSStrength *)strength
|
|
expression: (GSCSLinearExpression *)expression
|
|
variable: (GSCSVariable *)variable
|
|
{
|
|
self = [super init];
|
|
if (self)
|
|
{
|
|
ASSIGN(_strength, strength != nil ? [strength copy]
|
|
: [GSCSStrength strengthRequired]);
|
|
ASSIGN(_expression, expression);
|
|
ASSIGN(_variable, variable);
|
|
_type = type;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (instancetype) initLinearConstraintWithExpression:
|
|
(GSCSLinearExpression *)expression
|
|
strength: (GSCSStrength *)strength
|
|
variable: (GSCSVariable *)variable
|
|
{
|
|
return [self initWithType: GSCSConstraintTypeLinear
|
|
strength: strength
|
|
expression: expression
|
|
variable: variable];
|
|
}
|
|
|
|
- (instancetype) initLinearConstraintWithExpression:
|
|
(GSCSLinearExpression *)expression
|
|
{
|
|
return
|
|
[self initLinearConstraintWithExpression: expression
|
|
strength: [GSCSStrength strengthRequired]
|
|
variable: nil];
|
|
}
|
|
|
|
- (instancetype) initLinearInequityConstraintWithExpression:
|
|
(GSCSLinearExpression *)expression
|
|
{
|
|
return
|
|
[self initWithType: GSCSConstraintTypeLinearInequity
|
|
strength: [GSCSStrength strengthRequired]
|
|
expression: expression
|
|
variable: nil];
|
|
}
|
|
|
|
- (instancetype) initEditConstraintWithVariable: (GSCSVariable *)variable
|
|
strength: (GSCSStrength *)strength
|
|
{
|
|
GSCSLinearExpression *expression =
|
|
[[GSCSLinearExpression alloc] initWithVariable: variable
|
|
coefficient: -1
|
|
constant: [variable value]];
|
|
GSCSConstraint *constraint = [self initWithType: GSCSConstraintTypeEdit
|
|
strength: strength
|
|
expression: expression
|
|
variable: variable];
|
|
RELEASE(expression);
|
|
return constraint;
|
|
}
|
|
|
|
- (instancetype) initStayConstraintWithVariable: (GSCSVariable *)variable
|
|
strength: (GSCSStrength *)strength
|
|
{
|
|
GSCSLinearExpression *expression =
|
|
[[GSCSLinearExpression alloc] initWithVariable: variable
|
|
coefficient: -1
|
|
constant: [variable value]];
|
|
GSCSConstraint *constraint = [[GSCSConstraint alloc] initWithType: GSCSConstraintTypeStay
|
|
strength: strength
|
|
expression: expression
|
|
variable: variable];
|
|
RELEASE(expression);
|
|
return constraint;
|
|
}
|
|
|
|
- (instancetype) initWithLhsVariable: (GSCSVariable *)lhs
|
|
equalsRhsVariable: (GSCSVariable *)rhs
|
|
{
|
|
GSCSLinearExpression *expression =
|
|
[[GSCSLinearExpression alloc] initWithVariable: lhs];
|
|
[expression addVariable: rhs coefficient: -1];
|
|
GSCSConstraint *constraint = [self initLinearConstraintWithExpression: expression];
|
|
RELEASE(expression);
|
|
|
|
return constraint;
|
|
}
|
|
|
|
- (instancetype) initWithLhsVariable: (GSCSVariable *)lhs
|
|
equalsConstant: (CGFloat)rhs
|
|
{
|
|
GSCSLinearExpression *expression =
|
|
[[GSCSLinearExpression alloc] initWithVariable: lhs
|
|
coefficient: 1
|
|
constant: -rhs];
|
|
GSCSConstraint *constraint = [self initLinearConstraintWithExpression: expression];
|
|
RELEASE(expression);
|
|
return constraint;
|
|
}
|
|
|
|
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
|
operator: (GSCSConstraintOperator) operator
|
|
rightVariable: (GSCSVariable *)rhs
|
|
{
|
|
if (operator == GSCSConstraintOperatorEqual)
|
|
{
|
|
return AUTORELEASE([[GSCSConstraint alloc]
|
|
initWithLhsVariable: lhs equalsRhsVariable: rhs]);
|
|
}
|
|
else
|
|
{
|
|
GSCSLinearExpression *rhsExpression =
|
|
[[GSCSLinearExpression alloc] initWithVariable: rhs];
|
|
if (operator == GSCSConstraintOperationGreaterThanOrEqual)
|
|
{
|
|
[rhsExpression multiplyConstantAndTermsBy: -1];
|
|
[rhsExpression addVariable: lhs];
|
|
}
|
|
else if (operator == GSCSConstraintOperatorLessThanOrEqual)
|
|
{
|
|
[rhsExpression addVariable: lhs coefficient: -1];
|
|
}
|
|
|
|
RELEASE(rhsExpression);
|
|
|
|
return AUTORELEASE([[GSCSConstraint alloc]
|
|
initLinearInequityConstraintWithExpression: rhsExpression]);
|
|
}
|
|
}
|
|
|
|
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
|
operator: (GSCSConstraintOperator) operator
|
|
rightConstant: (CGFloat)rhs
|
|
{
|
|
GSCSLinearExpression *expression;
|
|
GSCSConstraint *constraint;
|
|
if (operator == GSCSConstraintOperatorEqual)
|
|
{
|
|
expression = [[GSCSLinearExpression alloc] init];
|
|
[expression addVariable: lhs coefficient: 1];
|
|
[expression setConstant: -rhs];
|
|
|
|
constraint = [[GSCSConstraint alloc]
|
|
initLinearConstraintWithExpression: expression
|
|
strength: [GSCSStrength strengthRequired]
|
|
variable: nil];
|
|
}
|
|
else
|
|
{
|
|
expression =
|
|
[[GSCSLinearExpression alloc] initWithConstant: rhs];
|
|
if (operator == GSCSConstraintOperationGreaterThanOrEqual)
|
|
{
|
|
[expression multiplyConstantAndTermsBy: -1];
|
|
[expression addVariable: lhs coefficient: 1.0];
|
|
}
|
|
else if (operator == GSCSConstraintOperatorLessThanOrEqual)
|
|
{
|
|
[expression addVariable: lhs coefficient: -1.0];
|
|
}
|
|
|
|
constraint = [[GSCSConstraint alloc]
|
|
initLinearInequityConstraintWithExpression: expression];
|
|
}
|
|
|
|
RELEASE(expression);
|
|
return AUTORELEASE(constraint);
|
|
}
|
|
|
|
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
|
operator: (GSCSConstraintOperator) operator
|
|
rightExpression: (GSCSLinearExpression *)rhs
|
|
{
|
|
GSCSLinearExpression *lhsExpression =
|
|
[[GSCSLinearExpression alloc] initWithVariable: lhs];
|
|
GSCSConstraint *constraint = [self constraintWithLeftExpression: lhsExpression operator: operator rightExpression: rhs];
|
|
RELEASE(lhsExpression);
|
|
return constraint;
|
|
}
|
|
|
|
+ (GSCSConstraint *) constraintWithLeftConstant: (CGFloat)lhs
|
|
operator: (GSCSConstraintOperator) operator
|
|
rightVariable: (GSCSVariable *)rhs
|
|
{
|
|
GSCSLinearExpression *valueExpression =
|
|
[[GSCSLinearExpression alloc] initWithConstant: lhs];
|
|
|
|
GSCSConstraint *constraint = nil;
|
|
if (operator == GSCSConstraintOperatorEqual)
|
|
{
|
|
[valueExpression addVariable: rhs coefficient: -1.0];
|
|
constraint = [[GSCSConstraint alloc]
|
|
initLinearConstraintWithExpression: valueExpression];
|
|
}
|
|
else
|
|
{
|
|
if (operator == GSCSConstraintOperationGreaterThanOrEqual)
|
|
{
|
|
[valueExpression addVariable: rhs coefficient: -1.0];
|
|
}
|
|
else if (operator == GSCSConstraintOperatorLessThanOrEqual)
|
|
{
|
|
[valueExpression multiplyConstantAndTermsBy: -1];
|
|
[valueExpression addVariable: rhs coefficient: 1.0];
|
|
}
|
|
|
|
constraint = [[GSCSConstraint alloc]
|
|
initLinearInequityConstraintWithExpression: valueExpression];
|
|
}
|
|
|
|
RELEASE(valueExpression);
|
|
return constraint;
|
|
}
|
|
|
|
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
|
operator: (GSCSConstraintOperator) operator
|
|
rightVariable: (GSCSVariable *)rhs
|
|
{
|
|
GSCSLinearExpression *rhsExpression =
|
|
[[GSCSLinearExpression alloc] initWithVariable: rhs];
|
|
GSCSConstraint *constraint = [self constraintWithLeftExpression: lhs operator: operator rightExpression: rhsExpression];
|
|
RELEASE(rhsExpression);
|
|
return constraint;
|
|
}
|
|
|
|
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
|
operator: (GSCSConstraintOperator) operator
|
|
rightExpression: (GSCSLinearExpression *)rhs
|
|
{
|
|
GSCSLinearExpression *expression = [rhs copy];
|
|
GSCSConstraint *constraint;
|
|
if (operator == GSCSConstraintOperatorEqual)
|
|
{
|
|
[expression addExpression: lhs multiplier: -1];
|
|
constraint = [[GSCSConstraint alloc]
|
|
initLinearConstraintWithExpression: expression];
|
|
}
|
|
else
|
|
{
|
|
if (operator == GSCSConstraintOperationGreaterThanOrEqual)
|
|
{
|
|
[expression multiplyConstantAndTermsBy: -1];
|
|
[expression addExpression: lhs];
|
|
}
|
|
else if (operator == GSCSConstraintOperatorLessThanOrEqual)
|
|
{
|
|
[expression addExpression: lhs multiplier: -1];
|
|
}
|
|
|
|
constraint = [[GSCSConstraint alloc]
|
|
initLinearInequityConstraintWithExpression: expression];
|
|
}
|
|
|
|
RELEASE(expression);
|
|
return AUTORELEASE(constraint);
|
|
}
|
|
|
|
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
|
operator: (GSCSConstraintOperator) operator
|
|
rightConstant: (CGFloat)rhs
|
|
{
|
|
GSCSLinearExpression *rhsExpression =
|
|
[[GSCSLinearExpression alloc] initWithConstant: rhs];
|
|
GSCSConstraint *constraint = [self constraintWithLeftExpression: lhs operator: operator rightExpression: rhsExpression];
|
|
RELEASE(rhsExpression);
|
|
return constraint;
|
|
}
|
|
|
|
+ (instancetype) editConstraintWithVariable: (GSCSVariable *)variable
|
|
{
|
|
return AUTORELEASE([[self alloc]
|
|
initEditConstraintWithVariable: variable
|
|
strength: [GSCSStrength strengthStrong]]);
|
|
}
|
|
|
|
- (void) setStrength: (GSCSStrength *)strength
|
|
{
|
|
ASSIGN(_strength, strength);
|
|
}
|
|
|
|
- (BOOL) isRequired
|
|
{
|
|
return [_strength isRequired];
|
|
}
|
|
|
|
- (BOOL) isEditConstraint
|
|
{
|
|
return _type == GSCSConstraintTypeEdit;
|
|
}
|
|
|
|
- (BOOL) isStayConstraint
|
|
{
|
|
return _type == GSCSConstraintTypeStay;
|
|
}
|
|
|
|
- (BOOL) isInequality
|
|
{
|
|
return _type == GSCSConstraintTypeLinearInequity;
|
|
}
|
|
|
|
- (GSCSLinearExpression *) expression
|
|
{
|
|
return _expression;
|
|
}
|
|
|
|
- (GSCSVariable *) variable
|
|
{
|
|
return _variable;
|
|
}
|
|
|
|
- (GSCSStrength *) strength
|
|
{
|
|
return _strength;
|
|
}
|
|
|
|
- (GSCSConstraintType) type
|
|
{
|
|
return _type;
|
|
}
|
|
|
|
- (void) dealloc
|
|
{
|
|
RELEASE(_strength);
|
|
RELEASE(_expression);
|
|
RELEASE(_variable);
|
|
|
|
[super dealloc];
|
|
}
|
|
|
|
@end |