Browse Source

Cleanup and fixes to dialog and tooltip positioning. Dialogs and tooltips should now not be partially shown outside of screen

merge-requests/399/head
eidheim 6 years ago
parent
commit
78659e5177
  1. 31
      src/project.cc
  2. 36
      src/selection_dialog.cc
  3. 4
      src/selection_dialog.h
  4. 16
      src/source_base.cc
  5. 1
      src/source_base.h
  6. 2
      src/source_spellcheck.cc
  7. 21
      src/tooltips.cc
  8. 18
      src/window.cc

31
src/project.cc

@ -216,10 +216,8 @@ void Project::Base::show_symbols() {
}
stream->seekg(0, std::ios::beg);
if(view) {
auto dialog_iter = view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
}
if(view)
SelectionDialog::create(view, true, true);
else
SelectionDialog::create(true, true);
@ -512,10 +510,8 @@ void Project::LLDB::debug_backtrace() {
auto view = Notebook::get().get_current_view();
auto backtrace = Debug::LLDB::get().get_backtrace();
if(view) {
auto iter = view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(iter), true, true);
}
if(view)
SelectionDialog::create(view, true, true);
else
SelectionDialog::create(true, true);
std::vector<Debug::LLDB::Frame> rows;
@ -571,11 +567,8 @@ void Project::LLDB::debug_show_variables() {
auto view = Notebook::get().get_current_view();
auto variables = Debug::LLDB::get().get_variables();
Gtk::TextIter iter;
if(view) {
iter = view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(iter), true, true);
}
if(view)
SelectionDialog::create(view, true, true);
else
SelectionDialog::create(true, true);
auto rows = std::make_shared<std::vector<Debug::LLDB::Variable>>();
@ -612,7 +605,7 @@ void Project::LLDB::debug_show_variables() {
self->debug_variable_tooltips.clear();
};
SelectionDialog::get()->on_changed = [self = this->shared_from_this(), rows, view, iter](unsigned int index, const std::string &text) {
SelectionDialog::get()->on_changed = [self = this->shared_from_this(), rows, view](unsigned int index, const std::string &text) {
if(index >= rows->size()) {
self->debug_variable_tooltips.hide();
return;
@ -633,8 +626,10 @@ void Project::LLDB::debug_show_variables() {
buffer->insert(buffer->get_insert()->get_iter(), value.substr(0, value.size() - 1));
}
};
if(view)
if(view) {
auto iter = view->get_buffer()->get_insert()->get_iter();
self->debug_variable_tooltips.emplace_back(view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter), std::move(set_tooltip_buffer));
}
else
self->debug_variable_tooltips.emplace_back(std::move(set_tooltip_buffer));
@ -697,10 +692,8 @@ void Project::LanguageProtocol::show_symbols() {
if(!capabilities.workspace_symbol && !(capabilities.document_symbol && language_protocol_view))
return Base::show_symbols();
if(view) {
auto dialog_iter = view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
}
if(view)
SelectionDialog::create(view, true, true);
else
SelectionDialog::create(true, true);

36
src/selection_dialog.cc

@ -97,26 +97,44 @@ SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, const Glib::R
int window_width = row_width + 1;
window.resize(window_width, window_height);
auto move_window_to_center = [this, application_window, window_width, window_height] {
int root_x, root_y;
application_window->get_position(root_x, root_y);
root_x += application_window->get_width() / 2 - window_width / 2;
root_y += application_window->get_height() / 2 - window_height / 2;
window.move(root_x, root_y);
};
if(this->text_view) {
Gdk::Rectangle iter_rect;
this->text_view->get_iter_location(this->start_mark->get_iter(), iter_rect);
Gdk::Rectangle visible_rect;
this->text_view->get_visible_rect(visible_rect);
int buffer_x = std::max(iter_rect.get_x(), visible_rect.get_x());
int visible_window_x, visible_window_max_y;
this->text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(), visible_rect.get_y() + visible_rect.get_height(), visible_window_x, visible_window_max_y);
Gdk::Rectangle iter_rect;
this->text_view->get_iter_location(this->start_mark->get_iter(), iter_rect);
int buffer_x = iter_rect.get_x();
int buffer_y = iter_rect.get_y() + iter_rect.get_height();
int window_x, window_y;
this->text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y, window_x, window_y);
if(window_y < 0 || window_y > visible_window_max_y) // Move dialog to center if it is above or below visible parts of text_view
move_window_to_center();
else {
window_x = std::max(window_x, visible_window_x); // Adjust right if dialog is left of text_view
int root_x, root_y;
this->text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y, root_x, root_y);
// Adjust left if dialog is right of screen
auto screen_width = Gdk::Screen::get_default()->get_width();
root_x = root_x + window_width > screen_width ? screen_width - window_width : root_x;
window.move(root_x, root_y + 1); //TODO: replace 1 with some margin
}
else {
int root_x, root_y;
application_window->get_position(root_x, root_y);
root_x += application_window->get_width() / 2 - window_width / 2;
root_y += application_window->get_height() / 2 - window_height / 2;
window.move(root_x, root_y);
}
else
move_window_to_center();
});
list_view_text.signal_cursor_changed().connect([this] {

4
src/selection_dialog.h

@ -75,8 +75,8 @@ class SelectionDialog : public SelectionDialogBase {
public:
bool on_key_press(GdkEventKey *key);
static void create(Gtk::TextView *text_view, const Glib::RefPtr<Gtk::TextBuffer::Mark> &start_mark, bool show_search_entry = true, bool use_markup = false) {
instance = std::unique_ptr<SelectionDialog>(new SelectionDialog(text_view, start_mark, show_search_entry, use_markup));
static void create(Gtk::TextView *text_view, bool show_search_entry = true, bool use_markup = false) {
instance = std::unique_ptr<SelectionDialog>(new SelectionDialog(text_view, text_view->get_buffer()->create_mark(text_view->get_buffer()->get_insert()->get_iter()), show_search_entry, use_markup));
}
static void create(bool show_search_entry = true, bool use_markup = false) {
instance = std::unique_ptr<SelectionDialog>(new SelectionDialog(nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), show_search_entry, use_markup));

16
src/source_base.cc

@ -511,22 +511,6 @@ Gtk::TextIter Source::BaseView::get_iter_at_line_end(int line_nr) {
}
}
Gtk::TextIter Source::BaseView::get_iter_for_dialog() {
auto iter = get_buffer()->get_insert()->get_iter();
Gdk::Rectangle visible_rect;
get_visible_rect(visible_rect);
Gdk::Rectangle iter_rect;
get_iter_location(iter, iter_rect);
iter_rect.set_width(1);
if(iter.get_line_offset() >= 80) {
get_iter_at_location(iter, visible_rect.get_x(), iter_rect.get_y());
get_iter_location(iter, iter_rect);
}
if(!visible_rect.intersects(iter_rect))
get_iter_at_location(iter, visible_rect.get_x(), visible_rect.get_y() + visible_rect.get_height() / 3);
return iter;
}
void Source::BaseView::place_cursor_at_line_pos(int line, int pos) {
get_buffer()->place_cursor(get_iter_at_line_pos(line, pos));
}

1
src/source_base.h

@ -43,7 +43,6 @@ namespace Source {
Gtk::TextIter get_iter_at_line_index(int line, int index);
Gtk::TextIter get_iter_at_line_end(int line_nr);
Gtk::TextIter get_iter_for_dialog();
/// Safely places cursor at line using get_iter_at_line_pos.
void place_cursor_at_line_pos(int line, int pos);

2
src/source_spellcheck.cc

@ -154,7 +154,7 @@ Source::SpellCheckView::SpellCheckView(const boost::filesystem::path &file_path,
delayed_spellcheck_suggestions_connection.disconnect();
delayed_spellcheck_suggestions_connection = Glib::signal_timeout().connect([this]() {
if(get_buffer()->get_insert()->get_iter().has_tag(spellcheck_error_tag)) {
SelectionDialog::create(this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false);
SelectionDialog::create(this, false);
auto word = get_word(get_buffer()->get_insert()->get_iter());
if(*word.first == '\'' && word.second.get_offset() - word.first.get_offset() >= 3) {
auto before_end = word.second;

21
src/tooltips.cc

@ -185,20 +185,25 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
int root_x = 0, root_y = 0;
if(text_view) {
//Adjust if tooltip is left of text_view
Gdk::Rectangle visible_rect;
text_view->get_visible_rect(visible_rect);
int visible_x, visible_y;
text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(), visible_rect.get_y(), visible_x, visible_y);
auto activation_rectangle_x = std::max(activation_rectangle.get_x(), visible_x);
int visible_window_x, visible_window_y;
text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(), visible_rect.get_y(), visible_window_x, visible_window_y);
text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x, activation_rectangle.get_y(), root_x, root_y);
auto window_x = std::max(activation_rectangle.get_x(), visible_window_x); // Adjust tooltip right if it is left of text_view
auto window_y = activation_rectangle.get_y();
text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y, root_x, root_y);
root_x -= 3; // -1xpadding
if(root_y < size.second)
root_x += visible_rect.get_width() * 0.1;
root_x += visible_rect.get_width() * 0.1; // Adjust tooltip right if it might be above cursor
rectangle.set_y(std::max(0, root_y - size.second)); // Move tooptip down if it is above screen
// Move tooltip left if it is right of screen
auto screen_width = Gdk::Screen::get_default()->get_width();
rectangle.set_x(root_x + size.first > screen_width ? screen_width - size.first : root_x);
}
rectangle.set_x(root_x);
rectangle.set_y(std::max(0, root_y - size.second));
rectangle.set_width(size.first);
rectangle.set_height(size.second);

18
src/window.cc

@ -769,10 +769,8 @@ void Window::set_menu_actions() {
debug_path = build->get_debug_path();
}
if(view) {
auto dialog_iter = view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
}
if(view)
SelectionDialog::create(view, true, true);
else
SelectionDialog::create(true, true);
@ -919,8 +917,7 @@ void Window::set_menu_actions() {
});
auto goto_selected_location = [](Source::View *view, const std::vector<Source::Offset> &locations) {
if(!locations.empty()) {
auto dialog_iter = view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
SelectionDialog::create(view, true, true);
std::vector<Source::Offset> rows;
auto project_path = Project::Build::create(view->file_path)->project_path;
if(project_path.empty()) {
@ -983,8 +980,7 @@ void Window::set_menu_actions() {
if(view->get_usages) {
auto usages = view->get_usages();
if(!usages.empty()) {
auto dialog_iter = view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
SelectionDialog::create(view, true, true);
std::vector<Source::Offset> rows;
auto iter = view->get_buffer()->get_insert()->get_iter();
@ -1031,8 +1027,7 @@ void Window::set_menu_actions() {
if(view->get_methods) {
auto methods = Notebook::get().get_current_view()->get_methods();
if(!methods.empty()) {
auto dialog_iter = view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
SelectionDialog::create(view, true, true);
std::vector<Source::Offset> rows;
auto iter = view->get_buffer()->get_insert()->get_iter();
for(auto &method : methods) {
@ -1336,8 +1331,7 @@ void Window::set_menu_actions() {
return;
}
auto dialog_iter = current_view->get_iter_for_dialog();
SelectionDialog::create(current_view, current_view->get_buffer()->create_mark(dialog_iter), true);
SelectionDialog::create(current_view, true);
std::vector<Source::Offset> rows;

Loading…
Cancel
Save