yellowfive@57: --[[----------------------------------------------------------------------------- yellowfive@57: Slider Widget yellowfive@57: Graphical Slider, like, for Range values. yellowfive@57: -------------------------------------------------------------------------------]] yellowfive@57: local Type, Version = "Slider", 21 yellowfive@57: local AceGUI = LibStub and LibStub("AceGUI-3.0", true) yellowfive@57: if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end yellowfive@57: yellowfive@57: -- Lua APIs yellowfive@57: local min, max, floor = math.min, math.max, math.floor yellowfive@57: local tonumber, pairs = tonumber, pairs yellowfive@57: yellowfive@57: -- WoW APIs yellowfive@57: local PlaySound = PlaySound yellowfive@57: local CreateFrame, UIParent = CreateFrame, UIParent yellowfive@57: yellowfive@57: -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded yellowfive@57: -- List them here for Mikk's FindGlobals script yellowfive@57: -- GLOBALS: GameFontHighlightSmall yellowfive@57: yellowfive@57: --[[----------------------------------------------------------------------------- yellowfive@57: Support functions yellowfive@57: -------------------------------------------------------------------------------]] yellowfive@57: local function UpdateText(self) yellowfive@57: local value = self.value or 0 yellowfive@57: if self.ispercent then yellowfive@57: self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10)) yellowfive@57: else yellowfive@57: self.editbox:SetText(floor(value * 100 + 0.5) / 100) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function UpdateLabels(self) yellowfive@57: local min, max = (self.min or 0), (self.max or 100) yellowfive@57: if self.ispercent then yellowfive@57: self.lowtext:SetFormattedText("%s%%", (min * 100)) yellowfive@57: self.hightext:SetFormattedText("%s%%", (max * 100)) yellowfive@57: else yellowfive@57: self.lowtext:SetText(min) yellowfive@57: self.hightext:SetText(max) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: --[[----------------------------------------------------------------------------- yellowfive@57: Scripts yellowfive@57: -------------------------------------------------------------------------------]] yellowfive@57: local function Control_OnEnter(frame) yellowfive@57: frame.obj:Fire("OnEnter") yellowfive@57: end yellowfive@57: yellowfive@57: local function Control_OnLeave(frame) yellowfive@57: frame.obj:Fire("OnLeave") yellowfive@57: end yellowfive@57: yellowfive@57: local function Frame_OnMouseDown(frame) yellowfive@57: frame.obj.slider:EnableMouseWheel(true) yellowfive@57: AceGUI:ClearFocus() yellowfive@57: end yellowfive@57: yellowfive@57: local function Slider_OnValueChanged(frame) yellowfive@57: local self = frame.obj yellowfive@57: if not frame.setup then yellowfive@57: local newvalue = frame:GetValue() yellowfive@57: if self.step and self.step > 0 then yellowfive@57: local min_value = self.min or 0 yellowfive@57: newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value yellowfive@57: end yellowfive@57: if newvalue ~= self.value and not self.disabled then yellowfive@57: self.value = newvalue yellowfive@57: self:Fire("OnValueChanged", newvalue) yellowfive@57: end yellowfive@57: if self.value then yellowfive@57: UpdateText(self) yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function Slider_OnMouseUp(frame) yellowfive@57: local self = frame.obj yellowfive@57: self:Fire("OnMouseUp", self.value) yellowfive@57: end yellowfive@57: yellowfive@57: local function Slider_OnMouseWheel(frame, v) yellowfive@57: local self = frame.obj yellowfive@57: if not self.disabled then yellowfive@57: local value = self.value yellowfive@57: if v > 0 then yellowfive@57: value = min(value + (self.step or 1), self.max) yellowfive@57: else yellowfive@57: value = max(value - (self.step or 1), self.min) yellowfive@57: end yellowfive@57: self.slider:SetValue(value) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function EditBox_OnEscapePressed(frame) yellowfive@57: frame:ClearFocus() yellowfive@57: end yellowfive@57: yellowfive@57: local function EditBox_OnEnterPressed(frame) yellowfive@57: local self = frame.obj yellowfive@57: local value = frame:GetText() yellowfive@57: if self.ispercent then yellowfive@57: value = value:gsub('%%', '') yellowfive@57: value = tonumber(value) / 100 yellowfive@57: else yellowfive@57: value = tonumber(value) yellowfive@57: end yellowfive@57: yellowfive@57: if value then yellowfive@57: PlaySound("igMainMenuOptionCheckBoxOn") yellowfive@57: self.slider:SetValue(value) yellowfive@57: self:Fire("OnMouseUp", value) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: local function EditBox_OnEnter(frame) yellowfive@57: frame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1) yellowfive@57: end yellowfive@57: yellowfive@57: local function EditBox_OnLeave(frame) yellowfive@57: frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8) yellowfive@57: end yellowfive@57: yellowfive@57: --[[----------------------------------------------------------------------------- yellowfive@57: Methods yellowfive@57: -------------------------------------------------------------------------------]] yellowfive@57: local methods = { yellowfive@57: ["OnAcquire"] = function(self) yellowfive@57: self:SetWidth(200) yellowfive@57: self:SetHeight(44) yellowfive@57: self:SetDisabled(false) yellowfive@57: self:SetIsPercent(nil) yellowfive@57: self:SetSliderValues(0,100,1) yellowfive@57: self:SetValue(0) yellowfive@57: self.slider:EnableMouseWheel(false) yellowfive@57: end, yellowfive@57: yellowfive@57: -- ["OnRelease"] = nil, yellowfive@57: yellowfive@57: ["SetDisabled"] = function(self, disabled) yellowfive@57: self.disabled = disabled yellowfive@57: if disabled then yellowfive@57: self.slider:EnableMouse(false) yellowfive@57: self.label:SetTextColor(.5, .5, .5) yellowfive@57: self.hightext:SetTextColor(.5, .5, .5) yellowfive@57: self.lowtext:SetTextColor(.5, .5, .5) yellowfive@57: --self.valuetext:SetTextColor(.5, .5, .5) yellowfive@57: self.editbox:SetTextColor(.5, .5, .5) yellowfive@57: self.editbox:EnableMouse(false) yellowfive@57: self.editbox:ClearFocus() yellowfive@57: else yellowfive@57: self.slider:EnableMouse(true) yellowfive@57: self.label:SetTextColor(1, .82, 0) yellowfive@57: self.hightext:SetTextColor(1, 1, 1) yellowfive@57: self.lowtext:SetTextColor(1, 1, 1) yellowfive@57: --self.valuetext:SetTextColor(1, 1, 1) yellowfive@57: self.editbox:SetTextColor(1, 1, 1) yellowfive@57: self.editbox:EnableMouse(true) yellowfive@57: end yellowfive@57: end, yellowfive@57: yellowfive@57: ["SetValue"] = function(self, value) yellowfive@57: self.slider.setup = true yellowfive@57: self.slider:SetValue(value) yellowfive@57: self.value = value yellowfive@57: UpdateText(self) yellowfive@57: self.slider.setup = nil yellowfive@57: end, yellowfive@57: yellowfive@57: ["GetValue"] = function(self) yellowfive@57: return self.value yellowfive@57: end, yellowfive@57: yellowfive@57: ["SetLabel"] = function(self, text) yellowfive@57: self.label:SetText(text) yellowfive@57: end, yellowfive@57: yellowfive@57: ["SetSliderValues"] = function(self, min, max, step) yellowfive@57: local frame = self.slider yellowfive@57: frame.setup = true yellowfive@57: self.min = min yellowfive@57: self.max = max yellowfive@57: self.step = step yellowfive@57: frame:SetMinMaxValues(min or 0,max or 100) yellowfive@57: UpdateLabels(self) yellowfive@57: frame:SetValueStep(step or 1) yellowfive@57: if self.value then yellowfive@57: frame:SetValue(self.value) yellowfive@57: end yellowfive@57: frame.setup = nil yellowfive@57: end, yellowfive@57: yellowfive@57: ["SetIsPercent"] = function(self, value) yellowfive@57: self.ispercent = value yellowfive@57: UpdateLabels(self) yellowfive@57: UpdateText(self) yellowfive@57: end yellowfive@57: } yellowfive@57: yellowfive@57: --[[----------------------------------------------------------------------------- yellowfive@57: Constructor yellowfive@57: -------------------------------------------------------------------------------]] yellowfive@57: local SliderBackdrop = { yellowfive@57: bgFile = "Interface\\Buttons\\UI-SliderBar-Background", yellowfive@57: edgeFile = "Interface\\Buttons\\UI-SliderBar-Border", yellowfive@57: tile = true, tileSize = 8, edgeSize = 8, yellowfive@57: insets = { left = 3, right = 3, top = 6, bottom = 6 } yellowfive@57: } yellowfive@57: yellowfive@57: local ManualBackdrop = { yellowfive@57: bgFile = "Interface\\ChatFrame\\ChatFrameBackground", yellowfive@57: edgeFile = "Interface\\ChatFrame\\ChatFrameBackground", yellowfive@57: tile = true, edgeSize = 1, tileSize = 5, yellowfive@57: } yellowfive@57: yellowfive@57: local function Constructor() yellowfive@57: local frame = CreateFrame("Frame", nil, UIParent) yellowfive@57: yellowfive@57: frame:EnableMouse(true) yellowfive@57: frame:SetScript("OnMouseDown", Frame_OnMouseDown) yellowfive@57: yellowfive@57: local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal") yellowfive@57: label:SetPoint("TOPLEFT") yellowfive@57: label:SetPoint("TOPRIGHT") yellowfive@57: label:SetJustifyH("CENTER") yellowfive@57: label:SetHeight(15) yellowfive@57: yellowfive@57: local slider = CreateFrame("Slider", nil, frame) yellowfive@57: slider:SetOrientation("HORIZONTAL") yellowfive@57: slider:SetHeight(15) yellowfive@57: slider:SetHitRectInsets(0, 0, -10, 0) yellowfive@57: slider:SetBackdrop(SliderBackdrop) yellowfive@57: slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal") yellowfive@57: slider:SetPoint("TOP", label, "BOTTOM") yellowfive@57: slider:SetPoint("LEFT", 3, 0) yellowfive@57: slider:SetPoint("RIGHT", -3, 0) yellowfive@57: slider:SetValue(0) yellowfive@57: slider:SetScript("OnValueChanged",Slider_OnValueChanged) yellowfive@57: slider:SetScript("OnEnter", Control_OnEnter) yellowfive@57: slider:SetScript("OnLeave", Control_OnLeave) yellowfive@57: slider:SetScript("OnMouseUp", Slider_OnMouseUp) yellowfive@57: slider:SetScript("OnMouseWheel", Slider_OnMouseWheel) yellowfive@57: yellowfive@57: local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") yellowfive@57: lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 3) yellowfive@57: yellowfive@57: local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") yellowfive@57: hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3) yellowfive@57: yellowfive@57: local editbox = CreateFrame("EditBox", nil, frame) yellowfive@57: editbox:SetAutoFocus(false) yellowfive@57: editbox:SetFontObject(GameFontHighlightSmall) yellowfive@57: editbox:SetPoint("TOP", slider, "BOTTOM") yellowfive@57: editbox:SetHeight(14) yellowfive@57: editbox:SetWidth(70) yellowfive@57: editbox:SetJustifyH("CENTER") yellowfive@57: editbox:EnableMouse(true) yellowfive@57: editbox:SetBackdrop(ManualBackdrop) yellowfive@57: editbox:SetBackdropColor(0, 0, 0, 0.5) yellowfive@57: editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80) yellowfive@57: editbox:SetScript("OnEnter", EditBox_OnEnter) yellowfive@57: editbox:SetScript("OnLeave", EditBox_OnLeave) yellowfive@57: editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed) yellowfive@57: editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed) yellowfive@57: yellowfive@57: local widget = { yellowfive@57: label = label, yellowfive@57: slider = slider, yellowfive@57: lowtext = lowtext, yellowfive@57: hightext = hightext, yellowfive@57: editbox = editbox, yellowfive@57: alignoffset = 25, yellowfive@57: frame = frame, yellowfive@57: type = Type yellowfive@57: } yellowfive@57: for method, func in pairs(methods) do yellowfive@57: widget[method] = func yellowfive@57: end yellowfive@57: slider.obj, editbox.obj = widget, widget yellowfive@57: yellowfive@57: return AceGUI:RegisterAsWidget(widget) yellowfive@57: end yellowfive@57: yellowfive@57: AceGUI:RegisterWidgetType(Type,Constructor,Version)