From 37beca71031a52577c06a9224552fbda689e8a33 Mon Sep 17 00:00:00 2001
From: Meow <30401521+me0wg4ming@users.noreply.github.com>
Date: Fri, 6 Feb 2026 08:07:33 +0100
Subject: [PATCH] New throttling menu
New throttling menu
---
README.md | 7 +
api/config.lua | 2 +
api/unitframes.lua | 4 +-
env/translations_deDE.lua | 32 ++++
env/translations_enUS.lua | 32 ++++
init/libs.xml | 1 +
libs/libpredict.lua | 4 +-
libs/libthrottle.lua | 172 ++++++++++++++++++++
modules/chat.lua | 4 +-
modules/gui.lua | 319 +++++++++++++++++++++++++++++++++++++-
modules/nameplates.lua | 6 +-
modules/player.lua | 2 +-
modules/tooltip.lua | 4 +-
pfUI-tbc.toc | 2 +-
pfUI.lua | 2 +
pfUI.toc | 2 +-
16 files changed, 579 insertions(+), 16 deletions(-)
create mode 100644 libs/libthrottle.lua
diff --git a/README.md b/README.md
index 0a2389b6..10d6930e 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,13 @@ This version includes significant performance improvements, DLL-enhanced feature
> **Looking for TBC support?** Visit the original pfUI by Shagu: [https://github.com/shagu/pfUI](https://github.com/shagu/pfUI)
+---
+
+## 🎯 What's New in Version 7.6.1 (February 6, 2026)
+- Added a new menu in /pfui named "Throttling" - Players who were unsatisfied with the throggling update rate can change it now for nameplates, Toolip Cursor and Chat Tab.
+
+---
+
## 🎯 What's New in Version 7.6.0 (February 3, 2026)
### 🚀 Centralized Cast-Bar Tracking System (libdebuff.lua + nameplates.lua)
diff --git a/api/config.lua b/api/config.lua
index 8bbf7549..5c6ce9e9 100644
--- a/api/config.lua
+++ b/api/config.lua
@@ -712,6 +712,8 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("tooltip", nil, "font_tooltip", "Interface\\AddOns\\pfUI\\fonts\\Myriad-Pro.ttf")
pfUI:UpdateConfig("tooltip", nil, "font_tooltip_size", "12")
+ -- Throttle Settings
+
pfUI:UpdateConfig("chat", "text", "input_width", "0")
pfUI:UpdateConfig("chat", "text", "input_height", "0")
pfUI:UpdateConfig("chat", "text", "outline", "1")
diff --git a/api/unitframes.lua b/api/unitframes.lua
index 255c404e..814adb96 100644
--- a/api/unitframes.lua
+++ b/api/unitframes.lua
@@ -1395,7 +1395,7 @@ function pfUI.uf.OnUpdate()
-- update combat feedback (no throttle - needs immediate feedback)
if this.feedbackText then CombatFeedback_OnUpdate(arg1) end
- -- Throttle raid/party frames for performance (10 updates/sec)
+ -- Throttle raid/party frames for performance
if this.label == "raid" or this.label == "party" then
if (this.throttleTick or 0) > now then
if pfUI.uf.stats and pfUI.uf.stats.enabled then
@@ -1403,7 +1403,7 @@ function pfUI.uf.OnUpdate()
end
return
end
- this.throttleTick = now + 0.1
+ this.throttleTick = now + 0.1 -- Default: 10 FPS
end
-- ============================================================================
diff --git a/env/translations_deDE.lua b/env/translations_deDE.lua
index 4df027d2..6ca88afa 100644
--- a/env/translations_deDE.lua
+++ b/env/translations_deDE.lua
@@ -878,4 +878,36 @@ pfUI_translation["deDE"] = {
["Zonetime"] = nil,
["Zoom & Fade"] = nil,
["Zoom Target Nameplate"] = nil,
+
+ -- Throttling translations
+ ["Throttling"] = "Drosselung",
+ ["Nameplates"] = "Namensplaketten",
+ ["Tooltips"] = "Tooltips",
+ ["Chat Tab"] = "Chat Tab",
+ ["Libpredict"] = "Libpredict",
+ ["Panel Alignment"] = "Panel Ausrichtung",
+ ["Nameplate Update Rate"] = "Namensplaketten Aktualisierungsrate",
+ ["Target/Casting Plates"] = "Ziel/Cast Plaketten",
+ ["Normal Plates"] = "Normale Plaketten",
+ ["Mass Pulls (20+ Plates)"] = "Große Pulls (20+ Plaketten)",
+ ["Tooltip Update Rate"] = "Tooltip Aktualisierungsrate",
+ ["Cursor Follow"] = "Cursor Folgen",
+ ["Health/Status Bar"] = "Leben/Status Leiste",
+ ["Unit Frame Update Rate"] = "Einheiten Frame Aktualisierungsrate",
+ ["Raid/Party Frames"] = "Raid/Gruppe Frames",
+ ["Player Frame"] = "Spieler Frame",
+ ["Chat Tab Hover Check"] = "Chat Tab Hover Prüfung",
+ ["Heal Prediction Cleanup"] = "Heilvorhersage Bereinigung",
+ ["Panel Alignment Check"] = "Panel Ausrichtungsprüfung",
+ ["Custom FPS"] = "Benutzerdefiniert FPS",
+ ["Very Slow"] = "Sehr Langsam",
+ ["Slow"] = "Langsam",
+ ["Normal"] = "Normal",
+ ["Fast"] = "Schnell",
+ ["Very Fast"] = "Sehr Schnell",
+ ["Fastest"] = "Schnellste",
+ ["Reset to Defaults"] = "Auf Standard zurücksetzen",
+ ["Target/Casting"] = "Ziel/Cast",
+ ["Normal"] = "Normal",
+ ["Mass"] = "Masse",
}
diff --git a/env/translations_enUS.lua b/env/translations_enUS.lua
index 841d7c7f..031c68b3 100644
--- a/env/translations_enUS.lua
+++ b/env/translations_enUS.lua
@@ -878,4 +878,36 @@ pfUI_translation["enUS"] = {
["Zonetime"] = nil,
["Zoom & Fade"] = nil,
["Zoom Target Nameplate"] = nil,
+
+ -- Throttling translations
+ ["Throttling"] = nil,
+ ["Nameplates"] = nil,
+ ["Tooltips"] = nil,
+ ["Chat Tab"] = nil,
+ ["Libpredict"] = nil,
+ ["Panel Alignment"] = nil,
+ ["Nameplate Update Rate"] = nil,
+ ["Target/Casting Plates"] = nil,
+ ["Normal Plates"] = nil,
+ ["Mass Pulls (20+ Plates)"] = nil,
+ ["Tooltip Update Rate"] = nil,
+ ["Cursor Follow"] = nil,
+ ["Health/Status Bar"] = nil,
+ ["Unit Frame Update Rate"] = nil,
+ ["Raid/Party Frames"] = nil,
+ ["Player Frame"] = nil,
+ ["Chat Tab Hover Check"] = nil,
+ ["Heal Prediction Cleanup"] = nil,
+ ["Panel Alignment Check"] = nil,
+ ["Custom FPS"] = nil,
+ ["Very Slow"] = nil,
+ ["Slow"] = nil,
+ ["Normal"] = nil,
+ ["Fast"] = nil,
+ ["Very Fast"] = nil,
+ ["Fastest"] = nil,
+ ["Reset to Defaults"] = nil,
+ ["Target/Casting"] = nil,
+ ["Normal"] = nil,
+ ["Mass"] = nil,
}
diff --git a/init/libs.xml b/init/libs.xml
index 01d76ce1..9778a9c3 100644
--- a/init/libs.xml
+++ b/init/libs.xml
@@ -8,5 +8,6 @@
+
diff --git a/libs/libpredict.lua b/libs/libpredict.lua
index 4cc83672..390f90fc 100644
--- a/libs/libpredict.lua
+++ b/libs/libpredict.lua
@@ -240,10 +240,10 @@ libpredict:SetScript("OnEvent", function()
end)
libpredict:SetScript("OnUpdate", function()
- -- throttle cleanup to 0.1s - no need to check every frame
+ -- throttle cleanup - no need to check every frame
local now = pfUI.uf.now or GetTime()
if (this.tick or 0) > now then return end
- this.tick = now + 0.1
+ this.tick = now + 0.1 -- Default: 10 FPS
-- update on timeout events
for timestamp, targets in pairs(events) do
diff --git a/libs/libthrottle.lua b/libs/libthrottle.lua
new file mode 100644
index 00000000..91347331
--- /dev/null
+++ b/libs/libthrottle.lua
@@ -0,0 +1,172 @@
+-- load pfUI environment
+setfenv(1, pfUI:GetEnvironment())
+
+-- return instantly when another libthrottle is already active
+if pfUI.api.libthrottle then return end
+
+-- Create libthrottle namespace
+local libthrottle = CreateFrame("Frame", "pfLibThrottle")
+pfUI.api.libthrottle = libthrottle
+
+-- Preset definitions (FPS -> seconds)
+libthrottle.presets = {
+ ["very_slow"] = { fps = 2, delay = 0.5 },
+ ["slow"] = { fps = 5, delay = 0.2 },
+ ["normal"] = { fps = 10, delay = 0.1 },
+ ["fast"] = { fps = 20, delay = 0.05 },
+ ["very_fast"] = { fps = 30, delay = 0.033 },
+ ["fastest"] = { fps = 50, delay = 0.02 },
+}
+
+-- Localized preset names
+libthrottle.presetNames = {
+ ["very_slow"] = "Very Slow (2 FPS)",
+ ["slow"] = "Slow (5 FPS)",
+ ["normal"] = "Normal (10 FPS)",
+ ["fast"] = "Fast (20 FPS)",
+ ["very_fast"] = "Very Fast (30 FPS)",
+ ["fastest"] = "Fastest (50 FPS)",
+ ["custom"] = "Custom",
+}
+
+-- Default throttle categories
+libthrottle.defaults = {
+ nameplates = "custom",
+ nameplates_target = "custom",
+ nameplates_mass = "custom",
+ tooltip_cursor = "custom",
+ chat_tab = "custom",
+}
+
+-- Convert FPS to throttle delay in seconds
+function libthrottle:FpsToDelay(fps)
+ if not fps or fps <= 0 then return 0.1 end
+ return 1 / fps
+end
+
+-- Convert delay to FPS
+function libthrottle:DelayToFps(delay)
+ if not delay or delay <= 0 then return 10 end
+ return math.floor(1 / delay)
+end
+
+-- Get throttle delay for a category
+-- Returns: delay in seconds
+function libthrottle:Get(category)
+ local configValue = _G.pfUI_throttle and _G.pfUI_throttle[category]
+ if not configValue then
+ configValue = self.defaults[category] or "normal"
+ end
+
+ -- Check if it's a preset name
+ local preset = self.presets[configValue]
+ if preset then
+ return preset.delay
+ end
+
+ -- If it's "custom", read from the _custom field
+ if configValue == "custom" then
+ local customFps = tonumber(_G.pfUI_throttle[category .. "_custom"])
+ if customFps then
+ return self:FpsToDelay(customFps)
+ end
+ end
+
+ -- Fallback to normal preset
+ return self.presets["normal"].delay
+end
+
+-- Get FPS value for a category (for display purposes)
+function libthrottle:GetFps(category)
+ local delay = self:Get(category)
+ return self:DelayToFps(delay)
+end
+
+-- Get preset name for a category
+function libthrottle:GetPreset(category)
+ local configValue = _G.pfUI_throttle and _G.pfUI_throttle[category]
+ if not configValue then
+ return self.defaults[category] or "normal"
+ end
+
+ -- Check if it's a known preset
+ if self.presets[configValue] then
+ return configValue
+ end
+
+ -- Must be a custom value
+ return "custom"
+end
+
+-- Check if a category is using custom FPS
+function libthrottle:IsCustom(category)
+ return self:GetPreset(category) == "custom"
+end
+
+-- Set throttle for a category
+function libthrottle:Set(category, value)
+ if not _G.pfUI_throttle then _G.pfUI_throttle = {} end
+
+ -- Validate preset
+ if type(value) == "string" and self.presets[value] then
+ _G.pfUI_throttle[category] = value
+ return true
+ end
+
+ -- If it's "custom", keep it
+ if value == "custom" then
+ _G.pfUI_throttle[category] = value
+ return true
+ end
+
+ return false
+end
+
+-- Reset a category to its default value
+function libthrottle:ResetToDefault(category)
+ local default = self.defaults[category]
+ if default then
+ if not _G.pfUI_throttle then _G.pfUI_throttle = {} end
+ _G.pfUI_throttle[category] = default
+ return true
+ end
+ return false
+end
+
+-- Reset all categories to defaults
+function libthrottle:ResetAllToDefaults()
+ if not _G.pfUI_throttle then _G.pfUI_throttle = {} end
+ for category, default in pairs(self.defaults) do
+ _G.pfUI_throttle[category] = default
+ end
+end
+
+-- Initialize - set defaults if config doesn't exist
+libthrottle:SetScript("OnEvent", function()
+ if event == "PLAYER_ENTERING_WORLD" then
+ if not _G.pfUI_throttle then
+ _G.pfUI_throttle = {}
+ end
+
+ -- Set defaults for any missing categories
+ for category, default in pairs(libthrottle.defaults) do
+ if not _G.pfUI_throttle[category] then
+ _G.pfUI_throttle[category] = default
+ end
+ end
+
+ -- Set defaults for custom fields if missing
+ if not _G.pfUI_throttle.nameplates_target_custom then _G.pfUI_throttle.nameplates_target_custom = "50" end
+ if not _G.pfUI_throttle.nameplates_custom then _G.pfUI_throttle.nameplates_custom = "10" end
+ if not _G.pfUI_throttle.nameplates_mass_custom then _G.pfUI_throttle.nameplates_mass_custom = "7" end
+ if not _G.pfUI_throttle.tooltip_cursor_custom then _G.pfUI_throttle.tooltip_cursor_custom = "10" end
+ if not _G.pfUI_throttle.chat_tab_custom then _G.pfUI_throttle.chat_tab_custom = "10" end
+
+ this:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ end
+end)
+
+libthrottle:RegisterEvent("PLAYER_ENTERING_WORLD")
+
+-- Export to pfUI namespace for easier access
+pfUI.throttle = libthrottle
diff --git a/modules/chat.lua b/modules/chat.lua
index 0bc00833..bcf9618e 100644
--- a/modules/chat.lua
+++ b/modules/chat.lua
@@ -455,8 +455,8 @@ pfUI:RegisterModule("chat", "vanilla:tbc", function ()
if C.chat.global.tabmouse == "1" then
pfUI.chat.mouseovertab = CreateFrame("Frame")
pfUI.chat.mouseovertab:SetScript("OnUpdate", function()
- -- throttle to 0.1s
- if ( this.tick or .1) > GetTime() then return else this.tick = GetTime() + .1 end
+ -- throttle
+ if ( this.tick or .1) > GetTime() then return else this.tick = GetTime() + pfUI.throttle:Get("chat_tab") end -- Default: Normal (10 FPS)
if pfUI.chat.hideLock then return end
diff --git a/modules/gui.lua b/modules/gui.lua
index b0d9b52e..0a2c7a8c 100644
--- a/modules/gui.lua
+++ b/modules/gui.lua
@@ -351,13 +351,13 @@ pfUI:RegisterModule("gui", "vanilla:tbc", function ()
entry.text = text
entry.func = function()
- if category[config] ~= value then
+ if category and category[config] ~= value then
category[config] = value
if ufunc then ufunc() else pfUI.gui.settingChanged = true end
end
end
- if category[config] == value then
+ if category and category[config] == value then
frame.input.current = i
end
@@ -1625,6 +1625,321 @@ pfUI:RegisterModule("gui", "vanilla:tbc", function ()
CreateConfig(nil, T["Selected Core"], C.gm, "server", "dropdown", pfUI.gui.dropdowns.gmserver_text)
end)
+ -- Throttling Menu
+ CreateGUIEntry(T["Throttling"], T["Nameplates"], function()
+ local header = CreateConfig(nil, T["Nameplate Update Rate"], nil, nil, "header")
+ header:GetParent().objectCount = header:GetParent().objectCount - 1
+ header:SetHeight(20)
+
+ local targetCustom -- declare first so callback can use it
+
+ CreateConfig(function()
+ -- Callback when dropdown changes - update custom field immediately
+ if targetCustom and targetCustom.input then
+ local isCustom = pfUI.throttle:IsCustom("nameplates_target")
+ if not isCustom then
+ -- Preset selected - show FPS from preset, make readonly
+ targetCustom.input:EnableMouse(false)
+ targetCustom.input:EnableKeyboard(false)
+ targetCustom.input:ClearFocus()
+ targetCustom.input:SetTextColor(.5,.5,.5,1)
+ targetCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_target")))
+ else
+ -- Custom selected - make editable
+ targetCustom.input:EnableMouse(true)
+ targetCustom.input:EnableKeyboard(true)
+ targetCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.nameplates_target_custom then
+ targetCustom.input:SetText(_G.pfUI_throttle.nameplates_target_custom)
+ end
+ end
+ end
+ end, T["Target/Casting Plates"], _G.pfUI_throttle, "nameplates_target", "dropdown", {
+ "very_slow:" .. T["Very Slow"] .. " (2 FPS)",
+ "slow:" .. T["Slow"] .. " (5 FPS)",
+ "normal:" .. T["Normal"] .. " (10 FPS)",
+ "fast:" .. T["Fast"] .. " (20 FPS)",
+ "very_fast:" .. T["Very Fast"] .. " (30 FPS)",
+ "fastest:" .. T["Fastest"] .. " (50 FPS)",
+ "custom:" .. T["Custom"],
+ })
+
+ -- Now create custom field AFTER dropdown
+ targetCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_target_custom")
+
+ -- Set initial state
+ local isCustom = pfUI.throttle:IsCustom("nameplates_target")
+ if not isCustom then
+ targetCustom.input:EnableMouse(false)
+ targetCustom.input:EnableKeyboard(false)
+ targetCustom.input:SetTextColor(.5,.5,.5,1)
+ targetCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_target")))
+ else
+ targetCustom.input:EnableMouse(true)
+ targetCustom.input:EnableKeyboard(true)
+ targetCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.nameplates_target_custom then
+ targetCustom.input:SetText(_G.pfUI_throttle.nameplates_target_custom)
+ end
+ end
+
+ -- Spacer after custom field
+ local spacer1 = CreateConfig(nil, " ", nil, nil, "header")
+ spacer1:GetParent().objectCount = spacer1:GetParent().objectCount - 1
+ spacer1:SetHeight(5)
+
+ local normalCustom
+
+ CreateConfig(function()
+ if normalCustom and normalCustom.input then
+ local isCustom = pfUI.throttle:IsCustom("nameplates")
+ if not isCustom then
+ normalCustom.input:EnableMouse(false)
+ normalCustom.input:EnableKeyboard(false)
+ normalCustom.input:ClearFocus()
+ normalCustom.input:SetTextColor(.5,.5,.5,1)
+ normalCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates")))
+ else
+ normalCustom.input:EnableMouse(true)
+ normalCustom.input:EnableKeyboard(true)
+ normalCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.nameplates_custom then
+ normalCustom.input:SetText(_G.pfUI_throttle.nameplates_custom)
+ end
+ end
+ end
+ end, T["Normal Plates"], _G.pfUI_throttle, "nameplates", "dropdown", {
+ "very_slow:" .. T["Very Slow"] .. " (2 FPS)",
+ "slow:" .. T["Slow"] .. " (5 FPS)",
+ "normal:" .. T["Normal"] .. " (10 FPS)",
+ "fast:" .. T["Fast"] .. " (20 FPS)",
+ "very_fast:" .. T["Very Fast"] .. " (30 FPS)",
+ "fastest:" .. T["Fastest"] .. " (50 FPS)",
+ "custom:" .. T["Custom"],
+ })
+
+ normalCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_custom")
+
+ local isCustom2 = pfUI.throttle:IsCustom("nameplates")
+ if not isCustom2 then
+ normalCustom.input:EnableMouse(false)
+ normalCustom.input:EnableKeyboard(false)
+ normalCustom.input:SetTextColor(.5,.5,.5,1)
+ normalCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates")))
+ else
+ normalCustom.input:EnableMouse(true)
+ normalCustom.input:EnableKeyboard(true)
+ normalCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.nameplates_custom then
+ normalCustom.input:SetText(_G.pfUI_throttle.nameplates_custom)
+ end
+ end
+
+ -- Spacer after custom field
+ local spacer2 = CreateConfig(nil, " ", nil, nil, "header")
+ spacer2:GetParent().objectCount = spacer2:GetParent().objectCount - 1
+ spacer2:SetHeight(5)
+
+ local massCustom
+
+ CreateConfig(function()
+ if massCustom and massCustom.input then
+ local isCustom = pfUI.throttle:IsCustom("nameplates_mass")
+ if not isCustom then
+ massCustom.input:EnableMouse(false)
+ massCustom.input:EnableKeyboard(false)
+ massCustom.input:ClearFocus()
+ massCustom.input:SetTextColor(.5,.5,.5,1)
+ massCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_mass")))
+ else
+ massCustom.input:EnableMouse(true)
+ massCustom.input:EnableKeyboard(true)
+ massCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.nameplates_mass_custom then
+ massCustom.input:SetText(_G.pfUI_throttle.nameplates_mass_custom)
+ end
+ end
+ end
+ end, T["Mass Pulls (20+ Plates)"], _G.pfUI_throttle, "nameplates_mass", "dropdown", {
+ "very_slow:" .. T["Very Slow"] .. " (2 FPS)",
+ "slow:" .. T["Slow"] .. " (5 FPS)",
+ "normal:" .. T["Normal"] .. " (10 FPS)",
+ "fast:" .. T["Fast"] .. " (20 FPS)",
+ "very_fast:" .. T["Very Fast"] .. " (30 FPS)",
+ "fastest:" .. T["Fastest"] .. " (50 FPS)",
+ "custom:" .. T["Custom"],
+ })
+
+ massCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_mass_custom")
+
+ local isCustom3 = pfUI.throttle:IsCustom("nameplates_mass")
+ if not isCustom3 then
+ massCustom.input:EnableMouse(false)
+ massCustom.input:EnableKeyboard(false)
+ massCustom.input:SetTextColor(.5,.5,.5,1)
+ massCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_mass")))
+ else
+ massCustom.input:EnableMouse(true)
+ massCustom.input:EnableKeyboard(true)
+ massCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.nameplates_mass_custom then
+ massCustom.input:SetText(_G.pfUI_throttle.nameplates_mass_custom)
+ end
+ end
+
+ -- Spacer before reset button
+ local spacer = CreateConfig(nil, " ", nil, nil, "header")
+ spacer:GetParent().objectCount = spacer:GetParent().objectCount - 1
+ spacer:SetHeight(10)
+
+ -- Reset to defaults button
+ CreateConfig(nil, T["Reset to Defaults"], nil, nil, "button", function()
+ pfUI.throttle:ResetToDefault("nameplates_target")
+ pfUI.throttle:ResetToDefault("nameplates")
+ pfUI.throttle:ResetToDefault("nameplates_mass")
+ -- Also reset custom fields to their default FPS values
+ _G.pfUI_throttle.nameplates_target_custom = "50"
+ _G.pfUI_throttle.nameplates_custom = "10"
+ _G.pfUI_throttle.nameplates_mass_custom = "7"
+ Reload()
+ end, true)
+ end)
+
+ CreateGUIEntry(T["Throttling"], T["Tooltips"], function()
+ local header = CreateConfig(nil, T["Tooltip Update Rate"], nil, nil, "header")
+ header:GetParent().objectCount = header:GetParent().objectCount - 1
+ header:SetHeight(20)
+
+ local cursorCustom
+
+ CreateConfig(function()
+ if cursorCustom and cursorCustom.input then
+ local isCustom = pfUI.throttle:IsCustom("tooltip_cursor")
+ if not isCustom then
+ cursorCustom.input:EnableMouse(false)
+ cursorCustom.input:EnableKeyboard(false)
+ cursorCustom.input:ClearFocus()
+ cursorCustom.input:SetTextColor(.5,.5,.5,1)
+ cursorCustom.input:SetText(tostring(pfUI.throttle:GetFps("tooltip_cursor")))
+ else
+ cursorCustom.input:EnableMouse(true)
+ cursorCustom.input:EnableKeyboard(true)
+ cursorCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.tooltip_cursor_custom then
+ cursorCustom.input:SetText(_G.pfUI_throttle.tooltip_cursor_custom)
+ end
+ end
+ end
+ end, T["Cursor Follow"], _G.pfUI_throttle, "tooltip_cursor", "dropdown", {
+ "very_slow:" .. T["Very Slow"] .. " (2 FPS)",
+ "slow:" .. T["Slow"] .. " (5 FPS)",
+ "normal:" .. T["Normal"] .. " (10 FPS)",
+ "fast:" .. T["Fast"] .. " (20 FPS)",
+ "very_fast:" .. T["Very Fast"] .. " (30 FPS)",
+ "fastest:" .. T["Fastest"] .. " (50 FPS)",
+ "custom:" .. T["Custom"],
+ })
+
+ cursorCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "tooltip_cursor_custom")
+
+ local isCustom = pfUI.throttle:IsCustom("tooltip_cursor")
+ if not isCustom then
+ cursorCustom.input:EnableMouse(false)
+ cursorCustom.input:EnableKeyboard(false)
+ cursorCustom.input:SetTextColor(.5,.5,.5,1)
+ cursorCustom.input:SetText(tostring(pfUI.throttle:GetFps("tooltip_cursor")))
+ else
+ cursorCustom.input:EnableMouse(true)
+ cursorCustom.input:EnableKeyboard(true)
+ cursorCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.tooltip_cursor_custom then
+ cursorCustom.input:SetText(_G.pfUI_throttle.tooltip_cursor_custom)
+ end
+ end
+
+ -- Small spacer
+ local spacer1 = CreateConfig(nil, " ", nil, nil, "header")
+ spacer1:GetParent().objectCount = spacer1:GetParent().objectCount - 1
+ spacer1:SetHeight(5)
+
+ -- Info note about Native mode
+ local infoText = CreateConfig(nil, T["Note: Only works when Cursor Align is NOT 'Native'"], nil, nil, "header")
+ infoText:GetParent().objectCount = infoText:GetParent().objectCount - 1
+ infoText:SetHeight(25)
+
+ -- Spacer before reset button
+ local spacer = CreateConfig(nil, " ", nil, nil, "header")
+ spacer:GetParent().objectCount = spacer:GetParent().objectCount - 1
+ spacer:SetHeight(5)
+
+ -- Reset to defaults button
+ CreateConfig(nil, T["Reset to Defaults"], nil, nil, "button", function()
+ pfUI.throttle:ResetToDefault("tooltip_cursor")
+ _G.pfUI_throttle.tooltip_cursor_custom = "10"
+ Reload()
+ end, true)
+ end)
+ CreateGUIEntry(T["Throttling"], T["Chat Tab"], function()
+ local chatCustom
+
+ CreateConfig(function()
+ if chatCustom and chatCustom.input then
+ local isCustom = pfUI.throttle:IsCustom("chat_tab")
+ if not isCustom then
+ chatCustom.input:EnableMouse(false)
+ chatCustom.input:EnableKeyboard(false)
+ chatCustom.input:ClearFocus()
+ chatCustom.input:SetTextColor(.5,.5,.5,1)
+ chatCustom.input:SetText(tostring(pfUI.throttle:GetFps("chat_tab")))
+ else
+ chatCustom.input:EnableMouse(true)
+ chatCustom.input:EnableKeyboard(true)
+ chatCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.chat_tab_custom then
+ chatCustom.input:SetText(_G.pfUI_throttle.chat_tab_custom)
+ end
+ end
+ end
+ end, T["Chat Tab Hover Check"], _G.pfUI_throttle, "chat_tab", "dropdown", {
+ "very_slow:" .. T["Very Slow"] .. " (2 FPS)",
+ "slow:" .. T["Slow"] .. " (5 FPS)",
+ "normal:" .. T["Normal"] .. " (10 FPS)",
+ "fast:" .. T["Fast"] .. " (20 FPS)",
+ "very_fast:" .. T["Very Fast"] .. " (30 FPS)",
+ "fastest:" .. T["Fastest"] .. " (50 FPS)",
+ "custom:" .. T["Custom"],
+ })
+
+ chatCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "chat_tab_custom")
+
+ local isCustom = pfUI.throttle:IsCustom("chat_tab")
+ if not isCustom then
+ chatCustom.input:EnableMouse(false)
+ chatCustom.input:EnableKeyboard(false)
+ chatCustom.input:SetTextColor(.5,.5,.5,1)
+ chatCustom.input:SetText(tostring(pfUI.throttle:GetFps("chat_tab")))
+ else
+ chatCustom.input:EnableMouse(true)
+ chatCustom.input:EnableKeyboard(true)
+ chatCustom.input:SetTextColor(.2,1,.8,1)
+ if _G.pfUI_throttle.chat_tab_custom then
+ chatCustom.input:SetText(_G.pfUI_throttle.chat_tab_custom)
+ end
+ end
+
+ -- Spacer before reset button
+ local spacer = CreateConfig(nil, " ", nil, nil, "header")
+ spacer:GetParent().objectCount = spacer:GetParent().objectCount - 1
+ spacer:SetHeight(10)
+
+ -- Reset to defaults button
+ CreateConfig(nil, T["Reset to Defaults"], nil, nil, "button", function()
+ pfUI.throttle:ResetToDefault("chat_tab")
+ _G.pfUI_throttle.chat_tab_custom = "10"
+ Reload()
+ end, true)
+ end)
+
CreateGUIEntry(T["Unit Frames"], T["General"], function()
CreateConfig(nil, T["Disable pfUI Unit Frames"], C.unitframes, "disable", "checkbox")
CreateConfig(nil, T["Healthbar Animation Speed"], C.unitframes, "animation_speed", "dropdown", pfUI.gui.dropdowns.uf_animationspeed)
diff --git a/modules/nameplates.lua b/modules/nameplates.lua
index 7b4926a2..15f35351 100644
--- a/modules/nameplates.lua
+++ b/modules/nameplates.lua
@@ -1263,11 +1263,11 @@ nameplates:RegisterEvent("ZONE_CHANGED_NEW_AREA")
local throttle
if target or isCasting then
- throttle = 0.02 -- 50 FPS for target OR active castbar
+ throttle = pfUI.throttle:Get("nameplates_target") -- Default: Fast (20 FPS)
elseif visiblePlateCount > 20 then
- throttle = 0.15 -- ~7 FPS for mass pulls (20+ plates)
+ throttle = pfUI.throttle:Get("nameplates_mass") -- Default: Slow (5 FPS) for mass pulls
else
- throttle = 0.1 -- 10 FPS for others (healthbar updates)
+ throttle = pfUI.throttle:Get("nameplates") -- Default: Normal (10 FPS)
end
-- Check for pending event updates (these bypass throttle for immediate response)
diff --git a/modules/player.lua b/modules/player.lua
index 6e366d4a..053bcd6a 100644
--- a/modules/player.lua
+++ b/modules/player.lua
@@ -16,7 +16,7 @@ pfUI:RegisterModule("player", "vanilla:tbc", function ()
local originalOnUpdate = pfUI.uf.player:GetScript("OnUpdate")
pfUI.uf.player:SetScript("OnUpdate", function()
if (this.throttleTick or 0) > GetTime() then return end
- this.throttleTick = GetTime() + 0.1
+ this.throttleTick = GetTime() + 0.1 -- Default: 10 FPS
originalOnUpdate()
end)
end
diff --git a/modules/tooltip.lua b/modules/tooltip.lua
index 054b604b..becefa51 100644
--- a/modules/tooltip.lua
+++ b/modules/tooltip.lua
@@ -33,9 +33,9 @@ pfUI:RegisterModule("tooltip", "vanilla", function ()
tooltip.cursor:SetWidth(tonumber(C.tooltip.cursoroffset) * 2)
tooltip.cursor:SetHeight(tonumber(C.tooltip.cursoroffset) * 2)
tooltip.cursor:SetScript("OnUpdate", function()
- -- throttle to 0.1s - cursor following doesn't need to be every frame
+ -- throttle - cursor following doesn't need to be every frame
if (this.tick or 0) > GetTime() then return end
- this.tick = GetTime() + 0.1
+ this.tick = GetTime() + (pfUI.throttle and pfUI.throttle:Get("tooltip_cursor") or 0.1)
local scale = UIParent:GetScale()
local x, y = GetCursorPosition()
diff --git a/pfUI-tbc.toc b/pfUI-tbc.toc
index f475c9ae..81f9455a 100644
--- a/pfUI-tbc.toc
+++ b/pfUI-tbc.toc
@@ -4,7 +4,7 @@
## Notes: A complete user interface replacement.
## Notes-ruRU: Полная замена пользовательского интерфейса.
## Version: 7.6.0 (experiment version)
-## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache
+## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache, pfUI_throttle
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
pfUI.lua
diff --git a/pfUI.lua b/pfUI.lua
index 8d2791b3..0d06ee48 100644
--- a/pfUI.lua
+++ b/pfUI.lua
@@ -30,6 +30,7 @@ pfUI_init = {}
pfUI_profiles = {}
pfUI_addon_profiles = {}
pfUI_cache = {}
+pfUI_throttle = {}
-- localization
pfUI_locale = {}
@@ -241,6 +242,7 @@ function pfUI:GetEnvironment()
pfUI.env._G = getfenv(0)
pfUI.env.C = pfUI_config
+ pfUI.env.pfUI_throttle = _G.pfUI_throttle
pfUI.env.L = (pfUI_locale[GetLocale()] or pfUI_locale["enUS"])
return pfUI.env
diff --git a/pfUI.toc b/pfUI.toc
index 62459348..6fb07428 100644
--- a/pfUI.toc
+++ b/pfUI.toc
@@ -4,7 +4,7 @@
## Notes: A complete user interface replacement.
## Notes-ruRU: Полная замена пользовательского интерфейса.
## Version: 7.6.0 (experiment version)
-## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache
+## SavedVariables: pfUI_profiles, pfUI_addon_profiles, pfUI_cache, pfUI_throttle
## SavedVariablesPerCharacter: pfUI_config, pfUI_init, pfUI_playerDB
pfUI.lua