Active+ Member CONTROL 261 Posted November 2 Active+ Member Share Posted November 2 hi everyone, i would like to share the way that i've been using for the last couple months to deal with the ui in interfacemoudle.py Why ? In the current implementation of UI management in interfacemodule.py, we face several challenges: - Code duplication - Maintenance difficulties - Complexity in adding new elements - Inflexible implementation The Old Implementation The old implementation relies on individual checks for each window: def Close(self): if self.dlgWhisperWithoutTarget: self.dlgWhisperWithoutTarget.Destroy() del self.dlgWhisperWithoutTarget if self.wndChat: self.wndChat.Destroy() if self.wndTaskBar: self.wndTaskBar.Destroy() # ... and so on for each window def HideAllWindows(self): if self.wndTaskBar: self.wndTaskBar.Hide() if self.wndEnergyBar: self.wndEnergyBar.Hide() # ... more windows def __HideWindows(self): hideWindows = self.wndTaskBar,\ self.wndCharacter,\ self.wndInventory,\ self.wndMiniMap,\ self.wndGuild,\ self.wndMessenger,\ # ... more windows Issues with this approach: - Repetitive code patterns - Difficult to add new windows - Risk of forgetting to handle some windows - Hard to track all managed windows - Code maintenance becomes challenging as the UI grows The New Implementation The new implementation introduces a more dynamic and maintainable approach: Spoiler def GetObjTable(self): objTable = [ 'dlgWhisperWithoutTarget', 'wndChat', 'wndTaskBar', 'wndExpandedTaskBar', # ... other windows ] if app.ENABLE_ACCE_SYSTEM: objTable.append('wndAcceCombine') objTable.append('wndAcceAbsorption') return objTable # Handle all windows dynamically def Close(self): def hide_destroy_and_del_attr(obj, attr_name): wnd = getattr(obj, attr_name, None) if wnd: wnd.Hide() wnd.Destroy() delattr(obj, attr_name) if uiQuest.QuestDialog.__dict__.has_key("QuestCurtain"): uiQuest.QuestDialog.QuestCurtain.Close() del uiQuest.QuestDialog.QuestCurtain if self.wndQuestWindow: for eachQuestWindow in self.wndQuestWindow.values(): eachQuestWindow.nextCurtainMode = -1 eachQuestWindow.CloseSelf() eachQuestWindow = None self.wndQuestWindow = {} if constInfo.ENABLE_SAVE_WINDOWS: self.SaveWndChildren() for attr_name in self.GetObjTable(): hide_destroy_and_del_attr(self, attr_name) self.wndChatLog.Destroy() for btn in self.questButtonList: btn.SetEvent(0) self.DestroyAllQuestButtons() for btn in self.whisperButtonList: btn.SetEvent(0) self.DestroyAllWhisperButtons() for dlg in self.whisperDialogDict.values(): dlg.Destroy() for brd in self.guildScoreBoardDict.values(): brd.Destroy() for dlg in self.equipmentDialogDict.values(): dlg.Destroy() self.questButtonList = [] self.whisperButtonList = [] self.whisperDialogDict = {} self.guildScoreBoardDict = {} self.equipmentDialogDict = {} uiChat.DestroyChatInputSetWindow() def HideAllWindows(self): for attr_name in self.GetObjTable(): wnd = getattr(self, attr_name, None) if wnd: wnd.Hide() def __HideWindows(self): hideWindows = [] for attr_name in self.GetObjTable(): wnd = getattr(self, attr_name, None) if wnd: hideWindows.append(wnd) hideWindows = filter(lambda x:x.IsShow(), hideWindows) map(lambda x:x.Hide(), hideWindows) self.HideAllQuestButton() self.HideAllWhisperButton() if self.wndChat.IsEditMode(): self.wndChat.CloseChat() self.wndMiniMap.AtlasWindow.Hide() return hideWindows Advantages of the New Approach: - Centralized Window Management: All UI elements are defined in one place (GetObjTable) - Easy to Extend: Adding new windows only requires adding them to the objTable list - DRY (Don't Repeat Yourself): Common operations are handled by reusable functions - Maintainable: Less code duplication means fewer places to fix bugs - Flexible: Conditional UI elements can be easily added based on features/flags - Consistent Behavior: All windows are handled in the same way Implementation Details: - GetObjTable: Maintains a central list of all UI elements - hide_destroy_and_del_attr: Helper function for common window operations - Conditional additions based on feature flags (e.g., ENABLE_ACCE_SYSTEM) - Special cases are still handled separately when needed Usage and Extension To add a new window to the system: - Add the window name to GetObjTable - The window will automatically be included in all common operations (Close, Hide, etc.) - Special handling can be added if needed - This refactoring significantly improves code maintainability and makes the system more flexible for future additions and modifications. Ciao 18 1 1 2 1 6 Link to comment Share on other sites More sharing options...
Premium jking 191 Posted November 3 Premium Share Posted November 3 Good, small thing that can make our lives easier. Thanks for the release. Link to comment Share on other sites More sharing options...
Recommended Posts