1

I need to create a draggable button. The drag starts from multiple source and ends at a sink. Is there any way to get position of the sources and the sink after creation of the page.

Container {
                horizontalAlignment: HorizontalAlignment.Fill
                Label {
                    id: preId
                    preferredWidth: 700

                    text: rootContainer.data.part1
                    multiline: true
                    textStyle {
                        textAlign: TextAlign.Center
                        color: Color.Black
                    }
                    horizontalAlignment: HorizontalAlignment.Center
                }
            }
            Container {
                horizontalAlignment: HorizontalAlignment.Center

                SinkButton {
                    id: sinkId
                    preferredHeight: 100
                    preferredWidth: 686
                    textColor: Color.Black
                    enabled: false
                    layoutProperties: AbsoluteLayoutProperties {

                    }
                }
            }
            Container {
                horizontalAlignment: HorizontalAlignment.Fill
                topPadding: -5
                bottomPadding: squareDisplay ? 10 : 50
                Label {
                    id: postId
                    text: rootContainer.data.postData
                    multiline: true
                    textStyle {
                        textAlign: TextAlign.Center
                        color: Color.Black
                    }
                    horizontalAlignment: HorizontalAlignment.Center
                }
            }
        }

I want to know the position of "sinkId" relative to the window. Its position varies depending on "preId" text length. LayoutUpdateHandler is a possible solution but layoutFrame.x or layoutFrame.y always comes zero on checking. Is there any way to get position of any visual node on/after page creation?

Sunseeker
  • 1,503
  • 9
  • 21
Shailesh
  • 490
  • 5
  • 11
  • what is `SinkButton` in you code? I guess it's a custom widget. You need to provide the code for this as well otherwise that piece of code won't have a chance to be launched – Sunseeker Jul 17 '13 at 00:13

2 Answers2

1

First, LayoutUpdateHandler reports layoutFrame properties quite well, not sure why it's not working in your case. Here is the working code demonstrating that if you want to utilise this class for your needs:

import bb.cascades 1.0

Page {
    Container {
        layout: DockLayout {}
        horizontalAlignment: HorizontalAlignment.Fill
        verticalAlignment: VerticalAlignment.Fill
        Button {
            id: button
            horizontalAlignment: HorizontalAlignment.Center
            verticalAlignment: VerticalAlignment.Center
            text: "click me"
            onClicked: {
                console.log("Button layout - x:" + layoutHandler.layoutFrame.x + ", y:" + layoutHandler.layoutFrame.y + 
                            ", width:"+ layoutHandler.layoutFrame.width + ", height: " + layoutHandler.layoutFrame.height);
            }

            attachedObjects: [
                LayoutUpdateHandler {
                    id: layoutHandler
                }
            ] 
        }
    }
}

Also, if you want to respond to touch events of your widget which I guess draggable functionality means, the best bet here would be to use a series of touch-input reactions provided by touchBehaviors which could added to any VisualNode as via QML as via C++, doesn't matter. So in order to do this, you need to create a TouchBehavior object with a defined TouchReaction with respective properties.

So, for example, for tracking touch events of some VisualNode upon receiving a touch down event until a touch up one occurs you need to define a respective touchBehaviour object and connect to the onTouch() slot of that VisualNode where you get all the events captured by your touchBehaviour event filter. Here is the code demonstrating this approach:

import bb.cascades 1.0

Page {
    Container {
        layout: DockLayout {}
        horizontalAlignment: HorizontalAlignment.Fill
        verticalAlignment: VerticalAlignment.Fill
        Button {
            id: button
            horizontalAlignment: HorizontalAlignment.Center
            verticalAlignment: VerticalAlignment.Center
            text: "click me"

            touchBehaviors: [
                TouchBehavior {
                    TouchReaction {
                        eventType: TouchType.Down
                        phase: PropagationPhase.AtTarget
                        response: TouchResponse.StartTracking
                    }
                }
            ]

            onTouch: {
                console.log("===== got touch event of type " + event.touchType + " =====");
                console.log("\twindowX - " + event.windowX);
                console.log("\twindowX - " + event.windowX);
                console.log("\twindowY - " + event.windowY);
                console.log("\tlocalX - " + event.localX);
                console.log("\tlocalY - " + event.localY);
                console.log("\n");
            }
        }
    }
}

Then you can add you logic in onTouch() slot handler.

Additional information on the subject:

Sunseeker
  • 1,503
  • 9
  • 21
0

LayoutUpdateHandler will tell you the position of your element in relation to the parent, which in the case of SinkId is a Container wrapping it. LayoutUpdateHandler will always return you 0 in this case.

Either remove the container and set the horizontalAlignment: HorizontalAlignment.Center property on sinkId directly and use a LayoutUpdateHandler, or use a LayoutUpdateHandler on the container surrounding sinkId.

Ergin Babani
  • 346
  • 1
  • 2