1 #pragma once 2 #include "source.hpp" 3 #include <boost/optional.hpp> 4 #include <gtkmm.h> 5 #include <iostream> 6 #include <list> 7 #include <map> 8 #include <sigc++/sigc++.h> 9 #include <type_traits> 10 #include <vector> 11 12 class Notebook : public Gtk::Paned { 13 class TabLabel : public Gtk::EventBox { 14 public: 15 TabLabel(const std::function<void()> &on_close); 16 Gtk::Label label; 17 }; 18 19 class CursorLocation { 20 public: CursorLocation(Source::View * view,const Gtk::TextIter & iter)21 CursorLocation(Source::View *view, const Gtk::TextIter &iter) : view(view), mark(iter, false) {} 22 Source::View *view; 23 Source::Mark mark; 24 }; 25 26 Notebook(); 27 28 public: get()29 static Notebook &get() { 30 static Notebook instance; 31 return instance; 32 } 33 34 std::vector<Gtk::Notebook> notebooks; 35 36 size_t size(); 37 Source::View *get_view(size_t index); 38 Source::View *get_current_view(); 39 std::vector<Source::View *> &get_views(); 40 enum class Position { 41 left, 42 right, 43 infer, 44 split 45 }; 46 bool open(Source::View *view); 47 bool open(const boost::filesystem::path &file_path, Position position = Position::infer); 48 void install_rust(); 49 void open_uri(const std::string &uri); 50 void configure(size_t index); 51 bool save(size_t index); 52 bool save_current(); 53 bool close(size_t index); 54 bool close(Source::View *view); 55 bool close_current(); 56 void next(); 57 void previous(); 58 void toggle_split(); 59 std::vector<std::pair<size_t, Source::View *>> get_notebook_views(); 60 61 Gtk::Label status_location; 62 Gtk::Label status_file_path; 63 Gtk::Label status_branch; 64 Gtk::Label status_diagnostics; 65 Gtk::Label status_state; 66 void update_status(Source::BaseView *view); 67 void clear_status(); 68 69 std::function<void(Source::View *)> on_focus_page; 70 std::function<void(Source::View *)> on_change_page; 71 std::function<void(Source::View *)> on_close_page; 72 73 /// Cursor history 74 std::list<CursorLocation> cursor_locations; 75 std::list<CursorLocation>::iterator current_cursor_location = cursor_locations.end(); 76 bool disable_next_update_cursor_locations = false; 77 void delete_cursor_locations(Source::View *view); 78 79 private: 80 /// Throws on out of bounds arguments 81 Source::View *get_view(size_t notebook_index, int page); 82 void focus_view(Source::View *view); 83 /// Throws if view is not found 84 size_t get_index(Source::View *view); 85 /// Throws on out of bounds index 86 std::pair<size_t, int> get_notebook_page(size_t index); 87 /// Throws if view is not found 88 std::pair<size_t, int> get_notebook_page(Source::View *view); 89 90 std::vector<Source::View *> source_views; //Is NOT freed in destructor, this is intended for quick program exit. 91 std::vector<std::unique_ptr<Gtk::Widget>> source_maps; 92 std::vector<std::unique_ptr<Gtk::ScrolledWindow>> scrolled_windows; 93 std::vector<std::unique_ptr<Gtk::Box>> hboxes; 94 std::vector<std::unique_ptr<TabLabel>> tab_labels; 95 96 bool split = false; 97 boost::optional<size_t> last_index; 98 99 void set_current_view(Source::View *view); 100 Source::View *current_view = nullptr; 101 Source::View *intermediate_view = nullptr; 102 103 bool save_modified_dialog(size_t index); 104 }; 105