SDL 触摸屏区域在触发运动事件时保持聚焦

问题描述 投票:0回答:1

我正在尝试开发一个简单的应用程序,由一个带有红色方块的窗口组成,用作按钮。应用程序代码如下:

按钮/调试功能:

// Define a structure for the button
typedef struct {
SDL_Rect draw_rect; // dimensions of button
struct {
    Uint8 r, g, b, a;
} colour;
bool pressed;
} button_t;

static bool button(SDL_Renderer* r, button_t* btn) {
// draw button
SDL_SetRenderDrawColor(r, btn->colour.r, btn->colour.g, btn->colour.b, btn->colour.a);
SDL_RenderFillRect(r, &btn->draw_rect);

// if button press detected - reset it so it wouldn't trigger twice
if (btn->pressed) {
    btn->pressed = false;
    return true;
}
return false;
}

// Write a function to process the mouse events for the button
static void button_process_event(button_t* btn, const SDL_Event* ev) 
{
// react on mouse click within button rectangle by setting 'pressed'
if (ev->type == SDL_MOUSEBUTTONDOWN) {
    if (ev->button.button == SDL_BUTTON_LEFT &&
            ev->button.x >= btn->draw_rect.x &&
            ev->button.x <= (btn->draw_rect.x + btn->draw_rect.w) &&
            ev->button.y >= btn->draw_rect.y &&
            ev->button.y <= (btn->draw_rect.y + btn->draw_rect.h)) {
        btn->pressed = true;
    }
}
}

// Write a function to print the mouse event
static void print_event(const SDL_Event* e) {
// print the event type
if (e->type == SDL_FINGERDOWN) {
printf("touch finger DOWN event\n");
}
else if (e->type == SDL_FINGERUP) {
printf("touch finger UP event\n");
}
else if (e->type == SDL_FINGERMOTION) {
printf("touch finger MOTION event\n");
}
else if (e->type == SDL_MOUSEMOTION) {
printf("Mouse motion event\n");
printf("mouse motion coords: %d,%d\n",e->motion.x,e->motion.y);
}
else if (e->type == SDL_MOUSEBUTTONDOWN) {
printf("Mouse button down event\n");
printf("button coords: %d,%d\n",e->button.x,e->button.y);
}
else if (e->type == SDL_MOUSEBUTTONUP) {
printf("Mouse button up event\n");
printf("button coords: %d,%d\n",e->button.x,e->button.y);
}
else if (e->type == SDL_MOUSEWHEEL) {
printf("Mouse wheel event\n");
}
else{
    printf("unknown event %d\n",e->type);
}
}

int main(int argc, char* argv[])
{
// Initialize the SDL2 video subsystem
SDL_Init(SDL_INIT_VIDEO);

// Create a window with a title, position, and size
SDL_Window* window = SDL_CreateWindow("Empty Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 320, 240, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_FULLSCREEN );

// Create a renderer for the window
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

// Set the renderer's draw color
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // black

// Clear the renderer with the draw color
SDL_RenderClear(renderer);

// Create an instance of the button structure
button_t start_button = {
        .colour = {.r = 255, .g = 10, .b = 10, .a = 255}, // white
        .draw_rect = {.x = 100, .y = 0, .w = 100, .h = 100}, // center of the window
};

然后是主要功能:

// Main loop
SDL_Event event;
bool quit = false;

while (!quit) {
    // Poll events
    while (SDL_PollEvent(&event)) {
        // Quit on close, window close, or 'escape' key hit
        if (event.type == SDL_QUIT ||
                (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE) ||
                (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE)) {
            quit = true;
        }


        // Pass event to button
        button_process_event(&start_button, &event);

                    //debug event
        print_event(&event);
    }

    // Clear the renderer
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // black

    SDL_RenderClear(renderer);

    // Draw the button
    if (button(renderer, &start_button)) {
        // Handle the button click event
        printf("Start button pressed\n");
    }

    // Present the renderer
    SDL_RenderPresent(renderer);
}

// Destroy the renderer and the window
SDL_DestroyRenderer(renderer);

SDL_DestroyWindow(window);

// Quit the SDL2 video subsystem
SDL_Quit();

return 0;
}

正如预期的那样,上面的代码会生成一个带有红色方形按钮的黑色窗口,但是,我观察到一些奇怪的行为:

  1. 当我第一次尝试触摸屏幕(屏幕的每个位置)时,以下字符串会打印在标准输出上: “鼠标按钮按下事件 按钮坐标:0,0 鼠标按钮松开事件 按钮坐标:0,0” 似乎屏幕区域保持“聚焦”,直到我将手指拖动到其他屏幕位置(没有运动事件,聚焦区域保持不变);

  2. 手指触摸/运动生成的事件只是鼠标事件:鼠标按钮按下+鼠标按钮向上或鼠标运动(我尝试使用鼠标事件相关提示但没有成功);

  3. 与1中所述一致,使程序打印“按下开始按钮”(仅当按下红色方形按钮时才打印)我必须先将手指拖动到按钮区域(产生运动事件)在该区域),然后程序开始为每次触摸屏幕打印“按下开始按钮”(独立于触摸的区域)。

有人对让我的应用程序“正常”工作有任何建议吗?

c events graphics sdl touchscreen
1个回答
0
投票

问题在于使用带有 libinput 的 directfb 作为底层“驱动程序”,由于某种原因,它会将触摸屏设备解释为纯鼠标设备。 通过使用选项 --enable-tslib 重新编译 directfb 并导出 env_var TSLIB_TSDEVICE=/dev/input/event0 (在我的例子中这是事件设备),问题已经解决。

© www.soinside.com 2019 - 2024. All rights reserved.