Building Interactive Buttons

Adding Keyboard Shortcuts to SDL Buttons

How can I add keyboard shortcuts to trigger button actions?

Abstract art representing computer programming

Adding keyboard shortcuts to trigger button actions is a great way to improve the accessibility and usability of your SDL application. We can achieve this by extending our Button class and modifying our event handling logic. Let's go through the process step by step.

First, let's modify our Button class to include a keyboard shortcut:

#include <SDL.h>
#include <string>

class Button : public Rectangle {
public:
  Button(int x, int y, int w, int h,
         SDL_Keycode shortcut = SDLK_UNKNOWN)
    : Rectangle{x, y, w, h},
      shortcut{shortcut} {}

  void
  HandleEvent(const SDL_Event& E) override {
    if (E.type == SDL_MOUSEBUTTONDOWN) {
      if (IsWithinBounds(E.button.x,
                         E.button.y)) {
        HandleClick();
      }
    } else if (E.type == SDL_KEYDOWN &&
               E.key.keysym.sym == shortcut) {
      HandleClick(); 
    }
  }

  virtual void HandleClick() {
    // Default implementation, to be overridden
    // by derived classes
  }

private:
  SDL_Keycode shortcut;
};

In this updated Button class, we've added a shortcut member to store the keyboard shortcut and modified the HandleEvent() method to check for keyboard events matching the shortcut.

Now, let's create a few specific button types with keyboard shortcuts:

class PlayButton : public Button {
public:
  PlayButton(int x, int y, int w, int h)
    : Button{x, y, w, h, SDLK_p} {} 

  void HandleClick() override {
    std::cout << "Game started!\n";
    // Add game start logic here
  }
};

class QuitButton : public Button {
public:
  QuitButton(int x, int y, int w, int h)
    : Button{x, y, w, h, SDLK_q} {} 

  void HandleClick() override {
    std::cout << "Quitting game...\n";
    SDL_Event quitEvent;
    quitEvent.type = SDL_QUIT;
    SDL_PushEvent(&quitEvent);
  }
};

These button classes define specific actions and associate them with keyboard shortcuts ('P' for Play and 'Q' for Quit).

Now, let's use these buttons in our main game loop:

#include <SDL.h>
#include <iostream>

int main(int argc, char* argv[]) {
  SDL_Init(SDL_INIT_VIDEO);

  Window GameWindow;
  PlayButton playButton{50, 50, 100, 50};
  QuitButton quitButton{50, 120, 100, 50};

  SDL_Event Event;
  bool shouldQuit{false};
  while (!shouldQuit) {
    while (SDL_PollEvent(&Event)) {
      playButton.HandleEvent(Event);
      quitButton.HandleEvent(Event);
      if (Event.type == SDL_QUIT) {
        shouldQuit = true;
      }
    }

    GameWindow.Render();
    playButton.Render(GameWindow.GetSurface());
    quitButton.Render(GameWindow.GetSurface());
    GameWindow.Update();
  }

  SDL_Quit();
  return 0;
}

In this main loop, we create PlayButton and QuitButton instances and handle their events. Now, users can trigger the Play action by clicking the Play button or pressing 'P', and quit the game by clicking the Quit button or pressing 'Q'.

To make the shortcuts more discoverable, you might want to display them on the buttons or in a help menu. You could modify the Button::Render() method to include the shortcut:

void Button::Render(
    SDL_Surface* Surface) override {
  Rectangle::Render(Surface);
  // Render button text (implementation depends
  // on your text rendering method)
  RenderText(Surface, text);
  // Render shortcut hint
  if (shortcut != SDLK_UNKNOWN) {
    std::string shortcutHint =
        "(" + SDL_GetKeyName(shortcut) + ")";
    RenderText(Surface, shortcutHint,
               Rect.x + Rect.w - 20,
               Rect.y + Rect.h - 20);
  }
}

By implementing keyboard shortcuts this way, you're providing users with multiple ways to interact with your application, improving its overall usability and accessibility.

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 46 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved