diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index ed1909a..58f2601 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -34,8 +34,9 @@
-
+
+
@@ -128,9 +129,9 @@
-
+
-
+
@@ -169,7 +170,7 @@
-
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d9fe4b3..634974f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ project(kte)
include(GNUInstallDirs)
set(CMAKE_CXX_STANDARD 17)
-set(KTE_VERSION "1.0.3")
+set(KTE_VERSION "1.0.4")
# Default to terminal-only build to avoid SDL/OpenGL dependency by default.
# Enable with -DBUILD_GUI=ON when SDL2/OpenGL/Freetype are available.
@@ -201,5 +201,5 @@ if (${BUILD_GUI})
endif ()
# Install kge man page only when GUI is built
install(FILES docs/kge.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
- install(FILES kge.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
+ install(FILES kge.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
endif ()
diff --git a/GUIRenderer.cc b/GUIRenderer.cc
index 894c257..2bf3da7 100644
--- a/GUIRenderer.cc
+++ b/GUIRenderer.cc
@@ -151,14 +151,14 @@ GUIRenderer::Draw(Editor &ed)
}
}
}
- // Handle mouse click before rendering to avoid dependent on drawn items
- if (ImGui::IsWindowHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
- ImVec2 mp = ImGui::GetIO().MousePos;
- // Compute viewport-relative row so (0) is top row of the visible area
- float vy_f = (mp.y - list_origin.y - scroll_y) / row_h;
- long vy = static_cast(vy_f);
- if (vy < 0)
- vy = 0;
+ // Handle mouse click before rendering to avoid dependent on drawn items
+ if (ImGui::IsWindowHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
+ ImVec2 mp = ImGui::GetIO().MousePos;
+ // Compute viewport-relative row so (0) is top row of the visible area
+ float vy_f = (mp.y - list_origin.y - scroll_y) / row_h;
+ long vy = static_cast(vy_f);
+ if (vy < 0)
+ vy = 0;
// Clamp vy within visible content height to avoid huge jumps
ImVec2 cr_min = ImGui::GetWindowContentRegionMin();
@@ -170,70 +170,75 @@ GUIRenderer::Draw(Editor &ed)
if (vy >= vis_rows)
vy = vis_rows - 1;
- // Translate viewport row to buffer row using Buffer::Rowoffs
- std::size_t by = buf->Rowoffs() + static_cast(vy);
- if (by >= lines.size()) {
- if (!lines.empty())
- by = lines.size() - 1;
- else
- by = 0;
- }
+ // Translate viewport row to buffer row using Buffer::Rowoffs
+ std::size_t by = buf->Rowoffs() + static_cast(vy);
+ if (by >= lines.size()) {
+ if (!lines.empty())
+ by = lines.size() - 1;
+ else
+ by = 0;
+ }
- // Compute desired pixel X inside the viewport content (subtract horizontal scroll)
- float px = (mp.x - list_origin.x - scroll_x);
- if (px < 0.0f)
- px = 0.0f;
+ // Compute desired pixel X inside the viewport content (subtract horizontal scroll)
+ float px = (mp.x - list_origin.x - scroll_x);
+ if (px < 0.0f)
+ px = 0.0f;
- // Convert pixel X to a render-column target including horizontal col offset
- // Use our own tab expansion of width 8 to match command layer logic.
- const std::string &line_clicked = lines[by];
- const std::size_t tabw = 8;
- // We iterate source columns computing absolute rendered column (rx_abs) from 0,
- // then translate to viewport-space by subtracting Coloffs.
- std::size_t coloffs = buf->Coloffs();
- std::size_t rx_abs = 0; // absolute rendered column
- std::size_t i = 0; // source column iterator
+ // Empty buffer guard: if there are no lines yet, just move to 0:0
+ if (lines.empty()) {
+ Execute(ed, CommandId::MoveCursorTo, std::string("0:0"));
+ } else {
+ // Convert pixel X to a render-column target including horizontal col offset
+ // Use our own tab expansion of width 8 to match command layer logic.
+ const std::string &line_clicked = lines[by];
+ const std::size_t tabw = 8;
+ // We iterate source columns computing absolute rendered column (rx_abs) from 0,
+ // then translate to viewport-space by subtracting Coloffs.
+ std::size_t coloffs = buf->Coloffs();
+ std::size_t rx_abs = 0; // absolute rendered column
+ std::size_t i = 0; // source column iterator
- // Fast-forward i until rx_abs >= coloffs to align with leftmost visible column
- if (!line_clicked.empty() && coloffs > 0) {
- while (i < line_clicked.size() && rx_abs < coloffs) {
- if (line_clicked[i] == '\t') {
- rx_abs += (tabw - (rx_abs % tabw));
- } else {
- rx_abs += 1;
- }
- ++i;
- }
- }
+ // Fast-forward i until rx_abs >= coloffs to align with leftmost visible column
+ if (!line_clicked.empty() && coloffs > 0) {
+ while (i < line_clicked.size() && rx_abs < coloffs) {
+ if (line_clicked[i] == '\t') {
+ rx_abs += (tabw - (rx_abs % tabw));
+ } else {
+ rx_abs += 1;
+ }
+ ++i;
+ }
+ }
- // Now search for closest source column to clicked px within/after viewport
- std::size_t best_col = i; // default to first visible column
- float best_dist = std::numeric_limits::infinity();
- while (true) {
- // For i in [current..size], evaluate candidate including the implicit end position
- std::size_t rx_view = (rx_abs >= coloffs) ? (rx_abs - coloffs) : 0;
- float rx_px = static_cast(rx_view) * space_w;
- float dist = std::fabs(px - rx_px);
- if (dist <= best_dist) {
- best_dist = dist;
- best_col = i;
- }
- if (i == line_clicked.size())
- break;
- // advance to next source column
- if (line_clicked[i] == '\t') {
- rx_abs += (tabw - (rx_abs % tabw));
- } else {
- rx_abs += 1;
- }
- ++i;
- }
+ // Now search for closest source column to clicked px within/after viewport
+ std::size_t best_col = i; // default to first visible column
+ float best_dist = std::numeric_limits::infinity();
+ while (true) {
+ // For i in [current..size], evaluate candidate including the implicit end position
+ std::size_t rx_view = (rx_abs >= coloffs) ? (rx_abs - coloffs) : 0;
+ float rx_px = static_cast(rx_view) * space_w;
+ float dist = std::fabs(px - rx_px);
+ if (dist <= best_dist) {
+ best_dist = dist;
+ best_col = i;
+ }
+ if (i == line_clicked.size())
+ break;
+ // advance to next source column
+ if (line_clicked[i] == '\t') {
+ rx_abs += (tabw - (rx_abs % tabw));
+ } else {
+ rx_abs += 1;
+ }
+ ++i;
+ }
- // Dispatch absolute buffer coordinates (row:col)
- char tmp[64];
- std::snprintf(tmp, sizeof(tmp), "%zu:%zu", by, best_col);
- Execute(ed, CommandId::MoveCursorTo, std::string(tmp));
- }
+ // Dispatch absolute buffer coordinates (row:col)
+ char tmp[64];
+ std::snprintf(tmp, sizeof(tmp), "%zu:%zu", by, best_col);
+ Execute(ed, CommandId::MoveCursorTo, std::string(tmp));
+ }
+ }
// Cache current horizontal offset in rendered columns
const std::size_t coloffs_now = buf->Coloffs();
for (std::size_t i = rowoffs; i < lines.size(); ++i) {