2017-10-04 11:20:27 +02:00
|
|
|
#include "externals.hh"
|
|
|
|
#include "window.hh"
|
|
|
|
#include "imgui_impl_sdl.h"
|
2017-11-20 21:54:46 +01:00
|
|
|
#include <imgui_internal.h>
|
2017-10-04 11:20:27 +02:00
|
|
|
|
2017-11-22 14:13:02 +01:00
|
|
|
|
|
|
|
/*= A_ModalDialog ============================================================*/
|
|
|
|
|
|
|
|
A_ModalDialog::A_ModalDialog(
|
|
|
|
char const* const id ) noexcept
|
|
|
|
: id_{ id , uint32_t( strlen( id ) + 1 ) }
|
|
|
|
{}
|
|
|
|
|
2017-11-23 12:24:40 +01:00
|
|
|
A_ModalDialog::A_ModalDialog(
|
|
|
|
T_String const& id ) noexcept
|
|
|
|
{
|
|
|
|
if ( id && id[ id.length( ) - 1 ] == 0 ) {
|
|
|
|
id_ = ebcl::T_Buffer< char >{ id.data( ) , id.size( ) };
|
|
|
|
} else {
|
|
|
|
id_ = id.toOSString( );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-22 14:13:02 +01:00
|
|
|
A_ModalDialog::~A_ModalDialog( )
|
|
|
|
{ }
|
|
|
|
|
2017-11-23 12:24:40 +01:00
|
|
|
uint8_t A_ModalDialog::addButton(
|
|
|
|
char const* name ) noexcept
|
|
|
|
{
|
|
|
|
buttons_.addNew( name , strlen( name ) + 1 );
|
|
|
|
return buttons_.size( ) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t A_ModalDialog::addButton(
|
|
|
|
T_String const& name ) noexcept
|
|
|
|
{
|
|
|
|
if ( name && name[ name.length( ) - 1 ] == 0 ) {
|
|
|
|
buttons_.addNew( name.data( ) , name.size( ) );
|
|
|
|
} else {
|
|
|
|
buttons_.add( name.toOSString( ) );
|
|
|
|
}
|
|
|
|
return buttons_.size( );
|
|
|
|
}
|
|
|
|
|
2017-11-22 14:13:02 +01:00
|
|
|
void A_ModalDialog::initDialog( ) noexcept
|
|
|
|
{}
|
|
|
|
|
|
|
|
bool A_ModalDialog::draw( ) noexcept
|
|
|
|
{
|
|
|
|
using namespace ImGui;
|
|
|
|
if ( !open_ ) {
|
2017-11-23 12:24:40 +01:00
|
|
|
assert( buttons_.size( ) );
|
|
|
|
OpenPopup( &id_[ 0 ] );
|
2017-11-22 14:13:02 +01:00
|
|
|
open_ = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
initDialog( );
|
|
|
|
if ( initialSize_ ) {
|
|
|
|
SetNextWindowSize( *initialSize_ , ImGuiCond_Appearing );
|
|
|
|
}
|
|
|
|
|
2017-11-23 12:24:40 +01:00
|
|
|
BeginPopupModal( &id_[ 0 ] , nullptr , ImGuiWindowFlags_NoResize );
|
|
|
|
const auto btMask{ drawDialog( ) };
|
|
|
|
assert( btMask != 0 );
|
|
|
|
|
|
|
|
const ImVec2 ws( GetWindowContentRegionMax( ) );
|
|
|
|
auto const& style( GetStyle( ) );
|
|
|
|
const float innerWidth{ ws.x - 2 * style.FramePadding.x };
|
|
|
|
const auto nButtons{ buttons_.size( ) };
|
|
|
|
const ImVec2 buttonSize{
|
|
|
|
std::max( 40.f , ( innerWidth - nButtons * style.FramePadding.x ) / nButtons ) ,
|
|
|
|
0.f
|
|
|
|
};
|
|
|
|
|
|
|
|
int32_t clicked{ -1 };
|
|
|
|
for ( auto i = 0u ; i < buttons_.size( ) ; i ++ ) {
|
|
|
|
const auto m{ 1 << i };
|
|
|
|
const bool d{ ( btMask & m ) == 0 };
|
|
|
|
if ( i ) {
|
|
|
|
SameLine( 0 );
|
|
|
|
}
|
|
|
|
if ( d ) {
|
2017-11-22 14:13:02 +01:00
|
|
|
PushItemFlag( ImGuiItemFlags_Disabled , true );
|
|
|
|
PushStyleVar( ImGuiStyleVar_Alpha ,
|
|
|
|
GetStyle( ).Alpha * .5f );
|
|
|
|
}
|
2017-11-23 12:24:40 +01:00
|
|
|
if ( Button( &buttons_[ i ][ 0 ] , buttonSize ) ) {
|
|
|
|
assert( clicked == -1 );
|
|
|
|
clicked = i;
|
2017-11-22 14:13:02 +01:00
|
|
|
}
|
2017-11-23 12:24:40 +01:00
|
|
|
if ( d ) {
|
2017-11-22 14:13:02 +01:00
|
|
|
PopItemFlag( );
|
|
|
|
PopStyleVar( );
|
|
|
|
}
|
2017-11-23 12:24:40 +01:00
|
|
|
}
|
|
|
|
const bool close( clicked != -1 && onButton( clicked ) );
|
|
|
|
if ( close ) {
|
|
|
|
CloseCurrentPopup( );
|
|
|
|
}
|
|
|
|
EndPopup( );
|
|
|
|
return !close;
|
|
|
|
}
|
2017-11-22 14:13:02 +01:00
|
|
|
|
2017-11-23 12:24:40 +01:00
|
|
|
|
|
|
|
/*= T_MessageBox =============================================================*/
|
|
|
|
|
|
|
|
void T_MessageBox::setButtons(
|
|
|
|
const T_Buttons buttons ) noexcept
|
|
|
|
{
|
|
|
|
assert( buttons );
|
|
|
|
for ( auto i = 0u , nb = 0u ; i < 4 ; i ++ ) {
|
|
|
|
const E_Button b{ (E_Button) i };
|
|
|
|
const bool hasButton{ buttons & T_Buttons{ b } };
|
|
|
|
if ( !hasButton ) {
|
|
|
|
continue;
|
2017-11-22 14:13:02 +01:00
|
|
|
}
|
2017-11-23 12:24:40 +01:00
|
|
|
buttonMask_ |= ( 1 << nb );
|
|
|
|
nb ++;
|
|
|
|
buttons_.add( b );
|
|
|
|
switch ( b ) {
|
|
|
|
case BT_OK: addButton( "OK" ); break;
|
|
|
|
case BT_CANCEL: addButton( "Cancel" ); break;
|
|
|
|
case BT_YES: addButton( "Yes" ); break;
|
|
|
|
case BT_NO: addButton( "No" ); break;
|
2017-11-22 14:13:02 +01:00
|
|
|
}
|
|
|
|
}
|
2017-11-23 12:24:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
T_MessageBox::T_MessageBox(
|
|
|
|
char const* const title ,
|
|
|
|
char const* const text ,
|
|
|
|
F_Handler handler ,
|
|
|
|
const T_Buttons buttons ) noexcept
|
|
|
|
: A_ModalDialog( title ) , text_{ text , strlen( text ) + 1 } ,
|
|
|
|
handler_{ std::move( handler ) }
|
|
|
|
{
|
|
|
|
setButtons( buttons );
|
|
|
|
setInitialSize( 300.f , 100.f );
|
|
|
|
}
|
|
|
|
|
|
|
|
T_MessageBox::T_MessageBox(
|
|
|
|
T_String const& title ,
|
|
|
|
T_String const& text ,
|
|
|
|
F_Handler handler ,
|
|
|
|
const T_Buttons buttons ) noexcept
|
|
|
|
: A_ModalDialog( title ) , handler_{ std::move( handler ) }
|
|
|
|
{
|
|
|
|
if ( text && text[ text.length( ) - 1 ] == 0 ) {
|
|
|
|
text_ = ebcl::T_Buffer< char >{ text.data( ) , text.size( ) };
|
|
|
|
} else {
|
|
|
|
text_ = text.toOSString( );
|
|
|
|
}
|
|
|
|
setButtons( buttons );
|
|
|
|
setInitialSize( 300.f , 100.f );
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t T_MessageBox::drawDialog( ) noexcept
|
|
|
|
{
|
|
|
|
ImGui::TextWrapped( "%s" , &text_[ 0 ] );
|
|
|
|
return buttonMask_;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool T_MessageBox::onButton(
|
|
|
|
uint8_t button ) noexcept
|
|
|
|
{
|
|
|
|
assert( button < buttons_.size( ) );
|
|
|
|
if ( handler_ ) {
|
|
|
|
handler_( buttons_[ button ] );
|
|
|
|
}
|
|
|
|
return true;
|
2017-11-22 14:13:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*= T_Window =================================================================*/
|
|
|
|
|
2017-11-21 17:32:52 +01:00
|
|
|
namespace {
|
|
|
|
#include "font-awesome.inl"
|
|
|
|
|
|
|
|
static const ImWchar IconsRanges_[] = {
|
|
|
|
ICON_MIN_FA ,
|
|
|
|
ICON_MAX_FA ,
|
|
|
|
0
|
|
|
|
};
|
2017-11-22 14:13:02 +01:00
|
|
|
} // namespace <anon>
|
2017-10-04 11:20:27 +02:00
|
|
|
|
|
|
|
T_Window::T_Window( )
|
|
|
|
{
|
|
|
|
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 , ¤t );
|
|
|
|
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 );
|
2017-11-20 21:54:46 +01:00
|
|
|
|
|
|
|
using namespace ImGui;
|
2017-11-21 17:32:52 +01:00
|
|
|
StyleColorsDark( );
|
2017-11-20 21:54:46 +01:00
|
|
|
ImGuiIO& io{ GetIO( ) };
|
2017-11-22 09:01:51 +01:00
|
|
|
io.IniFilename = nullptr;
|
2017-11-20 21:54:46 +01:00
|
|
|
{
|
|
|
|
ImFontConfig cfg;
|
|
|
|
cfg.SizePixels = 13.0f;
|
|
|
|
defaultFont_ = io.Fonts->AddFontDefault( &cfg );
|
2017-11-21 17:32:52 +01:00
|
|
|
|
|
|
|
ImFontConfig icons;
|
|
|
|
icons.MergeMode = true;
|
|
|
|
icons.PixelSnapH = true;
|
|
|
|
io.Fonts->AddFontFromMemoryCompressedBase85TTF(
|
|
|
|
FontAwesome__compressed_data_base85 , 13.f ,
|
|
|
|
&icons , IconsRanges_ );
|
2017-11-20 21:54:46 +01:00
|
|
|
}
|
|
|
|
{
|
|
|
|
ImFontConfig cfg;
|
|
|
|
cfg.SizePixels = 9.0f;
|
|
|
|
smallFont_ = io.Fonts->AddFontDefault( &cfg );
|
2017-11-21 17:32:52 +01:00
|
|
|
|
|
|
|
ImFontConfig icons;
|
|
|
|
icons.MergeMode = true;
|
|
|
|
icons.PixelSnapH = true;
|
|
|
|
icons.DstFont = smallFont_;
|
|
|
|
io.Fonts->AddFontFromMemoryCompressedBase85TTF(
|
|
|
|
FontAwesome__compressed_data_base85 , 9.f ,
|
|
|
|
&icons , IconsRanges_ );
|
2017-11-20 21:54:46 +01:00
|
|
|
}
|
2017-10-04 11:20:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
T_Window::~T_Window( )
|
|
|
|
{
|
|
|
|
ImGui_ImplSdl_Shutdown( );
|
|
|
|
SDL_GL_DeleteContext( gl );
|
|
|
|
SDL_DestroyWindow( window );
|
|
|
|
SDL_Quit( );
|
|
|
|
}
|
|
|
|
|
|
|
|
void T_Window::startFrame(
|
2017-11-03 09:08:19 +01:00
|
|
|
const bool capture ,
|
|
|
|
ImVec2 const& mouseInitial ) const
|
2017-10-04 11:20:27 +02:00
|
|
|
{
|
|
|
|
ImGui_ImplSdl_NewFrame( window , capture , mouseInitial );
|
|
|
|
}
|
|
|
|
|
|
|
|
void T_Window::warpMouse(
|
2017-11-03 09:08:19 +01:00
|
|
|
ImVec2 const& pos ) const
|
2017-10-04 11:20:27 +02:00
|
|
|
{
|
|
|
|
SDL_WarpMouseInWindow( window , pos.x , pos.y );
|
|
|
|
}
|
|
|
|
|
|
|
|
void T_Window::swap( ) const
|
|
|
|
{
|
|
|
|
SDL_GL_SwapWindow( window );
|
|
|
|
}
|
2017-11-22 14:13:02 +01:00
|
|
|
|
|
|
|
void T_Window::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( );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|