Fixed major issues
[ede] / explorer / src / ExplorerWindow.ec
index 54a6a6a..eb690c3 100644 (file)
@@ -1,6 +1,7 @@
 import "Explorer"
-import "IconBag"
-import "ToolBar"
+//import "IconBag"
+//import "ToolBar"
+import "SearchBox"
 
 #ifdef _DEBUG
    define title = "Ecere Explorer (Debug)";
@@ -16,11 +17,13 @@ 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 backgroundColor = Color { 155, 170, 160 };
+//define backgroundColor = Color { 250, 250, 255 };
+//define backgroundColor = beige;//white; //Color { 128, 145, 175 }; //200, 224, 224 }; //lightGray;
+define foregroundColor = Color { 45, 45, 45 };//black;
+define selectionColor = Color { 80, 140, 110 };//app.currentSkin.selectionColor;
+define selectionText = black;//app.currentSkin.selectionText;
+define toolBarBackgroundColor = Color { 170, 187, 176 }; //backgroundColor;//white; //Color { 240, 240, 250 };
 define toolBarForegroundColor = foregroundColor;//white; //Color { 240, 240, 250 };
 
 enum ExplorerToolId
@@ -48,6 +51,85 @@ enum ExplorerToolId
    hasHeader
 };
 
+enum Icon
+{
+   missing,
+   newWindow, goBack, goForward, goUp, goHome, newFile, newFolder,
+   browse,
+   panelTree, panelSearch,
+   addressBar,
+   refresh,
+   viewList, viewDetails, viewIcons, viewCards, viewShowcase, viewTree, viewCustom,
+   previewPictures,
+   searchInFileName, inFileNameMatchCase, inFileNameMatchWord,
+   searchInFileContent, inFileContentMatchCase, inFileContentMatchWord,
+   searchInSubDirs, searchStart, searchStop,
+   hasHeader
+};
+static const char * iconNames[Icon::enumSize] =
+{
+   "<:ecere>emblems/unreadable.png",         /* missing */
+
+   "<: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 */
+
+   ":panel-tree.png",                        /* panelTree */
+   "<:ecere>actions/editFind.png",           /* panelSearch */
+
+   "",                                       /* addressBar */
+
+   "<: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 */
+   ":panel-tree.png",                        /* viewTree */
+   ":view-custom.png",                       /* viewCustom */
+
+   "<: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 */
+};
+
+class IconToolButton : ToolButton
+{
+   //inactive = true;
+   //bitmapAlignment = left;
+
+   property Icon icon
+   {
+      set
+      {
+         bitmap = BitmapResource { fileName = iconNames[value], alphaBlend = true };
+         //id = value;
+      }
+   }
+}
+
+class ToggleIconToolButton : IconToolButton
+{
+   toggle = true;
+}
+
+
 class ExplorerWindow : Window
 {
    text = title;
@@ -62,6 +144,7 @@ class ExplorerWindow : Window
    minClientSize = { 600, 300 };
    nativeDecorations = true;
    tabCycle = true;
+   icon = { ":explorerIcon.png" };
 
    /*
    bool userMode;
@@ -69,7 +152,7 @@ class ExplorerWindow : Window
 
    int treeSplit;
    int searchSplit;
-   
+
    ExplorerToolId lastViewId;
 */
 
@@ -79,20 +162,23 @@ class ExplorerWindow : Window
 
 
    menu = Menu { };
-   
+
    Menu fileMenu { menu, "File", f };
    Menu windowMenu { menu, "Window", w };
-      MenuItem itemNewWindow
-      {
-         windowMenu, "New Window", n;
-         
-         bool NotifySelect(MenuItem selection, Modifiers mods)
-         {
-            ExplorerWindow { }.Create();
-            return true;
-         }
-      };
+      MenuItem itemNewWindow { windowMenu, "New Window", n, NotifySelect = NewWindow_NotifySelect };
 
+   bool NewWindow_NotifySelect(MenuItem selection, Modifiers mods)
+   {
+      //ExplorerWindow { }.Create();
+      ExplorerWindow w { };//.Create();
+      w.location = location;
+      w.view.autoLoad = true;
+      w.Create();
+      w.Activate(); // tocheck: not working?
+      return true;
+   }
+
+#if 0
    IconBag<ExplorerToolId> iconBag
    {
       //window = guiApp.desktop;
@@ -100,47 +186,9 @@ class ExplorerWindow : Window
       alphaBlend = true;
       iconNames =
       [
-         "<: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>mimeTypes/file.png",             /* newFile */
-         "<:ecere>actions/folderNew.png",          /* newFolder */
-
-         ":browse.png",                            /* browse */
-
-         ":panel-tree.png",                        /* panelTree */
-         "<:ecere>actions/editFind.png",           /* panelSearch */
-
-         "",                                       /* addressBar */
-
-         "<: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 */
-         ":panel-tree.png",                        /* viewTree */
-         ":view-custom.png",                       /* viewCustom */
-         
-         "<: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 */
       ];
    };
+#endif
 
    Stacker stack
    {
@@ -151,6 +199,9 @@ class ExplorerWindow : Window
       opacity = 0.0f;
       tabCycle = true;
 
+      flipper = panels;
+      flipSpring = true;
+
       anchor = { left = 0, top = 0, right = 0, bottom = 0 };
       //moveable = false;
    };
@@ -164,28 +215,37 @@ class ExplorerWindow : Window
       background = toolBarBackgroundColor;
       tabCycle = true;
 
-      iconBag = iconBag;
+      //iconBag = iconBag;
+      inactive = false;
 
-      void NotifyToolClick(ToolButton button)
+      flipper = addressBar;
+      flipSpring = true;
+
+#if 0
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
+         bool noViewActivation = false;
          ExplorerToolId id = (ExplorerToolId)button.id;
          switch(id)
          {
             case none:
                break;
             case newWindow:
-               ExplorerWindow { }.Create();
+            {
+               noViewActivation = true;
+               NewWindow_NotifySelect(null, 0);
                break;
+            }
             case goBack:
             case goForward:
                historyIndex += id == goBack ? -1 : 1;
-               GoToHistoryIndex(false, false, false);
+               GoToHistoryIndex(/*false, false, */false);
                break;
             case goHome:
             {
                char * home = getenv("HOME");
                if(home && home[0] && FileExists(home).isDirectory)
-                  GoTo(home, false, false);
+                  location = home;//GoTo(home, false, false);
                break;
             }
             case goUp:
@@ -198,17 +258,15 @@ class ExplorerWindow : Window
                   newPath[0] = '/';
                   newPath[1] = 0;
                }
-               GoTo(newPath, false, false);
+               location = newPath;//GoTo(newPath, false, false);
                delete newPath;
                break;
             }
             case newFile:
