view ObjectiveTracker/ObjectiveStyle.lua @ 37:e84d645c8ab8

- revised the tracker update function to build its complete data list up front and use the values as points of comparison for determining possible out of place blocks, which will be iterated over afterward to remove what wasn't re-used - also entailed revising the exact role of global event handlers and function hooks, limiting their directions of communication so one doesn't end up calling the other multiple or inifinity times - schema handling polish
author Nenue
date Mon, 18 Apr 2016 07:56:23 -0400
parents e837384ac363
children 07ef62fe201f
line wrap: on
line source
local B = select(2,...).frame
local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
local print = B.print('SetStyle')
-------------------------------------------------------------
--- Deals with swapping between different color palettes
---

local titleFont, textFont = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Regular.ttf]]
local titleSize, textSize = 16, 15
local titleOutline, textOutline = "OUTLINE", "OUTLINE"
local titleSpacing, textSpacing = 3, 3
local unpack, type, pairs, tconcat = unpack, type, pairs, table.concat
local wrapperHeadFont, wrapperHeadSize, wrapperHeadOutline = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 16, 'NONE'
local headerFont, headerSize = [[Interface\Addons\SharedMedia_MyMedia\font\ArchivoNarrow-Bold.ttf]], 24
local headerOutline, headerSpacing = 'OUTLINE', 2


mod.defaults.Style = {
  Format = {
    Frame = {
      Width = 270,
    },
    title = {
      Indent = 0,
      Spacing = 0,
    },
    status = {
      Indent = 5,
      Spacing = 0,
    }
  },
  FontBank = {
    ['Normal'] = _G.VeneerCriteriaFontNormal,
    ['Progress'] = _G.VeneerCriteriaFontProgress,
    ['Complete'] = _G.VeneerCriteriaFontComplete,
    ['Failed'] = _G.VeneerCriteriaFontFailed,
  },
  Normal = {
    title = {
      TextColor = {1, 1, 1, 1},
      Width = 270,
      Spacing = 0,
      Indent = 2,
    },
    titlebg = {
    },
    status = {
      Width = 270,
      Spacing = 0,
    },
    statusbg = {
    },
    Frame = {
    }
  },
  Tracker = {
    Normal = {
      title = {
        Font = {headerFont, headerSize, headerOutline}, Spacing = headerSpacing,
        Indent = 2,
        TextColor = {1, .9, .2, 1},
      },
      titlebg = {
        Gradient = {'VERTICAL', MinColor = {0,0,0,0.25}, MaxColor = {0,0,0,.15}},
      }
    }
  },
  TrackerBlock = {
    Normal = {
      titlebg = {
        Indent = 2,
        Gradient = { 'HORIZONTAL', MinColor = {0.7, 0, 0.9, 1}, MaxColor = {.7, 0, 0.9, .1}},
      },
      title = {
        TextColor = {1,1,1,1},
        Font = {titleFont, titleSize, titleOutline},
        Spacing = titleSpacing,
      },
      status = {
        TextColor = {1,1,1,1},
        Font = {textFont, textSize, textOutline},
        Spacing = textSpacing,
      },
      statusbg = {
        Gradient = { 'HORIZONTAL', MinColor = {0.2, .4, 1, 1}, MaxColor = {.7, 0, 0.9, .1}},
      }
    },
    Daily = {
      titlebg = {
        Gradient = {'HORIZONTAL', MinColor = {0, .4, 1, 1},          MaxColor = {0, 0.4, 1, .1},        },
      },
      statusbg = {
        Gradient = {'HORIZONTAL', MinColor = {0, .4, 1, 1},          MaxColor = {0, 0.35, .90, .1},        },
      },
      title = {
        TextColor = {0.7,1,1,1},
        Font = {titleFont, titleSize, titleOutline},
        Spacing = titleSpacing,
      },
      status = {
        TextColor = {1,1,1,1},
        Font = {textFont, textSize, textOutline},
        Spacing = textSpacing,
      },
    },
    Super = {
      title = {
        TextColor = {1,1,1,1},
        Font = {titleFont, titleSize, titleOutline},
        Spacing = titleSpacing, BackgroundFullWidth = true
      },
      titlebg = {
        Gradient = { 'HORIZONTAL', MinColor = {0, .7, .6, 1}, MaxColor = {0, .7, .6, 1}},
      },
      status = {
        TextColor = {1,1,1,1},
        Font = {textFont, textSize, textOutline},
        Spacing = textSpacing,
      },
      statusbg = {
        Gradient = { 'HORIZONTAL', MinColor = {0, .7, .6, 1}, MaxColor = {0, .7, .6, 1} },
      },
    },
    MouseDown = {
      title = {
        Font = {titleFont, titleSize, titleOutline},
        Spacing = titleSpacing,
      },
      titlebg = {
        Gradient = {'HORIZONTAL',  MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1},        },
      },
      status = {
        Font = {textFont, textSize, textOutline},
        Spacing = textSpacing,
      },
      statusbg = {
        Gradient = {'HORIZONTAL', MinColor = {0.2, .4, 1, 1}, MaxColor = {0.2, .4, 1, 1},        },
      }
    },
    Complete = {
      title = {
        TextColor = {1,1,1,1},
        Font = {titleFont, titleSize, titleOutline},        Spacing = titleSpacing,
      },
      titlebg = {
        Gradient = {'HORIZONTAL', MinColor = {0, 1, 0, 1},          MaxColor = {0, 1, 0, 1},        },
      },
      status = {
        TextColor = {1,1,1,1},
        Font = {textFont, textSize, textOutline},        Spacing = textSpacing,
      },
      statusbg = {
        Gradient = {'HORIZONTAL', MinColor = {0, 1, 0, 1},          MaxColor = {0, 1, 0, 1},        },
      }
    },
    AutoQuest = {
      Normal = {
        titlebg = {
          Indent = 2,
          Gradient = {'HORIZONTAL', MinColor = {0.2, .4, 1, 1}, MaxColor = {.7, 0, 0.9, 1}},
        },
        title = {
          TextColor = {1,1,1,1},
          Font = {titleFont, titleSize, titleOutline},
          Spacing = titleSpacing,
        },
        status = {
          TextColor = {0,1,0,1},
          Font = {textFont, textSize, textOutline},
          Spacing = textSpacing,
        },
        statusbg = {
          Gradient = {'HORIZONTAL', MinColor = {0.2, .4, 1, 1}, MaxColor = {.7, 0, 0.9, 1}},
        }
      },
    },
    Cheevs =  {
      Normal = {

        title = {
          Font = {titleFont, titleSize, titleOutline},
          Spacing = titleSpacing,
        },
        titlebg = {
          Gradient = {'HORIZONTAL', MinColor = {0.2, .4, 1, 1}, MaxColor = {.7, 0, 0.9, 1}},

        },
        status = {
          Font = {textFont, textSize, textOutline},
          Spacing = textSpacing,
        },
        statusbg = {
          Gradient = {'HORIZONTAL', MinColor = {0.2, .4, 1, 1}, MaxColor = {.7, 0, 0.9, 1}},
        },
      },
      Complete = {
        title = {
          Font = {titleFont, titleSize, titleOutline},
          Spacing = titleSpacing,
        },
        titlebg = {
          Gradient = {'HORIZONTAL', MinColor = {0.2, .4, 1, 1}, MaxColor = {.7, 0, 0.9, 1}},
        },
        status = {
          Font = {textFont, textSize, textOutline},
          Spacing = textSpacing,
        },
        statusbg = {
          Gradient = {'HORIZONTAL', MinColor = {0.2, .4, 1, 1}, MaxColor = {.7, 0, 0.9, 1}},
        },
      },
    }
  }
}

