Gwtquery stop parent from being draggable - draggable

I am working on a rotatable plugin for gwtquery. The idea is to create a seating chart app for teacher. Any how I can now get an element to rotate if as long as its not draggable.
What the plugin does is appends a child and makes the child draggable and uses the x and y from screen to get atan2 radians from a center point ... the parent's center point. If the parent is constantly moving then the ceterpoint isn't fixed and thus no rotation.
I've tried the following to trying and disable the parent but to no avail
private final DragFunction start = new DragFunction(){
#Override
public void f(DragContext context) {
//check to see if parent is draggable
DraggableOptions disable = new DraggableOptions();
disable.setDisabled(true);
$(context.getDraggable()).css($$("background-color:Magenta"));
$(context.getDraggable()).parent().css($$("border: 3px solid Magenta"));
//The parent's border indeed turned magenta
//but the draggable parent was not disable :{
$(context.getDraggable()).parent().as(Draggable).options(disable);
$(document).on("mousemove.rotatable", new Function(){
#Override
public boolean f(Event e){
e.stopPropagation();
e.preventDefault();
mouseCoords = new Point( e.getScreenX(), e.getScreenY());
angle = radToDeg(getAngle(mouseCoords, centerCoords));
rotate(angle);
rotating = true;
return true;
}
});
};// end start
};
Any help at all is greatly appreciated

The question is "why is the parent draggable if you don't need that ?"
If you realy need that the parent is draggable, the best in your case is to add a dragFunction to the parent that are checking the value of a boolean. If this boolean is false, throws a StopDragException to stop the drag of the parent.
Set this boolean to false in your start function above. And set back this boolean to true when the child stops to drag.

Related

Javafx relocate and rotate