-               if(CreateNewFileDialog { master = this, parent = parent, currentDirectory = view.path }.Modal() == ok )
-                  Refresh();
+               NewFile(view, null, 0);
                break;
             case newFolder:
-               if(CreateDirectoryDialog { master = this, parent = parent, currentDirectory = view.path }.Modal() == ok )
-                  Refresh();
+               NewFolder(view, null, 0);
                break;
             case panelTree:
                SearchStop();
@@ -219,7 +277,7 @@ class ExplorerWindow : Window
                {
                   split.rightPane = view;
                   view.anchor = { top = 0, bottom = 0, right = 0 };
-                  GoTo(addressBar.path, false, false);
+                  location = addressBar.path;//GoTo(addressBar.path, false, false);
                   ReadyTree();
                }
                else
@@ -228,7 +286,6 @@ class ExplorerWindow : Window
                   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:
                ToggleSearchMode(button.checked);
@@ -250,9 +307,8 @@ class ExplorerWindow : Window
                   //split.rightPane = null;
                   //view.anchor = { left = 2, top = 0, bottom = 0, right = 0 };
 
-                  GoTo(addressBar.path, false, false);
+                  location = addressBar.path;//GoTo(addressBar.path, false, false);
                }
-               //panels.size = { panels.size.w, panels.size.h }; // TOFIX : another Stacker fix needed
                break;
             case refresh:
                Refresh();
@@ -290,29 +346,65 @@ class ExplorerWindow : Window
                view.hasHeader ^= true;
                break;
          }
-         view.Activate();
+         if(!noViewActivation)
+            view.Activate();
+         return true;
       }
+#endif
    };
 
    Window { toolBar, size = { w = 8 }, inactive = true };
-   ToolButton goBack { toolBar, this, id = ExplorerToolId::goBack, hotKey = { left, alt = true }, disabled = true };
+   IconToolButton goBack { toolBar, this, icon = goBack, hotKey = { left, alt = true }, toolTip = "Back", disabled = true;
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         historyIndex += -1;
+         GoToHistoryIndex(/*false, false, */false);
+         view.Activate();
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 2 }, inactive = true };
-   ToolButton goForward { toolBar, this, id = ExplorerToolId::goForward, hotKey = { right, alt = true }, disabled = true };
+   IconToolButton goForward { toolBar, this, icon = goForward, hotKey = { right, alt = true }, toolTip = "Forward", disabled = true;
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         historyIndex += 1;
+         GoToHistoryIndex(/*false, false, */false);
+         view.Activate();
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 2 }, inactive = true };
-   ToolButton refresh { toolBar, this, id = ExplorerToolId::refresh, hotKey = { r, ctrl = true } };
+   IconToolButton refresh { toolBar, this, icon = refresh, hotKey = { r, ctrl = true }, toolTip = "Refresh";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         Refresh();
+         view.Activate();
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 2 }, inactive = true };
-   ToolButton goHome { toolBar, this, id = ExplorerToolId::goHome, hotKey = { h, ctrl = true } };
+   IconToolButton goHome { toolBar, this, icon = goHome, hotKey = { h, ctrl = true }, toolTip = "Go Home";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         char * home = getenv("HOME");
+         if(home && home[0] && FileExists(home).isDirectory)
+            location = home;//GoTo(home, false, false);
+         view.Activate();
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 8 }, inactive = true };
    PathBox addressBar
    {
       toolBar, this;
-      size = { 300, 22 }, id = ExplorerToolId::addressBar;
+      size = { 300, 22 };//, icon = addressBar;
       typeExpected = directory;
       borderStyle = deep;
       background = toolBarBackgroundColor;
       foreground = toolBarForegroundColor;
       selectionColor = selectionColor;
       selectionText = selectionText;
+      toolTip = "Location";
 
       bool OnKeyDown(Key key, unichar ch)
       {
@@ -326,47 +418,185 @@ class ExplorerWindow : Window
 
       bool NotifyModified(PathBox pathBox)
       {
-         GoTo(pathBox.path, false, false);
+         location = pathBox.path;//GoTo(pathBox.path, false, false);
          return true;
       }
    };
-   FlipStacker { toolBar, spring = previous };
+   //FlipStacker { toolBar, spring = previous };
    Window { toolBar, size = { w = 8 }, inactive = true };
-   ToolButton newFile { toolBar, this, id = ExplorerToolId::newFile, hotKey = { n, ctrl = true } };
+   IconToolButton newFile { toolBar, this, icon = newFile, hotKey = { l, ctrl = true }, toolTip = "Create New File";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         NewFile(view, null, 0);
+         view.Activate();
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 2 }, inactive = true };
-   ToolButton newFolder { toolBar, this, id = ExplorerToolId::newFolder, hotKey = { d, ctrl = true } };
+   IconToolButton newFolder { toolBar, this, icon = newFolder, hotKey = { d, ctrl = true }, toolTip = "Create New Folder";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         NewFolder(view, null, 0);
+         view.Activate();
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 8 }, inactive = true };
-   ToolButton goUp { toolBar, this, id = ExplorerToolId::goUp, hotKey = { up, alt = true } };
+   IconToolButton goUp { toolBar, this, icon = goUp, hotKey = { up, alt = true }, toolTip = "Go to Parent Folder";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         const char * path = view.path;
+         char * newPath = new char[strlen(path)+1];
+         StripLastDirectory(path, newPath);
+         if(!newPath[0])
+         {
+            newPath[0] = '/';
+            newPath[1] = 0;
+         }
+         location = newPath;//GoTo(newPath, false, false);
+         delete newPath;
+         view.Activate();
+         return 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*/ };
+   //GroupToggleIconToolButton selectedPanel;
+   ToggleIconToolButton panelTree   { toolBar, this, icon = panelTree/*, selected = &selectedPanel*//*, checked = true*/, toolTip = "Toggle Tree Panel";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         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 };
+            location = addressBar.path;//GoTo(addressBar.path, false, false);
+            ReadyTree();
+         }
+         else
+         {
+            split.rightPane = null;
+            view.anchor = { left = 2, top = 0, bottom = 0, right = 0 };
+         }
+         //search.visible = !button.checked;
+         view.Activate();
+         return true;
+      }
+   };
+   ToggleIconToolButton panelSearch { toolBar, this, icon = panelSearch, hotKey = { f, ctrl = true }/*, selected = &selectedPanel*/, toolTip = "Toggle Search";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         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 };
+
+            location = addressBar.path;//GoTo(addressBar.path, false, false);
+         }
+         view.Activate();
+         return true;
+      }
+   };
    //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 };
