mirror of https://gitlab.com/cppit/jucipp
4 changed files with 71 additions and 74 deletions
@ -1,94 +1,89 @@ |
|||||||
#include "tooltips.h" |
#include "tooltips.h" |
||||||
|
#include <thread> |
||||||
|
|
||||||
Gdk::Rectangle Tooltips::tooltips_rectangle=Gdk::Rectangle(); |
Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle(); |
||||||
|
|
||||||
Tooltip::Tooltip(Gtk::TextView& text_view, const std::string& label_text,
|
Tooltip::Tooltip(std::shared_ptr<Gtk::Widget> widget, Gtk::TextView& text_view,
|
||||||
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark): |
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark): |
||||||
text_view(text_view), Gtk::Dialog("", (Gtk::Window&)*text_view.get_toplevel()), label(label_text),
|
widget(widget), text_view(text_view), Gtk::Dialog("", (Gtk::Window&)*text_view.get_toplevel()),
|
||||||
start_mark(start_mark), end_mark(end_mark) { |
start_mark(start_mark), end_mark(end_mark) { |
||||||
get_content_area()->add(label); |
get_content_area()->add(*widget); |
||||||
property_decorated()=false; |
property_decorated()=false; |
||||||
set_accept_focus(false); |
set_accept_focus(false); |
||||||
|
signal_realize().connect([this](){ |
||||||
|
adjust(); //Fix for older GTK+ versions?
|
||||||
|
}); |
||||||
} |
} |
||||||
|
|
||||||
void Tooltip::update() { |
void Tooltip::update() { |
||||||
auto iter=start_mark->get_iter(); |
auto iter=start_mark->get_iter(); |
||||||
auto end_iter=end_mark->get_iter(); |
auto end_iter=end_mark->get_iter(); |
||||||
if(iter.get_offset()<end_iter.get_offset()) { |
if(iter.get_offset()<end_iter.get_offset()) { |
||||||
text_view.get_iter_location(iter, text_rectangle); |
text_view.get_iter_location(iter, activation_rectangle); |
||||||
iter++; |
iter++; |
||||||
while(iter!=end_iter) { |
while(iter!=end_iter) { |
||||||
Gdk::Rectangle rectangle; |
Gdk::Rectangle rectangle; |
||||||
text_view.get_iter_location(iter, rectangle); |
text_view.get_iter_location(iter, rectangle); |
||||||
text_rectangle.join(rectangle); |
activation_rectangle.join(rectangle); |
||||||
iter++; |
iter++; |
||||||
} |
} |
||||||
} |
} |
||||||
int location_window_x, location_window_y; |
int location_window_x, location_window_y; |
||||||
text_view.buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, text_rectangle.get_x(), text_rectangle.get_y(), location_window_x, location_window_y); |
text_view.buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, activation_rectangle.get_x(), activation_rectangle.get_y(), location_window_x, location_window_y); |
||||||
text_rectangle.set_x(location_window_x); |
activation_rectangle.set_x(location_window_x); |
||||||
text_rectangle.set_y(location_window_y); |
activation_rectangle.set_y(location_window_y); |
||||||
|
adjusted=false; |
||||||
} |
} |
||||||
|
|
||||||
void Tooltip::adjust() { |
void Tooltip::adjust() { |
||||||
|
if(adjusted) |
||||||
|
return; |
||||||
int tooltip_width, tooltip_height; |
int tooltip_width, tooltip_height; |
||||||
get_size(tooltip_width, tooltip_height); |
get_size(tooltip_width, tooltip_height); |
||||||
int root_x, root_y; |
int root_x, root_y; |
||||||
text_view.get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(text_rectangle.get_x(), text_rectangle.get_y(), root_x, root_y); |
text_view.get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle.get_x(), activation_rectangle.get_y(), root_x, root_y); |
||||||
Gdk::Rectangle rectangle; |
Gdk::Rectangle rectangle; |
||||||
rectangle.set_x(root_x); |
rectangle.set_x(root_x); |
||||||
rectangle.set_y(root_y-tooltip_height); |
rectangle.set_y(root_y-tooltip_height); |
||||||
rectangle.set_width(tooltip_width); |
rectangle.set_width(tooltip_width); |
||||||
rectangle.set_height(tooltip_height); |
rectangle.set_height(tooltip_height); |
||||||
|
|
||||||
if(Tooltips::tooltips_rectangle.get_width()!=0) { |
if(Tooltips::drawn_tooltips_rectangle.get_width()!=0) { |
||||||
if(rectangle.intersects(Tooltips::tooltips_rectangle)) |
if(rectangle.intersects(Tooltips::drawn_tooltips_rectangle)) |
||||||
rectangle.set_y(Tooltips::tooltips_rectangle.get_y()-tooltip_height); |
rectangle.set_y(Tooltips::drawn_tooltips_rectangle.get_y()-tooltip_height); |
||||||
Tooltips::tooltips_rectangle.join(rectangle); |
Tooltips::drawn_tooltips_rectangle.join(rectangle); |
||||||
} |
} |
||||||
else |
else |
||||||
Tooltips::tooltips_rectangle=rectangle; |
Tooltips::drawn_tooltips_rectangle=rectangle; |
||||||
|
|
||||||
if(rectangle.get_y()<0) |
|
||||||
rectangle.set_y(0); |
|
||||||
move(rectangle.get_x(), rectangle.get_y()); |
move(rectangle.get_x(), rectangle.get_y()); |
||||||
|
adjusted=true; |
||||||
} |
} |
||||||
|
|
||||||
void Tooltips::add(const std::string& text, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark) { |
void Tooltips::show(const Gdk::Rectangle& rectangle) { |
||||||
tooltips.emplace_back(new Tooltip(text_view, text, start_mark, end_mark)); |
for(auto& tooltip: *this) { |
||||||
} |
tooltip.update(); |
||||||
|
if(rectangle.intersects(tooltip.activation_rectangle)) { |
||||||
//If you want to show tooltips from several Tooltips-objects at once, you might want to set clear_tooltips_rectangle=true only on the first one.
|
tooltip.show_all(); |
||||||
//If not, they would overlap (clear_tooltips_rectangle=false to avoid this on the following Tooltips-objects)
|
if(tooltip.get_realized()) |
||||||
void Tooltips::show(const Gdk::Rectangle& rectangle, bool clear_tooltips_rectangle) { |
tooltip.adjust(); |
||||||
if(clear_tooltips_rectangle) |
|
||||||
tooltips_rectangle=Gdk::Rectangle(); |
|
||||||
for(auto& tooltip: tooltips) { |
|
||||||
tooltip->update(); |
|
||||||
if(rectangle.intersects(tooltip->text_rectangle)) { |
|
||||||
tooltip->show_all(); |
|
||||||
tooltip->adjust(); |
|
||||||
} |
} |
||||||
else |
else |
||||||
tooltip->hide(); |
tooltip.hide(); |
||||||
} |
} |
||||||
text_view.grab_focus(); |
|
||||||
} |
} |
||||||
|
|
||||||
//See Tooltips::show(const Gdk::Rectangle& rectangle, bool clear_tooltips_rectangle=true)
|
void Tooltips::show() { |
||||||
void Tooltips::show(bool clear_tooltips_rectangle) { |
for(auto& tooltip: *this) { |
||||||
if(clear_tooltips_rectangle) |
tooltip.update(); |
||||||
tooltips_rectangle=Gdk::Rectangle(); |
tooltip.show_all(); |
||||||
for(auto& tooltip: tooltips) { |
if(tooltip.get_realized()) |
||||||
tooltip->update(); |
tooltip.adjust(); |
||||||
tooltip->show_all(); |
|
||||||
tooltip->adjust(); |
|
||||||
} |
} |
||||||
text_view.grab_focus(); |
|
||||||
} |
} |
||||||
|
|
||||||
void Tooltips::hide() { |
void Tooltips::hide() { |
||||||
for(auto& tooltip: tooltips) { |
for(auto& tooltip: *this) { |
||||||
tooltip->hide(); |
tooltip.hide(); |
||||||
} |
} |
||||||
} |
} |
||||||
|
|||||||
Loading…
Reference in new issue