diff --git a/src/input_handler.cc b/src/input_handler.cc index 462408f7c..8c0ca802d 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -75,12 +75,21 @@ struct MouseHandler Buffer& buffer = context.buffer(); BufferCoord cursor; - switch (key.modifiers) + auto& selections = context.selections(); + switch ((Key::Modifiers)(key.modifiers & Key::Modifiers::MouseEvent)) { case Key::Modifiers::MousePress: m_dragging = true; m_anchor = context.window().buffer_coord(key.coord()); - context.selections_write_only() = SelectionList{ buffer, m_anchor }; + if (not (key.modifiers & Key::Modifiers::Control)) + context.selections_write_only() = { buffer, m_anchor}; + else + { + size_t main = selections.size(); + selections.push_back({m_anchor}); + selections.set_main_index(main); + selections.sort_and_merge_overlapping(); + } return true; case Key::Modifiers::MouseRelease: @@ -88,16 +97,16 @@ struct MouseHandler return true; m_dragging = false; cursor = context.window().buffer_coord(key.coord()); - context.selections_write_only() = - SelectionList{ buffer, Selection{buffer.clamp(m_anchor), cursor} }; + selections.main() = {buffer.clamp(m_anchor), cursor}; + selections.sort_and_merge_overlapping(); return true; case Key::Modifiers::MousePos: if (not m_dragging) return true; cursor = context.window().buffer_coord(key.coord()); - context.selections_write_only() = - SelectionList{ buffer, Selection{buffer.clamp(m_anchor), cursor} }; + selections.main() = {buffer.clamp(m_anchor), cursor}; + selections.sort_and_merge_overlapping(); return true; case Key::Modifiers::MouseWheelDown: diff --git a/src/keys.cc b/src/keys.cc index e353ecbcc..11b2ad93e 100644 --- a/src/keys.cc +++ b/src/keys.cc @@ -113,10 +113,10 @@ KeyList parse_keys(StringView str) String key_to_str(Key key) { - if (key.modifiers & Key::Modifiers::MouseEvent) + if (auto mouse_event = (key.modifiers & Key::Modifiers::MouseEvent)) { const auto coord = key.coord() + DisplayCoord{1,1}; - switch (key.modifiers) + switch ((Key::Modifiers)mouse_event) { case Key::Modifiers::MousePos: return format("", coord.line, coord.column); diff --git a/src/keys.hh b/src/keys.hh index 1728b17c7..732ca08e5 100644 --- a/src/keys.hh +++ b/src/keys.hh @@ -100,12 +100,6 @@ constexpr Key ctrlalt(Codepoint key) { return { Key::Modifiers::ControlAlt, key constexpr Codepoint encode_coord(DisplayCoord coord) { return (Codepoint)(((int)coord.line << 16) | ((int)coord.column & 0x0000FFFF)); } -constexpr Key mouse_press(DisplayCoord pos) { return { Key::Modifiers::MousePress, encode_coord(pos) }; } -constexpr Key mouse_release(DisplayCoord pos) { return { Key::Modifiers::MouseRelease, encode_coord(pos) }; } -constexpr Key mouse_pos(DisplayCoord pos) { return { Key::Modifiers::MousePos, encode_coord(pos) }; } -constexpr Key mouse_wheel_down(DisplayCoord pos) { return { Key::Modifiers::MouseWheelDown, encode_coord(pos) }; } -constexpr Key mouse_wheel_up(DisplayCoord pos) { return { Key::Modifiers::MouseWheelUp, encode_coord(pos) }; } - constexpr Key resize(DisplayCoord dim) { return { Key::Modifiers::Resize, encode_coord(dim) }; } inline size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.key); } diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index 0f09a2438..efd078e5f 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -487,6 +487,7 @@ bool NCursesUI::is_key_available() return c != ERR; } + Key NCursesUI::get_key() { check_resize(); @@ -498,12 +499,27 @@ Key NCursesUI::get_key() MEVENT ev; if (getmouse(&ev) == OK) { - DisplayCoord pos{ ev.y - (m_status_on_top ? 1 : 0), ev.x }; - if (BUTTON_PRESS(ev.bstate, 1)) return mouse_press(pos); - if (BUTTON_RELEASE(ev.bstate, 1)) return mouse_release(pos); - if (BUTTON_PRESS(ev.bstate, m_wheel_down_button)) return mouse_wheel_down(pos); - if (BUTTON_PRESS(ev.bstate, m_wheel_up_button)) return mouse_wheel_up(pos); - return mouse_pos(pos); + auto get_modifiers = [this](mmask_t mask) { + Key::Modifiers res{}; + + if (mask & BUTTON_CTRL) + res |= Key::Modifiers::Control; + if (mask & BUTTON_ALT) + res |= Key::Modifiers::Alt; + + if (BUTTON_PRESS(mask, 1)) + return res | Key::Modifiers::MousePress; + if (BUTTON_RELEASE(mask, 1)) + return res | Key::Modifiers::MouseRelease; + if (BUTTON_PRESS(mask, m_wheel_down_button)) + return res | Key::Modifiers::MouseWheelDown; + if (BUTTON_PRESS(mask, m_wheel_up_button)) + return res | Key::Modifiers::MouseWheelUp; + return res | Key::Modifiers::MousePos; + }; + + return { get_modifiers(ev.bstate), + encode_coord({ ev.y - (m_status_on_top ? 1 : 0), ev.x }) }; } }