-   OptionToolButton viewTree     { toolBar, this, id = ExplorerToolId::viewTree, selected = &selectedView };
+   /*OptionIconToolButton selectedView;
+   OptionIconToolButton viewList     { toolBar, this, icon = viewList, selected = &selectedView, checked = true };
+   OptionIconToolButton viewDetails  { toolBar, this, icon = viewDetails, selected = &selectedView };
+   OptionIconToolButton viewIcons    { toolBar, this, icon = viewIcons, selected = &selectedView };
+   OptionIconToolButton viewTiles    { toolBar, this, icon = viewCards, selected = &selectedView };
+   OptionIconToolButton viewShowcase { toolBar, this, icon = viewShowcase, selected = &selectedView };
+   OptionIconToolButton viewTree     { toolBar, this, icon = 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 };
+   //ToggleIconToolButton viewList     { toolBar, this, icon = viewList, checked = true };
+      /*case viewList:
+         view.details = false;
+         view.treeBranches = false;
+         view.Refresh();
+         break;*/
+   ToggleIconToolButton viewDetails  { toolBar, this, icon = viewDetails, toolTip = "Toggle Listing Details";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         view.details = button.checked;
+         view.treeBranches = false;
+         view.Refresh();
+         view.Activate();
+         return true;
+      }
+   };
+      /*case viewCards:
+         //SwitchViews(toolId);
+         view.details = false;
+         view.treeBranches = false;
+         view.Refresh();
+         break;*/
+   //ToggleIconToolButton viewIcons    { toolBar, this, icon = viewIcons };
+   //ToggleIconToolButton viewTiles    { toolBar, this, icon = viewCards };
+   ToggleIconToolButton viewShowcase { toolBar, this, icon = viewShowcase, toolTip = "Toggle Showcase";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         view.preview = button.checked;
+         view.Refresh();
+         view.Activate();
+         return true;
+      }
+   };
+   ToggleIconToolButton viewTree     { toolBar, this, icon = viewTree, hotKey = { t, ctrl = true }, toolTip = "Toggle Tree Listing";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         view.treeBranches = button.checked;
+         view.Refresh();
+         view.Activate();
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 8 }, inactive = true };
-   ToggleToolButton previewPictures { toolBar, this, id = ExplorerToolId::previewPictures };
+   ToggleIconToolButton previewPictures { toolBar, this, icon = previewPictures, toolTip = "Toggle Picture Preview";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         view.previewPictures = button.checked;
+         view.Refresh();
+         view.Activate();
+         return true;
+      }
+   };
 
    Window { toolBar, size = { w = 8 }, inactive = true };
-   ToolButton hasHeader { toolBar, this, id = ExplorerToolId::hasHeader };
+   ToggleIconToolButton hasHeader { toolBar, this, icon = hasHeader, toolTip = "Toggle Listing Header";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         view.hasHeader ^= true;
+         view.Activate();
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 8 }, inactive = true };
-   ToolButton newWindow { toolBar, this, id = ExplorerToolId::newWindow, hotKey = { w, ctrl = true } };
+   IconToolButton newWindow { toolBar, this, icon = newWindow, hotKey = { w, ctrl = true }, toolTip = "Open New Window";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         NewWindow_NotifySelect(null, 0);
+         return true;
+      }
+   };
    Window { toolBar, size = { w = 8 }, inactive = true };
 
 
