Sequencer - Some work towards having a zoomable thing

Display areas for the header and the sequencer itself; writes lewd text
in the header with the appropriate font; computes some of the data for
proper zooming, and prints it to stdout because fuck you, that's why.
This commit is contained in:
Emmanuel BENOîT 2017-11-20 21:54:46 +01:00
parent 037fea3101
commit 3fd377699f
5 changed files with 137 additions and 2 deletions

View file

@ -76,6 +76,10 @@ void T_Main::mainLoop( )
if ( needInit ) { if ( needInit ) {
initDemo( ); initDemo( );
} }
#warning FIXME remove this
if ( !sequencer ) {
sequencer.setNew( );
}
Globals::Watcher( ).check( ); Globals::Watcher( ).check( );
Globals::Shaders( ).update( ); Globals::Shaders( ).update( );

View file

@ -289,6 +289,11 @@ struct T_SyncManager : public virtual A_MouseCtrl
float duration( ) const noexcept float duration( ) const noexcept
{ return time_.duration( ); } { return time_.duration( ); }
uint32_t durationUnits( ) const noexcept
{ return time_.iDuration; }
float durationUnitSize( ) const noexcept
{ return time_.uDuration; }
void setTime( const float time ); void setTime( const float time );
void timeDelta( const float delta ) void timeDelta( const float delta )
{ setTime( time_.time + delta ); } { setTime( time_.time + delta ); }

View file

