AuctionLite-classic/ListBox.lua

177 lignes
4.9 KiB
Lua

-------------------------------------------------------------------------------
-- ListBox.lua
--
-- A custom control for use with AceConfig. This control doesn't implement
-- the spec exactly--it just does what it needs to for AuctionLite's purposes.
-------------------------------------------------------------------------------
local _
local AceGUI = LibStub("AceGUI-3.0");
local Version = 1;
local Type = "ListBox";
local ListBox = {};
-- Draw the list box.
local function ListBox_Update(box)
local scrollFrame = box.scrollFrame;
local buttons = box.buttons;
local list = box.obj.list;
local values = box.obj.values;
local numButtons = #buttons;
local numCategories = #list;
if numCategories > numButtons and not scrollFrame:IsShown() then
OptionsList_DisplayScrollBar(box);
elseif numCategories <= numButtons and scrollFrame:IsShown() then
OptionsList_HideScrollBar(box);
end
FauxScrollFrame_Update(scrollFrame, numCategories, numButtons,
buttons[1]:GetHeight());
OptionsList_ClearSelection(box, box.buttons);
local offset = FauxScrollFrame_GetOffset(scrollFrame);
for i = 1, numButtons do
local item = list[i + offset];
if item then
OptionsList_DisplayButton(buttons[i], { name = item, id = i + offset });
if values[i + offset] then
OptionsList_SelectButton(box, buttons[i]);
end
else
OptionsList_HideButton(buttons[i]);
end
end
end
-- Handle a mouse click on an entry.
local function ListButton_OnClick(button)
local box = button:GetParent();
local id = button.element.id;
box.obj:Fire("OnValueChanged", id, not box.obj.values[id]);
box.obj:Fire("OnClosed");
ListBox_Update(box);
end
-- Acquire this widget.
function ListBox:OnAcquire()
self:SetDisabled(false);
end
-- Release this widget for reuse.
function ListBox:OnRelease()
self.frame:ClearAllPoints();
self.frame:Hide();
self:SetDisabled(false);
end
-- Enable/disable the widget.
function ListBox:SetDisabled(disabled)
self.disabled = disabled;
if disabled then
self.box:EnableMouse(false);
self.label:SetTextColor(0.5, 0.5, 0.5);
else
self.box:EnableMouse(true);
self.label:SetTextColor(1, 0.82, 0);
end
end
-- Indicate whether it's a multiselect control.
function ListBox:SetMultiselect(multi)
self.multi = multi;
end
-- Set (and show/hide) the widget label.
function ListBox:SetLabel(text)
if (text or "") == "" then
self.frame:SetHeight(196);
self.box:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, 0);
self.label:Hide();
self.label:SetText("");
else
self.frame:SetHeight(216);
self.box:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -20);
self.label:Show();
self.label:SetText(text);
end
end
-- Set the contents of the widget. Must be a integer-indexed list.
function ListBox:SetList(list)
self.list = list;
self.values = {};
ListBox_Update(self.box);
end
-- Unused, since only multiselect is supported for now.
function ListBox:SetValue(value)
assert(false);
end
-- Activate/deactivate an item.
function ListBox:SetItemValue(key, value)
if not value then
value = nil;
end
self.values[key] = value;
ListBox_Update(self.box);
end
-- Build a new widget. We use OptionsFrameListTemplate as provided by
-- Blizzard, with a few nefarious tweaks.
local function Constructor()
local num = AceGUI:GetNextWidgetNum(Type);
local frame = CreateFrame("Frame", "AceGUI30ListBox" .. num, UIParent);
local self = {};
for k, v in pairs(ListBox) do self[k] = v end;
self.num = num;
self.type = Type;
self.frame = frame;
frame.obj = self;
frame:SetHeight(216);
local box = CreateFrame("Frame", "AceGUI30ListBoxBox" .. num, frame,
"OptionsFrameListTemplate");
box.update = ListBox_Update;
box:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -20);
box:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0);
box:SetHeight(196);
local buttons = box.buttons;
local maxButtons = math.floor((box:GetHeight() - 8) / box.buttonHeight);
while #buttons < maxButtons do
local index = #buttons + 1;
local button = CreateFrame("Button", box:GetName() .. "Button" .. index,
box, "OptionsListButtonTemplate");
button:SetPoint("TOPLEFT", buttons[#buttons], "BOTTOMLEFT");
tinsert(buttons, button);
end
local button;
for _, button in ipairs(buttons) do
button.text:SetText("Button");
button:SetPoint("RIGHT", button:GetParent(), "RIGHT");
button:SetScript("OnClick", ListButton_OnClick);
end
box.buttons = buttons;
self.box = box;
box.obj = self;
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall");
label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -2);
label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -2);
label:SetJustifyH("LEFT");
label:SetHeight(18);
self.label = label;
label.obj = self;
AceGUI:RegisterAsWidget(self);
return self;
end
AceGUI:RegisterWidgetType(Type, Constructor, Version);