i have an node in javafx which are moving in a timeline.
Now i want rotate the node also.
I tried it but everytime the node doesn't hold the path anymore and "fly away". Is there a way to relcate and rotate (I tried it with rotatetransition)?
Edit:
That is my View -Class
public class MyView extends ImageView{
public MyView (Image image) {
super(image);
RotateTransition transition = new RotateTransition();
transition.setCycleCount(Animation.INDEFINITE);
transition.setNode(this);
transition.setDuration(Duration.millis(10));
transition.setFromAngle(5);
transition.setToAngle(5;
transition.setAutoReverse(true);
transition.play(); // */
}
}
On another class i have this:
private void startMoveAnimation(MyView[] views) {
x++;
y++;
this.timeline = new Timeline();
timeline.setCycleCount(Animation.INDEFINITE);
moveEvent = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
for(View view: views){
view.relocate(x,y);
}
}
}
};
KeyFrame moveKeyFrame = new KeyFrame(Duration.millis(SPEED), moveEvent);
timeline.getKeyFrames().add(moveKeyFrame);
timeline.play(); // */
}
x and y are double values.
Using transforms gives you better control of the order of the transformations. Furthermore some transfroms allow you to specify a pivot point, which is not possible for e.g. the Node.rotate property. Transforms in a list are applied "right to left". (The transform with the highest index is applied first).
The following example shows how to move a rectangle rotating arount its own center (even though the cycle resets to the original position instead of continuously moving in the same direction, but the properties of the transforms can be animated independently in arbitrary ways):
#Override
public void start(Stage primaryStage) {
Rectangle view = new Rectangle(100, 100);
// pivot point = center of rect
Rotate rotate = new Rotate(0, 50, 50);
Translate translate = new Translate();
// rotate first, then move
view.getTransforms().addAll(translate, rotate);
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(translate.xProperty(), 0d),
new KeyValue(translate.yProperty(), 0d), new KeyValue(rotate.angleProperty(), 0d)),
new KeyFrame(Duration.seconds(2), new KeyValue(translate.xProperty(), 300d),
new KeyValue(translate.yProperty(), 500d), new KeyValue(rotate.angleProperty(), 360d)));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
Pane root = new Pane(view);
Scene scene = new Scene(root, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
That's what I would try first:
Put the node into a Group. Add the Group to the parent instead of the node. Do the translate animation on the Group and do the rotate animation on the node itself. This is just a first guess which I cannot try out because you haven't provided a minimal reproducible example.

Unity3D Draggable GUI.Box with GUI controls

I'm constructing a custom node editor window in Unity, and I've had a look at various resources such as this one, which uses GUI.Box to construct node windows.
This works great, and I'm able to drag these windows around the way I want, however once I add controls to the GUI.Box, I want them to override the Drag() function I've written.
Here's an example of the issue - When I move the vertical slider up, the entire box drags with it.
Is there a way to fix this behavior using GUI.Box, or should I go back to GUI.Window with its built-in GUI.DragWindow()?
Here's a simplified version of the code I'm using:
EditorMouseInput.cs:
private bool ActionLeftMouseDown()
{
mouseDownNode = editor.GetSelectedNode(Input.current.mousePosition);
if (mouseDownNode == null)
editor.StartMovingEditorCanvas();
else
mouseDownNode.IsSelected = true;
}
BaseNodeEditor.cs:
public BaseNode GetSelectedNode(Vector2 mousePos)
{
foreach (BaseNode node in Nodes)
{
if (node.WindowRect.Contains(mousePos))
return node;
}
return null;
}
public void Drag(Vector2 delta)
{
if (!MoveEditorMode && !ConnectionMode)
{
foreach (BaseNode node in Nodes)
{
node.Drag(delta);
}
}
BaseNode.cs:
public void Drag(Vector2 delta)
{
if (IsSelected)
draggedDistance += delta;
}
The vertical slider is added in the derived JumpNode class. Extract of the helper class that constructs the slider:
Vector2 pos = node.WindowRect.position + rect.position * GridSpacing;
value = GUI.VerticalSlider(new Rect(pos, rect.size * GridSpacing), value, maxValue, minValue);
I can see why this doesn't do what I want, but I don't know how to go about it given the GUI controls aren't part of the GUI.Box.
Any help or suggestions, even a nudge towards another source would be greatly appreciated - I feel I've used all the search terms that exist in my head!
Edit - Solved: Thanks to Kleber for solving this one for me. In case anyone else runs into this or a similar issue, the solution for me was in realising that GUI controls consume left mousedown events automatically, so clicking a slider means there's no propagation to the Box to check if it was clicked.
What I needed to do was separate the IsSelected and IsDragged flags in the Node class, and clear IsDragged on mouseUp. I originally used IsSelected to flag both drag enabled, and selected (multiple nodes could be selected and dragged at once).
It's quite a complex tutorial so I didn't read it entirely, but the problem seems to be the MouseDrag detection. Well, basically you want to stop the event propagation when you click on a GUI element inside the Box, right? To do so, you call:
Event.current.Use()
every time the user drags the mouse on one of your components.
Using the resource you've mentioned, I altered the Node class and added a slider inside the Draw() method, ending like this:
public void Draw() {
inPoint.Draw();
outPoint.Draw();
GUI.Box(rect, title, style);
GUI.BeginGroup(rect);
_value = GUI.HorizontalSlider(new Rect(20, 0, 50, 20), _value, 100, -100);
GUI.EndGroup();
}
Another thing you can do is change how you draw your window. Here it's a simple example that I've tested on the latest Unity version (5.6):
private void OnGUI() {
GUI.Box(_rect, string.Empty);
GUI.BeginGroup(_rect);
_value = GUI.VerticalSlider(new Rect(145, 100, 20, 100), _value, 100, -100);
GUI.EndGroup();
var e = Event.current;
if (e.type == EventType.MouseDrag && _rect.Contains(e.mousePosition)) {
_rect.x += e.delta.x;
_rect.y += e.delta.y;
Repaint();
}
}
As you can see, this example doesn't need an Event.current.Use() to work properly.

Add Image dynamically in runtime - Unity 5

In my unity based Android game I wish to add the image dynamically based on the number of questions in each level. The image is shown for reference. Each correct answer will be marked in green and the wrong one in red. I am new to unity and trying hard to find steps to achieve this.
Any help with an example for this requirement will be a great help.
I once wrote a script for dynamically creating buttons based on each level. What I did was creating the first button on the scene and adding the other buttons based on the first one. Below is the shell of my code:
// tutorialButton and levelButtons are public variables which can be set from Inspector
RectTransform rect = tutorialButton.GetComponent<RectTransform> ();
for (int i = 1; i < levelSize; i++) {
// Instantiate the button dynamically
GameObject newButton = GameObject.Instantiate (tutorialButton);
// Set the parent of the new button (In my case, the parent of tutorialButton)
newButton.transform.SetParent (levelButtons.transform);
//Set the scale to be the same as the tutorialButton
newButton.transform.localScale = tutorialButton.transform.localScale;
//Set the position to the right of the tutorialButton
Vector3 position = tutorialButton.transform.localPosition;
position.x += rect.rect.width*i;
newButton.transform.localPosition = position;
}
I am not exactly sure if this is the right approach as it may or may not give unexpected results depending on different screen sizes and your canvas, but hopefully it gives you an idea about dynamically creating objects.
I'm not sure if this helps, but if you have all the images in the scene under a canvas, with this you just need to drag the canvas on the script and use
//level-1 is to keep the array notation
FindObjectOfType<NameOfScript>.ChangeColor(level-1,Color.green);
or you can do also
//level-1 is to keep the array notation
FindObjectOfType<NameOfScript>.RevertColor(level - 1);
This is the script:
//Keep it private but you still see it in inspector
//#Encapsulation :)
[SerializeField]
private Canvas _canvas;
private Image[] _images;
//keep the original colors in case you want to change back
private Color[] _origColors;
void Start () {
_images = GetComponentsInChildren<Image>();
_origColors = new Color[_images.Length];
for (int i = 0; i < _images.Length; i++)
{
_origColors[i] = _images[i].color;
}
}
//Reverts the color of the image back to the original
public void RevertToOriginal(int imageIndex)
{
_images[imageIndex].color = _origColors[imageIndex];
}
//Change to color to the coresponding index, starts from 0
public void ChangeColor(int imageIndex, Color color)
{
_images[imageIndex].color = color;
}
P.S If you want it visible only at the end you can make a method where you enable = (true or false) for the canvas. So you keep it false till the end of the level and you make it true when you want to show, while after every answer you call the ChangeColor depending on the result.
To make it easier you can use:
NameOfScript variableName = FindObjectOfType<NameOfScript>();
and after that you just call
variableName.ChangeColor(level - 1, Color.green);
Also it does not matter where you put the script. I would make some kind of manager(empty GameObject) in the scene and put it there.

Changing alpha of Text's CanvasGroup in OnTriggerEnter Unity

I'm currently working on a game that pays hommage to Marble Blast Gold/Ultra.
At this point I have text that is positioned with the marble. The text is a child of a canvas and I have a canvas group added to the text. I initially set the alpha of the canvas group to 0 so that you can't see the text.
What I'm trying to do is have it so that when you pick up a power up the text reappears by changing the canvas group's alpha back to 1 and then once the power up is used set it back to 0.
I'm not seeming to have any luck with my current code.
// Super Jump pickup
if (col.gameObject.tag == "Spring")
{
superJumpText.GetComponent<CanvasGroup>().alpha = 1;
canSuperJump = true;
canSuperSpeed = false;
col.gameObject.SetActive(false);
hitSuperJump = true;
Invoke("Display", 20);
}
void Update()
{
//super jump
if (canSuperJump)
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
Vector3 jump = new Vector3(0, superJumpForce, 0);
GetComponent<Rigidbody>().AddForce(jump);
canSuperJump = false;
superJumpText.GetComponent<CanvasGroup>().alpha = 0;
}
}
}
The only reason this would not work for you is that somewhere in your parent hierarchy you have a gameobject with another canvas group. That would ALWAYS override the child canvas group settings UNLESS you select the 'Ignore Parent Groups' checkbox in the child canvas

