217 lines
6.5 KiB
Lua
217 lines
6.5 KiB
Lua
--[[-----------------------------------------------------------------------------------------------
|
|
|
|
-----------------------------------------------------------------------------------------------]]--
|
|
|
|
local round = function (num) return math.floor(num + .5); end
|
|
|
|
function HybridScrollFrame_OnLoad (self)
|
|
self:EnableMouse(true);
|
|
end
|
|
|
|
function HybridScrollFrame_OnValueChanged (self, value)
|
|
HybridScrollFrame_SetOffset(self, value);
|
|
HybridScrollFrame_UpdateButtonStates(self, value);
|
|
end
|
|
|
|
function HybridScrollFrame_UpdateButtonStates(self, currValue)
|
|
if ( not currValue ) then
|
|
currValue = self.scrollBar:GetValue();
|
|
end
|
|
|
|
self.scrollUp:Enable();
|
|
self.scrollDown:Enable();
|
|
|
|
local minVal, maxVal = self.scrollBar:GetMinMaxValues();
|
|
if ( currValue >= maxVal ) then
|
|
self.scrollBar.thumbTexture:Show();
|
|
if ( self.scrollDown ) then
|
|
self.scrollDown:Disable()
|
|
end
|
|
end
|
|
if ( currValue <= minVal ) then
|
|
self.scrollBar.thumbTexture:Show();
|
|
if ( self.scrollUp ) then
|
|
self.scrollUp:Disable();
|
|
end
|
|
end
|
|
end
|
|
|
|
function HybridScrollFrame_OnMouseWheel (self, delta, stepSize)
|
|
if ( not self.scrollBar:IsVisible() ) then
|
|
return;
|
|
end
|
|
|
|
local minVal, maxVal = 0, self.range;
|
|
stepSize = stepSize or self.stepSize or self.buttonHeight;
|
|
if ( delta == 1 ) then
|
|
self.scrollBar:SetValue(max(minVal, self.scrollBar:GetValue() - stepSize));
|
|
else
|
|
self.scrollBar:SetValue(min(maxVal, self.scrollBar:GetValue() + stepSize));
|
|
end
|
|
end
|
|
|
|
function HybridScrollFrameScrollButton_OnUpdate (self, elapsed)
|
|
self.timeSinceLast = self.timeSinceLast + elapsed;
|
|
if ( self.timeSinceLast >= ( self.updateInterval or 0.08 ) ) then
|
|
if ( not IsMouseButtonDown("LeftButton") ) then
|
|
self:SetScript("OnUpdate", nil);
|
|
elseif ( self:IsMouseOver() ) then
|
|
local parent = self.parent or self:GetParent():GetParent();
|
|
HybridScrollFrame_OnMouseWheel (parent, self.direction, (self.stepSize or parent.buttonHeight/3));
|
|
self.timeSinceLast = 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
function HybridScrollFrameScrollButton_OnClick (self, button, down)
|
|
local parent = self.parent or self:GetParent():GetParent();
|
|
|
|
if ( down ) then
|
|
self.timeSinceLast = (self.timeToStart or -0.2);
|
|
self:SetScript("OnUpdate", HybridScrollFrameScrollButton_OnUpdate);
|
|
HybridScrollFrame_OnMouseWheel (parent, self.direction);
|
|
PlaySound("UChatScrollButton");
|
|
else
|
|
self:SetScript("OnUpdate", nil);
|
|
end
|
|
end
|
|
|
|
function HybridScrollFrame_Update (self, totalHeight, displayedHeight)
|
|
local range = totalHeight - self:GetHeight();
|
|
if ( range > 0 and self.scrollBar ) then
|
|
local minVal, maxVal = self.scrollBar:GetMinMaxValues();
|
|
if ( math.floor(self.scrollBar:GetValue()) >= math.floor(maxVal) ) then
|
|
self.scrollBar:SetMinMaxValues(0, range)
|
|
if ( math.floor(self.scrollBar:GetValue()) ~= math.floor(range) ) then
|
|
self.scrollBar:SetValue(range);
|
|
else
|
|
HybridScrollFrame_SetOffset(self, range); -- If we've scrolled to the bottom, we need to recalculate the offset.
|
|
end
|
|
else
|
|
self.scrollBar:SetMinMaxValues(0, range)
|
|
end
|
|
self.scrollBar:Enable();
|
|
HybridScrollFrame_UpdateButtonStates(self);
|
|
self.scrollBar:Show();
|
|
elseif ( self.scrollBar ) then
|
|
self.scrollBar:SetValue(0);
|
|
if ( self.scrollBar.doNotHide ) then
|
|
self.scrollBar:Disable();
|
|
self.scrollUp:Disable();
|
|
self.scrollDown:Disable();
|
|
self.scrollBar.thumbTexture:Hide();
|
|
else
|
|
self.scrollBar:Hide();
|
|
end
|
|
end
|
|
|
|
self.range = range;
|
|
self.scrollChild:SetHeight(displayedHeight);
|
|
self:UpdateScrollChildRect();
|
|
end
|
|
|
|
function HybridScrollFrame_GetOffset (self)
|
|
return math.floor(self.offset or 0), (self.offset or 0);
|
|
end
|
|
|
|
function HybridScrollFrameScrollChild_OnLoad (self)
|
|
self:GetParent().scrollChild = self;
|
|
end
|
|
|
|
function HybridScrollFrame_ExpandButton (self, offset, height)
|
|
self.largeButtonTop = round(offset);
|
|
self.largeButtonHeight = round(height)
|
|
HybridScrollFrame_SetOffset(self, self.scrollBar:GetValue());
|
|
end
|
|
|
|
function HybridScrollFrame_CollapseButton (self)
|
|
self.largeButtonTop = nil;
|
|
self.largeButtonHeight = nil;
|
|
end
|
|
|
|
function HybridScrollFrame_SetOffset (self, offset)
|
|
local buttons = self.buttons
|
|
local buttonHeight = self.buttonHeight;
|
|
local element, overflow;
|
|
|
|
local scrollHeight = 0;
|
|
|
|
local largeButtonTop = self.largeButtonTop
|
|
if ( largeButtonTop and offset >= largeButtonTop ) then
|
|
local largeButtonHeight = self.largeButtonHeight;
|
|
-- Initial offset...
|
|
element = largeButtonTop / buttonHeight;
|
|
|
|
if ( offset >= (largeButtonTop + largeButtonHeight) ) then
|
|
element = element + 1;
|
|
|
|
local leftovers = (offset - (largeButtonTop + largeButtonHeight) );
|
|
|
|
element = element + ( leftovers / buttonHeight );
|
|
overflow = element - math.floor(element);
|
|
scrollHeight = overflow * buttonHeight;
|
|
else
|
|
scrollHeight = math.abs(offset - largeButtonTop);
|
|
end
|
|
else
|
|
element = offset / buttonHeight;
|
|
overflow = element - math.floor(element);
|
|
scrollHeight = overflow * buttonHeight;
|
|
end
|
|
|
|
if ( math.floor(self.offset or 0) ~= math.floor(element) and self.update ) then
|
|
self.offset = element;
|
|
self.update();
|
|
else
|
|
self.offset = element;
|
|
end
|
|
|
|
self:SetVerticalScroll(scrollHeight);
|
|
end
|
|
|
|
function HybridScrollFrame_CreateButtons (self, buttonTemplate, initialOffsetX, initialOffsetY, initialPoint, initialRelative, offsetX, offsetY, point, relativePoint)
|
|
local scrollChild = self.scrollChild;
|
|
local button, buttonHeight, buttons, numButtons;
|
|
|
|
local buttonName = self:GetName() .. "Button";
|
|
|
|
initialPoint = initialPoint or "TOPLEFT";
|
|
initialRelative = initialRelative or "TOPLEFT";
|
|
point = point or "TOPLEFT";
|
|
relativePoint = relativePoint or "BOTTOMLEFT";
|
|
offsetX = offsetX or 0;
|
|
offsetY = offsetY or 0;
|
|
|
|
if ( self.buttons ) then
|
|
buttons = self.buttons;
|
|
buttonHeight = buttons[1]:GetHeight();
|
|
else
|
|
button = CreateFrame("BUTTON", buttonName .. 1, scrollChild, buttonTemplate);
|
|
buttonHeight = button:GetHeight();
|
|
button:SetPoint(initialPoint, scrollChild, initialRelative, initialOffsetX, initialOffsetY);
|
|
buttons = {}
|
|
tinsert(buttons, button);
|
|
end
|
|
|
|
self.buttonHeight = round(buttonHeight);
|
|
|
|
local numButtons = math.ceil(self:GetHeight() / buttonHeight) + 1;
|
|
|
|
for i = #buttons + 1, numButtons do
|
|
button = CreateFrame("BUTTON", buttonName .. i, scrollChild, buttonTemplate);
|
|
button:SetPoint(point, buttons[i-1], relativePoint, offsetX, offsetY);
|
|
tinsert(buttons, button);
|
|
end
|
|
|
|
scrollChild:SetWidth(self:GetWidth())
|
|
scrollChild:SetHeight(numButtons * buttonHeight);
|
|
self:SetVerticalScroll(0);
|
|
self:UpdateScrollChildRect();
|
|
|
|
self.buttons = buttons;
|
|
local scrollBar = self.scrollBar;
|
|
scrollBar:SetMinMaxValues(0, numButtons * buttonHeight)
|
|
scrollBar:SetValueStep(.005);
|
|
scrollBar:SetValue(0);
|
|
end
|