KeyUp/KeyDown is only caught once - libgdx

I am trying to display a Dialog every time the keys BACK or SCAPE are pressed. However the event is only been caught once, dialog is shown but if I close it by pressing my button NO, then it will never appear again until I go to another screen.
This is how I catch the KeyUp event:
#Override
public boolean keyUp(int keycode) {
if (keycode == Keys.BACK || keycode == Keys.ESCAPE) {
dialog.setVisible(true);
}
return false;
}
This is my button inside of the Dialog:
btnNo.addListener(
new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
{
return true;
}
public void touchUp(InputEvent event, float x, float y, int pointer, int button){
dialog.setVisible(false);
}
});
If you have any idea ,please let me know...

Check out the following site they have clear description on how to use Dialog in LibGDX http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Dialog.html

My issue has been resolved with the following block code in the Render():
if (Gdx.input.isKeyPressed(Keys.BACK) || Gdx.input.isKeyPressed(Keys.ESCAPE)){
Gdx.input.setCatchBackKey(true);
dialog.setVisible(true);
}

Related

panStop method of GestureListener interface never called

I'm implementing GestureListener interface for detecting touch events and everything works well except that panStop method is never called. It looks like:
public boolean panStop(float x, float y, int pointer, int button) {
initialZoom = pg.zoom;
hud.released();
return false;
}
But, as I said it's never called. Pan is working well, just, when I stop panning and lift my finger nothing happens. What I did wrong here? Do I have to call super methods in my implemented methods maybe?
Basically I have to detect when user lifts it's finger from the screen. There is touchDown method but not touchUp ?!?
if you want to use touchup you have to call :
Gdx.input.setInputProcessor(new InputProcessor() {
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return true;
}
}
for the panStop() i think you need to put the return to True instead of
return false
Hope this was helpful
good luck !
Edit : try this
public boolean panStop(float x, float y, int pointer, int button) {
initialZoom = pg.zoom;
hud.released();
return true;
}

How to check if Tree was hit or not in libgdx scene2d?

Basically all I want is to clear selection of the tree if user clicked not on the tree. My current code is:
entityTree.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
if (entityTree.getNodeAt(y) == null) {
entityTree.getSelection().clear();
}
}
});
But it doesn't work for two reasons:
clicked is only called if the tree is actually clicked. If click happens on some button or wherever else, the tree doesn't get a click event.
Current code checks only y-component. It should be combined with code that checks if tree boundaries are hit.
tree.getStage().addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (tree.getStage().hit(x, y, true) != tree || tree.getNodeAt(y) == null)
tree.getSelection().clear();
return false;
}
});

How to detect when drag input is end in libgdx

I don't know how to detect when the user drag event is end or not so I decide to do like this
protected class Input extends DragListener{
boolean dragging=false;
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
return true;
}
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
if(!dragging)dragging=true;
*my game logic*
.
.
.
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("touch up","");
if (dragging) {
*my game logic*
.
.
.
}
}
}
I try my class by drag and touch up ,nothing happen.
I drag again and nothing happen. then I tap and the console is print "touchUp" two time.
Is there anything else to detect it
In the interface GestureListener that resides in GestureDetector there is a method pan and panStop. You should implement that interface, add all the methods from it and use pan for your dragging behaviour and panStop for the solution to your question. The methods register for both touch and mouse as well as multiple finger touches.

Disabling a TextButton

I am trying to disable a TextButton that I've coded as follows:
// Setup new game button
final TextButton newGameButton = new TextButton("New Game", style);
newGameButton.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
Tyr.getInstance().setScreen(new GameScreen());
AudioHelper.stopMusic();
return true;
}
});
table.add(newGameButton).spaceBottom(BUTTON_SPACE);
table.row();
However, the "setDisabled(true)" function doesn't seem to be working. Is there some other way that I can accomplish this task?
Found a solution: "newGameButton.setTouchable(Touchable.disabled);"

CCScrollView with CCControlButton. How to control the touch area?

I have CCScrollView with container with CCControlButtons, when the buttons scroll out of the visible CCScrollView area, They are also can be touched too. How can I control the area ?
Inspired by Tomasz's answer, I created an alternative solution, also inheriting from CCControlButton:
bool ScrollableButton::isTouchInside(CCTouch *touch) {
return !dragging && CCControlButton::isTouchInside(touch);
}
bool ScrollableButton::ccTouchBegan(CCTouch *touch, CCEvent *event) {
dragging = false;
return CCControlButton::ccTouchBegan(touch, event);
}
void ScrollableButton::ccTouchMoved(CCTouch *touch, CCEvent *event) {
if (!dragging && ccpDistance(touch->getLocation(), touch->getStartLocation()) > 25) {
dragging = true;
}
CCControlButton::ccTouchMoved(touch, event);
}
void ScrollableButton::ccTouchEnded(CCTouch *touch, CCEvent *event) {
CCControlButton::ccTouchEnded(touch, event);
dragging = false;
}
void ScrollableButton::ccTouchCancelled(CCTouch *touch, CCEvent *event) {
CCControlButton::ccTouchCancelled(touch, event);
dragging = false;
}
The secret sauce is the override of the isTouchInside function, which will return false even if the touch is inside, but was moved. This way, the button will also release its "zoomed" state as soon as you start scrolling.
It also adds a small tolerance factor, so if the touch moves just a little, it's still considered a "click". This factor is hardcoded at 25 in the example above.
My problems:
There is a scrollView with many buttons (items). Above it there are 2 function buttons (return, start).
When I scroll down item buttons overlie function buttons. When I swallow all touches above my scrollview I will lose my function buttons. So I have to find another solution.
When I start draging scroll view a item button is pressed. When I ended the button action will be execute. This is very annoying.
But there is the solution. I have created new CCControlButton. It checks whether was clicked outside scrollview or was dragged. The button is used for items buttons.
bool ControlButtonForScrolling::checkIfTouchIsInsideScrollView(CCTouch *pTouch)
{
CCPoint touchLocation = pTouch->getLocation(); // Get the touch position
touchLocation = _scrollView->getParent()->convertToNodeSpace(touchLocation);
CCRect bBox=_scrollView->boundingBox();
bool result = bBox.containsPoint(touchLocation);
return result;
}
bool ControlButtonForScrolling::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
bool isInside = this->checkIfTouchIsInsideScrollView(pTouch);
if (isInside) {
return CCControlButton::ccTouchBegan(pTouch, pEvent);
}
else
{
return false;
}
}
void ControlButtonForScrolling::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
CCControlButton::ccTouchMoved(pTouch, pEvent);
_scrollWasDragged = true; // information about dragging is stored to prevent sending action
}
void ControlButtonForScrolling::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
// this method is a copy of CCControlButton::ccTouchEnded except lines with _scrollWasDragged
m_eState = CCControlStateNormal;
m_isPushed = false;
setHighlighted(false);
if (!_scrollWasDragged)
{
if (isTouchInside(pTouch))
{
sendActionsForControlEvents(CCControlEventTouchUpInside);
}
else
{
sendActionsForControlEvents(CCControlEventTouchUpOutside);
}
}
_scrollWasDragged = false;
}