3 import "ArrayFactoredGrowth"
4 import "ArrayBinarySorted"
8 public class FileTreeBranchBSArray : ArrayBinarySorted
10 type = class(FileTreeBranch);
12 FileTreeBranch * const _;
13 BSloc Add(FileTreeBranch item)
15 BSloc result = Find(item);
18 Insert(result.pos, 1);
23 BSloc Remove(FileTreeBranch item)
29 public class FileTreeBranchArray : Array
31 type = class(FileTreeBranch);
33 FileTreeBranch * const _;
34 FileTreeBranch * Add(FileTreeBranch item)
41 FileTreeBranch * AddBefore(uint position, FileTreeBranch item)
49 public class FileTreeBranch : struct
51 FileTreeBranch prev, next;
53 bool loaded, childrenLoaded;
60 FileTreeBranch parent;
64 void GetPath(String outputPath)
67 strcpy(outputPath, name);
70 for(up = parent; up; up = up.parent)
72 char temp[MAX_LOCATION];
73 strcpy(temp, up.name);
74 PathCat(temp, outputPath);
75 strcpy(outputPath, temp);
80 bool IsChildOf(FileTreeBranch branch)
83 for(test = parent; test; test = test.parent)
89 void DuplicateChildren(bool recursive, bool forceExpanded, FileTreeBranch addTo, ListBox tree)
95 for(child = children.first; child; child = child.next)
97 FileTreeBranch copy { };
98 copy.name = CopyString(child.name);
99 copy.type = child.type;
100 AddBranch(copy, child.loaded, false, addTo, tree);
102 copy.row.collapsed = false;
104 child.DuplicateChildren(recursive, forceExpanded, copy, tree);
109 void EnsureVisible(bool expand)
112 parent.EnsureVisible(true);
114 row.collapsed = false;
123 FileTreeBranch child;
124 for(; (child = children.first); )
127 children.Delete(child);
138 parent.children.Delete(this);
141 void OnDisplay(Surface surface, int x, int y, int width, ExplorerListBox icons, Alignment alignment, DataDisplayFlags displayFlags)
143 //int indentSize = (displayFlags.dropBox) ? 0 : 10;
149 char label[MAX_FILENAME];
156 icon = icons.icons[type].bitmap;
157 //xStart = indent * indent + x + (icon ? (icon.width + 5) : 0);
158 xStart = x + (icon ? (icon.width + 5) : 0);
164 sprintf(label, "%s [%s]", name, info);
171 if(type == folder || type == folderOpen)
172 surface.SetForeground(yellow);
176 //textOffset = indent * indentSize + (icon ? (icon.width + 4) : 0);
178 surface.TextOpacity(false);
179 surface.TextExtent(label, len, &w, &h);
182 // Draw the current row stipple
183 if(displayFlags.selected)
184 //surface.Area(xStart - 1, y, xStart - 1, y + h - 1);
185 //surface.Area(xStart + w - 1, y, xStart + w + 1, y + h - 1);
186 surface.Area(xStart - 3, y, xStart + w + 1, y + h - 1);
188 //surface.WriteTextDots(alignment, x + textOffset, y + 2, width - textOffset, name, strlen(name));
189 surface.WriteTextDots(alignment, xStart, y + 2, width, label, len);
193 if(displayFlags.current)
195 if(displayFlags.active)
197 surface.LineStipple(0x5555);
198 if(displayFlags.selected)
199 surface.SetForeground(0xFFFFFF80);
201 surface.SetForeground(black);
205 surface.SetForeground(selectionColor);
207 surface.Rectangle(xStart - 3, y, xStart + w + 1, y + h - 1);
208 surface.LineStipple(0);
213 //surface.blend = true;
214 //surface.alphaWrite = blend;
215 surface.SetForeground(white);
216 //surface.Blit(icon, x + indent * indentSize, y,0,0, icon.width, icon.height);
217 surface.Blit(icon, x,y,0,0, icon.width, icon.height);
222 int OnCompare(FileTreeBranch b)
225 if(type == b.type || (type < folder && b.type < folder) || (type >= drive))
226 result = strcmpi(name, b.name);
229 if(type == folder && b.type < folder) result = -1;
230 else if(type < folder && b.type == folder) result = 1;
235 char * OnGetString(char * tempString, FileSystemToolWindow fileSysToolWnd, bool * needClass)
237 return name ? name : "";
241 FileTreeBranch MakeFileTreeBranch(const FileStats stats, const char * name)
243 FileTreeBranch fileTreeBranch { stats = stats };
244 fileTreeBranch.name = CopyString(name);
245 if(!fileTreeBranch.name)
246 fileTreeBranch.name = null;
247 if(stats.attribs.isDirectory)
249 fileTreeBranch.type = (stats.attribs.isDrive) ? drive : folder;
250 if(stats.attribs.isServer) fileTreeBranch.type = server;
251 if(stats.attribs.isShare) fileTreeBranch.type = share;
252 if(stats.attribs.isCDROM) fileTreeBranch.type = cdrom;
253 if(stats.attribs.isRemote) fileTreeBranch.type = netDrive;
254 if(stats.attribs.isRemovable)
256 if(name[0] == 'A' || name[0] == 'B')
257 fileTreeBranch.type = floppy;
259 fileTreeBranch.type = removable;
264 char extension[MAX_EXTENSION];
265 GetExtension(fileTreeBranch.name, extension);
266 fileTreeBranch.type = FileItemType::SelectByExtension(extension);
268 return fileTreeBranch;
271 void AddBranch(FileTreeBranch branch, bool loaded, bool addLoader, FileTreeBranch addTo, ListBox tree)
273 DataRow row = (addTo && addTo.row) ? addTo.row.AddRow() : tree.AddRow();
276 branch.parent = addTo;
277 branch.indent = addTo.indent + 1;
278 addTo.children.Add(branch);
280 row.tag = (int)branch;
282 row.SetData(null, branch);
284 branch.loaded = loaded;
286 //AddBranch(FileTreeBranch { }, false, false, branch, tree); // why would this create a compile error?
287 AddBranch(FileTreeBranch { type = none }, false, false, branch, tree);
289 if(branch.indent > 0)
290 row.collapsed = true;
291 else if(branch.type == folder)
292 branch.type = folderOpen;
295 void BranchLoad(FileTreeBranch branch, ListBox tree)
299 char path[MAX_LOCATION];
300 branch.GetPath(path);
302 FileListing listing { path };
303 if(branch.children.count == 1)
304 DeleteBranch(branch.children.first, tree);
306 while(listing.Find())
308 if(listing.stats.attribs.isDirectory)
310 FileTreeBranch child = MakeFileTreeBranch(listing.stats, listing.name);
311 AddBranch(child, true, false, branch, tree);
312 BranchChildLoad(child, branch, tree);
316 branch.childrenLoaded = true;
317 branch.loaded = true;
319 else if(!branch.childrenLoaded)
321 FileTreeBranch child;
322 if(branch.children.first)
324 for(child = branch.children.first; child; child = child.next)
327 BranchLoad(child, tree);
328 else if(!child.childrenLoaded)
329 BranchChildLoad(child, branch, tree);
331 branch.childrenLoaded = true;
336 static void BranchChildLoad(FileTreeBranch parent, FileTreeBranch branch, ListBox tree)
338 char path[MAX_LOCATION];
339 parent.GetPath(path);
342 FileListing listing { path };
343 while(listing.Find())
345 if(listing.stats.attribs.isDirectory)
347 FileTreeBranch child = MakeFileTreeBranch(listing.stats, listing.name);
348 AddBranch(child, true, false, parent, tree);
355 //parent.childrenLoaded = true;
358 void DeleteBranch(FileTreeBranch branch, ListBox tree)
360 FileTreeBranch child;
361 for(; (child = branch.children.first); )
362 DeleteBranch(child, tree);
363 tree.DeleteRow(branch.row);