I am pretty new to cocos2d-x.I have created a button and i wanted to change the state of the button when i tap the button . i am having trouble changing the state from play to pause similar to a music player.Below is the code.
void Gallery::buttonUI(Size visibleSize,Vec2 origin)
{
button = Button::create("play.png");
//button->loadTextures("pause.png","play.png","pause.png");
button->setPosition(Point((visibleSize.width/2)+origin.x,(visibleSize.height/2)+origin.y-80));
button->setContentSize(Size(100.0f, button->getVirtualRendererSize().height));
button->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
switch (type)
{
case Widget::TouchEventType::BEGAN:
break;
case Widget::TouchEventType::ENDED:
CCLOG("Characters: %c %c", 'a', 65);
if (!flag)
Gallery::pauseSong();
else
Gallery::resumeSong();
break;
default:
break;
}
});
this->addChild(button);
}
void Gallery::playSong()
{
CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic("1.mp3");
CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("1.mp3");
flag = false;
}
void Gallery::pauseSong()
{
CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
flag = true;
}
void Gallery::resumeSong()
{
CocosDenshion::SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
flag = false;
}
I don’t know of such methods for the ui::Button. But I don’t see the use of specific ui::Button items (capinsets, different methods for different touch events etc.) in your method also.
So, I think the MenuItemImage is better in your case:
bool flag = true;
MenuItemImage *button = MenuItemImage::create("play.png", "play_pressed.png", CC_CALLBACK_0(Gallery::playSong, this));
button->setPosition(Vec2((visibleSize.width/2)+origin.x,(visibleSize.height/2)+origin.y-80)); // better is use Vec2, Point can be ambiguous
Menu* menu = Menu::create(button, NULL); // add created button on Menu
menu ->setPosition(0,0);
this->addChild(menu);
And then set the images in handler pressing:
void Gallery::playSong()
{
if(flag)
{
// preload better move to AppDelegate.cpp
// CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic("1.mp3");
flag = false;
CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("1.mp3");
button->setNormalImage(Sprite::create(“pause.png”));
button->setSelectedImage(Sprite::create(“pause_pressed.png”)); // if you use selected image
}
else
{
flag = true;
CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
button->setNormalImage(Sprite::create(“play.png”));
button->setSelectedImage(Sprite::create(“play_pressed.png”));
}
}
In cocos 3.x use property: setHighlighted(bool)
Example:
When press a key: button->setHighlighted(true);
When release the key:
button->setHighlighted(false);
Related
So been trying my exit and play button work but they do not react the way I want them too for some strange reason. When I change one to else if and if only statement they either both exit or change them again and both start the game. They act like they are the same button and not individuals despite how they are selected and pressed.
Here is my header file:
#pragma once
#include <memory>
#include "State.h"
#include "Game.h"
#include <SFML/Graphics.hpp>
class MainMenu : public Engine::State
{
public:
enum behavior
{
HOVERED, NORMAL
};
private:
std::shared_ptr<Context> context;
sf::Text gameTitle;
sf::Text playButton;
sf::Text exitButton;
void hover(sf::RenderWindow& window, sf::Event event);
//checking certain conditions if it is true or false
bool isPlayButtonSelected;
bool isPlayButtonPressed;
bool isExitButtonSelected;
bool isExitButtonPressed;
public:
MainMenu(std::shared_ptr<Context>& context);
~MainMenu();
void Init() override;
void ProcessInput() override;
void Update(sf::Time deltaTime) override;
void Draw() override;
};
Here is the cpp file:
#include "MainMenu.h"
#include "GamePlay.h"
MainMenu::MainMenu(std::shared_ptr<Context> &context) : context(context),
isPlayButtonSelected(true), isPlayButtonPressed(false), isExitButtonPressed(false),
isExitButtonSelected(false)
{
}
MainMenu::~MainMenu()
{
}
void MainMenu::Init()
{
//our assets being put here that we stored and implement it
context -> assets ->AddFont(MainFont, "Assets/Asdonuts.ttf");
//Titlle screen name of the game code
gameTitle.setFont(context->assets->GetFont(MainFont));
gameTitle.setString("Final Game Project");
gameTitle.setOrigin(gameTitle.getGlobalBounds().width/2,
gameTitle.getGlobalBounds().height/2);
gameTitle.setPosition(context->window->getSize().x/3.5,
context->window->getSize().y/2 - 450.f);
gameTitle.setCharacterSize(150);
//This is the code for the play button
playButton.setFont(context->assets->GetFont(MainFont));
playButton.setString("Start");
playButton.setOrigin(playButton.getGlobalBounds().width/2,
playButton.getGlobalBounds().height/2);
playButton.setPosition(context->window->getSize().x/2,
context->window->getSize().y/2 - 50.f);
playButton.setCharacterSize(70);
//This is the code for the exit button
exitButton.setFont(context->assets->GetFont(MainFont));
exitButton.setString("Exit");
exitButton.setOrigin(exitButton.getGlobalBounds().width/2,
exitButton.getGlobalBounds().height/2);
exitButton.setPosition(context->window->getSize().x/2,
context->window->getSize().y/2 + 50.f);
exitButton.setCharacterSize(70);
}
//this function is when the screen is running and reads user input when pressing
//the buttons and things that happend when they press certain buttons
//while also keeping the window open till they choose to close it on the x button
//on the top right corner
void MainMenu::ProcessInput()
{
sf::Event event;
while(context->window->pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
context->window->close();
}
else if(event.type == sf::Event::KeyPressed)
{
switch(event.key.code)
{
case sf::Keyboard::Up:
{
if(!isPlayButtonSelected)
{
isPlayButtonSelected = true;
isExitButtonSelected = false;
}
break;
}
case sf::Keyboard::W:
{
if(!isPlayButtonSelected)
{
isPlayButtonSelected = true;
isExitButtonSelected = false;
}
break;
}
case sf::Keyboard::Down:
{
if(!isExitButtonSelected)
{
isPlayButtonSelected = false;
isExitButtonSelected = true;
}
break;
}
case sf::Keyboard::S:
{
if(!isExitButtonSelected)
{
isPlayButtonSelected = false;
isExitButtonSelected = true;
}
break;
}
case sf::Keyboard::Enter:
{
isPlayButtonPressed = false;
isExitButtonPressed = false;
if(!isPlayButtonPressed)
{
isPlayButtonPressed = true;
}
else if(!isExitButtonPressed)
{
isExitButtonPressed = true;
}
break;
}
default:
{
break;
}
}
}
}
}
void MainMenu::Update(sf::Time deltaTime)
{
//conditions for the menu fonts and all
//so like we know who is highlighted and not highlighted for the user to understand
//what is going on and what selection they are hovering on
if(isPlayButtonSelected)
{
playButton.setFillColor(sf::Color::Blue);
exitButton.setFillColor(sf::Color::White);
}
else
{
exitButton.setFillColor(sf::Color::Blue);
playButton.setFillColor(sf::Color::White);
}
//important thing for our main menu
//if Play button is pressed the game starts
if(isPlayButtonPressed)
{
context->states->Add(std::make_unique<GamePlay>(context), true);
}
//if the exit button is pressed, the game SHOULD exit
else if(isExitButtonPressed)
{
context->window->close();
}
}
void MainMenu::Draw()
{
//draw everything that needs to be display in the main menu
context->window->clear(sf::Color(53, 189, 164));
context->window->draw(gameTitle);
context->window->draw(playButton);
context->window->draw(exitButton);
context->window->display();
}
So an example what I mean is this one both buttons start the game but if I change it to this:
case sf::Keyboard::Enter:
{
isPlayButtonPressed = false;
isExitButtonPressed = false;
if(!isPlayButtonPressed)
{
isPlayButtonPressed = true;
}
if(!isExitButtonPressed)
{
isExitButtonPressed = true;
}
break;
}
if(isPlayButtonPressed)
{
context->states->Add(std::make_unique<GamePlay>(context), true);
}
//if the exit button is pressed, the game SHOULD exit
if(isExitButtonPressed)
{
context->window->close();
}
They will both exit and not start the game. I have been messing around one if and the other else or both as if statements. Despite the changes and testing none of the buttons act individually and act how they are supposed to act. So curious how to fix this issue?
Unsure if I should provide all my headers and cpp files for more context.
I am not really sure if I understand well your problem, but in your example it seems like isExitButtonPressed is always true at the end.
You're setting it to false at the begining and then setting it to true in the if statement which has always a fulfilled condition giving the fact that you set isExitButtonPressed to false beforehand !
I have a custom class, CustomButton that extends Fl_Button. On my screen there are a bunch of Fl_Input and CustomButton widgets that I want to be able to navigate between using a tab keypress. Tabbing between input fields works fine, but once a CustomButton gets focus, I can't seem to tab away from it.
Here's my handle function
int CustomButton::handle ( int event )
{
int is_event_handled = 0;
switch (event)
{
case FL_KEYBOARD:
// If the keypress was enter, toggle the button on/off
if (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)
{
// Do stuff...
}
is_event_handled = 1;
break;
case FL_FOCUS:
case FL_UNFOCUS:
// The default Fl_Button handling does not allow Focus/Unfocus
// for the button so mark the even as handled to skip the Fl_Button processing
is_event_handled = 1;
break;
default:
is_event_handled = 0;
break;
}
if ( is_event_handled == 1 ) return 1;
return Fl_Round_Button::handle ( event );
}
I am using fltk 1.1.10.
For a very simple, minimal example which demonstrates how to control the focus, please check the navigation.cxx test file.
Maybe your widget did get the focus (check this with Fl::focus()), but it does not show that up (you need to handle the FL_FOCUS and/or FL_UNFOCUS events)?
My problem was my CustomButton::handle() returning 1 after a FL_KEYBOARD event without actually using the tab key press.
Moving is_event_handled = 1 into the if statement lets me consume the FL_Enter keypress only and lets other widgets (i.e. the Fl_Group that controls navigation) take any other keypresses.
Alternatively get rid of the if and replace with something like
switch(Fl::event_key())
{
case FL_Enter:
case FL_KP_Enter:
// Do stuff
is_event_handled = 1;
break;
default:
is_event_handled = 0;
break;
}
I have a widget on top of my mainwindow, more like and Advertisement Banner. It is preventing the user from using some functionalities behind it so I set it to
setAttribute( Qt::WA_TransparentForMouseEvents );
But that specific ad banner has 2 buttons, and if it set as 'transparent', they can't be used obvoiusly. My question is that, how can I still use the button functionalities inside the banner of it set to transparent for mouse events?
It looks like this:
Made a solution using the Mouse Events of the said Banner Widget:
void advertisement::mouseMoveEvent(QMouseEvent *event)
{
qDebug()<< event->button();
if (isRightBtn)
{
this->setAttribute(Qt::WA_TransparentForMouseEvents);
main->_IsCamRotate = true;
main->triggerMouseMove(event);
}
}
void advertisement::mousePressEvent(QMouseEvent *event)
{
qDebug()<< event->button();
switch(event->button())
{
case Qt::MouseButton::RightButton:
isRightBtn = true;
break;
}
}
void advertisement::mouseReleaseEvent(QMouseEvent *event)
{
if (!this->rect().contains(event->pos()) && event->button() == Qt::MouseButton::RightButton)
{
main->triggerMouseRelease(event);
isRightBtn = false;
this->setAttribute(Qt::WA_TransparentForMouseEvents, false);
}
}
I'm trying get all the button child widgets of a window. The buttons were created through QDialogButtonBox. How do I get the which one is the cancel/ok/save button?
I have:
QWidget *pWin = QApplication::activeWindow();
QList<QPushButton *> allPButtons = pWin->findChildren<QPushButton *>();
QListIterator<QPushButton*> i(allPButtons);
while( i.hasNext() )
{
//identify which button is cancel/ok/save button here
/*Note: This is where I'm having trouble, getting the text of the
button here returns NULL. Any other way of Identifying which is
which?
Is it a special case when buttons are created through QDialogButtonBox?
*/
}
You should use the QDialogButtonBox::button() method, to get the button of the corresponding role.
For instance :
QPushButton* pOkButton = pButtonBox->button(QDialogButtonBox::Ok);
QPushButton* pCancelButton = pButtonBox->button(QDialogButtonBox::Cancel);
// and so on...
Generally speaking, I would say it's a bad idea to find a button from it's text, as this text might change when you app is internationalized.
One way is by text parameter from constructor such as QPushButton(const QString & text, QWidget * parent = 0):
QPushButton* buttonSave = new QPushButton("Save");
// etc..
while( i.hasNext() )
{
//identify which button is cancel/ok/save button here
if(i.next()->text() == "Save") {
// do something to save push button
}
}
Another alternative solution:
Use QDialogButtonBox's buttons function to return a list of all the buttons that have been added to the button box, then iterate over the list and identify each button using QDialogButtonBox's standardButton.
auto buttons = ui->buttonBox->buttons();
for (auto button : buttons) {
switch (ui->buttonBox->standardButton(button)) {
case QDialogButtonBox::Ok:
// do something
break;
case QDialogButtonBox::Cancel:
// do something
break;
case QDialogButtonBox::Save:
// do something
break;
default:
break;
}
}
For non-standard buttons
Map each button to an enum:
.h file:
private:
enum class NonStandardButton { Undo, Redo };
// map of non-standard buttons to enum class NonStandardButton
QHash<QAbstractButton*, NonStandardButton> buttonsMap;
.cpp file:
// in constructor
auto undoQPushButton =
ui->buttonBox->addButton("Undo", QDialogButtonBox::ActionRole);
auto redoQPushButton =
ui->buttonBox->addButton("Redo", QDialogButtonBox::ActionRole);
buttonsMap.insert(undoQPushButton, NonStandardButton::Undo);
buttonsMap.insert(redoQPushButton, NonStandardButton::Redo);
Then use QDialogButtonBox::NoButton to identify non-standard buttons:
switch (ui->buttonBox->standardButton(button)) {
case QDialogButtonBox::NoButton:
switch (buttonsMap.value(button)) {
case NonStandardButton::Undo:
// do something
break;
case NonStandardButton::Redo:
// do something
break;
default:
break;
}
default:
break;
}
Is it easy to create GLUT pop-up menus for my OpenGL application? If yes, how?
Creating and using pop-up menus with GLUT is very simple. Here is a code sample that creates a pop-up menu with 4 options:
// Menu items
enum MENU_TYPE
{
MENU_FRONT,
MENU_SPOT,
MENU_BACK,
MENU_BACK_FRONT,
};
// Assign a default value
MENU_TYPE show = MENU_BACK_FRONT;
// Menu handling function declaration
void menu(int);
int main()
{
// ...
// Create a menu
glutCreateMenu(menu);
// Add menu items
glutAddMenuEntry("Show Front", MENU_FRONT);
glutAddMenuEntry("Show Back", MENU_BACK);
glutAddMenuEntry("Spotlight", MENU_SPOT);
glutAddMenuEntry("Blend 'em all", MENU_BACK_FRONT);
// Associate a mouse button with menu
glutAttachMenu(GLUT_RIGHT_BUTTON);
// ...
return;
}
// Menu handling function definition
void menu(int item)
{
switch (item)
{
case MENU_FRONT:
case MENU_SPOT:
case MENU_DEPTH:
case MENU_BACK:
case MENU_BACK_FRONT:
{
show = (MENU_TYPE) item;
}
break;
default:
{ /* Nothing */ }
break;
}
glutPostRedisplay();
return;
}