Bläddra i källkod

feat(ui): implement scroll wheel support

Added mouse wheel scrolling support. Implemented Window::scroll_lines() logic to handle view scrolling with cursor tracking, and attached Gtk::EventControllerScroll to editor windows.
Bernardo Magri 1 månad sedan
förälder
incheckning
ba41a81b99
3 ändrade filer med 48 tillägg och 0 borttagningar
  1. 3 0
      include/lumacs/window.hpp
  2. 19 0
      src/gtk_editor.cpp
  3. 26 0
      src/window.cpp

+ 3 - 0
include/lumacs/window.hpp

@@ -42,6 +42,9 @@ public:
     
     void adjust_scroll();
     
+    // Explicit scrolling (moves view, and cursor if necessary)
+    void scroll_lines(int lines); // + for down, - for up
+    
     std::pair<size_t, size_t> visible_line_range() const;
 
 private:

+ 19 - 0
src/gtk_editor.cpp

@@ -436,6 +436,25 @@ protected:
             });
             drawing_area->add_controller(click_controller);
             
+            // Add scroll handling
+            auto scroll_controller = Gtk::EventControllerScroll::create();
+            scroll_controller->set_flags(Gtk::EventControllerScroll::Flags::VERTICAL);
+            std::weak_ptr<Window> weak_window_scroll = node->window;
+            scroll_controller->signal_scroll().connect([weak_window_scroll, drawing_area](double /*dx*/, double dy) -> bool {
+                 if (auto window = weak_window_scroll.lock()) {
+                     // dy is usually 1.0 or -1.0 for wheel steps
+                     // Scroll 3 lines per step
+                     int lines = static_cast<int>(dy * 3.0);
+                     if (lines != 0) {
+                         window->scroll_lines(lines);
+                         drawing_area->queue_draw();
+                     }
+                     return true;
+                 }
+                 return false;
+            }, true);
+            drawing_area->add_controller(scroll_controller);
+            
             // Store reference for single-window compatibility
             if (!drawing_area_) {
                 drawing_area_ = drawing_area;

+ 26 - 0
src/window.cpp

@@ -70,6 +70,32 @@ void Window::set_viewport_size(int width, int height) {
     adjust_scroll();
 }
 
+void Window::scroll_lines(int lines) {
+    int max_lines = static_cast<int>(buffer_->line_count());
+    int new_offset = viewport_.scroll_offset + lines;
+    
+    // Clamp offset
+    if (new_offset < 0) new_offset = 0;
+    // Don't scroll past end of buffer (allow some empty space though)
+    if (new_offset >= max_lines) new_offset = max_lines - 1;
+    if (new_offset < 0) new_offset = 0;
+
+    viewport_.scroll_offset = new_offset;
+    
+    // If cursor is now out of view, move it into view
+    int cursor_line = static_cast<int>(cursor_.line);
+    int view_top = viewport_.scroll_offset;
+    int view_bottom = view_top + viewport_.height; // Exclusive
+    
+    if (cursor_line < view_top) {
+        cursor_.line = static_cast<size_t>(view_top);
+    } else if (cursor_line >= view_bottom) {
+        cursor_.line = static_cast<size_t>(std::max(0, view_bottom - 1));
+    }
+    
+    clamp_cursor();
+}
+
 void Window::adjust_scroll() {
     viewport_.height = std::max(10, viewport_.height);
     viewport_.width = std::max(10, viewport_.width);