Browse Source

Some cleanup, and added colors in tooltips.

merge-requests/365/head
eidheim 11 years ago
parent
commit
7bcdeae516
  1. 4
      juci/config.json
  2. 28
      juci/source.cc
  3. 83
      juci/tooltips.cc
  4. 30
      juci/tooltips.h

4
juci/config.json

@ -8,7 +8,9 @@
"type": "#0066FF",
"keyword": "blue",
"comment": "grey",
"own": "pink"
"own": "pink",
"diagnostic_warning": "orange",
"diagnostic_error": "red"
},
"syntax": {
"43": "type",

28
juci/source.cc

@ -136,7 +136,7 @@ clang::Index Source::ClangView::clang_index(0, 0);
Source::ClangView::ClangView(const Source::Config& config, const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal):
Source::View(config, file_path, project_path), terminal(terminal),
parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false), diagnostic_tooltips(*this) {
parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
override_font(Pango::FontDescription(config.font));
override_background_color(Gdk::RGBA(config.background));
for (auto &item : config.tags) {
@ -357,20 +357,26 @@ void Source::ClangView::update_diagnostics() {
if(diagnostic.path==file_path) {
auto start=buffer->get_iter_at_offset(diagnostic.start_location.offset);
auto end=buffer->get_iter_at_offset(diagnostic.end_location.offset);
diagnostic_tooltips.add(diagnostic.severity_spelling+": "+diagnostic.spelling, get_source_buffer()->create_mark(start), get_source_buffer()->create_mark(end));
std::string diagnostic_tag_name;
if(diagnostic.severity<=CXDiagnostic_Warning)
diagnostic_tag_name="diagnostic_warning";
else
diagnostic_tag_name="diagnostic_error";
auto tooltip_widget=std::make_shared<Gtk::TextView>(Gtk::TextBuffer::create(buffer->get_tag_table()));
tooltip_widget->set_editable(false);
tooltip_widget->get_buffer()->insert_with_tag(tooltip_widget->get_buffer()->get_insert()->get_iter(), diagnostic.severity_spelling, diagnostic_tag_name);
tooltip_widget->get_buffer()->insert_at_cursor(": "+diagnostic.spelling);
diagnostic_tooltips.emplace_back(tooltip_widget, *this, get_source_buffer()->create_mark(start), get_source_buffer()->create_mark(end));
auto tag=buffer->create_tag();
tag->property_underline()=Pango::Underline::UNDERLINE_ERROR;
auto tag_class=G_OBJECT_GET_CLASS(tag->gobj()); //For older GTK+ 3 versions:
auto param_spec=g_object_class_find_property(tag_class, "underline-rgba");
if(param_spec!=NULL) {
if(diagnostic.severity<=CXDiagnostic_Warning) {
//TODO: get color from config.json
tag->set_property("underline-rgba", Gdk::RGBA("orange"));
}
else {
//TODO: get color from config.json
tag->set_property("underline-rgba", Gdk::RGBA("red"));
}
auto diagnostic_tag=buffer->get_tag_table()->lookup(diagnostic_tag_name);
if(diagnostic_tag!=0)
tag->set_property("underline-rgba", diagnostic_tag->property_foreground_rgba().get_value());
}
buffer->apply_tag(tag, start, end);
}
@ -380,6 +386,7 @@ void Source::ClangView::update_diagnostics() {
bool Source::ClangView::clangview_on_motion_notify_event(GdkEventMotion* event) {
Gdk::Rectangle rectangle(event->x, event->y, 1, 1);
diagnostic_tooltips.init();
diagnostic_tooltips.show(rectangle);
return false;
}
@ -393,6 +400,7 @@ void Source::ClangView::clangview_on_mark_set(const Gtk::TextBuffer::iterator& i
rectangle.set_x(location_window_x-2);
rectangle.set_y(location_window_y);
rectangle.set_width(4);
diagnostic_tooltips.init();
diagnostic_tooltips.show(rectangle);
}
}

83
juci/tooltips.cc

@ -1,94 +1,89 @@
#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):
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) {
get_content_area()->add(label);
get_content_area()->add(*widget);
property_decorated()=false;
set_accept_focus(false);
signal_realize().connect([this](){
adjust(); //Fix for older GTK+ versions?
});
}
void Tooltip::update() {
auto iter=start_mark->get_iter();
auto end_iter=end_mark->get_iter();
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++;
while(iter!=end_iter) {
Gdk::Rectangle rectangle;
text_view.get_iter_location(iter, rectangle);
text_rectangle.join(rectangle);
activation_rectangle.join(rectangle);
iter++;
}
}
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_rectangle.set_x(location_window_x);
text_rectangle.set_y(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);
activation_rectangle.set_x(location_window_x);
activation_rectangle.set_y(location_window_y);
adjusted=false;
}
void Tooltip::adjust() {
if(adjusted)
return;
int tooltip_width, tooltip_height;
get_size(tooltip_width, tooltip_height);
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;
rectangle.set_x(root_x);
rectangle.set_y(root_y-tooltip_height);
rectangle.set_width(tooltip_width);
rectangle.set_height(tooltip_height);
if(Tooltips::tooltips_rectangle.get_width()!=0) {
if(rectangle.intersects(Tooltips::tooltips_rectangle))
rectangle.set_y(Tooltips::tooltips_rectangle.get_y()-tooltip_height);
Tooltips::tooltips_rectangle.join(rectangle);
if(Tooltips::drawn_tooltips_rectangle.get_width()!=0) {
if(rectangle.intersects(Tooltips::drawn_tooltips_rectangle))
rectangle.set_y(Tooltips::drawn_tooltips_rectangle.get_y()-tooltip_height);
Tooltips::drawn_tooltips_rectangle.join(rectangle);
}
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());
adjusted=true;
}
void Tooltips::add(const std::string& text, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark) {
tooltips.emplace_back(new Tooltip(text_view, text, start_mark, end_mark));
}
//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.
//If not, they would overlap (clear_tooltips_rectangle=false to avoid this on the following Tooltips-objects)
void Tooltips::show(const Gdk::Rectangle& rectangle, bool clear_tooltips_rectangle) {
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();
void Tooltips::show(const Gdk::Rectangle& rectangle) {
for(auto& tooltip: *this) {
tooltip.update();
if(rectangle.intersects(tooltip.activation_rectangle)) {
tooltip.show_all();
if(tooltip.get_realized())
tooltip.adjust();
}
else
tooltip->hide();
tooltip.hide();
}
text_view.grab_focus();
}
//See Tooltips::show(const Gdk::Rectangle& rectangle, bool clear_tooltips_rectangle=true)
void Tooltips::show(bool clear_tooltips_rectangle) {
if(clear_tooltips_rectangle)
tooltips_rectangle=Gdk::Rectangle();
for(auto& tooltip: tooltips) {
tooltip->update();
tooltip->show_all();
tooltip->adjust();
void Tooltips::show() {
for(auto& tooltip: *this) {
tooltip.update();
tooltip.show_all();
if(tooltip.get_realized())
tooltip.adjust();
}
text_view.grab_focus();
}
void Tooltips::hide() {
for(auto& tooltip: tooltips) {
tooltip->hide();
for(auto& tooltip: *this) {
tooltip.hide();
}
}

30
juci/tooltips.h

@ -2,40 +2,32 @@
#define JUCI_TOOLTIPS_H_
#include "gtkmm.h"
#include <string>
#include <vector>
#include <list>
class Tooltip : public Gtk::Dialog {
public:
Tooltip(Gtk::TextView& text_view, const std::string& label_text, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
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);
void update();
void adjust();
Gtk::Label label;
Gdk::Rectangle activation_rectangle;
bool adjusted=false;
private:
std::shared_ptr<Gtk::Widget> widget;
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
Gdk::Rectangle text_rectangle;
private:
Gtk::TextView& text_view;
};
class Tooltips {
class Tooltips : public std::list<Tooltip> {
public:
Tooltips(Gtk::TextView& text_view): text_view(text_view) {}
void clear() {tooltips.clear();}
void add(const std::string& text, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
void show(const Gdk::Rectangle& rectangle, bool clear_tooltips_rectangle=true);
void show(bool clear_tooltips_rectangle=true);
void init() {drawn_tooltips_rectangle=Gdk::Rectangle();}
void show(const Gdk::Rectangle& rectangle);
void show();
void hide();
static Gdk::Rectangle tooltips_rectangle;
private:
Gtk::TextView& text_view;
std::vector<std::unique_ptr<Tooltip> > tooltips;
static Gdk::Rectangle drawn_tooltips_rectangle;
};
#endif // JUCI_TOOLTIPS_H_

Loading…
Cancel
Save