local style_cache_func = {}
local block_vars = {
  ['titleSize'] = {'titleWidth', 'titleHeight'},
  ['FrameSize'] = {'width', 'height'}
}
local attrib_vars = {
  ['Font'] = {'height'},
}

mod.BlockStyleCache = {}
local style_cache = mod.BlockStyleCache
mod.regions = {}
mod.regionStyles = {}
mod.SetBlockStyle = function(frame, frameType, ...)
  -- var names intended to reflect argument order
  print('|cFFFFFF00'..frame:GetName()..'|r', frameType, ...)
  --@debug@
  local c = mod.defaults.Normal
  local style_list = {... }
  local styleName = frameType .. '-' .. table.concat(style_list,'')
  local previousClass = {mod.Conf.Style[frameType] }
  local previousClassString = {'frame' }
  local parentName

  if not style_cache[styleName] then
    local style = {}

    --[[
    if mod.defaults.Style[frameType] then
      print(' setting style class |cFF00FFFF'..frameType)
    else
      print(' resorting to class Normal (missing |cFFFF8800'.. frameType..'|r)')
    end
    --]]
    local normal = mod.defaults.Style.Normal
    local root =  mod.defaults.Style[frameType] or normal
    for i, className in ipairs(style_list) do
      print('|cFF00FF00'..i..'|r', className)
      local class = normal
      local childClass
      if previousClass  then
        for i = #previousClass, 1, -1  do
          print('checking if '..className..' child of '.. previousClassString[i])
          if previousClass[i][className] then
            print('  it is!')
            childClass = previousClass[i][className]
            parentName = previousClassString[i]
            break
          end
        end
      end
      if childClass then
        class = childClass
        print('  ChildClass '..parentName..'.|cFFFF0088'.. className .. '|r')
      elseif root[className] then
        class = root[className]
        print('  SubClass |cFF0088FF'.. className .. '|r')
      elseif normal[className] then
        class = normal[className]
        print('  SubClass Normal.|cFFFF0088'..className..'|r')
      else
        --print('  SubClass not found '..className..'')
      end
      tinsert(previousClass, class)
      tinsert(previousClassString, className)

      for elementName, element in pairs(class) do
        if not elementName:match('^%u') then
          --print('   scanning Element |cFF8800FF'.. elementName ..'|r')
          if not style[elementName] then
            style[elementName] = {}
          end
          for key, value in pairs(element) do
            if mod.SetBlockAttribute[key] then
              --print('   |cFF00FF00'..elementName..'|r.|cFF00FFFF'..key..' =', (type(value) == 'table' and ('{'..table.concat(value,', ')..'}') or tostring(value)))
              style[elementName][key] = value
            end

          end
        end

      end
    end

    for k, elements in pairs(mod.defaults.Style.Normal) do
      if not style[k] and type(elements) ~= 'table' then
        style[k] = elements
      end
    end


    --[[print('result for: ', frame:GetName())
    for k,v in pairs(style) do
      if type(v) == 'table' and not k:match('^%u') then
        for kk, vv in pairs(v) do
        --print('  |cFFFFFF00'..k..'|r.|cFF00FF00'..kk..'|r =', (type(vv) == 'table' and ('{'..table.concat(vv,', ')..'}') or tostring(vv)))
        end
      else
        --print(' |cFFFFFFFF' .. k ..'|r =', tostring(v))
      end
    end
    --]]
    print('saving |cFFFFFF00'..styleName)
    style_cache[styleName] = style
  else

    print('using |cFFFF00FF'..styleName)
  end

  local style = style_cache[styleName]

  if not style_cache_func[styleName] then
    local code =
        "return function (frame)\n"..
        "  local func = Veneer.ObjectiveTracker.SetBlockAttribute\n"..
        "  local cache = Veneer.ObjectiveTracker.BlockStyleCache"
            --.. "  print('CacheFunc', '|cFFFFFF00SET|r "..styleName.." |cFFFFFF00ON|r', frame:GetName()) "

    for elementName, styleset in pairs(style) do
        code = code ..
            "\n if frame['"..elementName.."'] then"

        for attributeName, value in pairs(styleset) do
          if mod.SetBlockAttribute[attributeName] then
            --print('  add function '..elementName..':'.. attributeName ..'(', (type(value) == 'table' and ('{'..table.concat(value,', ')..'}') or tostring(value)), ')')


            --mod.SetBlockAttribute[attributeName](region, value)
            code = code
                --.. "\n    print('CacheFunc', '  applying', '|cFF00FFFF" .. attributeName .. "|r to', '|cFF0088FF"..elementName.."|r', cache['"..styleName.."']['"..elementName.."']['".. attributeName .."'])"
                .. "\n\n    func['" .. attributeName .. "'](frame['"..elementName.."'],"..
                " cache['"..styleName.."']['"..elementName.."']['".. attributeName .."'])"

            --- Set any frame.blah variables used in Updates
            if block_vars[elementName .. attributeName] then
              --print('|cFF008800BVar|r', elementName..attributeName)
              for i, blockKey in ipairs(block_vars[elementName .. attributeName]) do
                --print('  assigning |cFF008800'..blockKey..'|r')
                frame[blockKey] = (type(value) == 'table') and value[i] or value
              end
            end

          end
        end
        code = code ..
            "\n  else"..
            --"\n    print('CacheFunc', '  |cFFFF4400missing', frame:GetName()..'."..elementName.."')"..
            "\n  end"
    end
    code = code .. "\nend"
    local result = assert(loadstring(code))
    --print('storing style func', styleName, result())
    style_cache_func[styleName] = result()

  end
  style_cache_func[styleName](frame)

  --- Hardcoding the sizing vars for sanity
  local defaultWidth = mod.Conf.Wrapper.Width
  local normalSettings = mod.defaults.Style.Format
  frame.width = defaultWidth
  frame.statusWidth = defaultWidth - normalSettings.status.Indent
  frame.titleWidth = defaultWidth - normalSettings.title.Indent
  frame.attachmentHeight = frame.attachmentHeight or 0

  if frame.title then
    frame.titleHeight = frame.title and frame.title:GetStringHeight() or 0
    if frame.titleHeight > 0 then
      print('add spacing to', frame.titleHeight)
      frame.titleHeight = frame.titleHeight + (frame.title.spacing or 0)*2
    end

    frame.title.spacing = frame.title.spacing or frame.title:GetSpacing()
    frame.title:SetPoint('LEFT', frame, 'LEFT', normalSettings.title.Indent)
    frame.title:SetPoint('TOP', frame, 'TOP', 0, -frame.title.spacing)
    frame.title:SetWidth(frame.width)
    if frame.titlebg then
      frame.titlebg:SetHeight(frame.titleHeight)
      frame.titlebg:SetWidth(frame.width)
    end
    print('  titleHeight', frame.titleHeight, 'indent', normalSettings.title.Indent, 'spacing', frame.title.spacing)
    print('    -- text:', frame.title:GetSize())
    print('    --   bg:', frame.titlebg:GetSize())

  else
    frame.titleHeight = 0
  end


  if frame.status and (frame.status:GetText() or frame.attachmentHeight > 0) then
    frame.statusHeight   = frame.status and frame.status:GetStringHeight()  or 0
    if frame.statusHeight > 0 then
      frame.statusHeight = frame.statusHeight  + (frame.status.spacing or 0)*2
    end

    frame.status.spacing = frame.status.spacing or frame.status:GetSpacing()

    frame.status:SetWidth(frame.width)
    frame.status:SetPoint('LEFT', frame, 'LEFT', normalSettings.status.Indent, 0)
    frame.status:SetPoint('TOP', frame.titlebg, 'BOTTOM', 0, 0)
    --frame.status:SetHeight(frame.statusHeight)
    if frame.statusbg then

      --frame.statusbg:SetHeight(frame.statusHeight + (frame.attachmentHeight or 0))
      --frame.statusbg:SetPoint('BOTTOM', frame, 'BOTTOM', 0, 0)
      frame.statusbg:SetWidth(frame.width)
    end
    print('  status tHeight', frame.statusHeight, 'indent', normalSettings.status.Indent, 'spacing', frame.status.spacing)
  else
    if frame.status then
      frame.status:Hide()
    end
    if frame.statusbg then
      frame.statusbg:Hide()
    end
    frame.statusHeight = 0
  end

  frame.height = frame.titleHeight + frame.statusHeight + (frame.attachmentHeight or 0)
  frame:SetSize(frame.width, frame.height)
  print('  |cFF0088FFsizing frame', frame.width, frame.height)
