Files
Endfield-Data/LuaScripts/UI/Panels/DialogRecord/DialogRecordCtrl.lua
2025-12-02 20:37:18 +07:00

353 lines
9.8 KiB
Lua

local uiCtrl = require_ex('UI/Panels/Base/UICtrl')
local PANEL_ID = PanelId.DialogRecord
DialogRecordCtrl = HL.Class('DialogRecordCtrl', uiCtrl.UICtrl)
DialogRecordCtrl.s_messages = HL.StaticField(HL.Table) << {
}
DialogRecordCtrl.m_getCell = HL.Field(HL.Function)
DialogRecordCtrl.m_voiceHandleId = HL.Field(HL.Number) << -1
DialogRecordCtrl.m_timer = HL.Field(HL.Number) << -1
DialogRecordCtrl.m_cellSizes = HL.Field(HL.Table)
DialogRecordCtrl.m_curPlayingIndex = HL.Field(HL.Number) << -1
DialogRecordCtrl.m_focusInfo = HL.Field(HL.Table)
DialogRecordCtrl.m_playVoiceBindingId = HL.Field(HL.Number) << -1
DialogRecordCtrl.OnCreate = HL.Override(HL.Any) << function(self, arg)
self.m_cellSizes = {}
self.m_focusInfo = {}
self.view.btnClose.onClick:AddListener(function()
self:PlayAnimationOutWithCallback(function()
self:Notify(MessageConst.HIDE_DIALOG_RECORD)
end)
end)
self.view.backTopButton.onClick:AddListener(function()
self.view.scrollList:ScrollToIndex(CSIndex(1))
end)
self.view.backBottomButton.onClick:AddListener(function()
self.view.scrollList:ScrollToIndex(CSIndex(self.view.scrollList.count))
end)
self.m_getCell = UIUtils.genCachedCellFunction(self.view.scrollList)
self.view.scrollList.onUpdateCell:AddListener(function(obj, csIndex)
self:_OnUpdateCell(self.m_getCell(obj), LuaIndex(csIndex))
end)
self.view.scrollList.getCellSize = function(csIndex)
local luaIndex = LuaIndex(csIndex)
return self.m_cellSizes[luaIndex]
end
if DeviceInfo.usingController then
self.m_playVoiceBindingId = self:BindInputPlayerAction("dialog_play_log_voice", function()
self:_ToggleVoicePlay(self.m_focusInfo)
end)
InputManagerInst:ToggleBinding(self.m_playVoiceBindingId, false)
end
self.view.controllerHintPlaceholder:InitControllerHintPlaceholder({ self.view.inputGroup.groupId })
end
DialogRecordCtrl._UpdateCellSize = HL.Method() << function(self)
self.m_cellSizes = {}
local cell = self.view.cell
local records = GameWorld.dialogManager.records
for index = 1, records.Count do
cell.gameObject:SetActive(true)
self:_RefreshCell(cell, index)
table.insert(self.m_cellSizes, cell.transform.rect.height)
end
cell.gameObject:SetActive(false)
end
DialogRecordCtrl._RefreshCell = HL.Method(HL.Table, HL.Number, HL.Opt(HL.Boolean)) << function(self, cell, index,
exceptAudio)
local records = GameWorld.dialogManager.records
local textId = records[CSIndex(index)]
local voiceId = DialogUtils.GetTrunkVoiceId(textId)
local res, duration = VoiceUtils.TryGetVoiceDuration(voiceId)
local isPlaying = index == self.m_curPlayingIndex
if not res then
voiceId = ""
end
local hasVoice = not exceptAudio and not string.isEmpty(voiceId)
local isTrunk, trunkTbData = Tables.dialogTextTable:TryGetValue(textId)
local isOption, optionTbData = Tables.dialogOptionTable:TryGetValue(textId)
local trunkNode = cell.trunkNode
local optionNode = cell.optionNode
local line = cell.line
cell.hasVoice = hasVoice
trunkNode.gameObject:SetActive(isTrunk)
optionNode.gameObject:SetActive(isOption)
line.gameObject:SetActive(index > 1 and index == self.view.scrollList.count)
if isTrunk then
local actorName = UIUtils.removePattern(trunkTbData.actorName, UIConst.NARRATIVE_ANONYMITY_PATTERN)
trunkNode.characterNameText:SetAndResolveTextStyle(UIUtils.resolveTextCinematic(actorName))
trunkNode.text:SetAndResolveTextStyle(UIUtils.resolveTextCinematic(trunkTbData.dialogText))
trunkNode.playingAudioButton.gameObject:SetActive(false)
trunkNode.audioButton.gameObject:SetActive(hasVoice)
trunkNode.audioButtonEx.gameObject:SetActive(hasVoice)
self:_SetCellIsPlaying(cell, isPlaying)
trunkNode.audioButton.onClick:RemoveAllListeners()
trunkNode.audioButtonEx.onClick:RemoveAllListeners()
trunkNode.playingAudioButton.onClick:RemoveAllListeners()
if hasVoice then
trunkNode.audioButton.onClick:AddListener(function()
self:_RefreshPlayingCell(index)
self:_TryPlayAudio(voiceId, duration)
end)
trunkNode.playingAudioButton.onClick:AddListener(function()
if self.m_curPlayingIndex == index then
self:_RefreshPlayingCell(-1)
self:_StopAudio()
end
end)
trunkNode.audioButtonEx.onClick:AddListener(function() self:_ToggleVoicePlay({index, voiceId, duration}) end)
trunkNode.trunkButton.onIsNaviTargetChanged = function(isNaviTarget)
if isNaviTarget and DeviceInfo.usingController then
self.m_focusInfo = { index, voiceId, duration }
InputManagerInst:ToggleBinding(self.m_playVoiceBindingId, true)
end
end
else
trunkNode.trunkButton.onIsNaviTargetChanged = function(isNaviTarget)
if isNaviTarget and DeviceInfo.usingController then
self.m_focusInfo = {}
InputManagerInst:ToggleBinding(self.m_playVoiceBindingId, false)
end
end
end
LayoutRebuilder.ForceRebuildLayoutImmediate(trunkNode.characterDialogNode.transform)
LayoutRebuilder.ForceRebuildLayoutImmediate(trunkNode.transform)
elseif isOption then
optionNode.optionButton.onIsNaviTargetChanged = function(isNaviTarget)
if isNaviTarget and DeviceInfo.usingController then
self.m_focusInfo = {}
InputManagerInst:ToggleBinding(self.m_playVoiceBindingId, false)
end
end
optionNode.text:SetAndResolveTextStyle(UIUtils.resolveTextCinematic(optionTbData.optionText))
LayoutRebuilder.ForceRebuildLayoutImmediate(optionNode.optionNode.transform)
end
LayoutRebuilder.ForceRebuildLayoutImmediate(cell.transform)
end
DialogRecordCtrl._ToggleVoicePlay = HL.Method(HL.Table) << function(self, info)
if next(info) == nil then
return
end
local index, voiceId, duration = unpack(info)
if self.m_curPlayingIndex == index then
self:_RefreshPlayingCell(-1)
self:_StopAudio()
else
self:_RefreshPlayingCell(index)
self:_TryPlayAudio(voiceId, duration)
end
end
DialogRecordCtrl._OnUpdateCell = HL.Method(HL.Any, HL.Number) << function(self, object, index)
local cell = self.m_getCell(object)
self:_RefreshCell(cell, index)
end
DialogRecordCtrl._GetCellByIndex = HL.Method(HL.Number).Return(HL.Any) << function(self, luaIndex)
local cell
if luaIndex > 0 then
local object = self.view.scrollList:Get(CSIndex(luaIndex))
if object then
cell = self.m_getCell(object)
end
end
return cell
end
DialogRecordCtrl._SetCellIsPlaying = HL.Method(HL.Any, HL.Boolean) << function(self, cell, isPlaying)
if not cell then
return
end
local trunkNode = cell.trunkNode
local hasVoice = cell.hasVoice
if hasVoice then
trunkNode.audioButton.gameObject:SetActive(not isPlaying)
trunkNode.playingAudioButton.gameObject:SetActive(isPlaying)
trunkNode.playingAudioBG.gameObject:SetActive(isPlaying)
if isPlaying then
trunkNode.text.color = self.view.config.TRUNK_TEXT_PLAYING_COLOR
else
trunkNode.text.color = self.view.config.TRUNK_TEXT_DEFAULT_COLOR
end
else
trunkNode.audioButton.gameObject:SetActive(false)
end
end
DialogRecordCtrl._RefreshPlayingCell = HL.Method(HL.Number) << function(self, newIndex)
if self.m_curPlayingIndex == newIndex then
return
end
local oldCell = self:_GetCellByIndex(self.m_curPlayingIndex)
self:_SetCellIsPlaying(oldCell, false)
local newCell = self:_GetCellByIndex(newIndex)
self:_SetCellIsPlaying(newCell, true)
self.m_curPlayingIndex = newIndex
end
DialogRecordCtrl._TryPlayAudio = HL.Method(HL.String, HL.Number) << function(self, voiceId, duration)
GameWorld.dialogManager:TryStopCurVoice()
self:_StopAudio()
self.m_voiceHandleId = VoiceManager:SpeakNarrative(voiceId, nil, CS.Beyond.Gameplay.Audio.NarrativeVoiceConfig.DEFAULT_CONFIG)
self.m_timer = self:_StartTimer(duration, function()
self:_RefreshPlayingCell(-1)
self:_StopAudio()
end)
end
DialogRecordCtrl._StopAudio = HL.Method() << function(self)
if self.m_voiceHandleId > 0 then
VoiceManager:StopVoice(self.m_voiceHandleId)
end
self.m_voiceHandleId = -1
if self.m_timer > 0 then
self:_ClearTimer(self.m_timer)
end
self.m_timer = -1
end
DialogRecordCtrl.OnShow = HL.Override() << function(self)
local count = GameWorld.dialogManager.records.Count
self:_UpdateCellSize()
self.view.scrollList:UpdateCount(count)
self.view.scrollList:ScrollToIndex(CSIndex(self.view.scrollList.count), true)
self.view.scrollListNaviGroup:ManuallyFocus()
end
DialogRecordCtrl.OnClose = HL.Override() << function(self)
self:_StopAudio()
self.view.scrollListNaviGroup:ManuallyStopFocus()
end
DialogRecordCtrl._Update = HL.Method() << function(self)
local firstCellShowing = self.view.scrollList:IsCellShowing(CSIndex(1))
local lastCellShowing = self.view.scrollList:IsCellShowing(CSIndex(self.view.scrollList.count))
self.view.backTopButton.gameObject:SetActive(not firstCellShowing)
self.view.backBottomButton.gameObject:SetActive(not lastCellShowing)
end
DialogRecordCtrl.OnHide = HL.Override() << function(self)
self:_RefreshPlayingCell(-1)
self:_StopAudio()
end
HL.Commit(DialogRecordCtrl)