+#if 0
    /*void OnDestroy()
    {
       iconBag.window = null;
@@ -383,6 +613,7 @@ class ExplorerWindow : Window
    {
       iconBag.Unload();
    }
+#endif
 
    Stacker panels
    {
@@ -399,7 +630,7 @@ class ExplorerWindow : Window
       //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 };
 
@@ -412,9 +643,14 @@ class ExplorerWindow : Window
       borderStyle = none;
       background = toolBarBackgroundColor;
       tabCycle = true;
-      iconBag = iconBag;
+      //iconBag = iconBag;
+      inactive = false;
 
-      void NotifyToolClick(ToolButton button)
+      flipper = searchInFileContent;
+      flipSpring = true;
+
+#if 0
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
          ExplorerToolId id = (ExplorerToolId)button.id;
          switch(id)
@@ -429,23 +665,26 @@ class ExplorerWindow : Window
                break;
          }
          view.Activate();
+         return true;
       }
+#endif
    };
 
-
    Window { searchBar, size = { w = 8 }, inactive = true };
-   Label { searchBar, this, labeledWindow = searchInFileName};
-   Window { searchBar, size = { w = 2 }, inactive = true };
-   EditBox searchInFileName
+   //Label { searchBar, this, labeledWindow = searchInFileName};
+   //Window { searchBar, size = { w = 2 }, inactive = true };
+   SearchBox searchInFileName
    {
       searchBar, this;
-      size = { 200, 22 }, id = ExplorerToolId::searchInFileName;
+      size = { 200, 22 };//, icon = searchInFileName;
       borderStyle = deep;
       background = toolBarBackgroundColor;
       foreground = toolBarForegroundColor;
       selectionColor = selectionColor;
       selectionText = selectionText;
-      text = "File Name:";
+      //text = "File Name:";
+      caption = "Search File Names";
+      toolTip = "Search File Names";
 
       bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
       {
@@ -465,22 +704,34 @@ class ExplorerWindow : Window
    };
    Window { searchBar, size = { w = 2 }, inactive = true };
 #ifndef __WIN32__
-   ToggleToolButton inFileNameMatchCase { searchBar, this, id = ExplorerToolId::inFileNameMatchCase };
+   ToggleIconToolButton inFileNameMatchCase { searchBar, this, icon = inFileNameMatchCase, toolTip = "Toggle Match Case";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         return true;
+      }
+   };
 #endif
-   ToggleToolButton inFileNameMatchWord { searchBar, this, id = ExplorerToolId::inFileNameMatchWord };
+   ToggleIconToolButton inFileNameMatchWord { searchBar, this, icon = inFileNameMatchWord, toolTip = "Toggle Match Whole Word";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         return true;
+      }
+   };
    Window { searchBar, size = { w = 8 }, inactive = true };
-   Label { searchBar, this, labeledWindow = searchInFileContent};
-   Window { searchBar, size = { w = 2 }, inactive = true };
-   EditBox searchInFileContent
+   //Label { searchBar, this, labeledWindow = searchInFileContent};
+   //Window { searchBar, size = { w = 2 }, inactive = true };
+   SearchBox searchInFileContent
    {
       searchBar, this;
-      size = { 200, 22 }, id = ExplorerToolId::searchInFileContent;
+      size = { 200, 22 };//, icon = searchInFileContent;
       borderStyle = deep;
       background = toolBarBackgroundColor;
       foreground = toolBarForegroundColor;
       selectionColor = selectionColor;
       selectionText = selectionText;
-      text = "File Content:";
+      //text = "File Content:";
+      caption = "Search File Contents";
+      toolTip = "Search File Contents";
 
       bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
       {
@@ -496,15 +747,44 @@ class ExplorerWindow : Window
          return true;
       }*/
    };
-   FlipStacker { searchBar, spring = previous };
-   ToggleToolButton inFileContentMatchCase { searchBar, this, id = ExplorerToolId::inFileContentMatchCase };
-   ToggleToolButton inFileContentMatchWord { searchBar, this, id = ExplorerToolId::inFileContentMatchWord };
+   //FlipStacker { searchBar, spring = previous };
+   ToggleIconToolButton inFileContentMatchCase { searchBar, this, icon = inFileContentMatchCase, toolTip = "Toggle Match Case";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         return true;
+      }
+   };
+   ToggleIconToolButton inFileContentMatchWord { searchBar, this, icon = inFileContentMatchWord, toolTip = "Toggle Match Whole Word";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         return true;
+      }
+   };
    Window { searchBar, size = { w = 8 }, inactive = true };
-   ToggleToolButton searchInSubDirs { searchBar, this, id = ExplorerToolId::searchInSubDirs, checked = true };
+   ToggleIconToolButton searchInSubDirs { searchBar, this, icon = searchInSubDirs, checked = true, toolTip = "Toggle Include Subfolders";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         return true;
+      }
+   };
    Window { searchBar, size = { w = 8 }, inactive = true };
-   ToolButton searchStart { searchBar, this, id = ExplorerToolId::searchStart, hotKey = { s, ctrl = true } };
+   IconToolButton searchStart { searchBar, this, icon = searchStart, hotKey = { s, ctrl = true }, toolTip = "Start Search";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         SearchStart();
+         view.Activate();
+         return true;
+      }
+   };
    Window { searchBar, size = { w = 8 }, inactive = true };