@ -1,6 +1,10 @@
#include "externals.hh" #include "externals.hh"
#include "syncview.hh" #include "syncview.hh"
#include "globals.hh" #include "globals.hh"
#include "window.hh"
#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui_internal.h>
using namespace ebcl; using namespace ebcl;
@ -10,7 +14,19 @@ namespace {
struct T_SyncViewImpl_ struct T_SyncViewImpl_
{ {
static constexpr float SeqHeaderHeight = 24;
static constexpr float MinUnitWidth = 80;
const uint32_t ColFrame{ ImGui::GetColorU32( ImVec4{ 0 , 0 , 0 , .8 } ) };
const uint32_t ColHeader{ ImGui::GetColorU32( ImVec4{ .5 , .5 , .5 , .8 } ) };
const uint32_t ColHeaderText{ ImGui::GetColorU32( ImVec4{ 0 , 0 , 0 , 1 } ) };
const uint32_t ColMain{ ImGui::GetColorU32( ImVec4{ .4 , .4 , .4 , .8 } ) };
float zoomLevel{ 1.f };
bool display( ) noexcept; bool display( ) noexcept;
void sequencerWidget( ) noexcept;
void sequencerHeader( ImRect const& bb ) noexcept;
}; };
@ -24,8 +40,10 @@ bool T_SyncViewImpl_::display( ) noexcept
SetNextWindowSize( ImVec2( dspSize.x , 150 ) , ImGuiSetCond_Appearing ); SetNextWindowSize( ImVec2( dspSize.x , 150 ) , ImGuiSetCond_Appearing );
SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) , ImGuiSetCond_Appearing ); SetNextWindowPos( ImVec2( 0 , dspSize.y - 150 ) , ImGuiSetCond_Appearing );
bool displayed{ true }; bool displayed{ true };
Begin( "Sequencer" , &displayed , ImGuiWindowFlags_NoCollapse ); Begin( "Sequencer" , &displayed , ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoScrollWithMouse );
if ( !displayed ) { if ( !displayed ) {
End( );
return false; return false;
} }
@ -46,11 +64,98 @@ bool T_SyncViewImpl_::display( ) noexcept
} }
PopItemWidth( ); PopItemWidth( );
PopID( ); PopID( );
End( );
PushItemWidth( -1 );
sequencerWidget( );
PopItemWidth( );
End( );
return true; return true;
} }
void T_SyncViewImpl_::sequencerWidget( ) noexcept
{
using namespace ImGui;
const auto width{ CalcItemWidth( ) };
auto* const win( GetCurrentWindow( ) );
const auto seqId{ win->GetID( "##sequencer" ) };
const ImVec2 cPos( win->DC.CursorPos );
const ImVec2 ws( GetWindowContentRegionMax( ) );
auto& style( ImGui::GetStyle( ) );
const ImRect bbHeader{ cPos , cPos + ImVec2( width , SeqHeaderHeight ) };
const ImRect bbDisplay{ ImVec2{ cPos.x , bbHeader.Max.y } ,
ImVec2{ cPos.x + width , GetWindowPos( ).y + ws.y - style.FramePadding.y } };
const ImRect bbAll{ bbHeader.Min , bbDisplay.Max };
ItemSize( bbAll , style.FramePadding.y );
if ( !ItemAdd( bbAll , seqId ) ) {
return;
}
/*
* Scaling:
* At minimal zoom level, we want the whole "track" to fit inside the
* available width.
* At maximal zoom level, we want units from the sync manager to cover
* $MIN_UNIT_WIDTH pixels (that should depend on the text size).
* The displayed size of the units increases along with the zoom level.
* Display units are rescaled when the distance between them
* becomes >= 2 * $MIN_UNIT_WIDTH
* At worst, the sequence is only one unit long; this means that no
* scaling occurs between minimal and maximal levels.
*/
auto& sync( Globals::Sync( ) );
const uint32_t units{ sync.durationUnits( ) };
const float maxZoomUnits{ width / MinUnitWidth };
const float slope{ maxZoomUnits - units };
const float dUnits{ units + zoomLevel * slope };
printf( "%d units ; %f/screen at max zoom ; slope %f ; display %f units at ZL %f\n" , units , maxZoomUnits , slope , dUnits , zoomLevel );
PushID( seqId );
BeginGroup( );
const auto hdrId{ win->GetID( "##header" ) };
const auto dspId{ win->GetID( "##display" ) };
auto* const dl( GetWindowDrawList( ) );
if ( ItemAdd( bbHeader , hdrId ) ) {
PushID( hdrId );
sequencerHeader( bbHeader );
PopID( );
}
if ( bbDisplay.Min.y < bbDisplay.Max.y && ItemAdd( bbDisplay , dspId ) ) {
// XXX display main area
dl->AddRectFilled( bbDisplay.Min , bbDisplay.Max ,
ImGui::GetColorU32( ImVec4( .4 , .4 , .4 , .8 ) ) );
}
EndGroup( );
PopID( );
}
void T_SyncViewImpl_::sequencerHeader(
ImRect const& bb ) noexcept
{
using namespace ImGui;
auto* const dl( GetWindowDrawList( ) );
PushFont( Globals::Window( ).smallFont( ) );
PushStyleColor( ImGuiCol_Text , ColHeaderText );
dl->AddRectFilled( bb.Min + ImVec2( 1 , 1 ) , bb.Max - ImVec2( 1 , 1 ) ,
ColHeader );
dl->AddRect( bb.Min , bb.Max , ColFrame );
const ImRect textBb{ bb.Min - ImVec2{ 10 , 0 } , bb.Max + ImVec2{ 10 , 0 } };
RenderTextClipped( textBb.Min , textBb.Max , "test!" , nullptr , nullptr , ImVec2{ 0 , .25 } , &bb );
RenderTextClipped( textBb.Min , textBb.Max , "...icle" , nullptr , nullptr , ImVec2{ 0 , .75 } , &bb );
PopStyleColor( );
PopFont( );
}
} // namespace } // namespace
/*= T_SyncView =================================================================*/ /*= T_SyncView =================================================================*/

View file

@ -1,6 +1,7 @@
#include "externals.hh" #include "externals.hh"
#include "window.hh" #include "window.hh"
#include "imgui_impl_sdl.h" #include "imgui_impl_sdl.h"
#include <imgui_internal.h>
T_Window::T_Window( ) T_Window::T_Window( )
@ -27,6 +28,19 @@ T_Window::T_Window( )
} }
ImGui_ImplSdl_Init( window ); ImGui_ImplSdl_Init( window );
using namespace ImGui;
ImGuiIO& io{ GetIO( ) };
{
ImFontConfig cfg;
cfg.SizePixels = 13.0f;
defaultFont_ = io.Fonts->AddFontDefault( &cfg );
}
{
ImFontConfig cfg;
cfg.SizePixels = 9.0f;
smallFont_ = io.Fonts->AddFontDefault( &cfg );
}
} }
T_Window::~T_Window( ) T_Window::~T_Window( )

View file

@ -15,8 +15,15 @@ struct T_Window
void swap( ) const; void swap( ) const;
ImFont* defaultFont( ) const noexcept
{ return defaultFont_; }
ImFont* smallFont( ) const noexcept
{ return smallFont_; }
private: private:
SDL_Window * window; SDL_Window * window;
SDL_GLContext gl; SDL_GLContext gl;
ImFont* defaultFont_;
ImFont* smallFont_;
}; };