Skip to content

Instantly share code, notes, and snippets.

@siredmar
Last active August 7, 2020 14:45
Show Gist options
  • Save siredmar/bbdc71084cd7b33e0d14a9bf51244e2e to your computer and use it in GitHub Desktop.
Save siredmar/bbdc71084cd7b33e0d14a9bf51244e2e to your computer and use it in GitHub Desktop.
/*
sdlgui/example1.cpp -- C++ version of an example application that shows
how to use the various widget classes.
Based on NanoGUI by Wenzel Jakob <wenzel@inf.ethz.ch>.
Adaptation for SDL by Dalerank <dalerankn8@gmail.com>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE.txt file.
*/
#include <memory>
#include <sdlgui/button.h>
#include <sdlgui/screen.h>
#include <sdlgui/window.h>
#if defined(_WIN32)
#include <windows.h>
#endif
#include <iostream>
#if defined(_WIN32)
#include <SDL.h>
#else
#include <SDL2/SDL.h>
#endif
#if defined(_WIN32)
#include <SDL_image.h>
#else
#include <SDL2/SDL_image.h>
#endif
using std::cerr;
using std::cout;
using std::endl;
#undef main
using namespace sdlgui;
class TestWindow1;
class TestWindow2;
class Fps
{
public:
explicit Fps(int tickInterval = 30)
: m_tickInterval(tickInterval)
, m_nextTime(SDL_GetTicks() + tickInterval)
{
}
void next()
{
SDL_Delay(getTicksToNextFrame());
m_nextTime += m_tickInterval;
}
private:
const int m_tickInterval;
Uint32 m_nextTime;
Uint32 getTicksToNextFrame() const
{
Uint32 now = SDL_GetTicks();
return (m_nextTime <= now) ? 0 : m_nextTime - now;
}
};
class TestWindow2 : public Screen
{
public:
TestWindow2(SDL_Window* pwindow, int rwidth, int rheight)
: Screen(pwindow, Vector2i(rwidth, rheight), "SDL_gui Test")
, pwindow(pwindow)
, quit(false)
, width(rwidth)
, height(rheight)
{
{
auto& button = wdg<Button>("Button 2", [this] {
std::cout << "screen 2 button pushed!" << std::endl;
});
button.setSize(sdlgui::Vector2i{ 100, 20 });
button.setPosition(100, 100);
auto& back = wdg<Button>("Back", [this] {
std::cout << "back button pushed!" << std::endl;
quit = true;
});
back.setSize(sdlgui::Vector2i{ 100, 20 });
back.setPosition(100, 140);
}
performLayout(mSDL_Renderer);
}
~TestWindow2()
{
}
int Handle()
{
Fps fps;
try
{
SDL_Event e;
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
onEvent(e);
}
std::cout << "Screen 2 running" << std::endl;
SDL_SetRenderDrawColor(mSDL_Renderer, 0xd3, 0xd3, 0xd3, 0xff);
SDL_RenderClear(mSDL_Renderer);
drawAll();
// Render the rect to the screen
SDL_RenderPresent(mSDL_Renderer);
fps.next();
}
}
catch (const std::runtime_error& e)
{
std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
#if defined(_WIN32)
MessageBoxA(nullptr, error_msg.c_str(), NULL, MB_ICONERROR | MB_OK);
#else
std::cerr << error_msg << endl;
#endif
return -1;
}
return 0;
}
private:
SDL_Window* pwindow;
bool quit;
int width;
int height;
};
class TestWindow1 : public Screen
{
public:
TestWindow1(SDL_Window* pwindow, int rwidth, int rheight)
: Screen(pwindow, Vector2i(rwidth, rheight), "SDL_gui Test")
, pwindow(pwindow)
, quit(false)
, loadScreenTwo(false)
, width(rwidth)
, height(rheight)
{
{
auto& button = wdg<Button>("Button 1", [this] {
std::cout << "screen 1 button pushed!" << std::endl;
loadScreenTwo = true;
});
button.setSize(sdlgui::Vector2i{ 100, 20 });
button.setPosition(100, 100);
auto& exit = wdg<Button>("Exit", [this] {
std::cout << "Exit button pushed!" << std::endl;
quit = true;
});
exit.setSize(sdlgui::Vector2i{ 100, 20 });
exit.setPosition(100, 140);
}
performLayout(mSDL_Renderer);
}
~TestWindow1()
{
}
int Handle()
{
Fps fps;
bool quit = false;
try
{
SDL_Event e;
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
onEvent(e);
}
std::cout << "Sceen 1 running" << std::endl;
if (loadScreenTwo)
{
loadScreenTwo = false;
TestWindow2 testwindow2(pwindow, width, height);
testwindow2.Handle();
}
SDL_SetRenderDrawColor(mSDL_Renderer, 0xd3, 0xd3, 0xd3, 0xff);
SDL_RenderClear(mSDL_Renderer);
drawAll();
// Render the rect to the screen
SDL_RenderPresent(mSDL_Renderer);
fps.next();
}
}
catch (const std::runtime_error& e)
{
std::string error_msg = std::string("Caught a fatal error: ") + std::string(e.what());
#if defined(_WIN32)
MessageBoxA(nullptr, error_msg.c_str(), NULL, MB_ICONERROR | MB_OK);
#else
std::cerr << error_msg << endl;
#endif
return -1;
}
return 0;
}
private:
SDL_Window* pwindow;
bool quit;
bool loadScreenTwo;
int width;
int height;
};
int main(int /* argc */, char** /* argv */)
{
char rendername[256] = { 0 };
SDL_RendererInfo info;
SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
SDL_Window* window; // Declare a pointer to an SDL_Window
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
int winWidth = 400;
int winHeight = 200;
// Create an application window with the following settings:
window = SDL_CreateWindow(
"An SDL2 window", // const char* title
SDL_WINDOWPOS_UNDEFINED, // int x: initial x position
SDL_WINDOWPOS_UNDEFINED, // int y: initial y position
winWidth, // int w: width, in pixels
winHeight, // int h: height, in pixels
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI // Uint32 flags: window options, see docs
);
// Check that the window was successfully made
if (window == NULL)
{
// In the event that the window could not be made...
std::cout << "Could not create window: " << SDL_GetError() << '\n';
SDL_Quit();
return 1;
}
auto context = SDL_GL_CreateContext(window);
for (int it = 0; it < SDL_GetNumRenderDrivers(); it++)
{
SDL_GetRenderDriverInfo(it, &info);
strcat(rendername, info.name);
strcat(rendername, " ");
}
SDL_Renderer* mSDL_Renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawBlendMode(mSDL_Renderer, SDL_BLENDMODE_BLEND);
TestWindow1* screen1 = new TestWindow1(window, winWidth, winHeight);
screen1->Handle();
return 0;
}
@siredmar
Copy link
Author

siredmar commented Aug 7, 2020

I want to create an application that sits directly on a SDL2 window. Currently i don't want to make this windows thing within the SDL2 window. Basically what i need is to place widgets directly on the screen.
This works pretty good, however i have a problem switching nanogui screen contexts.

The minimalistic example above shows basically what i wish to do.

This is screen1 in action:

image

Pressing on screen1 at Button 1 opens screen2.

image

Then pressing on screen2 at Back button closes screen2 and opens back screen1.
image

However, the controls on screen1 don't react to anything.
This is my problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment