summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-10-13 22:59:02 +0100
committerMaxime Coste <frrrwww@gmail.com>2016-10-13 22:59:02 +0100
commite8dcdb6072f65e2bc598419ad285cafd4de9b820 (patch)
tree8c5fab9e2fb324067279c57ec884633095cfe3d5 /src
parentcc2affea11781d4ad1e1b9d7a9c7d729064c2c10 (diff)
Support Ctrl + mouse dragging to add a new selection
Fixes #838
Diffstat (limited to 'src')
-rw-r--r--src/input_handler.cc21
-rw-r--r--src/keys.cc4
-rw-r--r--src/keys.hh6
-rw-r--r--src/ncurses_ui.cc28
4 files changed, 39 insertions, 20 deletions
diff --git a/src/input_handler.cc b/src/input_handler.cc
index 462408f7..8c0ca802 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 e353ecbc..11b2ad93 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("<mouse:move:{}.{}>", coord.line, coord.column);
diff --git a/src/keys.hh b/src/keys.hh
index 1728b17c..732ca08e 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 0f09a243..efd078e5 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 }) };
}
}