demotool/ui-utilities.cc

184 lines
4.8 KiB
C++
Raw Normal View History

#include "externals.hh"
#include "c-camera.hh"
#include "c-utilities.hh"
#include "ui-utilities.hh"
#include <imgui_internal.h>
void ImGui::PushDisabled( ) noexcept
{
PushItemFlag( ImGuiItemFlags_Disabled , true );
PushStyleVar( ImGuiStyleVar_Alpha , GetStyle( ).Alpha * .5f );
}
void ImGui::PopDisabled( ) noexcept
{
PopItemFlag( );
PopStyleVar( );
}
/*------------------------------------------------------------------------------*/
bool ImGui::MenuItemCheckbox(
char const* name ,
bool* checked ) noexcept
{
bool rv{ MenuItem( name , "" , *checked , true ) };
if ( rv ) {
*checked = !*checked;
}
return rv;
}
/*------------------------------------------------------------------------------*/
bool ImGui::ToolbarButton(
char const* const string ,
ImVec2 const& size ,
char const* const tooltip ,
bool enabled ) noexcept
{
if ( !enabled ) {
PushDisabled( );
}
const bool rv{ Button( string , size ) };
if ( !enabled ) {
PopDisabled( );
} else if ( tooltip && IsItemHovered( ) ) {
BeginTooltip( );
Text( tooltip );
EndTooltip( );
}
return rv;
}
void ImGui::ToolbarSeparator( ) noexcept
{
SameLine( );
VerticalSeparator( );
SameLine( );
}
/*= T_CameraMouseControl =======================================================*/
void T_CameraMouseControl::handleDragAndDrop(
ImVec2 const& move ,
T_KeyboardModifiers modifiers ,
T_MouseButtons buttons ) noexcept
{
if ( move.x == 0 || move.y == 0 ) {
return;
}
const float fdx( move.x * .1f * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f ) );
const float fdy( move.y * .1f * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f ) );
if ( ( buttons & E_MouseButton::LEFT ) && ( modifiers & E_KeyboardModifier::SHIFT ) ) {
// Left mouse button, shift - move camera
const auto side( normalize( cross( camera.upVector( ) , camera.direction( ) ) ) );
camera.lookAt( ) += .1f * ( side * fdx + camera.upVector( ) * fdy );
} else if ( buttons & E_MouseButton::LEFT ) {
// Left mouse button, no shift - change yaw/pitch
updateAngle( camera.angles( ).y , fdx );
updateAngle( camera.angles( ).x , fdy );
} else if ( buttons & E_MouseButton::RIGHT ) {
// Right mouse button - change roll
updateAngle( camera.angles( ).z , fdx );
}
camera.cvtAnglesToVectors( );
}
void T_CameraMouseControl::handleWheel(
const float wheel ,
T_KeyboardModifiers modifiers ,
T_MouseButtons /* buttons */ ) noexcept
{
const float delta( wheel * ( ( modifiers & E_KeyboardModifier::CTRL ) ? 1.f : .1f) );
if ( modifiers & E_KeyboardModifier::SHIFT ) {
camera.fieldOfView( ) = ImClamp( camera.fieldOfView( ) + delta , 1.f , 179.f );
camera.cvtFov2Np( );
} else {
camera.distance( ) = std::max( .01f , camera.distance( ) - delta );
camera.cvtAnglesToVectors( );
}
}
/*----------------------------------------------------------------------------*/
T_CameraChanges CameraUI( T_Camera& camera ) noexcept
{
using namespace ImGui;
// What gets changed
static const T_CameraChanges changeFlags[] = {
E_CameraChange::MATRIX ,
{} ,
E_CameraChange::MATRIX ,
E_CameraChange::MATRIX ,
{} ,
E_CameraChange::MATRIX ,
E_CameraChange::MATRIX ,
{} ,
E_CameraChange::FOV ,
E_CameraChange::FOV ,
};
// Which update gets called.
enum E_ChangeCall_ {
CC_NONE ,
CC_FROM_VECTORS ,
CC_FROM_ANGLES ,
CC_FROM_FOV ,
CC_FROM_NP ,
};
static const E_ChangeCall_ changeCalls[] = {
CC_FROM_ANGLES ,
CC_NONE ,
CC_FROM_ANGLES ,
CC_FROM_ANGLES ,
CC_NONE ,
CC_FROM_VECTORS ,
CC_FROM_VECTORS ,
CC_NONE ,
CC_FROM_FOV ,
CC_FROM_NP ,
};
static_assert( IM_ARRAYSIZE( changeFlags ) == IM_ARRAYSIZE( changeCalls ) ,
"invalid configuration" );
// Changes (also draws the fields)
const bool changed[] = {
DragFloat3( "Target" , &camera.lookAt( ).x ) ,
( Separator( ) , false ) ,
DragFloat( "Distance" , &camera.distance( ) , .1f , .1f , 1e8 , "%.1f" ) ,
DragFloat3( "Angles" , &camera.angles( ).x , .01f , -180 , 180 ) ,
( Separator( ) , false ) ,
DragFloat3( "Position" , &camera.position( ).x ) ,
DragFloat3( "Up vector" , &camera.upVector( ).x ) ,
( Separator( ) , false ) ,
DragFloat( "FoV" , &camera.fieldOfView( ) , .01f , .01f , 179.9f ) ,
DragFloat( "Near plane" , &camera.nearPlane( ) , .00001f , .001f , 1e6f ) ,
};
static_assert( IM_ARRAYSIZE( changeFlags ) == IM_ARRAYSIZE( changed ) ,
"invalid configuration" );
T_CameraChanges changes;
for ( unsigned i = 0 ; i < IM_ARRAYSIZE( changed ) ; i ++ ) {
if ( changed[ i ] ) {
switch ( changeCalls[ i ] ) {
case CC_NONE: break;
case CC_FROM_VECTORS: camera.cvtVectorsToAngles( ); break;
case CC_FROM_ANGLES: camera.cvtAnglesToVectors( ); break;
case CC_FROM_FOV: camera.cvtFov2Np( ); break;
case CC_FROM_NP: camera.cvtNp2Fov( ); break;
}
changes = changes | changeFlags[ i ];
}
}
return changes;
}