# LibMatic

Shared widget library for Infinite Loop Alchemist addons.

## Modules

### LibMatic-IconPicker-1.0

A modal icon-browser widget any consumer addon can open. Backed by `IconDataProviderMixin` on modern clients with a `GetMacroIcons` / `GetMacroItemIcons` fallback on older flavors.

```lua
local picker = LibStub("LibMatic-IconPicker-1.0")
picker:Open(currentFileID, function(chosen)
    if chosen then
        -- user picked an icon (fileDataID)
    else
        -- user cancelled
    end
end)
```

Public API:

- `lib:Open(currentIcon, callback)` - opens the modal. `currentIcon` is the fileDataID to preview as already-selected (may be `nil`). `callback` is required; called exactly once with the chosen fileDataID or `nil` if cancelled.
- `lib:Close()` - hides the modal without invoking the callback.
- `lib:IsOpen()` - boolean.

### LibMatic-ChangeLog-1.0

An in-game changelog popup any consumer addon can show. Renders a scrolling AceGUI window from a structured spec, version-gates auto-show, and builds the AceConfig styling panel.

```lua
local lib = LibStub("LibMatic-ChangeLog-1.0")
lib:Show({
    title = "MyAddon - Change Log",
    version = "1.2.0",
    footer = "For the full version history see CurseForge.",
    entries = {
        { version = "1.2.0", date = "05/21/2026", sections = {
            { label = "Added", body = "A new thing." },
        } },
    },
    style = MyAddonDB.profile.changeLogPopUp,
})
```

Public API:

- `lib:Show(spec)` - open or re-focus the popup.
- `lib:ShowIfNew(spec, lastSeenVersion)` - show only when `spec.version` is newer than `lastSeenVersion` and `spec.freshInstall` is not set. Returns `wasNewer`.
- `lib:Close()` - hide the popup.
- `lib:BuildOptionsTable(opts)` - return an AceConfig group for changelog styling. `opts.profile` is the live style table; `opts.defaults`, `opts.order`, `opts.name`, `opts.locale` are optional.

When AceGUI is unavailable the library degrades to a `StaticPopup`.

### LibMatic-CombatTextBounce-1.0

Bouncing combat-text animations. Attaches floating, bouncing text to a frame and plays one-off messages.

Public API:

- `lib:AttachBounce(target, opts)` - attach a managed bounce emitter to a frame.
- `lib:Show(text, opts)` - play a single bounce message.
- `lib:SetDefaultFont(path, size, outline, critOutline)`, `lib:SetBounceStyle(style)` / `lib:GetBounceStyle()`, `lib:SetAlwaysBounce(enabled, scale)` - configure behavior.
- `lib:CancelAll()` - stop every active animation. `lib:Demo()` - preview.

### LibMatic-FitText-1.0

Text-fitting mixins. Sizes a button to its label, or scales a font string down to fit a width.

Public API:

- `lib:Mixin(target, padding, canDecrease)` - mix fit-to-text behavior into a button.
- `lib:MixinFontString(fs, maxWidth)` - mix scale-to-fit behavior into a font string.

### LibMatic-RosterFrame-1.0

A resizable, scrollable roster window widget.

```lua
local lib = LibStub("LibMatic-RosterFrame-1.0")
local window = lib:New(config)
window:Show()
```

Public API:

- `lib:New(config)` - create a roster window, returns a window object.
- Window methods: `Show()`, `Hide()`, `Toggle()`, `IsShown()`, `GetFrame()`, `Refresh()`, `ScheduleRefresh()`, `SetHScroll(enabled)`, `SetZebra(enabled)`.

## Embedding

LibMatic is the single source of truth. Consumer addons do not copy the modules in; they reference this repo two ways.

Local development: symlink the consumer's `Libs/LibMatic` at this repo, so the running addon always uses the live library.

```
ln -s /path/to/libmatic <consumer>/Libs/LibMatic
```

The symlink is listed in the consumer's `.gitignore`; it is a local-machine artifact, not committed.

Packaging: the consumer's `.pkgmeta` declares LibMatic as an external, so the BigWigs packager fetches this repo into `Libs/LibMatic` when it builds the release zip.

```yaml
externals:
  Libs/LibMatic:
    url: git@github.com:InfiniteLoopAlchemist/LibMatic.git
    branch: main
```

This repo's own `.pkgmeta` ignore list keeps `docs` and dev files out of consumer packages. Either way the consumer's `embeds.xml` references the modules at the same paths, after LibStub:

```xml
<Script file="Libs\LibMatic\LibStub\LibStub.lua"/>
<Include file="Libs\LibMatic\LibMatic-IconPicker-1.0\LibMatic-IconPicker-1.0.xml"/>
```

LibStub's version arbitration means the highest-minor copy across all loaded addons wins.

## Standalone test

Install the LibMatic folder as a standalone addon, log in, type `/libmatictest` (alias `/lmt`).

## License

All Rights Reserved. See LICENSE. LibStub keeps its own original license.
