Browse Source

A tooltip is no longer hidden if the mouse cursor is moving towards it

merge-requests/382/head
eidheim 8 years ago
parent
commit
3d166a8988
  1. 15
      src/source.cc
  2. 62
      src/tooltips.cc
  3. 15
      src/tooltips.h
  4. 2
      tests/stubs/tooltips.cc

15
src/source.cc

@ -515,6 +515,13 @@ void Source::View::configure() {
}
void Source::View::setup_tooltip_and_dialog_events() {
type_tooltips.on_motion=[this] {
delayed_tooltips_connection.disconnect();
};
diagnostic_tooltips.on_motion=[this] {
delayed_tooltips_connection.disconnect();
};
get_buffer()->signal_changed().connect([this] {
hide_tooltips();
});
@ -526,6 +533,8 @@ void Source::View::setup_tooltip_and_dialog_events() {
gdouble x=event->x;
gdouble y=event->y;
delayed_tooltips_connection=Glib::signal_timeout().connect([this, x, y]() {
type_tooltips.hide();
diagnostic_tooltips.hide();
Tooltips::init();
Gdk::Rectangle rectangle(x, y, 1, 1);
if(parsed) {
@ -535,8 +544,10 @@ void Source::View::setup_tooltip_and_dialog_events() {
return false;
}, 100);
}
type_tooltips.hide();
diagnostic_tooltips.hide();
auto last_mouse_pos = std::make_pair(on_motion_last_x, on_motion_last_y);
auto mouse_pos = std::make_pair(event->x, event->y);
type_tooltips.hide(last_mouse_pos, mouse_pos);
diagnostic_tooltips.hide(last_mouse_pos, mouse_pos);
}
on_motion_last_x=event->x;
on_motion_last_y=event->y;

62
src/tooltips.cc

@ -35,7 +35,7 @@ void Tooltip::update() {
}
}
void Tooltip::show(bool disregard_drawn) {
void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion) {
Tooltips::shown_tooltips.emplace(this);
if(!window) {
@ -55,6 +55,12 @@ void Tooltip::show(bool disregard_drawn) {
window->set_skip_taskbar_hint(true);
window->set_default_size(0, 0);
window->signal_motion_notify_event().connect([on_motion](GdkEventMotion *event) {
if(on_motion)
on_motion();
return false;
});
window->get_style_context()->add_class("juci_tooltip_window");
auto visual = window->get_screen()->get_rgba_visual();
if(visual)
@ -91,13 +97,13 @@ void Tooltip::show(bool disregard_drawn) {
int root_x, root_y;
dialog->get_position(root_x, root_y);
root_x-=3; // -1xpadding
position.first=root_x;
position.second=root_y-size.second;
if(position.second<0)
position.second=0;
rectangle.set_x(root_x);
rectangle.set_y(root_y-size.second);
if(rectangle.get_y()<0)
rectangle.set_y(0);
}
}
window->move(position.first, position.second);
window->move(rectangle.get_x(), rectangle.get_y());
});
}
@ -115,7 +121,6 @@ void Tooltip::show(bool disregard_drawn) {
if(root_y<size.second)
root_x+=visible_rect.get_width()*0.1;
}
Gdk::Rectangle rectangle;
rectangle.set_x(root_x);
rectangle.set_y(std::max(0, root_y-size.second));
rectangle.set_width(size.first);
@ -136,16 +141,39 @@ void Tooltip::show(bool disregard_drawn) {
Tooltips::drawn_tooltips_rectangle=rectangle;
}
position={rectangle.get_x(), rectangle.get_y()};
if(window->get_realized())
window->move(position.first, position.second);
window->move(rectangle.get_x(), rectangle.get_y());
window->show_all();
shown=true;
}
void Tooltip::hide() {
void Tooltip::hide(const std::pair<int, int> &last_mouse_pos, const std::pair<int, int> &mouse_pos) {
// Keep tooltip if mouse is moving towards it
// Calculated using dot product between the mouse_pos vector and the corners of the tooltip window
if(text_view && window && shown && last_mouse_pos.first!=-1 && last_mouse_pos.second!=-1 && mouse_pos.first!=-1 && mouse_pos.second!=-1) {
static int root_x, root_y;
text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(last_mouse_pos.first, last_mouse_pos.second, root_x, root_y);
int diff_x=mouse_pos.first-last_mouse_pos.first;
int diff_y=mouse_pos.second-last_mouse_pos.second;
class Corner {
public:
Corner(int x, int y): x(x-root_x), y(y-root_y) {}
int x, y;
};
std::vector<Corner> corners;
corners.emplace_back(rectangle.get_x(), rectangle.get_y());
corners.emplace_back(rectangle.get_x()+rectangle.get_width(), rectangle.get_y());
corners.emplace_back(rectangle.get_x(), rectangle.get_y()+rectangle.get_height());
corners.emplace_back(rectangle.get_x()+rectangle.get_width(), rectangle.get_y()+rectangle.get_height());
for(auto &corner: corners) {
if(diff_x*corner.x + diff_y*corner.y >= 0)
return;
}
}
Tooltips::shown_tooltips.erase(this);
if(window)
window->hide();
shown=false;
}
void Tooltip::wrap_lines() {
@ -196,10 +224,8 @@ void Tooltip::wrap_lines() {
void Tooltips::show(const Gdk::Rectangle& rectangle, bool disregard_drawn) {
for(auto &tooltip : tooltip_list) {
tooltip.update();
if(rectangle.intersects(tooltip.activation_rectangle)) {
tooltip.show(disregard_drawn);
shown=true;
}
if(rectangle.intersects(tooltip.activation_rectangle))
tooltip.show(disregard_drawn, on_motion);
else
tooltip.hide();
}
@ -208,13 +234,11 @@ void Tooltips::show(const Gdk::Rectangle& rectangle, bool disregard_drawn) {
void Tooltips::show(bool disregard_drawn) {
for(auto &tooltip : tooltip_list) {
tooltip.update();
tooltip.show(disregard_drawn);
shown=true;
tooltip.show(disregard_drawn, on_motion);
}
}
void Tooltips::hide() {
void Tooltips::hide(const std::pair<int, int> &last_mouse_pos, const std::pair<int, int> &mouse_pos) {
for(auto &tooltip : tooltip_list)
tooltip.hide();
shown=false;
tooltip.hide(last_mouse_pos, mouse_pos);
}

15
src/tooltips.h

@ -12,8 +12,8 @@ public:
~Tooltip();
void update();
void show(bool disregard_drawn=false);
void hide();
void show(bool disregard_drawn=false, const std::function<void()> &on_motion=nullptr);
void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
Gdk::Rectangle activation_rectangle;
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
@ -27,17 +27,20 @@ private:
std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer;
Gtk::TextView *text_view;
std::pair<int, int> size;
std::pair<int, int> position;
Gdk::Rectangle rectangle;
bool shown=false;
};
class Tooltips {
public:
static std::set<Tooltip*> shown_tooltips;
static Gdk::Rectangle drawn_tooltips_rectangle;
static void init() {drawn_tooltips_rectangle=Gdk::Rectangle();}
void show(const Gdk::Rectangle& rectangle, bool disregard_drawn=false);
void show(bool disregard_drawn=false);
bool shown=false;
void hide();
void hide(const std::pair<int, int> &last_mouse_pos = {-1, -1}, const std::pair<int, int> &mouse_pos = {-1, -1});
void clear() {tooltip_list.clear();};
template<typename... Ts>
@ -45,7 +48,7 @@ public:
tooltip_list.emplace_back(std::forward<Ts>(params)...);
}
static Gdk::Rectangle drawn_tooltips_rectangle;
std::function<void()> on_motion;
private:
std::list<Tooltip> tooltip_list;

2
tests/stubs/tooltips.cc

@ -13,4 +13,4 @@ void Tooltips::show(Gdk::Rectangle const&, bool) {}
void Tooltips::show(bool) {}
void Tooltips::hide() {}
void Tooltips::hide(const std::pair<int, int> &, const std::pair<int, int> &) {}

Loading…
Cancel
Save