Skip to content

Commit

Permalink
Texture SUb Element
Browse files Browse the repository at this point in the history
  • Loading branch information
InfusOnWoW committed Dec 10, 2024
1 parent ca830b2 commit 5a5940a
Show file tree
Hide file tree
Showing 9 changed files with 556 additions and 81 deletions.
184 changes: 184 additions & 0 deletions WeakAuras/BaseRegions/Texture.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
if not WeakAuras.IsLibsOK() then return end

---@type string
local AddonName = ...
---@class Private
local Private = select(2, ...)

local L = WeakAuras.L

--- @class TextureBase
Private.TextureBase = {}

--- @class TextureBaseInstance
--- @field texture Texture
--- @field mirror_h boolean
--- @field mirror_v boolean
--- @field mirror boolean
--- @field rotation number
--- @field effectiveRotation number
--- @field canRotate boolean
--- @field textureWrapMode WrapMode

--- @class TextureBaseOptions
--- @field canRotate boolean
--- @field mirror boolean
--- @field rotation number
--- @field textureWrapMode WrapMode

local SQRT2 = sqrt(2)
local function GetRotatedPoints(degrees, scaleForFullRotate)
local angle = rad(135 - degrees)
local factor = scaleForFullRotate and 1 or SQRT2
local vx = math.cos(angle) / factor
local vy = math.sin(angle) / factor

return 0.5+vx,0.5-vy , 0.5-vy,0.5-vx , 0.5+vy,0.5+vx , 0.5-vx,0.5+vy
end

local GetAtlasInfo = C_Texture and C_Texture.GetAtlasInfo or GetAtlasInfo

function Private.TextureBase:IsAtlas(input)
return type(input) == "string" and GetAtlasInfo(input) ~= nil
end

local funcs = {
--- @class TextureBaseInstance
--- @field ClearAllPoints fun(self: TextureBaseInstance)
ClearAllPoints = function(self)
self.texture:ClearAllPoints()
end,

--- @class TextureBaseInstance
--- @field SetAllPoints fun(self: TextureBaseInstance, ... : any)
SetAllPoints = function(self, ...)
self.texture:SetAllPoints(...)
end,

--- @class TextureBaseInstance
--- @field DoTexCoord fun(self: TextureBaseInstance)
DoTexCoord = function(self)
local mirror_h, mirror_v = self.mirror_h, self.mirror_v
if(self.mirror) then
mirror_h = not mirror_h
end
local ulx,uly , llx,lly , urx,ury , lrx,lry
= GetRotatedPoints(self.effectiveRotation, self.canRotate and not self.texture.IsAtlas)
if(mirror_h) then
if(mirror_v) then
self.texture:SetTexCoord(lrx,lry , urx,ury , llx,lly , ulx,uly)
else
self.texture:SetTexCoord(urx,ury , lrx,lry , ulx,uly , llx,lly)
end
else
if(mirror_v) then
self.texture:SetTexCoord(llx,lly , ulx,uly , lrx,lry , urx,ury)
else
self.texture:SetTexCoord(ulx,uly , llx,lly , urx,ury , lrx,lry)
end
end
end,

--- @class TextureBaseInstance
--- @field SetMirrorFromScale fun(self: TextureBaseInstance, h: boolean, v: boolean)
SetMirrorFromScale = function(self, h, v)
if self.mirror_h == h and self.mirror_v == v then
return
end
self.mirror_h = h
self.mirror_v = v
self:DoTexCoord()
end,

--- @class TextureBaseInstance
--- @field SetMirror fun(self: TextureBaseInstance, b: boolean)
SetMirror = function(self, b)
if self.mirror == b then
return
end
self.mirror = b
self:DoTexCoord()
end,

--- @class TextureBaseInstance
--- @field SetTexture fun(self: TextureBaseInstance, file: number|string)
SetTexture = function(self, file)
self.textureName = file
local oldIsAtlas = self.texture.IsAtlas
Private.SetTextureOrAtlas(self.texture, self.textureName, self.textureWrapMode, self.textureWrapMode)
if self.texture.IsAtlas ~= oldIsAtlas then
self:DoTexCoord()
end
end,

--- @class TextureBaseInstance
--- @field SetColor fun(self: TextureBaseInstance, r: number, g: number, b: number, a: number)
SetVertexColor = function(self, r, g, b, a)
self.texture:SetVertexColor(r, g, b,a)
end,

--- @class TextureBaseInstance
--- @field SetDesaturated fun(self: TextureBaseInstance, b: boolean)
SetDesaturated = function(self, b)
self.texture:SetDesaturated(b)
end,

--- @class TextureBaseInstance
--- @field SetAnimRotation fun(self: TextureBaseInstance, degrees: number?)
SetAnimRotation = function(self, degrees)
self.animRotation = degrees
self:UpdateEffectiveRotation()
end,

--- @class TextureBaseInstance
--- @field SetRotation fun(self: TextureBaseInstance, degrees: number)
SetRotation = function(self, degrees)
self.rotation = degrees
self:UpdateEffectiveRotation()
end,

--- @class TextureBaseInstance
--- @field UpdateEffectiveRotation fun(self: TextureBaseInstance)
UpdateEffectiveRotation = function(self)
self.effectiveRotation = self.animRotation or self.rotation
self:DoTexCoord()
end,

--- @class TextureBaseInstance
--- @field GetBaseRotation fun(self: TextureBaseInstance): number
GetBaseRotation = function(self)
return self.rotation
end
}

--- @type fun(frame: Frame) : TextureBaseInstance
function Private.TextureBase.create(frame)
local base = {}

for funcName, func in pairs(funcs) do
base[funcName] = func
end

