diff --git a/texedit/gui/command_ids.hpp b/texedit/gui/command_ids.hpp index dd43b7e..9d75d1a 100644 --- a/texedit/gui/command_ids.hpp +++ b/texedit/gui/command_ids.hpp @@ -11,13 +11,15 @@ namespace te::gui::cmds { enum { - Menu_URLSourcePage = 101, + Menu_URLSourcePage = 501, Menu_URLFeatureRequest, Menu_URLBugReport, Menu_URLUserManual, Menu_PaneExplorer, Menu_PaneOutput, Menu_PanePreview, + Menu_OpenFolder, + Button_OpenFolder, }; } diff --git a/texedit/gui/layout/panes/editor_pane.cpp b/texedit/gui/layout/panes/editor_pane.cpp index 3af4284..088c416 100644 --- a/texedit/gui/layout/panes/editor_pane.cpp +++ b/texedit/gui/layout/panes/editor_pane.cpp @@ -8,7 +8,7 @@ #include "editor_pane.hpp" namespace te::gui { - EditorPane::EditorPane(wxWindow *parent) : PaneBase(parent) { + EditorPane::EditorPane(wxWindow *parent) : PaneBase{parent} { _stc = new wxStyledTextCtrl(this, wxID_ANY); _sizer = new wxBoxSizer(wxVERTICAL); diff --git a/texedit/gui/layout/panes/explorer_pane.cpp b/texedit/gui/layout/panes/explorer_pane.cpp index c4a59dd..4c988fd 100644 --- a/texedit/gui/layout/panes/explorer_pane.cpp +++ b/texedit/gui/layout/panes/explorer_pane.cpp @@ -7,12 +7,45 @@ #include "explorer_pane.hpp" +#include "gui/command_ids.hpp" + namespace te::gui { - ExplorerPane::ExplorerPane(wxWindow *parent) : PaneBase(parent) { - _dirctl = new wxGenericDirCtrl(this, wxID_ANY); + LocalDirCtrl::LocalDirCtrl(wxWindow *parent, const wxString &root, wxWindowID id) : _root{root} { + Init(); + Create(parent, id); + } + + void LocalDirCtrl::SetupSections() { + AddSection(_root, wxFileNameFromPath(_root), wxFileIconsTable::folder_open); + ExpandPath(_root); + } + + ExplorerPane::ExplorerPane(wxWindow *parent) : PaneBase(parent) { _sizer = new wxBoxSizer(wxVERTICAL); - _sizer->Add(_dirctl, 1, wxEXPAND); SetSizer(_sizer); + + AddEmptyTreeButton(); + } + + void ExplorerPane::ChangeRootDir(const wxString &path) { + _sizer->Clear(); + + // destroy and recreate the dirctrl + if (_dirctrl) { + _sizer->Detach(_dirctrl); + _dirctrl->Destroy(); + } + _dirctrl = new LocalDirCtrl(this, path, wxID_ANY); + _sizer->Add(_dirctrl, 1, wxEXPAND); + } + + void ExplorerPane::AddEmptyTreeButton() { + _sizer->Clear(); + + _empty_tree_btn = new wxButton(this, cmds::Button_OpenFolder, "Open a folder"); + _empty_tree_stretch_spacer[0] = _sizer->AddStretchSpacer(); + _sizer->Add(_empty_tree_btn, 0, wxALIGN_CENTER); + _empty_tree_stretch_spacer[1] = _sizer->AddStretchSpacer(); } } diff --git a/texedit/gui/layout/panes/explorer_pane.hpp b/texedit/gui/layout/panes/explorer_pane.hpp index f2f0432..63158ea 100644 --- a/texedit/gui/layout/panes/explorer_pane.hpp +++ b/texedit/gui/layout/panes/explorer_pane.hpp @@ -14,13 +14,32 @@ #include "pane_base.hpp" namespace te::gui { + // An implementation of wxGenericDirCtrl that is local to a specified directory, as opposed to listing the entire filesystem + class LocalDirCtrl : public wxGenericDirCtrl { + public: + LocalDirCtrl(wxWindow *parent, const wxString &root, wxWindowID id = wxID_ANY); + + void SetupSections() override; + + private: + wxString _root; + }; + class ExplorerPane : public PaneBase { public: ExplorerPane(wxWindow *parent); + inline LocalDirCtrl *GetDirCtrl() const { return _dirctrl; } + + void ChangeRootDir(const wxString &path); + private: + wxSizerItem *_empty_tree_stretch_spacer[2]; + wxButton *_empty_tree_btn; + void AddEmptyTreeButton(); + wxBoxSizer *_sizer; - wxGenericDirCtrl *_dirctl; + LocalDirCtrl *_dirctrl{nullptr}; }; } diff --git a/texedit/gui/layout/panes/output_pane.cpp b/texedit/gui/layout/panes/output_pane.cpp index e4d4141..eb6b9c1 100644 --- a/texedit/gui/layout/panes/output_pane.cpp +++ b/texedit/gui/layout/panes/output_pane.cpp @@ -8,7 +8,7 @@ #include "output_pane.hpp" namespace te::gui { - OutputPane::OutputPane(wxWindow *parent) : PaneBase(parent) { + OutputPane::OutputPane(wxWindow *parent) : PaneBase{parent} { _listbox = new wxListBox(this, wxID_ANY); _sizer = new wxBoxSizer(wxVERTICAL); diff --git a/texedit/gui/layout/panes/preview_pane.cpp b/texedit/gui/layout/panes/preview_pane.cpp index 69b8051..5b818c9 100644 --- a/texedit/gui/layout/panes/preview_pane.cpp +++ b/texedit/gui/layout/panes/preview_pane.cpp @@ -8,7 +8,7 @@ #include "preview_pane.hpp" namespace te::gui { - PreviewPane::PreviewPane(wxWindow *parent) : PaneBase(parent) { + PreviewPane::PreviewPane(wxWindow *parent) : PaneBase{parent} { wxString pdf; _webView = wxWebView::New(this, wxID_ANY); diff --git a/texedit/gui/main_frame.cpp b/texedit/gui/main_frame.cpp index cbbcf24..47f6381 100644 --- a/texedit/gui/main_frame.cpp +++ b/texedit/gui/main_frame.cpp @@ -7,6 +7,7 @@ #include "main_frame.hpp" +#include "layout/panes/explorer_pane.hpp" #include "layout/panes/output_pane.hpp" #include "layout/panes/preview_pane.hpp" #include "process/services/compiler_process.hpp" @@ -16,6 +17,7 @@ #include "prog_info.hpp" #include +#include #include namespace te::gui { @@ -43,6 +45,7 @@ namespace te::gui { wxMenuBar *menuBar = new wxMenuBar(); wxMenu *fileMenu = new wxMenu(); + fileMenu->Append(cmds::Menu_OpenFolder, "O&pen Folder..."); fileMenu->Append(wxID_EXIT, "&Quit"); menuBar->Append(fileMenu, "&File"); @@ -65,6 +68,12 @@ namespace te::gui { SetMenuBar(menuBar); } + void MainFrame::ShowURL(const wxString &url) { + if (!wxLaunchDefaultBrowser(url)) { + wxLogError("Failed to open URL \"%s\"", url); + } + } + void MainFrame::OnIdle(wxIdleEvent &ev) { wxString sc = _compiler_proc->ReadLineStdout(); if (!sc.IsEmpty()) { @@ -77,10 +86,20 @@ namespace te::gui { } } - void MainFrame::ShowURL(const wxString &url) { - if (!wxLaunchDefaultBrowser(url)) { - wxLogError("Failed to open URL \"%s\"", url); + void MainFrame::OnDirCtrlFileActivated(wxTreeEvent &event) { + wxGenericDirCtrl dirctrl = _layout.GetExplorerPane()->GetDirCtrl(); + + wxLogMessage("%s", dirctrl.GetPath(event.GetItem())); + } + + void MainFrame::OnButtonOpenFolder(wxCommandEvent &event) { + wxDirDialog dlg(this, "Choose a workspace directory", "", wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); + + if (dlg.ShowModal() == wxID_CANCEL) { + return; } + + _layout.GetExplorerPane()->ChangeRootDir(dlg.GetPath()); } void MainFrame::OnMenuAbout(wxCommandEvent &event) { @@ -120,6 +139,11 @@ namespace te::gui { wxBEGIN_EVENT_TABLE(MainFrame, wxFrame) EVT_IDLE(MainFrame::OnIdle) + + EVT_DIRCTRL_FILEACTIVATED(wxID_ANY, MainFrame::OnDirCtrlFileActivated) + EVT_BUTTON(cmds::Button_OpenFolder, MainFrame::OnButtonOpenFolder) + EVT_MENU(cmds::Menu_OpenFolder, MainFrame::OnButtonOpenFolder) + EVT_MENU(wxID_EXIT, MainFrame::OnMenuQuit) EVT_MENU(wxID_ABOUT, MainFrame::OnMenuAbout) EVT_MENU(cmds::Menu_URLSourcePage, MainFrame::OnMenuURLSourcePage) diff --git a/texedit/gui/main_frame.hpp b/texedit/gui/main_frame.hpp index 69c8bfe..18d3b8c 100644 --- a/texedit/gui/main_frame.hpp +++ b/texedit/gui/main_frame.hpp @@ -10,6 +10,7 @@ #define __texedit__root_frame_hpp__ #include +#include #include "process/process_manager.hpp" #include "process/services/compiler_process.hpp" @@ -33,10 +34,12 @@ namespace te::gui { void BuildMenuBar(); - void OnIdle(wxIdleEvent &ev); - void ShowURL(const wxString &url); + void OnIdle(wxIdleEvent &ev); + void OnDirCtrlFileActivated(wxTreeEvent &event); + void OnButtonOpenFolder(wxCommandEvent &event); + void OnMenuAbout(wxCommandEvent &event); void OnMenuQuit(wxCommandEvent &event); void OnMenuURLSourcePage(wxCommandEvent &event); diff --git a/texedit/util/resources.cpp b/texedit/util/resources.cpp index a31a58d..7354304 100644 --- a/texedit/util/resources.cpp +++ b/texedit/util/resources.cpp @@ -8,6 +8,7 @@ #include "resources.hpp" #include +#include #include namespace te::util { @@ -16,7 +17,7 @@ namespace te::util { return f.GetPath(); } - wxString RelToExec(std::vector dirs, wxString filename) { + wxString RelToExec(const std::vector &dirs, const wxString &filename) { wxFileName f = wxFileName::DirName(GetTexeditDir()); for (auto d : dirs) { f.AppendDir(d); @@ -27,11 +28,11 @@ namespace te::util { filename; } - wxString RelToExec(wxString filename) { + wxString RelToExec(const wxString &filename) { return RelToExec({}, filename); } - bool ValidateExecutable(wxString path) { + bool ValidateExecutable(const wxString &path) { wxFileName f{path}; return f.FileExists() && f.IsFileExecutable(); } diff --git a/texedit/util/resources.hpp b/texedit/util/resources.hpp index b02ab9f..44ddd13 100644 --- a/texedit/util/resources.hpp +++ b/texedit/util/resources.hpp @@ -15,10 +15,10 @@ namespace te::util { wxString GetTexeditDir(); - wxString RelToExec(std::vector dirs, wxString filename); - wxString RelToExec(wxString filename); + wxString RelToExec(const std::vector &dirs, const wxString &filename); + wxString RelToExec(const wxString &filename); - bool ValidateExecutable(wxString path); + bool ValidateExecutable(const wxString &path); } #endif