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 3 commits
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
61 changes: 35 additions & 26 deletions Sources/ApollonEdit/ViewModels/ApollonEditViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,37 +63,27 @@ 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) {
// if let elements = umlModel.elements {
// for element in elements {
// if let type = element.value.type, type.isContainer {
// if let containerRect = element.value.boundsAsCGRect, let elementRect = elementToCheck.boundsAsCGRect {
// if containerRect.contains(elementRect) {
// elementToCheck.owner = element.value.id
// element.value.addChild(elementToCheck)
// }
// }
// }
// }
// }
// }

/// Updates the Element Size after dragging the resize button
func updateElementSize(drag: CGSize) {
let widthToAdd = drag.width.rounded(.towardZero)
Expand All @@ -104,10 +94,16 @@ open class ApollonEditViewModel: ApollonViewModel {
element.bounds?.height += heightToAdd

if element.type?.isContainer == false {
if let children = element.children {
for child in children {
child.bounds?.width += widthToAdd
child.bounds?.height += heightToAdd
if let attributes = element.attributes{
for attribute in attributes {
attribute.bounds?.width += widthToAdd
attribute.bounds?.height += heightToAdd
}
}
if let methods = element.methods{
for method in methods {
method.bounds?.width += widthToAdd
method.bounds?.height += heightToAdd
}
}
}
Expand All @@ -121,7 +117,7 @@ open class ApollonEditViewModel: ApollonViewModel {
var largestYBottomRight: CGFloat = 0.0
var smallestXTopLeft: CGFloat = 0.0
var smallestYTopLeft: CGFloat = 0.0

if let elements = umlModel.elements {
for element in elements {
if let bounds = element.value.bounds {
Expand All @@ -146,10 +142,23 @@ open class ApollonEditViewModel: ApollonViewModel {
for element in elements {
element.value.bounds?.x += abs(smallestXTopLeft)
element.value.bounds?.y += abs(smallestYTopLeft)
if let attributes = element.value.attributes {
for attribute in attributes {
attribute.bounds?.x += abs(smallestXTopLeft)
attribute.bounds?.y += abs(smallestYTopLeft)
}
}
if let methods = element.value.methods {
for method in methods {
method.bounds?.x += abs(smallestXTopLeft)
method.bounds?.y += abs(smallestYTopLeft)
}
}
}
umlModel.size?.width += -(smallestXTopLeft) + DIAGRAM_MARGIN
umlModel.size?.height += -(smallestYTopLeft) + DIAGRAM_MARGIN
}

calculateIdealScale()
}
}
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,9 @@ 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]
element.attributes?.append(elementAttribute)
element.methods?.append(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
2 changes: 1 addition & 1 deletion Sources/ApollonShared/DataModels/Boundary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public struct Boundary: Codable {
self.width = width
self.height = height
}
// swiftlint:enable identifier_name
// swiftlint:enable identifier_nae
}

/// Hashable (Equatable) extension
Expand Down
24 changes: 5 additions & 19 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,6 @@ public class UMLElement: Codable, SelectableUMLItem {

/// Public encode function to encode elements without the children property
public func encode(to encoder: Encoder) throws {
self.encodeChildrenToArray()
var container = encoder.container(keyedBy: UMLElementCodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(name, forKey: .name)
Expand Down Expand Up @@ -117,7 +117,6 @@ public class UMLElement: Codable, SelectableUMLItem {
self.children?.append(child)
}
}

/// Remove a child from a UML element
public func removeChild(_ child: UMLElement) {
if let allChildren = self.verticallySortedChildren,
Expand All @@ -142,19 +141,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