diff --git a/MareSynchronos/UI/CompactUI.cs b/MareSynchronos/UI/CompactUI.cs index 5b1720a..3f765d7 100644 --- a/MareSynchronos/UI/CompactUI.cs +++ b/MareSynchronos/UI/CompactUI.cs @@ -160,7 +160,7 @@ public class CompactUi : Window, IDisposable _lastAddedUserComment = string.Empty; } - if (ImGui.BeginPopupModal("Set Notes for New User", ref _showModalForUserAddition, ImGuiWindowFlags.AlwaysAutoResize)) + if (ImGui.BeginPopupModal("Set Notes for New User", ref _showModalForUserAddition, UiShared.PopupWindowFlags)) { if (_lastAddedUser == null) { @@ -180,6 +180,7 @@ public class CompactUi : Window, IDisposable _showModalForUserAddition = false; } } + UiShared.SetScaledWindowSize(275); ImGui.EndPopup(); } } @@ -477,14 +478,15 @@ public class CompactUi : Window, IDisposable string shardConnection = string.Equals(_apiController.ServerInfo.ShardName, "Main", StringComparison.OrdinalIgnoreCase) ? string.Empty : $"Shard: {_apiController.ServerInfo.ShardName}"; #endif var shardTextSize = ImGui.CalcTextSize(shardConnection); + var printShard = !string.IsNullOrEmpty(_apiController.ServerInfo.ShardName) && shardConnection != string.Empty; if (_apiController.ServerState is ServerState.Connected) { - ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X) / 2 - (userSize.X + textSize.X) / 2); - ImGui.AlignTextToFramePadding(); + ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X) / 2 - (userSize.X + textSize.X) / 2 - ImGui.GetStyle().ItemSpacing.X / 2); + if (!printShard) ImGui.AlignTextToFramePadding(); ImGui.TextColored(ImGuiColors.ParsedGreen, userCount); ImGui.SameLine(); - ImGui.AlignTextToFramePadding(); + if (!printShard) ImGui.AlignTextToFramePadding(); ImGui.Text("Users Online"); } else @@ -492,8 +494,19 @@ public class CompactUi : Window, IDisposable ImGui.AlignTextToFramePadding(); ImGui.TextColored(ImGuiColors.DalamudRed, "Not connected to any server"); } + + if (printShard) + { + ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().ItemSpacing.Y); + ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X) / 2 - shardTextSize.X / 2); + ImGui.TextUnformatted(shardConnection); + } ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - buttonSize.X); + if (printShard) + { + ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ((userSize.Y + textSize.Y) / 2 + shardTextSize.Y) / 2 - ImGui.GetStyle().ItemSpacing.Y + buttonSize.Y / 2); + } var color = UiShared.GetBoolColor(!_configuration.FullPause); var connectedIcon = !_configuration.FullPause ? FontAwesomeIcon.Link : FontAwesomeIcon.Unlink; @@ -506,12 +519,6 @@ public class CompactUi : Window, IDisposable } ImGui.PopStyleColor(); UiShared.AttachToolTip(!_configuration.FullPause ? "Disconnect from " + _apiController.ServerDictionary[_configuration.ApiUri] : "Connect to " + _apiController.ServerDictionary[_configuration.ApiUri]); - - if (!string.IsNullOrEmpty(_apiController.ServerInfo.ShardName)) - { - ImGui.SetCursorPosX((ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth()) / 2 - shardTextSize.X / 2); - ImGui.TextUnformatted(shardConnection); - } } private void DrawTransfers() diff --git a/MareSynchronos/UI/GroupPanel.cs b/MareSynchronos/UI/GroupPanel.cs index 45e17e0..a51ec51 100644 --- a/MareSynchronos/UI/GroupPanel.cs +++ b/MareSynchronos/UI/GroupPanel.cs @@ -95,11 +95,12 @@ namespace MareSynchronos.UI ? (userCanCreateMoreGroups ? "Create Syncshell" : $"You cannot create more than {_apiController.ServerInfo.MaxGroupsCreatedByUser} Syncshells") : (userCanJoinMoreGroups ? "Join Syncshell" + _syncShellToJoin : $"You cannot join more than {_apiController.ServerInfo.MaxGroupsJoinedByUser} Syncshells")); - if (ImGui.BeginPopupModal("Enter Syncshell Password", ref _showModalEnterPassword, ImGuiWindowFlags.AlwaysAutoResize)) + if (ImGui.BeginPopupModal("Enter Syncshell Password", ref _showModalEnterPassword, UiShared.PopupWindowFlags)) { UiShared.TextWrapped("Before joining any Syncshells please be aware that you will be automatically paired with everyone in the Syncshell."); ImGui.Separator(); UiShared.TextWrapped("Enter the password for Syncshell " + _syncShellToJoin + ":"); + ImGui.SetNextItemWidth(-1); ImGui.InputTextWithHint("##password", _syncShellToJoin + " Password", ref _syncShellPassword, 255, ImGuiInputTextFlags.Password); if (_errorGroupJoin) { @@ -119,12 +120,12 @@ namespace MareSynchronos.UI } _syncShellPassword = string.Empty; } + UiShared.SetScaledWindowSize(290); ImGui.EndPopup(); } - if (ImGui.BeginPopupModal("Create Syncshell", ref _showModalCreateGroup)) + if (ImGui.BeginPopupModal("Create Syncshell", ref _showModalCreateGroup, UiShared.PopupWindowFlags)) { - ImGui.SetWindowSize(new(400, 200)); UiShared.TextWrapped("Press the button below to create a new Syncshell."); ImGui.SetNextItemWidth(200); if (ImGui.Button("Create Syncshell")) @@ -145,6 +146,7 @@ namespace MareSynchronos.UI ImGui.Separator(); _errorGroupCreate = false; ImGui.TextUnformatted("Syncshell ID: " + _lastCreatedGroup.GID); + ImGui.AlignTextToFramePadding(); ImGui.TextUnformatted("Syncshell Password: " + _lastCreatedGroup.Password); ImGui.SameLine(); if (ImGuiComponents.IconButton(FontAwesomeIcon.Copy)) @@ -160,6 +162,7 @@ namespace MareSynchronos.UI new Vector4(1, 0, 0, 1)); } + UiShared.SetScaledWindowSize(350); ImGui.EndPopup(); } @@ -292,15 +295,14 @@ namespace MareSynchronos.UI if (!_showModalBanList) _modalBanListOpened = false; - if (ImGui.BeginPopupModal("Manage Banlist for " + group.GID, ref _showModalBanList)) + if (ImGui.BeginPopupModal("Manage Banlist for " + group.GID, ref _showModalBanList, UiShared.PopupWindowFlags)) { - ImGui.SetWindowSize(new Vector2(700, 300)); if (UiShared.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server")) { _bannedUsers = _apiController.GetBannedUsersForGroup(group.GID).Result; } - if (ImGui.BeginTable("bannedusertable" + group.GID, 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingStretchProp)) + if (ImGui.BeginTable("bannedusertable" + group.GID, 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.ScrollY)) { ImGui.TableSetupColumn("UID", ImGuiTableColumnFlags.None, 1); ImGui.TableSetupColumn("By", ImGuiTableColumnFlags.None, 1); @@ -326,11 +328,11 @@ namespace MareSynchronos.UI _ = _apiController.UnbanUserFromGroup(group.GID, bannedUser.UID); _bannedUsers.RemoveAll(b => string.Equals(b.UID, bannedUser.UID, StringComparison.Ordinal)); } - ImGui.TableNextColumn(); } ImGui.EndTable(); } + UiShared.SetScaledWindowSize(700, 300); ImGui.EndPopup(); } @@ -343,10 +345,11 @@ namespace MareSynchronos.UI if (!_showModalChangePassword) _modalChangePwOpened = false; - if (ImGui.BeginPopupModal("Change Syncshell Password", ref _showModalChangePassword, ImGuiWindowFlags.AlwaysAutoResize)) + if (ImGui.BeginPopupModal("Change Syncshell Password", ref _showModalChangePassword, UiShared.PopupWindowFlags)) { UiShared.TextWrapped("Enter the new Syncshell password for Syncshell " + name + " here."); UiShared.TextWrapped("This action is irreversible"); + ImGui.SetNextItemWidth(-1); ImGui.InputTextWithHint("##changepw", "New password for " + name, ref _newSyncShellPassword, 255); if (ImGui.Button("Change password")) { @@ -361,6 +364,7 @@ namespace MareSynchronos.UI UiShared.ColorTextWrapped("The selected password is too short. It must be at least 10 characters.", new Vector4(1, 0, 0, 1)); } + UiShared.SetScaledWindowSize(290); ImGui.EndPopup(); } @@ -394,15 +398,17 @@ namespace MareSynchronos.UI bool invitesEnabled = entry.InvitesEnabled ?? true; var lockedIcon = invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock; var iconSize = UiShared.GetIconSize(lockedIcon); + var diffLockUnlockIcons = invitesEnabled ? 0 : (UiShared.GetIconSize(FontAwesomeIcon.LockOpen).X - iconSize.X) / 2; var barbuttonSize = UiShared.GetIconButtonSize(FontAwesomeIcon.Bars); var isOwner = string.Equals(entry.OwnedBy, _apiController.UID, StringComparison.Ordinal); - ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - barbuttonSize.X - iconSize.X - ImGui.GetStyle().ItemSpacing.X); + ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - barbuttonSize.X - iconSize.X - diffLockUnlockIcons - ImGui.GetStyle().ItemSpacing.X); ImGui.PushFont(UiBuilder.IconFont); ImGui.Text(lockedIcon.ToIconString()); ImGui.PopFont(); UiShared.AttachToolTip(invitesEnabled ? "Syncshell is open for new joiners" : "Syncshell is closed for new joiners"); ImGui.SameLine(); + ImGui.SetCursorPosX(ImGui.GetCursorPosX() + diffLockUnlockIcons); if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars)) { ImGui.OpenPopup("ShellPopup"); @@ -440,7 +446,8 @@ namespace MareSynchronos.UI if (isOwner) { - if (UiShared.IconTextButton(lockedIcon, invitesEnabled ? "Lock Syncshell" : "Unlock Syncshell")) + var changedToIcon = !invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock; + if (UiShared.IconTextButton(changedToIcon, invitesEnabled ? "Lock Syncshell" : "Unlock Syncshell")) { ImGui.CloseCurrentPopup(); _ = _apiController.SendGroupChangeInviteState(entry.GID, !entry.InvitesEnabled ?? true); @@ -471,7 +478,7 @@ namespace MareSynchronos.UI { ImGui.CloseCurrentPopup(); _showModalBanList = true; - _bannedUsers = new(); + _bannedUsers = _apiController.GetBannedUsersForGroup(entry.GID).Result; } if (isOwner) @@ -622,7 +629,10 @@ namespace MareSynchronos.UI if (plusButtonShown) { ImGui.SetCursorPosY(originalY); - ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - plusButtonSize.X - (isOwner ? barButtonSize.X + ImGui.GetStyle().ItemSpacing.X : 0)); + var barWidth = isOwner || (isModerator && !userIsMod && !userIsOwner) + ? barButtonSize.X + ImGui.GetStyle().ItemSpacing.X + : 0; + ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - plusButtonSize.X - barWidth); if (ImGuiComponents.IconButton(FontAwesomeIcon.Plus)) { @@ -634,7 +644,6 @@ namespace MareSynchronos.UI if (isOwner || (isModerator && !userIsMod && !userIsOwner)) { ImGui.SetCursorPosY(originalY); - var subtractedWidth = plusButtonShown ? (plusButtonSize.X) : 0; ImGui.SameLine(ImGui.GetWindowContentRegionMin().X + UiShared.GetWindowContentRegionWidth() - barButtonSize.X); if (ImGuiComponents.IconButton(FontAwesomeIcon.Bars)) @@ -699,6 +708,12 @@ namespace MareSynchronos.UI ImGui.EndPopup(); } + if (!plusButtonShown && !(isOwner || (isModerator && !userIsMod && !userIsOwner))) + { + ImGui.SameLine(); + ImGui.Dummy(barButtonSize with { X = 0 }); + } + if (_showModalBanUser && !_banUserPopupOpen) { ImGui.OpenPopup("Ban User"); @@ -707,9 +722,8 @@ namespace MareSynchronos.UI if (!_showModalBanUser) _banUserPopupOpen = false; - if (ImGui.BeginPopupModal("Ban User", ref _showModalBanUser)) + if (ImGui.BeginPopupModal("Ban User", ref _showModalBanUser, UiShared.PopupWindowFlags)) { - ImGui.SetWindowSize(new Vector2(300, 200)); UiShared.TextWrapped("User " + (entry.UserAlias ?? entry.UserUID) + " will be banned and removed from this Syncshell."); ImGui.InputTextWithHint("##banreason", "Ban Reason", ref _banReason, 255); if (ImGui.Button("Ban User")) @@ -720,6 +734,7 @@ namespace MareSynchronos.UI _banReason = string.Empty; } UiShared.TextWrapped("The reason will be displayed in the banlist. The current server-side alias if present (Vanity ID) will automatically be attached to the reason."); + UiShared.SetScaledWindowSize(300); ImGui.EndPopup(); } } diff --git a/MareSynchronos/UI/SettingsUi.cs b/MareSynchronos/UI/SettingsUi.cs index cbfb3ab..53958aa 100644 --- a/MareSynchronos/UI/SettingsUi.cs +++ b/MareSynchronos/UI/SettingsUi.cs @@ -431,28 +431,31 @@ public class SettingsUi : Window, IDisposable UiShared.DrawHelpText("Completely deletes all your uploaded files on the service."); - if (ImGui.BeginPopupModal("Delete all your files?", ref _deleteFilesPopupModalShown, - ImGuiWindowFlags.AlwaysAutoResize)) + if (ImGui.BeginPopupModal("Delete all your files?", ref _deleteFilesPopupModalShown, UiShared.PopupWindowFlags)) { UiShared.TextWrapped( "All your own uploaded files on the service will be deleted.\nThis operation cannot be undone."); ImGui.Text("Are you sure you want to continue?"); ImGui.Separator(); - if (ImGui.Button("Delete everything", new Vector2(150, 0))) + ImGui.Spacing(); + + var buttonSize = (ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X - + ImGui.GetStyle().ItemSpacing.X) / 2; + + if (ImGui.Button("Delete everything", new Vector2(buttonSize, 0))) { Task.Run(() => _apiController.DeleteAllMyFiles()); - ImGui.CloseCurrentPopup(); _deleteFilesPopupModalShown = false; } ImGui.SameLine(); - if (ImGui.Button("Cancel##cancelDelete", new Vector2(150, 0))) + if (ImGui.Button("Cancel##cancelDelete", new Vector2(buttonSize, 0))) { - ImGui.CloseCurrentPopup(); _deleteFilesPopupModalShown = false; } + UiShared.SetScaledWindowSize(325); ImGui.EndPopup(); } @@ -464,30 +467,33 @@ public class SettingsUi : Window, IDisposable UiShared.DrawHelpText("Completely deletes your account and all uploaded files to the service."); - if (ImGui.BeginPopupModal("Delete your account?", ref _deleteAccountPopupModalShown, - ImGuiWindowFlags.AlwaysAutoResize)) + if (ImGui.BeginPopupModal("Delete your account?", ref _deleteAccountPopupModalShown, UiShared.PopupWindowFlags)) { UiShared.TextWrapped( "Your account and all associated files and data on the service will be deleted."); UiShared.TextWrapped("Your UID will be removed from all pairing lists."); ImGui.Text("Are you sure you want to continue?"); ImGui.Separator(); - if (ImGui.Button("Delete account", new Vector2(150, 0))) + ImGui.Spacing(); + + var buttonSize = (ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X - + ImGui.GetStyle().ItemSpacing.X) / 2; + + if (ImGui.Button("Delete account", new Vector2(buttonSize, 0))) { Task.Run(() => _apiController.DeleteAccount()); - ImGui.CloseCurrentPopup(); _deleteAccountPopupModalShown = false; SwitchToIntroUi?.Invoke(); } ImGui.SameLine(); - if (ImGui.Button("Cancel##cancelDelete", new Vector2(150, 0))) + if (ImGui.Button("Cancel##cancelDelete", new Vector2(buttonSize, 0))) { - ImGui.CloseCurrentPopup(); _deleteAccountPopupModalShown = false; } + UiShared.SetScaledWindowSize(325); ImGui.EndPopup(); } } diff --git a/MareSynchronos/UI/UIShared.cs b/MareSynchronos/UI/UIShared.cs index 3940aba..341e35e 100644 --- a/MareSynchronos/UI/UIShared.cs +++ b/MareSynchronos/UI/UIShared.cs @@ -41,6 +41,10 @@ public class UiShared : IDisposable public bool UidFontBuilt { get; private set; } public static bool CtrlPressed() => (GetKeyState(0xA2) & 0x8000) != 0 || (GetKeyState(0xA3) & 0x8000) != 0; public static bool ShiftPressed() => (GetKeyState(0xA1) & 0x8000) != 0 || (GetKeyState(0xA0) & 0x8000) != 0; + + public static ImGuiWindowFlags PopupWindowFlags = ImGuiWindowFlags.NoResize | + ImGuiWindowFlags.NoScrollbar | + ImGuiWindowFlags.NoScrollWithMouse; public ApiController ApiController => _apiController; @@ -98,6 +102,38 @@ public class UiShared : IDisposable } } + public static void SetScaledWindowSize(float width, bool centerWindow = true) + { + var newLineHeight = ImGui.GetCursorPosY(); + ImGui.NewLine(); + newLineHeight = ImGui.GetCursorPosY() - newLineHeight; + var x = width * ImGuiHelpers.GlobalScale; + var y = ImGui.GetCursorPos().Y + ImGui.GetWindowContentRegionMin().Y - newLineHeight * 2 - ImGui.GetStyle().ItemSpacing.Y; + + if (centerWindow) + { + var center = ImGui.GetMainViewport().GetCenter(); + ImGui.SetWindowPos(new Vector2(center.X - x / 2, center.Y - y / 2)); + } + + ImGui.SetWindowSize(new Vector2(x, y)); + } + + public static void SetScaledWindowSize(float width, float height, bool centerWindow = true) + { + ImGui.SameLine(); + var x = width * ImGuiHelpers.GlobalScale; + var y = height * ImGuiHelpers.GlobalScale; + + if (centerWindow) + { + var center = ImGui.GetMainViewport().GetCenter(); + ImGui.SetWindowPos(new Vector2(center.X - x / 2, center.Y - y / 2)); + } + + ImGui.SetWindowSize(new Vector2(x, y)); + } + public static void DrawWithID(string id, Action drawSubSection) { ImGui.PushID(id); @@ -569,23 +605,19 @@ public class UiShared : IDisposable var buttonSizeY = (iconSize.Y > textSize.Y ? iconSize.Y : textSize.Y) + padding.Y * 2; var buttonSize = new Vector2(buttonSizeX, buttonSizeY); - if (ImGui.BeginChild(icon.ToIconString() + text, buttonSize)) + if (ImGui.Button("###" + icon.ToIconString() + text, buttonSize)) { - if (ImGui.Button("", buttonSize)) - { - buttonClicked = true; - } - - ImGui.SameLine(); - ImGui.SetCursorPosX(padding.X); - ImGui.PushFont(UiBuilder.IconFont); - ImGui.Text(icon.ToIconString()); - ImGui.PopFont(); - ImGui.SameLine(); - ImGui.Text(text); - ImGui.EndChild(); + buttonClicked = true; } + ImGui.SameLine(); + ImGui.SetCursorPosX(ImGui.GetCursorPosX() - buttonSize.X - padding.X); + ImGui.PushFont(UiBuilder.IconFont); + ImGui.Text(icon.ToIconString()); + ImGui.PopFont(); + ImGui.SameLine(); + ImGui.Text(text); + return buttonClicked; }