public unsafe void Draw(string title, byte[] mem_data, int mem_size, int base_display_addr = 0) { if (!ImGui.BeginWindow(title)) { ImGui.EndWindow(); return; } float line_height = ImGuiNative.igGetTextLineHeight(); int line_total_count = (mem_size + Rows - 1) / Rows; ImGuiNative.igSetNextWindowContentSize(new Vector2(0.0f, line_total_count * line_height)); ImGui.BeginChild("##scrolling", new Vector2(0, -ImGuiNative.igGetFrameHeightWithSpacing()), false, 0); ImGui.PushStyleVar(StyleVar.FramePadding, new Vector2(0, 0)); ImGui.PushStyleVar(StyleVar.ItemSpacing, new Vector2(0, 0)); int addr_digits_count = 0; for (int n = base_display_addr + mem_size - 1; n > 0; n >>= 4) { addr_digits_count++; } float glyph_width = ImGui.GetTextSize("F").X; float cell_width = glyph_width * 3; // "FF " we include trailing space in the width to easily catch clicks everywhere var clipper = new ImGuiListClipper(line_total_count, line_height); int visible_start_addr = clipper.DisplayStart * Rows; int visible_end_addr = clipper.DisplayEnd * Rows; bool data_next = false; if (!AllowEdits || DataEditingAddr >= mem_size) { DataEditingAddr = -1; } int data_editing_addr_backup = DataEditingAddr; if (DataEditingAddr != -1) { if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(GuiKey.UpArrow)) && DataEditingAddr >= Rows) { DataEditingAddr -= Rows; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(GuiKey.DownArrow)) && DataEditingAddr < mem_size - Rows) { DataEditingAddr += Rows; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(GuiKey.LeftArrow)) && DataEditingAddr > 0) { DataEditingAddr -= 1; DataEditingTakeFocus = true; } else if (ImGui.IsKeyPressed(ImGui.GetKeyIndex(GuiKey.RightArrow)) && DataEditingAddr < mem_size - 1) { DataEditingAddr += 1; DataEditingTakeFocus = true; } } if ((DataEditingAddr / Rows) != (data_editing_addr_backup / Rows)) { // Track cursor movements float scroll_offset = ((DataEditingAddr / Rows) - (data_editing_addr_backup / Rows)) * line_height; bool scroll_desired = (scroll_offset < 0.0f && DataEditingAddr < visible_start_addr + Rows * 2) || (scroll_offset > 0.0f && DataEditingAddr > visible_end_addr - Rows * 2); if (scroll_desired) { ImGuiNative.igSetScrollY(ImGuiNative.igGetScrollY() + scroll_offset); } } for (int line_i = clipper.DisplayStart; line_i < clipper.DisplayEnd; line_i++) // display only visible items { int addr = line_i * Rows; ImGui.Text(FixedHex(base_display_addr + addr, addr_digits_count) + ": "); ImGui.SameLine(); // Draw Hexadecimal float line_start_x = ImGuiNative.igGetCursorPosX(); for (int n = 0; n < Rows && addr < mem_size; n++, addr++) { ImGui.SameLine(line_start_x + cell_width * n); if (DataEditingAddr == addr) { // Display text input on current byte ImGui.PushID(addr); // FIXME: We should have a way to retrieve the text edit cursor position more easily in the API, this is rather tedious. TextEditCallback callback = (data) => { int *p_cursor_pos = (int *)data->UserData; if (!data->HasSelection()) { *p_cursor_pos = data->CursorPos; } return(0); }; int cursor_pos = -1; bool data_write = false; if (DataEditingTakeFocus) { ImGui.SetKeyboardFocusHere(); ReplaceChars(DataInput, FixedHex(mem_data[addr], 2)); ReplaceChars(AddrInput, FixedHex(base_display_addr + addr, addr_digits_count)); } ImGui.PushItemWidth(ImGui.GetTextSize("FF").X); var flags = InputTextFlags.CharsHexadecimal | InputTextFlags.EnterReturnsTrue | InputTextFlags.AutoSelectAll | InputTextFlags.NoHorizontalScroll | InputTextFlags.AlwaysInsertMode | InputTextFlags.CallbackAlways; if (ImGui.InputText("##data", DataInput, 32, flags, callback, new IntPtr(&cursor_pos))) { data_write = data_next = true; } else if (!DataEditingTakeFocus && !ImGui.IsLastItemActive()) { DataEditingAddr = -1; } DataEditingTakeFocus = false; ImGui.PopItemWidth(); if (cursor_pos >= 2) { data_write = data_next = true; } if (data_write) { int data; if (TryHexParse(DataInput, out data)) { mem_data[addr] = (byte)data; } } ImGui.PopID(); } else { ImGui.Text(FixedHex(mem_data[addr], 2)); if (AllowEdits && ImGui.IsItemHovered(HoveredFlags.Default) && ImGui.IsMouseClicked(0)) { DataEditingTakeFocus = true; DataEditingAddr = addr; } } } ImGui.SameLine(line_start_x + cell_width * Rows + glyph_width * 2); //separator line drawing replaced by printing a pipe char // Draw ASCII values addr = line_i * Rows; var asciiVal = new System.Text.StringBuilder(2 + Rows); asciiVal.Append("| "); for (int n = 0; n < Rows && addr < mem_size; n++, addr++) { int c = mem_data[addr]; asciiVal.Append((c >= 32 && c < 128) ? Convert.ToChar(c) : '.'); } ImGui.TextUnformatted(asciiVal.ToString()); //use unformatted, so string can contain the '%' character } //clipper.End(); //not implemented ImGui.PopStyleVar(2); ImGui.EndChild(); if (data_next && DataEditingAddr < mem_size) { DataEditingAddr = DataEditingAddr + 1; DataEditingTakeFocus = true; } ImGui.Separator(); ImGuiNative.igAlignTextToFramePadding(); ImGui.PushItemWidth(50); ImGuiNative.igPushAllowKeyboardFocus(false); int rows_backup = Rows; if (ImGui.DragInt("##rows", ref Rows, 0.2f, 4, 32, "%.0f rows")) { if (Rows <= 0) { Rows = 4; } Vector2 new_window_size = ImGui.GetWindowSize(); new_window_size.X += (Rows - rows_backup) * (cell_width + glyph_width); ImGui.SetWindowSize(new_window_size); } ImGuiNative.igPopAllowKeyboardFocus(); ImGui.PopItemWidth(); ImGui.SameLine(); ImGui.Text(string.Format(" Range {0}..{1} ", FixedHex(base_display_addr, addr_digits_count), FixedHex(base_display_addr + mem_size - 1, addr_digits_count))); ImGui.SameLine(); ImGui.PushItemWidth(70); if (ImGui.InputText("##addr", AddrInput, 32, InputTextFlags.CharsHexadecimal | InputTextFlags.EnterReturnsTrue, null)) { int goto_addr; if (TryHexParse(AddrInput, out goto_addr)) { goto_addr -= base_display_addr; if (goto_addr >= 0 && goto_addr < mem_size) { ImGui.BeginChild("##scrolling"); ImGuiNative.igSetScrollFromPosY(ImGui.GetCursorStartPos().Y + (goto_addr / Rows) * ImGuiNative.igGetTextLineHeight()); ImGui.EndChild(); DataEditingAddr = goto_addr; DataEditingTakeFocus = true; } } } ImGui.PopItemWidth(); ImGui.EndWindow(); }
private string ChooseFileMainMethod( string directory, bool _isFolderChooserDialog, bool _isSaveFileDialog, string _saveFileName, string fileFilterExtensionString, string windowTitle, Vector2?windowSize, Vector2?windowPos, float windowAlpha ) { //----------------------------------------------------------------------------- Internal I = _internal; string rv = I.chosenPath = ""; //----------------------------------------------------- bool isSelectFolderDialog = I.isSelectFolderDialog = _isFolderChooserDialog; bool isSaveFileDialog = I.isSaveFileDialog = _isSaveFileDialog; bool allowDirectoryCreation = I.allowDirectoryCreation = I.forbidDirectoryCreation ? false : (isSelectFolderDialog || isSaveFileDialog); //---------------------------------------------------------- //---------------------------------------------------------- Style style = ImGui.GetStyle(); Vector4 dummyButtonColor = new Vector4(0.0f, 0.0f, 0.0f, 0.5f); // Only the alpha is twickable from here // Fill ColorSet above and fix dummyButtonColor here { for (int i = 0, sz = (int)Internal.Color.ImGuiCol_Dialog_Directory_Text; i <= sz; i++) { Vector4 r = style.GetColor(i < sz ? (ColorTarget.Button + i) : ColorTarget.Text); Internal.ColorCombine(ref ColorSet[i], r, df); } for (int i = (int)Internal.Color.ImGuiCol_Dialog_File_Background, sz = (int)Internal.Color.ImGuiCol_Dialog_File_Text; i <= sz; i++) { Vector4 r = style.GetColor(i < sz ? (ColorTarget.Button - (int)Internal.Color.ImGuiCol_Dialog_File_Background + i) : ColorTarget.Text); Internal.ColorCombine(ref ColorSet[i], r, ff); } if (dummyButtonColor.W > 0) { Vector4 bbc = style.GetColor(ColorTarget.Button); dummyButtonColor.X = bbc.X; dummyButtonColor.Y = bbc.Y; dummyButtonColor.Z = bbc.Z; dummyButtonColor.W *= bbc.W; } } if (I.rescan) { string validDirectory = "."; if (directory != null && directory.Length > 0) { if (Directory.Exists(directory)) { validDirectory = directory; } else { validDirectory = Path.GetDirectoryName(directory); if (!Directory.Exists(validDirectory)) { validDirectory = "."; } } } I.currentFolder = Path.GetFullPath(validDirectory); I.editLocationCheckButtonPressed = false; I.history.reset(); // reset history I.history.switchTo(I.currentFolder); // init history I.dirs.Clear(); I.files.Clear(); I.dirNames.Clear(); I.fileNames.Clear(); I.currentSplitPath.Clear(); I.newDirectoryName = "New Folder"; if (_saveFileName != null) { //&I.saveFileName[0] = _saveFileName; I.saveFileName = Path.GetFileName(_saveFileName); // Better! } else { I.saveFileName = ""; } isSelectFolderDialog = _isFolderChooserDialog; isSaveFileDialog = _isSaveFileDialog; allowDirectoryCreation = I.forbidDirectoryCreation? false : (isSelectFolderDialog || isSaveFileDialog); if (isSelectFolderDialog && I.sortingMode > (int)Sorting.SORT_ORDER_LAST_MODIFICATION_INVERSE) { I.sortingMode = 0; } I.forceRescan = true; I.open = true; I.filter.Clear(); if (windowTitle == null || windowTitle.Length == 0) { if (isSelectFolderDialog) { I.wndTitle = "Please select a folder"; } else if (isSaveFileDialog) { I.wndTitle = "Please choose/create a file for saving"; } else { I.wndTitle = "Please choose a file"; } } else { I.wndTitle = windowTitle; } I.wndTitle += "##"; // char[] tmpWndTitleNumber = new char[12]; // ImFormatString(tmpWndTitleNumber,11,"%d", I.uniqueNumber); string tmpWndTitleNumber = I.uniqueNumber.ToString(); I.wndTitle += tmpWndTitleNumber; I.wndPos = windowPos ?? new Vector2(); I.wndSize = windowSize ?? new Vector2(); if (I.wndSize.X <= 0) { I.wndSize.X = 400; } if (I.wndSize.Y <= 0) { I.wndSize.Y = 400; } Vector2 mousePos = ImGui.GetMousePos();// ImGui.GetCursorPos(); if (I.wndPos.X <= 0) { I.wndPos.X = mousePos.X - I.wndSize.X * 0.5f; } if (I.wndPos.Y <= 0) { I.wndPos.Y = mousePos.Y - I.wndSize.Y * 0.5f; } Vector2 screenSize = ImGui.GetIO().DisplaySize; if (I.wndPos.X > screenSize.X - I.wndSize.X) { I.wndPos.X = screenSize.X - I.wndSize.X; } if (I.wndPos.Y > screenSize.Y - I.wndSize.Y) { I.wndPos.Y = screenSize.Y - I.wndSize.Y; } if (I.wndPos.X < 0) { I.wndPos.X = 0; } if (I.wndPos.Y < 0) { I.wndPos.Y = 0; } //fprintf(stderr,"screenSize = %f,%f mousePos = %f,%f wndPos = %f,%f wndSize = %f,%f\n",screenSize.X,screenSize.Y,mousePos.X,mousePos.Y,wndPos.X,wndPos.Y,wndSize.X,wndSize.Y); if (I.detectKnownDirectoriesAtEveryOpening) { pUserKnownDirectories = Directory_GetUserKnownDirectories(ref pUserKnownDirectoryDisplayNames, ref pNumberKnownUserDirectoriesExceptDrives, true); } } if (!I.open) { return(rv); } if (I.forceRescan) { I.forceRescan = false; int sortingModeForDirectories = (I.sortingMode <= (int)Sorting.SORT_ORDER_LAST_MODIFICATION_INVERSE) ? I.sortingMode : (I.sortingMode % 2); Directory_GetDirectories(I.currentFolder, ref I.dirs, ref I.dirNames, (Sorting)sortingModeForDirectories); // this is because directories don't return their size or their file extensions (so if needed we sort them alphabetically) //I.dirNames.resize(I.dirs.size());for (int i=0,sz=I.dirs.size();i<sz;i++) Path.GetFileName(I.dirs[i],(char*)I.dirNames[i]); if (!isSelectFolderDialog) { if (fileFilterExtensionString == null || fileFilterExtensionString.Length == 0) { Directory_GetFiles(I.currentFolder, ref I.files, ref I.fileNames, (Sorting)I.sortingMode); } else { Directory_GetFiles(I.currentFolder, ref I.files, fileFilterExtensionString, ref I.fileNames, (Sorting)I.sortingMode); } //I.fileNames.resize(I.files.size());for (int i=0,sz=I.files.size();i<sz;i++) Path.GetFileName(I.files[i],(char*)I.fileNames[i]); } else { I.files.Clear(); I.fileNames.Clear(); I.saveFileName = ""; string currentFolderName = Path.GetFileName(I.currentFolder); int currentFolderNameSize = currentFolderName.Length; if (currentFolderNameSize == 0 || currentFolderName[currentFolderNameSize - 1] == ':') { currentFolderName += "/"; } I.saveFileName += currentFolderName; } I.history.getCurrentSplitPath(ref I.currentSplitPath); const int approxNumEntriesPerColumn = 20;//(int) (20.f / browseSectionFontScale);// tweakable I.totalNumBrowsingEntries = (int)(I.dirs.Count + I.files.Count); I.numBrowsingColumns = I.totalNumBrowsingEntries / approxNumEntriesPerColumn; if (I.numBrowsingColumns <= 0) { I.numBrowsingColumns = 1; } if (I.totalNumBrowsingEntries % approxNumEntriesPerColumn > (approxNumEntriesPerColumn / 2)) { ++I.numBrowsingColumns; } if (I.numBrowsingColumns > 6) { I.numBrowsingColumns = 6; } I.numBrowsingEntriesPerColumn = I.totalNumBrowsingEntries / I.numBrowsingColumns; if (I.totalNumBrowsingEntries % I.numBrowsingColumns != 0) { ++I.numBrowsingEntriesPerColumn; } //# define DEBUG_HISTORY #if DEBUG_HISTORY if (I.history.getInfoSize() > 0) { fprintf(stderr, "\nHISTORY: currentFolder:\"%s\" history.canGoBack=%s history.canGoForward=%s currentHistory:\n", I.currentFolder, I.history.canGoBack()?"true":"false", I.history.canGoForward()?"true":"false"); } if (I.history.getCurrentFolderInfo()) { I.history.getCurrentFolderInfo()->display(); } #endif //DEBUG_HISTORY } if (I.rescan) { I.rescan = false; // Mandatory ImGui.BeginWindow(I.wndTitle, ref I.open, I.wndSize, windowAlpha, WindowFlags.Default); ImGuiNative.igSetWindowPos(I.wndPos, Condition.FirstUseEver); ImGui.SetWindowSize(I.wndSize); //fprintf(stderr,"\"%s\" wndPos={%1.2f,%1.2f}\n",wndTitle.c_str(),wndPos.X,wndPos.Y); } else { ImGui.BeginWindow(I.wndTitle, ref I.open, new Vector2(0, 0), windowAlpha, WindowFlags.Default); } ImGui.Separator(); //------------------------------------------------------------------------------------ // History (=buttons: < and >) { bool historyBackClicked = false; bool historyForwardClicked = false; // history ----------------------------------------------- ImGui.PushID("historyDirectoriesID"); bool historyCanGoBack = I.history.canGoBack(); bool historyCanGoForward = I.history.canGoForward(); if (!historyCanGoBack) { ImGui.PushStyleColor(ColorTarget.Button, dummyButtonColor); ImGui.PushStyleColor(ColorTarget.ButtonHovered, dummyButtonColor); ImGui.PushStyleColor(ColorTarget.ButtonActive, dummyButtonColor); } historyBackClicked = ImGui.Button("<") & historyCanGoBack; ImGui.SameLine(); if (!historyCanGoBack) { ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); } if (!historyCanGoForward) { ImGui.PushStyleColor(ColorTarget.Button, dummyButtonColor); ImGui.PushStyleColor(ColorTarget.ButtonHovered, dummyButtonColor); ImGui.PushStyleColor(ColorTarget.ButtonActive, dummyButtonColor); } historyForwardClicked = ImGui.Button(">") & historyCanGoForward; ImGui.SameLine(); if (!historyCanGoForward) { ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); } ImGui.PopID(); // ------------------------------------------------------- if (historyBackClicked || historyForwardClicked) { ImGui.EndWindow(); if (historyBackClicked) { I.history.goBack(); } else if (historyForwardClicked) { I.history.goForward(); } I.forceRescan = true; I.currentFolder = I.history.getCurrentFolder(); I.editLocationInputText = I.currentFolder; #if DEBUG_HISTORY if (historyBackClicked) { fprintf(stderr, "\nPressed BACK to\t"); } else { fprintf(stderr, "\nPressed FORWARD to\t"); } fprintf(stderr, "\"%s\" (%d)\n", I.currentFolder, (int)*I.history.getCurrentSplitPathIndex()); #undef DEBUG_HISTOTY #endif //DEBUG_HISTORY return(rv); } } //------------------------------------------------------------------------------------ // Edit Location CheckButton bool editLocationInputTextReturnPressed = false; { bool mustValidateInputPath = false; ImGui.PushStyleColor(ColorTarget.Button, I.editLocationCheckButtonPressed? dummyButtonColor : style.GetColor(ColorTarget.Button)); if (ImGui.Button("L##EditLocationCheckButton")) { I.editLocationCheckButtonPressed = !I.editLocationCheckButtonPressed; if (I.editLocationCheckButtonPressed) { I.editLocationInputText = I.currentFolder; ImGui.SetKeyboardFocusHere(); } //if (!I.editLocationCheckButtonPressed) mustValidateInputPath = true; // or not ? I mean: the user wants to quit or to validate in this case ? } ImGui.PopStyleColor(); if (I.editLocationCheckButtonPressed) { ImGui.SameLine(); Encoding.UTF8.GetBytes(I.editLocationInputText, 0, I.editLocationInputText.Length, tmpPathBytes, 0); editLocationInputTextReturnPressed = ImGui.InputText("##EditLocationInputText", tmpPathBytes, MaxPathBytes, InputTextFlags.AutoSelectAll | InputTextFlags.EnterReturnsTrue, null); I.editLocationInputText = Encoding.UTF8.GetString(tmpPathBytes); if (editLocationInputTextReturnPressed) { mustValidateInputPath = true; } else { ImGui.Separator(); } } if (mustValidateInputPath) { // it's better to clean the input path here from trailing slashes: StringBuilder cleanEnteredPathB = new StringBuilder(I.editLocationInputText); int len = cleanEnteredPathB.Length; while (len > 0 && (cleanEnteredPathB[len - 1] == '/' || cleanEnteredPathB[len - 1] == '\\')) { cleanEnteredPathB.Remove(len - 1, 1); len = cleanEnteredPathB.Length; } string cleanEnteredPath = cleanEnteredPathB.ToString(); if (len == 0 || I.currentFolder == cleanEnteredPath) { I.editLocationCheckButtonPressed = false; } else if (Directory.Exists(cleanEnteredPath)) { I.editLocationCheckButtonPressed = false; // Optional (return to split-path buttons) //---------------------------------------------------------------------------------- I.history.switchTo(cleanEnteredPath); I.currentFolder = cleanEnteredPath; I.forceRescan = true; } //else fprintf(stderr,"mustValidateInputPath NOOP: \"%s\" \"%s\"\n",I.currentFolder,cleanEnteredPath); } else { ImGui.SameLine(); } } //------------------------------------------------------------------------------------ // Split Path control if (!I.editLocationCheckButtonPressed && !editLocationInputTextReturnPressed) { bool mustSwitchSplitPath = false; FolderInfo fi = I.history.getCurrentFolderInfo(); Vector2 framePadding = ImGui.GetStyle().FramePadding; float originalFramePaddingX = framePadding.X; framePadding.X = 0; // Split Path // Tab: { //----------------------------------------------------- // TAB LABELS //----------------------------------------------------- { int numTabs = (int)I.currentSplitPath.Count; int newSelectedTab = fi.splitPathIndex; for (int t = 0; t < numTabs; t++) { if (t > 0) { ImGui.SameLine(0, 0); } if (t == fi.splitPathIndex) { ImGui.PushStyleColor(ColorTarget.Button, dummyButtonColor); ImGui.PushStyleColor(ColorTarget.ButtonHovered, dummyButtonColor); ImGui.PushStyleColor(ColorTarget.ButtonActive, dummyButtonColor); } ImGui.PushID(I.currentSplitPath[t]); bool pressed = ImGui.Button(I.currentSplitPath[t]); ImGui.PopID(); if (pressed) { if (fi.splitPathIndex != t && !mustSwitchSplitPath) { mustSwitchSplitPath = true; } newSelectedTab = t; } if (t == fi.splitPathIndex) { ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); } } if (mustSwitchSplitPath) { FolderInfo mfi = null; fi.getFolderInfoForSplitPathIndex(newSelectedTab, ref mfi); I.history.switchTo(mfi); I.forceRescan = true; I.currentFolder = I.history.getCurrentFolder(); I.editLocationInputText = I.currentFolder; //fprintf(stderr,"%s\n",I.currentFolder); } } } framePadding.X = originalFramePaddingX; } //------------------------------------------------------------------------------------ // Start collapsable regions---------------------------------------------------------- // User Known directories------------------------------------------------------------- if (I.allowKnownDirectoriesSection && pUserKnownDirectories.Count > 0) { ImGui.Separator(); if (ImGui.CollapsingHeader("Known Directories##UserKnownDirectories", TreeNodeFlags.CollapsingHeader)) { ImGui.PushID(id); ImGui.PushStyleColor(ColorTarget.Text, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_Directory_Text]); ImGui.PushStyleColor(ColorTarget.Button, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_Directory_Background]); ImGui.PushStyleColor(ColorTarget.ButtonHovered, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_Directory_Hover]); ImGui.PushStyleColor(ColorTarget.ButtonActive, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_Directory_Pressed]); for (int i = 0, sz = (int)pUserKnownDirectories.Count; i < sz; i++) { string userKnownFolder = pUserKnownDirectories[i]; string userKnownFolderDisplayName = pUserKnownDirectoryDisplayNames[i]; if (ImGui.SmallButton(userKnownFolderDisplayName) && userKnownFolder != I.currentFolder) { I.currentFolder = userKnownFolder; I.editLocationInputText = I.currentFolder; I.history.switchTo(I.currentFolder); I.forceRescan = true; //------------------------------------------------------------------------------------------------------------------------------ } if (i != sz - 1 && (i >= pNumberKnownUserDirectoriesExceptDrives || i % 7 != 6)) { ImGui.SameLine(); } } ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopID(); } } // End User Known directories--------------------------------------------------------- // Allow directory creation ---------------------------------------------------------- if (allowDirectoryCreation) { ImGui.Separator(); bool mustCreate = false; if (ImGui.CollapsingHeader("New Directory##allowDirectoryCreation", TreeNodeFlags.CollapsingHeader)) { ImGui.PushID(id); Encoding.UTF8.GetBytes(I.newDirectoryName, 0, I.newDirectoryName.Length, tmpPathBytes, 0); ImGui.InputText("##createNewFolderName", tmpPathBytes, MaxFilenameBytes, InputTextFlags.Default, null); I.newDirectoryName = Encoding.UTF8.GetString(tmpPathBytes); ImGui.SameLine(); mustCreate = ImGui.Button("CREATE"); ImGui.PopID(); } if (mustCreate && I.newDirectoryName.Length > 0) { string newDirPath = Path.Combine(I.currentFolder, I.newDirectoryName); if (!Directory.Exists(newDirPath)) { //# define SIMULATING_ONLY #if SIMULATING_ONLY fprintf(stderr, "creating: \"%s\"\n", newDirPath); #undef SIMULATING_ONLY #else //SIMULATING_ONLY Directory.CreateDirectory(newDirPath); if (!Directory.Exists(newDirPath)) { Console.Error.WriteLine("Error creating new folder: \"{0}\"\n", newDirPath); } else { I.forceRescan = true; // Just update } #endif //SIMULATING_ONLY } } } // End allow directory creation ------------------------------------------------------ // Filtering entries ----------------------------------------------------------------- if (I.allowFiltering) { ImGui.Separator(); if (ImGui.CollapsingHeader("Filtering##fileNameFiltering", TreeNodeFlags.CollapsingHeader)) { ImGui.PushID(id); I.filter.Draw(); ImGui.PopID(); } } // End filtering entries ------------------------------------------------------------- // End collapsable regions------------------------------------------------------------ // Selection field ------------------------------------------------------------------- if (isSaveFileDialog || isSelectFolderDialog) { ImGui.Separator(); bool selectionButtonPressed = false; ImGui.PushID(id); if (isSaveFileDialog) { ImGui.Text("File:"); ImGui.SameLine(); Encoding.UTF8.GetBytes(I.saveFileName, 0, I.saveFileName.Length, tmpPathBytes, 0); ImGui.InputText("##saveFileName", tmpPathBytes, MaxFilenameBytes, InputTextFlags.Default, null); I.saveFileName = Encoding.UTF8.GetString(tmpPathBytes); ImGui.SameLine(); } else { //ImGui.AlignFirstTextHeightToWidgets(); ImGui.Text("Folder:"); ImGui.SameLine(); Vector4 r = style.GetColor(ColorTarget.Text); Internal.ColorCombine(ref ColorSet[(int)Internal.Color.ImGuiCol_Dialog_SelectedFolder_Text], r, sf); ImGuiNative.igTextColored(ColorSet[(int)Internal.Color.ImGuiCol_Dialog_SelectedFolder_Text], I.saveFileName); ImGui.SameLine(); } if (isSelectFolderDialog) { selectionButtonPressed = ImGui.Button("Select"); } else { selectionButtonPressed = ImGui.Button("Save"); } ImGui.PopID(); if (selectionButtonPressed) { if (isSelectFolderDialog) { rv = I.currentFolder; I.open = true; } else if (isSaveFileDialog) { if (I.saveFileName.Length > 0) { bool pathOk = true; if (I.mustFilterSaveFilePathWithFileFilterExtensionString && fileFilterExtensionString != null && fileFilterExtensionString.Length > 0) { pathOk = false; string saveFileNameExtension = Path.GetExtension(I.saveFileName); bool saveFileNameHasExtension = saveFileNameExtension.Length > 0; //------------------------------------------------------------------- string[] wExts = fileFilterExtensionString.Split(';'); int wExtsSize = wExts.Length; if (!saveFileNameHasExtension) { if (wExtsSize == 0) { pathOk = true; // Bad situation, better allow this case } else { I.saveFileName += wExts[0]; } } else { // saveFileNameHasExtension for (int i = 0; i < wExtsSize; i++) { string ext = wExts[i]; if (ext == saveFileNameExtension) { pathOk = true; break; } } if (!pathOk && wExtsSize > 0) { I.saveFileName += wExts[0]; } } } if (pathOk) { string savePath = Path.Combine(I.currentFolder, I.saveFileName); rv = savePath; I.open = true; } } } } //ImGui.Spacing(); } // End selection field---------------------------------------------------------------- ImGui.Separator(); // sorting -------------------------------------------------------------------- ImGui.Text("Sorting by: "); ImGui.SameLine(); { int oldSortingMode = I.sortingMode; int oldSelectedTab = I.sortingMode / 2; //----------------------------------------------------- // TAB LABELS //----------------------------------------------------- { int newSortingMode = oldSortingMode; int numUsedTabs = isSelectFolderDialog ? 2 : numTabs; for (int t = 0; t < numUsedTabs; t++) { if (t > 0) { ImGui.SameLine(); } if (t == oldSelectedTab) { ImGui.PushStyleColor(ColorTarget.Button, dummyButtonColor); } ImGui.PushID(names[t]); bool pressed = ImGui.SmallButton(names[t]); ImGui.PopID(); if (pressed) { if (oldSelectedTab == t) { newSortingMode = oldSortingMode; if (newSortingMode % 2 == 0) { ++newSortingMode; // 0,2,4 } else { --newSortingMode; } } else { newSortingMode = t * 2; } } if (t == oldSelectedTab) { ImGui.PopStyleColor(); } } if (newSortingMode != oldSortingMode) { I.sortingMode = newSortingMode; //printf("sortingMode = %d\n",sortingMode); I.forceRescan = true; } //-- Browsing per row ----------------------------------- if (I.allowDisplayByOption && I.numBrowsingColumns > 1) { ImGui.SameLine(); ImGui.Text(" Display by:"); ImGui.SameLine(); ImGui.PushStyleColor(ColorTarget.Button, dummyButtonColor); if (ImGui.SmallButton(!Internal.BrowsingPerRow? "Column##browsingPerRow" : "Row##browsingPerRow")) { Internal.BrowsingPerRow = !Internal.BrowsingPerRow; } ImGui.PopStyleColor(); } //-- End browsing per row ------------------------------- } } //----------------------------------------------------------------------------- ImGui.Separator(); //----------------------------------------------------------------------------- // MAIN BROWSING FRAME: //----------------------------------------------------------------------------- { ImGui.BeginChild("BrowsingFrame"); // ImGui.SetScrollPosHere(); // possible future ref: while drawing to place the scroll bar ImGui.Columns(I.numBrowsingColumns, null, true); ImGui.PushID(id); int cntEntries = 0; // Directories -------------------------------------------------------------- if (I.dirs.Count > 0) { ImGui.PushStyleColor(ColorTarget.Text, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_Directory_Text]); ImGui.PushStyleColor(ColorTarget.Button, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_Directory_Background]); ImGui.PushStyleColor(ColorTarget.ButtonHovered, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_Directory_Hover]); ImGui.PushStyleColor(ColorTarget.ButtonActive, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_Directory_Pressed]); for (int i = 0, sz = (int)I.dirs.Count; i < sz; i++) { string dirName = I.dirNames[i]; if (I.filter.PassFilter(dirName)) { if (ImGui.SmallButton(dirName)) { I.currentFolder = I.dirs[i]; I.editLocationInputText = I.currentFolder; I.history.switchTo(I.currentFolder); I.forceRescan = true; //------------------------------------------------------------------------------------------------------------------------------ } ++cntEntries; if (Internal.BrowsingPerRow) { ImGui.NextColumn(); } else if (cntEntries == I.numBrowsingEntriesPerColumn) { cntEntries = 0; ImGui.NextColumn(); } } } ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); } // Files ---------------------------------------------------------------------- if (!isSelectFolderDialog && I.files.Count > 0) { ImGui.PushStyleColor(ColorTarget.Text, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_File_Text]); ImGui.PushStyleColor(ColorTarget.Button, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_File_Background]); ImGui.PushStyleColor(ColorTarget.ButtonHovered, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_File_Hover]); ImGui.PushStyleColor(ColorTarget.ButtonActive, ColorSet[(int)Internal.Color.ImGuiCol_Dialog_File_Pressed]); for (int i = 0, sz = (int)I.files.Count; i < sz; i++) { string fileName = I.fileNames[i]; if (I.filter.PassFilter(fileName)) { if (ImGui.SmallButton(fileName)) { if (!isSaveFileDialog) { rv = I.files[i]; I.open = true; } else { I.saveFileName = Path.GetFileName(I.files[i]); } } ++cntEntries; if (Internal.BrowsingPerRow) { ImGui.NextColumn(); } else if (cntEntries == I.numBrowsingEntriesPerColumn) { cntEntries = 0; ImGui.NextColumn(); } } } ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); ImGui.PopStyleColor(); } //----------------------------------------------------------------------------- ImGui.PopID(); ImGui.EndChild(); } //----------------------------------------------------------------------------- ImGui.EndWindow(); return(rv); }
private static unsafe void SubmitUI() { // Demo code adapted from the official Dear ImGui demo program: // https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx11/main.cpp#L172 // 1. Show a simple window. // Tip: if we don't call ImGui.BeginWindow()/ImGui.EndWindow() the widgets automatically appears in a window called "Debug". { ImGui.Text("Hello, world!"); // Display some text (you can use a format string too) ImGui.SliderFloat("float", ref _f, 0, 1, _f.ToString("0.000")); // Edit 1 float using a slider from 0.0f to 1.0f //ImGui.ColorEdit3("clear color", ref _clearColor); // Edit 3 floats representing a color ImGui.Text($"Mouse position: {ImGui.GetMousePos()}"); ImGui.Checkbox("Demo Window", ref _showDemoWindow); // Edit bools storing our windows open/close state ImGui.Checkbox("Another Window", ref _showAnotherWindow); ImGui.Checkbox("Memory Editor", ref _showMemoryEditor); if (ImGui.Button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated) { _counter++; } ImGui.SameLine(0, -1); ImGui.Text($"counter = {_counter}"); ImGui.DragInt("Draggable Int", ref _dragInt); float framerate = ImGui.GetIO().Framerate; ImGui.Text($"Application average {1000.0f / framerate:0.##} ms/frame ({framerate:0.#} FPS)"); } // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name your windows. if (_showAnotherWindow) { ImGui.Begin("Another Window", ref _showAnotherWindow); ImGui.Text("Hello from another window!"); if (ImGui.Button("Close Me")) { _showAnotherWindow = false; } ImGui.End(); } // 3. Show the ImGui demo window. Most of the sample code is in ImGui.ShowDemoWindow(). Read its code to learn more about Dear ImGui! if (_showDemoWindow) { // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. // Here we just want to make the demo initial state a bit more friendly! ImGui.SetNextWindowPos(new Vector2(650, 20), ImGuiCond.FirstUseEver); ImGui.ShowDemoWindow(ref _showDemoWindow); } if (ImGui.TreeNode("Tabs")) { if (ImGui.TreeNode("Basic")) { ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags.None; if (ImGui.BeginTabBar("MyTabBar", tab_bar_flags)) { if (ImGui.BeginTabItem("Avocado")) { ImGui.Text("This is the Avocado tab!\nblah blah blah blah blah"); ImGui.EndTabItem(); } if (ImGui.BeginTabItem("Broccoli")) { ImGui.Text("This is the Broccoli tab!\nblah blah blah blah blah"); ImGui.EndTabItem(); } if (ImGui.BeginTabItem("Cucumber")) { ImGui.Text("This is the Cucumber tab!\nblah blah blah blah blah"); ImGui.EndTabItem(); } ImGui.EndTabBar(); } ImGui.Separator(); ImGui.TreePop(); } if (ImGui.TreeNode("Advanced & Close Button")) { // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0). ImGui.CheckboxFlags("ImGuiTabBarFlags_Reorderable", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.Reorderable); ImGui.CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.AutoSelectNewTabs); ImGui.CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.NoCloseWithMiddleMouseButton); if ((s_tab_bar_flags & (uint)ImGuiTabBarFlags.FittingPolicyMask) == 0) { s_tab_bar_flags |= (uint)ImGuiTabBarFlags.FittingPolicyDefault; } if (ImGui.CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.FittingPolicyResizeDown)) { s_tab_bar_flags &= ~((uint)ImGuiTabBarFlags.FittingPolicyMask ^ (uint)ImGuiTabBarFlags.FittingPolicyResizeDown); } if (ImGui.CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", ref s_tab_bar_flags, (uint)ImGuiTabBarFlags.FittingPolicyScroll)) { s_tab_bar_flags &= ~((uint)ImGuiTabBarFlags.FittingPolicyMask ^ (uint)ImGuiTabBarFlags.FittingPolicyScroll); } // Tab Bar string[] names = { "Artichoke", "Beetroot", "Celery", "Daikon" }; for (int n = 0; n < s_opened.Length; n++) { if (n > 0) { ImGui.SameLine(); } ImGui.Checkbox(names[n], ref s_opened[n]); } // Passing a bool* to BeginTabItem() is similar to passing one to Begin(): the underlying bool will be set to false when the tab is closed. if (ImGui.BeginTabBar("MyTabBar", (ImGuiTabBarFlags)s_tab_bar_flags)) { for (int n = 0; n < s_opened.Length; n++) { if (s_opened[n] && ImGui.BeginTabItem(names[n], ref s_opened[n])) { ImGui.Text($"This is the {names[n]} tab!"); if ((n & 1) != 0) { ImGui.Text("I am an odd tab."); } ImGui.EndTabItem(); } } ImGui.EndTabBar(); } ImGui.Separator(); ImGui.TreePop(); } ImGui.TreePop(); } ImGuiIOPtr io = ImGui.GetIO(); SetThing(out io.DeltaTime, 2f); if (_showMemoryEditor) { _memoryEditor.Draw("Memory Editor", _memoryEditorData, _memoryEditorData.Length); } }
public static void Render() { if (!WindowManager.LootTable) { return; } ImGui.SetNextWindowSize(size, ImGuiCond.Once); if (!ImGui.Begin("Loot Table Editor")) { ImGui.End(); return; } if (ImGui.Button("Save")) { LootTables.Save(); } ImGui.SameLine(); if (ImGui.Button("New##pe")) { ImGui.OpenPopup("Add Item##pe"); } if (selectedTable != null) { ImGui.SameLine(); if (ImGui.Button("Delete")) { LootTables.Defined.Remove(selectedTable); LootTables.Data.Remove(selectedTable); selectedTable = null; } } filter.Draw(""); ImGui.SameLine(); ImGui.Text($"{count}"); if (ImGui.BeginPopupModal("Add Item##pe")) { ImGui.PushItemWidth(300); ImGui.InputText("Id", ref poolName, 64); ImGui.PopItemWidth(); if (ImGui.Button("Add") || Input.Keyboard.WasPressed(Keys.Enter, true)) { selectedTable = poolName; LootTables.Defined[poolName] = new AnyDrop(); LootTables.Data[poolName] = new JsonObject { ["type"] = "any" }; poolName = ""; ImGui.CloseCurrentPopup(); } ImGui.SameLine(); if (ImGui.Button("Cancel") || Input.Keyboard.WasPressed(Keys.Escape, true)) { poolName = ""; ImGui.CloseCurrentPopup(); } ImGui.EndPopup(); } if (selectedTable != null) { ImGui.SameLine(); if (ImGui.Button("Remove##pe")) { LootTables.Defined.Remove(selectedTable); selectedTable = null; } } count = 0; ImGui.Separator(); var height = ImGui.GetStyle().ItemSpacing.Y; ImGui.BeginChild("rolingRegionItems##Pe", new System.Numerics.Vector2(0, -height), false, ImGuiWindowFlags.HorizontalScrollbar); foreach (var i in LootTables.Defined) { ImGui.PushID($"{id}___m"); if (filter.PassFilter(i.Key)) { count++; if (ImGui.Selectable($"{i.Key}##ped", i.Key == selectedTable)) { selectedTable = i.Key; } } ImGui.PopID(); id++; } id = 0; ImGui.EndChild(); ImGui.End(); if (selectedTable == null) { return; } var show = true; ImGui.SetNextWindowSize(size, ImGuiCond.Once); if (!ImGui.Begin("Loot Table", ref show)) { ImGui.End(); return; } if (!show) { selectedTable = null; ImGui.End(); return; } LootTables.RenderDrop(LootTables.Data[selectedTable]); ImGui.End(); }