Skip to content

File evaButton.h

File List > src > evaButton.h

Go to the documentation of this file

#pragma once

#include "evaSwitch.h"

namespace eva
{
    static const unsigned short LONGPRESS_DELAY = 750;

    static const unsigned char ON_SHORTCLICK = 0x08;
    static const unsigned char ON_LONGCLICK = 0x10;
    static const unsigned char ON_LONGPRESS = 0x20;

    template <class TReader>
    class Button : public Switch<TReader>
    {
    public:
        using Switch<TReader>::Switch;

    protected:
        bool checkLongPress(unsigned long now)
        {
            return this->pressTime && (now - this->pressTime) > LONGPRESS_DELAY;
        }

        void handleLongPress()
        {
            this->notify(ON_LONGPRESS, this->levelCode);
            this->pressTime = 0;
        }

        void handleDeactivating(unsigned char wasLevelCode, unsigned long now)
        {
            Switch<TReader>::handleDeactivating(wasLevelCode);
            this->notify((pressTime > 0) ? ON_SHORTCLICK : ON_LONGCLICK, wasLevelCode);
            this->pressTime = 0;
        }

        void handleActivating(unsigned long now)
        {
            Switch<TReader>::handleActivating();
            this->pressTime = now;
        }

    private:
        void tick() override
        {
            if (this->levelCode < 0)
                return;

            unsigned long now = millis();
            unsigned char wasLevelCode = this->levelCode;
            if (!this->updateState())
                return;

            if (this->checkChanging(wasLevelCode))
                this->handleChanging();

            if (checkLongPress(now))
                handleLongPress();

            if (this->checkDeactivating(wasLevelCode))
                handleDeactivating(wasLevelCode, now);

            if (this->checkActivating(wasLevelCode))
                handleActivating(now);
        }

    protected:
        unsigned long pressTime = 0;
    };

    template <int PIN, int PIN_MODE, int ACTIVATES_ON>
    using PinButton = Button<BinarizeEqDecor<DebounceDecor<DigitalPinReader<PIN, PIN_MODE>>, ACTIVATES_ON>>;

    template <int PIN>
    using PullUpButton = Button<BinarizeEqDecor<DebounceDecor<DigitalPinReader<PIN, INPUT_PULLUP>>, LOW>>;

    template <int PIN, int PIN_MODE, signed short... LEVELS>
    using PinMultiButton = Button<QuantizeDecor<DebounceDecor<AnalogPinReader<PIN, PIN_MODE>>, LEVELS...>>;
}