|
@@ -117,6 +117,8 @@ protected:
|
|
|
// Safety check - don't draw if core is null (during destruction)
|
|
// Safety check - don't draw if core is null (during destruction)
|
|
|
if (!core_) return;
|
|
if (!core_) return;
|
|
|
|
|
|
|
|
|
|
+ const auto cursor = core_->cursor();
|
|
|
|
|
+
|
|
|
// Fill background
|
|
// Fill background
|
|
|
auto theme = core_->active_theme();
|
|
auto theme = core_->active_theme();
|
|
|
Color bg = theme ? theme->get_bg_color(ThemeElement::Background) : Color(0, 0, 0);
|
|
Color bg = theme ? theme->get_bg_color(ThemeElement::Background) : Color(0, 0, 0);
|
|
@@ -162,45 +164,30 @@ protected:
|
|
|
const auto& buffer = core_->buffer();
|
|
const auto& buffer = core_->buffer();
|
|
|
auto [start_line, end_line] = core_->active_window()->visible_line_range();
|
|
auto [start_line, end_line] = core_->active_window()->visible_line_range();
|
|
|
|
|
|
|
|
- for (int screen_y = 0; screen_y < editor_lines && start_line + screen_y < end_line; ++screen_y) { // Use editor_lines
|
|
|
|
|
|
|
+ for (int screen_y = 0; screen_y < editor_lines && start_line + screen_y < end_line; ++screen_y) {
|
|
|
size_t buffer_line_idx = start_line + screen_y;
|
|
size_t buffer_line_idx = start_line + screen_y;
|
|
|
const auto& line_text = buffer.line(buffer_line_idx);
|
|
const auto& line_text = buffer.line(buffer_line_idx);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
layout->set_text(line_text);
|
|
layout->set_text(line_text);
|
|
|
-
|
|
|
|
|
- // TODO: Apply Pango Attributes based on buffer styles (Faces)
|
|
|
|
|
-
|
|
|
|
|
- cr->move_to(0, screen_y * line_height_ + ascent_);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Render text at baseline position
|
|
|
|
|
+ double text_baseline_y = screen_y * line_height_ + ascent_;
|
|
|
|
|
+ cr->move_to(0, text_baseline_y);
|
|
|
layout->show_in_cairo_context(cr);
|
|
layout->show_in_cairo_context(cr);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Render Cursor
|
|
|
|
|
- const auto cursor = core_->cursor();
|
|
|
|
|
|
|
+ // Render Cursor - Draw at text baseline, extending up and down
|
|
|
if (cursor.line >= static_cast<size_t>(start_line) && cursor.line < static_cast<size_t>(end_line)) {
|
|
if (cursor.line >= static_cast<size_t>(start_line) && cursor.line < static_cast<size_t>(end_line)) {
|
|
|
- int cursor_screen_x = static_cast<int>(cursor.column * char_width_);
|
|
|
|
|
- int cursor_screen_y = static_cast<int>((cursor.line - start_line) * line_height_);
|
|
|
|
|
-
|
|
|
|
|
- // Get cursor color from theme (fallback to a visible color)
|
|
|
|
|
- Color cursor_color = theme ? theme->get_fg_color(ThemeElement::Cursor) : Color(255, 255, 0); // Yellow fallback
|
|
|
|
|
-
|
|
|
|
|
- // Draw cursor background (filled rectangle)
|
|
|
|
|
- cr->set_source_rgb(cursor_color.r / 255.0, cursor_color.g / 255.0, cursor_color.b / 255.0);
|
|
|
|
|
- cr->rectangle(cursor_screen_x, cursor_screen_y, char_width_, line_height_);
|
|
|
|
|
|
|
+ double cursor_screen_x = cursor.column * char_width_;
|
|
|
|
|
+ int screen_y = cursor.line - start_line;
|
|
|
|
|
+ // Position cursor at baseline, then offset upward by ascent to get top of line
|
|
|
|
|
+ double text_baseline_y = screen_y * line_height_ + ascent_;
|
|
|
|
|
+ double cursor_top_y = text_baseline_y - ascent_; // Move up to top of line
|
|
|
|
|
+
|
|
|
|
|
+ // Draw bright green vertical bar from top of line
|
|
|
|
|
+ cr->set_source_rgb(0.0, 1.0, 0.0); // Bright green
|
|
|
|
|
+ cr->rectangle(cursor_screen_x, cursor_top_y, 2.0, line_height_);
|
|
|
cr->fill();
|
|
cr->fill();
|
|
|
-
|
|
|
|
|
- // Draw the character at cursor position in inverted color
|
|
|
|
|
- if (cursor.line < buffer.line_count()) {
|
|
|
|
|
- const auto& line_text = buffer.line(cursor.line);
|
|
|
|
|
- if (cursor.column < line_text.length()) {
|
|
|
|
|
- std::string char_at_cursor(1, line_text[cursor.column]);
|
|
|
|
|
- layout->set_text(char_at_cursor);
|
|
|
|
|
-
|
|
|
|
|
- // Use background color for text to create inversion effect
|
|
|
|
|
- cr->set_source_rgb(bg.r / 255.0, bg.g / 255.0, bg.b / 255.0);
|
|
|
|
|
- cr->move_to(cursor_screen_x, cursor_screen_y + ascent_);
|
|
|
|
|
- layout->show_in_cairo_context(cr);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -246,9 +233,11 @@ protected:
|
|
|
|
|
|
|
|
// Input
|
|
// Input
|
|
|
bool on_key_pressed(guint keyval, guint /*keycode*/, Gdk::ModifierType state) {
|
|
bool on_key_pressed(guint keyval, guint /*keycode*/, Gdk::ModifierType state) {
|
|
|
|
|
+ // Safety check - don't process keys if core is destroyed
|
|
|
|
|
+ if (!core_) return false;
|
|
|
|
|
+
|
|
|
// 1. Resolve the base key name
|
|
// 1. Resolve the base key name
|
|
|
std::string key_name = resolve_key(keyval, state);
|
|
std::string key_name = resolve_key(keyval, state);
|
|
|
- std::cout << "[DEBUG] Raw keyval: " << keyval << ", resolved to: '" << key_name << "'" << std::endl;
|
|
|
|
|
if (key_name.empty()) return false;
|
|
if (key_name.empty()) return false;
|
|
|
|
|
|
|
|
// 2. Handle Modifiers
|
|
// 2. Handle Modifiers
|
|
@@ -258,9 +247,6 @@ protected:
|
|
|
bool is_meta = (state_uint & static_cast<unsigned int>(Gdk::ModifierType::META_MASK)) != 0;
|
|
bool is_meta = (state_uint & static_cast<unsigned int>(Gdk::ModifierType::META_MASK)) != 0;
|
|
|
bool is_lumacs_meta = is_alt || is_meta;
|
|
bool is_lumacs_meta = is_alt || is_meta;
|
|
|
|
|
|
|
|
- std::cout << "[DEBUG] Modifiers - Ctrl: " << is_control << ", Alt: " << is_alt
|
|
|
|
|
- << ", Meta: " << is_meta << std::endl;
|
|
|
|
|
-
|
|
|
|
|
// 3. Handle Minibuffer Input Logic (Command/Buffer/File modes)
|
|
// 3. Handle Minibuffer Input Logic (Command/Buffer/File modes)
|
|
|
// If in a special mode, we might consume the key directly instead of passing to Lua bindings,
|
|
// If in a special mode, we might consume the key directly instead of passing to Lua bindings,
|
|
|
// UNLESS it's a control sequence like C-g or Return.
|
|
// UNLESS it's a control sequence like C-g or Return.
|
|
@@ -321,7 +307,6 @@ protected:
|
|
|
if (is_control && key_name.length() == 1) key_name = "C-" + key_name;
|
|
if (is_control && key_name.length() == 1) key_name = "C-" + key_name;
|
|
|
if (is_lumacs_meta) key_name = "M-" + key_name; // Use combined meta/alt
|
|
if (is_lumacs_meta) key_name = "M-" + key_name; // Use combined meta/alt
|
|
|
|
|
|
|
|
- std::cout << "Key: " << key_name << std::endl; // Enable debug output
|
|
|
|
|
KeyResult result = core_->lua_api()->process_key(key_name);
|
|
KeyResult result = core_->lua_api()->process_key(key_name);
|
|
|
|
|
|
|
|
// Fallback handlers for common editing keys
|
|
// Fallback handlers for common editing keys
|