diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 7b1dbf07..408ee1e9 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -8075,24 +8075,60 @@ df_cfg_strings_from_gfx(Arena *arena, String8 root_path, DF_CfgSrc source) //- rjf: serialize theme colors if(source == DF_CfgSrc_User) { + // rjf: determine if this theme matches an existing preset + B32 is_preset = 0; + DF_ThemePreset matching_preset = DF_ThemePreset_DefaultDark; + { + for(DF_ThemePreset p = (DF_ThemePreset)0; p < DF_ThemePreset_COUNT; p = (DF_ThemePreset)(p+1)) + { + B32 matches_this_preset = 1; + for(DF_ThemeColor c = (DF_ThemeColor)(DF_ThemeColor_Null+1); c < DF_ThemeColor_COUNT; c = (DF_ThemeColor)(c+1)) + { + if(!MemoryMatchStruct(&df_gfx_state->cfg_theme_target.colors[c], &df_g_theme_preset_colors_table[p][c])) + { + matches_this_preset = 0; + break; + } + } + if(matches_this_preset) + { + is_preset = 1; + matching_preset = p; + break; + } + } + } + + // rjf: serialize header String8 indent_str = str8_lit(" "); str8_list_push(arena, &strs, str8_lit("/// colors ////////////////////////////////////////////////////////////////////\n")); str8_list_push(arena, &strs, str8_lit("\n")); - str8_list_push(arena, &strs, str8_lit("colors:\n")); - str8_list_push(arena, &strs, str8_lit("{\n")); - for(DF_ThemeColor color = (DF_ThemeColor)(DF_ThemeColor_Null+1); - color < DF_ThemeColor_COUNT; - color = (DF_ThemeColor)(color+1)) + + // rjf: serialize preset theme + if(is_preset) { - String8 color_name = df_g_theme_color_cfg_string_table[color]; - Vec4F32 color_rgba = df_gfx_state->cfg_theme_target.colors[color]; - String8 color_hex = hex_string_from_rgba_4f32(arena, color_rgba); - str8_list_pushf(arena, &strs, " %S:%.*s0x%S\n", - color_name, - 30 > color_name.size ? ((int)(30 - color_name.size)) : 0, indent_str.str, - color_hex); + str8_list_pushf(arena, &strs, "color_preset: \"%S\"\n\n", df_g_theme_preset_code_string_table[matching_preset]); + } + + // rjf: serialize non-preset theme + if(!is_preset) + { + str8_list_push(arena, &strs, str8_lit("colors:\n")); + str8_list_push(arena, &strs, str8_lit("{\n")); + for(DF_ThemeColor color = (DF_ThemeColor)(DF_ThemeColor_Null+1); + color < DF_ThemeColor_COUNT; + color = (DF_ThemeColor)(color+1)) + { + String8 color_name = df_g_theme_color_cfg_string_table[color]; + Vec4F32 color_rgba = df_gfx_state->cfg_theme_target.colors[color]; + String8 color_hex = hex_string_from_rgba_4f32(arena, color_rgba); + str8_list_pushf(arena, &strs, " %S:%.*s0x%S\n", + color_name, + 30 > color_name.size ? ((int)(30 - color_name.size)) : 0, indent_str.str, + color_hex); + } + str8_list_push(arena, &strs, str8_lit("}\n\n")); } - str8_list_push(arena, &strs, str8_lit("}\n\n")); } //- rjf: serialize fonts @@ -11477,6 +11513,29 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) } } + //- rjf: apply theme presets + DF_CfgVal *color_preset = df_cfg_val_from_string(table, str8_lit("color_preset")); + if(color_preset != &df_g_nil_cfg_val) + { + String8 color_preset_name = color_preset->last->first->string; + DF_ThemePreset preset = (DF_ThemePreset)0; + B32 found_preset = 0; + for(DF_ThemePreset p = (DF_ThemePreset)0; p < DF_ThemePreset_COUNT; p = (DF_ThemePreset)(p+1)) + { + if(str8_match(color_preset_name, df_g_theme_preset_code_string_table[p], StringMatchFlag_CaseInsensitive)) + { + found_preset = 1; + preset = p; + break; + } + } + if(found_preset) + { + MemoryCopy(df_gfx_state->cfg_theme_target.colors, df_g_theme_preset_colors_table[preset], sizeof(df_g_theme_preset_colors__default_dark)); + MemoryCopy(df_gfx_state->cfg_theme.colors, df_g_theme_preset_colors_table[preset], sizeof(df_g_theme_preset_colors__default_dark)); + } + } + //- rjf: if theme colors are all zeroes, then set to default - config appears busted { B32 all_colors_are_zero = 1; diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index d3a0f77c..8d6eb654 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -308,62 +308,62 @@ DF_GfxViewRuleTable: //////////////////////////////// //~ rjf: Theme Color Codes -@table(name display_name name_lower r g b a) +@table(name display_name name_lower allow_zero_on_load) DF_ThemeTable: { - {Null "Null" null } - {PlainText "Plain Text" plain_text } - {PlainBackground "Plain Background" plain_background } - {PlainBorder "Plain Border" plain_border } - {PlainOverlay "Plain Overlay" plain_overlay } - {CodeDefault "Code (Default)" code_default } - {CodeFunction "Code (Function)" code_function } - {CodeType "Code (Type)" code_type } - {CodeLocal "Code (Local)" code_local } - {CodeKeyword "Code (Keyword)" code_keyword } - {CodeSymbol "Code (Symbol)" code_symbol } - {CodeNumeric "Code (Numeric)" code_numeric } - {CodeString "Code (String)" code_string } - {CodeMeta "Code (Meta)" code_meta } - {CodeComment "Code (Comment)" code_comment } - {LineInfo0 "Line Info (0)" line_info_0 } - {LineInfo1 "Line Info (1)" line_info_1 } - {LineInfo2 "Line Info (2)" line_info_2 } - {LineInfo3 "Line Info (3)" line_info_3 } - {AltText "Alt Text" alt_text } - {AltBackground "Alt Background" alt_background } - {AltBorder "Alt Border" alt_border } - {AltOverlay "Alt Overlay" alt_overlay } - {TabInactive "Inactive Tab" tab_inactive } - {TabActive "Active Tab" tab_active } - {EntityBackground "Entity Background" entity_background } - {QueryBar "Query Bar" query_bar } - {WeakText "Weak Text" weak_text } - {TextSelection "Text Selection" text_selection } - {Cursor "Cursor" cursor } - {Highlight0 "Highlight (0)" highlight_0 } - {Highlight1 "Highlight (1)" highlight_1 } - {SuccessText "Success Text" success_text } - {SuccessBackground "Success Background" success_background } - {SuccessBorder "Success Border" success_border } - {FailureText "Failure Text" failure_text } - {FailureBackground "Failure Background" failure_background } - {FailureBorder "Failure Border" failure_border } - {ActionText "Action Text" action_text } - {ActionBackground "Action Background" action_background } - {ActionBorder "Action Border" action_border } - {DropSiteOverlay "Drop Site Overlay" drop_site_overlay } - {Thread0 "Thread (0)" thread_0 } - {Thread1 "Thread (1)" thread_1 } - {Thread2 "Thread (2)" thread_2 } - {Thread3 "Thread (3)" thread_3 } - {Thread4 "Thread (4)" thread_4 } - {Thread5 "Thread (5)" thread_5 } - {Thread6 "Thread (6)" thread_6 } - {Thread7 "Thread (7)" thread_7 } - {ThreadUnwound "Thread (Unwound)" thread_unwound } - {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay } - {DropShadow "Drop Shadow" drop_shadow } + {Null "Null" null 0} + {PlainText "Plain Text" plain_text 0} + {PlainBackground "Plain Background" plain_background 0} + {PlainBorder "Plain Border" plain_border 0} + {PlainOverlay "Plain Overlay" plain_overlay 0} + {CodeDefault "Code (Default)" code_default 0} + {CodeFunction "Code (Function)" code_function 0} + {CodeType "Code (Type)" code_type 0} + {CodeLocal "Code (Local)" code_local 0} + {CodeKeyword "Code (Keyword)" code_keyword 0} + {CodeSymbol "Code (Symbol)" code_symbol 0} + {CodeNumeric "Code (Numeric)" code_numeric 0} + {CodeString "Code (String)" code_string 0} + {CodeMeta "Code (Meta)" code_meta 0} + {CodeComment "Code (Comment)" code_comment 0} + {LineInfo0 "Line Info (0)" line_info_0 0} + {LineInfo1 "Line Info (1)" line_info_1 0} + {LineInfo2 "Line Info (2)" line_info_2 0} + {LineInfo3 "Line Info (3)" line_info_3 0} + {AltText "Alt Text" alt_text 0} + {AltBackground "Alt Background" alt_background 0} + {AltBorder "Alt Border" alt_border 0} + {AltOverlay "Alt Overlay" alt_overlay 0} + {TabInactive "Inactive Tab" tab_inactive 0} + {TabActive "Active Tab" tab_active 0} + {EntityBackground "Entity Background" entity_background 0} + {QueryBar "Query Bar" query_bar 0} + {WeakText "Weak Text" weak_text 0} + {TextSelection "Text Selection" text_selection 0} + {Cursor "Cursor" cursor 0} + {Highlight0 "Highlight (0)" highlight_0 0} + {Highlight1 "Highlight (1)" highlight_1 0} + {SuccessText "Success Text" success_text 0} + {SuccessBackground "Success Background" success_background 0} + {SuccessBorder "Success Border" success_border 0} + {FailureText "Failure Text" failure_text 0} + {FailureBackground "Failure Background" failure_background 0} + {FailureBorder "Failure Border" failure_border 0} + {ActionText "Action Text" action_text 0} + {ActionBackground "Action Background" action_background 0} + {ActionBorder "Action Border" action_border 0} + {DropSiteOverlay "Drop Site Overlay" drop_site_overlay 0} + {Thread0 "Thread (0)" thread_0 0} + {Thread1 "Thread (1)" thread_1 0} + {Thread2 "Thread (2)" thread_2 0} + {Thread3 "Thread (3)" thread_3 0} + {Thread4 "Thread (4)" thread_4 0} + {Thread5 "Thread (5)" thread_5 0} + {Thread6 "Thread (6)" thread_6 0} + {Thread7 "Thread (7)" thread_7 0} + {ThreadUnwound "Thread (Unwound)" thread_unwound 0} + {InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay 1} + {DropShadow "Drop Shadow" drop_shadow 1} } //////////////////////////////// @@ -487,6 +487,12 @@ df_g_theme_preset_display_string_table: @expand(DF_ThemePresetTable a) `str8_lit_comp("$(a.display_string)"),`; } +@table_gen_data(type: String8, fallback: `{0}`) +df_g_theme_preset_code_string_table: +{ + @expand(DF_ThemePresetTable a) `str8_lit_comp("$(a.name_lower)"),`; +} + @table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`) df_g_theme_preset_colors__default_dark: { diff --git a/src/df/gfx/generated/df_gfx.meta.h b/src/df/gfx/generated/df_gfx.meta.h index be5e428d..58d67a6d 100644 --- a/src/df/gfx/generated/df_gfx.meta.h +++ b/src/df/gfx/generated/df_gfx.meta.h @@ -235,6 +235,19 @@ str8_lit_comp("4coder"), str8_lit_comp("Far Manager"), }; +String8 df_g_theme_preset_code_string_table[] = +{ +str8_lit_comp("default_dark"), +str8_lit_comp("default_light"), +str8_lit_comp("vs_dark"), +str8_lit_comp("vs_light"), +str8_lit_comp("solarized_dark"), +str8_lit_comp("solarized_light"), +str8_lit_comp("handmade_hero"), +str8_lit_comp("four_coder"), +str8_lit_comp("far_manager"), +}; + Vec4F32 df_g_theme_preset_colors__default_dark[] = { rgba_from_u32_lit_comp(0xff00ffff),