bunch of changes, unfortunate lack of commits
[ede] / explorer / src / ExplorerWindow.ec
index bdfe373..54a6a6a 100644 (file)
@@ -2,31 +2,66 @@ import "Explorer"
 import "IconBag"
 import "ToolBar"
 
+#ifdef _DEBUG
+   define title = "Ecere Explorer (Debug)";
+#else
+   define title = "Ecere Explorer";
+#endif
+
+/*
+define backgroundColor = Color { 30, 40, 50 }; //Color { 20, 20, 60 };
+define foregroundColor = lightGray; //white;
+define selectionColor = lightYellow;
+define selectionText = Color { 20, 30, 40 };
+define toolBarBackgroundColor = backgroundColor;//white; //Color { 240, 240, 250 };
+define toolBarForegroundColor = foregroundColor;//white; //Color { 240, 240, 250 };
+*/
+define backgroundColor = beige;//white; //Color { 128, 145, 175 }; //200, 224, 224 }; //lightGray;
+define foregroundColor = black;
+define selectionColor = app.currentSkin.selectionColor;
+define selectionText = app.currentSkin.selectionText;
+define toolBarBackgroundColor = backgroundColor;//white; //Color { 240, 240, 250 };
+define toolBarForegroundColor = foregroundColor;//white; //Color { 240, 240, 250 };
+
 enum ExplorerToolId
 {
    none,
    newWindow, goBack, goForward, goUp, goHome,
+   newFile, newFolder,
    browse,
    panelTree, panelSearch,
    addressBar,
    refresh,
-   viewList, viewDetails, viewIcons, viewCards, viewShowcase, viewCustom,
-   previewPictures
+   viewList, viewDetails, viewIcons, viewCards, viewShowcase, viewTree, viewCustom,
+   previewPictures,
+
+   searchInFileName,
+   inFileNameMatchCase,
+   inFileNameMatchWord,
+   searchInFileContent,
+   inFileContentMatchCase,
+   inFileContentMatchWord,
+   searchInSubDirs,
+   searchStart,
+   searchStop,
+
+   hasHeader
 };
 
 class ExplorerWindow : Window
 {
-   text = "Ecere Explorer";
-   background = activeBorder;
+   text = title;
+   background = backgroundColor;
    borderStyle = sizable;
    hasMaximize = true;
    hasMinimize = true;
    hasClose = true;
-   //hasMenuBar = true;
+   hasMenuBar = true;
    //tabCycle = true;
    size = { 840, 480 };
    minClientSize = { 600, 300 };
    nativeDecorations = true;
+   tabCycle = true;
 
    /*
    bool userMode;
@@ -36,12 +71,18 @@ class ExplorerWindow : Window
    int searchSplit;
    
    ExplorerToolId lastViewId;
+*/
+
+   bool treeInitialized;
+   int historyIndex;
+   Array<HistoryItem> history { };
+
 
    menu = Menu { };
    
    Menu fileMenu { menu, "File", f };
    Menu windowMenu { menu, "Window", w };
-      MenuItem newWindow
+      MenuItem itemNewWindow
       {
          windowMenu, "New Window", n;
          
@@ -51,7 +92,6 @@ class ExplorerWindow : Window
             return true;
          }
       };
