239 lines
7.9 KiB
C++

/******************************************************************************
* Copyright (c) 2018(-2023) STMicroelectronics.
* All rights reserved.
*
* This file is part of the TouchGFX 4.22.0 distribution.
*
* This software is licensed under terms that can be found in the LICENSE file in
* the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
*******************************************************************************/
/**
* @file touchgfx/widgets/RadioButtonGroup.hpp
*
* Declares the touchgfx::RadioButtonGroup class.
*/
#ifndef TOUCHGFX_RADIOBUTTONGROUP_HPP
#define TOUCHGFX_RADIOBUTTONGROUP_HPP
#include <touchgfx/Callback.hpp>
#include <touchgfx/hal/Types.hpp>
#include <touchgfx/widgets/AbstractButton.hpp>
#include <touchgfx/widgets/RadioButton.hpp>
namespace touchgfx
{
/**
* Class for handling a collection of RadioButton objects. The RadioButtonGroup handles the
* automatic deselection of other radio buttons when a new RadioButton is selected. A
* callback is executed when a new selection occurs reporting the newly selected
* RadioButton.
*
* @tparam CAPACITY The number of RadioButtons to store in the RadioButtonGroup.
*
* @see RadioButton
*/
template <uint16_t CAPACITY>
class RadioButtonGroup
{
public:
/** Initializes a new instance of the RadioButtonGroup class. */
RadioButtonGroup()
: size(0),
radioButtonClicked(this, &RadioButtonGroup::radioButtonClickedHandler),
radioButtonUnselected(this, &RadioButtonGroup::radioButtonDeselectedHandler),
radioButtonSelectedCallback(0),
radioButtonDeselectedCallback(0)
{
}
/** Finalizes an instance of the RadioButtonGroup class. */
virtual ~RadioButtonGroup()
{
}
/**
* Add the RadioButton to the RadioButtonGroup. Adding more radio buttons than the
* \a CAPACITY of the RadioButtonGroup raises an assert.
*
* @param [in] radioButton The RadioButton to add.
*/
virtual void add(RadioButton& radioButton)
{
assert(size < CAPACITY && "RadioButtonGroup capacity exceeded!");
radioButton.setAction(radioButtonClicked);
radioButton.setDeselectedAction(radioButtonUnselected);
radioButtons[size++] = &radioButton;
}
/**
* Gets the RadioButton at the specified index.
*
* @param index the index of the RadioButton to return.
*
* @return the RadioButton at the specified index. Returns 0 if the index is illegal.
*/
virtual RadioButton* getRadioButton(uint16_t index) const
{
return (size > index) ? radioButtons[index] : 0;
}
/**
* Gets the index of the currently selected RadioButton.
*
* @return the index of the selected RadioButton. Returns -1 if no RadioButton is
* selected.
*/
virtual int32_t getSelectedRadioButtonIndex() const
{
for (uint16_t i = 0; i < size; i++)
{
if (radioButtons[i]->getSelected())
{
return i;
}
}
return -1;
}
/**
* Gets the currently selected RadioButton
*
* @return a pointer to the selected RadioButton. Returns 0 if no RadioButton is
* selected.
*/
virtual RadioButton* getSelectedRadioButton() const
{
int32_t index = getSelectedRadioButtonIndex();
return (index < 0) ? 0 : getRadioButton(index);
}
/**
* Sets the specified RadioButton to be selected.
*
* Sets the specified RadioButton to be selected and all other radio buttons to be
* deselected. Do not call this function before all RadioButton objects have been added
* to the RadioButtonGroup. Will call the radioButtonSelected callback.
*
* @param [in] radioButton the RadioButton to be selected.
*/
virtual void setSelected(RadioButton& radioButton)
{
radioButton.setSelected(true);
radioButtonClickedHandler(radioButton);
}
/**
* Sets whether or not it is possible to deselect RadioButtons by clicking them when
* they are selected. If deselection is enabled, it will be possible to select a
* RadioButton (and as a result deselect all other radio buttons) and the push the same
* RadioButton again to deselect it. The result is that no RadioButton is selected.
*
* @param deselectionEnabled true if it should be possible to deselect by click.
*
* @see getDeselectionEnabled
*/
virtual void setDeselectionEnabled(bool deselectionEnabled)
{
for (uint16_t i = 0; i < size; i++)
{
radioButtons[i]->setDeselectionEnabled(deselectionEnabled);
}
}
/**
* Gets the current deselectionEnabled state.
*
* @return The current deselectionEnabled state.
*
* @see setDeselectionEnabled
*/
virtual bool getDeselectionEnabled() const
{
return (size > 0) ? radioButtons[0]->getDeselectionEnabled() : false;
}
/**
* Associates an action to be performed when a radio button belonging to this group is
* selected.
*
* @param callback The callback to be executed. The callback will be given a reference
* to the RadioButton that was selected.
*
* @see GenericCallback
*/
void setRadioButtonSelectedHandler(GenericCallback<const AbstractButton&>& callback)
{
radioButtonSelectedCallback = &callback;
}
/**
* Associates an action to be performed when a radio button belonging to this group
* transition from selected to unselected.
*
* @param callback The callback to be executed. The callback will be given a reference
* to the RadioButton that was selected.
*
* @see GenericCallback
*/
void setRadioButtonDeselectedHandler(GenericCallback<const AbstractButton&>& callback)
{
radioButtonDeselectedCallback = &callback;
}
protected:
RadioButton* radioButtons[CAPACITY]; ///< The list of added RadioButtons.
uint16_t size; ///< The current number of added RadioButtons.
Callback<RadioButtonGroup, const AbstractButton&> radioButtonClicked; ///< Callback that is attached to the RadioButtons.
Callback<RadioButtonGroup, const AbstractButton&> radioButtonUnselected; ///< Callback that is attached to the RadioButtons.
GenericCallback<const AbstractButton&>* radioButtonSelectedCallback; ///< The callback to be executed when a radio button belonging to this group is selected.
GenericCallback<const AbstractButton&>* radioButtonDeselectedCallback; ///< The callback to be executed when a radio button belonging to this group is deselected.
/**
* Handles the event that a RadioButton has been selected. deselects all other
* RadioButtons.
*
* @param radioButton the RadioButton that has been selected.
*/
virtual void radioButtonClickedHandler(const AbstractButton& radioButton)
{
// Deselect other radio buttons
for (uint16_t i = 0; i < size; i++)
{
if (radioButtons[i] != &radioButton)
{
if (radioButtons[i]->getSelected())
{
radioButtons[i]->setSelected(false);
}
}
}
if (radioButtonSelectedCallback && radioButtonSelectedCallback->isValid())
{
radioButtonSelectedCallback->execute(radioButton);
}
}
/**
* Handles the event that a RadioButton has been deselected.
*
* @param radioButton the RadioButton that has been deselected.
*/
virtual void radioButtonDeselectedHandler(const AbstractButton& radioButton)
{
if (radioButtonDeselectedCallback && radioButtonDeselectedCallback->isValid())
{
radioButtonDeselectedCallback->execute(radioButton);
}
}
};
} // namespace touchgfx
#endif // TOUCHGFX_RADIOBUTTONGROUP_HPP