Skip to content

File AbstractMenu.h

File List > external-docs > libDaisy > src > ui > AbstractMenu.h

Go to the documentation of this file

Source Code

#pragma once

#include "hid/disp/display.h"
#include "util/MappedValue.h"
#include "UI.h"

namespace daisy
{
class AbstractMenu : public UiPage
{
  public:
    enum class Orientation
    {
        leftRightSelectUpDownModify,
        upDownSelectLeftRightModify,
    };

    enum class ItemType
    {
        callbackFunctionItem,
        checkboxItem,
        valueItem,
        openUiPageItem,
        closeMenuItem,
        customItem,
    };

    class CustomItem
    {
      public:
        virtual ~CustomItem() {}

        virtual void Draw(OneBitGraphicsDisplay& display,
                          int                    currentIndex,
                          int                    numItemsTotal,
                          Rectangle              boundsToDrawIn,
                          bool                   isEditing)
            = 0;

        virtual bool CanBeEnteredForEditing() const { return false; }

        virtual void ModifyValue(int16_t  increments,
                                 uint16_t stepsPerRevolution,
                                 bool     isFunctionButtonPressed)
        {
            (void)(increments);              // silence unused variable warnings
            (void)(stepsPerRevolution);      // silence unused variable warnings
            (void)(isFunctionButtonPressed); // silence unused variable warnings
        };

        virtual void ModifyValue(float valueSliderPosition0To1,
                                 bool  isFunctionButtonPressed)
        {
            (void)(valueSliderPosition0To1); // silence unused variable warnings
            (void)(isFunctionButtonPressed); // silence unused variable warnings
        };

        virtual void OnOkayButton(){};
    };

    struct ItemConfig
    {
        ItemType type = ItemType::closeMenuItem;
        const char* text = "";

        union
        {
            struct
            {
                void (*callbackFunction)(void* context);
                void* context;
            } asCallbackFunctionItem;

            struct
            {
                bool* valueToModify;
            } asCheckboxItem;

            struct
            {
                MappedValue* valueToModify;
            } asMappedValueItem;

            struct
            {
                UiPage* pageToOpen;
            } asOpenUiPageItem;

            struct
            {
                CustomItem* itemObject;
            } asCustomItem;
        };
    };

    AbstractMenu() = default;
    virtual ~AbstractMenu() override {}

    uint16_t          GetNumItems() const { return numItems_; }
    const ItemConfig& GetItem(uint16_t itemIdx) const
    {
        return items_[itemIdx];
    }
    void    SelectItem(uint16_t itemIdx);
    int16_t GetSelectedItemIdx() const { return selectedItemIdx_; }

    // inherited from UiPage
    bool OnOkayButton(uint8_t numberOfPresses, bool isRetriggering) override;
    bool OnCancelButton(uint8_t numberOfPresses, bool isRetriggering) override;
    bool OnArrowButton(ArrowButtonType arrowType,
                       uint8_t         numberOfPresses,
                       bool            isRetriggering) override;
    bool OnFunctionButton(uint8_t numberOfPresses,
                          bool    isRetriggering) override;
    bool OnMenuEncoderTurned(int16_t  turns,
                             uint16_t stepsPerRevolution) override;
    bool OnValueEncoderTurned(int16_t  turns,
                              uint16_t stepsPerRevolution) override;
    bool OnValuePotMoved(float newPosition) override;
    void OnShow() override;

  protected:
    void Init(const ItemConfig* items,
              uint16_t          numItems,
              Orientation       orientation,
              bool              allowEntering);

    bool IsFunctionButtonDown() const { return isFuncButtonDown_; }

    Orientation orientation_ = Orientation::upDownSelectLeftRightModify;
    const ItemConfig* items_ = nullptr;
    uint16_t numItems_ = 0;
    int16_t selectedItemIdx_ = -1;
    bool allowEntering_ = true;
    bool isEditing_ = false;

  private:
    AbstractMenu(const AbstractMenu& other) = delete;
    AbstractMenu& operator=(const AbstractMenu& other) = delete;

    bool CanItemBeEnteredForEditing(uint16_t itemIdx);
    void ModifyItemValue(uint16_t itemIdx,
                         int16_t  increments,
                         uint16_t stepsPerRevolution,
                         bool     isFunctionButtonPressed);
    void ModifyItemValue(uint16_t itemIdx,
                         float    valueSliderPosition0To1,
                         bool     isFunctionButtonPressed);
    void TriggerItemAction(uint16_t itemIdx);

    bool isFuncButtonDown_ = false;
};


} // namespace daisy