1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-19 16:40:26 +02:00
Beef/IDE/src/ui/PathEditWidget.bf

231 lines
5.3 KiB
Beef
Raw Normal View History

2019-08-23 11:56:54 -07:00
using Beefy.theme.dark;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Generic;
namespace IDE.ui
{
class PathEditWidget : ExpressionEditWidget
{
enum PathKind
{
Unknown,
Folder,
File
}
class DirectoryTask : Task
{
class Entry
{
public bool mIsDirectory;
public String mFileName ~ delete _;
}
public PathEditWidget mPathEditWidget;
public String mDirectoryPath = new .() ~ delete _;
public List<Entry> mEntries = new .() ~ DeleteContainerAndItems!(_);
public this()
{
}
protected override void InnerInvoke()
{
var searchStr = scope String();
searchStr.Append(mDirectoryPath);
searchStr.Append("/*");
for (var dirEntry in Directory.Enumerate(searchStr, .Directories | .Files))
{
var entry = new Entry();
entry.mIsDirectory = dirEntry.IsDirectory;
entry.mFileName = new String();
dirEntry.GetFileName(entry.mFileName);
mEntries.Add(entry);
}
if (!mDetachState.HasFlag(.Deatched))
mPathEditWidget.mAutocompleteDirty = true;
}
}
DirectoryTask mDirectoryTask ~ { if (_ != null) _.Detach(); };
bool mAutocompleteDirty;
public String mRelPath ~ delete _;
PathKind mPathKind;
DarkButton mBrowseButton;
public this(PathKind pathKind = .Unknown)
{
mPathKind = pathKind;
if (mPathKind != .Unknown)
{
mBrowseButton = new DarkButton();
mBrowseButton.Label = "...";
AddWidget(mBrowseButton);
mBrowseButton.mOnMouseClick.Add(new (mouseArgs) =>
{
if (mPathKind == .Folder)
{
String path = scope .();
GetText(path);
#if !CLI
FolderBrowserDialog folderDialog = scope .();
folderDialog.SelectedPath = path;
mWidgetWindow.PreModalChild();
if (folderDialog.ShowDialog(gApp.GetActiveWindow()).GetValueOrDefault() == .OK)
{
SetText(scope String()..Append(folderDialog.SelectedPath));
}
#endif
}
});
}
}
public override void UpdateText(char32 keyChar, bool doAutoComplete)
{
if (!doAutoComplete)
return;
var editText = scope String();
GetText(editText);
int cursorPos = mEditWidgetContent.CursorTextPos;
int firstSlash = -1;
int startSlash = -1;
int nextSlash = -1;
for (int i < editText.Length)
{
let c = editText[i];
if ((c == '\\') || (c == '/'))
{
if (firstSlash == -1)
firstSlash = i;
if (cursorPos >= i)
{
startSlash = i;
}
else
{
if (nextSlash == -1)
nextSlash = i;
}
}
}
var editWidgetContent = (ExpressionEditWidgetContent)mEditWidgetContent;
if ((firstSlash != -1) && (keyChar != '\'') && (keyChar != '/'))
{
String selStr = scope String();
if (nextSlash != -1)
selStr.Append(editText, startSlash + 1, nextSlash - startSlash - 1);
else
selStr.Append(editText, startSlash + 1, cursorPos - startSlash - 1);
String info = scope .();
info.Append("uncertain\n");
info.AppendF("insertRange\t{0} {1}\n", startSlash + 1, cursorPos);
//info.Append("directory\thi\n");
//info.Append("directory\thi2\n");
String subRelPath = scope String();
if (startSlash != -1)
subRelPath.Append(editText, 0, startSlash);
var subAbsPath = scope String();
if (mRelPath != null)
Path.GetAbsolutePath(subRelPath, mRelPath, subAbsPath);
else
Path.GetAbsolutePath(subRelPath, gApp.mInstallDir, subAbsPath);
if ((mDirectoryTask == null) || (mDirectoryTask.mDirectoryPath != subAbsPath))
{
if (mDirectoryTask != null)
{
mDirectoryTask.Detach();
mDirectoryTask = null;
}
if (editWidgetContent.mAutoComplete != null)
editWidgetContent.mAutoComplete.Close();
mDirectoryTask = new DirectoryTask();
mDirectoryTask.mPathEditWidget = this;
mDirectoryTask.mDirectoryPath.Set(subAbsPath);
mDirectoryTask.Start();
return;
}
if (!mDirectoryTask.IsCompleted)
{
return;
}
for (var entry in mDirectoryTask.mEntries)
{
if (!entry.mFileName.StartsWith(selStr, .OrdinalIgnoreCase))
continue;
if (entry.mIsDirectory)
info.AppendF("folder\t{0}\n", entry.mFileName);
else
info.AppendF("file\t{0}\n", entry.mFileName);
}
var autoComplete = GetAutoComplete();
autoComplete.mUncertain = true;
SetAutoCompleteInfo(info, 0);
}
else
{
if (mDirectoryTask != null)
{
mDirectoryTask.Detach();
mDirectoryTask = null;
}
if (editWidgetContent.mAutoComplete != null)
editWidgetContent.mAutoComplete.Close();
}
}
public override void Update()
{
base.Update();
if (mAutocompleteDirty)
{
UpdateText(0, true);
mAutocompleteDirty = false;
}
}
public override void Resize(float x, float y, float width, float height)
{
base.Resize(x, y, width, height);
if (mBrowseButton != null)
{
mBrowseButton.Resize(mWidth - DarkTheme.sUnitSize - GS!(2), GS!(2), DarkTheme.sUnitSize, DarkTheme.sUnitSize);
}
}
}
class PathComboBox : DarkComboBox
{
public override bool WantsKeyHandling()
{
if (mEditWidget == null)
return true;
var expressionEditWidget = (ExpressionEditWidgetContent)mEditWidget.mEditWidgetContent;
return expressionEditWidget.mAutoComplete == null;
}
}
}