/////////////////////// // Sam Svensson 2013 // /////////////////////// #ifndef MISC_EVENT_BUTTON_H #define MISC_EVENT_BUTTON_H #include "IEventButton.h" namespace Oyster { namespace Event { template struct ButtonEvent { ButtonState state; IEventButton* sender; Owner owner; void* userData; }; template class EventButton : public IEventButton { protected: //typedef for callback function pointer typedef void (*EventFunc)(Oyster::Event::ButtonEvent& e); struct PrivData { PrivData() : ID(currID++){} static unsigned int currID; const unsigned int ID; ButtonState previousState; Owner owner; EventFunc eventCallback; void* userData; bool enabled; }; PrivData privData; private: //Implement this in the inherited classes for collision against that shape. virtual bool Collision(MouseInput& input) = 0; public: EventButton(); EventButton(Owner owner); EventButton(EventFunc func); EventButton(EventFunc func, Owner owner); EventButton(EventFunc func, Owner owner, void* userData); virtual ~EventButton(); void Update(MouseInput& input); //Send event to callback function void SendEvent(ButtonState state); //Set void SetEnabled(bool enable); void SetUserData(void* data); void SetEventFunc(EventFunc func); void SetOwner(Owner owner); //Get bool Enabled(); unsigned int GetID(); //EventFunc GetFunctionPointer(); Owner GetOwner(); ButtonState GetState(); bool operator ==(const EventButton& obj); }; template unsigned int EventButton::PrivData::currID = 0; template EventButton::EventButton() { this->privData.eventCallback = NULL; this->privData.userData = NULL; this->privData.previousState = ButtonState_None; this->privData.enabled = true; } template EventButton::EventButton(Owner owner) { this->privData.owner = owner; this->privData.eventCallback = NULL; this->privData.userData = NULL; this->privData.previousState = ButtonState_None; this->privData.enabled = true; } template EventButton::EventButton(EventFunc func) { this->privData.eventCallback = func; this->privData.userData = NULL; this->privData.previousState = ButtonState_None; this->privData.enabled = true; } template EventButton::EventButton(EventFunc func, Owner owner) { this->privData.owner = owner; this->privData.eventCallback = func; this->privData.userData = NULL; this->privData.previousState = ButtonState_None; this->privData.enabled = true; } template EventButton::EventButton(EventFunc func, Owner owner, void* userData) { this->privData.owner = owner; this->privData.eventCallback = func; this->privData.userData = userData; this->privData.previousState = ButtonState_None; this->privData.enabled = true; } template EventButton::~EventButton() {} //Checks for collision and template void EventButton::Update(MouseInput& input) { if(this->privData.enabled) { ButtonState currentState = ButtonState_None; static bool outside = false; static bool clicked = false; //Check for collision against the button. if(Collision(input)) { if(input.mouseButtonPressed) { //Change state when the mouse button is pressed switch(this->privData.previousState) { case ButtonState_None: outside = true; currentState = ButtonState_Hover; break; case ButtonState_Hover: if(outside == false) { clicked = true; currentState = ButtonState_Pressed; } else { currentState = ButtonState_Hover; } break; case ButtonState_Released: currentState = ButtonState_Hover; break; case ButtonState_Pressed: case ButtonState_Down: currentState = ButtonState_Down; break; default: break; } } else { outside = false; //Change state when the mouse button is NOT pressed switch(this->privData.previousState) { case ButtonState_None: case ButtonState_Hover: case ButtonState_Released: currentState = ButtonState_Hover; clicked = false; break; case ButtonState_Pressed: case ButtonState_Down: currentState = ButtonState_Released; break; default: break; } } } //Only call the callback function when the state has changed. if(this->privData.previousState != currentState) SendEvent(currentState); this->privData.previousState = currentState; } } template void EventButton::SendEvent(ButtonState state) { if(privData.eventCallback != NULL) { Oyster::Event::ButtonEvent event; event.state = state; event.sender = this; event.owner = privData.owner; event.userData = privData.userData; privData.eventCallback(event); } } //Set if the button should be updated and collided with. template void EventButton::SetEnabled(bool enable) { this->privData.enabled = enable; } template void EventButton::SetUserData(void* data) { this->privData.userData = data; } template void EventButton::SetEventFunc(EventFunc func) { this->privData.EventFunc = EventFunc; } template void EventButton::SetOwner(Owner owner) { this->privData.owner = owner; } template bool EventButton::Enabled() { return this->privData.enabled; } template unsigned int EventButton::GetID() { return this->privData.ID; } /* Something is wrong, can't return EventFunc template EventFunc EventButton::GetFunctionPointer() { return this->privData.eventCallback; }*/ template Owner EventButton::GetOwner() { return this->privData.owner; } template ButtonState EventButton::GetState() { return this->privData.previousState; } template bool EventButton::operator ==(const EventButton& obj) { return (this->privData.ID == obj.privData.ID); } } } #endif