-*/
 
    IconBag<ExplorerToolId> iconBag
    {
@@ -60,31 +100,45 @@ class ExplorerWindow : Window
       alphaBlend = true;
       iconNames =
       [
-         "<:ecere>emblems/unreadable.png",     /* none */
+         "<:ecere>emblems/unreadable.png",         /* none */
 
-         "<:ecere>actions/windowNew.png",            /* newWindow */
-         "<:ecere>actions/goPrevious.png",           /* goBack */
-         "<:ecere>actions/goNext.png",               /* goForward */
-         "<:ecere>actions/goUp.png",                 /* goUp */
-         "<:ecere>actions/goHome.png",               /* goHome */
+         "<:ecere>actions/windowNew.png",          /* newWindow */
+         "<:ecere>actions/goPrevious.png",         /* goBack */
+         "<:ecere>actions/goNext.png",             /* goForward */
+         "<:ecere>actions/goUp.png",               /* goUp */
+         "<:ecere>actions/goHome.png",             /* goHome */
+         "<:ecere>mimeTypes/file.png",             /* newFile */
+         "<:ecere>actions/folderNew.png",          /* newFolder */
 
-         ":browse.png",                                           /* browse */
+         ":browse.png",                            /* browse */
 
-         ":panel-tree.png",                                       /* panelTree */
-         "<:ecere>actions/editFind.png",             /* panelSearch */
+         ":panel-tree.png",                        /* panelTree */
+         "<:ecere>actions/editFind.png",           /* panelSearch */
 
-         "<:ecere>emblems/unreadable.png",     /* addressBar */
+         "",                                       /* addressBar */
 
-         "<:ecere>actions/viewRefresh.png",          /* refresh */
+         "<:ecere>actions/viewRefresh.png",        /* refresh */
 
-         ":view-list.png",                                        /* viewList */
-         ":view-details.png",                                     /* viewDetails */
-         ":view-icons.png",                                       /* viewIcons */
-         ":view-cards.png",                                       /* viewCards */
-         ":view-showcase-right.png",                              /* viewShowcase */
-         ":view-custom.png",                                      /* viewCustom */
+         ":view-list.png",                         /* viewList */
+         ":view-details.png",                      /* viewDetails */
+         ":view-icons.png",                        /* viewIcons */
+         ":view-cards.png",                        /* viewCards */
+         ":view-showcase-right.png",               /* viewShowcase */
+         ":panel-tree.png",                        /* viewTree */
+         ":view-custom.png",                       /* viewCustom */
          
-         "<:ecere>mimeTypes/image.png"     /* previewPictures */
+         "<:ecere>mimeTypes/image.png",            /* previewPictures */
+
+         "",                                       /* searchInFileName */
+         "<:ecere>emblems/unreadable.png",         /* inFileNameMatchCase */
+         "<:ecere>emblems/unreadable.png",         /* inFileNameMatchWord */
+         "",                                       /* searchInFileContent */
+         "<:ecere>emblems/unreadable.png",         /* inFileContentMatchCase */
+         "<:ecere>emblems/unreadable.png",         /* inFileContentMatchWord */
+         ":browse.png",                            /* searchInSubDirs */
+         "<:ecere>actions/editFind.png",           /* searchStart */
+         "<:ecere>emblems/unreadable.png",         /* searchStop */
+         "<:ecere>emblems/unreadable.png"          /* hasHeader */
       ];
    };
 
@@ -93,9 +147,10 @@ class ExplorerWindow : Window
       this;
       gap = 0;
       direction = vertical;
-      background = activeBorder;
-      //opacity = 1.0f;
-      
+      background = backgroundColor;
+      opacity = 0.0f;
+      tabCycle = true;
+
       anchor = { left = 0, top = 0, right = 0, bottom = 0 };
       //moveable = false;
    };
