Experimental support for mouse

This commit is contained in:
Maxime Coste 2015-03-22 10:08:44 +00:00
parent def33de9bc
commit 5eaf472fc0
3 changed files with 78 additions and 2 deletions

View File

@ -49,6 +49,45 @@ namespace InputModes
static constexpr std::chrono::milliseconds idle_timeout{50}; static constexpr std::chrono::milliseconds idle_timeout{50};
static constexpr std::chrono::milliseconds fs_check_timeout{500}; static constexpr std::chrono::milliseconds fs_check_timeout{500};
struct MouseHandler
{
bool handle_key(Key key, Context& context)
{
if (not context.has_window())
return false;
if (key.modifiers == Key::Modifiers::MousePress)
{
m_dragging = true;
m_anchor = context.window().buffer_coord(key.mouse_coord());
context.selections() = SelectionList{ context.buffer(), m_anchor };
return true;
}
if (key.modifiers == Key::Modifiers::MouseRelease)
{
if (not m_dragging)
return true;
m_dragging = false;
auto cursor = context.window().buffer_coord(key.mouse_coord());
context.selections() = SelectionList{ context.buffer(), Selection{m_anchor, cursor} };
return true;
}
if (key.modifiers == Key::Modifiers::MousePos)
{
if (not m_dragging)
return true;
auto cursor = context.window().buffer_coord(key.mouse_coord());
context.selections() = SelectionList{ context.buffer(), Selection{m_anchor, cursor} };
return true;
}
return false;
}
private:
bool m_dragging = false;
ByteCoord m_anchor;
};
class Normal : public InputMode class Normal : public InputMode
{ {
public: public:
@ -87,6 +126,9 @@ public:
void on_key(Key key) override void on_key(Key key) override
{ {
if (m_mouse_handler.handle_key(key, context()))
return;
if (m_waiting_for_reg) if (m_waiting_for_reg)
{ {
if (key.modifiers == Key::Modifiers::None) if (key.modifiers == Key::Modifiers::None)
@ -139,6 +181,7 @@ public:
} }
m_params = { 0, '"' }; m_params = { 0, '"' };
} }
context().hooks().run_hook("NormalKey", key_to_str(key), context()); context().hooks().run_hook("NormalKey", key_to_str(key), context());
m_idle_timer.set_next_date(Clock::now() + idle_timeout); m_idle_timer.set_next_date(Clock::now() + idle_timeout);
} }
@ -167,6 +210,7 @@ private:
bool m_waiting_for_reg = false; bool m_waiting_for_reg = false;
Timer m_idle_timer; Timer m_idle_timer;
Timer m_fs_check_timer; Timer m_fs_check_timer;
MouseHandler m_mouse_handler;
}; };
template<WordType word_type> template<WordType word_type>
@ -1109,7 +1153,8 @@ void InputHandler::on_next_key(KeymapMode keymap_mode, KeyCallback callback)
static bool is_valid(Key key) static bool is_valid(Key key)
{ {
return key != Key::Invalid and key.key <= 0x10FFFF; return key != Key::Invalid and
((key.modifiers & ~Key::Modifiers::ControlAlt) or key.key <= 0x10FFFF);
} }
void InputHandler::handle_key(Key key) void InputHandler::handle_key(Key key)

View File

@ -5,6 +5,7 @@
#include "flags.hh" #include "flags.hh"
#include "hash.hh" #include "hash.hh"
#include "vector.hh" #include "vector.hh"
#include "coord.hh"
namespace Kakoune namespace Kakoune
{ {
@ -16,7 +17,11 @@ struct Key
None = 0, None = 0,
Control = 1 << 0, Control = 1 << 0,
Alt = 1 << 1, Alt = 1 << 1,
ControlAlt = Control | Alt ControlAlt = Control | Alt,
MousePress = 1 << 2,
MouseRelease = 1 << 3,
MousePos = 1 << 4,
}; };
enum NamedKey : Codepoint enum NamedKey : Codepoint
{ {
@ -62,6 +67,8 @@ struct Key
constexpr bool operator==(Key other) const { return val() == other.val(); } constexpr bool operator==(Key other) const { return val() == other.val(); }
constexpr bool operator!=(Key other) const { return val() != other.val(); } constexpr bool operator!=(Key other) const { return val() != other.val(); }
constexpr bool operator<(Key other) const { return val() < other.val(); } constexpr bool operator<(Key other) const { return val() < other.val(); }
constexpr CharCoord mouse_coord() const { return {(int)((key & 0xFFFF0000) >> 16), (int)(key & 0x0000FFFF)}; }
}; };
template<> struct WithBitOps<Key::Modifiers> : std::true_type {}; template<> struct WithBitOps<Key::Modifiers> : std::true_type {};
@ -78,6 +85,12 @@ constexpr Key alt(Codepoint key) { return { Key::Modifiers::Alt, key }; }
constexpr Key ctrl(Codepoint key) { return { Key::Modifiers::Control, key }; } constexpr Key ctrl(Codepoint key) { return { Key::Modifiers::Control, key }; }
constexpr Key ctrlalt(Codepoint key) { return { Key::Modifiers::ControlAlt, key }; } constexpr Key ctrlalt(Codepoint key) { return { Key::Modifiers::ControlAlt, key }; }
constexpr Codepoint encode_mouse_coord(CharCoord coord) { return (Codepoint)(((int)coord.line << 16) | ((int)coord.column & 0x0000FFFF)); }
constexpr Key mouse_press(CharCoord pos) { return { Key::Modifiers::MousePress, encode_mouse_coord(pos) }; }
constexpr Key mouse_release(CharCoord pos) { return { Key::Modifiers::MouseRelease, encode_mouse_coord(pos) }; }
constexpr Key mouse_pos(CharCoord pos) { return { Key::Modifiers::MousePos, encode_mouse_coord(pos) }; }
inline size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.key); } inline size_t hash_value(const Key& key) { return hash_values(key.modifiers, key.key); }
} }

View File

@ -260,6 +260,10 @@ NCursesUI::NCursesUI()
signal(SIGWINCH, on_term_resize); signal(SIGWINCH, on_term_resize);
signal(SIGINT, on_sigint); signal(SIGINT, on_sigint);
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, nullptr);
mouseinterval(0);
// force enable report mouse position
printf("\033[?1002h");
update_dimensions(); update_dimensions();
wrefresh(stdscr); wrefresh(stdscr);
@ -267,6 +271,7 @@ NCursesUI::NCursesUI()
NCursesUI::~NCursesUI() NCursesUI::~NCursesUI()
{ {
printf("\033[?1002l");
endwin(); endwin();
signal(SIGWINCH, SIG_DFL); signal(SIGWINCH, SIG_DFL);
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL);
@ -442,6 +447,19 @@ Key NCursesUI::get_key()
check_resize(); check_resize();
const int c = getch(); const int c = getch();
if (c == KEY_MOUSE)
{
MEVENT ev;
if (getmouse(&ev) == OK)
{
CharCoord pos{ ev.y, ev.x };
if ((ev.bstate & BUTTON1_PRESSED) == BUTTON1_PRESSED) return mouse_press(pos);
if ((ev.bstate & BUTTON1_RELEASED) == BUTTON1_RELEASED) return mouse_release(pos);
else return mouse_pos(pos);
}
}
if (c > 0 and c < 27) if (c > 0 and c < 27)
{ {
if (c == CTRL('l')) if (c == CTRL('l'))