Jump to content
Maintenance : Final step ×

UI Renewal/Improve


Recommended Posts

  • Active+ Member

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

  • Metin2 Dev 18
  • Eyes 1
  • Dislove 1
  • Good 2
  • Love 1
  • Love 6
Link to comment
Share on other sites

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.