@@ -103,9 +158,13 @@ class ExplorerWindow : Window
    ToolBar/*<ExplorerToolId>*/ toolBar
    {
       stack, this;
-      iconBag = iconBag;
       size = { h = 32 };
       //moveable = false;
+      borderStyle = none;
+      background = toolBarBackgroundColor;
+      tabCycle = true;
+
+      iconBag = iconBag;
 
       void NotifyToolClick(ToolButton button)
       {
@@ -119,62 +178,141 @@ class ExplorerWindow : Window
                break;
             case goBack:
             case goForward:
+               historyIndex += id == goBack ? -1 : 1;
+               GoToHistoryIndex(false, false, false);
                break;
+            case goHome:
+            {
+               char * home = getenv("HOME");
+               if(home && home[0] && FileExists(home).isDirectory)
+                  GoTo(home, false, false);
+               break;
+            }
             case goUp:
             {
                char * path = view.path;
-               char * newPath = new char[strlen(path)];
+               char * newPath = new char[strlen(path)+1];
                StripLastDirectory(path, newPath);
-               view.path = newPath;
+               if(!newPath[0])
+               {
+                  newPath[0] = '/';
+                  newPath[1] = 0;
+               }
+               GoTo(newPath, false, false);
                delete newPath;
                break;
             }
+            case newFile:
+               if(CreateNewFileDialog { master = this, parent = parent, currentDirectory = view.path }.Modal() == ok )
+                  Refresh();
+               break;
+            case newFolder:
+               if(CreateDirectoryDialog { master = this, parent = parent, currentDirectory = view.path }.Modal() == ok )
+                  Refresh();
+               break;
             case panelTree:
-               // TODO TOFIX : need to fix Stacker for this to work
+               SearchStop();
+               //ToggleSearchMode(false);
                tree.visible = button.checked;
+               split.visible = button.checked;
+               if(button.checked)
+               {
+                  split.rightPane = view;
+                  view.anchor = { top = 0, bottom = 0, right = 0 };
+                  GoTo(addressBar.path, false, false);
+                  ReadyTree();
+               }
+               else
+               {
+                  split.rightPane = null;
+                  view.anchor = { left = 2, top = 0, bottom = 0, right = 0 };
+               }
                //search.visible = !button.checked;
                panels.size = { panels.size.w, panels.size.h }; // TOFIX : another Stacker fix needed
                break;
             case panelSearch:
-               // TODO TOFIX : need to fix Stacker for this to work
-               //search.visible = button.checked;
-               tree.visible = !button.checked;
-               panels.size = { panels.size.w, panels.size.h }; // TOFIX : another Stacker fix needed
+               ToggleSearchMode(button.checked);
+
+               //tree.visible = false; //!button.checked;
+               //split.visible = false; //!button.checked;
+               if(button.checked)
+               {
+                  /*split.rightPane = view;
+                  view.anchor = { top = 0, bottom = 0, right = 0 };*/
+                  //split.rightPane = null;
+                  //view.anchor = { left = 2, top = 0, bottom = 0, right = 0 };
+
+                  //SearchStart();
+                  searchInFileName.Activate();
+               }
+               else
+               {
+                  //split.rightPane = null;
+                  //view.anchor = { left = 2, top = 0, bottom = 0, right = 0 };
+
+                  GoTo(addressBar.path, false, false);
+               }
+               //panels.size = { panels.size.w, panels.size.h }; // TOFIX : another Stacker fix needed
                break;
             case refresh:
-               if(tree.visible)
-                  tree.Refresh();
-               view.Refresh();
+               Refresh();
                break;
             case previewPictures:
                view.previewPictures = button.checked;
                view.Refresh();
                break;
             case viewList:
+               view.details = false;
+               view.treeBranches = false;
+               view.Refresh();
+               break;
             case viewDetails:
+               view.details = true;
+               view.treeBranches = false;
+               view.Refresh();
+               break;
             case viewIcons:
             case viewCards:
-            case viewShowcase:
                //SwitchViews(toolId);
+               view.details = false;
+               view.treeBranches = false;
+               view.Refresh();
+               break;
+            case viewShowcase:
+               view.preview = button.checked;
+               view.Refresh();
+               break;
+            case viewTree:
+               view.treeBranches = button.checked;
+               view.Refresh();
+               break;
+            case hasHeader:
+               view.hasHeader ^= true;
                break;
          }
+         view.Activate();
       }
    };
 
