Improve widescreen support across all GUIs
Key features implemented: - Modified ToonBase.py to add dynamic FOV adjustment and GUI positioning methods for widescreen compatibility - Updated RewardPanel.py to use new getGUIEdgePos method for proper skip button alignment in widescreen - Enhanced SuitAvatarPanel.py with widescreen-aware positioning for detail panel - Adapted PlayerInfoPanel.py to use new GUI positioning system for proper edge alignment - Improved ToonAvatarPanel.py with widescreen-compatible frame positioning - Updated TownBattle.py to use widescreen-aware timer positioning
This commit is contained in:
parent
41cd200178
commit
80eef05754
|
|
@ -1,25 +1,72 @@
|
|||
```
|
||||
# Compiled and build artifacts
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
*.log
|
||||
resources/
|
||||
news/
|
||||
sign/
|
||||
whitelist/
|
||||
__pycache__/
|
||||
*.o
|
||||
*.obj
|
||||
*.class
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.DS_Store
|
||||
*.jpg
|
||||
.idea
|
||||
*.a
|
||||
*.out
|
||||
|
||||
# Dependencies
|
||||
.venv/
|
||||
venv/
|
||||
*.json
|
||||
!win32/.vscode/tasks.json
|
||||
!linux/.vscode/tasks.json
|
||||
!darwin/.vscode/tasks.json
|
||||
*.buildings
|
||||
*.trackRecords
|
||||
PPYTHON_PATH
|
||||
local/
|
||||
errorCode
|
||||
panda3d/
|
||||
PPYTHON_PATH
|
||||
PPYTHON_PATH
|
||||
node_modules/
|
||||
dist/
|
||||
build/
|
||||
target/
|
||||
.gradle/
|
||||
.mypy_cache/
|
||||
.pytest_cache/
|
||||
|
||||
# Logs and temp files
|
||||
*.log
|
||||
*.tmp
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.env.local
|
||||
*.env.*
|
||||
|
||||
# Editors
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Coverage
|
||||
coverage/
|
||||
htmlcov/
|
||||
.coverage
|
||||
|
||||
# Compressed files
|
||||
*.zip
|
||||
*.gz
|
||||
*.tar
|
||||
*.tgz
|
||||
*.bz2
|
||||
*.xz
|
||||
*.7z
|
||||
*.rar
|
||||
*.zst
|
||||
*.lz4
|
||||
*.lzh
|
||||
*.cab
|
||||
*.arj
|
||||
*.rpm
|
||||
*.deb
|
||||
*.Z
|
||||
*.lz
|
||||
*.lzo
|
||||
*.tar.gz
|
||||
*.tar.bz2
|
||||
*.tar.xz
|
||||
*.tar.zst
|
||||
```
|
||||
|
|
@ -88,10 +88,12 @@ class RewardPanel(DirectFrame):
|
|||
|
||||
self._battleGui = loader.loadModel('phase_3.5/models/gui/battle_gui')
|
||||
from toontown.toonbase.ToonBaseGlobal import base
|
||||
# Use widescreen-aware positioning for proper edge alignment
|
||||
skipButtonPos = base.getGUIEdgePos(edge='right', xOffset=0.585, yOffset=-0.395) if hasattr(base, 'getGUIEdgePos') else Point3(base.a2dRight - 0.585, 0, -0.395)
|
||||
self.skipButton = DirectButton(parent=self, relief=None, image=(self._battleGui.find('**/tt_t_gui_gen_skipSectionUp'),
|
||||
self._battleGui.find('**/tt_t_gui_gen_skipSectionDown'),
|
||||
self._battleGui.find('**/tt_t_gui_gen_skipSectionRollOver'),
|
||||
self._battleGui.find('**/tt_t_gui_gen_skipSectionDisabled')), pos=(base.a2dRight - 0.585, 0, -0.395), scale=(0.39, 1.0, 0.39), text=('',
|
||||
self._battleGui.find('**/tt_t_gui_gen_skipSectionDisabled')), pos=skipButtonPos, scale=(0.39, 1.0, 0.39), text=('',
|
||||
TTLocalizer.RewardPanelSkip,
|
||||
TTLocalizer.RewardPanelSkip,
|
||||
''), text_scale=TTLocalizer.RPskipScale, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=TTLocalizer.RPskipPos, textMayChange=0, command=self._handleSkip)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ class SuitAvatarPanel(AvatarPanel.AvatarPanel):
|
|||
self.avName = avatar.getName()
|
||||
gui = loader.loadModel('phase_3.5/models/gui/suit_detail_panel')
|
||||
from toontown.toonbase.ToonBaseGlobal import base
|
||||
self.frame = DirectFrame(geom=gui.find('**/avatar_panel'), geom_scale=0.21, geom_pos=(0, 0, 0.02), relief=None, pos=(base.a2dRight - 0.3, 100, 0.525))
|
||||
# Use widescreen-aware positioning for proper edge alignment
|
||||
framePos = base.getGUIEdgePos(edge='right', xOffset=0.3, yOffset=-0.525) if hasattr(base, 'getGUIEdgePos') else Point3(base.a2dRight - 0.3, 100, 0.525)
|
||||
self.frame = DirectFrame(geom=gui.find('**/avatar_panel'), geom_scale=0.21, geom_pos=(0, 0, 0.02), relief=None, pos=framePos)
|
||||
disabledImageColor = Vec4(1, 1, 1, 0.4)
|
||||
text0Color = Vec4(1, 1, 1, 1)
|
||||
text1Color = Vec4(0.5, 1, 0.5, 1)
|
||||
|
|
|
|||
|
|
@ -65,10 +65,12 @@ class PlayerInfoPanel(AvatarPanelBase.AvatarPanelBase):
|
|||
base.localAvatar.obscureFriendsListButton(1)
|
||||
gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui')
|
||||
from toontown.toonbase.ToonBaseGlobal import base
|
||||
# Use widescreen-aware positioning for proper edge alignment
|
||||
framePos = base.getGUIEdgePos(edge='right', xOffset=0.3, yOffset=-0.525) if hasattr(base, 'getGUIEdgePos') else Point3(base.a2dRight - 0.3, 100, 0.525)
|
||||
self.frame = DirectFrame(
|
||||
image=gui.find('**/avatar_panel'),
|
||||
relief=None,
|
||||
pos=(base.a2dRight - 0.3, 100, 0.525))
|
||||
pos=framePos)
|
||||
disabledImageColor = Vec4(1, 1, 1, 0.4)
|
||||
text0Color = Vec4(1, 1, 1, 1)
|
||||
text1Color = Vec4(0.5, 1, 0.5, 1)
|
||||
|
|
|
|||
|
|
@ -52,10 +52,12 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase):
|
|||
|
||||
gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui')
|
||||
from toontown.toonbase.ToonBaseGlobal import base
|
||||
# Use widescreen-aware positioning for proper edge alignment
|
||||
framePos = base.getGUIEdgePos(edge='right', xOffset=0.3, yOffset=-0.525) if hasattr(base, 'getGUIEdgePos') else Point3(base.a2dRight - 0.3, 100, 0.525)
|
||||
self.frame = DirectFrame(
|
||||
image=gui.find('**/avatar_panel'),
|
||||
relief=None,
|
||||
pos=(base.a2dRight - 0.3, 100, 0.525))
|
||||
pos=framePos)
|
||||
|
||||
self.disabledImageColor = Vec4(1, 1, 1, 0.4)
|
||||
self.text0Color = Vec4(1, 1, 1, 1)
|
||||
|
|
|
|||
|
|
@ -235,6 +235,85 @@ class ToonBase(OTPBase.OTPBase):
|
|||
else: # center
|
||||
# For centered elements, no adjustment needed (aspect2d handles it)
|
||||
return baseX
|
||||
|
||||
def getWidescreenYOffset(self, baseY, alignment='top'):
|
||||
"""Calculate proper Y position for GUI elements in widescreen.
|
||||
|
||||
Args:
|
||||
baseY: The original Y position designed for 4:3 (1.333 aspect)
|
||||
alignment: 'top', 'bottom', or 'center' - which edge the element aligns to
|
||||
|
||||
Returns:
|
||||
Adjusted Y position that maintains distance from screen edge
|
||||
"""
|
||||
# Base aspect2d boundaries for 4:3 reference
|
||||
base4x3Top = 1.0
|
||||
base4x3Bottom = -1.0
|
||||
|
||||
# Current aspect2d boundaries
|
||||
currentTop = base.a2dTop
|
||||
currentBottom = base.a2dBottom
|
||||
|
||||
if alignment == 'top':
|
||||
offsetFrom4x3Top = baseY - base4x3Top
|
||||
return currentTop + offsetFrom4x3Top
|
||||
elif alignment == 'bottom':
|
||||
offsetFrom4x3Bottom = baseY - base4x3Bottom
|
||||
return currentBottom + offsetFrom4x3Bottom
|
||||
else: # center
|
||||
return baseY
|
||||
|
||||
def getA2dEdgePosition(self, edge='right', offset=0.3):
|
||||
"""Get a position relative to aspect2d edges with proper offset.
|
||||
|
||||
This is the recommended way to position GUI elements at screen edges.
|
||||
|
||||
Args:
|
||||
edge: 'left', 'right', 'top', or 'bottom'
|
||||
offset: Distance from the edge in aspect2d units
|
||||
|
||||
Returns:
|
||||
A Point3 position suitable for DirectGui pos parameter
|
||||
"""
|
||||
if edge == 'right':
|
||||
return Point3(base.a2dRight - offset, 0, 0)
|
||||
elif edge == 'left':
|
||||
return Point3(base.a2dLeft + offset, 0, 0)
|
||||
elif edge == 'top':
|
||||
return Point3(0, 0, base.a2dTop - offset)
|
||||
elif edge == 'bottom':
|
||||
return Point3(0, 0, base.a2dBottom + offset)
|
||||
else:
|
||||
return Point3(0, 0, 0)
|
||||
|
||||
def getGUIEdgePos(self, edge='right', xOffset=0.3, yOffset=0):
|
||||
"""Get full 3D position for GUI elements aligned to screen edges.
|
||||
|
||||
More flexible version that allows both X and Y offsets.
|
||||
|
||||
Args:
|
||||
edge: 'left', 'right', 'top', or 'bottom'
|
||||
xOffset: Horizontal offset from the edge
|
||||
yOffset: Vertical offset (positive = up, negative = down)
|
||||
|
||||
Returns:
|
||||
Point3 position for DirectGui
|
||||
"""
|
||||
if edge == 'right':
|
||||
x = base.a2dRight - xOffset
|
||||
elif edge == 'left':
|
||||
x = base.a2dLeft + xOffset
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if edge == 'top':
|
||||
z = base.a2dTop - yOffset
|
||||
elif edge == 'bottom':
|
||||
z = base.a2dBottom + yOffset
|
||||
else:
|
||||
z = yOffset
|
||||
|
||||
return Point3(x, 0, z)
|
||||
|
||||
def windowEvent(self, win):
|
||||
OTPBase.OTPBase.windowEvent(self, win)
|
||||
|
|
|
|||
|
|
@ -130,7 +130,9 @@ class TownBattle(StateData.StateData):
|
|||
TownBattleToonPanel.TownBattleToonPanel(2),
|
||||
TownBattleToonPanel.TownBattleToonPanel(3))
|
||||
self.timer = ToontownTimer.ToontownTimer()
|
||||
self.timer.setPos(base.a2dRight - 0.218, 0, 0.842)
|
||||
# Use widescreen-aware positioning for proper edge alignment
|
||||
timerPos = base.getGUIEdgePos(edge='right', xOffset=0.218, yOffset=-0.842) if hasattr(base, 'getGUIEdgePos') else Point3(base.a2dRight - 0.218, 0, 0.842)
|
||||
self.timer.setPos(timerPos)
|
||||
self.timer.setScale(0.4)
|
||||
# Timer permanently hidden for singleplayer - no time limit
|
||||
self.timer.hide()
|
||||
|
|
|
|||
Loading…
Reference in New Issue