Creating Clickable Text and Hyperlinks

How can I create clickable text or hyperlinks within my SDL application?

Creating clickable text or hyperlinks in SDL involves rendering the text, tracking its position, and handling mouse events. Here's how you can implement this functionality:

Rendering Clickable Text

First, let's create a ClickableText class that extends our Text class:

#include <functional>
#include <string>

class ClickableText : public Text {
public:
  ClickableText(std::string Content,
                int FontSize,
                std::function<void()>
                ClickHandler)
    : Text{FontSize},
      ClickHandler{ClickHandler} {
    CreateSurface(Content);
  }

  bool IsClicked(int MouseX, int MouseY) const {
    return MouseX >= DestinationRectangle.x &&
      MouseX < DestinationRectangle.x +
      DestinationRectangle.w &&
      MouseY >= DestinationRectangle.y &&
      MouseY < DestinationRectangle.y +
      DestinationRectangle.h;
  }

  void OnClick() {
    if (ClickHandler) { ClickHandler(); }
  }

private:
  std::function<void()> ClickHandler;
};

Handling Mouse Events

Now, let's implement mouse event handling in our main loop:

#include <iostream>
#include <vector>

int main() {
  SDL_Init(SDL_INIT_VIDEO);
  TTF_Init();

  Window GameWindow;

  std::vector<ClickableText> Hyperlinks;
  Hyperlinks.emplace_back(
    "Click me!", 24, [](){
      std::cout << "Hyperlink clicked!\n";
     });

  Hyperlinks.emplace_back(
    "Another link", 24, [](){
      std::cout << "Second link clicked!\n";
    });

  // Position the hyperlinks
  Hyperlinks[0].DestinationRectangle = {
    50, 50, 0, 0};
  Hyperlinks[1].DestinationRectangle = {
    50, 100, 0, 0};

  SDL_Event Event;
  bool ShouldQuit{false};

  while (!ShouldQuit) {
    while (SDL_PollEvent(&Event)) {
      if (Event.type == SDL_QUIT) {
        ShouldQuit = true;
      } else if (Event.type ==
        SDL_MOUSEBUTTONDOWN) {
        int MouseX, MouseY;
        SDL_GetMouseState(&MouseX, &MouseY);
        for (auto& Link : Hyperlinks) {
          if (Link.IsClicked(MouseX, MouseY)) {
            Link.OnClick();
          }
        }
      }
    }

    GameWindow.Render();
    for (const auto& Link : Hyperlinks) {
      Link.Render(GameWindow.GetSurface());
    }
    GameWindow.Update();
  }

  TTF_Quit();
  SDL_Quit();
  return 0;
}

Styling Clickable Text

To make the clickable text look like hyperlinks, you can change the color or add an underline:

class ClickableText : public Text {
public:
  ClickableText(std::string Content,
                int FontSize,
                std::function<void()>
                ClickHandler)
    : Text{FontSize},
      ClickHandler{ClickHandler} {
    TTF_SetFontStyle(Font, TTF_STYLE_UNDERLINE);
    CreateSurface(Content);
  }

  void CreateSurface(
    std::string Content) override {
    SDL_FreeSurface(TextSurface);
    TextSurface = TTF_RenderUTF8_Blended(
      Font, Content.c_str(),
      {0, 0, 255, 255}); // Blue color
    if (!TextSurface) {
      std::cout <<
        "Error creating TextSurface: " <<
        SDL_GetError();
    }
  }

  // ... rest of the class implementation ...
};

This implementation provides a basic framework for clickable text in SDL. You can extend it further by adding hover effects, changing the cursor when over a link, or implementing more complex interactions based on your specific needs.

Remember to handle edge cases, such as when the text changes or when the window is resized, to ensure the clickable areas remain accurate.

Text Performance, Fitting and Wrapping

Explore advanced techniques for optimizing and controlling text rendering when using SDL_ttf

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Adjusting Text Kerning and Letter Spacing
How can I implement text kerning or letter-spacing adjustments with SDL_ttf?
Implementing a Text-Heavy UI
What's the best approach for implementing a text-heavy UI, like a chat system?
Or Ask your Own Question
Purchase the course to ask your own questions