| 100 | } |
| 101 | |
| 102 | void reshade::imgui::code_editor::render(const char *title, const uint32_t palette[color_palette_max], bool border, ImFont *font, float font_size) |
| 103 | { |
| 104 | // There should always at least be a single line with a new line character |
| 105 | assert(!_lines.empty()); |
| 106 | |
| 107 | // Get all the style values here, before they are overwritten via 'ImGui::PushStyleVar' |
| 108 | const float button_size = ImGui::GetFrameHeight(); |
| 109 | const float bottom_height = ImGui::GetFrameHeightWithSpacing() + ImGui::GetStyle().ItemSpacing.y; |
| 110 | const float button_spacing = ImGui::GetStyle().ItemInnerSpacing.x; |
| 111 | |
| 112 | ImGui::PushFont(font, font_size); |
| 113 | ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::ColorConvertU32ToFloat4(palette[color_background])); |
| 114 | ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); |
| 115 | |
| 116 | ImGuiIO &io = ImGui::GetIO(); |
| 117 | const bool ctrl = io.KeyCtrl, shift = io.KeyShift, alt = io.KeyAlt; |
| 118 | |
| 119 | const bool open_search_window = ctrl && !shift && !alt && (ImGui::IsKeyPressed(ImGuiKey_F) || ImGui::IsKeyPressed(ImGuiKey_H)); |
| 120 | if (open_search_window) |
| 121 | { |
| 122 | // Copy currently selected text into search box |
| 123 | if (_select_beg != _select_end) |
| 124 | _search_text[get_selected_text().copy(_search_text, sizeof(_search_text) - 1)] = '\0'; |
| 125 | |
| 126 | _search_window_open = ImGui::IsKeyPressed(ImGuiKey_H) && !_readonly ? 2 /* search + replace */ : 1 /* search */; |
| 127 | } |
| 128 | else if (_search_window_open < 0) |
| 129 | { |
| 130 | _search_window_open = 0; |
| 131 | ImGui::SetNextWindowFocus(); |
| 132 | } |
| 133 | |
| 134 | ImGui::BeginChild(title, ImVec2(0, _search_window_open * -bottom_height), border ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNavInputs); |
| 135 | |
| 136 | char buf[128] = "", *buf_end = buf; |
| 137 | |
| 138 | // Deduce text start offset by evaluating maximum number of lines plus two spaces as text width |
| 139 | std::snprintf(buf, 16, " %zu ", _lines.size()); |
| 140 | const float text_start = calc_text_size(buf).x + _left_margin; |
| 141 | const float space_size = calc_text_size(" ").x; |
| 142 | // The following holds the approximate width and height of a default character for offset calculation |
| 143 | const ImVec2 char_advance = ImVec2(space_size, ImGui::GetTextLineHeightWithSpacing() * _line_spacing); |
| 144 | |
| 145 | _cursor_anim += io.DeltaTime; |
| 146 | |
| 147 | // Handle keyboard input |
| 148 | if (ImGui::IsWindowFocused()) |
| 149 | { |
| 150 | if (ImGui::IsWindowHovered()) |
| 151 | ImGui::SetMouseCursor(ImGuiMouseCursor_TextInput); |
| 152 | |
| 153 | io.WantTextInput = true; |
| 154 | io.WantCaptureKeyboard = true; |
| 155 | |
| 156 | if (ImGui::IsKeyPressed(ImGuiKey_Escape)) |
| 157 | ImGui::SetWindowFocus(nullptr); // Reset window focus |
| 158 | else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Z)) |
| 159 | undo(); |
no test coverage detected