Support Ctrl + mouse dragging to add a new selection

Fixes #838
This commit is contained in:
Maxime Coste 2016-10-13 22:59:02 +01:00
parent cc2affea11
commit e8dcdb6072
4 changed files with 39 additions and 20 deletions

View File

@ -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:

View File

@ -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);

View File

@ -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); }

View File

@ -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 }) };
}
}