-   ToolButton searchStop { searchBar, this, id = ExplorerToolId::searchStop, hotKey = { escape }, disabled = true; };
+   IconToolButton searchStop { searchBar, this, icon = searchStop, hotKey = { escape }, disabled = true, toolTip = "Stop Search";
+      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+      {
+         SearchStop();
+         view.Activate();
+         return true;
+      }
+   };
    Window { searchBar, size = { w = 8 }, inactive = true };
 
 
@@ -553,7 +833,7 @@ class ExplorerWindow : Window
             {
                char p[MAX_LOCATION];
                node.GetPath(p);
-               GoTo(node.path, false, true);
+               location = node.path;//GoTo(node.path, false, true);
             }
          }
          return true;
@@ -575,6 +855,7 @@ class ExplorerWindow : Window
       split = 300;
    };
 
+   //FileSystemCache testCache;
    FileSystemBox view
    {
       panels, this;
@@ -593,6 +874,16 @@ class ExplorerWindow : Window
       multiSelect = true;
       autoLoad = false;
 
+      //iteratorClass = class(FileSystemCacheIterator);
+      //iteratorClass = class(FileSystemIterator);
+
+      bool NotifyIteratorInit(FileSystemBox box, FileSystemIterator fileSystemIterator)
+      {
+         //((FileSystemCacheIterator)fileSystemIterator).cache = testCache;
+         //((FileSystemIterator)fileSystemIterator)
+         return true;
+      }
+
       bool NotifyNodeOpen(FileSystemBox box, FileSystemBoxSelection selection)
       {
          FileSystemNode node = selection.node;
@@ -601,26 +892,26 @@ class ExplorerWindow : Window
             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
+            //#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
+            //#endif
             }
             else if(node.type.isFolder)
-               GoTo(node.path, true, false);
+               location = node.path;//GoTo(node.path, true, false);
          }
          UpdateHistoryItem(selection);
          return true;
@@ -628,7 +919,110 @@ class ExplorerWindow : Window
 
       bool NotifyNodeSelect(FileSystemBox box, FileSystemBoxSelection selection)
       {
-         UpdateHistoryItem(selection);
+         if(!comparedLocations)
+            UpdateHistoryItem(selection);
+         return true;
+      }
+
+      bool NotifyNodeMenu(FileSystemBox box, Menu menu, FileSystemBoxSelection selection)
+      {
+         char * text;
+         char * itemString;
+         FileSystemNode node = selection.node;
+
+         //PrintLn(node.name);
+         if(box.selection.nodes.count == 1)
+            itemString = CopyString(node.name);
+         else
+            itemString = PrintString(box.selection.nodes.count, " items");
+         text = PrintString("Open ", itemString);
+         MenuItem { menu, text, o, disabled = false;
+            NotifySelect = FileSystemBox::MenuOpen
+            /*bool FileSystemBox::NotifySelect(MenuItem selection, Modifiers mods)
+            {
+               for(node : this.selection.nodes)
+               {
+                  // todo: somehow bring MenuOpen / OpenNode behavior ourside
+               }
+               return true;
+            }*/
+         };
+         //delete text;
+         if(node.type == folder)
+         {
+            text = PrintString("Open ", itemString, " in another window");
+            MenuItem { menu, text, w, disabled = false;
+               bool FileSystemBox::NotifySelect(MenuItem selection, Modifiers mods)
+               {
+                  for(node : this.selection.nodes)
+                  {
+                     ExplorerWindow ew { /*location = this.selection.node.path*/ };//.Create();
+                     ew.Create();
+                     ew.location = /*this.selection.*/node.path;
+                  }
+                  return true;
+               }
+            };
+            //delete text;
+            MenuDivider { menu };
+            text = PrintString("Open ", itemString, " in shell");
+            MenuItem { menu, text, w, disabled = false;
+               bool FileSystemBox::NotifySelect(MenuItem selection, Modifiers mods)
+               {
+                  for(node : this.selection.nodes)
+                  {
+                     if(node.stats.attribs)
+                        ShellOpen(/*this.selection.*/node.path);
+                  }
+                  return true;
+               }
+            };
+            //delete text;
+            MenuDivider { menu };
+            MenuItem { menu, "Create File", w, NotifySelect = NewFile, disabled = false };
+            MenuItem { menu, "Create Folder", w, NotifySelect = NewFolder, disabled = false };
+         }
+         if(panelSearch.checked)
+         {
+            MenuDivider { menu };
+            MenuItem { menu, "Open Containing Folder", f, NotifySelect = FileSystemBox::MenuOpen, disabled = false;
+               bool FileSystemBox::NotifySelect(MenuItem selection, Modifiers mods)
+               {
+                  char path[MAX_LOCATION];
+                  StripLastDirectory(this.selection.node.path, path);
+                  this.path = path;
+                  return true;
+               }
+            };
+            MenuItem { menu, "Open Containing Folder in another window", r, NotifySelect = FileSystemBox::MenuOpen, disabled = false;
+               bool FileSystemBox::NotifySelect(MenuItem selection, Modifiers mods)
+               {
+                  char path[MAX_LOCATION];
+                  ExplorerWindow ew { /*location = this.selection.node.path*/ };//.Create();
+                  ew.Create();
+                  StripLastDirectory(this.selection.node.path, path);
+                  ew.location = path;
+                  return true;
+               }
+            };
+            delete itemString;
+         }
+         if(node.isListItem/* && TODO: unless node is at root location*/)
+         {
+            MenuDivider { menu };
+            MenuItem { menu, "Replace by Parent\tCtrl+R", r, NotifySelect = FileSystemBox::MenuReplaceListItemByContainingDir, disabled = false };
+         }
+         else if(box.mode == list)
+         {
+            MenuDivider { menu };
+            MenuItem { menu, "Replace List Item\tCtrl+R", r, NotifySelect = FileSystemBox::MenuReplaceListItemByChild, disabled = false };
+         }
+         MenuDivider { menu };
+         MenuItem { menu, "Cut\tCtrl+X", t, NotifySelect = null, disabled = false };
+         MenuItem { menu, "Copy\tCtrl+C", c, NotifySelect = null, disabled = false };
+         MenuItem { menu, "Paste\tCtrl+V", p, NotifySelect = null, disabled = false /*!clipboard*/ };
+         MenuItem { menu, "Delete\tDel", d, NotifySelect = null, disabled = false };
+         //MenuDivider { menu };
          return true;
       }
 