-   Window s1 { toolBar, size = { w = 8 } };
-   ToolButton goBack { toolBar, this, id = ExplorerToolId::goBack };
-   Window s2 { toolBar, size = { w = 2 } };
-   ToolButton goForward { toolBar, this, id = ExplorerToolId::goForward };
-   Window s3 { toolBar, size = { w = 2 } };
-   ToolButton refresh { toolBar, this, id = ExplorerToolId::refresh };
-   Window s4 { toolBar, size = { w = 2 } };
-   ToolButton goHome { toolBar, this, id = ExplorerToolId::goHome };
-   Window s5 { toolBar, size = { w = 8 } };
+   Window { toolBar, size = { w = 8 }, inactive = true };
+   ToolButton goBack { toolBar, this, id = ExplorerToolId::goBack, hotKey = { left, alt = true }, disabled = true };
+   Window { toolBar, size = { w = 2 }, inactive = true };
+   ToolButton goForward { toolBar, this, id = ExplorerToolId::goForward, hotKey = { right, alt = true }, disabled = true };
+   Window { toolBar, size = { w = 2 }, inactive = true };
+   ToolButton refresh { toolBar, this, id = ExplorerToolId::refresh, hotKey = { r, ctrl = true } };
+   Window { toolBar, size = { w = 2 }, inactive = true };
+   ToolButton goHome { toolBar, this, id = ExplorerToolId::goHome, hotKey = { h, ctrl = true } };
+   Window { toolBar, size = { w = 8 }, inactive = true };
    PathBox addressBar
    {
       toolBar, this;
-      size = { 300, 23 }, id = ExplorerToolId::addressBar;
+      size = { 300, 22 }, id = ExplorerToolId::addressBar;
       typeExpected = directory;
+      borderStyle = deep;
+      background = toolBarBackgroundColor;
+      foreground = toolBarForegroundColor;
+      selectionColor = selectionColor;
+      selectionText = selectionText;
 
       bool OnKeyDown(Key key, unichar ch)
       {
@@ -188,32 +326,46 @@ class ExplorerWindow : Window
 
       bool NotifyModified(PathBox pathBox)
       {
-         view.path = pathBox.path;
+         GoTo(pathBox.path, false, false);
          return true;
       }
    };
    FlipStacker { toolBar, spring = previous };
-   Window s6 { toolBar, size = { w = 8 } };
-   ToolButton goUp { toolBar, this, id = ExplorerToolId::goUp };
-   Window s7 { toolBar, size = { w = 8 } };
-   GroupToggleToolButton selectedPanel;
-   GroupToggleToolButton panelTree   { toolBar, this, id = ExplorerToolId::panelTree, selected = &selectedPanel, checked = true };
-   GroupToggleToolButton panelSearch { toolBar, this, id = ExplorerToolId::panelSearch, selected = &selectedPanel };
-   selectedPanel = panelTree;
-   Window s8 { toolBar, size = { w = 8 } };
-   OptionToolButton selectedView;
+   Window { toolBar, size = { w = 8 }, inactive = true };
+   ToolButton newFile { toolBar, this, id = ExplorerToolId::newFile, hotKey = { n, ctrl = true } };
+   Window { toolBar, size = { w = 2 }, inactive = true };
+   ToolButton newFolder { toolBar, this, id = ExplorerToolId::newFolder, hotKey = { d, ctrl = true } };
+   Window { toolBar, size = { w = 8 }, inactive = true };
+   ToolButton goUp { toolBar, this, id = ExplorerToolId::goUp, hotKey = { up, alt = true } };
+   Window { toolBar, size = { w = 8 }, inactive = true };
+   //GroupToggleToolButton selectedPanel;
+   ToggleToolButton panelTree   { toolBar, this, id = ExplorerToolId::panelTree, hotKey = { t, ctrl = true }/*, selected = &selectedPanel*//*, checked = true*/ };
+   ToggleToolButton panelSearch { toolBar, this, id = ExplorerToolId::panelSearch, hotKey = { f, ctrl = true }/*, selected = &selectedPanel*/ };
+   //selectedPanel = panelTree;
+   Window { toolBar, size = { w = 8 }, inactive = true };
+   /*OptionToolButton selectedView;
    OptionToolButton viewList     { toolBar, this, id = ExplorerToolId::viewList, selected = &selectedView, checked = true };
    OptionToolButton viewDetails  { toolBar, this, id = ExplorerToolId::viewDetails, selected = &selectedView };
    OptionToolButton viewIcons    { toolBar, this, id = ExplorerToolId::viewIcons, selected = &selectedView };
    OptionToolButton viewTiles    { toolBar, this, id = ExplorerToolId::viewCards, selected = &selectedView };
    OptionToolButton viewShowcase { toolBar, this, id = ExplorerToolId::viewShowcase, selected = &selectedView };
-   selectedView = viewList;
-   Window s9 { toolBar, size = { w = 8 } };
+   OptionToolButton viewTree     { toolBar, this, id = ExplorerToolId::viewTree, selected = &selectedView };
+   selectedView = viewList;*/
+   //ToggleToolButton viewList     { toolBar, this, id = ExplorerToolId::viewList, checked = true };
+   ToggleToolButton viewDetails  { toolBar, this, id = ExplorerToolId::viewDetails };
+   //ToggleToolButton viewIcons    { toolBar, this, id = ExplorerToolId::viewIcons };
+   //ToggleToolButton viewTiles    { toolBar, this, id = ExplorerToolId::viewCards };
+   ToggleToolButton viewShowcase { toolBar, this, id = ExplorerToolId::viewShowcase };
+   ToggleToolButton viewTree     { toolBar, this, id = ExplorerToolId::viewTree };
+   Window { toolBar, size = { w = 8 }, inactive = true };
    ToggleToolButton previewPictures { toolBar, this, id = ExplorerToolId::previewPictures };
 
-   Window s10 { toolBar, size = { w = 8 } };
-   ToolButton newWindow { toolBar, this, id = ExplorerToolId::newWindow };
-   Window s11 { toolBar, size = { w = 8 } };
+   Window { toolBar, size = { w = 8 }, inactive = true };
+   ToolButton hasHeader { toolBar, this, id = ExplorerToolId::hasHeader };
+   Window { toolBar, size = { w = 8 }, inactive = true };
+   ToolButton newWindow { toolBar, this, id = ExplorerToolId::newWindow, hotKey = { w, ctrl = true } };
+   Window { toolBar, size = { w = 8 }, inactive = true };
+
 
    /*void OnDestroy()
    {
@@ -237,45 +389,459 @@ class ExplorerWindow : Window
       stack, this;
       gap = 0;
       direction = horizontal;
-      background = yellow;//activeBorder;
-      //opacity = 1.0f;
+      opacity = 0.0f;
+      tabCycle = true;
 
       anchor.left = 0;
-      anchor.bottom = 0;
+      //anchor.bottom = 0;
       anchor.right = 0;
+
+      //size = { h = 400 };
    };
 
-   //FlipStacker flipStack { stack, spring = previous };
+   FlipStacker flipStack { stack, spring = previous };
+
+   //Window searchSpace { stack, size = { h = 32 }, background = toolBarBackgroundColor, inactive = true, opacity = 0.0f };
+
+   ToolBar/*<ExplorerToolId>*/ searchBar
+   {
+      stack, this;
+      size = { h = 32 };
+      visible = false;
+      //moveable = false;
+      borderStyle = none;
+      background = toolBarBackgroundColor;
+      tabCycle = true;
+      iconBag = iconBag;
+
+      void NotifyToolClick(ToolButton button)
+      {
+         ExplorerToolId id = (ExplorerToolId)button.id;
+         switch(id)
+         {
+            case none:
+               break;
+            case searchStart:
+               SearchStart();
+               break;
+            case searchStop:
+               SearchStop();
+               break;
+         }
+         view.Activate();
+      }
+   };
+
+
+   Window { searchBar, size = { w = 8 }, inactive = true };
+   Label { searchBar, this, labeledWindow = searchInFileName};
+   Window { searchBar, size = { w = 2 }, inactive = true };
+   EditBox searchInFileName
+   {
+      searchBar, this;
+      size = { 200, 22 }, id = ExplorerToolId::searchInFileName;
+      borderStyle = deep;
+      background = toolBarBackgroundColor;
+      foreground = toolBarForegroundColor;
+      selectionColor = selectionColor;
+      selectionText = selectionText;
+      text = "File Name:";
+
+      bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
+      {
+         if((SmartKey)key == enter)
+            SearchStart();
+         return true;
+      }
+
+      /*bool NotifyActivate(Window window, bool active, Window previous)
+      {
+         if(active)
+         {
+            toolBar.focusHolder = window;
+         }
+         return true;
+      }*/
+   };
+   Window { searchBar, size = { w = 2 }, inactive = true };
+#ifndef __WIN32__
+   ToggleToolButton inFileNameMatchCase { searchBar, this, id = ExplorerToolId::inFileNameMatchCase };
+#endif
+   ToggleToolButton inFileNameMatchWord { searchBar, this, id = ExplorerToolId::inFileNameMatchWord };
+   Window { searchBar, size = { w = 8 }, inactive = true };
+   Label { searchBar, this, labeledWindow = searchInFileContent};
+   Window { searchBar, size = { w = 2 }, inactive = true };
+   EditBox searchInFileContent
+   {
+      searchBar, this;
+      size = { 200, 22 }, id = ExplorerToolId::searchInFileContent;
+      borderStyle = deep;
+      background = toolBarBackgroundColor;
+      foreground = toolBarForegroundColor;
+      selectionColor = selectionColor;
+      selectionText = selectionText;
+      text = "File Content:";
+
+      bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
+      {
+         if((SmartKey)key == enter)
+            SearchStart();
+         return true;
+      }
+
+      /*bool NotifyActivate(Window window, bool active, Window previous)
+      {
+         if(active)
+            toolBar.focusHolder = window;
+         return true;
+      }*/
+   };
+   FlipStacker { searchBar, spring = previous };
+   ToggleToolButton inFileContentMatchCase { searchBar, this, id = ExplorerToolId::inFileContentMatchCase };
+   ToggleToolButton inFileContentMatchWord { searchBar, this, id = ExplorerToolId::inFileContentMatchWord };
+   Window { searchBar, size = { w = 8 }, inactive = true };
+   ToggleToolButton searchInSubDirs { searchBar, this, id = ExplorerToolId::searchInSubDirs, checked = true };
+   Window { searchBar, size = { w = 8 }, inactive = true };
+   ToolButton searchStart { searchBar, this, id = ExplorerToolId::searchStart, hotKey = { s, ctrl = true } };
+   Window { searchBar, size = { w = 8 }, inactive = true };
+   ToolButton searchStop { searchBar, this, id = ExplorerToolId::searchStop, hotKey = { escape }, disabled = true; };
+   Window { searchBar, size = { w = 8 }, inactive = true };
+
+
+
+   //Window { searchBar, size = { h = 1 } };
 
    /*SearchPanel searchPanel
    {
       panels, this;
    };*/
 
-   /*Tree*/FileSystemBox tree
+   /*Window hack
+   {
+      panels, this;
+      anchor.top = 0;
+      anchor.bottom = 0;
+      anchor.right = 0;
+      borderStyle = none;
+      background = backgroundColor;
+   };*/
+
+   /*Tree*/FileSystemBox tree//;
    {
       panels, this;
       size = { w = 240 };
+      borderStyle = none;
+      background = backgroundColor;
+      foreground = foregroundColor;
+      selectionColor = selectionColor;
+      selectionText = selectionText;
+      visible = false;
       anchor.top = 0;
       anchor.bottom = 0;
-      navigateFolders = true;
+      //anchor = { left = 0, top = 0, bottom = 0 };
+
       treeBranches = true;
       foldersOnly = true;
-      borderStyle = none;
+      autoLoad = false;
+
+      bool NotifyNodeSelect(FileSystemBox box, FileSystemBoxSelection selection)
+      {
+         if(treeInitialized)
+         {
+            FileSystemNode node = selection.node;
+            if(node)
+            {
+               char p[MAX_LOCATION];
+               node.GetPath(p);
+               GoTo(node.path, false, true);
+            }
+         }
+         return true;
+      }
+
+      /*bool NotifyActivate(Window window, bool active, Window previous)
+      {
+         if(active)
+            toolBar.focusHolder = window;
+         return true;
+      }*/
+   };
+
+   PaneSplitter split
+   {
+      panels, this;
       visible = false;
+      leftPane = tree;//, rightPane = view;
+      split = 300;
    };
 
    FileSystemBox view
    {
       panels, this;
+      borderStyle = none;
+      background = backgroundColor;
+      foreground = foregroundColor;
+      selectionColor = selectionColor;
+      selectionText = selectionText;
       anchor.top = 0;
       anchor.bottom = 0;
       anchor.right = 0;
+      //anchor = { left = 2, top = 0, bottom = 0, right = 0 };
+
       locationBox = addressBar;
       navigateFolders = true;
-      borderStyle = none;
+      multiSelect = true;
+      autoLoad = false;
+
+      bool NotifyNodeOpen(FileSystemBox box, FileSystemBoxSelection selection)
+      {
+         FileSystemNode node = selection.node;
+         if(node)
+         {
+            if(node.type.isFile)
+            {
+               char path[MAX_LOCATION];
+            #ifndef __WIN32__
+               char command[MAX_LOCATION];
+               node.GetPath(path);
+               /*_FileType t = node.type;
+               if(t == ewsFile || t == epjFile ||
+                     t == ecFile || t == ehFile ||
+                     t == cppFile || t == hppFile ||
+                     t == cFile || t == hFile ||
+                     t == textFile || t == webFile)*/
+                  sprintf(command, "gnome-open \"%s\"", path);
+               /*else
+                  sprintf(command, "%s", path);*/
+               Execute(command);
+            #else
+               node.GetPath(path);
+               ShellOpen(path);
+            #endif
+            }
+            else if(node.type.isFolder)
+               GoTo(node.path, true, false);
+         }
+         UpdateHistoryItem(selection);
+         return true;
+      }
+
+      bool NotifyNodeSelect(FileSystemBox box, FileSystemBoxSelection selection)
+      {
+         UpdateHistoryItem(selection);
+         return true;
+      }
+
+      /*bool NotifyActivate(Window window, bool active, Window previous)
+      {
+         if(active)
+            toolBar.focusHolder = window;
+         return true;
+      }*/
+   };
+
+   FileSystemSearch searchThread
+   {
+      owner = this, fsb = view, tree = tree/*, searchPanel = this*/;
+
+      /*bool ExplorerWindow::NotifyUpdateSearchLocation(FileSystemSearch search, char * location)
+      {
+         char string[MAX_LOCATION + 2048];
+         sprintf(string, "%s (Searching %s)", title, location);
+         PrintLn(string); //view.results.text = string;
+         text = string;
+         return true;
+      }*/
+
+      bool ExplorerWindow::NotifySearchTerminated(FileSystemSearch search)
+      {
+         searchStop.disabled = true;
+         return true;
+      }
    };
 
+   void ToggleSearchMode(bool inSearch)
+   {
+      SearchStop();
+      //search.visible = inSearch;
+      //panelSearch.checked = inSearch; // <------ this is toggling panelSearch even though it shouldn't
+      //searchSpace.visible = !inSearch;
+      searchBar.visible = inSearch;
+      history[historyIndex].inSearch = inSearch;
+      size = { size.w, size.h };
+      view.pathColumn = inSearch;
+      /*if(inSearch)
+         searchThread.InitResults();*/
+      if(inSearch && /*(*/searchInFileName.contents[0]/* || searchInFileContents.contents[0])*/)
+         SearchStart();
+   }
+
+   void ReadyTree()
+   {
+      if(tree.visible)
+      {
+         if(!treeInitialized)
+         {
+            tree.path = "/"; // this should be available as a parameter
+            treeInitialized = true;
+         }
+         tree.SelectLocation(view.path);
+      }
+   }
+
+   void Refresh()
+   {
+      if(searchBar.visible)
+         SearchStart();
+      else
+      {
+         if(tree.visible)
+            tree.Refresh();
+         view.Refresh();
+      }
+   }
+
+   void GoTo(char * location, bool viewIsAtLocation, bool treeIsAtLocation)
+   {
+      HistoryItem item = null;
+      if(!history.count || fstrcmp(history[historyIndex].path, location))
+      {
+         int c;
+         for(c = 0; c < history.count; c++)
+            if(!fstrcmp(history[c].path, location))
+               break;
+         if(c == history.count)
+         {
+            item = { path = CopyString(location) };
+            if(history.count)
+            {
+               while(historyIndex < history.count-1)
+               {
+                  delete history[history.count-1].path;
+                  history.count--;
+               }
+            }
+            history.Add(item);
+            historyIndex = history.count-1;
+         }
+         else
+            historyIndex = c;
+      }
+      GoToHistoryIndex(viewIsAtLocation, treeIsAtLocation, item != null);
+   }
+
+   void GoToHistoryIndex(bool viewIsAtLocation, bool treeIsAtLocation, bool updateHistoryItem)
+   {
+      HistoryItem item = history[historyIndex];
+
+      goBack.disabled = historyIndex == 0;
+      goForward.disabled = historyIndex == history.count-1;
+      goUp.disabled = !fstrcmp(item.path, "/");
+
+      if(!viewIsAtLocation)
+      {
+         if(item.inSearch != panelSearch.checked)
+         {
+            ToggleSearchMode(item.inSearch);
+            if(item.inSearch)
+               SearchStart();
+         }
+         if(!item.inSearch)
+         /*{
+            //SearchStart();
+         }
+         else*/
+         {
+            view.path = item.path;
+            item.holdRecordingSelection = true;
+            view.SelectMultipleByPath(item.selection);
+         }
+      }
+      if(tree.visible && !treeIsAtLocation)
+         tree.SelectLocation(item.path);
+
+      if(updateHistoryItem)
+         UpdateHistoryItem(view.selection);
+   }
+
+   void UpdateHistoryItem(FileSystemBoxSelection selection)
+   {
+      HistoryItem item = history[historyIndex];
+
+      if(!item.holdRecordingSelection)
+      {
+         if(selection.node || (selection.nodes && selection.nodes.count))
+         {
+            item.selection.Free();
+            if(selection.nodes.count)
+            {
+               for(node : selection.nodes)
+                  item.selection.Add(CopyString(node.path));
+            }
+            else if(selection.node)
+               item.selection.Add(CopyString(selection.node.path));
+         }
+      }
+      else
+         item.holdRecordingSelection = false;
+   }
+
+   void SearchStart()
+   {
+      SearchStop();
+      searchThread.active = true;
+
+      searchThread.optionSubdirs = searchInSubDirs.checked == true;
+      searchThread.optionTree = view.treeBranches; //(options.subdirs.checked && options.tree.checked);
+      searchThread.optionBrowser = tree.visible; //(options.subdirs.checked && options.browser.checked);
+#ifndef __WIN32__
+      searchThread.optionNameMatchCase = inFileNameMatchCase.checked;
+#else
+      searchThread.optionNameMatchCase = false;
+#endif
+      searchThread.optionNameMatchWord = inFileNameMatchWord.checked;
+      searchThread.optionContentMatchCase = inFileContentMatchCase.checked;
+      searchThread.optionContentMatchWord = inFileContentMatchWord.checked;
+
+      strcpy(searchThread.location, view.path);
+      strcpy(searchThread.nameSearch, searchInFileName.contents);
+      strcpy(searchThread.contentSearch, searchInFileContent.contents);
+
+      //actions.startStop.text = "Stop Search";
+      //actions.clear.disabled = false;
+      //view.results.Clear();
+      //view.results.hasHeader = !searchThread.optionTree;
+      //view.results.treeBranches = searchThread.optionTree;
+      //view.browser.Clear();
+      //ToggleBrowserDisplay(searchThread.optionBrowser);
+
+      //view.browser.text = "Browser";
+      /*{
+         char string[MAX_LOCATION + 2048];
+         sprintf(string, "%s (Searching %s)", title, view.path);
+         //PrintLn(string); //view.results.text = string;
+         text = string;
+      }*/
+      searchThread.InitResults();
+      searchThread.Create();
+      searchStop.disabled = false;
+      //Update(null);
+   }
+
+   bool SearchStop()
+   {
+      if(searchThread.active)
+      {
+         searchThread.terminate = true;
+         //searchStop.disabled = true;
+         app.Unlock();
+            searchThread.Wait();
+         app.Lock();
+         return true;
+      }
+      return false;
+   }
+
    /*ExplorerSearch search
    {
       deep, this;
@@ -292,13 +858,6 @@ class ExplorerWindow : Window
       parent = deep, master = this;
       tabCycle = true;
       anchor = Anchor { top = 0, bottom = 0, right = 0 };
-   };
-
-   SplitWindow split
-   {
-      deep, this;
-      leftPane = tree, rightPane = viewHolder;
-      split = 300;
    };*/
 
    // Preview / Showcase
@@ -376,38 +935,9 @@ class ExplorerWindow : Window
       lastViewId = viewId;
    }*/
 
