mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +00:00
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:
parent
a913346b83
commit
2be7334ce2
16 changed files with 870 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
32
Source/GSCSConstraint.h
Normal 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
27
Source/GSCSConstraint.m
Normal 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
|
36
Source/GSCSFloatComparator.h
Normal file
36
Source/GSCSFloatComparator.h
Normal 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
|
39
Source/GSCSFloatComparator.m
Normal file
39
Source/GSCSFloatComparator.m
Normal 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
44
Source/GSCSSolution.h
Normal 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
100
Source/GSCSSolution.m
Normal 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
32
Source/GSCSVariable.h
Normal 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
27
Source/GSCSVariable.m
Normal 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
|
44
Source/GSCassowarySolver.h
Normal file
44
Source/GSCassowarySolver.h
Normal 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
|
53
Source/GSCassowarySolver.m
Normal file
53
Source/GSCassowarySolver.m
Normal 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
|
|
@ -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__)
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
|
||||
- (GSAutoLayoutEngine*) _layoutEngine;
|
||||
|
||||
- (void) _layoutEngineDidChangeAlignmentRect;
|
||||
|
||||
@end
|
||||
|
||||
#endif // _GNUstep_H_NSViewPrivate
|
||||
|
|
Loading…
Reference in a new issue