Browse Source

Type info.

merge-requests/365/head
eidheim 11 years ago
parent
commit
655a30023a
  1. 61
      juci/source.cc
  2. 2
      juci/source.h
  3. 48
      juci/tooltips.cc
  4. 9
      juci/tooltips.h

61
juci/source.cc

@ -307,7 +307,9 @@ extract_tokens(int start_offset, int end_offset) {
clang::SourceLocation end(tu_.get(), file_path, end_offset);
clang::SourceRange range(&start, &end);
clang::Tokens tokens(tu_.get(), &range);
std::vector<clang::Token> tks = tokens.tokens();
tokens.get_token_types(tu_.get());
std::vector<clang::Token>& tks = tokens.tokens();
update_types(tks);
for (auto &token : tks) {
switch (token.kind()) {
case 0: highlight_cursor(&token, &ranges); break; // PunctuationToken
@ -352,34 +354,63 @@ void Source::ClangView::update_syntax(const std::vector<Source::Range> &ranges)
void Source::ClangView::update_diagnostics() {
diagnostic_tooltips.clear();
auto diagnostics=tu_->get_diagnostics();
auto buffer=get_source_buffer();
for(auto& diagnostic: 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);
auto start=get_buffer()->get_iter_at_offset(diagnostic.start_location.offset);
auto end=get_buffer()->get_iter_at_offset(diagnostic.end_location.offset);
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(": \n"+diagnostic.spelling);
//TODO: Insert newlines to diagnostic.spelling (use 80 chars, then newline?)
diagnostic_tooltips.emplace_back(tooltip_widget, *this, get_source_buffer()->create_mark(start), get_source_buffer()->create_mark(end));
auto tag=buffer->create_tag();
std::string spelling=diagnostic.spelling;
std::string severity_spelling=diagnostic.severity_spelling;
auto get_tooltip_buffer=[this, spelling, severity_spelling, diagnostic_tag_name]() {
auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), severity_spelling, diagnostic_tag_name);
tooltip_buffer->insert_at_cursor(":\n"+spelling);
//TODO: Insert newlines to diagnostic.spelling (use 80 chars, then newline?)
return tooltip_buffer;
};
diagnostic_tooltips.emplace_back(get_tooltip_buffer, *this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
auto tag=get_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) {
auto diagnostic_tag=buffer->get_tag_table()->lookup(diagnostic_tag_name);
auto diagnostic_tag=get_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);
get_buffer()->apply_tag(tag, start, end);
}
}
}
void Source::ClangView::update_types(std::vector<clang::Token>& tokens) {
type_tooltips.clear();
for(auto& token: tokens) {
if(token.type!="") {
clang::SourceRange range(tu_.get(), &token);
clang::SourceLocation start(&range, true);
clang::SourceLocation end(&range, false);
std::string path;
unsigned start_offset, end_offset;
start.get_location_info(&path, NULL, NULL, &start_offset);
end.get_location_info(NULL, NULL, NULL, &end_offset);
if(path==file_path) {
auto start=get_buffer()->get_iter_at_offset(start_offset);
auto end=get_buffer()->get_iter_at_offset(end_offset);
auto get_tooltip_buffer=[this, token]() {
auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
tooltip_buffer->insert_at_cursor("Type: "+token.type);
return tooltip_buffer;
};
type_tooltips.emplace_back(get_tooltip_buffer, *this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
}
}
}
}
@ -387,6 +418,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();
type_tooltips.show(rectangle);
diagnostic_tooltips.show(rectangle);
return false;
}
@ -401,6 +433,7 @@ void Source::ClangView::clangview_on_mark_set(const Gtk::TextBuffer::iterator& i
rectangle.set_y(location_window_y);
rectangle.set_width(4);
diagnostic_tooltips.init();
type_tooltips.show(rectangle);
diagnostic_tooltips.show(rectangle);
}
}

2
juci/source.h