-   /*void GoToLocation(char * location)
-   {
-      int c;
-      char * temp;
-      char step[MAX_LOCATION];
-      
-      StringArray steps { growingFactor = 4 };
-      ExplorerFileBranch last = null;
-      
-      temp = CopyString(location);
-      while(strlen(temp))
-      {
-         GetLastDirectory(temp, step);
-         StripLastDirectory(temp, temp);
-         steps.Add(CopyString(step));
-      }
-      
-      for(c = steps._count - 1; c >= 0; c--)
-      {
-         last = tree.Find(steps._[c], last);
-         if(!last)
-            break;
-         tree.Select(last);
-      }
-      
-      delete temp;
-      delete steps;
-   }*/
-
    /*void SearchLocation(char * location)
    {
-      GoToLocation(location);
+      GoTo(location);
       search.location.editBox.contents = location;
    }*/
 
@@ -415,6 +945,13 @@ class ExplorerWindow : Window
    {
       //userMode = true;
       addressBar.path = view.path;
+      ReadyTree();
+      return true;
+   }
+
+   bool OnClose(bool parentClosing)
+   {
+      SearchStop();
       return true;
    }
 
@@ -449,3 +986,16 @@ class ExplorerWindow : Window
 }
 
 //class TreeFileSystemBox : FileSystemBox { }
+
+class HistoryItem
+{
+   char * path;
+   bool holdRecordingSelection;
+   bool inSearch;
+   Array<String> selection { };
+
+   ~HistoryItem()
+   {
+      delete path;
+   }
+}