end

--- Argument containers
local o -- text flag
local a1, a2, a3, a4, b1, b2, b3, b4 -- color1, color2
local f1, f2, f3 -- font
local w1, w2 -- size
local p1, p2, p3, x, y -- path/point args
mod.SetBlockAttribute = {}
local sb = mod.SetBlockAttribute
local print = B.print('Attribute')
sb.Gradient = function(region, value)
  print('|cFF8844FFGradient|r', region:GetName(), unpack(value))
  o = value[1]
  a1, a2, a3, a4 = unpack(value.MinColor)
  b1, b2, b3, b4 = unpack(value.MaxColor)
  region:SetVertexColor(1,1,1)
  region:SetTexture(1,1,1,1)
  region:SetGradientAlpha(o, a1, a2, a3, a4, b1, b2, b3, b4)
end

sb.Background = function(region, value)
  print('|cFF0088FFBackground|r', unpack(value))
  region:SetVertexColor(1,1,1) -- reset
  region:SetTexture(unpack(value))
end
sb.BackgroundComplex = function (region, value)
  local left, tile, right = value.Left, value.Tile, value.Right

end
sb.Font = function(region, value)
  f1, f2, f3 = unpack(value)
  print('|cFFFFFF00Font|r', f1, f2, f3)
  region:SetFont(f1, f2, f3)
end

sb.Spacing = function(region, value)
  print('FontSpacing', region:GetName(), value)
  region:SetSpacing(value)
  region.spacing = value
end

sb.TextColor = function(region, value)
  a1, a2, a3, a4 = unpack(value)
  print('TextColor', a1, a2, a3, a4)
  region:SetTextColor(a1, a2, a3, a4)
end
sb.Texture = function(region, value)

  p1, a1, a2, a3, a4 = unpack(value)
  print('Texture', p1, a1, a2, a3, a4)
  region:SetTexture(p1)
  if a1 then
    region:SetTexCoord(a1, a2, a3, a4)
  end
end
sb.Width = function(region, value)
  w1 = value
  region:SetWidth(w1)
end

sb.Height = function(region, value)
  w2 = value
  region:SetHeight(w2)
end
sb.Size = function(region, value)
  w1, w2 = unpack(value)
  region:SetSize(w1, w2)
end