+
+ DataField nameField { dataType = "FileSystemNode", width = 240, userData = this, freeData = false };
+ DataField typeField { header = "Type", dataType = /*"String"*/ "char *", width = 40, freeData = false };
+ DataField sizeField { header = "Size", dataType = "FileSize", width = 96, alignment = right, freeData = false };
+
+ bool OnPostCreate()
+ {
+ Load();
+ return true;
+ }
+
+ ListBox list
+ {
+ this;
+
+ borderStyle = none;
+ hasHorzScroll = true;
+ hasVertScroll = true;
+ fullRowSelect = false;
+ sortable = true;
+
+ anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
+
+ // WHY is this not working ?
+ /*void OnResize(int width, int height)
+ {
+ if(vertScroll.visible)
+ nameField.width = width - vertScroll.size.w;
+ else
+ nameField.width = width;
+ }*/
+
+ bool NotifyCollapse(ListBox listBox, DataRow row, bool collapsed)
+ {
+ if(row)
+ {
+ FileSystemNode node = (FileSystemNode)row.tag;
+ FileSystemNode child;
+ if(collapsed)
+ {
+ /*
+ for(child = node.children.last; child; child = node.children.last)
+ {
+ listBox.DeleteRow(child.row);
+ child.Free();
+ delete child;
+ }
+ node.childrenLoaded = false;
+ */
+ }
+ else
+ {
+ if(!node.loaded || !node.childrenLoaded)
+ {
+ LoadTreeNode(node);
+ //list.Sort(nameField, 1);
+ //node.
+ }
+ for(child = node.children.first; child && child.next; child = child.next);
+ if(child)
+ child.EnsureVisible(false);
+ }
+ }
+ return true;
+ }
+
+ bool NotifyRightClick(ListBox listBox, int x, int y, Modifiers mods)
+ {
+ DataRow row = listBox.currentRow;
+ if(row)
+ {
+ FileSystemNode node = (FileSystemNode)row.tag;
+ if(node)
+ {
+ PopupMenu popup;
+ Menu 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 };
+
+ popup = PopupMenu
+ {
+ master = this, menu = menu,
+ position = {
+ x + clientStart.x + absPosition.x - guiApp.desktop.position.x,
+ y + clientStart.y + absPosition.y - guiApp.desktop.position.y }
+ };
+ popup.Create();
+ }
+ }
+ return true;
+ }
+
+ bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
+ {
+ if(row)
+ {
+ FileSystemNode node = (FileSystemNode)row.tag;
+ NotifyNodeSelect(listBox.parent.master, this, node);
+ selection = node;
+ }
+ return true;
+ }
+
+ bool NotifyEditing(ListBox listBox, DataRow row)
+ {
+ if(row)
+ {
+ FileSystemNode node = (FileSystemNode)row.tag;
+ }
+ return true;
+ }
+
+ bool NotifyEdited(ListBox listBox, DataRow row)
+ {
+ if(row)
+ {
+ FileSystemNode node = (FileSystemNode)row.tag;
+ }
+ return true;
+ }
+
+ bool NotifyEditDone(ListBox listBox, DataRow row)
+ {
+ if(row)
+ {
+ FileSystemNode node = (FileSystemNode)row.tag;
+ }
+ return true;
+ }
+
+ bool NotifyDoubleClick(ListBox listBox, int x, int y, Modifiers mods)
+ {
+ return OpenNode();
+ }
+
+ bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
+ {
+ bool result;
+ if((SmartKey)key == enter)
+ result = OpenNode();
+ else
+ result = true;
+ return true;
+ }
+ };
+
+ bool OpenNode()
+ {
+ bool result;
+ if(selection && selection.type.isFolder && bits.navigateFolders)
+ {
+ property::path = selection.path;
+ result = true;
+ }
+ else
+ result = NotifyNodeOpen(this.master, this, selection);
+ return result;
+ }
+
+ // Edit Menu
+ Menu editMenu { menu, "Edit", e };
+ MenuItem itemEditCut
+ {
+ editMenu, "Cut\tCtrl+X", t, disabled = true;
+
+ bool NotifySelect(MenuItem selection, Modifiers mods)
+ {
+ //EditCut();
+ return true;
+ }
+ };
+ MenuItem itemEditCopy
+ {
+ editMenu, "Copy\tCtrl+C", c, disabled = true;
+
+ bool NotifySelect(MenuItem selection, Modifiers mods)
+ {
+ //EditCopy();
+ return true;
+ }
+ };
+ MenuItem itemEditPaste
+ {
+ editMenu, "Paste\tCtrl+V", p;
+
+ bool NotifySelect(MenuItem selection, Modifiers mods)
+ {
+ //EditPaste();
+ return true;
+ }
+ };
+ MenuItem itemEditDelete
+ {
+ editMenu, "Delete\tDel", d, disabled = true;
+
+ bool NotifySelect(MenuItem selection, Modifiers mods)
+ {
+ //EditDelete();
+ return true;
+ }
+ };
+
+ // WHY is this crashing ?
+ /*void OnResize(int width, int height)
+ {
+ if(this && nameField)
+ nameField.width = width - 80;
+ }*/
+
+ void Load()
+ {
+ // TODO: fix this!
+ // this is crashing in for designer when details = true // can't save the file, always yields a crash
+ /*if(list && created)
+ {
+ list.ClearFields();
+ list.AddField(nameField);
+ if(bits.details)
+ {
+ list.AddField(typeField);
+ list.AddField(sizeField);
+ }
+ }*/
+ if(bits.treeBranches)
+ LoadTree();
+ else
+ LoadList();
+ }
+
+ void LoadList()
+ {
+ FileListing listing { path, extensions = extensions };
+
+ list.Clear();
+ while(listing.Find())
+ {
+ if((!bits.foldersOnly && !bits.filesOnly) ||
+ (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
+ (bits.filesOnly && !listing.stats.attribs.isDirectory/*listing.stats.attribs.isFile*/)) // TOCHECK: isFile broken?
+ {
+ FileSystemNode node = MakeFileSystemNode(listing.stats, listing.name, listing.path, bits.previewPictures, displaySystem);
+ DataRow row = list.AddRow();
+ row.tag = (int)node;
+ row.SetData(nameField, node);
+ if(bits.details)
+ {
+ row.SetData(typeField, node.extension);
+ row.SetData(sizeField, (void *)node.stats.size);
+ }
+ }
+ }
+ list.Sort(nameField, 1);
+ }
+
+ void LoadTree()
+ {
+ bool isRoot = !strcmp(path, "/");
+ //char startPath[MAX_LOCATION];
+ FileSystemNode parent;
+ FileSystemNode node;
+ FileListing listing { path, extensions = extensions };
+
+ /*if(!path)
+ GetWorkingDir(startPath, sizeof(startPath));
+ else
+ strcpy(path, startPath);*/
+
+ list.Clear();
+
+ delete root;
+ #ifdef __WIN32__
+ if(isRoot)
+ {
+ root = FileSystemNode { loaded = true, childrenLoaded = true };
+ AddTreeNode(root, true, false, null);
+ while(listing.Find())
+ {
+ int len = strlen(listing.name);
+ char info[MAX_LOCATION];
+ char name[MAX_LOCATION];
+ if(listing.stats.attribs.isDrive &&
+ len > 3 && !strncmp(&listing.name[1], ": [", 3))
+ {
+ strncpy(name, listing.name, 2);
+ name[2] = 0;
+ strncpy(info, &listing.name[4], len - 5);
+ info[len - 5] = 0;
+ }
+ else
+ {
+ strcpy(name, listing.name);
+ info[0] = 0;
+ }
+
+ parent = MakeFileSystemNode(listing.stats, name, listing.path, bits.previewPictures, displaySystem);
+ if(info[0])
+ parent.info = CopyString(info);
+ parent.loaded = true;
+ AddTreeNode(parent, !listing.stats.attribs.isDirectory, listing.stats.attribs.isDirectory, root);
+ if(!listing.stats.attribs.isDirectory)
+ parent.childrenLoaded = true;
+ }
+
+ node = FileSystemNode { name = msNetwork, type = network };
+ AddTreeNode(node, false, true, null);
+ node.row.collapsed = true;
+ }
+ else
+ #endif
+ {
+ root = MakeFileSystemNode(FileStats { attribs = FileExists(path)}, path, path, bits.previewPictures, displaySystem);
+ AddTreeNode(root, false, true, null);
+ LoadTreeNode(root);
+ }
+
+ if(isRoot)
+ {
+ root.type = computer;
+ root.name = rootName;
+ }
+
+ list.Sort(nameField, 1);
+ list.SelectRow(root.row);
+ }
+
+ void LoadTreeNode(FileSystemNode node)
+ {
+ if(!node.loaded)
+ {
+ char path[MAX_LOCATION];
+ node.GetPath(path);
+ {
+ FileListing listing { path, extensions = extensions };
+ if(node.children.count == 1)
+ DeleteNode(node.children.first);
+
+ while(listing.Find())
+ {
+ if((!bits.foldersOnly && !bits.filesOnly) ||
+ (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
+ (bits.filesOnly && !listing.stats.attribs.isDirectory/*listing.stats.attribs.isFile*/)) // TOCHECK: isFile broken?
+ {
+ FileSystemNode child = MakeFileSystemNode(listing.stats, listing.name, listing.path, bits.previewPictures, displaySystem);
+ AddTreeNode(child, true, false, node);
+ NodeChildLoad(child, node);
+ }
+ }
+ }
+ node.childrenLoaded = true;
+ node.loaded = true;
+ node.row.SortSubRows(false);
+ }
+ else if(!node.childrenLoaded)
+ {
+ FileSystemNode child;
+ if(node.children.first)
+ {
+ for(child = node.children.first; child; child = child.next)
+ {
+ if(!child.loaded)
+ LoadTreeNode(child);
+ else if(!child.childrenLoaded)
+ NodeChildLoad(child, node);
+ }
+ node.childrenLoaded = true;
+ node.row.SortSubRows(false);
+ }
+ }
+ }
+
+ void NodeChildLoad(FileSystemNode parent, FileSystemNode node)
+ {
+ char path[MAX_LOCATION];
+ parent.GetPath(path);
+ {
+ bool added = false;
+ FileListing listing { path, extensions = extensions };
+ while(listing.Find())
+ {
+ if((!bits.foldersOnly && !bits.filesOnly) ||
+ (bits.foldersOnly && listing.stats.attribs.isDirectory) ||
+ (bits.filesOnly && !listing.stats.attribs.isDirectory/*listing.stats.attribs.isFile*/)) // TOCHECK: isFile broken?
+ {
+ FileSystemNode child = MakeFileSystemNode(listing.stats, listing.name, listing.path, bits.previewPictures, displaySystem);
+ AddTreeNode(child, true, false, parent);
+ added = true;
+ }
+ }
+ if(!added)
+ added = true;
+ }
+ //parent.childrenLoaded = true;
+ }
+
+ void AddTreeNode(FileSystemNode node, bool loaded, bool addLoader, FileSystemNode addTo)
+ {
+ DataRow row = (addTo && addTo.row) ? addTo.row.AddRow() : list.AddRow();
+ if(addTo)
+ {
+ node.parent = addTo;
+ node.indent = addTo.indent + 1;
+ addTo.children.Add(node);
+ }
+ row.tag = (int)node;
+ node.row = row;
+ row.SetData(null, node);
+
+ node.loaded = loaded;
+ if(addLoader)
+ //AddTreeNode(FileSystemNode { }, false, false, node); // why would this create a compile error?
+ AddTreeNode(FileSystemNode { type = none }, false, false, node);
+
+ if(node.indent > 0)
+ row.collapsed = true;
+ else if(node.type == folder)
+ node.type = folderOpen;
+ }
+
+ void DeleteNode(FileSystemNode node)
+ {
+ FileSystemNode child;
+ for(; (child = node.children.first); )
+ DeleteNode(child);
+ list.DeleteRow(node.row);
+ node.Delete();
+ }