2015-08-31 22:25:10 +00:00
|
|
|
#include "MicroBit.h"
|
2015-08-12 10:53:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
2015-08-31 22:25:10 +00:00
|
|
|
* Create a representation of a virtual button, that generates events based upon the combination
|
2015-08-12 10:53:41 +00:00
|
|
|
* of two given buttons.
|
|
|
|
* @param id the ID of the new MultiButton object.
|
|
|
|
* @param button1 the ID of the first button to integrate.
|
|
|
|
* @param button2 the ID of the second button to integrate.
|
|
|
|
* @param name the physical pin on the processor that this butotn is connected to.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* @code
|
|
|
|
* multiButton(MICROBIT_ID_BUTTON_AB, MICROBIT_ID_BUTTON_A, MICROBIT_ID_BUTTON_B);
|
|
|
|
* @endcode
|
|
|
|
*
|
|
|
|
* Possible Events:
|
|
|
|
* @code
|
|
|
|
* MICROBIT_BUTTON_EVT_DOWN
|
|
|
|
* MICROBIT_BUTTON_EVT_UP
|
|
|
|
* MICROBIT_BUTTON_EVT_CLICK
|
|
|
|
* MICROBIT_BUTTON_EVT_LONG_CLICK
|
|
|
|
* MICROBIT_BUTTON_EVT_HOLD
|
|
|
|
* @endcode
|
|
|
|
*/
|
2015-11-23 19:46:20 +00:00
|
|
|
MicroBitMultiButton::MicroBitMultiButton(uint16_t id, uint16_t button1, uint16_t button2, MicroBitMessageBus &messageBus)
|
2015-08-12 10:53:41 +00:00
|
|
|
{
|
|
|
|
this->id = id;
|
|
|
|
this->button1 = button1;
|
|
|
|
this->button2 = button2;
|
2016-02-26 15:42:57 +00:00
|
|
|
this->eventConfiguration = MICROBIT_BUTTON_SIMPLE_EVENTS;
|
2015-08-12 10:53:41 +00:00
|
|
|
|
2015-11-23 19:46:20 +00:00
|
|
|
messageBus.listen(button1, MICROBIT_EVT_ANY, this, &MicroBitMultiButton::onButtonEvent, MESSAGE_BUS_LISTENER_IMMEDIATE);
|
|
|
|
messageBus.listen(button2, MICROBIT_EVT_ANY, this, &MicroBitMultiButton::onButtonEvent, MESSAGE_BUS_LISTENER_IMMEDIATE);
|
2015-08-12 10:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t MicroBitMultiButton::otherSubButton(uint16_t b)
|
|
|
|
{
|
|
|
|
return (b == button1 ? button2 : button1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int MicroBitMultiButton::isSubButtonPressed(uint16_t button)
|
|
|
|
{
|
|
|
|
if (button == button1)
|
|
|
|
return status & MICROBIT_MULTI_BUTTON_STATE_1;
|
|
|
|
|
|
|
|
if (button == button2)
|
|
|
|
return status & MICROBIT_MULTI_BUTTON_STATE_2;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int MicroBitMultiButton::isSubButtonHeld(uint16_t button)
|
|
|
|
{
|
|
|
|
if (button == button1)
|
|
|
|
return status & MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
|
|
|
|
|
|
|
|
if (button == button2)
|
|
|
|
return status & MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-31 10:27:38 +00:00
|
|
|
int MicroBitMultiButton::isSubButtonSupressed(uint16_t button)
|
|
|
|
{
|
|
|
|
if (button == button1)
|
|
|
|
return status & MICROBIT_MULTI_BUTTON_SUPRESSED_1;
|
|
|
|
|
|
|
|
if (button == button2)
|
|
|
|
return status & MICROBIT_MULTI_BUTTON_SUPRESSED_2;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2015-08-12 10:53:41 +00:00
|
|
|
|
|
|
|
void MicroBitMultiButton::setButtonState(uint16_t button, int value)
|
|
|
|
{
|
|
|
|
if (button == button1)
|
|
|
|
{
|
|
|
|
if (value)
|
|
|
|
status |= MICROBIT_MULTI_BUTTON_STATE_1;
|
|
|
|
else
|
|
|
|
status &= ~MICROBIT_MULTI_BUTTON_STATE_1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (button == button2)
|
|
|
|
{
|
|
|
|
if (value)
|
|
|
|
status |= MICROBIT_MULTI_BUTTON_STATE_2;
|
|
|
|
else
|
|
|
|
status &= ~MICROBIT_MULTI_BUTTON_STATE_2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MicroBitMultiButton::setHoldState(uint16_t button, int value)
|
|
|
|
{
|
|
|
|
if (button == button1)
|
|
|
|
{
|
|
|
|
if (value)
|
|
|
|
status |= MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
|
|
|
|
else
|
|
|
|
status &= ~MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (button == button2)
|
|
|
|
{
|
|
|
|
if (value)
|
|
|
|
status |= MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
|
|
|
|
else
|
|
|
|
status &= ~MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-31 10:27:38 +00:00
|
|
|
void MicroBitMultiButton::setSupressedState(uint16_t button, int value)
|
|
|
|
{
|
|
|
|
if (button == button1)
|
|
|
|
{
|
|
|
|
if (value)
|
|
|
|
status |= MICROBIT_MULTI_BUTTON_SUPRESSED_1;
|
|
|
|
else
|
|
|
|
status &= ~MICROBIT_MULTI_BUTTON_SUPRESSED_1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (button == button2)
|
|
|
|
{
|
|
|
|
if (value)
|
|
|
|
status |= MICROBIT_MULTI_BUTTON_SUPRESSED_2;
|
|
|
|
else
|
|
|
|
status &= ~MICROBIT_MULTI_BUTTON_SUPRESSED_2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-26 15:42:57 +00:00
|
|
|
/**
|
|
|
|
* Changes the event configuraiton of this button to the given value.
|
|
|
|
* All subsequent events generated by this button will then be informed by this configuration.
|
|
|
|
*
|
|
|
|
* @param config the new configuration for this button. legal values are MICROBIT_BUTTON_ALL_EVENTS or MICROBIT_BUTTON_SIMPLE_EVENTS.
|
|
|
|
*
|
|
|
|
* example:
|
|
|
|
* @code
|
|
|
|
*
|
|
|
|
* // configure a button to generate all possible events from attached buttons.
|
|
|
|
* uBit.buttonAB.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
|
|
|
|
*
|
|
|
|
* // configure a button to suppress MICROBIT_BUTTON_EVT_CLICK and MICROBIT_BUTTON_EVT_LONG_CLICK events.
|
|
|
|
* uBit.buttonAB.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
|
|
|
|
*
|
|
|
|
* @endcode
|
|
|
|
*/
|
|
|
|
void MicroBitMultiButton::setEventConfiguration(MicroBitButtonEventConfiguration config)
|
2016-02-08 13:31:48 +00:00
|
|
|
{
|
2016-02-26 15:42:57 +00:00
|
|
|
this->eventConfiguration = config;
|
2016-02-08 13:31:48 +00:00
|
|
|
}
|
|
|
|
void MicroBitMultiButton::onButtonEvent(MicroBitEvent evt)
|
2015-08-12 10:53:41 +00:00
|
|
|
{
|
|
|
|
int button = evt.source;
|
|
|
|
int otherButton = otherSubButton(button);
|
|
|
|
|
|
|
|
switch(evt.value)
|
|
|
|
{
|
|
|
|
case MICROBIT_BUTTON_EVT_DOWN:
|
|
|
|
setButtonState(button, 1);
|
|
|
|
if(isSubButtonPressed(otherButton))
|
|
|
|
MicroBitEvent e(id, MICROBIT_BUTTON_EVT_DOWN);
|
|
|
|
|
|
|
|
break;
|
2015-10-31 10:27:38 +00:00
|
|
|
|
|
|
|
case MICROBIT_BUTTON_EVT_HOLD:
|
|
|
|
setHoldState(button, 1);
|
|
|
|
if(isSubButtonHeld(otherButton))
|
|
|
|
MicroBitEvent e(id, MICROBIT_BUTTON_EVT_HOLD);
|
|
|
|
|
|
|
|
break;
|
2015-08-12 10:53:41 +00:00
|
|
|
|
|
|
|
case MICROBIT_BUTTON_EVT_UP:
|
|
|
|
if(isSubButtonPressed(otherButton))
|
2015-10-31 10:27:38 +00:00
|
|
|
{
|
2015-08-12 10:53:41 +00:00
|
|
|
MicroBitEvent e(id, MICROBIT_BUTTON_EVT_UP);
|
2015-10-31 10:27:38 +00:00
|
|
|
|
|
|
|
if (isSubButtonHeld(button) && isSubButtonHeld(otherButton))
|
|
|
|
MicroBitEvent e(id, MICROBIT_BUTTON_EVT_LONG_CLICK);
|
|
|
|
else
|
|
|
|
MicroBitEvent e(id, MICROBIT_BUTTON_EVT_CLICK);
|
|
|
|
|
|
|
|
setSupressedState(otherButton, 1);
|
|
|
|
}
|
2016-02-26 15:42:57 +00:00
|
|
|
else if (!isSubButtonSupressed(button) && eventConfiguration == MICROBIT_BUTTON_ALL_EVENTS)
|
2015-10-31 10:27:38 +00:00
|
|
|
{
|
|
|
|
if (isSubButtonHeld(button))
|
|
|
|
MicroBitEvent e(button, MICROBIT_BUTTON_EVT_LONG_CLICK);
|
|
|
|
else
|
|
|
|
MicroBitEvent e(button, MICROBIT_BUTTON_EVT_CLICK);
|
|
|
|
}
|
|
|
|
|
2015-08-12 10:53:41 +00:00
|
|
|
setButtonState(button, 0);
|
|
|
|
setHoldState(button, 0);
|
2015-10-31 10:27:38 +00:00
|
|
|
setSupressedState(button, 0);
|
|
|
|
|
2015-08-12 10:53:41 +00:00
|
|
|
break;
|
2015-10-31 10:27:38 +00:00
|
|
|
|
2015-08-12 10:53:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests if this MultiButton is currently pressed.
|
|
|
|
* @return 1 if both physical buttons are pressed simultaneously.
|
|
|
|
*/
|
|
|
|
int MicroBitMultiButton::isPressed()
|
|
|
|
{
|
|
|
|
return ((status & MICROBIT_MULTI_BUTTON_STATE_1) && (status & MICROBIT_MULTI_BUTTON_STATE_2));
|
|
|
|
}
|