@@ -668,7 +1062,6 @@ class ExplorerWindow : Window
       //searchSpace.visible = !inSearch;
       searchBar.visible = inSearch;
       history[historyIndex].inSearch = inSearch;
-      size = { size.w, size.h };
       view.pathColumn = inSearch;
       /*if(inSearch)
          searchThread.InitResults();*/
@@ -701,43 +1094,90 @@ class ExplorerWindow : Window
       }
    }
 
-   void GoTo(char * location, bool viewIsAtLocation, bool treeIsAtLocation)
+   //void NewFile()
+   bool FileSystemBox::NewFile(MenuItem selection, Modifiers mods)
    {
-      HistoryItem item = null;
-      if(!history.count || fstrcmp(history[historyIndex].path, location))
+      if(master._class == class(ExplorerWindow))
       {
-         int c;
-         for(c = 0; c < history.count; c++)
-            if(!fstrcmp(history[c].path, location))
-               break;
-         if(c == history.count)
+         ExplorerWindow ew = (ExplorerWindow)master;
+         if(CreateNewFileDialog { /*master = */ew/*, parent = parent*/, currentDirectory = selection ? ew.view.selection.node.path : ew.view.path }.Modal() == ok )
+            ew.Refresh();
+      }
+      return true;
+   }
+
+   //void NewFolder()
+   bool FileSystemBox::NewFolder(MenuItem selection, Modifiers mods)
+   {
+      if(master._class == class(ExplorerWindow))
+      {
+         ExplorerWindow ew = (ExplorerWindow)master;
+         if(CreateDirectoryDialog { /*master = */ew/*, parent = parent*/, currentDirectory = selection ? ew.view.selection.node.path : ew.view.path }.Modal() == ok )
+            ew.Refresh();
+      }
+      return true;
+   }
+
+   //void GoTo(char * location/*, bool viewIsAtLocation, bool treeIsAtLocation*/)
+   property const char * location
+   {
+      set
+      {
+         HistoryItem item = null;
+         if(!history.count || fstrcmp(history[historyIndex].path, value))
          {
-            item = { path = CopyString(location) };
-            if(history.count)
+            int c;
+            for(c = 0; c < history.count; c++)
+               if(!fstrcmp(history[c].path, value))
+                  break;
+            if(c == history.count)
             {
-               while(historyIndex < history.count-1)
+               item = { path = CopyString(value) };
+               if(history.count)
                {
-                  delete history[history.count-1].path;
-                  history.count--;
+                  while(historyIndex < history.count-1)
+                  {
+                     delete history[history.count-1].path;
+                     history.count--;
+                  }
                }
+               history.Add(item);
+               historyIndex = history.count-1;
             }
-            history.Add(item);
-            historyIndex = history.count-1;
+            else
+               historyIndex = c;
          }
-         else
-            historyIndex = c;
+         GoToHistoryIndex(/*viewIsAtLocation, treeIsAtLocation, */item != null);
+      }
+      get { return view.path; }
+   }
+
+   property Array<String> comparedLocations
+   {
+      set
+      {
+         // dd
+         view.comparedPaths = value;
+      }
+      get
+      {
+         return view.comparedPaths;
       }
-      GoToHistoryIndex(viewIsAtLocation, treeIsAtLocation, item != null);
    }
 