@ -97,7 +97,9 @@ namespace Source {
std::vector<Range> extract_tokens(int, int);
void update_syntax(const std::vector<Range> &locations);
void update_diagnostics();
void update_types(std::vector<clang::Token>& tokens);
Tooltips diagnostic_tooltips;
Tooltips type_tooltips;
bool clangview_on_motion_notify_event(GdkEventMotion* event);
void clangview_on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark);

48
juci/tooltips.cc

@ -3,19 +3,14 @@
Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle();
Tooltip::Tooltip(std::shared_ptr<Gtk::TextView> tooltip_widget, Gtk::TextView& text_view,
Tooltip::Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> get_buffer, Gtk::TextView& text_view,
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark):
tooltip_widget(tooltip_widget), text_view(text_view), Gtk::Window(Gtk::WindowType::WINDOW_POPUP),
start_mark(start_mark), end_mark(end_mark) {
add(*tooltip_widget);
property_decorated()=false;
set_accept_focus(false);
set_skip_taskbar_hint(true);
set_default_size(0, 0);
get_buffer(get_buffer), text_view(text_view),
start_mark(start_mark), end_mark(end_mark) {}
auto layout=Pango::Layout::create(tooltip_widget->get_pango_context());
layout->set_text(tooltip_widget->get_buffer()->get_text());
layout->get_pixel_size(tooltip_width, tooltip_height);
Tooltip::~Tooltip() {
text_view.get_buffer()->delete_mark(start_mark);
text_view.get_buffer()->delete_mark(end_mark);
}
void Tooltip::update() {
@ -38,6 +33,24 @@ void Tooltip::update() {
}
void Tooltip::adjust() {
if(!window) {
//init window
window=std::unique_ptr<Gtk::Window>(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP));
window->property_decorated()=false;
window->set_accept_focus(false);
window->set_skip_taskbar_hint(true);
window->set_default_size(0, 0);
tooltip_widget=std::unique_ptr<Gtk::TextView>(new Gtk::TextView(this->get_buffer()));
tooltip_widget->set_editable(false);
window->add(*tooltip_widget);
auto layout=Pango::Layout::create(tooltip_widget->get_pango_context());
layout->set_text(tooltip_widget->get_buffer()->get_text());
layout->get_pixel_size(tooltip_width, tooltip_height);
}
int 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;
@ -54,7 +67,7 @@ void Tooltip::adjust() {
else
Tooltips::drawn_tooltips_rectangle=rectangle;
move(rectangle.get_x(), rectangle.get_y());
window->move(rectangle.get_x(), rectangle.get_y());
}
void Tooltips::show(const Gdk::Rectangle& rectangle) {
@ -62,10 +75,10 @@ void Tooltips::show(const Gdk::Rectangle& rectangle) {
tooltip.update();
if(rectangle.intersects(tooltip.activation_rectangle)) {
tooltip.adjust();
tooltip.show_all();
tooltip.window->show_all();
}
else
tooltip.hide();
else if(tooltip.window)
tooltip.window->hide();
}
}
@ -73,12 +86,13 @@ void Tooltips::show() {
for(auto& tooltip: *this) {
tooltip.update();
tooltip.adjust();
tooltip.show_all();
tooltip.window->show_all();
}
}
void Tooltips::hide() {
for(auto& tooltip: *this) {
tooltip.hide();
if(tooltip.window)
tooltip.window->hide();
}
}

9
juci/tooltips.h

@ -4,16 +4,19 @@
#include <string>
#include <list>
class Tooltip : public Gtk::Window {
class Tooltip {
public:
Tooltip(std::shared_ptr<Gtk::TextView> tooltip_widget, Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> get_buffer, Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
~Tooltip();
void update();
void adjust();
Gdk::Rectangle activation_rectangle;
std::unique_ptr<Gtk::Window> window;
private:
std::shared_ptr<Gtk::TextView> tooltip_widget;
std::function<Glib::RefPtr<Gtk::TextBuffer>()> get_buffer;
std::unique_ptr<Gtk::TextView> tooltip_widget;
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
Gtk::TextView& text_view;

Loading…
Cancel
Save