From 2ec8ff15d73ad80396df879020ea704a71e9bcfe Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 9 Jul 2015 15:31:26 +0200 Subject: [PATCH] Added comments to autocompletion. Try with gtkmm objects. --- juci/selectiondialog.cc | 40 +++++++++++++++++++++++++++++++++------- juci/selectiondialog.h | 7 +++++-- juci/source.cc | 27 ++++++++++++++++----------- juci/source.h | 1 + juci/tooltips.cc | 26 ++++++++++++++------------ juci/tooltips.h | 6 +++--- 6 files changed, 72 insertions(+), 35 deletions(-) diff --git a/juci/selectiondialog.cc b/juci/selectiondialog.cc index 6a703ad..7d333ca 100644 --- a/juci/selectiondialog.cc +++ b/juci/selectiondialog.cc @@ -1,7 +1,5 @@ #include "selectiondialog.h" #include -#include -using namespace std; SelectionDialog::SelectionDialog(Gtk::TextView& text_view): text_view(text_view) { @@ -33,6 +31,9 @@ void SelectionDialog::show() { select(); } }); + list_view_text->signal_cursor_changed().connect([this](){ + cursor_changed(); + }); list_view_text->signal_realize().connect([this](){ resize(); }); @@ -69,24 +70,26 @@ void SelectionDialog::hide() { void SelectionDialog::select(bool hide_window) { selected=true; auto selected=list_view_text->get_selected(); - std::string select; + std::pair select; if(selected.size()>0) { select = rows.at(list_view_text->get_text(selected[0])); text_view.get_buffer()->erase(start_mark->get_iter(), text_view.get_buffer()->get_insert()->get_iter()); - text_view.get_buffer()->insert(start_mark->get_iter(), select); + text_view.get_buffer()->insert(start_mark->get_iter(), select.first); } if(hide_window) { + if(tooltips) + tooltips->hide(); hide(); - char find_char=select.back(); + char find_char=select.first.back(); if(find_char==')' || find_char=='>') { if(find_char==')') find_char='('; else find_char='<'; - size_t pos=select.find(find_char); + size_t pos=select.first.find(find_char); if(pos!=std::string::npos) { auto start_offset=start_mark->get_iter().get_offset()+pos+1; - auto end_offset=start_mark->get_iter().get_offset()+select.size()-1; + auto end_offset=start_mark->get_iter().get_offset()+select.first.size()-1; if(start_offset!=end_offset) text_view.get_buffer()->select_range(text_view.get_buffer()->get_iter_at_offset(start_offset), text_view.get_buffer()->get_iter_at_offset(end_offset)); } @@ -137,6 +140,7 @@ bool SelectionDialog::on_key_press(GdkEventKey* key) { } } select(false); + cursor_changed(); return true; } if(key->keyval==GDK_KEY_Up) { @@ -149,6 +153,7 @@ bool SelectionDialog::on_key_press(GdkEventKey* key) { } } select(false); + cursor_changed(); return true; } if(key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_ISO_Left_Tab || key->keyval==GDK_KEY_Tab) { @@ -159,6 +164,27 @@ bool SelectionDialog::on_key_press(GdkEventKey* key) { return false; } +void SelectionDialog::cursor_changed() { + if(tooltips) + tooltips->hide(); + auto selected=list_view_text->get_selected(); + if(selected.size()>0) { + auto select = rows.at(list_view_text->get_text(selected[0])); + if(select.second.size()>0) { + tooltips=std::unique_ptr(new Tooltips()); + auto tooltip_text=select.second; + auto get_tooltip_buffer=[this, tooltip_text]() { + auto tooltip_buffer=Gtk::TextBuffer::create(text_view.get_buffer()->get_tag_table()); + //TODO: Insert newlines to tooltip_text (use 80 chars, then newline?) + tooltip_buffer->insert_at_cursor(tooltip_text); + return tooltip_buffer; + }; + tooltips->emplace_back(get_tooltip_buffer, text_view, text_view.get_buffer()->create_mark(start_mark->get_iter()), text_view.get_buffer()->create_mark(text_view.get_buffer()->get_insert()->get_iter())); + tooltips->show(true); + } + } +} + void SelectionDialog::move() { INFO("SelectionDialog set position"); Gdk::Rectangle rectangle; diff --git a/juci/selectiondialog.h b/juci/selectiondialog.h index eb979e9..ec27d9b 100644 --- a/juci/selectiondialog.h +++ b/juci/selectiondialog.h @@ -3,6 +3,7 @@ #include "gtkmm.h" #include "logging.h" +#include "tooltips.h" class SelectionDialog { public: @@ -14,12 +15,13 @@ public: bool on_key_release(GdkEventKey* key); bool on_key_press(GdkEventKey* key); - std::map rows; + std::map > rows; bool shown=false; private: void resize(); - void select(bool hide_window=true); + void select(bool hide_window=true); + void cursor_changed(); Gtk::Entry search_entry; Glib::RefPtr start_mark; @@ -30,6 +32,7 @@ private: std::unique_ptr window; std::unique_ptr scrolled_window; std::unique_ptr list_view_text; + std::unique_ptr tooltips; }; #endif // JUCI_SELECTIONDIALOG_H_ \ No newline at end of file diff --git a/juci/source.cc b/juci/source.cc index 6df1ca3..9ff1a95 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -287,12 +287,16 @@ get_autocomplete_suggestions(int line_number, int column, std::map chunks_ = results.get(i).get_chunks(); - std::vector chunks; - for (auto &chunk : chunks_) { - chunks.emplace_back(chunk); + auto result=results.get(i); + const vector chunks_ = result.get_chunks(); + if(chunks_.size()>0) { + std::vector chunks; + for (auto &chunk : chunks_) { + chunks.emplace_back(chunk); + } + suggestions.emplace_back(chunks); + suggestions.back().brief_comments=result.get_brief_comments(); } - suggestions.emplace_back(chunks); } DEBUG("Number of suggestions"); DEBUG_VAR(suggestions.size()); @@ -418,7 +422,7 @@ void Source::ClangView::update_types() { auto get_tooltip_buffer=[this, c]() { auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table()); tooltip_buffer->insert_at_cursor("Type: "+(*clang_tokens)[c].type); - auto brief_comment=clang_tokens->get_brief_comment(c); + auto brief_comment=clang_tokens->get_brief_comments(c); if(brief_comment!="") tooltip_buffer->insert_at_cursor("\n\n"+brief_comment); return tooltip_buffer; @@ -573,7 +577,7 @@ bool Source::ClangView::on_key_release(GdkEventKey* key) { std::shared_ptr > ac_data=std::make_shared >(); autocomplete_done_function=[this, ac_data](){ if(!autocomplete_cancel) { - std::map rows; + std::map > rows; for (auto &data : *ac_data) { std::stringstream ss; std::string return_value; @@ -587,11 +591,12 @@ bool Source::ClangView::on_key_release(GdkEventKey* key) { } } if (ss.str().length() > 0) { // if length is 0 the result is empty - rows[ss.str() + " --> " + return_value] = ss.str(); + auto pair=std::pair(ss.str(), data.brief_comments); + rows[ss.str() + " --> " + return_value] = pair; } } if (rows.empty()) { - rows["No suggestions found..."] = ""; + rows["No suggestions found..."] = std::pair(); } selection_dialog.rows=std::move(rows); selection_dialog.show(); @@ -614,8 +619,8 @@ bool Source::ClangView::on_key_release(GdkEventKey* key) { autocomplete_thread.detach(); } else { - std::map rows; - rows["Autocomplete already running, try again."] = ""; + std::map > rows; + rows["Autocomplete already running, try again."] = std::pair("", ""); selection_dialog.rows=std::move(rows); selection_dialog.show(); } diff --git a/juci/source.h b/juci/source.h index e65b34a..1cc82de 100644 --- a/juci/source.h +++ b/juci/source.h @@ -56,6 +56,7 @@ namespace Source { explicit AutoCompleteData(const std::vector &chunks) : chunks(chunks) { } std::vector chunks; + std::string brief_comments; }; class View : public Gsv::View { diff --git a/juci/tooltips.cc b/juci/tooltips.cc index 130e4cf..01d05f5 100644 --- a/juci/tooltips.cc +++ b/juci/tooltips.cc @@ -16,8 +16,8 @@ Tooltip::~Tooltip() { void Tooltip::update() { auto iter=start_mark->get_iter(); auto end_iter=end_mark->get_iter(); + text_view.get_iter_location(iter, activation_rectangle); if(iter.get_offset()(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP)); @@ -63,13 +63,15 @@ void Tooltip::adjust() { rectangle.set_width(tooltip_width); rectangle.set_height(tooltip_height); - 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); + if(!disregard_drawn) { + 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::drawn_tooltips_rectangle=rectangle; } - else - Tooltips::drawn_tooltips_rectangle=rectangle; window->move(rectangle.get_x(), rectangle.get_y()); } @@ -79,11 +81,11 @@ bool Tooltip::tooltip_on_motion_notify_event(GdkEventMotion* event) { return false; } -void Tooltips::show(const Gdk::Rectangle& rectangle) { +void Tooltips::show(const Gdk::Rectangle& rectangle, bool disregard_drawn) { for(auto& tooltip: *this) { tooltip.update(); if(rectangle.intersects(tooltip.activation_rectangle)) { - tooltip.adjust(); + tooltip.adjust(disregard_drawn); tooltip.window->show_all(); } else if(tooltip.window) @@ -91,10 +93,10 @@ void Tooltips::show(const Gdk::Rectangle& rectangle) { } } -void Tooltips::show() { +void Tooltips::show(bool disregard_drawn) { for(auto& tooltip: *this) { tooltip.update(); - tooltip.adjust(); + tooltip.adjust(disregard_drawn); tooltip.window->show_all(); } } diff --git a/juci/tooltips.h b/juci/tooltips.h index 9189622..4bd4466 100644 --- a/juci/tooltips.h +++ b/juci/tooltips.h @@ -10,7 +10,7 @@ public: ~Tooltip(); void update(); - void adjust(); + void adjust(bool disregard_drawn=false); Gdk::Rectangle activation_rectangle; std::unique_ptr window; @@ -28,8 +28,8 @@ private: class Tooltips : public std::list { public: void init() {drawn_tooltips_rectangle=Gdk::Rectangle();} - void show(const Gdk::Rectangle& rectangle); - void show(); + void show(const Gdk::Rectangle& rectangle, bool disregard_drawn=false); + void show(bool disregard_drawn=false); void hide(); static Gdk::Rectangle drawn_tooltips_rectangle;