#pragma once #include "source_base.hpp" #include #include #include #include class SelectionDialogBase { class ListViewText : public Gtk::TreeView { class ColumnRecord : public Gtk::TreeModel::ColumnRecord { public: ColumnRecord() { add(text); add(index); } Gtk::TreeModelColumn text; Gtk::TreeModelColumn index; }; public: bool use_markup; ColumnRecord column_record; ListViewText(bool use_markup); void append(const std::string &value); void erase_rows(); void clear(); private: Glib::RefPtr list_store; Gtk::CellRendererText cell_renderer; unsigned int size = 0; }; class SearchEntry : public Gtk::SearchEntry { public: SearchEntry() : Gtk::SearchEntry() {} bool on_key_press_event(GdkEventKey *event) override { return Gtk::SearchEntry::on_key_press_event(event); }; }; public: SelectionDialogBase(Gtk::TextView *text_view, const boost::optional &start_iter, bool show_search_entry, bool use_markup); virtual ~SelectionDialogBase() {} void add_row(const std::string &row); void erase_rows(); void set_cursor_at_last_row(); void show(); void hide(); bool is_visible() { return window.is_visible(); } void get_position(int &root_x, int &root_y) { window.get_position(root_x, root_y); } std::function on_show; std::function on_hide; std::function index, const std::string &text)> on_change; std::function on_select; std::function on_search_entry_changed; Source::Mark start_mark; protected: void cursor_changed(); Gtk::TextView *text_view; Gtk::Window window; Gtk::Box vbox; Gtk::ScrolledWindow scrolled_window; ListViewText list_view_text; SearchEntry search_entry; bool show_search_entry; boost::optional last_index; }; class SelectionDialog : public SelectionDialogBase { SelectionDialog(Gtk::TextView *text_view, const boost::optional &start_iter, bool show_search_entry, bool use_markup); static std::unique_ptr instance; public: bool on_key_press(GdkEventKey *event); static void create(Gtk::TextView *text_view, bool show_search_entry = true, bool use_markup = false) { instance = std::unique_ptr(new SelectionDialog(text_view, 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(new SelectionDialog(nullptr, {}, show_search_entry, use_markup)); } static std::unique_ptr &get() { return instance; } }; class CompletionDialog : public SelectionDialogBase { CompletionDialog(Gtk::TextView *text_view, const Gtk::TextIter &start_iter); static std::unique_ptr instance; public: bool on_key_release(GdkEventKey *event); bool on_key_press(GdkEventKey *event); static void create(Gtk::TextView *text_view, const Gtk::TextIter &start_iter) { instance = std::unique_ptr(new CompletionDialog(text_view, start_iter)); } static std::unique_ptr &get() { return instance; } private: void select(bool hide_window = true); int show_offset; bool row_in_entry = false; };