diff --git a/BeefLibs/Beefy2D/src/theme/dark/DarkCheckBox.bf b/BeefLibs/Beefy2D/src/theme/dark/DarkCheckBox.bf index dbb62b55..bff67f10 100644 --- a/BeefLibs/Beefy2D/src/theme/dark/DarkCheckBox.bf +++ b/BeefLibs/Beefy2D/src/theme/dark/DarkCheckBox.bf @@ -121,7 +121,7 @@ namespace Beefy.theme.dark { g.SetFont(mFont); - DarkTheme.DrawUnderlined(g, mLabel, GS!(22), 0); + DarkTheme.DrawUnderlined(g, mLabel, GS!(22), GS!(-1)); /*int underlinePos = mLabel.IndexOf('&'); if ((underlinePos != -1) && (underlinePos < mLabel.Length - 1)) diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index 410574ed..17d7a8bf 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -48,6 +48,28 @@ namespace System mCmdInfo.Append("\n"); } + public void AddFilePath(StringView dataName, StringView label, StringView defaultValue) + { + mCmdInfo.AppendF($"addFilePath\t"); + dataName.QuoteString(mCmdInfo); + mCmdInfo.Append("\t"); + label.QuoteString(mCmdInfo); + mCmdInfo.Append("\t"); + defaultValue.QuoteString(mCmdInfo); + mCmdInfo.Append("\n"); + } + + public void AddFolderPath(StringView dataName, StringView label, StringView defaultValue) + { + mCmdInfo.AppendF($"addFolderPath\t"); + dataName.QuoteString(mCmdInfo); + mCmdInfo.Append("\t"); + label.QuoteString(mCmdInfo); + mCmdInfo.Append("\t"); + defaultValue.QuoteString(mCmdInfo); + mCmdInfo.Append("\n"); + } + public void AddCombo(StringView dataName, StringView label, StringView defaultValue, Span values) { mCmdInfo.AppendF($"addCombo\t"); @@ -105,6 +127,10 @@ namespace System int tabPos = line.IndexOf('\t'); var key = line.Substring(0, tabPos); var value = line.Substring(tabPos + 1); + + if (key == "FolderDir") + Directory.SetCurrentDirectory(value).IgnoreError(); + if (mParams.TryAdd(key, var keyPtr, var valuePtr)) { *keyPtr = key; diff --git a/IDE/src/ui/GenerateDialog.bf b/IDE/src/ui/GenerateDialog.bf index b87b99d2..926edf70 100644 --- a/IDE/src/ui/GenerateDialog.bf +++ b/IDE/src/ui/GenerateDialog.bf @@ -548,6 +548,8 @@ namespace IDE.ui if (mUIData != null) { + Project project = gApp.mWorkspace.FindProject(mProjectName); + if (mOutputPanel != null) { mOutputPanel.RemoveSelf(); @@ -587,6 +589,23 @@ namespace IDE.ui AddWidget(editWidget); mUIEntries.Add(uiEntry); mTabWidgets.Add(editWidget); + case "addFilePath", "addFolderPath": + if (mSubmitting) + break; + UIEntry uiEntry = new UIEntry(); + uiEntry.mName = partItr.GetNext().Value.UnQuoteString(.. new .()); + uiEntry.mLabel = partItr.GetNext().Value.UnQuoteString(.. new .()); + var defaultValue = partItr.GetNext().Value.UnQuoteString(.. scope .()); + PathEditWidget editWidget = new PathEditWidget((kind == "addFilePath") ? .File : .Folder); + if (project != null) + editWidget.mDefaultFolderPath = new .(project.mProjectDir); + uiEntry.mWidget = editWidget; + editWidget.SetText(defaultValue); + editWidget.mEditWidgetContent.SelectAll(); + editWidget.mOnSubmit.Add(new => EditSubmitHandler); + AddWidget(editWidget); + mUIEntries.Add(uiEntry); + mTabWidgets.Add(editWidget); case "addCombo": if (mSubmitting) break; diff --git a/IDE/src/ui/PathEditWidget.bf b/IDE/src/ui/PathEditWidget.bf index cdcef731..96756491 100644 --- a/IDE/src/ui/PathEditWidget.bf +++ b/IDE/src/ui/PathEditWidget.bf @@ -57,6 +57,7 @@ namespace IDE.ui public String mRelPath ~ delete _; PathKind mPathKind; DarkButton mBrowseButton; + public String mDefaultFolderPath ~ delete _; public this(PathKind pathKind = .Unknown) { @@ -73,6 +74,9 @@ namespace IDE.ui { String path = scope .(); GetText(path); + + if (path.IsWhiteSpace) + path.Set(mDefaultFolderPath); #if !CLI FolderBrowserDialog folderDialog = scope .(); folderDialog.SelectedPath = path; @@ -83,6 +87,30 @@ namespace IDE.ui } #endif } + else if (mPathKind == .File) + { + String path = scope .(); + GetText(path); + + + String dirPath = scope .(); + Path.GetDirectoryPath(path, dirPath).IgnoreError(); + if ((dirPath.IsWhiteSpace) && (mDefaultFolderPath != null)) + dirPath.Set(mDefaultFolderPath); + +#if !CLI + OpenFileDialog fileDialog = scope .(); + fileDialog.FileName = path; + if (!dirPath.IsWhiteSpace) + fileDialog.InitialDirectory = dirPath; + mWidgetWindow.PreModalChild(); + if (fileDialog.ShowDialog(gApp.GetActiveWindow()).GetValueOrDefault() == .OK) + { + if (!fileDialog.FileNames.IsEmpty) + SetText(scope String()..Append(fileDialog.FileNames[0])); + } +#endif + } }); mEditWidgetContent.mTextInsets.mRight += GS!(20); } diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 88c2167c..a34719fd 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -3472,14 +3472,24 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str) ////////////////////////////////////////////////////////////////////////// -void CeContext::FixProjectRelativePath(StringImpl& path) +void CeContext::CalcWorkingDir() { - BfProject* activeProject = NULL; - auto activeTypeDef = mCallerActiveTypeDef; - if (activeTypeDef != NULL) - activeProject = activeTypeDef->mProject; - if (activeProject != NULL) - path = GetAbsPath(path, activeProject->mDirectory); + if (mWorkingDir.IsEmpty()) + { + BfProject* activeProject = NULL; + auto activeTypeDef = mCallerActiveTypeDef; + if (activeTypeDef != NULL) + activeProject = activeTypeDef->mProject; + if (activeProject != NULL) + mWorkingDir = activeProject->mDirectory; + } +} + +void CeContext::FixRelativePath(StringImpl& path) +{ + CalcWorkingDir(); + if (!mWorkingDir.IsEmpty()) + path = GetAbsPath(path, mWorkingDir); } bool CeContext::AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value) @@ -6249,7 +6259,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); + FixRelativePath(path); BfpDirectory_Create(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Rename) @@ -6264,8 +6274,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CE_CHECKADDR_STR(srcPath, srcAddr); String destPath; CE_CHECKADDR_STR(destPath, destAddr); - FixProjectRelativePath(srcPath); - FixProjectRelativePath(destPath); + FixRelativePath(srcPath); + FixRelativePath(destPath); BfpDirectory_Rename(srcPath.c_str(), destPath.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Delete) @@ -6277,7 +6287,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); + FixRelativePath(path); BfpDirectory_Delete(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_GetCurrent) @@ -6293,7 +6303,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); - BfpDirectory_GetCurrent(namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); + CalcWorkingDir(); + TryStringOut(mWorkingDir, namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_SetCurrent) { @@ -6304,8 +6315,19 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); - BfpDirectory_SetCurrent(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); + FixRelativePath(path); + + if (::BfpDirectory_Exists(path.c_str())) + { + mWorkingDir = path; + if (outResultAddr != 0) + *(BfpFileResult*)(memStart + outResultAddr) = BfpFileResult_Ok; + } + else + { + if (outResultAddr != 0) + *(BfpFileResult*)(memStart + outResultAddr) = BfpFileResult_NotFound; + } } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Exists) { @@ -6314,7 +6336,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); + FixRelativePath(path); result = BfpDirectory_Exists(path.c_str()); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_GetSysDirectory) @@ -6356,7 +6378,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); CE_CHECKADDR(outResultAddr, 4); - FixProjectRelativePath(path); + FixRelativePath(path); auto bfpFile = BfpFile_Create(path.c_str(), (BfpFileCreateKind)createKind, (BfpFileCreateFlags)createFlags, (BfpFileAttributes)createFileAttrs, (BfpFileResult*)(memStart + outResultAddr)); if (bfpFile != NULL) { @@ -6522,7 +6544,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 8); String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); + FixRelativePath(path); AddFileRebuild(path); result = BfpFile_GetTime_LastWrite(path.c_str()); } @@ -6536,7 +6558,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); + FixRelativePath(path); result = BfpFile_GetAttributes(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_SetAttributes) @@ -6549,7 +6571,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); + FixRelativePath(path); BfpFile_SetAttributes(path.c_str(), attribs, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Copy) @@ -6565,8 +6587,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CE_CHECKADDR_STR(srcPath, srcAddr); String destPath; CE_CHECKADDR_STR(destPath, destAddr); - FixProjectRelativePath(srcPath); - FixProjectRelativePath(destPath); + FixRelativePath(srcPath); + FixRelativePath(destPath); BfpFile_Copy(srcPath.c_str(), destPath.c_str(), fileCopyKind, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Rename) @@ -6581,8 +6603,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* CE_CHECKADDR_STR(srcPath, srcAddr); String destPath; CE_CHECKADDR_STR(destPath, destAddr); - FixProjectRelativePath(srcPath); - FixProjectRelativePath(destPath); + FixRelativePath(srcPath); + FixRelativePath(destPath); BfpFile_Rename(srcPath.c_str(), destPath.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Delete) @@ -6594,7 +6616,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); + FixRelativePath(path); BfpFile_Delete(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Exists) @@ -6604,7 +6626,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - FixProjectRelativePath(path); + FixRelativePath(path); AddFileRebuild(path); result = BfpFile_Exists(path.c_str()); } @@ -6655,7 +6677,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); - FixProjectRelativePath(srcPath); + FixRelativePath(srcPath); BfpFile_GetFullPath(srcPath.c_str(), namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetActualPath) @@ -6675,7 +6697,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); - FixProjectRelativePath(srcPath); + FixRelativePath(srcPath); BfpFile_GetActualPath(srcPath.c_str(), namePtr, &nameSize, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Create) @@ -6704,7 +6726,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if ((targetPath.Contains('/')) || (targetPath.Contains('\\'))) { - FixProjectRelativePath(targetPath); + FixRelativePath(targetPath); } auto bfpSpawn = BfpSpawn_Create(targetPath.c_str(), @@ -6840,7 +6862,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if (outResultAddr != 0) CE_CHECKADDR(outResultAddr, 4); - FixProjectRelativePath(path); + FixRelativePath(path); auto bfpFindFileData = BfpFindFileData_FindFirstFile(path.c_str(), (BfpFindFileFlags)flags, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); if (bfpFindFileData != NULL) { @@ -9602,6 +9624,7 @@ void CeMachine::ReleaseContext(CeContext* ceContext) for (auto kv : ceContext->mInternalDataMap) kv.mValue->Release(); ceContext->mInternalDataMap.Clear(); + ceContext->mWorkingDir.Clear(); } BfTypedValue CeMachine::Call(CeCallSource callSource, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray& args, CeEvalFlags flags, BfType* expectingType) diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 377e881e..c0ab8519 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -1090,6 +1090,7 @@ public: BfModule* mCurModule; CeFrame* mCurFrame; CeEmitContext* mCurEmitContext; + String mWorkingDir; public: CeContext(); @@ -1097,8 +1098,9 @@ public: BfError* Fail(const StringImpl& error); BfError* Fail(const CeFrame& curFrame, const StringImpl& error); - - void FixProjectRelativePath(StringImpl& path); + + void CalcWorkingDir(); + void FixRelativePath(StringImpl& path); bool AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value); void AddFileRebuild(const StringImpl& filePath); uint8* CeMalloc(int size);