ImGui styles: Allow writing only changed values to C++ code

This commit is contained in:
Daniel Gibson 2024-05-26 03:56:28 +02:00
parent 2a7683ebaa
commit c0b6660389
4 changed files with 68 additions and 42 deletions

View file

@ -1602,11 +1602,17 @@ static void DrawOtherOptionsMenu()
}
AddTooltip( "Writes the current style settings (incl. colors) as userstyle" );
static bool onlyChanges = false;
if ( ImGui::Button( "Copy style code to clipboard" ) ) {
D3::ImGuiHooks::CopyCurrentStyle();
D3::ImGuiHooks::CopyCurrentStyle( onlyChanges );
}
AddTooltip( "Generates C++ code for the current style settings (incl. colors) and copies it into the clipboard" );
ImGui::SameLine();
ImGui::Checkbox( "Only changed settings", &onlyChanges );
AddTooltip( "Only generate C++ code for attributes/colors that are changed compared to the default (dark) ImGui theme" );
ImGui::Spacing();
if ( ImGui::Button( "Show ImGui Demo" ) ) {

View file

@ -54,7 +54,8 @@ namespace DG {
// generate C++ code that replicates the given style into a text buffer
// (that you can write to a file or set the clipboard from or whatever)
extern ImGuiTextBuffer WriteImGuiStyleToCode( const ImGuiStyle& s );
// if refStyle is set, only differences in style compared to refStyle are written
extern ImGuiTextBuffer WriteImGuiStyleToCode( const ImGuiStyle& style, const ImGuiStyle* refStyle = nullptr );
} //namespace
#endif
@ -424,20 +425,28 @@ static inline int numSpaces( const char* name, int targetLen )
return ret > 0 ? ret : 0;
}
ImGuiTextBuffer WriteImGuiStyleToCode( const ImGuiStyle& s )
ImGuiTextBuffer WriteImGuiStyleToCode( const ImGuiStyle& s, const ImGuiStyle* refStyle )
{
ImGuiTextBuffer ret;
ret.reserve(6000);
ret.append( "ImGuiStyle& style = ImGui::GetStyle();\n" );
#define D3_IMATTR_FLOAT( NAME ) \
ret.appendf( "style.%s %*s= %g;\n", #NAME, numSpaces( #NAME , 27 ), "", s. NAME );
if ( refStyle == nullptr || s. NAME != refStyle-> NAME ) { \
ret.appendf( "style.%s %*s= %g;\n", #NAME, numSpaces( #NAME , 27 ), "", s. NAME ); \
}
#define D3_IMATTR_VEC2( NAME ) \
ret.appendf( "style.%s %*s= ImVec2( %g, %g );\n", #NAME, numSpaces( #NAME , 27 ), "", s. NAME .x, s. NAME .y );
if ( refStyle == nullptr || s. NAME .x != refStyle-> NAME .x || s. NAME .y != refStyle-> NAME .y ) { \
ret.appendf( "style.%s %*s= ImVec2( %g, %g );\n", #NAME, numSpaces( #NAME , 27 ), "", s. NAME .x, s. NAME .y ); \
}
#define D3_IMATTR_INT( NAME ) \
ret.appendf( "style.%s = %d; // TODO: flag\n", #NAME, s. NAME );
if ( refStyle == nullptr || s. NAME != refStyle-> NAME ) { \
ret.appendf( "style.%s = %d; // TODO: flag\n", #NAME, s. NAME ); \
}
#define D3_IMATTR_BOOL( NAME ) \
ret.appendf( "style.%s %*s= %s;\n", #NAME, numSpaces( #NAME , 27 ), "", s. NAME ? "true" : "false" );
if ( refStyle == nullptr || s. NAME != refStyle-> NAME ) { \
ret.appendf( "style.%s %*s= %s;\n", #NAME, numSpaces( #NAME , 27 ), "", s. NAME ? "true" : "false" ); \
}
D3_IMSTYLE_ATTRS
@ -452,16 +461,20 @@ ImGuiTextBuffer WriteImGuiStyleToCode( const ImGuiStyle& s )
ret.append( "\nImVec4* colors = style.Colors;\n" );
#define D3_IMSTYLE_COLOR( NAME ) { \
const ImVec4& c = s.Colors[ ImGuiCol_ ## NAME ]; \
ret.appendf( "colors[ ImGuiCol_%s ]%*s = ImVec4( %g, %g, %g, %g );\n", #NAME, \
numSpaces( #NAME , 21 ), "", c.x, c.y, c.z, c.w ); \
for ( ImGuiCol cIdx=0; cIdx < ImGuiCol_COUNT; ++cIdx ) {
const ImVec4& c = s.Colors[cIdx];
if ( refStyle != nullptr ) {
const ImVec4& c2 = refStyle->Colors[cIdx];
if ( c.x == c2.x && c.y == c2.y && c.z == c2.z && c.w == c2.w ) {
// same colors, nothing to do
continue;
}
}
const char* name = ImGui::GetStyleColorName( cIdx );
ret.appendf( "colors[ ImGuiCol_%s ]%*s = ImVec4( %g, %g, %g, %g );\n",
name, numSpaces( name , 21 ), "", c.x, c.y, c.z, c.w );
}
D3_IMSTYLE_COLORS
#undef D3_IMSTYLE_COLOR
ret.append("\n");
return ret;

View file

@ -28,21 +28,22 @@ idCVar imgui_style( "imgui_style", "0", CVAR_SYSTEM|CVAR_INTEGER|CVAR_ARCHIVE, "
// implemented in imgui_savestyle.cpp
namespace DG {
// writes the given ImGuiStyle to the given filename (opened with fopen())
// returns true on success, false if opening the file failed
extern bool WriteImGuiStyle( const ImGuiStyle& style, const char* filename );
// writes the given ImGuiStyle to the given filename (opened with fopen())
// returns true on success, false if opening the file failed
extern bool WriteImGuiStyle( const ImGuiStyle& style, const char* filename );
// reads the the given filename (opened with fopen())
// and sets the given ImGuiStyle accordingly.
// if any attributes/colors/behaviors are missing the the file,
// they are not modified in style, so it probably makes sense to initialize
// style to a sane default before calling that function.
// returns true on success, false if opening the file failed
extern bool ReadImGuiStyle( ImGuiStyle& style, const char* filename );
// reads the the given filename (opened with fopen())
// and sets the given ImGuiStyle accordingly.
// if any attributes/colors/behaviors are missing the the file,
// they are not modified in style, so it probably makes sense to initialize
// style to a sane default before calling this function.
// returns true on success, false if opening the file failed
extern bool ReadImGuiStyle( ImGuiStyle& style, const char* filename );
// generate C++ code that replicates the given style into a text buffer
// (that you can either write to a file or set the clipboard from or whatever)
extern ImGuiTextBuffer WriteImGuiStyleToCode( const ImGuiStyle& s );
// generate C++ code that replicates the given style into a text buffer
// (that you can write to a file or set the clipboard from or whatever)
// if refStyle is set, only differences in style compared to refStyle are written
extern ImGuiTextBuffer WriteImGuiStyleToCode( const ImGuiStyle& style, const ImGuiStyle* refStyle = nullptr );
} //namespace DG
namespace D3 {
@ -476,11 +477,10 @@ int GetOpenWindowsMask()
return openImguiWindows;
}
void SetImGuiStyle( Style d3style )
ImGuiStyle GetImGuiStyle( Style d3style )
{
ImGuiStyle& style = ImGui::GetStyle();
ImGuiStyle style; // default style
if ( d3style == Style::Dhewm3 ) {
style = ImGuiStyle(); // start with default style
// make it look a bit nicer with rounded edges
style.WindowRounding = 2.0f;
style.FrameRounding = 3.0f;
@ -488,21 +488,27 @@ void SetImGuiStyle( Style d3style )
style.ScrollbarRounding = 8.0f;
style.GrabRounding = 1.0f;
style.PopupRounding = 2.0f;
SetDhewm3StyleColors();
SetDhewm3StyleColors( &style );
} else if ( d3style == Style::User ) {
style = userStyle;
} else {
assert( d3style == Style::ImGui_Default && "invalid/unknown style" );
style = ImGuiStyle();
ImGui::StyleColorsDark();
ImGui::StyleColorsDark( &style );
}
return style;
}
void SetDhewm3StyleColors()
void SetImGuiStyle( Style d3style )
{
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
ImVec4* colors = style.Colors;
ImGui::GetStyle() = GetImGuiStyle( d3style );
}
void SetDhewm3StyleColors( ImGuiStyle* dst )
{
if ( dst == nullptr )
dst = &ImGui::GetStyle();
ImGui::StyleColorsDark( dst );
ImVec4* colors = dst->Colors;
colors[ImGuiCol_TitleBg] = ImVec4(0.28f, 0.36f, 0.48f, 0.88f);
colors[ImGuiCol_TabHovered] = ImVec4(0.42f, 0.69f, 1.00f, 0.80f);
colors[ImGuiCol_TabActive] = ImVec4(0.24f, 0.51f, 0.83f, 1.00f);
@ -526,9 +532,10 @@ bool WriteUserStyle()
return true;
}
void CopyCurrentStyle()
void CopyCurrentStyle( bool onlyChanges )
{
ImGuiTextBuffer buf = DG::WriteImGuiStyleToCode( ImGui::GetStyle() );
ImGuiStyle refStyle = GetImGuiStyle( Style::ImGui_Default );
ImGuiTextBuffer buf = DG::WriteImGuiStyleToCode( ImGui::GetStyle(), onlyChanges ? &refStyle : nullptr );
Sys_SetClipboardData( buf.c_str() );
}

View file

@ -71,14 +71,14 @@ enum Style {
extern void SetImGuiStyle( Style style );
// set the default dhewm3 imgui style colors
extern void SetDhewm3StyleColors();
extern void SetDhewm3StyleColors( ImGuiStyle* dst = nullptr );
extern void SetUserStyleColors();
// write current style settings (incl. colors) as userStyle
extern bool WriteUserStyle();
// copy current style to clipboard
extern void CopyCurrentStyle();
extern void CopyCurrentStyle( bool onlyChanges );
#else // IMGUI_DISABLE - just stub out everything