How to detect a collision between one object and multiple objects in XNA 4.0 C#?

I am new to XNA and CSharp programming so I want to learn to make a treasure hunting game as a beginning so I made a player(as a class) which can walk up, down, left and right. I made a Gem class also which the player can collide with and the gem disappears and a sound is played. But I want to make some walls that the player can collide with and stop so I made a class called Tile.cs (The wall class) and I made a void in it
public void CollideCheck(bool tWalk, bool bottomWalk, bool leftWalk, bool rightWalk, Rectangle topRect, Rectangle bottomRect, Rectangle rightRect, Rectangle leftRect)
{
colRect = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);
if (this.colRect.Intersects(topRect))
{
tWalk = false;
}
else
tWalk = true;
if (this.colRect.Intersects(bottomRect))
{
bottomWalk = false;
}
else
bottomWalk = true;
if (this.colRect.Intersects(leftRect))
{
leftWalk = false;
}
else
leftWalk = true;
if (this.colRect.Intersects(rightRect))
{
rightWalk = false;
}
else
rightWalk = true;
}
Then, in the Game1.cs (The main Class) I made an array of "Tiles":
Tile[] tiles = new Tile[5];
And in the update void I made this:
foreach (Tile tile in tiles)
{
tile.CollideCheck(player.topWalk, player.bottomWalk, player.leftWalk, player.rightWalk,
new Rectangle((int)player.Position.X, (int)player.Position.Y - (int)player.Speed.Y, player.currentAnim.FrameWidth, player.currentAnim.FrameHeight),
new Rectangle((int)player.Position.X, (int)player.Position.Y + (int)player.Speed.Y, player.currentAnim.FrameWidth, player.currentAnim.FrameHeight),
new Rectangle((int)player.Position.X + (int)player.Speed.X, (int)player.Position.Y, player.currentAnim.FrameWidth, player.currentAnim.FrameHeight),
new Rectangle((int)player.Position.X - (int)player.Speed.X, (int)player.Position.Y, player.currentAnim.FrameWidth, player.currentAnim.FrameHeight));
}
All those rectangles are the borders of the player but when I run the game the player doesn't collide with it so is there any way to fix this?
I can post the project if I am not very clear.
Your parameters are in only, but you set their values inside the call. You have to declare them as out variables so that their value is sent back to the caller. Using out also makes sure you always set a value to them before exiting the function.
So change your function declaration to public void CollideCheck(out bool tWalk, out bool bottomWalk, out bool leftWalk, out bool rightWalk, Rectangle topRect, Rectangle bottomRect, Rectangle rightRect, Rectangle leftRect) and you get the values back.

Resources