demotool/ui-app.cc
2017-11-24 09:51:05 +01:00

216 lines
4.8 KiB
C++

#include "externals.hh"
#include "ui.hh"
#include "ui-app.hh"
#include "ui-imgui-sdl.hh"
#include "ui-texture.hh"
#include <imgui_internal.h>
/*= T_UIApp =================================================================*/
namespace {
#include "font-awesome.inl"
static const ImWchar IconsRanges_[] = {
ICON_MIN_FA ,
ICON_MAX_FA ,
0
};
} // namespace <anon>
T_UIApp::T_UIApp( )
{
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER , 1 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE , 24 );
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE , 8 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION , 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION , 2 );
SDL_DisplayMode current;
SDL_GetCurrentDisplayMode( 0 , &current );
window_ = SDL_CreateWindow( "DEMO",
SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,
1280 , 720 ,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );
gl_ = SDL_GL_CreateContext( window_ );
glewInit( );
if ( !GLEW_VERSION_4_5 ) {
fprintf( stderr , "OpenGL 4.5 required\n" );
exit( 1 );
}
ImGui_ImplSdl_Init( window_ );
using namespace ImGui;
StyleColorsDark( );
ImGuiIO& io{ GetIO( ) };
io.IniFilename = nullptr;
{
ImFontConfig cfg;
cfg.SizePixels = 13.0f;
defaultFont_ = io.Fonts->AddFontDefault( &cfg );
ImFontConfig icons;
icons.MergeMode = true;
icons.PixelSnapH = true;
io.Fonts->AddFontFromMemoryCompressedBase85TTF(
FontAwesome__compressed_data_base85 , 13.f ,
&icons , IconsRanges_ );
}
{
ImFontConfig cfg;
cfg.SizePixels = 9.0f;
smallFont_ = io.Fonts->AddFontDefault( &cfg );
ImFontConfig icons;
icons.MergeMode = true;
icons.PixelSnapH = true;
icons.DstFont = smallFont_;
io.Fonts->AddFontFromMemoryCompressedBase85TTF(
FontAwesome__compressed_data_base85 , 9.f ,
&icons , IconsRanges_ );
}
}
T_UIApp::~T_UIApp( )
{
ImGui_ImplSdl_Shutdown( );
SDL_GL_DeleteContext( gl_ );
SDL_DestroyWindow( window_ );
SDL_Quit( );
}
void T_UIApp::addAction(
T_UIAction action ) noexcept
{
actions_.set( std::move( action ) );
}
void T_UIApp::actionMenu(
T_String const& id ) const noexcept
{
auto const* const a{ actions_.get( id ) };
if ( a ) {
a->menuItem( );
}
}
void T_UIApp::actionButton(
T_String const& id ) const noexcept
{
auto const* const a{ actions_.get( id ) };
if ( a ) {
a->tbButton( );
}
}
void T_UIApp::handleEvents( ) noexcept
{
SDL_Event event;
mMove_ = ImVec2( );
while ( SDL_PollEvent( &event ) ) {
ImGui_ImplSdl_ProcessEvent( &event );
if ( event.type == SDL_QUIT ) {
#warning FIXME request confirmation
exiting_ = true;
return;
}
if ( mCapture_ && event.type == SDL_MOUSEMOTION ) {
mMove_.x += event.motion.xrel;
mMove_.y += event.motion.yrel;
}
}
ImGui_ImplSdl_NewFrame( window_ , mCapture_ , mInitial_ );
ImGui::GetIO( ).MouseDrawCursor = true;
handleMouseCapture( );
}
void T_UIApp::handleMouseCapture( ) noexcept
{
using namespace ImGui;
auto const& io( GetIO( ) );
const T_MouseButtons mb( ([]() {;
T_MouseButtons mb;
if ( IsMouseDown( 0 ) ) {
mb |= E_MouseButton::LEFT;
}
if ( IsMouseDown( 1 ) ) {
mb |= E_MouseButton::RIGHT;
}
if ( IsMouseDown( 2 ) ) {
mb |= E_MouseButton::MIDDLE;
}
return mb;
})() );
const T_KeyboardModifiers kb( ([&io]() {
T_KeyboardModifiers kb;
if ( io.KeyCtrl ) {
kb |= E_KeyboardModifier::CTRL;
}
if ( io.KeyShift ) {
kb |= E_KeyboardModifier::SHIFT;
}
if ( io.KeyAlt ) {
kb |= E_KeyboardModifier::ALT;
}
return kb;
})() );
const bool appCanGrab( !( ImGui::IsMouseHoveringAnyWindow( )
|| io.WantCaptureMouse
|| io.WantCaptureKeyboard ) );
if ( mCapture_ && !( mb && mDelegate_ ) ) {
mCapture_ = false;
CaptureMouseFromApp( false );
SDL_SetRelativeMouseMode( SDL_FALSE );
SDL_WarpMouseInWindow( window_ , mInitial_.x , mInitial_.y );
SetMouseCursor( ImGuiMouseCursor_Arrow );
} else if ( mCapture_ && mDelegate_ ) {
SetMouseCursor( ImGuiMouseCursor_Move );
mDelegate_->handleDragAndDrop( mMove_ , kb , mb );
} else if ( appCanGrab && mb && mDelegate_ ) {
mCapture_ = true;
mInitial_ = GetMousePos( );
CaptureMouseFromApp( true );
SDL_SetRelativeMouseMode( SDL_TRUE );
SetMouseCursor( ImGuiMouseCursor_Move );
}
if ( ( appCanGrab || mCapture_ ) && io.MouseWheel && mDelegate_ ) {
mDelegate_->handleWheel( io.MouseWheel , kb , mb );
}
}
void T_UIApp::render( ) noexcept
{
handleDialogs( );
glUseProgram( 0 );
glBindProgramPipeline( 0 );
UI::Textures( ).reset( );
glClearColor( 0 , 0 , 0 , 1 );
ImGui::Render( );
}
void T_UIApp::swap( ) const noexcept
{
SDL_GL_SwapWindow( window_ );
}
void T_UIApp::handleDialogs( ) noexcept
{
const auto nDialogs{ modals_.size( ) };
for ( auto i = 0u ; i < nDialogs ; i ++ ) {
const bool keep{ modals_[ i ]->draw( ) };
assert( keep || i + 1 == nDialogs );
if ( !keep ) {
modals_.removeLast( );
}
}
}