You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
5.4 KiB

-- NumericBox.lua
-- @Author : DengSir (tdaddon@163.com)
-- @Link : https://dengsir.github.io
-- @Date : 10/15/2018, 10:46:28 PM
local MAJOR, MINOR = 'NumericBox', 2
local GUI = LibStub('tdGUI-1.0')
local NumericBox = GUI:NewClass(MAJOR, MINOR, GUI:GetClass('InputBox'))
if not NumericBox then return end
function NumericBox:Constructor()
self:SetNumeric(true)
self:SetMinMaxValues(0, 99)
self:SetValueStep(1)
self:SetScript('OnTextChanged', self.OnTextChanged)
self:SetScript('OnMouseWheel', self.OnMouseWheel)
self:SetScript('OnEditFocusLost', self.OnTextChanged)
end
function NumericBox:SetNumber(num)
if num < self._minValue then
num = self._minValue
elseif num > self._maxValue then
num = self._maxValue
end
self:SuperCall('SetNumber', num)
end
function NumericBox:GetMinMaxValues()
return self._minValue, self._maxValue
end
function NumericBox:SetMinMaxValues(minValue, maxValue)
if type(minValue) ~= 'number' then
error(([[bad argument #1 to 'SetMinMaxValues' (number expected, got %s)]]):format(type(minValue)), 2)
end
if type(maxValue) ~= 'number' then
error(([[bad argument #2 to 'SetMinMaxValues' (number expected, got %s)]]):format(type(maxValue)), 2)
end
if minValue < 0 then
error('err min value', 2)
end
if minValue > maxValue then
error('err max value', 2)
end
self._minValue = floor(minValue)
self._maxValue = floor(maxValue)
self:SetMaxBytes(#(tostring(self._maxValue)) + 1)
self:OnTextChanged()
self:OnEnableChanged()
self:Fire('OnMinMaxChanged', minValue, maxValue)
end
function NumericBox:SetValueStep(step)
self._step = step
end
function NumericBox:GetValueStep()
return self._step
end
function NumericBox:OnTextChanged(userInput)
if not userInput or #self:GetText() == self:GetMaxBytes() - 1 then
local value = self:GetNumber()
if value < self._minValue then
return self:SetNumber(self._minValue)
elseif value > self._maxValue then
return self:SetNumber(self._maxValue)
end
end
self:OnEnableChanged()
local value = self:GetNumber()
if value ~= self._prev then
self._prev = value
self:Fire('OnValueChanged', value)
end
end
function NumericBox:OnMouseWheel(delta)
if not self:IsEnabled() then
return
end
if IsShiftKeyDown() then
self:SetNumber(self:GetNumber() + delta * self._step * 3)
elseif IsControlKeyDown() then
self:SetNumber(delta > 0 and self._maxValue or self._minValue)
else
self:SetNumber(self:GetNumber() + delta * self._step)
end
end
function NumericBox:OnEnableChanged()
if not self.PlusButton then
return
end
local isEnabled = self:IsEnabled()
local value = self:GetNumber()
self.PlusButton:SetEnabled(isEnabled and value < self._maxValue)
self.MinusButton:SetEnabled(isEnabled and value > self._minValue)
end
local function ButtonOnClick(self)
self:GetParent():OnMouseWheel(self.delta)
end
local function LayoutTexture(button, texture, x, y, ...)
button:SetNormalTexture(texture)
button:SetDisabledTexture(texture)
button:SetPushedTexture(texture)
button:SetHighlightTexture(texture, 'ADD')
local texture = button:GetNormalTexture()
texture:ClearAllPoints()
texture:SetPoint('CENTER', x, y)
texture:SetSize(12, 8)
texture:SetTexCoord(...)
local texture = button:GetDisabledTexture()
texture:ClearAllPoints()
texture:SetPoint('CENTER', x, y)
texture:SetSize(12, 8)
texture:SetTexCoord(...)
texture:SetDesaturated(true)
texture:SetAlpha(0.5)
local texture = button:GetPushedTexture()
texture:ClearAllPoints()
texture:SetPoint('CENTER', x + 1, y -1)
texture:SetSize(12, 8)
texture:SetTexCoord(...)
local texture = button:GetHighlightTexture()
texture:ClearAllPoints()
texture:SetPoint('CENTER', x, y)
texture:SetSize(12, 8)
texture:SetTexCoord(...)
end
function NumericBox:SetButtonsEnabled(state)
if state then
if not self.PlusButton then
local PlusButton = CreateFrame('Button', nil, self) do
PlusButton:SetWidth(12)
PlusButton:SetPoint('BOTTOMRIGHT', self, 'RIGHT', -3, 0)
PlusButton:SetPoint('TOPRIGHT', -3, 0)
PlusButton:SetScript('OnClick', ButtonOnClick)
PlusButton.delta = 1
LayoutTexture(PlusButton, [[Interface\BUTTONS\Arrow-Up-Down]], 0, -1, 0, 1, 0.5, 0.9)
end
local MinusButton = CreateFrame('Button', nil, self) do
MinusButton:SetWidth(12)
MinusButton:SetPoint('TOPRIGHT', self, 'RIGHT', -3, 0)
MinusButton:SetPoint('BOTTOMRIGHT', -3, 0)
MinusButton:SetScript('OnClick', ButtonOnClick)
MinusButton.delta = -1
LayoutTexture(MinusButton, [[Interface\BUTTONS\Arrow-Down-Down]], 0, 1, 0, 1, 0.1, 0.5)
end
self.PlusButton = PlusButton
self.MinusButton = MinusButton
end
self.PlusButton:Show()
self.MinusButton:Show()
self:SetTextInsets(3, 15, 0, 0)
else
if self.PlusButton then
self.PlusButton:Hide()
self.MinusButton:Hide()
end
self:SetTextInsets(3, 3, 0, 0)
end
end
function NumericBox:IsButtonsEnabled()
return self.PlusButton or self.PlusButton:IsShown()
end