8f4bc83 - Initial commit
[wowui.git] / libs / AceGUI-3.0-SharedMediaWidgets / Libs / AceGUI-3.0 / widgets / AceGUIWidget-Slider.lua
1 --[[-----------------------------------------------------------------------------
2 Slider Widget
3 Graphical Slider, like, for Range values.
4 -------------------------------------------------------------------------------]]
5 local Type, Version = "Slider", 20
6 local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8
9 -- Lua APIs
10 local min, max, floor = math.min, math.max, math.floor
11 local tonumber, pairs = tonumber, pairs
12
13 -- WoW APIs
14 local PlaySound = PlaySound
15 local CreateFrame, UIParent = CreateFrame, UIParent
16
17 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
18 -- List them here for Mikk's FindGlobals script
19 -- GLOBALS: GameFontHighlightSmall
20
21 --[[-----------------------------------------------------------------------------
22 Support functions
23 -------------------------------------------------------------------------------]]
24 local function UpdateText(self)
25         local value = self.value or 0
26         if self.ispercent then
27                 self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
28         else
29                 self.editbox:SetText(floor(value * 100 + 0.5) / 100)
30         end
31 end
32
33 local function UpdateLabels(self)
34         local min, max = (self.min or 0), (self.max or 100)
35         if self.ispercent then
36                 self.lowtext:SetFormattedText("%s%%", (min * 100))
37                 self.hightext:SetFormattedText("%s%%", (max * 100))
38         else
39                 self.lowtext:SetText(min)
40                 self.hightext:SetText(max)
41         end
42 end
43
44 --[[-----------------------------------------------------------------------------
45 Scripts
46 -------------------------------------------------------------------------------]]
47 local function Control_OnEnter(frame)
48         frame.obj:Fire("OnEnter")
49 end
50
51 local function Control_OnLeave(frame)
52         frame.obj:Fire("OnLeave")
53 end
54
55 local function Frame_OnMouseDown(frame)
56         frame.obj.slider:EnableMouseWheel(true)
57         AceGUI:ClearFocus()
58 end
59
60 local function Slider_OnValueChanged(frame)
61         local self = frame.obj
62         if not frame.setup then
63                 local newvalue = frame:GetValue()
64                 if newvalue ~= self.value and not self.disabled then
65                         self.value = newvalue
66                         self:Fire("OnValueChanged", newvalue)
67                 end
68                 if self.value then
69                         UpdateText(self)
70                 end
71         end
72 end
73
74 local function Slider_OnMouseUp(frame)
75         local self = frame.obj
76         self:Fire("OnMouseUp", self.value)
77 end
78
79 local function Slider_OnMouseWheel(frame, v)
80         local self = frame.obj
81         if not self.disabled then
82                 local value = self.value
83                 if v > 0 then
84                         value = min(value + (self.step or 1), self.max)
85                 else
86                         value = max(value - (self.step or 1), self.min)
87                 end
88                 self.slider:SetValue(value)
89         end
90 end
91
92 local function EditBox_OnEscapePressed(frame)
93         frame:ClearFocus()
94 end
95
96 local function EditBox_OnEnterPressed(frame)
97         local self = frame.obj
98         local value = frame:GetText()
99         if self.ispercent then
100                 value = value:gsub('%%', '')
101                 value = tonumber(value) / 100
102         else
103                 value = tonumber(value)
104         end
105         
106         if value then
107                 PlaySound("igMainMenuOptionCheckBoxOn")
108                 self.slider:SetValue(value)
109                 self:Fire("OnMouseUp", value)
110         end
111 end
112
113 local function EditBox_OnEnter(frame)
114         frame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
115 end
116
117 local function EditBox_OnLeave(frame)
118         frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
119 end
120
121 --[[-----------------------------------------------------------------------------
122 Methods
123 -------------------------------------------------------------------------------]]
124 local methods = {
125         ["OnAcquire"] = function(self)
126                 self:SetWidth(200)
127                 self:SetHeight(44)
128                 self:SetDisabled(false)
129                 self:SetIsPercent(nil)
130                 self:SetSliderValues(0,100,1)
131                 self:SetValue(0)
132                 self.slider:EnableMouseWheel(false)
133         end,
134
135         -- ["OnRelease"] = nil,
136
137         ["SetDisabled"] = function(self, disabled)
138                 self.disabled = disabled
139                 if disabled then
140                         self.slider:EnableMouse(false)
141                         self.label:SetTextColor(.5, .5, .5)
142                         self.hightext:SetTextColor(.5, .5, .5)
143                         self.lowtext:SetTextColor(.5, .5, .5)
144                         --self.valuetext:SetTextColor(.5, .5, .5)
145                         self.editbox:SetTextColor(.5, .5, .5)
146                         self.editbox:EnableMouse(false)
147                         self.editbox:ClearFocus()
148                 else
149                         self.slider:EnableMouse(true)
150                         self.label:SetTextColor(1, .82, 0)
151                         self.hightext:SetTextColor(1, 1, 1)
152                         self.lowtext:SetTextColor(1, 1, 1)
153                         --self.valuetext:SetTextColor(1, 1, 1)
154                         self.editbox:SetTextColor(1, 1, 1)
155                         self.editbox:EnableMouse(true)
156                 end
157         end,
158
159         ["SetValue"] = function(self, value)
160                 self.slider.setup = true
161                 self.slider:SetValue(value)
162                 self.value = value
163                 UpdateText(self)
164                 self.slider.setup = nil
165         end,
166
167         ["GetValue"] = function(self)
168                 return self.value
169         end,
170
171         ["SetLabel"] = function(self, text)
172                 self.label:SetText(text)
173         end,
174
175         ["SetSliderValues"] = function(self, min, max, step)
176                 local frame = self.slider
177                 frame.setup = true
178                 self.min = min
179                 self.max = max
180                 self.step = step
181                 frame:SetMinMaxValues(min or 0,max or 100)
182                 UpdateLabels(self)
183                 frame:SetValueStep(step or 1)
184                 if self.value then
185                         frame:SetValue(self.value)
186                 end
187                 frame.setup = nil
188         end,
189
190         ["SetIsPercent"] = function(self, value)
191                 self.ispercent = value
192                 UpdateLabels(self)
193                 UpdateText(self)
194         end
195 }
196
197 --[[-----------------------------------------------------------------------------
198 Constructor
199 -------------------------------------------------------------------------------]]
200 local SliderBackdrop  = {
201         bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
202         edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
203         tile = true, tileSize = 8, edgeSize = 8,
204         insets = { left = 3, right = 3, top = 6, bottom = 6 }
205 }
206
207 local ManualBackdrop = {
208         bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
209         edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
210         tile = true, edgeSize = 1, tileSize = 5,
211 }
212
213 local function Constructor()
214         local frame = CreateFrame("Frame", nil, UIParent)
215
216         frame:EnableMouse(true)
217         frame:SetScript("OnMouseDown", Frame_OnMouseDown)
218
219         local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
220         label:SetPoint("TOPLEFT")
221         label:SetPoint("TOPRIGHT")
222         label:SetJustifyH("CENTER")
223         label:SetHeight(15)
224
225         local slider = CreateFrame("Slider", nil, frame)
226         slider:SetOrientation("HORIZONTAL")
227         slider:SetHeight(15)
228         slider:SetHitRectInsets(0, 0, -10, 0)
229         slider:SetBackdrop(SliderBackdrop)
230         slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
231         slider:SetPoint("TOP", label, "BOTTOM")
232         slider:SetPoint("LEFT", 3, 0)
233         slider:SetPoint("RIGHT", -3, 0)
234         slider:SetValue(0)
235         slider:SetScript("OnValueChanged",Slider_OnValueChanged)
236         slider:SetScript("OnEnter", Control_OnEnter)
237         slider:SetScript("OnLeave", Control_OnLeave)
238         slider:SetScript("OnMouseUp", Slider_OnMouseUp)
239         slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
240
241         local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
242         lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 3)
243
244         local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
245         hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3)
246
247         local editbox = CreateFrame("EditBox", nil, frame)
248         editbox:SetAutoFocus(false)
249         editbox:SetFontObject(GameFontHighlightSmall)
250         editbox:SetPoint("TOP", slider, "BOTTOM")
251         editbox:SetHeight(14)
252         editbox:SetWidth(70)
253         editbox:SetJustifyH("CENTER")
254         editbox:EnableMouse(true)
255         editbox:SetBackdrop(ManualBackdrop)
256         editbox:SetBackdropColor(0, 0, 0, 0.5)
257         editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
258         editbox:SetScript("OnEnter", EditBox_OnEnter)
259         editbox:SetScript("OnLeave", EditBox_OnLeave)
260         editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
261         editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
262
263         local widget = {
264                 label       = label,
265                 slider      = slider,
266                 lowtext     = lowtext,
267                 hightext    = hightext,
268                 editbox     = editbox,
269                 alignoffset = 25,
270                 frame       = frame,
271                 type        = Type
272         }
273         for method, func in pairs(methods) do
274                 widget[method] = func
275         end
276         slider.obj, editbox.obj = widget, widget
277
278         return AceGUI:RegisterAsWidget(widget)
279 end
280
281 AceGUI:RegisterWidgetType(Type,Constructor,Version)