imagebox: Add a `downscale` and `upscale` property.
Previously, it was really hard to get the image to do one *or* the other. The `resize` property set both at the same time. While it could, this does not deprecate the old `resize` property since 99% of the user wan't to lock both.
This commit is contained in:
parent
cefd4f843e
commit
5212f0634a
|
@ -80,7 +80,7 @@ function imagebox:draw(_, cr, width, height)
|
||||||
|
|
||||||
local w, h = self._private.default.width, self._private.default.height
|
local w, h = self._private.default.width, self._private.default.height
|
||||||
|
|
||||||
if not self._private.resize_forbidden then
|
if self._private.resize then
|
||||||
-- That's for the "fit" policy.
|
-- That's for the "fit" policy.
|
||||||
local aspects = {
|
local aspects = {
|
||||||
w = width / w,
|
w = width / w,
|
||||||
|
@ -93,10 +93,14 @@ function imagebox:draw(_, cr, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, aspect in ipairs {"w", "h"} do
|
for _, aspect in ipairs {"w", "h"} do
|
||||||
if policy[aspect] == "auto" then
|
if self._private.upscale == false and (w < width and h < height) then
|
||||||
aspects[aspect] = math.min(width / w, height / h)
|
aspects[aspect] = 1
|
||||||
|
elseif self._private.downscale == false and (w >= width and h >= height) then
|
||||||
|
aspects[aspect] = 1
|
||||||
elseif policy[aspect] == "none" then
|
elseif policy[aspect] == "none" then
|
||||||
aspects[aspect] = 1
|
aspects[aspect] = 1
|
||||||
|
elseif policy[aspect] == "auto" then
|
||||||
|
aspects[aspect] = math.min(width / w, height / h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -169,7 +173,15 @@ function imagebox:fit(_, width, height)
|
||||||
if not self._private.default then return 0, 0 end
|
if not self._private.default then return 0, 0 end
|
||||||
local w, h = self._private.default.width, self._private.default.height
|
local w, h = self._private.default.width, self._private.default.height
|
||||||
|
|
||||||
if not self._private.resize_forbidden or w > width or h > height then
|
if w <= width and h <= height and self._private.upscale == false then
|
||||||
|
return w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
if (w < width or h < height) and self._private.downscale == false then
|
||||||
|
return w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
if self._private.resize or w > width or h > height then
|
||||||
local aspect = math.min(width / w, height / h)
|
local aspect = math.min(width / w, height / h)
|
||||||
return w * aspect, h * aspect
|
return w * aspect, h * aspect
|
||||||
end
|
end
|
||||||
|
@ -311,23 +323,70 @@ function imagebox:set_clip_shape(clip_shape, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Should the image be resized to fit into the available space?
|
--- Should the image be resized to fit into the available space?
|
||||||
|
--
|
||||||
|
-- Note that `upscale` and `downscale` can affect the value of `resize`.
|
||||||
|
-- If conflicting values are passed to the constructor, then the result
|
||||||
|
-- is undefined.
|
||||||
|
--
|
||||||
-- @DOC_wibox_widget_imagebox_resize_EXAMPLE@
|
-- @DOC_wibox_widget_imagebox_resize_EXAMPLE@
|
||||||
-- @property resize
|
-- @property resize
|
||||||
-- @propemits true false
|
-- @propemits true false
|
||||||
-- @tparam boolean resize
|
-- @tparam boolean resize
|
||||||
|
|
||||||
--- Should the image be resized to fit into the available space?
|
--- Allow the image to be upscaled (made bigger).
|
||||||
-- @tparam boolean allowed If `false`, the image will be clipped, else it will
|
--
|
||||||
-- be resized to fit into the available space.
|
-- Note that `upscale` and `downscale` can affect the value of `resize`.
|
||||||
-- @method set_resize
|
-- If conflicting values are passed to the constructor, then the result
|
||||||
-- @hidden
|
-- is undefined.
|
||||||
|
--
|
||||||
|
-- @DOC_wibox_widget_imagebox_upscale_EXAMPLE@
|
||||||
|
-- @property upscale
|
||||||
|
-- @tparam boolean upscale
|
||||||
|
-- @see downscale
|
||||||
|
-- @see resize
|
||||||
|
|
||||||
|
--- Allow the image to be downscaled (made smaller).
|
||||||
|
--
|
||||||
|
-- Note that `upscale` and `downscale` can affect the value of `resize`.
|
||||||
|
-- If conflicting values are passed to the constructor, then the result
|
||||||
|
-- is undefined.
|
||||||
|
--
|
||||||
|
-- @DOC_wibox_widget_imagebox_downscale_EXAMPLE@
|
||||||
|
-- @property downscale
|
||||||
|
-- @tparam boolean downscale
|
||||||
|
-- @see upscale
|
||||||
|
-- @see resize
|
||||||
|
|
||||||
function imagebox:set_resize(allowed)
|
function imagebox:set_resize(allowed)
|
||||||
self._private.resize_forbidden = not allowed
|
self._private.resize = allowed
|
||||||
|
|
||||||
|
if allowed then
|
||||||
|
self._private.downscale = true
|
||||||
|
self._private.upscale = true
|
||||||
|
self:emit_signal("property::downscale", allowed)
|
||||||
|
self:emit_signal("property::upscale", allowed)
|
||||||
|
end
|
||||||
|
|
||||||
self:emit_signal("widget::redraw_needed")
|
self:emit_signal("widget::redraw_needed")
|
||||||
self:emit_signal("widget::layout_changed")
|
self:emit_signal("widget::layout_changed")
|
||||||
self:emit_signal("property::resize", allowed)
|
self:emit_signal("property::resize", allowed)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for _, prop in ipairs {"downscale", "upscale" } do
|
||||||
|
imagebox["set_" .. prop] = function(self, allowed)
|
||||||
|
self._private[prop] = allowed
|
||||||
|
|
||||||
|
if self._private.resize ~= (self._private.upscale or self._private.downscale) then
|
||||||
|
self._private.resize = self._private.upscale or self._private.downscale
|
||||||
|
self:emit_signal("property::resize", self._private.resize)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:emit_signal("widget::redraw_needed")
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
self:emit_signal("property::"..prop, allowed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Set the horizontal fit policy.
|
--- Set the horizontal fit policy.
|
||||||
--
|
--
|
||||||
-- Valid values are:
|
-- Valid values are:
|
||||||
|
@ -506,12 +565,14 @@ local function new(image, resize_allowed, clip_shape, ...)
|
||||||
local ret = base.make_widget(nil, nil, {enable_properties = true})
|
local ret = base.make_widget(nil, nil, {enable_properties = true})
|
||||||
|
|
||||||
gtable.crush(ret, imagebox, true)
|
gtable.crush(ret, imagebox, true)
|
||||||
|
ret._private.resize = true
|
||||||
|
|
||||||
if image then
|
if image then
|
||||||
ret:set_image(image)
|
ret:set_image(image)
|
||||||
end
|
end
|
||||||
|
|
||||||
if resize_allowed ~= nil then
|
if resize_allowed ~= nil then
|
||||||
ret:set_resize(resize_allowed)
|
ret.resize = resize_allowed
|
||||||
end
|
end
|
||||||
|
|
||||||
ret._private.clip_shape = clip_shape
|
ret._private.clip_shape = clip_shape
|
||||||
|
|
Loading…
Reference in New Issue