跳转至

lib/input/button_like/stm_hal_series/plain_button_impl.c

Source code

#include "../config/lib_settings.h"

#if defined(CFBD_IS_ST)
#include "button_like/plain_button.h"
#include "button_like/plain_button_impl.h"
#include "cfbd_define.h"
#include "gpio-stm-impl.h"

static IntrButtonArrayInfo* g_info;

static void each_button_process(CFBD_PlainButton* button)
{
    GPIO_PinState pin_state = CFBD_GPIOReadPin(button->handle);
    uint32_t current_time = HAL_GetTick();

    if (button->click_pending_time > 0 &&
        (current_time - button->click_pending_time) >= BUTTON_DOUBLE_CLICK_TIME) {
        // 单击超时,确认为单击
        button->current_state_id = BUTTON_EVENT_CLICK;
        button->click_pending_time = 0;

        CFBDInputEvent event;
        CFBD_PlainButtonEventMaker(button, &event);
        button->base_inputs.context->ops->enqueue_event(button->base_inputs.context, &event);
    }

    // ========================================
    // 🔧 步骤3: 按钮状态处理
    // ========================================
    CFBD_Bool is_pressed = (pin_state == button->button_press_state);
    CFBDInputEvent event;
    CFBD_Bool should_send_event = CFBD_FALSE;

    // --- 按下事件 ---
    if (is_pressed && !button->is_pressed) {
        button->is_pressed = CFBD_TRUE;
        button->press_time = current_time;
        button->current_state_id = BUTTON_EVENT_PRESS;
        button->long_press_triggered = CFBD_FALSE;

        // 检查是否是双击的第二次按下
        if (button->click_pending_time > 0 &&
            (current_time - button->click_pending_time) < BUTTON_DOUBLE_CLICK_TIME) {
            // 这是双击!取消待定的单击
            button->is_double_click_pending = CFBD_TRUE;
            button->click_pending_time = 0; // 清除单击待定
        }

        should_send_event = CFBD_TRUE;
    }
    else if (!is_pressed && button->is_pressed) {
        button->is_pressed = CFBD_FALSE;
        button->release_time = current_time;
        uint32_t press_duration = current_time - button->press_time;

        // 非长按的短按
        if (!button->long_press_triggered && press_duration < BUTTON_LONG_PRESS_TIME) {
            // 检查是否是双击的第二次释放
            if (button->is_double_click_pending) {
                button->current_state_id = BUTTON_EVENT_DOUBLE_CLICK;
                button->is_double_click_pending = CFBD_FALSE;
                button->click_pending_time = 0;
                should_send_event = CFBD_TRUE;
            }
            else {
                button->current_state_id = BUTTON_EVENT_CLICK;
                button->click_pending_time = current_time;
                should_send_event = CFBD_FALSE;
            }
        }
        else {
            // 长按释放
            button->current_state_id = BUTTON_EVENT_RELEASE;
            button->click_pending_time = 0;
            button->is_double_click_pending = CFBD_FALSE;
            should_send_event = CFBD_TRUE;
        }
    }
    // --- 持续按下:长按检测 ---
    else if (button->is_pressed && !button->long_press_triggered) {
        uint32_t press_duration = current_time - button->press_time;

        if (press_duration >= BUTTON_LONG_PRESS_TIME) {
            // 触发长按
            button->long_press_triggered = CFBD_TRUE;
            button->current_state_id = BUTTON_EVENT_LONG_PRESS;
            button->click_pending_time = 0;
            should_send_event = CFBD_TRUE;
        }
    }

    // ========================================
    // 🔧 步骤4: 发送事件
    // ========================================
    if (should_send_event) {
        CFBD_PlainButtonEventMaker(button, &event);
        if (button->base_inputs.context && button->base_inputs.context->ops) {
            button->base_inputs.context->ops->enqueue_event(button->base_inputs.context, &event);
        }
    }
}

static void CFBD_STButtonIntrCallbacks(void* intr_datas)
{
    uint16_t GPIO_Pin = *(uint16_t*) intr_datas;
    for (int i = 0; i < g_info->cnt; i++) {
        CFBD_PlainButton* btn = g_info->array[i];
        if (btn->handle->pin_internals_ == GPIO_Pin) {
            each_button_process(btn);
        }
    }
}

CFBD_ButtonIntrCallbacks CFBD_PlainButtonGetIntrCallbacksImpl(IntrButtonArrayInfo* info)
{
    g_info = info;
    return CFBD_STButtonIntrCallbacks;
}

#endif

Updated on 2026-02-03 at 13:21:55 +0000