// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 // // ConsoleSelectionController — owns the console's text-selection state (anchor + caret) and // all the pure logic around it: the mouse-drag lifecycle, select-all, ordering, extraction, // and the index shift applied when lines are evicted from the top by the buffer cap. // // It is deliberately ImGui-free. Screen->text hit-testing stays in the view (it needs the // current frame's wrapped layout + output origin); the view feeds the resulting // ConsoleTextPos values in here. That keeps the fiddly byte-offset / eviction math unit // testable in isolation from the renderer. #pragma once #include "console_text_layout.h" // ConsoleTextPos, ConsoleLineAccessor, ExtractConsoleSelection #include #include namespace dragonx { namespace ui { class ConsoleSelectionController { public: // Mouse-drag lifecycle. Positions are raw {line, col}: line = index into the full model, // col = byte offset within that line. void beginDrag(ConsoleTextPos pos); // button press void updateDrag(ConsoleTextPos pos); // movement while held void endDrag(ConsoleTextPos pos); // release // Select the whole buffer, [0,0] .. [lineCount-1, lastLineByteLen]. No-op if empty. void selectAll(int lineCount, int lastLineByteLen); // Drop the selection entirely (also ends any in-progress drag). void clear(); bool active() const { return active_; } // a selection currently exists bool dragging() const { return dragging_; } // a drag is in progress // Ordered bounds, start <= end. Only meaningful while active(). ConsoleTextPos rangeStart() const; ConsoleTextPos rangeEnd() const; // After the cap evicts `popped` lines from the front, shift the selection up to track // the same text. Drops the selection if it fell entirely off the top. void shiftForEviction(int popped); // Selected text, or "" when inactive. `visibleIndices` are the raw line indices currently // shown (the selection spans raw lines but copies only the visible ones). std::string extract(int lineCount, const ConsoleLineAccessor& getLine, const std::vector& visibleIndices) const; // Position ordering: is a at or before b in reading order? static bool isBeforeOrEqual(ConsoleTextPos a, ConsoleTextPos b); private: ConsoleTextPos anchor_{-1, 0}; // where the drag began / the selection origin ConsoleTextPos caret_{-1, 0}; // current drag position / the selection focus bool active_ = false; bool dragging_ = false; }; } // namespace ui } // namespace dragonx