Index: binaries/data/mods/public/gui/common/AlignmentHelper.js =================================================================== --- /dev/null +++ binaries/data/mods/public/gui/common/AlignmentHelper.js @@ -0,0 +1,51 @@ +/** + * This is a helper class to align edges of a set of GUIObjects. + * The class is designed to either vertically or horizontally align the GUIObjects. + */ +class AlignmentHelper +{ + /** + * @param {string} direction - Either min or max. Deciding whether we should move all objects to the minimal (left-most) or maximal (right-most) position. + */ + constructor(direction) + { + if (direction != "max" && direction != "min") + error("Invalid alignment direction."); + + this.direction = direction; + // An Object of Objects of Objects containing per direction the GUIObjects and their requested positions. + this.objectData = {}; + + this.defaultValue = this.direction == "max" ? -Infinity : Infinity; + } + + /** + * @param {Object} GUIObject - A GUIObject to be aligned. + * @param {string} edge - Either left or right. Determining the edge to change position for this object. + * @param {number} wantedPosition - The requested position of the edge. + */ + addObject(GUIObject, edge, wantedPosition = this.defaultValue) + { + this.objectData[GUIObject.name] = { + "GUIObject": GUIObject, + "edge": edge, + "wantedPosition": wantedPosition + }; + + this.align(); + } + + align() + { + let value = this.defaultValue; + for (const objectName in this.objectData) + value = Math[this.direction](value, this.objectData[objectName].wantedPosition); + + for (const objectName in this.objectData) + { + const objectSize = this.objectData[objectName].GUIObject.size; + objectSize[this.objectData[objectName].edge] = value; + this.objectData[objectName].GUIObject.size = objectSize; + } + } +} Index: binaries/data/mods/public/gui/common/functions_utility.js =================================================================== --- binaries/data/mods/public/gui/common/functions_utility.js +++ binaries/data/mods/public/gui/common/functions_utility.js @@ -221,6 +221,29 @@ } /** + * Change the width of a GUIObject to make the caption fits nicely. + * @param object - The GUIObject to consider. + * @param direction - Direction to change the side either "left" or "right". + * @param margin - Margin to be added to the width (can be negative). + */ +function resizeGUIObjectToCaption(object, align, margin = 0) +{ + const objectSize = object.size; + const width = Engine.GetTextWidth(object.font, object.caption) + margin + switch (align) + { + case "right": + objectSize.right = object.size.left + width; + break; + case "left": + objectSize.left = object.size.right - width; + break; + default: + } + object.size = objectSize; +} + +/** * Hide all children after a certain index */ function hideRemaining(parentName, start = 0) Index: binaries/data/mods/public/gui/session/chat/Chat.js =================================================================== --- binaries/data/mods/public/gui/session/chat/Chat.js +++ binaries/data/mods/public/gui/session/chat/Chat.js @@ -12,13 +12,15 @@ this.ChatHistory = new ChatHistory(); this.ChatHistory.registerSelectionChangeHandler(this.ChatWindow.onSelectionChange.bind(this.ChatWindow)); - this.ChatInput = new ChatInput(); + const alignmentHelper = new AlignmentHelper("max"); + + this.ChatInput = new ChatInput(alignmentHelper); this.ChatInput.registerChatSubmitHandler(executeNetworkCommand); this.ChatInput.registerChatSubmitHandler(cheats.executeCheat.bind(cheats)); this.ChatInput.registerChatSubmitHandler(this.submitChat.bind(this)); this.ChatInput.registerChatSubmittedHandler(this.closePage.bind(this)); - this.ChatAddressees = new ChatAddressees(); + this.ChatAddressees = new ChatAddressees(alignmentHelper); this.ChatAddressees.registerSelectionChangeHandler(this.ChatInput.onSelectionChange.bind(this.ChatInput)); this.ChatAddressees.registerSelectionChangeHandler(this.ChatWindow.onSelectionChange.bind(this.ChatWindow)); Index: binaries/data/mods/public/gui/session/chat/ChatAddressees.js =================================================================== --- binaries/data/mods/public/gui/session/chat/ChatAddressees.js +++ binaries/data/mods/public/gui/session/chat/ChatAddressees.js @@ -3,12 +3,17 @@ */ class ChatAddressees { - constructor() + constructor(alignmentHelper) { this.selectionChangeHandlers = []; + this.chatAddresseeCaption = Engine.GetGUIObjectByName("chatAddresseeCaption"); + resizeGUIObjectToCaption(this.chatAddresseeCaption, "right", this.CaptionMargin); + this.chatAddressee = Engine.GetGUIObjectByName("chatAddressee"); this.chatAddressee.onSelectionChange = this.onSelectionChange.bind(this); + + alignmentHelper.addObject(this.chatAddressee, "left", this.chatAddresseeCaption.size.right + this.DropdownMargin); } registerSelectionChangeHandler(handler) @@ -125,3 +130,6 @@ "isAddressee": (senderID, addresseeGUID) => addresseeGUID == Engine.GetPlayerGUID() } ]; + +ChatAddressees.prototype.CaptionMargin = 10; +ChatAddressees.prototype.DropdownMargin = 5; Index: binaries/data/mods/public/gui/session/chat/ChatHistory.js =================================================================== --- binaries/data/mods/public/gui/session/chat/ChatHistory.js +++ binaries/data/mods/public/gui/session/chat/ChatHistory.js @@ -13,6 +13,9 @@ this.selectionChangeHandlers = []; + this.chatHistoryFilterCaption = Engine.GetGUIObjectByName("chatHistoryFilterCaption"); + resizeGUIObjectToCaption(this.chatHistoryFilterCaption, "right", this.CaptionMargin); + this.chatHistoryFilter = Engine.GetGUIObjectByName("chatHistoryFilter"); let filters = prepareForDropdown(this.Filters.filter(chatFilter => !chatFilter.hidden)); this.chatHistoryFilter.list = filters.text.map(text => translateWithContext("chat history filter", text)); @@ -20,6 +23,10 @@ this.chatHistoryFilter.selected = 0; this.chatHistoryFilter.onSelectionChange = this.onSelectionChange.bind(this); + const chatHistoryFilterSize = this.chatHistoryFilter.size; + chatHistoryFilterSize.left = this.chatHistoryFilterCaption.size.right + this.CaptionToFilterMargin; + this.chatHistoryFilter.size = chatHistoryFilterSize; + this.chatHistoryText = Engine.GetGUIObjectByName("chatHistoryText"); } @@ -132,3 +139,6 @@ "hidden": !Engine.HasNetClient() } ]; + +ChatHistory.prototype.CaptionMargin = 10; +ChatHistory.prototype.CaptionToFilterMargin = 5; Index: binaries/data/mods/public/gui/session/chat/ChatInput.js =================================================================== --- binaries/data/mods/public/gui/session/chat/ChatInput.js +++ binaries/data/mods/public/gui/session/chat/ChatInput.js @@ -3,16 +3,21 @@ */ class ChatInput { - constructor() + constructor(alignmentHelper) { this.selectedCommand = ""; this.chatSubmitHandlers = []; this.chatSubmittedHandlers = []; + this.chatInputCaption = Engine.GetGUIObjectByName("chatInputCaption"); + resizeGUIObjectToCaption(this.chatInputCaption, "right", this.CaptionMargin); + this.chatInput = Engine.GetGUIObjectByName("chatInput"); this.chatInput.onPress = this.submitChatInput.bind(this); this.chatInput.onTab = this.autoComplete.bind(this); + alignmentHelper.addObject(this.chatInput, "left", this.chatInputCaption.size.right + this.InputMargin); + this.sendChat = Engine.GetGUIObjectByName("sendChat"); this.sendChat.onPress = this.submitChatInput.bind(this); @@ -88,3 +93,6 @@ handler(); } } + +ChatInput.prototype.CaptionMargin = 10; +ChatInput.prototype.InputMargin = 5; Index: binaries/data/mods/public/gui/session/chat/chat_window.xml =================================================================== --- binaries/data/mods/public/gui/session/chat/chat_window.xml +++ binaries/data/mods/public/gui/session/chat/chat_window.xml @@ -15,7 +15,7 @@ - + Filter: @@ -42,7 +42,7 @@ - + To: - + Text: