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:
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;
};
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;
}
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.
Answers to questions are automatically generated and may not have been reviewed.
Explore advanced techniques for optimizing and controlling text rendering when using SDL_ttf