EDIT :
J'ai trouvé. Button.cpp, ligne 34 : chkClicked=new sf::Thread(newFunc, parent);
Par contre, je ne vois pas en quoi j'ai donné trop d'arguments...
Bonjour,
Je suis bloqué sur une erreur que je ne comprends pas :
SFML-2.1\include\SFML\System\Thread.inl || In instantiation of 'void sf::priv::ThreadFunctorWithArg<F, A>::run() [with F = void (*)(); A = MWindow*]':
Button.cpp |145| required from here
SFML-2.1\include\SFML\System\Thread.inl |48| error: too many arguments to function
MWindow.h :
#ifndef MWINDOW_H
#define MWINDOW_H
#include <SFML/Graphics.hpp>
#include <vector>
class MWindow;
class Button : public sf::Sprite
{
friend class MWindow;
public:
Button(std::string const& adress, std::string const& adressO=std::string(), std::string const& adressL=std::string(), std::string const& adressD=std::string());
virtual ~Button();
bool setParent(MWindow *newParent = nullptr, void (*newFunc)() = nullptr);
// Sets 'parent' to newParent. If newParent is null, the button is disabled and ID is set to -1. Else it is enabled.
// Returns true if the parent has been successfully changed, else false.
MWindow* getParent();
// Returns 'parent' member.
virtual void setEnabled(bool yay);
// Sets the 'enabled' value to yay and changes de texture in consequences. An hidden button cannot be enabled.
bool getEnabled();
// Returns the 'enabled' member value
virtual void setHidden(bool hide);
// Sets the 'hidden' member to hide. If true, texture is set to 'texture', else to an empty texture.
// An hidden button is also disabled. Unhidde a button automatically re-enables it.
bool getHidden();
// Returns the 'hidden' member value
void changeTexture(std::string const& adress);
// texture.loadFromFile(adress);
void changeTextureOver(std::string const& adress=std::string());
// Give it an empty string and textureOver will be set with 'texture'
void changeTextureLeaned(std::string const& adress=std::string());
// Give it an empty string and textureLeaned will be set with 'texture'
void changeTextureDisabled(std::string const& adress=std::string());
// Give it an empty string and textureDisabled will be set with 'texture'
protected:
void checkClicked();
// Uses the sf::Event event to verify if the mouse is over the button and if the user clicks on
MWindow *parent;
sf::Texture texture, textureOver, textureLeaned, textureDisabled;
sf::Thread *chkClicked;
bool enabled, mouseOver, leaned, hidden;
int ID;
};
/////////////////////////////////////// MWindow ///////////////////////////////////////
class MWindow
{
friend class Button;
public:
MWindow(int x = 800, int y = 600, std::string const& title = "Main Window", bool deletebuttons = true, sf::ContextSettings const& settings = sf::ContextSettings());
/* Arguments :
* 'title' is simply the title of the window.
* 'deletebuttons' : if true, the buttons in the vector 'buttons' will be deleted in the destructor.
* 'x' ans 'y' are respectively the width and the height of the window
*/
MWindow(sf::RenderWindow *windowPtr, bool deletebuttons = true);
virtual ~MWindow();
virtual void startEventLoop();
bool addButton(Button *button, void (*func)());
// Returns true if the button is successfully added, false if the button was already in the window
bool removeButton(Button *button);
// Returns true if the button is successfully removed from the window, false if the button was not in the window.
// Note that this function does NOT delete the button.
bool removeButton(int index);
// Overload of removeButton(). Remove the Button at the 'index' position. Return true if successful, false if the 'index' position does not exist.
protected:
virtual void update();
// clear-draw-display function
virtual void checkButtons();
// checks if
sf::RenderWindow *window;
sf::Thread checkBtns;
std::vector<Button*> buttons;
std::vector<void (*)()> functions;
bool deleteButtons;
sf::Event event;
};
#endif // MWINDOW_H
MWindow.cpp :
#include "MWindow.h"
MWindow::MWindow(int x, int y, std::string const& title, bool deletebuttons, ContextSettings const& settings) : \
window(new sf::RenderWindow(sf::VideoMode(x,y), title, sf::Style::Titlebar | sf::Style::Close, settings)), \
checkBtns(&MWindow::checkButtons, this), buttons(), deleteButtons(deletebuttons)
{
checkBtns.launch();
}
MWindow::MWindow(sf::RenderWindow *windowPtr, bool deletebuttons) : window(windowPtr), checkBtns(&MWindow::checkButtons, this), buttons(), deleteButtons(deletebuttons)
{
checkBtns.launch();
}
MWindow::~MWindow()
{
if(deleteButtons)
{
for(int i(0) ; i < (int)buttons.size() ; i++)
delete buttons[i];
}
else
{
for(int i(0) ; i < (int)buttons.size() ; i++)
if(buttons[i] != nullptr)
buttons[i].ID=-1;
}
}
MWindow& MWindow::operator=(const MWindow& rhs)
{
if (this == &rhs) return *this; // handle self assignment
//assignment operator
return *this;
}
void MWindow::startEventLoop()
{
while(window->isOpen())
{
update();
while(window->pollEvent(event))
{
if(event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseButtonReleased || event.type == sf::Event::MouseMoved)
{
for(int i(0) ; i < (int)buttons.size() ; i++)
if(buttons[i] != nullptr && buttons[i]->getEnabled())
buttons[i]->checkClicked(event);
}
}
}
}
bool MWindow::addButton(Button *button, void (*func)())
{
for(int i(0) ; i < (int)buttons.size() ; i++)
if(buttons[i] == button)
return false;
if(buttons.empty())
{
buttons.push_back(button);
button->ID=0;
functions.push_back(func);
return;
}
for(int i(0) ; i < (int)buttons.size() ; i++)
{
if(buttons[i] == nullptr)
{
buttons[i]=button;
button->ID=i;
functions[i]=func;
}
}
buttons.push_back(button);
button->ID=buttons.size()-1;
functions.push_back(func);
return true;
}
bool MWindow::removeButton(Button *button)
{
for(int i(0) ; i < (int)buttons.size() ; i++)
{
if(buttons[i] == button)
{
buttons[i]->setParent(nullptr);
buttons[i] = nullptr;
return true;
}
}
return false;
}
bool MWindow::removeButton(int index)
{
try
{
buttons.at(index)->setParent(nullptr);
buttons.at(index) = nullptr;
}
catch (std::out_of_range const& exc) // My compiler (GCC 4.7.1) does not want of std::out_of_range or std::logic_error...why ?
{
return false;
}
return true;
}
void MWindow::update()
{
window->clear();
for(int i(0) ; i < (int)buttons.size(); i++)
if(buttons[i]!=nullptr)
window->draw(*buttons[i]);
window->display();
}
Button.cpp :
#include "MWindow.h"
Button::Button(std::string const& adress, std::string const& adressO, std::string const& adressL, std::string const& adressD) : \
parent(nullptr), texture(), textureOver(), textureLeaned(), textureDisabled(), chkClicked(new sf::Thread(&Button::checkClicked, this)), \
enabled(false), mouseOver(false), leaned(false), hidden(false), ID(-1)
{
changeTexture(adress);
changeTextureOver(adressO);
changeTextureLeaned(adressL);
changeTextureDisabled(adressD);
}
Button::~Button()
{
delete chkClicked;
}
bool Button::setParent(MWindow *newParent, void (*newFunc)())
{
if(!newParent->addButton(this, newFunc))
return false;
delete chkClicked;
parent=newParent;
if(parent == nullptr || newFunc == nullptr)
{
setEnabled(false);
ID=-1;
return false;
}
else
{
setEnabled(true);
chkClicked=new sf::Thread(newFunc, parent);
}
return true;
}
MWindow* Button::getParent()
{
return parent;
}
void Button::setEnabled(bool yay)
{
if((enabled && yay) || hidden)
{
return;
}
else if(yay)
{
enabled=true;
chkClicked->launch();
}
else
{
enabled=false;
setTexture(textureDisabled);
}
}
bool Button::getEnabled()
{
return enabled;
}
void Button::setHidden(bool hide)
{
if(hide)
{
setEnabled(false);
setTexture(sf::Texture());
hidden=true;
}
else
{
hidden=false;
setEnabled(true);
}
}
bool Button::getHidden()
{
return hidden;
}
void Button::changeTexture(std::string const& adress)
{
texture.loadFromFile(adress);
}
void Button::changeTextureOver(std::string const& adress)
{
textureOver.loadFromFile(adress);
}
void Button::changeTextureLeaned(std::string const& adress)
{
textureLeaned.loadFromFile(adress);
}
void Button::changeTextureDisabled(std::string const& adress)
{
textureDisabled.loadFromFile(adress);
}
void Button::checkClicked()
{
while(enabled)
{
if(parent->event.type == sf::Event::MouseMoved)
{
if(getGlobalBounds().contains(sf::Vector2<float>(parent->event.mouseMove.x, parent->event.mouseMove.y)))
{//if the mouse is in the button...
mouseOver=true;
setTexture(textureOver);
}
else
{
mouseOver=false;
setTexture(texture);
}
}
else if(parent->event.type == sf::Event::MouseButtonPressed && parent->event.mouseButton.button == sf::Mouse::Right && mouseOver)
{
leaned=true;
setTexture(textureLeaned);
}
else if(parent->event.type == sf::Event::MouseButtonReleased && parent->event.mouseButton.button == sf::Mouse::Right && leaned)
{
if(getGlobalBounds().contains(sf::Vector2<float>(parent->event.mouseButton.x, parent->event.mouseButton.y)))
{
setTexture(textureOver);
parent->functions[ID]();
}
else
{
setTexture(texture);
mouseOver=false;
}
leaned=false;
}
}
} // In instantiation of 'void sf::priv::ThreadFunctorWithArg<F, A>::run() [with F = void (*)(); A = MWindow*]': required from here
Merci d'avance pour vos éclaircissements.