Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for render problem. #9

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions Sources/ApollonEdit/ViewModels/ApollonEditViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,25 @@ open class ApollonEditViewModel: ApollonViewModel {
/// Update the position of an UMLElement
func updateElementPosition(value: DragGesture.Value) {
if let element = selectedElement as? UMLElement {
updatePositionRecursivelyForAllChildren(element, translation: value.translation)
updatePositionRecursively(element, translation: value.translation)
}
}

/// Recursively check the children of each element and move them, until an element has no more children
private func updatePositionRecursivelyForAllChildren(_ element: UMLElement, translation: CGSize) {
private func updatePositionRecursively(_ element: UMLElement, translation: CGSize) {
element.bounds?.x += translation.width.rounded(.towardZero)
element.bounds?.y += translation.height.rounded(.towardZero)

if let children = element.children {
for child in children {
updatePositionRecursivelyForAllChildren(child, translation: translation)
if let attributes = element.attributes {
for attribute in attributes {
updatePositionRecursively(attribute, translation: translation)
}
}
if let methods = element.methods {
for method in methods {
updatePositionRecursively(method, translation: translation)
}
}

}

// func checkIfElementIsInContainer(elementToCheck: UMLElement) {
Expand Down Expand Up @@ -161,6 +166,7 @@ open class ApollonEditViewModel: ApollonViewModel {
for element in elementsToAdd {
if let elementId = element.id {
umlModel.elements?[elementId] = element
print("FUNCTION add Element", element.name, element.attributes, element.methods)
FelixTJDietrich marked this conversation as resolved.
Show resolved Hide resolved
adjustDiagramSize()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ struct ClassCreator: ElementCreator {
let element = UMLElement(id: elementID, type: type, bounds: Boundary(x: pointToAdd.x, y: pointToAdd.y, width: 200, height: 120))
let elementAttribute = UMLElement(name: "+ attribute: Type", type: .classAttribute, owner: elementID, bounds: Boundary(x: pointToAdd.x, y: pointToAdd.y + 40, width: 200, height: 40))
let elementMethod = UMLElement(name: "+ method()", type: .classMethod, owner: elementID, bounds: Boundary(x: pointToAdd.x, y: pointToAdd.y + 80, width: 200, height: 40))
element.addChild(elementAttribute)
element.addChild(elementMethod)
return [element, elementAttribute, elementMethod]
element.attributes?.append(elementAttribute)
element.methods?.append(elementMethod)
return [element]
}
}

Expand All @@ -66,9 +66,7 @@ struct AbstractClassOrInterfaceCreator: ElementCreator {
let element = UMLElement(id: elementID, type: type, bounds: Boundary(x: pointToAdd.x, y: pointToAdd.y, width: 200, height: 130))
let elementAttribute = UMLElement(name: "+ attribute: Type", type: .classAttribute, owner: elementID, bounds: Boundary(x: pointToAdd.x, y: pointToAdd.y + 50, width: 200, height: 40))
let elementMethod = UMLElement(name: "+ method()", type: .classMethod, owner: elementID, bounds: Boundary(x: pointToAdd.x, y: pointToAdd.y + 90, width: 200, height: 40))
kurunbelemir marked this conversation as resolved.
Show resolved Hide resolved
element.addChild(elementAttribute)
element.addChild(elementMethod)
return [element, elementAttribute, elementMethod]
return [element]
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,17 @@ struct UMLClassDiagramElementRenderer: UMLDiagramRenderer {
for element in elements {
if [UMLElementType.Class, .abstractClass, .interface, .enumeration].contains(element.value.type) {
draw(element: element.value)
}
}

for element in elements {
if [UMLElementType.classAttribute, .classMethod].contains(element.value.type) {
draw(element: element.value)
if let attributes = element.value.attributes {
for attribute in attributes {
draw(element: attribute)
}
}
if let methods = element.value.methods {
for method in methods {
draw(element: method)
}
}

}
}
}
Expand Down Expand Up @@ -139,7 +144,7 @@ struct UMLClassDiagramElementRenderer: UMLDiagramRenderer {

private func drawAttributeAndMethodSeparators(_ element: UMLElement, in elementRect: CGRect) {
// Draw a line above the first attribute of this element
if let firstAttribute = element.verticallySortedChildren?.first(where: { $0.type == .classAttribute }),
if let firstAttribute = element.attributes?.first,
let firstAttributeTopLeft = firstAttribute.boundsAsCGRect?.origin,
let firstAttributeSize = firstAttribute.boundsAsCGRect?.size {
let firstAttributeTopRight = firstAttributeTopLeft.applying(.init(translationX: firstAttributeSize.width, y: 0))
Expand All @@ -152,7 +157,7 @@ struct UMLClassDiagramElementRenderer: UMLDiagramRenderer {
}

// Draw a line above the first method of this element
if let firstMethod = element.verticallySortedChildren?.first(where: { $0.type == .classMethod }),
if let firstMethod = element.methods?.first,
let firstMethodTopLeft = firstMethod.boundsAsCGRect?.origin,
let firstMethodSize = firstMethod.boundsAsCGRect?.size {
let firstMethodTopRight = firstMethodTopLeft.applying(.init(translationX: firstMethodSize.width, y: 0))
Expand Down
24 changes: 6 additions & 18 deletions Sources/ApollonShared/DataModels/UMLElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ public class UMLElement: Codable, SelectableUMLItem {
public var bounds: Boundary?
public var direction: ElementDirection?
public var assessmentNote: String?
public var attributes: [String]?
public var methods: [String]?
public var attributes: [UMLElement]?
public var methods: [UMLElement]?
public var children: [UMLElement]? = [] // not decoded

/// Public Init, so that new UML elements can be created
Expand All @@ -23,8 +23,9 @@ public class UMLElement: Codable, SelectableUMLItem {
self.bounds = bounds
self.direction = direction
self.assessmentNote = assessmentNote
self.attributes = attributes ?? []
self.methods = methods ?? []
self.attributes = []
self.methods = []

}

/// UMLElement Coding Keys
Expand All @@ -42,7 +43,7 @@ public class UMLElement: Codable, SelectableUMLItem {

/// Public encode function to encode elements without the children property
public func encode(to encoder: Encoder) throws {
self.encodeChildrenToArray()
//self.encodeChildrenToArray()
FelixTJDietrich marked this conversation as resolved.
Show resolved Hide resolved
var container = encoder.container(keyedBy: UMLElementCodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
Expand Down Expand Up @@ -142,19 +143,6 @@ public class UMLElement: Codable, SelectableUMLItem {

return isXWithinBounds && isYWithinBounds
}

public func encodeChildrenToArray() {
if let children {
for child in children {
if [UMLElementType.classAttribute, .objectAttribute].contains(child.type) {
self.attributes?.append(child.id ?? "")
}
if [UMLElementType.classMethod, .objectMethod].contains(child.type) {
self.methods?.append(child.id ?? "")
}
}
}
}
}

/// Hashable (Equatable) extension
Expand Down