Building a Modular UI System

Creating a Scrollable Container in SDL

How do I create a scrollable container for UI elements that exceed the window size?

Abstract art representing computer programming

Creating a scrollable container in SDL involves managing a viewport that shows only a portion of the total content. Here's how you can implement a basic scrollable container:

First, let's define a ScrollableContainer class:

#include <SDL.h>
#include <vector>

class ScrollableContainer {
private:
  SDL_Rect viewport;
  SDL_Rect content;
  int scrollY{0};
  std::vector<SDL_Rect> elements;

public:
  ScrollableContainer(int x, int y, int w,
                      int h)
    : viewport{x, y, w, h},
      content{0, 0, w, 0} {}

  void AddElement(const SDL_Rect& element) {
    elements.push_back(element);
    content.h = std::max(content.h,
                         element.y + element.h);
  }

  void Scroll(int amount) {
    scrollY += amount;
    scrollY = std::max(
        0, std::min(scrollY,
                    content.h - viewport.h));
  }

  void Render(SDL_Surface* surface) {
    SDL_Rect clipRect = viewport;
    SDL_SetClipRect(surface, &clipRect);

    for (const auto& element : elements) {
      SDL_Rect adjustedRect = element;
      adjustedRect.y -= scrollY;

      if (adjustedRect.y + adjustedRect.h > 0 &&
          adjustedRect.y < viewport.h) {
        SDL_FillRect(surface, &adjustedRect,
                     SDL_MapRGB(surface->format,
                       200, 200, 200));
      }
    }

    SDL_SetClipRect(surface, nullptr);
  }
};

Now, let's use this ScrollableContainer in our main loop:

#include <iostream>

int main() {
  // SDL initialization code...

  ScrollableContainer container{10, 10, 200,
    300};

  // Add some elements to the container
  for (int i = 0; i < 10; ++i) {
    container.AddElement({0, i * 60, 180, 50});
  }

  SDL_Event event;
  bool quit = false;

  while (!quit) {
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_QUIT) {
        quit = true;
      } else if (event.type == SDL_MOUSEWHEEL) {
        container.Scroll(-event.wheel.y *
                         20); 
        std::cout
            << "Scrolled "
            << (event.wheel.y > 0
                  ? "up"
                  : "down")
            << "\n";
      }
    }

    // Clear the screen
    SDL_FillRect(surface, nullptr,
                 SDL_MapRGB(surface->format,
                            255, 255, 255));

    // Render the scrollable container
    container.Render(surface);

    SDL_UpdateWindowSurface(window);
  }

  // SDL cleanup code...
  return 0;
}

This implementation creates a scrollable container that can hold multiple elements. The container uses SDL_SetClipRect() to ensure that only the visible portion of the content is rendered. The Scroll() method allows you to move the visible area up or down.

In the main loop, we're handling the SDL_MOUSEWHEEL event to allow scrolling with the mouse wheel. You could also implement scrolling via keyboard input or drag gestures for touch screens.

Remember to adjust the scrolling speed and behavior to suit your specific UI needs. You might also want to add visual indicators like scroll bars to show the current scroll position and the total content size.

This basic implementation can be extended to support horizontal scrolling, nested scrollable areas, or more complex layouts. As your UI becomes more complex, consider implementing a more robust UI framework or using an existing library that provides these features.

This Question is from the Lesson:

Building a Modular UI System

Learn how to create a flexible and extensible UI system using C++ and SDL, focusing on component hierarchy and polymorphism.

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

This Question is from the Lesson:

Building a Modular UI System

Learn how to create a flexible and extensible UI system using C++ and SDL, focusing on component hierarchy and polymorphism.

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