-   void GoToHistoryIndex(bool viewIsAtLocation, bool treeIsAtLocation, bool updateHistoryItem)
+   void GoToHistoryIndex(/*bool viewIsAtLocation, bool treeIsAtLocation, */bool updateHistoryItem)
    {
+      bool viewIsAtLocation;
+      bool treeIsAtLocation;
       HistoryItem item = history[historyIndex];
 
       goBack.disabled = historyIndex == 0;
       goForward.disabled = historyIndex == history.count-1;
       goUp.disabled = !fstrcmp(item.path, "/");
 
+      viewIsAtLocation = !fstrcmp(item.path, tree.path);
+      treeIsAtLocation = !fstrcmp(item.path, view.path);
+
       if(!viewIsAtLocation)
       {
          if(item.inSearch != panelSearch.checked)
@@ -752,7 +1192,8 @@ class ExplorerWindow : Window
          }
          else*/
          {
-            view.path = item.path;
+            if(fstrcmp(view.path, item.path))
+               view.path = item.path;
             item.holdRecordingSelection = true;
             view.SelectMultipleByPath(item.selection);
          }
@@ -766,24 +1207,27 @@ class ExplorerWindow : Window
 
    void UpdateHistoryItem(FileSystemBoxSelection selection)
    {
-      HistoryItem item = history[historyIndex];
-
-      if(!item.holdRecordingSelection)
+      if(history.count > historyIndex)   // TODO: Review why this would happen...
       {
-         if(selection.node || (selection.nodes && selection.nodes.count))
+         HistoryItem item = history[historyIndex];
+
+         if(!item.holdRecordingSelection)
          {
-            item.selection.Free();
-            if(selection.nodes.count)
+            if(selection.node || (selection.nodes && selection.nodes.count))
             {
-               for(node : selection.nodes)
-                  item.selection.Add(CopyString(node.path));
+               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 if(selection.node)
-               item.selection.Add(CopyString(selection.node.path));
          }
+         else
+            item.holdRecordingSelection = false;
       }
-      else
-         item.holdRecordingSelection = false;
    }
 
    void SearchStart()
@@ -879,7 +1323,7 @@ class ExplorerWindow : Window
       }
       return true;
    }*/
-   
+
    /*bool ViewNotifyItemOpen(ExplorerView view, ExplorerFileItem item)
    {
       ExplorerFileBranch branch = tree.branch;
@@ -888,14 +1332,14 @@ class ExplorerWindow : Window
          if(item.type.isFolderType)
          {
             ExplorerFileBranch child;
-            
+
             if(!branch.loaded || !branch.childrenLoaded)
                BranchLoad(branch, tree.tree);
 
             for(child = branch.children.first; child; child = child.next)
                if(!strcmp(child.name, item.name))
                   break;
-            
+
             if(child)
             {
                if(branch.row.collapsed)
@@ -937,7 +1381,7 @@ class ExplorerWindow : Window
 
    /*void SearchLocation(char * location)
    {
-      GoTo(location);
+      location = location;//GoTo(location);
       search.location.editBox.contents = location;
    }*/
 
@@ -946,6 +1390,7 @@ class ExplorerWindow : Window
       //userMode = true;
       addressBar.path = view.path;
       ReadyTree();
+      view.Refresh();
       return true;
    }
 
@@ -971,7 +1416,7 @@ class ExplorerWindow : Window
          NotifyItemOpen = ViewNotifyItemOpen;
       };
       lastViewId = viewList;
-      
+
       tree.Load();
       view.Load(tree.root);
    }*/