Implementing a modal dialog box in our SDL UI system involves creating a new component that overlays the main UI and captures all input events. Here's how you can create a basic modal dialog:
First, let's define a ModalDialog
 class:
#include <SDL.h>
#include <functional>
#include <string>
class ModalDialog : public Component {
private:
std::string message;
SDL_Rect bounds;
bool isVisible{false};
std::function<void()> onConfirm;
std::function<void()> onCancel;
public:
ModalDialog(const std::string& msg, int w,
int h)
: message{msg}, bounds{0, 0, w, h} {}
void Show(
std::function<void()> confirmCallback,
std::function<void()> cancelCallback) {
isVisible = true;
onConfirm = confirmCallback;
onCancel = cancelCallback;
}
void Hide() { isVisible = false; }
void HandleEvent(
const SDL_Event& e) override {
if (!isVisible)
return;
if (e.type == SDL_MOUSEBUTTONDOWN) {
int mouseX = e.button.x;
int mouseY = e.button.y;
if (mouseX >= bounds.x + 10 &&
mouseX <= bounds.x + 90 &&
mouseY >= bounds.y + bounds.h - 40 &&
mouseY <= bounds.y + bounds.h - 10) {
onConfirm();
Hide();
} else if (mouseX >=
bounds.x + bounds.w - 90 &&
mouseX <=
bounds.x + bounds.w - 10 &&
mouseY >=
bounds.y + bounds.h - 40 &&
mouseY <=
bounds.y + bounds.h - 10) {
onCancel();
Hide();
}
}
}
void Render(SDL_Surface* surface) override {
if (!isVisible)
return;
// Center the dialog
bounds.x = (surface->w - bounds.w) / 2;
bounds.y = (surface->h - bounds.h) / 2;
// Draw dialog background
SDL_FillRect(surface, &bounds,
SDL_MapRGB(surface->format,
200, 200, 200));
// Draw message
// In a real implementation, you'd use
// SDL_ttf for text rendering
// Draw buttons
SDL_Rect confirmButton = {
bounds.x + 10, bounds.y + bounds.h - 40,
80, 30};
SDL_FillRect(
surface, &confirmButton,
SDL_MapRGB(surface->format, 0, 255, 0));
SDL_Rect cancelButton = {
bounds.x + bounds.w - 90,
bounds.y + bounds.h - 40, 80, 30};
SDL_FillRect(
surface, &cancelButton,
SDL_MapRGB(surface->format, 255, 0, 0));
}
bool IsVisible() const { return isVisible; }
};
Now, let's integrate this ModalDialog
into our UIÂ system:
#include <iostream>
class UI {
private:
std::vector<std::unique_ptr<Component>>
components;
ModalDialog dialog{"Are you sure?", 300, 150};
public:
UI() {
components.push_back(
std::make_unique<Button>(
10, 10, 100, 50, "Show Dialog"));
components.push_back(
std::make_unique<ModalDialog>(dialog));
}
void HandleEvent(const SDL_Event& e) {
if (dialog.IsVisible()) {
dialog.HandleEvent(e);
} else {
for (auto& component : components) {
component->HandleEvent(e);
}
}
}
void Render(SDL_Surface* surface) {
for (auto& component : components) {
component->Render(surface);
}
dialog.Render(surface);
}
void ShowDialog() {
dialog.Show(
[]() { std::cout << "Confirmed!\n"; },
[]() { std::cout << "Cancelled!\n"; });
}
};
int main() {
// SDL initialization code...
UI ui;
SDL_Event event;
bool quit = false;
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
} else if (event.type ==
SDL_MOUSEBUTTONDOWN) {
if (event.button.x >= 10 &&
event.button.x <= 110 &&
event.button.y >= 10 &&
event.button.y <= 60) {
ui.ShowDialog();
}
}
ui.HandleEvent(event);
}
// Clear the screen
SDL_FillRect(surface, nullptr,
SDL_MapRGB(surface->format,
255, 255, 255));
// Render the UI
ui.Render(surface);
SDL_UpdateWindowSurface(window);
}
// SDL cleanup code...
return 0;
}
This implementation creates a modal dialog that appears when a button is clicked. The dialog captures all input events when it's visible, effectively making the rest of the UIÂ non-interactive.
The ModalDialog
class handles its own rendering and event processing. When it's visible, it draws itself centered on the screen and responds to mouse clicks on its buttons.
In a real-world application, you'd want to add more features to this basic implementation:
Remember to handle edge cases, such as window resizing while the dialog is open, and ensure that the dialog is always on top of other UIÂ elements.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to create a flexible and extensible UI system using C++ and SDL, focusing on component hierarchy and polymorphism.