5842eb7a2b
Traduction - Identifiants en anglais dans tout le module : addon, ecrans d'accueil, outils Python, banc d'essai et patcheur C#. - Fichiers au nom francais renommes (Gabarits.lua -> Templates.lua, Textes_*.lua -> Texts_*.lua, deployer.py -> deploy.py, tools/patcheur -> tools/patcher, etc.). - Commandes /fui et options de deploy.py en anglais (--check, --server, --remove-dbc). - Cles des variables sauvegardees et de data/dbc/statistics.json traduites, sans reprise des anciennes cles. - API de la micro-barre : ForeverUI.AddMicroButton(def) avec les champs name, atlasSet, after, tooltip, onClick, ready, et ForeverUI.UpdateMicro(name, isOpen). - Commentaires reecrits en anglais, courts, sans dates ni historique ; les fonctions au nom peu parlant et leurs parametres sont expliques. Code mort - Exports, fonctions et variables jamais lus retires. - Retires a la demande des modules : ForeverUI.PvPJauge, les exports FondEntete / TuilerEntete / Polices de TradeSkill, l'art legacy-up-c60, honorfill(half)blue et inv_misc_book_09, leurs entrees d'atlas et les parties d'outils correspondantes. Verifications : liaisons des noms comparees avant et apres, banc vert, chemins de textures inchanges, generateurs reproduisant les fichiers, patcheur identique octet pour octet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
227 lines
7.3 KiB
Lua
227 lines
7.3 KiB
Lua
-- camelot's MinimalScrollBar, rebuilt: 3.3.5 has neither it nor the ScrollBox that drives it.
|
|
-- The caller gives the row count, the rows that fit and the offset; the bar returns the new
|
|
-- offset and touches no list.
|
|
-- Measured on the art, not the atlas names: thumb-bottom fades out (alpha 1 to 255 over 36 px),
|
|
-- so it is not used; both thumb ends are thumb-top, the bottom one flipped.
|
|
-- The arrows (17 x 11) overhang the 8-wide bar by 4.5 on each side.
|
|
|
|
local ForeverUI = ForeverUI or {}
|
|
_G.ForeverUI = ForeverUI
|
|
|
|
local WIDTH = 8
|
|
local ARROW_W, ARROW_H = 17, 11
|
|
local CURSOR_TIP = 8 -- minimal-scrollbar-thumb-top
|
|
local CURSOR_MIN = 2 * CURSOR_TIP -- both ends, no middle
|
|
local TRACK_TIP = 8
|
|
|
|
local ATLAS = {
|
|
trackTop = "minimal-scrollbar-track-top-c60",
|
|
trackMiddle = "!minimal-scrollbar-track-middle-c60",
|
|
trackBottom = "minimal-scrollbar-track-bottom-c60",
|
|
cursorTip = "minimal-scrollbar-thumb-top-c60",
|
|
cursorMiddle = "minimal-scrollbar-thumb-middle-c60",
|
|
upArrow = "minimal-scrollbar-arrow-top-c60",
|
|
upArrowHover = "minimal-scrollbar-arrow-top-over-c60",
|
|
downArrow = "minimal-scrollbar-arrow-bottom-c60",
|
|
downArrowHover = "minimal-scrollbar-arrow-bottom-over-c60",
|
|
}
|
|
|
|
-- Mouse Y in a frame's coordinates: GetCursorPosition returns screen coordinates, so divide
|
|
-- by the frame's effective scale.
|
|
local function mouse(frame)
|
|
local _, y = GetCursorPosition()
|
|
return y / (frame:GetEffectiveScale() or 1)
|
|
end
|
|
|
|
-- Arrow button; step: rows moved per click (-1 up, 1 down).
|
|
local function createArrow(bar, name, atlas, hoverAtlas, step)
|
|
local button = CreateFrame("Button", name, bar)
|
|
button:SetWidth(ARROW_W)
|
|
button:SetHeight(ARROW_H)
|
|
|
|
local image = button:CreateTexture(nil, "ARTWORK")
|
|
ForeverUI.SetAtlas(image, atlas, true)
|
|
image:SetAllPoints(button)
|
|
button.image = image
|
|
|
|
button:SetScript("OnEnter", function(self)
|
|
ForeverUI.SetAtlas(self.image, hoverAtlas, true)
|
|
end)
|
|
button:SetScript("OnLeave", function(self)
|
|
ForeverUI.SetAtlas(self.image, atlas, true)
|
|
end)
|
|
button:SetScript("OnClick", function()
|
|
bar:MoveTo(bar.offset + step)
|
|
end)
|
|
|
|
return button
|
|
end
|
|
|
|
-- name: global name (arrows and thumb derive theirs from it); parent: owner frame;
|
|
-- list: the scrolled frame, which the bar anchors to as camelot's does to its ScrollBox.
|
|
function ForeverUI.CreateScrollBar(name, parent, list)
|
|
local bar = CreateFrame("Frame", name, parent)
|
|
bar:SetWidth(WIDTH)
|
|
bar:SetPoint("TOPLEFT", list, "TOPRIGHT", 5, -2)
|
|
bar:SetPoint("BOTTOMLEFT", list, "BOTTOMRIGHT", 5, 4)
|
|
|
|
bar.total = 0
|
|
bar.visibleCount = 0
|
|
bar.offset = 0
|
|
|
|
local top = createArrow(bar, name .. "Up", ATLAS.upArrow,
|
|
ATLAS.upArrowHover, -1)
|
|
top:SetPoint("TOP", bar, "TOP", 0, 0)
|
|
bar.upArrow = top
|
|
|
|
local down = createArrow(bar, name .. "Down", ATLAS.downArrow,
|
|
ATLAS.downArrowHover, 1)
|
|
down:SetPoint("BOTTOM", bar, "BOTTOM", 0, 0)
|
|
bar.downArrow = down
|
|
|
|
-- Track between the arrows: two rounded ends and a stretched middle.
|
|
local track = CreateFrame("Frame", nil, bar)
|
|
track:SetPoint("TOPLEFT", top, "BOTTOMLEFT", 0, 0)
|
|
track:SetPoint("BOTTOMRIGHT", down, "TOPRIGHT", 0, 0)
|
|
track:SetWidth(WIDTH)
|
|
bar.track = track
|
|
|
|
local function slice(frame, atlas, layer)
|
|
local t = frame:CreateTexture(nil, layer or "BACKGROUND")
|
|
ForeverUI.SetAtlas(t, atlas, true)
|
|
t:SetWidth(WIDTH)
|
|
return t
|
|
end
|
|
|
|
local trackTop = slice(track, ATLAS.trackTop)
|
|
trackTop:SetHeight(TRACK_TIP)
|
|
trackTop:SetPoint("TOP", track, "TOP", 0, 0)
|
|
local trackBottom = slice(track, ATLAS.trackBottom)
|
|
trackBottom:SetHeight(TRACK_TIP)
|
|
trackBottom:SetPoint("BOTTOM", track, "BOTTOM", 0, 0)
|
|
local trackMiddle = slice(track, ATLAS.trackMiddle)
|
|
trackMiddle:SetPoint("TOPLEFT", trackTop, "BOTTOMLEFT", 0, 0)
|
|
trackMiddle:SetPoint("BOTTOMRIGHT", trackBottom, "TOPRIGHT", 0, 0)
|
|
|
|
-- Thumb: three slices in a frame that moves.
|
|
local cursor = CreateFrame("Frame", name .. "Thumb", track)
|
|
cursor:SetWidth(WIDTH)
|
|
cursor:SetHeight(CURSOR_MIN)
|
|
cursor:EnableMouse(true)
|
|
bar.cursor = cursor
|
|
|
|
local cTop = slice(cursor, ATLAS.cursorTip, "ARTWORK")
|
|
cTop:SetHeight(CURSOR_TIP)
|
|
cTop:SetPoint("TOP", cursor, "TOP", 0, 0)
|
|
|
|
-- Same piece, flipped: swap the top and bottom of its atlas rectangle.
|
|
local cBottom = slice(cursor, ATLAS.cursorTip, "ARTWORK")
|
|
local e = ForeverUI.AtlasEntry(ATLAS.cursorTip)
|
|
if e then
|
|
cBottom:SetTexCoord(e[2], e[3], e[5], e[4])
|
|
end
|
|
cBottom:SetHeight(CURSOR_TIP)
|
|
cBottom:SetPoint("BOTTOM", cursor, "BOTTOM", 0, 0)
|
|
|
|
local cMiddle = slice(cursor, ATLAS.cursorMiddle, "ARTWORK")
|
|
cMiddle:SetPoint("TOPLEFT", cTop, "BOTTOMLEFT", 0, 0)
|
|
cMiddle:SetPoint("BOTTOMRIGHT", cBottom, "TOPRIGHT", 0, 0)
|
|
|
|
-- Bar methods
|
|
|
|
-- Moves to offset `to`, clamped. The bar knows only its three numbers, not the list.
|
|
-- Calls onScroll(offset) when the offset changes.
|
|
function bar:MoveTo(to)
|
|
local maximum = math.max(0, self.total - self.visibleCount)
|
|
to = math.max(0, math.min(math.floor(to + 0.5), maximum))
|
|
if to == self.offset then
|
|
return
|
|
end
|
|
self.offset = to
|
|
self:Reposition()
|
|
if self.onScroll then
|
|
self.onScroll(to)
|
|
end
|
|
end
|
|
|
|
-- Places the thumb: its height shows the visible share, its position the offset.
|
|
function bar:Reposition()
|
|
local height = self.track:GetHeight() or 0
|
|
local maximum = math.max(0, self.total - self.visibleCount)
|
|
|
|
if height <= 0 or maximum <= 0 then
|
|
self.cursor:Hide()
|
|
return
|
|
end
|
|
|
|
local part = self.visibleCount / self.total
|
|
local size = math.max(CURSOR_MIN, math.floor(height * part + 0.5))
|
|
if size > height then
|
|
size = height
|
|
end
|
|
local travel = height - size
|
|
|
|
self.cursor:SetHeight(size)
|
|
self.cursor:ClearAllPoints()
|
|
self.cursor:SetPoint("TOP", self.track, "TOP", 0,
|
|
-travel * (self.offset / maximum))
|
|
self.cursor:Show()
|
|
end
|
|
|
|
-- The caller gives the row count, rows that fit, current offset. The bar hides when
|
|
-- everything fits. When it shows or hides, onVisibility(shown) tells the caller, whose
|
|
-- content takes or gives back the space.
|
|
function bar:Configure(total, visibleCount, offset)
|
|
self.total = total or 0
|
|
self.visibleCount = visibleCount or 0
|
|
self.offset = offset or 0
|
|
local hasBar = self.total > self.visibleCount
|
|
if hasBar then
|
|
self:Show()
|
|
self:Reposition()
|
|
else
|
|
self:Hide()
|
|
end
|
|
if hasBar ~= self.wasNeeded then
|
|
self.wasNeeded = hasBar
|
|
if self.onVisibility then self.onVisibility(hasBar) end
|
|
end
|
|
end
|
|
|
|
-- Thumb drag: an OnUpdate follows the mouse while the button is held. 3.3.5 has no mouse
|
|
-- tracking on a frame.
|
|
cursor:SetScript("OnMouseDown", function(self)
|
|
self.grab = mouse(self)
|
|
self.grabOffset = bar.offset
|
|
self:SetScript("OnUpdate", function(me)
|
|
local height = bar.track:GetHeight() or 0
|
|
local travel = height - (me:GetHeight() or 0)
|
|
local maximum = math.max(0, bar.total - bar.visibleCount)
|
|
if travel <= 0 or maximum <= 0 then
|
|
return
|
|
end
|
|
local traveled = me.grab - mouse(me)
|
|
bar:MoveTo(me.grabOffset + traveled / travel * maximum)
|
|
end)
|
|
end)
|
|
cursor:SetScript("OnMouseUp", function(self)
|
|
self:SetScript("OnUpdate", nil)
|
|
end)
|
|
|
|
-- Clicking the track jumps one page toward the click.
|
|
track:EnableMouse(true)
|
|
track:SetScript("OnMouseDown", function(self)
|
|
local y = mouse(self)
|
|
local hovered = bar.cursor:GetTop() or 0
|
|
local below = bar.cursor:GetBottom() or 0
|
|
if y > hovered then
|
|
bar:MoveTo(bar.offset - bar.visibleCount)
|
|
elseif y < below then
|
|
bar:MoveTo(bar.offset + bar.visibleCount)
|
|
end
|
|
end)
|
|
|
|
bar:Hide()
|
|
return bar
|
|
end
|