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

Finding the tap location inside a group #502

Closed
aure opened this issue Oct 29, 2018 · 5 comments
Closed

Finding the tap location inside a group #502

aure opened this issue Oct 29, 2018 · 5 comments
Assignees
Milestone

Comments

@aure
Copy link
Contributor

aure commented Oct 29, 2018

The event location that is returned onTap or onTouchPressed seems to be relative to the entire window. Is there a way I can easily deduce the location of a tap within a button (clickable area). I want to be able to map the height location of the tap within the button to a variable from 0-1.

This might be less difficult on iOS because of a fixed screen size, but with a Mac app that can scale, it gets difficult because the numbers change when the window is resized.

My apologies if this is an easy one. :)

@ystrot
Copy link
Member

ystrot commented Oct 30, 2018

Hi Aurelius,

It looks like a bug, because tap location should be relative to a tapped node. Could you please attach some sample to reproduce it?

@ystrot ystrot self-assigned this Oct 30, 2018
@ystrot ystrot added this to the 0.9.4 milestone Oct 30, 2018
@aure
Copy link
Contributor Author

aure commented Nov 1, 2018

Here's some code that does a pretty good job, except that it doesn't handle window resizing yet. Currently I've just turned off resizing. It would also be fine if I could constrain the aspect ratio of the window.

If this is a suitable amount of complexity for your users, please feel free to close this issue, but if you can simplify it, that would be great. Either way, I can proceed.

//
//  TouchPadView.swift
//  MacawTouchPad
//
//  Created by Aurelius Prochazka on 11/1/18.
//  Copyright © 2018 Aure. All rights reserved.
//

import Macaw

class TouchPadView: MacawView {

    var touchPad: TouchPad!

    func drawNode() -> Node {
        let viewWidth = Double(self.layer!.bounds.width)
        let viewHeight = Double(self.layer!.bounds.height)

        let background = Rect(x: 0, y: 0, w: viewWidth, h: viewHeight)
            .fill(with: Color.rgb(r: 51, g: 51, b: 51))

        // Draw a touch pad in the middle of the screen
        touchPad = TouchPad(x: viewWidth / 4,
                            y: viewHeight / 4,
                            width: viewWidth / 2,
                            height: viewHeight / 2)

        return Group(contents: [background, touchPad])
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(node: Group(contents: []), coder: aDecoder)
        contentMode = .scaleAspectFit
        self.node = drawNode()

        touchPad.originalParentSize = self.layer!.bounds.size
        touchPad.parentSize = self.layer!.bounds.size
    }


    override func viewDidEndLiveResize() {
        touchPad.parentSize = self.layer!.bounds.size
    }

}

class TouchPad: Group {

    var originalParentSize = CGSize(width: 0.0, height: 0.0)
    var parentSize = CGSize(width: 0.0, height: 0.0)

    init(x: Double, y: Double, width: Double, height: Double) {
        let group = Group()
        super.init(contents: [group])

        let background = Shape(form: Rect(x: 0,
                                          y: 0,
                                          w: width,
                                          h: height))
        background.fill = Color.gray
        background.stroke = Stroke(fill: Color.black, width: 1)
        group.contents.append(background)

        let label = Text(text: "Touch Pad")
        label.place = label.place.move(dx: width / 4, dy: height / 4)
        group.contents.append(label)

        let xLabel = Text(text: "x:")
        xLabel.place = xLabel.place.move(dx: width / 4, dy: height / 2)
        group.contents.append(xLabel)

        let yLabel = Text(text: "y:")
        yLabel.place = yLabel.place.move(dx: width / 4, dy: height * 3 / 4)
        group.contents.append(yLabel)

        group.place = group.place.move(dx: x, dy: y)

        group.onTouchPressed { events in
            let location = events.points.first!.location

            // This works if your window is a constant aspect ratio
            let widthScale = width / Double(self.originalParentSize.width)
            let heightScale = height / Double(self.originalParentSize.height)

            let originalX = x / Double(self.originalParentSize.width)
            let originalY = y / Double(self.originalParentSize.height)

            let currentX = location.x / Double(self.parentSize.width)
            let currentY = location.y / Double(self.parentSize.height)

            xLabel.text = "x: " + String(format: "%0.2f", (currentX - originalX) / widthScale)
            yLabel.text = "y: " + String(format: "%0.2f", (currentY - originalY) / heightScale)

        }

    }
}

@aure
Copy link
Contributor Author

aure commented Nov 1, 2018

btw if you do wrap this up in Macaw, would be cool to offer all data - x, y, relatve x, y, and percentage of width height x y.

@ystrot
Copy link
Member

ystrot commented Nov 6, 2018

Hi Aurelius,

Thank you for the sample. I reproduced this issue and it's sad that we had absolute location in events, because it should be relative and now we can break some apps by fixing this issue. Probably we need to provide both absolute and relative locations now, need to think. Anyway you can use your workaround for now and I'll let you know once we add relative coordinates as well.

@ystrot ystrot closed this as completed in 10f3d0e Nov 14, 2018
ystrot added a commit that referenced this issue Nov 14, 2018
Fix #502: Finding the tap location inside a group
@aure
Copy link
Contributor Author

aure commented Nov 14, 2018

Nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants