oUF-wow / oUF

WoW AddOn - Unit frame framework.
MIT License
222 stars 58 forks source link

Including alpha in the UpdateColor function #611

Closed Kaszz closed 2 years ago

Kaszz commented 2 years ago

Describe the solution you'd like I want the alpha to be included in updating the health frame's color.

Describe alternatives you've considered I guess I could forego oUF, or maybe hook into the function (no clue if this is possible).

Kaszz commented 2 years ago

I wanted to make my own branch and pull requests, but I lack the rights. The solution should be as simple as changing the function to:

local function UpdateColor(self, event, unit)
    if(not unit or self.unit ~= unit) then return end
    local element = self.Health

    local r, g, b, color
    local _, _, _, a = self.Health:GetStatusBarColor()
    if(element.colorDisconnected and not UnitIsConnected(unit)) then
        color = self.colors.disconnected
    elseif(element.colorTapping and not UnitPlayerControlled(unit) and UnitIsTapDenied(unit)) then
        color = self.colors.tapped
    elseif(element.colorThreat and not UnitPlayerControlled(unit) and UnitThreatSituation('player', unit)) then
        color =  self.colors.threat[UnitThreatSituation('player', unit)]
    elseif(element.colorClass and UnitIsPlayer(unit))
        or (element.colorClassNPC and not UnitIsPlayer(unit))
        or (element.colorClassPet and UnitPlayerControlled(unit) and not UnitIsPlayer(unit)) then
        local _, class = UnitClass(unit)
        color = self.colors.class[class]
    elseif(element.colorSelection and unitSelectionType(unit, element.considerSelectionInCombatHostile)) then
        color = self.colors.selection[unitSelectionType(unit, element.considerSelectionInCombatHostile)]
    elseif(element.colorReaction and UnitReaction(unit, 'player')) then
        color = self.colors.reaction[UnitReaction(unit, 'player')]
    elseif(element.colorSmooth) then
        r, g, b = self:ColorGradient(element.cur or 1, element.max or 1, unpack(element.smoothGradient or self.colors.smooth))
    elseif(element.colorHealth) then
        color = self.colors.health
    end

    if(color) then
        r, g, b = color[1], color[2], color[3]
    end

    if(b) then
        element:SetStatusBarColor(r, g, b, a)

        local bg = element.bg
        if(bg) then
            local mu = bg.multiplier or 1
            bg:SetVertexColor(r * mu, g * mu, b * mu)
        end
    end

    --[[ Callback: Health:PostUpdateColor(unit, r, g, b)
    Called after the element color has been updated.

    * self - the Health element
    * unit - the unit for which the update has been triggered (string)
    * r    - the red component of the used color (number)[0-1]
    * g    - the green component of the used color (number)[0-1]
    * b    - the blue component of the used color (number)[0-1]
    --]]
    if(element.PostUpdateColor) then
        element:PostUpdateColor(unit, r, g, b)
    end
end
p3lim commented 2 years ago

You could try self.Health:GetStatusBarTexture():SetAlpha(0.5) instead, as :GetStatusBarTexture() returns the Texture object and not the texture file (that'd be :GetStatusBarTexture():GetTexture()).

I wanted to make my own branch and pull requests, but I lack the rights.

If you wanted to do this you'd fork the project, create your branch with your changes, then submit a pull request to the originating project from your modified branch, there are GitHub help articles about this subject. But please see if my suggestion works first.

Kaszz commented 2 years ago

My problem with that is then the UpdateColor function overrides the color for a short moment making the frame blink at full alpha causing a look like this:

blink

fafaraway commented 2 years ago

Totally agree with this, I have a similar situation. UpdateColor should contain the alpha value, so we don't have to modify the oUF code directly, or write a bunch of extra code in our own layout.

p3lim commented 2 years ago

How exactly did you get that blinking?

Using this I experienced no blinking whatsoever:

local Health = CreateFrame('Frame', nil, self)
Health:SetAllPoints()
Health.colorClass = true
Health.PostUpdateColor = function()
    Health:GetStatusBarTexture():SetAlpha(0.5)
end
self.Health = Health
Kaszz commented 2 years ago

How exactly did you get that blinking?

For context, I'm working on an extension of the Fader/range indicator feature in the ElvUI unitframes which uses oUF. Currently, it is only possible to alter the alpha of the entire unitframe by changing the alpha of the Health frame, I believe, however, I wanted to only lower the alpha of the "foreground," achieving the look of the gif in the previous comment.

I am new to Lua and any wow addon development, but it seemed that changes were required to oUF and oUF_Fader. In oUF_Fader I changed the ToggleAlpha function from setting alpha like this: self:SetAlpha(endAlpha). To: local r, g, b, a = self.Health:GetStatusBarColor() self.Health:SetStatusBarColor(r, g, b, endAlpha)

Is there an oUF discord that is better suited for questions?

p3lim commented 2 years ago

You'll need to ask the ElvUI people about this, as the solution I provided works fine for oUF, but you're using a fork of it with a plugin we have no control over, which seems to not have any options for overriding.

Altering the alpha of the statusbar texture object should work in both cases though, so you could replace :SetAlpha(endAlpha) with :GetStatusBarTexture():SetAlpha(endAlpha) in the fader plugin too, but we provide no guarantee it'll work since it's not our code.