From ed36d5360081241aa63f8cec23029823794e5fa8 Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 29 Dec 2024 16:03:59 -0500 Subject: [PATCH] Add Theme struct and theme management functions for improved GUI styling --- src/app/gui/style.cc | 545 +++++++++++++++++++++++++------------------ src/app/gui/style.h | 45 +++- 2 files changed, 358 insertions(+), 232 deletions(-) diff --git a/src/app/gui/style.cc b/src/app/gui/style.cc index a87b92eb..537caac3 100644 --- a/src/app/gui/style.cc +++ b/src/app/gui/style.cc @@ -1,11 +1,334 @@ #include "style.h" +#include "app/core/utils/file_util.h" +#include "gui/color.h" #include "imgui/imgui.h" #include "imgui/imgui_internal.h" namespace yaze { namespace gui { +namespace { +Color ParseColor(const std::string &color) { + Color result; + if (color.size() == 7 && color[0] == '#') { + result.red = std::stoi(color.substr(1, 2), nullptr, 16) / 255.0f; + result.green = std::stoi(color.substr(3, 2), nullptr, 16) / 255.0f; + result.blue = std::stoi(color.substr(5, 2), nullptr, 16) / 255.0f; + } else { + throw std::invalid_argument("Invalid color format: " + color); + } + return result; +} + +absl::Status ParseThemeContents(const std::string &key, + const std::string &value, Theme &theme) { + try { + if (key == "MenuBarBg") { + theme.menu_bar_bg = ParseColor(value); + } else if (key == "TitleBgActive") { + theme.title_bg_active = ParseColor(value); + } else if (key == "TitleBgCollapsed") { + theme.title_bg_collapsed = ParseColor(value); + } else if (key == "Tab") { + theme.tab = ParseColor(value); + } else if (key == "TabHovered") { + theme.tab_hovered = ParseColor(value); + } else if (key == "TabActive") { + theme.tab_active = ParseColor(value); + } + } catch (const std::exception &e) { + return absl::InvalidArgumentError(e.what()); + } + return absl::OkStatus(); +} + +} // namespace + +absl::StatusOr LoadTheme(const std::string &filename) { + std::string theme_contents; + try { + theme_contents = core::LoadFile(filename); + } catch (const std::exception &e) { + return absl::InternalError(e.what()); + } + + Theme theme; + std::istringstream theme_stream(theme_contents); + while (theme_stream.good()) { + std::string line; + std::getline(theme_stream, line); + if (line.empty()) { + continue; + } + + std::istringstream line_stream(line); + std::string key; + std::string value; + std::getline(line_stream, key, '='); + std::getline(line_stream, value); + RETURN_IF_ERROR(ParseThemeContents(key, value, theme)); + } + return theme; +} + +absl::Status SaveTheme(const Theme &theme) { + std::ostringstream theme_stream; + theme_stream << theme.name << "Theme\n"; + theme_stream << "MenuBarBg=#" << gui::ColorToHexString(theme.menu_bar_bg) + << "\n"; + theme_stream << "TitleBg=#" << gui::ColorToHexString(theme.title_bar_bg) << "\n"; + theme_stream << "Header=#" << gui::ColorToHexString(theme.header) << "\n"; + theme_stream << "HeaderHovered=#" << gui::ColorToHexString(theme.header_hovered) << "\n"; + theme_stream << "HeaderActive=#" << gui::ColorToHexString(theme.header_active) << "\n"; + theme_stream << "TitleBgActive=#" << gui::ColorToHexString(theme.title_bg_active) << "\n"; + theme_stream << "TitleBgCollapsed=#" << gui::ColorToHexString(theme.title_bg_collapsed) << "\n"; + theme_stream << "Tab=#" << gui::ColorToHexString(theme.tab) << "\n"; + theme_stream << "TabHovered=#" << gui::ColorToHexString(theme.tab_hovered) << "\n"; + theme_stream << "TabActive=#" << gui::ColorToHexString(theme.tab_active) << "\n"; + theme_stream << "Button=#" << gui::ColorToHexString(theme.button) << "\n"; + theme_stream << "ButtonHovered=#" << gui::ColorToHexString(theme.button_hovered) << "\n"; + theme_stream << "ButtonActive=#" << gui::ColorToHexString(theme.button_active) << "\n"; + + // Save the theme to a file. + + return absl::OkStatus(); +} + +void ApplyTheme(const Theme &theme) { + ImGuiStyle *style = &ImGui::GetStyle(); + ImVec4 *colors = style->Colors; + + colors[ImGuiCol_MenuBarBg] = gui::ConvertColorToImVec4(theme.menu_bar_bg); + colors[ImGuiCol_TitleBg] = gui::ConvertColorToImVec4(theme.title_bar_bg); + colors[ImGuiCol_Header] = gui::ConvertColorToImVec4(theme.header); + colors[ImGuiCol_HeaderHovered] = gui::ConvertColorToImVec4(theme.header_hovered); + colors[ImGuiCol_HeaderActive] = gui::ConvertColorToImVec4(theme.header_active); + colors[ImGuiCol_TitleBgActive] = gui::ConvertColorToImVec4(theme.title_bg_active); + colors[ImGuiCol_TitleBgCollapsed] = gui::ConvertColorToImVec4(theme.title_bg_collapsed); + colors[ImGuiCol_Tab] = gui::ConvertColorToImVec4(theme.tab); + colors[ImGuiCol_TabHovered] = gui::ConvertColorToImVec4(theme.tab_hovered); + colors[ImGuiCol_TabActive] = gui::ConvertColorToImVec4(theme.tab_active); + colors[ImGuiCol_Button] = gui::ConvertColorToImVec4(theme.button); + colors[ImGuiCol_ButtonHovered] = gui::ConvertColorToImVec4(theme.button_hovered); + colors[ImGuiCol_ButtonActive] = gui::ConvertColorToImVec4(theme.button_active); +} + +void ColorsYaze() { + ImGuiStyle *style = &ImGui::GetStyle(); + ImVec4 *colors = style->Colors; + + style->WindowPadding = ImVec2(10.f, 10.f); + style->FramePadding = ImVec2(10.f, 2.f); + style->CellPadding = ImVec2(4.f, 5.f); + style->ItemSpacing = ImVec2(10.f, 5.f); + style->ItemInnerSpacing = ImVec2(5.f, 5.f); + style->TouchExtraPadding = ImVec2(0.f, 0.f); + style->IndentSpacing = 20.f; + style->ScrollbarSize = 14.f; + style->GrabMinSize = 15.f; + + style->WindowBorderSize = 0.f; + style->ChildBorderSize = 1.f; + style->PopupBorderSize = 1.f; + style->FrameBorderSize = 0.f; + style->TabBorderSize = 0.f; + + style->WindowRounding = 0.f; + style->ChildRounding = 0.f; + style->FrameRounding = 5.f; + style->PopupRounding = 0.f; + style->ScrollbarRounding = 5.f; + + auto alttpDarkGreen = ImVec4(0.18f, 0.26f, 0.18f, 1.0f); + auto alttpMidGreen = ImVec4(0.28f, 0.36f, 0.28f, 1.0f); + auto allttpLightGreen = ImVec4(0.36f, 0.45f, 0.36f, 1.0f); + auto allttpLightestGreen = ImVec4(0.49f, 0.57f, 0.49f, 1.0f); + + colors[ImGuiCol_MenuBarBg] = alttpDarkGreen; + colors[ImGuiCol_TitleBg] = alttpMidGreen; + + colors[ImGuiCol_Header] = alttpDarkGreen; + colors[ImGuiCol_HeaderHovered] = allttpLightGreen; + colors[ImGuiCol_HeaderActive] = alttpMidGreen; + + colors[ImGuiCol_TitleBgActive] = alttpDarkGreen; + colors[ImGuiCol_TitleBgCollapsed] = alttpMidGreen; + + colors[ImGuiCol_Tab] = alttpDarkGreen; + colors[ImGuiCol_TabHovered] = alttpMidGreen; + colors[ImGuiCol_TabActive] = ImVec4(0.347f, 0.466f, 0.347f, 1.000f); + + colors[ImGuiCol_Button] = alttpMidGreen; + colors[ImGuiCol_ButtonHovered] = allttpLightestGreen; + colors[ImGuiCol_ButtonActive] = allttpLightGreen; + + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.36f, 0.45f, 0.36f, 0.30f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.36f, 0.45f, 0.36f, 0.40f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); + + colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); + colors[ImGuiCol_Border] = allttpLightGreen; + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + + colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.28f, 0.36f, 0.28f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.28f, 0.36f, 0.28f, 0.69f); + + colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); + + colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f); + + colors[ImGuiCol_TabUnfocused] = + ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabUnfocusedActive] = + ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TableHeaderBg] = alttpDarkGreen; + colors[ImGuiCol_TableBorderStrong] = alttpMidGreen; + colors[ImGuiCol_TableBorderLight] = + ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); +} + +void DrawBitmapViewer(const std::vector &bitmaps, float scale, + int ¤t_bitmap_id) { + if (bitmaps.empty()) { + ImGui::Text("No bitmaps available."); + return; + } + + // Display the current bitmap index and total count. + ImGui::Text("Viewing Bitmap %d / %zu", current_bitmap_id + 1, bitmaps.size()); + + // Buttons to navigate through bitmaps. + if (ImGui::Button("<- Prev")) { + if (current_bitmap_id > 0) { + --current_bitmap_id; + } + } + ImGui::SameLine(); + if (ImGui::Button("Next ->")) { + if (current_bitmap_id < bitmaps.size() - 1) { + ++current_bitmap_id; + } + } + + // Display the current bitmap. + const gfx::Bitmap ¤t_bitmap = bitmaps[current_bitmap_id]; + // Assuming Bitmap has a function to get its texture ID, and width and + // height. + ImTextureID tex_id = (ImTextureID)(intptr_t)current_bitmap.texture(); + ImVec2 size(current_bitmap.width() * scale, current_bitmap.height() * scale); + // ImGui::Image(tex_id, size); + + // Scroll if the image is larger than the display area. + if (ImGui::BeginChild("BitmapScrollArea", ImVec2(0, 0), false, + ImGuiWindowFlags_HorizontalScrollbar)) { + ImGui::Image(tex_id, size); + ImGui::EndChild(); + } +} + +static const char *const kKeywords[] = { + "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", + "BRA", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "CPX", + "CPY", "DEC", "DEX", "DEY", "EOR", "INC", "INX", "INY", "JMP", "JSR", + "JSL", "LDA", "LDX", "LDY", "LSR", "MVN", "NOP", "ORA", "PEA", "PER", + "PHA", "PHB", "PHD", "PHP", "PHX", "PHY", "PLA", "PLB", "PLD", "PLP", + "PLX", "PLY", "REP", "ROL", "ROR", "RTI", "RTL", "RTS", "SBC", "SEC", + "SEI", "SEP", "STA", "STP", "STX", "STY", "STZ", "TAX", "TAY", "TCD", + "TCS", "TDC", "TRB", "TSB", "TSC", "TSX", "TXA", "TXS", "TXY", "TYA", + "TYX", "WAI", "WDM", "XBA", "XCE", "ORG", "LOROM", "HIROM"}; + +static const char *const kIdentifiers[] = { + "abort", "abs", "acos", "asin", "atan", "atexit", + "atof", "atoi", "atol", "ceil", "clock", "cosh", + "ctime", "div", "exit", "fabs", "floor", "fmod", + "getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph", + "ispunct", "isspace", "isupper", "kbhit", "log10", "log2", + "log", "memcmp", "modf", "pow", "putchar", "putenv", + "puts", "rand", "remove", "rename", "sinh", "sqrt", + "srand", "strcat", "strcmp", "strerror", "time", "tolower", + "toupper"}; + +TextEditor::LanguageDefinition GetAssemblyLanguageDef() { + TextEditor::LanguageDefinition language_65816; + for (auto &k : kKeywords) + language_65816.mKeywords.emplace(k); + + for (auto &k : kIdentifiers) { + TextEditor::Identifier id; + id.mDeclaration = "Built-in function"; + language_65816.mIdentifiers.insert(std::make_pair(std::string(k), id)); + } + + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[ \\t]*#[ \\t]*[a-zA-Z_]+", TextEditor::PaletteIndex::Preprocessor)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "L?\\\"(\\\\.|[^\\\"])*\\\"", TextEditor::PaletteIndex::String)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "\\'\\\\?[^\\']\\'", TextEditor::PaletteIndex::CharLiteral)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", + TextEditor::PaletteIndex::Number)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[+-]?[0-9]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "0[0-7]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", + TextEditor::PaletteIndex::Number)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[a-zA-Z_][a-zA-Z0-9_]*", TextEditor::PaletteIndex::Identifier)); + language_65816.mTokenRegexStrings.push_back( + std::make_pair( + "[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/" + "\\;\\,\\.]", + TextEditor::PaletteIndex::Punctuation)); + + language_65816.mCommentStart = "/*"; + language_65816.mCommentEnd = "*/"; + language_65816.mSingleLineComment = ";"; + + language_65816.mCaseSensitive = false; + language_65816.mAutoIndentation = true; + + language_65816.mName = "65816"; + + return language_65816; +} + // TODO: Add more display settings to popup windows. void BeginWindowWithDisplaySettings(const char *id, bool *active, const ImVec2 &size, @@ -426,227 +749,5 @@ void TextWithSeparators(const absl::string_view &text) { ImGui::Separator(); } -// TODO: Make the ColorsYaze style into a configuration file. -void ColorsYaze() { - ImGuiStyle *style = &ImGui::GetStyle(); - ImVec4 *colors = style->Colors; - - style->WindowPadding = ImVec2(10.f, 10.f); - style->FramePadding = ImVec2(10.f, 2.f); - style->CellPadding = ImVec2(4.f, 5.f); - style->ItemSpacing = ImVec2(10.f, 5.f); - style->ItemInnerSpacing = ImVec2(5.f, 5.f); - style->TouchExtraPadding = ImVec2(0.f, 0.f); - style->IndentSpacing = 20.f; - style->ScrollbarSize = 14.f; - style->GrabMinSize = 15.f; - - style->WindowBorderSize = 0.f; - style->ChildBorderSize = 1.f; - style->PopupBorderSize = 1.f; - style->FrameBorderSize = 0.f; - style->TabBorderSize = 0.f; - - style->WindowRounding = 0.f; - style->ChildRounding = 0.f; - style->FrameRounding = 5.f; - style->PopupRounding = 0.f; - style->ScrollbarRounding = 5.f; - - auto alttpDarkGreen = ImVec4(0.18f, 0.26f, 0.18f, 1.0f); - auto alttpMidGreen = ImVec4(0.28f, 0.36f, 0.28f, 1.0f); - auto allttpLightGreen = ImVec4(0.36f, 0.45f, 0.36f, 1.0f); - auto allttpLightestGreen = ImVec4(0.49f, 0.57f, 0.49f, 1.0f); - - colors[ImGuiCol_MenuBarBg] = alttpDarkGreen; - colors[ImGuiCol_TitleBg] = alttpMidGreen; - - colors[ImGuiCol_Header] = alttpDarkGreen; - colors[ImGuiCol_HeaderHovered] = allttpLightGreen; - colors[ImGuiCol_HeaderActive] = alttpMidGreen; - - colors[ImGuiCol_TitleBgActive] = alttpDarkGreen; - colors[ImGuiCol_TitleBgCollapsed] = alttpMidGreen; - - colors[ImGuiCol_Tab] = alttpDarkGreen; - colors[ImGuiCol_TabHovered] = alttpMidGreen; - colors[ImGuiCol_TabActive] = ImVec4(0.347f, 0.466f, 0.347f, 1.000f); - - colors[ImGuiCol_Button] = alttpMidGreen; - colors[ImGuiCol_ButtonHovered] = allttpLightestGreen; - colors[ImGuiCol_ButtonActive] = allttpLightGreen; - - colors[ImGuiCol_ScrollbarBg] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.36f, 0.45f, 0.36f, 0.30f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.36f, 0.45f, 0.36f, 0.40f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); - - colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f); - colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); - colors[ImGuiCol_Border] = allttpLightGreen; - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - - colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.28f, 0.36f, 0.28f, 0.40f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.28f, 0.36f, 0.28f, 0.69f); - - colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); - colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.36f, 0.45f, 0.36f, 0.60f); - - colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f); - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f); - - colors[ImGuiCol_TabUnfocused] = - ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); - colors[ImGuiCol_TabUnfocusedActive] = - ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); - colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - colors[ImGuiCol_TableHeaderBg] = alttpDarkGreen; - colors[ImGuiCol_TableBorderStrong] = alttpMidGreen; - colors[ImGuiCol_TableBorderLight] = - ImVec4(0.26f, 0.26f, 0.28f, 1.00f); // Prefer using Alpha=1.0 here - colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.07f); - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); - colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); - colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; - colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); - colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); -} - -void DrawBitmapViewer(const std::vector &bitmaps, float scale, - int ¤t_bitmap_id) { - if (bitmaps.empty()) { - ImGui::Text("No bitmaps available."); - return; - } - - // Display the current bitmap index and total count. - ImGui::Text("Viewing Bitmap %d / %zu", current_bitmap_id + 1, bitmaps.size()); - - // Buttons to navigate through bitmaps. - if (ImGui::Button("<- Prev")) { - if (current_bitmap_id > 0) { - --current_bitmap_id; - } - } - ImGui::SameLine(); - if (ImGui::Button("Next ->")) { - if (current_bitmap_id < bitmaps.size() - 1) { - ++current_bitmap_id; - } - } - - // Display the current bitmap. - const gfx::Bitmap ¤t_bitmap = bitmaps[current_bitmap_id]; - // Assuming Bitmap has a function to get its texture ID, and width and - // height. - ImTextureID tex_id = (ImTextureID)(intptr_t)current_bitmap.texture(); - ImVec2 size(current_bitmap.width() * scale, current_bitmap.height() * scale); - // ImGui::Image(tex_id, size); - - // Scroll if the image is larger than the display area. - if (ImGui::BeginChild("BitmapScrollArea", ImVec2(0, 0), false, - ImGuiWindowFlags_HorizontalScrollbar)) { - ImGui::Image(tex_id, size); - ImGui::EndChild(); - } -} - -// ============================================================================ -// 65816 LanguageDefinition -// ============================================================================ - -static const char *const kKeywords[] = { - "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", - "BPL", "BRA", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", - "CMP", "CPX", "CPY", "DEC", "DEX", "DEY", "EOR", "INC", "INX", - "INY", "JMP", "JSR", "JSL", "LDA", "LDX", "LDY", "LSR", "MVN", - "NOP", "ORA", "PEA", "PER", "PHA", "PHB", "PHD", "PHP", "PHX", - "PHY", "PLA", "PLB", "PLD", "PLP", "PLX", "PLY", "REP", "ROL", - "ROR", "RTI", "RTL", "RTS", "SBC", "SEC", "SEI", "SEP", "STA", - "STP", "STX", "STY", "STZ", "TAX", "TAY", "TCD", "TCS", "TDC", - "TRB", "TSB", "TSC", "TSX", "TXA", "TXS", "TXY", "TYA", "TYX", - "WAI", "WDM", "XBA", "XCE", "ORG", "LOROM", "HIROM", "NAMESPACE", "DB"}; - -static const char *const kIdentifiers[] = { - "abort", "abs", "acos", "asin", "atan", "atexit", - "atof", "atoi", "atol", "ceil", "clock", "cosh", - "ctime", "div", "exit", "fabs", "floor", "fmod", - "getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph", - "ispunct", "isspace", "isupper", "kbhit", "log10", "log2", - "log", "memcmp", "modf", "pow", "putchar", "putenv", - "puts", "rand", "remove", "rename", "sinh", "sqrt", - "srand", "strcat", "strcmp", "strerror", "time", "tolower", - "toupper"}; - -TextEditor::LanguageDefinition GetAssemblyLanguageDef() { - TextEditor::LanguageDefinition language_65816; - for (auto &k : kKeywords) - language_65816.mKeywords.emplace(k); - - for (auto &k : kIdentifiers) { - TextEditor::Identifier id; - id.mDeclaration = "Built-in function"; - language_65816.mIdentifiers.insert(std::make_pair(std::string(k), id)); - } - - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "[ \\t]*#[ \\t]*[a-zA-Z_]+", TextEditor::PaletteIndex::Preprocessor)); - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "L?\\\"(\\\\.|[^\\\"])*\\\"", TextEditor::PaletteIndex::String)); - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "\\'\\\\?[^\\']\\'", TextEditor::PaletteIndex::CharLiteral)); - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", - TextEditor::PaletteIndex::Number)); - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "[+-]?[0-9]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number)); - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "0[0-7]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number)); - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", - TextEditor::PaletteIndex::Number)); - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "[a-zA-Z_][a-zA-Z0-9_]*", TextEditor::PaletteIndex::Identifier)); - language_65816.mTokenRegexStrings.push_back( - std::make_pair( - "[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/" - "\\;\\,\\.]", - TextEditor::PaletteIndex::Punctuation)); - - language_65816.mCommentStart = "/*"; - language_65816.mCommentEnd = "*/"; - language_65816.mSingleLineComment = ";"; - - language_65816.mCaseSensitive = false; - language_65816.mAutoIndentation = true; - - language_65816.mName = "65816"; - - return language_65816; -} - } // namespace gui - } // namespace yaze diff --git a/src/app/gui/style.h b/src/app/gui/style.h index f275317e..91375e79 100644 --- a/src/app/gui/style.h +++ b/src/app/gui/style.h @@ -1,16 +1,51 @@ #ifndef YAZE_APP_CORE_STYLE_H #define YAZE_APP_CORE_STYLE_H +#include #include #include "ImGuiColorTextEdit/TextEditor.h" #include "absl/strings/string_view.h" #include "app/gfx/bitmap.h" +#include "app/gui/color.h" #include "imgui/imgui.h" namespace yaze { namespace gui { +struct Theme { + std::string name; + + Color menu_bar_bg; + Color title_bar_bg; + + Color header; + Color header_hovered; + Color header_active; + + Color title_bg_active; + Color title_bg_collapsed; + + Color tab; + Color tab_hovered; + Color tab_active; + + Color button; + Color button_hovered; + Color button_active; +}; + +absl::StatusOr LoadTheme(const std::string &filename); +absl::Status SaveTheme(const Theme &theme); +void ApplyTheme(const Theme &theme); + +void ColorsYaze(); + +TextEditor::LanguageDefinition GetAssemblyLanguageDef(); + +void DrawBitmapViewer(const std::vector &bitmaps, float scale, + int ¤t_bitmap); + void BeginWindowWithDisplaySettings(const char *id, bool *active, const ImVec2 &size = ImVec2(0, 0), ImGuiWindowFlags flags = 0); @@ -31,15 +66,6 @@ void DrawDisplaySettings(ImGuiStyle *ref = nullptr); void TextWithSeparators(const absl::string_view &text); -void ColorsYaze(); - -TextEditor::LanguageDefinition GetAssemblyLanguageDef(); - -void DrawBitmapViewer(const std::vector &bitmaps, float scale, - int ¤t_bitmap); - -// ============================================================================ - static const char *ExampleNames[] = { "Artichoke", "Arugula", "Asparagus", "Avocado", "Bamboo Shoots", "Bean Sprouts", "Beans", "Beet", @@ -91,7 +117,6 @@ struct MultiSelectWithClipper { }; } // namespace gui - } // namespace yaze #endif