2012-06-26 00:13:30 +02:00
|
|
|
-- @docclass
|
2012-03-24 16:22:40 +01:00
|
|
|
UIScrollBar = extends(UIWidget)
|
|
|
|
|
2012-03-25 16:10:15 +02:00
|
|
|
-- private functions
|
|
|
|
local function calcValues(self)
|
|
|
|
local slider = self:getChildById('sliderButton')
|
|
|
|
local decrementButton = self:getChildById('decrementButton')
|
|
|
|
local incrementButton = self:getChildById('incrementButton')
|
|
|
|
|
|
|
|
local pxrange, center
|
|
|
|
if self.orientation == 'vertical' then
|
|
|
|
pxrange = (self:getHeight() - decrementButton:getHeight() - decrementButton:getMarginTop() - decrementButton:getMarginBottom()
|
|
|
|
- incrementButton:getHeight() - incrementButton:getMarginTop() - incrementButton:getMarginBottom())
|
2012-03-28 02:33:35 +02:00
|
|
|
center = self:getY() + math.floor(self:getHeight() / 2)
|
2012-03-25 16:10:15 +02:00
|
|
|
else -- horizontal
|
|
|
|
pxrange = (self:getWidth() - decrementButton:getWidth() - decrementButton:getMarginLeft() - decrementButton:getMarginRight()
|
|
|
|
- incrementButton:getWidth() - incrementButton:getMarginLeft() - incrementButton:getMarginRight())
|
2012-08-31 06:56:10 +02:00
|
|
|
center = self:getX() + math.floor(self:getWidth() / 2)
|
2012-03-25 16:10:15 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local range = self.maximum - self.minimum + 1
|
2012-03-28 02:33:35 +02:00
|
|
|
|
|
|
|
local proportion
|
|
|
|
|
|
|
|
if self.pixelsScroll then
|
|
|
|
proportion = pxrange/(range+pxrange)
|
|
|
|
else
|
|
|
|
proportion = math.min(math.max(self.step, 1), range)/range
|
|
|
|
end
|
|
|
|
|
|
|
|
local px = math.max(proportion * pxrange, 10)
|
|
|
|
px = px - px % 2 + 1
|
|
|
|
|
2012-03-25 19:10:19 +02:00
|
|
|
local offset = 0
|
2012-03-28 02:33:35 +02:00
|
|
|
if range == 0 or self.value == self.minimum then
|
|
|
|
if self.orientation == 'vertical' then
|
|
|
|
offset = -math.floor((self:getHeight() - px) / 2) + decrementButton:getMarginRect().height
|
|
|
|
else
|
|
|
|
offset = -math.floor((self:getWidth() - px) / 2) + decrementButton:getMarginRect().width
|
|
|
|
end
|
|
|
|
elseif range > 1 and self.value == self.maximum then
|
|
|
|
if self.orientation == 'vertical' then
|
|
|
|
offset = math.ceil((self:getHeight() - px) / 2) - incrementButton:getMarginRect().height
|
|
|
|
else
|
|
|
|
offset = math.ceil((self:getWidth() - px) / 2) - incrementButton:getMarginRect().width
|
|
|
|
end
|
|
|
|
elseif range > 1 then
|
|
|
|
offset = (((self.value - self.minimum) / (range - 1)) - 0.5) * (pxrange - px)
|
2012-03-25 19:10:19 +02:00
|
|
|
end
|
2012-03-25 16:10:15 +02:00
|
|
|
|
|
|
|
return range, pxrange, px, offset, center
|
|
|
|
end
|
|
|
|
|
2013-01-05 08:57:31 +01:00
|
|
|
local function updateValueDisplay(widget)
|
|
|
|
if widget == nil then return end
|
|
|
|
|
|
|
|
if widget:getShowValue() then
|
2013-02-20 03:03:45 +01:00
|
|
|
widget:setText(widget:getValue() .. (widget:getSymbol() or ''))
|
2013-01-05 08:57:31 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-03-25 16:10:15 +02:00
|
|
|
local function updateSlider(self)
|
|
|
|
local slider = self:getChildById('sliderButton')
|
|
|
|
if slider == nil then return end
|
|
|
|
|
|
|
|
local range, pxrange, px, offset, center = calcValues(self)
|
|
|
|
if self.orientation == 'vertical' then
|
|
|
|
slider:setHeight(px)
|
|
|
|
slider:setMarginTop(offset)
|
|
|
|
else -- horizontal
|
|
|
|
slider:setWidth(px)
|
|
|
|
slider:setMarginLeft(offset)
|
|
|
|
end
|
2013-01-05 08:57:31 +01:00
|
|
|
updateValueDisplay(self)
|
2012-03-25 16:10:15 +02:00
|
|
|
|
2012-06-08 18:58:08 +02:00
|
|
|
local status = (self.maximum ~= self.minimum)
|
|
|
|
|
|
|
|
self:setOn(status)
|
|
|
|
for _i,child in pairs(self:getChildren()) do
|
|
|
|
child:setEnabled(status)
|
2012-03-25 16:10:15 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-01-24 18:45:26 +01:00
|
|
|
local function parseSliderPos(self, slider, pos, move)
|
|
|
|
local delta, hotDistance
|
2012-03-25 16:10:15 +02:00
|
|
|
if self.orientation == 'vertical' then
|
2012-09-01 01:33:51 +02:00
|
|
|
delta = move.y
|
2013-01-24 18:45:26 +01:00
|
|
|
hotDistance = pos.y - slider:getY()
|
2012-03-25 16:10:15 +02:00
|
|
|
else
|
2012-09-01 01:33:51 +02:00
|
|
|
delta = move.x
|
2013-01-24 18:45:26 +01:00
|
|
|
hotDistance = pos.x - slider:getX()
|
|
|
|
end
|
|
|
|
|
|
|
|
if (delta > 0 and hotDistance + delta > self.hotDistance) or
|
|
|
|
(delta < 0 and hotDistance + delta < self.hotDistance) then
|
|
|
|
local range, pxrange, px, offset, center = calcValues(self)
|
|
|
|
local newvalue = self.value + delta * (range / (pxrange - px))
|
|
|
|
self:setValue(newvalue)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function parseSliderPress(self, slider, pos, button)
|
|
|
|
if self.orientation == 'vertical' then
|
|
|
|
self.hotDistance = pos.y - slider:getY()
|
|
|
|
else
|
|
|
|
self.hotDistance = pos.x - slider:getX()
|
2012-03-25 16:10:15 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- public functions
|
2012-03-24 16:22:40 +01:00
|
|
|
function UIScrollBar.create()
|
|
|
|
local scrollbar = UIScrollBar.internalCreate()
|
|
|
|
scrollbar:setFocusable(false)
|
2012-03-25 16:10:15 +02:00
|
|
|
scrollbar.value = 0
|
2012-06-01 21:39:09 +02:00
|
|
|
scrollbar.minimum = -999999
|
|
|
|
scrollbar.maximum = 999999
|
2012-03-25 16:10:15 +02:00
|
|
|
scrollbar.step = 1
|
|
|
|
scrollbar.orientation = 'vertical'
|
2012-03-28 02:33:35 +02:00
|
|
|
scrollbar.pixelsScroll = false
|
2013-01-05 08:57:31 +01:00
|
|
|
scrollbar.showValue = false
|
|
|
|
scrollbar.symbol = nil
|
2013-01-11 08:10:37 +01:00
|
|
|
scrollbar.mouseScroll = true
|
2012-03-24 16:22:40 +01:00
|
|
|
return scrollbar
|
|
|
|
end
|
|
|
|
|
|
|
|
function UIScrollBar:onSetup()
|
2012-06-01 21:39:09 +02:00
|
|
|
self.setupDone = true
|
2013-01-24 18:45:26 +01:00
|
|
|
local sliderButton = self:getChildById('sliderButton')
|
2012-08-21 13:09:48 +02:00
|
|
|
g_mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:decrement() end, 300)
|
|
|
|
g_mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:increment() end, 300)
|
2013-01-24 18:45:26 +01:00
|
|
|
g_mouse.bindPressMove(sliderButton, function(mousePos, mouseMoved) parseSliderPos(self, sliderButton, mousePos, mouseMoved) end)
|
|
|
|
g_mouse.bindPress(sliderButton, function(mousePos, mouseButton) parseSliderPress(self, sliderButton, mousePos, mouseButton) end)
|
2013-01-05 08:57:31 +01:00
|
|
|
|
2012-06-08 18:58:08 +02:00
|
|
|
updateSlider(self)
|
2012-03-24 16:22:40 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
function UIScrollBar:onStyleApply(styleName, styleNode)
|
2012-03-25 16:10:15 +02:00
|
|
|
for name,value in pairs(styleNode) do
|
|
|
|
if name == 'maximum' then
|
|
|
|
self:setMaximum(tonumber(value))
|
|
|
|
elseif name == 'minimum' then
|
|
|
|
self:setMinimum(tonumber(value))
|
|
|
|
elseif name == 'step' then
|
|
|
|
self:setStep(tonumber(value))
|
|
|
|
elseif name == 'orientation' then
|
|
|
|
self:setOrientation(value)
|
|
|
|
elseif name == 'value' then
|
|
|
|
self:setValue(value)
|
2012-03-28 02:33:35 +02:00
|
|
|
elseif name == 'pixels-scroll' then
|
|
|
|
self.pixelsScroll = true
|
2013-01-05 08:57:31 +01:00
|
|
|
elseif name == 'show-value' then
|
|
|
|
self.showValue = true
|
|
|
|
elseif name == 'symbol' then
|
|
|
|
self.symbol = value
|
2013-01-11 08:10:37 +01:00
|
|
|
elseif name == 'mouse-scroll' then
|
|
|
|
self.mouseScroll = value
|
2012-03-24 16:22:40 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2012-03-25 16:10:15 +02:00
|
|
|
|
2012-06-02 02:38:26 +02:00
|
|
|
function UIScrollBar:decrement(count)
|
|
|
|
count = count or self.step
|
2012-06-03 22:05:35 +02:00
|
|
|
self:setValue(self.value - count)
|
2012-03-25 16:10:15 +02:00
|
|
|
end
|
|
|
|
|
2012-06-02 02:38:26 +02:00
|
|
|
function UIScrollBar:increment(count)
|
|
|
|
count = count or self.step
|
2012-06-03 22:05:35 +02:00
|
|
|
self:setValue(self.value + count)
|
2012-03-25 16:10:15 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
function UIScrollBar:setMaximum(maximum)
|
|
|
|
if maximum == self.maximum then return end
|
2013-02-20 01:34:06 +01:00
|
|
|
self.maximum = maximum
|
|
|
|
if self.minimum > maximum then
|
|
|
|
self:setMinimum(maximum)
|
|
|
|
end
|
2012-03-25 16:10:15 +02:00
|
|
|
if self.value > maximum then
|
|
|
|
self:setValue(maximum)
|
|
|
|
else
|
|
|
|
updateSlider(self)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function UIScrollBar:setMinimum(minimum)
|
|
|
|
if minimum == self.minimum then return end
|
|
|
|
self.minimum = minimum
|
2013-02-20 01:34:06 +01:00
|
|
|
if self.maximum < minimum then
|
|
|
|
self:setMaximum(minimum)
|
|
|
|
end
|
2012-03-25 16:10:15 +02:00
|
|
|
if self.value < minimum then
|
|
|
|
self:setValue(minimum)
|
|
|
|
else
|
|
|
|
updateSlider(self)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function UIScrollBar:setRange(minimum, maximum)
|
|
|
|
self:setMinimum(minimum)
|
|
|
|
self:setMaximum(maximum)
|
|
|
|
end
|
|
|
|
|
|
|
|
function UIScrollBar:setValue(value)
|
|
|
|
value = math.max(math.min(value, self.maximum), self.minimum)
|
|
|
|
if self.value == value then return end
|
|
|
|
local delta = value - self.value
|
|
|
|
self.value = value
|
|
|
|
updateSlider(self)
|
2012-06-01 21:39:09 +02:00
|
|
|
if self.setupDone then
|
2012-09-02 01:16:17 +02:00
|
|
|
signalcall(self.onValueChange, self, math.round(value), delta)
|
2012-06-01 21:39:09 +02:00
|
|
|
end
|
2012-03-25 16:10:15 +02:00
|
|
|
end
|
|
|
|
|
2013-01-11 08:10:37 +01:00
|
|
|
function UIScrollBar:setMouseScroll(scroll)
|
|
|
|
self.mouseScroll = scroll
|
|
|
|
end
|
|
|
|
|
2012-03-25 16:10:15 +02:00
|
|
|
function UIScrollBar:setStep(step)
|
|
|
|
self.step = step
|
|
|
|
end
|
|
|
|
|
|
|
|
function UIScrollBar:setOrientation(orientation)
|
|
|
|
self.orientation = orientation
|
|
|
|
end
|
|
|
|
|
2013-02-20 03:03:45 +01:00
|
|
|
function UIScrollBar:setText(text)
|
|
|
|
local valueLabel = self:getChildById('valueLabel')
|
|
|
|
valueLabel:setText(text)
|
|
|
|
end
|
|
|
|
|
2012-03-25 16:10:15 +02:00
|
|
|
function UIScrollBar:onGeometryChange()
|
|
|
|
updateSlider(self)
|
|
|
|
end
|
|
|
|
|
2012-03-26 15:34:43 +02:00
|
|
|
function UIScrollBar:onMouseWheel(mousePos, mouseWheel)
|
2013-01-11 08:10:37 +01:00
|
|
|
if not self.mouseScroll then
|
|
|
|
return false
|
|
|
|
end
|
2013-01-05 08:57:31 +01:00
|
|
|
if mouseWheel == MouseWheelDown then
|
2012-03-29 15:45:40 +02:00
|
|
|
if self.orientation == 'vertical' then
|
|
|
|
self:decrement()
|
|
|
|
else
|
|
|
|
self:increment()
|
|
|
|
end
|
2012-03-26 15:34:43 +02:00
|
|
|
else
|
2012-03-29 15:45:40 +02:00
|
|
|
if self.orientation == 'vertical' then
|
|
|
|
self:increment()
|
|
|
|
else
|
|
|
|
self:decrement()
|
|
|
|
end
|
2012-03-26 15:34:43 +02:00
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2012-03-25 16:10:15 +02:00
|
|
|
function UIScrollBar:getMaximum() return self.maximum end
|
|
|
|
function UIScrollBar:getMinimum() return self.minimum end
|
2012-09-02 01:16:17 +02:00
|
|
|
function UIScrollBar:getValue() return math.round(self.value) end
|
2012-03-25 16:10:15 +02:00
|
|
|
function UIScrollBar:getStep() return self.step end
|
|
|
|
function UIScrollBar:getOrientation() return self.orientation end
|
2013-01-05 08:57:31 +01:00
|
|
|
function UIScrollBar:getShowValue() return self.showValue end
|
2013-01-11 08:10:37 +01:00
|
|
|
function UIScrollBar:getSymbol() return self.symbol end
|
|
|
|
function UIScrollBar:getMouseScroll() return self.mouseScroll end
|