local texture = frame:CreateTexture()
texture:SetSnapToPixelGrid(false)
texture:SetTexelSnappingBias(0)

base.texture = texture

--- @cast base TextureBaseInstance
return base
end

-- TODO better type for options
--- @type fun(base: TextureBaseInstance, options: TextureBaseOptions)
function Private.TextureBase.modify(base, options)
base.canRotate = options.canRotate
base.mirror = options.mirror
base.rotation = options.rotation
base.effectiveRotation = base.rotation
base.textureWrapMode = options.textureWrapMode

base.texture:SetDesaturated(options.desaturate)
base.texture:SetBlendMode(options.blendMode)
base:DoTexCoord()
end
94 changes: 20 additions & 74 deletions WeakAuras/RegionTypes/Texture.lua
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,7 @@ local function create(parent)
region:SetResizable(true);
region:SetResizeBounds(1, 1)

local texture = region:CreateTexture();
texture:SetSnapToPixelGrid(false)
texture:SetTexelSnappingBias(0)
local texture = Private.TextureBase.create(region)
region.texture = texture;
texture:SetAllPoints(region);

Expand All @@ -99,73 +97,40 @@ local function create(parent)
return region;
end

local SQRT2 = sqrt(2)
local function GetRotatedPoints(degrees, scaleForFullRotate)
local angle = rad(135 - degrees);
local factor = scaleForFullRotate and 1 or SQRT2
local vx = math.cos(angle) / factor
local vy = math.sin(angle) / factor

return 0.5+vx,0.5-vy , 0.5-vy,0.5-vx , 0.5+vy,0.5+vx , 0.5-vx,0.5+vy
end

local function modify(parent, region, data)
Private.regionPrototype.modify(parent, region, data);
region.texture:SetDesaturated(data.desaturate)
region:SetWidth(data.width);
region:SetHeight(data.height);
region.width = data.width;
region.height = data.height;
region.scalex = 1;
region.scaley = 1;
region.texture:SetBlendMode(data.blendMode);

region.mirror = data.mirror

local function DoTexCoord()
local mirror_h, mirror_v = region.mirror_h, region.mirror_v;
if(region.mirror) then
mirror_h = not mirror_h;
end
local ulx,uly , llx,lly , urx,ury , lrx,lry
= GetRotatedPoints(region.effectiveRotation, data.rotate and not region.texture.IsAtlas)
if(mirror_h) then
if(mirror_v) then
region.texture:SetTexCoord(lrx,lry , urx,ury , llx,lly , ulx,uly);
else
region.texture:SetTexCoord(urx,ury , lrx,lry , ulx,uly , llx,lly);
end
else
if(mirror_v) then
region.texture:SetTexCoord(llx,lly , ulx,uly , lrx,lry , urx,ury);
else
region.texture:SetTexCoord(ulx,uly , llx,lly , urx,ury , lrx,lry);
end
end
end

region.rotation = data.rotation
region.effectiveRotation = region.rotation
Private.TextureBase.modify(region.texture, {
canRotate = data.rotate,
desaturate = data.desaturate,
blendMode = data.blendMode,
mirror = data.mirror,
rotation = data.rotation,
textureWrapMode = data.textureWrapMode
})

function region:Scale(scalex, scaley)
region.scalex = scalex;
region.scaley = scaley;
local mirror_h, mirror_v
if(scalex < 0) then
region.mirror_h = true;
mirror_h = true
scalex = scalex * -1;
else
region.mirror_h = nil;
end
region:SetWidth(region.width * scalex);
if(scaley < 0) then
scaley = scaley * -1;
region.mirror_v = true;
else
region.mirror_v = nil;
mirror_v = true
end
region:SetHeight(region.height * scaley);

DoTexCoord();
region.texture:SetMirrorFromScale(mirror_h, mirror_v)
end

function region:SetRegionWidth(width)
Expand All @@ -179,29 +144,17 @@ local function modify(parent, region, data)
end

function region:SetMirror(mirror)
region.mirror = mirror
DoTexCoord()
self.texture:SetMirror(mirror)
end

function region:Update()
if self.state.texture then
self:SetTexture(self.state.texture)
self.texture:SetTexture(self.state.texture)
end
self:UpdateProgress()
end

function region:SetTexture(texture)
if self.textureName == texture then
return
end
self.textureName = texture
local oldIsAtlas = self.texture.IsAtlas
Private.SetTextureOrAtlas(self.texture, self.textureName, data.textureWrapMode, data.textureWrapMode);
if self.texture.IsAtlas ~= oldIsAtlas then
DoTexCoord()
end
end
region:SetTexture(data.texture)
region.texture:SetTexture(data.texture)

function region:Color(r, g, b, a)
region.color_r = r;
Expand Down Expand Up @@ -233,29 +186,22 @@ local function modify(parent, region, data)
region:Color(data.color[1], data.color[2], data.color[3], data.color[4]);

function region:SetDesaturated(b)
region.texture:SetDesaturated(b);
self.texture:SetDesaturated(b)
end

--- @type fun(degrees: number?)
function region:SetAnimRotation(degrees)
region.animRotation = degrees
region:UpdateEffectiveRotation()
self.texture:SetAnimRotation(degrees)
end

--- @type fun(degrees: number)
function region:SetRotation(degrees)
region.rotation = degrees
region:UpdateEffectiveRotation()
end

function region:UpdateEffectiveRotation()
region.effectiveRotation = region.animRotation or region.rotation
DoTexCoord()
self.texture:SetRotation(degrees)
end

--- @type fun(): number
function region:GetBaseRotation()
return region.rotation
return self.texture:GetBaseRotation()
end
region:SetRotation(data.rotation)

Expand Down
Loading

0 comments on commit 5a5940a

Please sign in to comment.