Implement part of GSAutoLayoutEngine dependency management logic (#178)

* Implement part of GSAutoLayoutEngine dependency management logic

* Fix formatting of GSAutoLayoutEngine, GSCSFloatComparator and GSCSSolution

* Address PR feedback

* Address PR feedback

* Replace assignment with ASSIGN macro and fix makefile

* Add back dealloc in GSAutoLayoutEngine.m and GSCSSolution.m
This commit is contained in:
Benjamin Johnson 2023-04-19 17:06:53 +10:00 committed by GitHub
parent a913346b83
commit 2be7334ce2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 870 additions and 18 deletions

View file

@ -655,8 +655,8 @@ PACKAGE_SCOPE
#if GS_HAS_DECLARED_PROPERTIES
@property (nonatomic) BOOL needsLayout;
#else
-(BOOL) needsLayout;
-(void) setNeedsLayout: (BOOL)needsLayout;
- (BOOL) needsLayout;
- (void) setNeedsLayout: (BOOL)needsLayout;
#endif
#if GS_HAS_DECLARED_PROPERTIES

View file

@ -358,7 +358,12 @@ GSXibKeyedUnarchiver.m \
GSXib5KeyedUnarchiver.m \
GSHelpAttachment.m \
GSAutoLayoutEngine.m \
GSAutoLayoutVFLParser.m
GSAutoLayoutVFLParser.m \
GSCassowarySolver.m \
GSCSConstraint.m \
GSCSVariable.m \
GSCSSolution.m \
GSCSFloatComparator.m \
# Turn off NSMenuItem warning that NSMenuItem conforms to <NSObject>,
# but does not implement <NSObject>'s methods itself (it inherits
@ -675,7 +680,12 @@ GSXibLoading.h \
GSXibKeyedUnarchiver.h \
GSHelpAttachment.h \
GSAutoLayoutVFLParser.h \
GSAutoLayoutEngine.h
GSAutoLayoutEngine.h \
GSCassowarySolver.h \
GSCSConstraint.h \
GSCSVariable.h \
GSCSSolution.h \
GSCSFloatComparator.h
libgnustep-gui_HEADER_FILES = ${GUI_HEADERS}

View file

@ -20,8 +20,9 @@
Boston, MA 02110 USA.
*/
#import "AppKit/NSLayoutConstraint.h"
#import <Foundation/Foundation.h>
#import "AppKit/NSLayoutConstraint.h"
#import "GSCassowarySolver.h"
@class NSView;
@class NSLayoutConstraint;
@ -30,6 +31,22 @@
#define _GS_AUTO_LAYOUT_ENGINE_H
@interface GSAutoLayoutEngine : NSObject
{
GSCassowarySolver *_solver;
NSMapTable *_variablesByKey;
NSMutableArray *_solverConstraints;
NSMapTable *_constraintsByAutoLayoutConstaintHash;
NSMapTable *_layoutConstraintsBySolverConstraint;
NSMutableArray *_trackedViews;
NSMutableDictionary *_viewIndexByViewHash;
NSMutableDictionary *_viewAlignmentRectByViewIndex;
NSMutableDictionary *_constraintsByViewIndex;
NSMapTable *_internalConstraintsByViewIndex;
NSMapTable *_supportingConstraintsByConstraint;
int _viewCounter;
}
- (instancetype) initWithSolver: (GSCassowarySolver*)solver;
- (void) addConstraint: (NSLayoutConstraint *)constraint;

View file

@ -1,19 +1,19 @@
/* Copyright (C) 2023 Free Software Foundation, Inc.
By: Benjamin Johnson
Date: 28-2-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,
@ -21,40 +21,424 @@
*/
#import "GSAutoLayoutEngine.h"
#include "AppKit/NSLayoutConstraint.h"
#import "AppKit/NSLayoutConstraint.h"
#import "GSCSConstraint.h"
#import "GSFastEnumeration.h"
#import "NSViewPrivate.h"
@interface GSAutoLayoutEngine (PrivateMethods)
- (GSCSConstraint *) solverConstraintForConstraint:
(NSLayoutConstraint *)constraint;
- (void) mapLayoutConstraint: (NSLayoutConstraint *)layoutConstraint
toSolverConstraint: (GSCSConstraint *)solverConstraint;
- (void) updateAlignmentRectsForTrackedViews;
- (void) updateAlignmentRectsForTrackedViewsForSolution:
(GSCSSolution *)solution;
- (BOOL) hasConstraintsForView: (NSView *)view;
- (GSCSConstraint *) getExistingConstraintForAutolayoutConstraint:
(NSLayoutConstraint *)constraint;
- (void) addConstraintAgainstViewConstraintsArray:
(NSLayoutConstraint *)constraint;
- (void) removeConstraintAgainstViewConstraintsArray:
(NSLayoutConstraint *)constraint;
- (void) addSupportingInternalConstraintsToView: (NSView *)view
forAttribute: (NSLayoutAttribute)attribute
constraint: (GSCSConstraint *)constraint;
- (void) removeInternalConstraintsForView: (NSView *)view;
- (void) addSolverConstraint: (GSCSConstraint *)constraint;
- (void) removeSolverConstraint: (GSCSConstraint *)constraint;
- (NSArray *) constraintsForView: (NSView *)view;
- (NSNumber *) indexForView: (NSView *)view;
- (void) notifyViewsOfAlignmentRectChange: (NSArray *)viewsWithChanges;
- (BOOL) solverCanSolveAlignmentRectForView: (NSView *)view
solution: (GSCSSolution *)solution;
- (void) recordAlignmentRect: (NSRect)alignmentRect
forViewIndex: (NSNumber *)viewIndex;
- (NSRect) solverAlignmentRectForView: (NSView *)view
solution: (GSCSSolution *)solution;
- (NSRect) currentAlignmentRectForViewAtIndex: (NSNumber *)viewIndex;
- (BOOL) updateViewAligmentRect: (GSCSSolution *)solution view: (NSView *)view;
@end
@implementation GSAutoLayoutEngine
- (void) addConstraint: (NSLayoutConstraint *)constraint
- (instancetype) initWithSolver: (GSCassowarySolver *)cassowarySolver;
{
// FIXME Add constraint to solver
self = [super init];
if (self != nil)
{
ASSIGN(_solver, cassowarySolver);
ASSIGN(_variablesByKey, [NSMapTable strongToStrongObjectsMapTable]);
ASSIGN(_constraintsByAutoLayoutConstaintHash, [NSMapTable strongToStrongObjectsMapTable]);
ASSIGN(_layoutConstraintsBySolverConstraint, [NSMapTable strongToStrongObjectsMapTable]);
ASSIGN(_solverConstraints, [NSMutableArray array]);
ASSIGN(_trackedViews, [NSMutableArray array]);
ASSIGN(_supportingConstraintsByConstraint, [NSMapTable strongToStrongObjectsMapTable]);
ASSIGN(_viewAlignmentRectByViewIndex, [NSMutableDictionary dictionary]);
ASSIGN(_viewIndexByViewHash, [NSMutableDictionary dictionary]);
ASSIGN(_constraintsByViewIndex, [NSMutableDictionary dictionary]);
ASSIGN(_internalConstraintsByViewIndex, [NSMapTable strongToStrongObjectsMapTable]);
}
return self;
}
- (instancetype) init
{
GSCassowarySolver *solver = [[GSCassowarySolver alloc] init];
self = [self initWithSolver: solver];
RELEASE(solver);
return self;
}
- (void) addConstraints: (NSArray *)constraints
{
// FIXME Add constraints to solver
FOR_IN(NSLayoutConstraint *, constraint, constraints)
[self addConstraint: constraint];
END_FOR_IN(constraints);
}
- (void) addConstraint: (NSLayoutConstraint *)constraint
{
GSCSConstraint *solverConstraint =
[self solverConstraintForConstraint: constraint];
[self mapLayoutConstraint: constraint toSolverConstraint: solverConstraint];
[self addSupportingInternalConstraintsToView: [constraint firstItem]
forAttribute: [constraint firstAttribute]
constraint: solverConstraint];
if ([constraint secondItem])
{
[self
addSupportingInternalConstraintsToView: [constraint secondItem]
forAttribute: [constraint secondAttribute]
constraint: solverConstraint];
}
[self addSolverConstraint: solverConstraint];
[self updateAlignmentRectsForTrackedViews];
[self addConstraintAgainstViewConstraintsArray: constraint];
}
- (void) removeConstraint: (NSLayoutConstraint *)constraint
{
// FIXME Remove constraint from solver
GSCSConstraint *solverConstraint =
[self getExistingConstraintForAutolayoutConstraint: constraint];
if (solverConstraint == nil)
{
return;
}
[self removeSolverConstraint: solverConstraint];
NSArray *internalConstraints =
[_supportingConstraintsByConstraint objectForKey: solverConstraint];
if (internalConstraints)
{
FOR_IN(GSCSConstraint *, internalConstraint, internalConstraints)
[self removeSolverConstraint: internalConstraint];
END_FOR_IN(internalConstraints);
}
[_supportingConstraintsByConstraint setObject: nil forKey: solverConstraint];
[self updateAlignmentRectsForTrackedViews];
[self removeConstraintAgainstViewConstraintsArray: constraint];
if ([self hasConstraintsForView: [constraint firstItem]])
{
[self removeInternalConstraintsForView: [constraint firstItem]];
}
if ([constraint secondItem] != nil &&
[self hasConstraintsForView: [constraint secondItem]])
{
[self removeInternalConstraintsForView: [constraint secondItem]];
}
}
- (void) removeConstraints: (NSArray *)constraints
{
// FIXME Remove constraints from solver
FOR_IN(NSLayoutConstraint *, constraint, constraints)
[self removeConstraint: constraint];
END_FOR_IN(constraints);
}
- (GSCSConstraint *) solverConstraintForConstraint:
(NSLayoutConstraint *)constraint
{
// FIXME Map NSLayoutConstraint to GSCSConstraint
return AUTORELEASE([[GSCSConstraint alloc] init]);
}
- (void) mapLayoutConstraint: (NSLayoutConstraint *)layoutConstraint
toSolverConstraint: (GSCSConstraint *)solverConstraint
{
[_constraintsByAutoLayoutConstaintHash setObject: solverConstraint
forKey: layoutConstraint];
[_layoutConstraintsBySolverConstraint setObject: layoutConstraint
forKey: solverConstraint];
}
- (void) addSupportingInternalConstraintsToView: (NSView *)view
forAttribute: (NSLayoutAttribute)attribute
constraint: (GSCSConstraint *)constraint
{
// FIXME addSupportingInternalConstraintsToView
}
- (void) removeInternalConstraintsForView: (NSView *)view
{
NSArray *internalViewConstraints =
[_internalConstraintsByViewIndex objectForKey: view];
FOR_IN(GSCSConstraint *, constraint, internalViewConstraints)
[self removeSolverConstraint: constraint];
END_FOR_IN(internalViewConstraints);
[_internalConstraintsByViewIndex setObject: nil forKey: view];
}
- (BOOL) hasConstraintsForView: (NSView *)view
{
NSNumber *viewIndex = [self indexForView: view];
return [[_constraintsByViewIndex objectForKey: viewIndex] count] > 0;
}
- (GSCSConstraint *) getExistingConstraintForAutolayoutConstraint:
(NSLayoutConstraint *)constraint
{
return [_constraintsByAutoLayoutConstaintHash objectForKey: constraint];
}
- (void) addConstraintAgainstViewConstraintsArray:
(NSLayoutConstraint *)constraint
{
NSNumber *firstItemViewIndex = [self indexForView: [constraint firstItem]];
NSMutableArray *constraintsForView =
[_constraintsByViewIndex objectForKey: firstItemViewIndex];
if (!constraintsForView)
{
constraintsForView = [NSMutableArray array];
[_constraintsByViewIndex setObject: constraintsForView
forKey: firstItemViewIndex];
}
[constraintsForView addObject: constraint];
if ([constraint secondItem] != nil)
{
NSNumber *secondItemViewIndex =
[self indexForView: [constraint secondItem]];
if ([_constraintsByViewIndex objectForKey: secondItemViewIndex])
{
[_constraintsByViewIndex setObject: [NSMutableArray array]
forKey: secondItemViewIndex];
}
[[_constraintsByViewIndex objectForKey: secondItemViewIndex]
addObject: constraint];
}
}
- (void) removeConstraintAgainstViewConstraintsArray:
(NSLayoutConstraint *)constraint
{
NSNumber *firstItemViewIndex = [self indexForView: [constraint firstItem]];
NSMutableArray *constraintsForFirstItem =
[_constraintsByViewIndex objectForKey: firstItemViewIndex];
NSUInteger indexOfConstraintInFirstItem =
[constraintsForFirstItem indexOfObject: constraint];
[constraintsForFirstItem removeObjectAtIndex: indexOfConstraintInFirstItem];
if ([constraint secondItem] != nil)
{
NSNumber *secondItemViewIndexIndex =
[self indexForView: [constraint secondItem]];
NSMutableArray *constraintsForSecondItem =
[_constraintsByViewIndex objectForKey: secondItemViewIndexIndex];
NSUInteger indexOfConstraintInSecondItem =
[constraintsForSecondItem indexOfObject: constraint];
[constraintsForSecondItem
removeObjectAtIndex: indexOfConstraintInSecondItem];
}
}
- (void) updateAlignmentRectsForTrackedViews
{
GSCSSolution *solution = [_solver solve];
[self updateAlignmentRectsForTrackedViewsForSolution: solution];
}
- (void) updateAlignmentRectsForTrackedViewsForSolution:
(GSCSSolution *)solution
{
NSMutableArray *viewsWithChanges = [NSMutableArray array];
FOR_IN(NSView *, view, _trackedViews)
BOOL viewAlignmentRectUpdated = [self updateViewAligmentRect: solution
view: view];
if (viewAlignmentRectUpdated)
{
[viewsWithChanges addObject: view];
}
END_FOR_IN(_trackedViews);
[self notifyViewsOfAlignmentRectChange: viewsWithChanges];
}
- (BOOL) updateViewAligmentRect: (GSCSSolution *)solution view: (NSView *)view
{
NSNumber *viewIndex = [self indexForView: view];
if ([self solverCanSolveAlignmentRectForView: view solution: solution])
{
NSRect existingAlignmentRect =
[self currentAlignmentRectForViewAtIndex: viewIndex];
BOOL isExistingAlignmentRect = NSIsEmptyRect(existingAlignmentRect);
NSRect solverAlignmentRect = [self solverAlignmentRectForView: view
solution: solution];
[self recordAlignmentRect: solverAlignmentRect forViewIndex: viewIndex];
if (isExistingAlignmentRect == NO
|| !NSEqualRects(solverAlignmentRect, existingAlignmentRect))
{
return YES;
}
}
return NO;
}
- (BOOL) solverCanSolveAlignmentRectForView: (NSView *)view
solution: (GSCSSolution *)solution
{
// FIXME
return NO;
}
- (void) recordAlignmentRect: (NSRect)alignmentRect
forViewIndex: (NSNumber *)viewIndex
{
NSValue *newRectValue = [NSValue valueWithRect: alignmentRect];
[_viewAlignmentRectByViewIndex setObject: newRectValue forKey: viewIndex];
}
- (NSRect) currentAlignmentRectForViewAtIndex: (NSNumber *)viewIndex
{
NSValue *existingRectValue =
[_viewAlignmentRectByViewIndex objectForKey: viewIndex];
if (existingRectValue == nil)
{
return NSZeroRect;
}
NSRect existingAlignmentRect;
[existingRectValue getValue: &existingAlignmentRect];
return existingAlignmentRect;
}
- (NSRect) solverAlignmentRectForView: (NSView *)view
solution: (GSCSSolution *)solution
{
// FIXME Get view solution from solver
return NSZeroRect;
}
- (void) notifyViewsOfAlignmentRectChange: (NSArray *)viewsWithChanges
{
FOR_IN(NSView *, view, viewsWithChanges)
[view _layoutEngineDidChangeAlignmentRect];
END_FOR_IN(viewsWithChanges);
}
- (NSRect) alignmentRectForView: (NSView *)view
{
// FIXME Get alignment rect for view from solver
return NSMakeRect (0, 0, 0, 0);
return NSZeroRect;
}
- (void) addSolverConstraint: (GSCSConstraint *)constraint
{
[_solverConstraints addObject: constraint];
[_solver addConstraint: constraint];
}
- (void) removeSolverConstraint: (GSCSConstraint *)constraint
{
[_solver removeConstraint: constraint];
[_solverConstraints removeObject: constraint];
}
- (NSNumber *) indexForView: (NSView *)view
{
return [_viewIndexByViewHash
objectForKey: [NSNumber numberWithUnsignedInteger: [view hash]]];
}
- (NSArray *) constraintsForView: (NSView *)view
{
// FIXME Get constraints for view
return [NSArray array];
NSNumber *viewIndex = [self indexForView: view];
if (!viewIndex)
{
return [NSArray array];
}
NSMutableArray *constraintsForView = [NSMutableArray array];
NSArray *viewConstraints = [_constraintsByViewIndex objectForKey: viewIndex];
FOR_IN(NSLayoutConstraint *, constraint, viewConstraints)
if ([constraint firstItem] == view)
{
[constraintsForView addObject: constraint];
}
END_FOR_IN(viewConstraints);
return constraintsForView;
}
- (void) dealloc
{
RELEASE (_trackedViews);
RELEASE (_viewAlignmentRectByViewIndex);
RELEASE (_viewIndexByViewHash);
RELEASE (_constraintsByViewIndex);
RELEASE (_constraintsByViewIndex);
RELEASE (_supportingConstraintsByConstraint);
RELEASE (_constraintsByAutoLayoutConstaintHash);
RELEASE (_internalConstraintsByViewIndex);
RELEASE (_solverConstraints);
RELEASE (_variablesByKey);
RELEASE (_solver);
[super dealloc];
}
@end

32
Source/GSCSConstraint.h Normal file
View file

@ -0,0 +1,32 @@
/* 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 <Foundation/Foundation.h>
#ifndef _GS_CS_CONSTRAINT_H
#define _GS_CS_CONSTRAINT_H
@interface GSCSConstraint : NSObject
@end
#endif

27
Source/GSCSConstraint.m Normal file
View file

@ -0,0 +1,27 @@
/* 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"
@implementation GSCSConstraint
@end

View file

@ -0,0 +1,36 @@
/* 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 <Foundation/Foundation.h>
#ifndef _GS_CS_FLOAT_COMPARATOR_H
#define _GS_CS_FLOAT_COMPARATOR_H
@interface GSCSFloatComparator : NSObject
+ (BOOL) isApproxiatelyEqual: (CGFloat)a b: (CGFloat)b;
+ (BOOL) isApproxiatelyZero: (CGFloat)value;
@end
#endif

View file

@ -0,0 +1,39 @@
/* 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 "GSCSFloatComparator.h"
@implementation GSCSFloatComparator
const float GSCSEpsilon = 1.0e-8;
+ (BOOL) isApproxiatelyEqual: (CGFloat)a b: (CGFloat)b
{
return fabs(a - b) <= GSCSEpsilon;
}
+ (BOOL) isApproxiatelyZero: (CGFloat)value
{
return [self isApproxiatelyEqual: value b: 0];
}
@end

44
Source/GSCSSolution.h Normal file
View file

@ -0,0 +1,44 @@
/* 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 <Foundation/Foundation.h>
#import "GSCSVariable.h"
#ifndef _GS_CS_Solution_H
#define _GS_CS_Solution_H
@interface GSCSSolution : NSObject
{
NSMapTable *_resultsByVariable;
}
- (void) setResult: (CGFloat)result forVariable: (GSCSVariable*)variable;
- (NSNumber*) resultForVariable: (GSCSVariable*)variable;
- (NSArray*) variables;
- (BOOL) isEqualToCassowarySolverSolution: (GSCSSolution*)solution;
@end
#endif

100
Source/GSCSSolution.m Normal file
View file

@ -0,0 +1,100 @@
/* 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 "GSCSSolution.h"
#import "GSCSFloatComparator.h"
#import "GSFastEnumeration.h"
@implementation GSCSSolution
- (instancetype) init
{
self = [super init];
if (self)
{
ASSIGN(_resultsByVariable, [NSMapTable strongToStrongObjectsMapTable]);
}
return self;
}
- (void) setResult: (CGFloat)result forVariable: (GSCSVariable *)variable
{
NSNumber *encodedResult = [NSNumber numberWithFloat: result];
[_resultsByVariable setObject: encodedResult forKey: variable];
}
- (NSNumber *) resultForVariable: (GSCSVariable *)variable;
{
return [_resultsByVariable objectForKey: variable];
}
- (NSArray *) variables
{
NSMutableArray *variables = [NSMutableArray array];
NSEnumerator *resultVariables = [_resultsByVariable keyEnumerator];
FOR_IN(GSCSVariable *, variable, resultVariables)
[variables addObject: variable];
END_FOR_IN(resultVariables)
return variables;
}
- (BOOL) solution: (GSCSSolution *)solution
hasEqualResultForVariable: (GSCSVariable *)variable
{
NSNumber *lhsResult = [self resultForVariable: variable];
NSNumber *rhsResult = [solution resultForVariable: variable];
BOOL hasResultForBoth = lhsResult != nil && rhsResult != nil;
if (!hasResultForBoth) {
return NO;
}
return [GSCSFloatComparator isApproxiatelyEqual: [lhsResult floatValue]
b: [rhsResult floatValue]];
}
- (BOOL) isEqualToCassowarySolverSolution: (GSCSSolution *)solution
{
if ([[self variables] count] != [[solution variables] count])
{
return NO;
}
NSArray *variables = [self variables];
FOR_IN(GSCSVariable *, variable, variables)
if (![self solution: solution hasEqualResultForVariable: variable])
{
return NO;
}
END_FOR_IN(variables)
return YES;
}
- (void) dealloc
{
RELEASE (_resultsByVariable);
[super dealloc];
}
@end

32
Source/GSCSVariable.h Normal file
View file

@ -0,0 +1,32 @@
/* 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 <Foundation/Foundation.h>
#ifndef _GS_CS_VARIABLE_H
#define _GS_CS_VARIABLE_H
@interface GSCSVariable : NSObject
@end
#endif

27
Source/GSCSVariable.m Normal file
View file

@ -0,0 +1,27 @@
/* 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 "GSCSVariable.h"
@implementation GSCSVariable
@end

View file

@ -0,0 +1,44 @@
/* 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 <Foundation/Foundation.h>
#import "GSCSConstraint.h"
#import "GSCSSolution.h"
#ifndef _GS_CASSOWARY_SOLVER_H
#define _GS_CASSOWARY_SOLVER_H
@interface GSCassowarySolver : NSObject
- (void) addConstraint: (GSCSConstraint*)constraint;
- (void) addConstraints: (NSArray*)constraints;
- (void) removeConstraint: (GSCSConstraint*)constraint;
- (void) removeConstraints: (NSArray*)constraints;
- (GSCSSolution*) solve;
@end
#endif

View file

@ -0,0 +1,53 @@
/* 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 "GSCassowarySolver.h"
@implementation GSCassowarySolver
- (void) addConstraint: (GSCSConstraint*)constraint
{
// FIXME Add constraint to solver
}
- (void) addConstraints: (NSArray*)constraints
{
// FIXME Add constraints to solver
}
- (void) removeConstraint: (GSCSConstraint*)constraint
{
// FIXME Remove constraint from solver
}
- (void) removeConstraints: (NSArray*)constraints
{
// FIXME Remove constraints from solver
}
- (GSCSSolution*) solve
{
// FIXME Return correct solution
return [[GSCSSolution alloc] init];
}
@end

View file

@ -5235,6 +5235,11 @@ static NSView* findByTag(NSView *view, NSInteger aTag, NSUInteger *level)
return [[self window] _layoutEngine];
}
- (void) _layoutEngineDidChangeAlignmentRect
{
[[self superview] setNeedsLayout: YES];
}
@end
@implementation NSView (__NSViewPrivateMethods__)

View file

@ -47,6 +47,8 @@
- (GSAutoLayoutEngine*) _layoutEngine;
- (void) _layoutEngineDidChangeAlignmentRect;
@end
#endif // _GNUstep_H_NSViewPrivate