LibDFramework-1.0 (Details Framework)

repository·master·Indexed 42 days ago

https://github.com/tercioo/details-damage-meter

A Lua library for World of Warcraft addons providing a widget toolkit and addon scaffolding system. It includes constructors for Blizzard-style UI elements (buttons, sliders, scroll boxes), a declarative options menu builder via DF:BuildMenu, and lifecycle management through DF:CreateNewAddOn.

Tokens
237.7K
Snippets
660
Records
935
Agent score
48%

What's inside LibDFramework

  1. Overview of DetailsFramework Encounter Journal (Ejc)

    master

    The DetailsFramework.Ejc module is a cached wrapper around the World of Warcraft Encounter Journal API. It is designed to minimize API calls by loading encounter and instance data once on first access and serving subsequent lookups from memory.

    Key features include:

    • Multi-key lookups: Search by name, instanceId, mapId, dungeonEncounterId, or journalEncounterId.
    • Lazy Loading: The cache is automatically built on the first function call, though it can be triggered manually.
    • Content Tracking: Identifies which content belongs to the current expansion.

    Access the module via DF.Ejc.

  2. Understand the LibDFramework-1.0 source layout

    master

    The library is organized into several functional modules. When integrating or extending the framework, note the following key components:

    • Core & Bootstrap: fw.lua (LibStub registration), definitions.lua (LuaCATS types), mixins.lua (Mixin helpers), and load.xml (file load order).
    • UI Components (Widgets): Includes panel.lua, button.lua, dropdown.lua, slider.lua, textentry.lua, label.lua, picture.lua, icon.lua, header.lua, tabcontainer.lua, scrollbox.lua, timebar.lua, and timeline.lua.
    • Advanced Visualization: charts.lua (multi-line rendering), unitframe.lua, keybind.lua, and anchorsystem.lua (nine-point anchoring).
    • Utilities: DFPixelUtil.lua (pixel-perfect scaling), math.lua (vector/geometry), colors.lua, savedvars.lua (profiles), and schedules.lua (timers).
    • Data & Forms: buildmenu.lua (declarative form generation), packtable.lua (serialization), and ejournal.lua (encounter journal access).
    • Examples: Each widget module has a corresponding *.examples.lua file providing runnable usage examples.
  3. Overview of the PackTable system

    master

    The PackTable system, located under detailsFramework.table (or DetailsFramework.table), provides utilities for serializing Lua tables into comma-separated strings and deserializing them back. It supports five distinct data layouts depending on whether you are dealing with flat arrays, nested arrays, or hash maps.

    LayoutPack FunctionUnpack FunctionDescription
    Flat arraypackunpackSingle indexed table.
    Array of arrayspacksubunpacksubMultiple indexed subtables, each with its own length prefix.
    Merged arrayspacksubmergeunpackMultiple subtables flattened into one, single length prefix.
    Hash mappackhashunpackhashKey-value pairs.
    Hash with array valuespackhashsubtableunpackhashsubtableKeys mapping to indexed subtables.
  4. Overview of the Scheduling System

    master

    The detailsFramework.Schedules namespace provides timing and execution control for WoW Lua code. Because WoW runs on a single thread, this system helps prevent frame drops by managing how and when functions execute. It provides five main execution patterns:

    1. Delayed execution: Run a function after a specific delay (After, NewTimer, AfterById, AfterByIdNoCancel).
    2. Repeated execution: Run a function on an interval (NewTicker) or for a fixed number of iterations (NewLooper).
    3. Combat-deferred execution: Queue work that cannot run during combat lockdown (AfterCombat).
    4. Frame-distributed execution: Split large tasks across many frames (LazyExecute).
    5. Next-frame execution: Defer a function to the next render frame (RunNextTick).

    All timing functions are built on top of WoW's C_Timer API.

  5. How line dimensions and text constraints are calculated

    master

    The cooltip library performs automatic width and height accumulation for tooltip lines to ensure proper layout.

    Text Constraints

    • Type 2 (Tooltip with bars): Calls LeftTextSpace() immediately after icon rendering to constrain the left text width so it fits alongside the status bar and right-side content.
    • Per-line Overrides: Individual lines can override text dimensions using leftTextSettings[9] (Width) and leftTextSettings[10] (Height).

    Width Tracking

    • Main Frame (No FixedWidth): stringWidth = leftText + rightText + leftIcon + rightIcon + 10. Updates frame1.w if the new line is wider.
    • Main Frame (With FixedWidth): Forces leftText width to FixedWidth - leftIcon - rightText - rightIcon - 22.
    • Sub Frame (No FixedWidthSub): stringWidth = leftText + rightText + leftIcon + rightIcon. Updates frame2.w if wider.
    • Sub Frame (With FixedWidthSub): Forces leftText width to FixedWidthSub - leftIcon - 12.

    Height Tracking

    • The line height is calculated as: max(leftIcon height, rightIcon height, leftTextHeight, rightTextHeight). This updates frame.hHeight if the line is taller.
  6. Access Dropdown properties via property-style access

    master

    The Dropdown capsule object uses Lua metamethods (__index and __newindex) to allow property-style access to its internal state. Instead of calling explicit getter methods, you can access values directly as if they were native fields.

    Example:

    local v = myDropdown.value     -- Accesses the currently selected value
    myDropdown.width = 200         -- Sets the width via a setter

    Lookup Order for __index:

    1. GetMembers: Checks if the key exists in the GetMembers table (e.g., value, text, shown).
    2. rawget: Checks if the key exists directly on the capsule table.
    3. Method Table: Falls through to DropDownMetaFunctions for method lookups (e.g., :Select(), :Open()).
  7. How the Picture / Image System works

    master

    The picture system provides a Lua wrapper (df_image) around WoW's native Texture objects. This wrapper allows you to use dot-syntax to read and write properties (like image.alpha = 0.5) and call native texture methods directly on the wrapper.

    CRITICAL: Unwrapping for Blizzard APIs Because the wrapper is a plain Lua table and not a native Blizzard object, you must unwrap it when passing it to Blizzard API functions that expect a real Texture or Frame (e.g., SetPoint, SetNormalTexture, or animation APIs). Use wrapper:GetUIObject() to retrieve the underlying native object.

    Key Relationships:

    • wrapper.image or wrapper.widget: The native WoW Texture object.
    • wrapper:GetUIObject(): Returns the native Texture.
    • nativeTexture.MyWrapper: A back-reference from the native texture to the DF wrapper.
  8. Implement custom logic with health bar hooks

    master

    The health bar uses a ScriptHookMixin system. You can respond to events using two patterns:

    1. Additive Hooks (SetHook): Allows multiple independent callbacks to coexist for the same event.
    2. Direct Override: Replacing the function on the object directly (e.g., healthBar.OnHealthChange = function(...)) is faster because it bypasss the hook dispatch loop, but it replaces all other existing hooks for that event.

    Available Hooks

    Hook nameCallback signatureFired when
    OnHealthChange(healthBar, displayedUnit)Health changes (UpdateHealth completes).
    OnHealthMaxChange(healthBar, displayedUnit)Max health changes (UpdateMaxHealth completes).
    OnAbsorbOverflow(healthBar, displayedUnit, overflowFraction)Shield amount exceeds missing health. overflowFraction is 0.0–1.0+ (or 0 when overflow ends).
    OnHide(healthBar)Frame is hidden.
    OnShow(healthBar)Frame is shown.
    -- Additive hook
    healthBar:SetHook("OnHealthChange", function(hb, unit)
        print("Health changed:", hb.currentHealth)
    end)
    
    -- Direct override (high performance)
    healthBar.OnHealthChange = function(self, unit)
        print("Health changed:", self.currentHealth)
    end
  9. Understand the dropdown menu building process

    master

    The DetailsFrameworkDropDownOnMouseDown function handles the logic for opening or closing a dropdown menu when the main button is clicked.

    1. Option Retrieval: It calls object.func(object) via DF:Dispatch to retrieve the optionsTable.
    2. Interruptible Hook: It calls object.OnMouseDownHook. If this hook returns a truthy value, the menu opening process is aborted.
    3. Lazy Frame Creation: For each visible option in the optionsTable, the framework creates a new option row frame using DF:CreateDropdownButton only if it doesn't already exist in the cache.
    4. Widget Population: Each row is populated with widgets like icons, labels, status bars, and right-side buttons based on the option's data.
    5. Auto-Sizing & Scrolling:
      • The menu width expands if the label is too long.
      • If the total height of all options exceeds realsizeH, a scrollbar is enabled and the mouse wheel is activated.
      • The menu automatically scrolls to center the currently selected option.

    Available Hooks/Callbacks

    • object.OnMouseDownHook(button, buttontype, optionsTable, scrollFrame, scrollChild, selectedTexture): Allows interrupting the menu opening.
    • object.OnCreateOptionFrame(dropdown, optionFrame, optionTable): Triggered once per new option frame creation.
    • object.OnUpdateOptionFrame(dropdown, optionFrame, optionTable): Triggered every time an option frame is updated or shown.
  10. Use AuraCache for efficient icon updates

    master

    The AuraCache table within an iconRow is a high-performance lookup used to determine if a spell is already being displayed. This allows developers to avoid redundant SetIcon calls during high-frequency updates.

    Cache Keys and Flags

    • AuraCache[spellId]: Returns true if the spell is currently shown.
    • AuraCache[spellName]: Returns true if the spell is currently shown by name.
    • AuraCache[identifierKey]: Returns true if a specific-keyed icon is shown.
    • AuraCache.canStealOrPurge: Returns true if at least one shown aura is stealable or purgeable.
    • AuraCache.hasEnrage: Returns true if at least one shown aura is an enrage (indicated by an empty-string debuffType).
  11. Understand the Generic Icon Row System

    master

    The Generic Icon Row system is a specialized UI component in the Details Framework designed for displaying icons (buffs, debuffs, or cooldowns) in a row. Unlike the standard CreateIconRow, the generic version supports a custom Horizontal Swipe Visualization.

    This visualization creates a 'bright remaining / dark elapsed' effect:

    1. A CooldownTexture (dark overlay) grows from the bottom to the top.
    2. A CooldownBrightnessTexture (additive-blend icon copy) shrinks from the top.
    3. A CooldownEdge (colored line) sits at the boundary, which can interpolate from green to red if swipe_progressive_color is enabled.

    This system is ideal for tracking auras where a clear, progressive visual of time remaining is required.

  12. Understand GameCooltip data containers and state

    master

    The gameCooltip instance uses several internal tables to manage the content and behavior of the tooltip/menu. These tables are populated via API calls (like AddLine, AddIcon, AddMenu) and are cleared whenever Reset() is called.

    Content Tables

    • LeftTextTable / RightTextTable: Stores main frame text entries.
    • LeftTextTableSub / RightTextTableSub: Stores sub-frame text entries (keyed by main-line index).
    • LeftIconTable / RightIconTable: Stores main frame icon entries.
    • LeftIconTableSub / RightIconTableSub: Stores sub-frame icon entries.
    • StatusBarTable / StatusBarTableSub: Stores status bar entries.
    • WallpaperTable / WallpaperTableSub: Stores wallpaper entries.
    • PopupFrameTable: Stores popup callbacks per line index (contains {onEnter, onLeave, param1, param2}).
    • FunctionsTableMain / FunctionsTableSub: Stores click callbacks for main and sub-menu lines.
    • ParametersTableMain / ParametersTableSub: Stores parameters for the callbacks.
    • FixedValue: A value passed as the second argument to all menu callbacks (after Host). Set via SetFixedParameter().
    • SelectedIndexMain: The index of the currently selected main-menu line.
    • SelectedIndexSec: A map of mainIndex $\rightarrow$ selected sub-menu index.