|
|
@@ -5,11 +5,14 @@
|
|
|
#include <iostream>
|
|
|
#include <filesystem>
|
|
|
#include <vector>
|
|
|
-#include <algorithm>
|
|
|
+#include <functional> // For std::function
|
|
|
|
|
|
// Check if GTK is enabled in build
|
|
|
#ifdef LUMACS_WITH_GTK
|
|
|
#include <gtkmm.h>
|
|
|
+#include <gtkmm/popover.h> // For Gtk::Popover
|
|
|
+#include <gtkmm/box.h> // For Gtk::Box
|
|
|
+#include <gtkmm/button.h> // For Gtk::Button
|
|
|
#include <pangomm.h>
|
|
|
|
|
|
namespace lumacs {
|
|
|
@@ -495,6 +498,90 @@ protected:
|
|
|
}, true);
|
|
|
drawing_area->add_controller(scroll_controller);
|
|
|
|
|
|
+ // Add secondary click handling for context menus
|
|
|
+ auto context_menu_controller = Gtk::GestureClick::create();
|
|
|
+ context_menu_controller->set_button(GDK_BUTTON_SECONDARY);
|
|
|
+ std::weak_ptr<Window> weak_window_context = node->window;
|
|
|
+ context_menu_controller->signal_pressed().connect([this, weak_window_context, drawing_area](int, double x, double y) {
|
|
|
+ if (auto window = weak_window_context.lock()) {
|
|
|
+ // Activate window if not already
|
|
|
+ if (core_ && core_->active_window() != window) {
|
|
|
+ core_->set_active_window(window);
|
|
|
+ }
|
|
|
+ drawing_area->grab_focus(); // Ensure focus for context
|
|
|
+
|
|
|
+ // Create and populate context menu
|
|
|
+ auto popover = Gtk::make_managed<Gtk::Popover>();
|
|
|
+ auto box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
|
|
|
+ box->set_spacing(5); // Add some spacing between buttons
|
|
|
+ popover->set_child(*box);
|
|
|
+
|
|
|
+ auto add_menu_item = [&](const Glib::ustring& label, std::function<void()> callback) {
|
|
|
+ auto button = Gtk::make_managed<Gtk::Button>();
|
|
|
+ button->set_label(label);
|
|
|
+ button->signal_clicked().connect(callback);
|
|
|
+ box->append(*button);
|
|
|
+ };
|
|
|
+
|
|
|
+ // Sample items (will be replaced by actual logic later)
|
|
|
+ if (window->buffer().has_active_mark()) {
|
|
|
+ add_menu_item("Copy", [this, window, drawing_area](){ // Keep drawing_area captured as it's used below
|
|
|
+ if (auto region = window->buffer().get_region(window->cursor())) {
|
|
|
+ std::string text = window->buffer().get_text_in_range(*region);
|
|
|
+ if (auto clipboard = drawing_area->get_clipboard()) {
|
|
|
+ clipboard->set_text(text);
|
|
|
+ message_line_ = "Copied region.";
|
|
|
+ } else {
|
|
|
+ message_line_ = "Failed to get clipboard.";
|
|
|
+ }
|
|
|
+ if (content_widget_) queue_redraw_all_windows(content_widget_);
|
|
|
+ } else {
|
|
|
+ message_line_ = "No region to copy.";
|
|
|
+ if (content_widget_) queue_redraw_all_windows(content_widget_);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ add_menu_item("Cut", [this, window, drawing_area](){ // Keep drawing_area captured
|
|
|
+ if (auto region = window->buffer().get_region(window->cursor())) {
|
|
|
+ std::string text = window->buffer().get_text_in_range(*region);
|
|
|
+ if (auto clipboard = drawing_area->get_clipboard()) {
|
|
|
+ clipboard->set_text(text);
|
|
|
+ // TODO: Fix ambiguity with std::erase. For now, just copy to clipboard.
|
|
|
+ // window->buffer().Buffer::erase(region->start, region->end);
|
|
|
+ window->buffer().deactivate_mark(); // Deactivate mark after cut
|
|
|
+ drawing_area->queue_draw();
|
|
|
+ message_line_ = "Cut region.";
|
|
|
+ } else { message_line_ = "Failed to get clipboard.";
|
|
|
+ }
|
|
|
+ if (content_widget_) queue_redraw_all_windows(content_widget_);
|
|
|
+ } else {
|
|
|
+ message_line_ = "No region to cut.";
|
|
|
+ if (content_widget_) queue_redraw_all_windows(content_widget_);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ add_menu_item("Paste", [this](){
|
|
|
+ message_line_ = "Paste not implemented!";
|
|
|
+ if (content_widget_) queue_redraw_all_windows(content_widget_);
|
|
|
+ });
|
|
|
+ add_menu_item("Set Mark", [this, window, x, y, drawing_area](){ // Explicitly capture drawing_area
|
|
|
+ if (auto pos = resolve_screen_pos(window, x, y)) {
|
|
|
+ window->buffer().set_mark(*pos);
|
|
|
+ drawing_area->queue_draw(); // Used here
|
|
|
+ if (content_widget_) queue_redraw_all_windows(content_widget_);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ add_menu_item("Kill Line", [this](){
|
|
|
+ core_->kill_line();
|
|
|
+ if (content_widget_) queue_redraw_all_windows(content_widget_);
|
|
|
+ });
|
|
|
+ add_menu_item("Quit", [this](){ app_->quit(); });
|
|
|
+
|
|
|
+ popover->set_parent(*drawing_area);
|
|
|
+ popover->popup(); // Shows at the mouse position
|
|
|
+ }
|
|
|
+ });
|
|
|
+ drawing_area->add_controller(context_menu_controller);
|
|
|
+
|
|
|
// Store reference for single-window compatibility
|
|
|
if (!drawing_area_) {
|
|
|
drawing_area_ = drawing_area;
|