diff --git a/theme/init.lua b/theme/init.lua index 95cd390..4dbe8b0 100644 --- a/theme/init.lua +++ b/theme/init.lua @@ -94,6 +94,7 @@ function module.setup_colors(data,args) priv["bg_"..k] = args["bg_"..k] or beautiful["menu_bg_"..v.beautiful_name] or beautiful["bg_"..v.beautiful_name] or (v.fallback and beautiful.bg_normal) priv["bgimage_"..k] = args["bgimage_"..k] or beautiful["menu_bgimage_"..v.beautiful_name] or beautiful["bgimage_"..v.beautiful_name] priv["border_color_"..k] = args["border_color_"..k] + or args["item_border_color"] or args["border_color"] or beautiful["menu_border_color_"..v.beautiful_name] or beautiful["border_color_"..v.beautiful_name] or (v.fallback and beautiful.border_color) diff --git a/tooltip.lua b/tooltip.lua index 5c7f1f0..2c3f98e 100644 --- a/tooltip.lua +++ b/tooltip.lua @@ -1,165 +1,13 @@ -local setmetatable,math = setmetatable,math -local beautiful = require( "beautiful" ) -local surface = require( "gears.surface" ) -local wibox = require( "wibox" ) -local object = require( "radical.object" ) -local shape = require( "gears.shape" ) -local capi = { screen = screen , - mouse = mouse } -local module={} +-- This is a shim module to use the new `awful.tooltip` instead of Radical +-- old implementation. Most features have been merged upstream and it is +-- no longer necessary to keep a Radical version of this. +-- +-- Also, this forces me to finish awful.tooltip instead of using my own. -local function get_direction(args) - if not args.parent or not args.parent.drawable then return "bottom" end - local drawable_geom = args.parent.drawable.drawable.geometry(args.parent.drawable.drawable) - if args.parent.y+args.parent.height < drawable_geom.height then --Vertical wibox - if drawable_geom.x > capi.screen[capi.mouse.screen].geometry.width - (drawable_geom.x+drawable_geom.width) then - return "left" - else - return "right" - end - else --Horizontal wibox - if drawable_geom.y > capi.screen[capi.mouse.screen].geometry.height - (drawable_geom.y+drawable_geom.height) then - return "top" - else - return "bottom" - end - end +local tooltip = require("awful.tooltip") + +return function(parent, text, args) + return tooltip{markup=""..text.."", objects = {parent}, mode = "outside"} end -local function rel_parent(w,args2,args) - if args2 and args2.parent then - local drawable_geom = args2.parent.drawable.drawable.geometry(args2.parent.drawable.drawable) - if (args.direction == "left") or (args.direction == "right") then - return {x=drawable_geom.x+((args.direction == "left") and - w.width or drawable_geom.width),y=drawable_geom.y+args2.parent.y+args2.parent.height/2-w.height/2} - else - return {x=drawable_geom.x+args2.parent.x-w.width/2 + args2.parent.width/2,y=(args.direction == "top") and drawable_geom.y-w.height or drawable_geom.y+drawable_geom.height} - end - end - return {} -end - -local function init(data,widget,args) - if widget and not data.init then - data.init = true - - -- Setup the wibox - local vertical = (args.direction == "left") or (args.direction == "right") - local w,extents = data.wibox or wibox{},widget._private.layout:get_pixel_extents() - extents.width = extents.width + 60 - w.visible = false - w.width = extents.width - w.height = vertical and 20 or 25 - w.ontop = true - w:set_bg(beautiful.tooltip_bg or beautiful.bg_normal or "") - - -- Pick the right shape - local s = nil - if args.direction == "bottom" then - s = shape.infobubble - elseif args.direction == "top" then - s = shape.transform(shape.infobubble) : rotate_at(w.width/2, w.height/2, math.pi) - elseif args.direction == "left" then - s = shape.transform(shape.rectangular_tag) : rotate_at(w.width/2, w.height/2, math.pi) - else - s = shape.rectangular_tag - end - - surface.apply_shape_bounding(w, s, w.height/2 - 2.5, 5) - - data.wibox = w - end -end - -local function set_text(self,text) - self.init = nil - self._text = text - if self._w then - self._w:set_markup("".. self._text .."") - end - init(self,self._w,self._args) -end - -local function set_markup(self,text) - self.init = nil - self._text = text - if self._w then - self._w:set_markup(self._text) - end - init(self,self._w,self._args) -end - - -local function new(widget,text, args) - args = args or {} - - local data = object({ - private_data = { - }, - autogen_getmap = true, - autogen_setmap = true, - autogen_signals = true, - }) - - data._text = text - - local function hide_tooltip() - if data.wibox then - data.wibox.visible = false - if data.drawable then - data.drawable:disconnect_signal("mouse::leave",hide_tooltip) - data.drawable = nil - end - end - end - - function data:hide() hide_tooltip() end - - function data:showToolTip(show,args2) - args2 = args2 or args or {} - args.direction = args.direction or get_direction(args2) - - local vertical,textw = (args.direction == "left") or (args.direction == "right"),wibox.widget.textbox() - textw.align = "center" - - if not args.is_markup then - textw:set_markup("".. data._text .."") - else - textw:set_markup(data._text) - end - - data._w = textw - init(data,textw,args) - - if data.wibox then - - local l,m = wibox.layout.fixed.horizontal(),wibox.container.margin(textw) - m:set_left ( 30 ) - m:set_right ( 10 ) - m:set_bottom ( not vertical and ((args.direction == "top") and 4 or -4) or 0 ) - l:add(m) - - l:fill_space(true) - data.wibox:set_widget(l) - - data.wibox:connect_signal("mouse::leave",hide_tooltip) - local relative_to_parent = rel_parent(data.wibox,args2,args) - data.wibox.x = math.floor(args2.x or args.x or relative_to_parent.x or capi.mouse.coords().x - data.wibox.width/2 -5) - data.wibox.y = math.floor(args2.y or args.y or relative_to_parent.y or ((not vertical) and capi.screen[capi.mouse.screen].geometry.height - 16 - 25 or 16)) - data.wibox.visible = true - if args2.parent and args2.parent.drawable and data.drawable ~= args2.parent.drawable then - data.drawable = args2.parent.drawable - data.drawable:connect_signal("mouse::leave",hide_tooltip) - end - end - end - widget:connect_signal("mouse::enter" , function(_,geometry) data:showToolTip( true , {parent=geometry}) end) - widget:connect_signal("mouse::leave" , hide_tooltip) - widget:connect_signal("button::press" , hide_tooltip) - data.set_text = set_text - data.set_markup = set_markup - data._args = args - return data -end - -return setmetatable(module, { __call = function(_, ...) return new(...) end }) --- kate: space-indent on; indent-width 2; replace-tabs on; +-- kate: space-indent on; indent-width 4; replace-tabs on; diff --git a/widgets/init.lua b/widgets/init.lua index 34d817f..a472cee 100644 --- a/widgets/init.lua +++ b/widgets/init.lua @@ -2,8 +2,8 @@ local wibox = require("wibox") wibox.layout.grid = require( "radical.widgets.grid" ) -wibox.widget.checkbox = require( "radical.widgets.checkbox" ) -wibox.widget.slider = require( "radical.widgets.slider" ) +-- wibox.widget.checkbox = require( "radical.widgets.checkbox" ) +-- wibox.widget.slider = require( "radical.widgets.slider" ) return { checkbox = require( "radical.widgets.checkbox" ), diff --git a/widgets/slider.lua b/widgets/slider.lua deleted file mode 100644 index edc0076..0000000 --- a/widgets/slider.lua +++ /dev/null @@ -1,371 +0,0 @@ ---------------------------------------------------------------------------- --- An interactive mouse based slider widget. --- --- @author Grigory Mishchenko <grishkokot@gmail.com> --- @author Emmanuel Lepage Vallee <elv1313@gmail.com> --- @copyright 2015 Grigory Mishchenko, 2016 Emmanuel Lepage Vallee --- @release @AWESOME_VERSION@ --- @classmod wibox.widget.slider ---------------------------------------------------------------------------- - -local setmetatable = setmetatable -local type = type -local color = require("gears.color") -local util = require("awful.util") -local beautiful = require("beautiful") -local base = require("wibox.widget.base") -local shape = require("gears.shape") -local gmatrix = require("gears.matrix") -local capi = { - mouse = mouse, - mousegrabber = mousegrabber, - root = root, -} - -local slider = {mt={}} - -local properties = { - -- Handle - handle_shape = shape.rectangle, - handle_color = false, - handle_margins = {}, - handle_width = false, - handler_border_width = 0, - handler_border_color = false, - - -- Bar - bar_shape = shape.rectangle, - bar_height = false, - bar_color = false, - bar_margins = {}, - bar_border_width = 0, - bar_border_color = false, - - -- Content - value = 0, - minimum = 0, - maximum = 100, - - -- Other - cursor = "fleur", -} - --- Create the accessors -for prop in pairs(properties) do - slider["set_"..prop] = function(self, value) - local changed = self._private[prop] ~= value - self._private[prop] = value - - if changed then - self:emit_signal("property::"..prop) - self:emit_signal("widget::redraw_needed") - end - end - - slider["get_"..prop] = function(self) - -- Ignoring the false's is on purpose - return self._private[prop] == nil - and properties[prop] - or self._private[prop] - end -end - --- Add some validation to set_value -function slider:set_value(value) - value = math.min(value, self:get_maximum()) - value = math.max(value, self:get_minimum()) - local changed = self._private.value ~= value - - self._private.value = value - - if changed then - self:emit_signal( "property::value" ) - self:emit_signal( "widget::redraw_needed" ) - end -end - -local function get_extremums(self) - local min = self._private.minimum or properties.minimum - local max = self._private.maximum or properties.maximum - local interval = max - min - - return min, max, interval -end - -local function get_value(self, width, x) - local _, _, interval = get_extremums(self) - - return math.floor((x*interval)/width) -end - -function slider:draw(_, cr, width, height) - local bar_height = self._private.bar_height - - -- If there is no background, then skip this - local bar_color = self._private.bar_color - or beautiful.slider_bar_color - - if bar_color then - cr:set_source(color(bar_color)) - end - - local margins = self._private.bar_margins - or beautiful.slider_bar_margins - - local x_offset, right_margin, y_offset = 0, 0 - - if margins then - if type(margins) == "number" then - bar_height = bar_height or (height - 2*margins) - x_offset, y_offset = margins, margins - right_margin = margins - else - bar_height = bar_height or (height - margins.top - margins.bottom) - x_offset, y_offset = margins.left, margins.top - right_margin = margins.right - end - else - bar_height = bar_height or beautiful.slider_bar_height or height - y_offset = (height - bar_height)/2 - end - - - cr:translate(x_offset, y_offset) - - local bar_shape = self._private.bar_shape - or beautiful.slider_bar_shape - or properties.bar_shape - - local bar_border_width = self._private.bar_border_width - or beautiful.slider_bar_border_width - or properties.bar_border_width - - bar_shape(cr, width - x_offset - right_margin, bar_height or height) - - if bar_color then - if bar_border_width == 0 then - cr:fill() - else - cr:fill_preserve() - end - end - - -- Draw the bar border - if bar_border_width > 0 then - local bar_border_color = self._private.bar_border_color - or beautiful.slider_bar_border_color - or properties.bar_border_color - - if bar_border_color then - cr:save() - cr:set_source(color(bar_border_color)) - cr:stroke() - cr:restore() - else - cr:stroke() - end - end - - cr:translate(-x_offset, -y_offset) - - -- Paint the handle - local handle_color = self._private.handle_color - or beautiful.slider_handle_color - - -- It is ok if there is no color, it will be inherited - if handle_color then - cr:set_source(color(handle_color)) - end - - local handle_height, handle_width = height, self._private.handle_width - or beautiful.slider_handle_width - or height/2 - - local handle_shape = self._private.handle_shape - or beautiful.slider_handle_shape - or properties.handle_shape - - -- Lets get the margins for the handle - local margins = self._private.bar_margins - or beautiful.slider_bar_margins - - local x_offset, y_offset = 0, 0 - - if margins then - if type(margins) == "number" then - x_offset, y_offset = margins, margins - handle_width = handle_width - 2*margins - handle_height = handle_height - 2*margins - else - x_offset, y_offset = margins.left, margins.top - handle_width = handle_width - margins.left - margins.right - handle_height = handle_height - margins.top - margins.bottom - end - end - - local value = self._private.value or self._private.min or 0 - - -- Get the widget size back to it's non-transfored value - --local matrix = gmatrix.from_cairo_matrix(cr:get_matrix()) - local min, _, interval = get_extremums(self) - local rel_value = ((value-min)/interval) * (width-handle_width) - - cr:translate(x_offset + rel_value, y_offset) - - local handle_border_width = self._private.handle_border_width - or beautiful.slider_handle_border_width - or properties.handle_border_width - - handle_shape(cr, handle_width, handle_height) - - if handle_border_width > 0 then - cr:fill_preserve() - else - cr:fill() - end - - -- Draw the handle border - if handle_border_width > 0 then - local handle_border_color = self._private.handle_border_color - or beautiful.slider_handle_border_color - or properties.handle_border_color - - if handle_border_color then - cr:set_source(color(handle_border_color)) - end - - cr:stroke() - end -end - -function slider:fit(_, width, height) - -- Use all the space, this should be used with a constraint widget - return width, height -end - -local event = {} - -function event.mouse_enter(self) - self:emit_signal("widget::redraw_needed") --TODO - local cursor = self._private.cursor or "fleur" - capi.root.cursor(cursor) -end - -function event.mouse_leave(self) - self:emit_signal("widget::redraw_needed") --TODO --- capi.root.cursor("fleur") -end - -local rect_order = {"x", "y", "width", "height"} - --- Move the handle to the correct location -local function move_handle(self, x, y, geo) - -- Fix the X position when used in a rotate or mirror widget - - -- Remove the translation to bring {x, y} and the rect on the same origin - local rem_translate = geo.matrix_to_device*gmatrix.identity - rem_translate.x0, rem_translate.y0 = 0, 0 - - local rect = {rem_translate:transform_rectangle( - 0, - 0, - geo.width, - geo.height - )} - - -- Floating point precision is here both too much and not enough - for k, v in ipairs(rect) do - rect[rect_order[k]] = util.round(v) - end - - local px = rem_translate:transform_point(x, y) - - -- If the transformation moved the rectangle away from {0,0}, compensate - if rect.x < 0 then - px = rect.width + px - end - --- --HACK Cairo 0,0 is top left, a matrix is bottom left, funny... - if util.round(rem_translate:transform_point(0, 100)) ~= 0 then - px = -(px - rect.width) - end - - self:set_value(get_value(self, rect.width, px)) - self:emit_signal("widget::redraw_needed") -end - -function event.mouse_press(self, x, y, button_id, _, geo) - if button_id ~= 1 then return end - - move_handle(self, x, y, geo) - - -- Get the "real" position of the widget - local wgeo = geo.drawable.drawable:geometry() - local wx = wgeo.x + geo.x - local wy = wgeo.y + geo.y - - capi.mousegrabber.run(function(mouse) - if not mouse.buttons[1] then - self:emit_signal("widget::redraw_needed") - return false - end - - -- Get the closest point to the widget - local abs_x, abs_y = mouse.x, mouse.y - abs_x = abs_x > (wx+geo.width) and wx+geo.width or ( - abs_x < wx and wx - ) or abs_x - abs_y = abs_y > (wy+geo.height) and wy+geo.height or ( - abs_y < wy and wy - ) or abs_y - - -- Get the relative point - local rx, ry = abs_x - wx, abs_y - wy - move_handle(self, rx, ry, geo) - - return true - end, self:get_cursor()) -end - ---- Create a slider widget. --- @tparam[opt={}] table args --- @function wibox.widget.slider -local function new(args) - local ret = base.make_widget(nil, nil, { - enable_properties = true, - }) - - util.table.crush(ret._private, args or {}) - - util.table.crush(ret, slider, true) - - -- Change the cusor and redraw (in case there is hover and pressed colors) - ret:connect_signal("mouse::enter" , event.mouse_enter) - ret:connect_signal("mouse::leave" , event.mouse_leave) - ret:connect_signal("button::press", event.mouse_press) - - return ret -end - -function slider.mt:__call(...) - return new(...) -end - ---FIXME This is still broken... ---[[w:setup{ - { - { - widget = wibox.widget.slider, - }, - direction = "east", - widget = wibox.container.rotate - }, - reflection = { - horizontal = true - }, - widget = wibox.container.mirror -}]] - -return setmetatable(slider, slider.mt) - --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/widgets/table.lua b/widgets/table.lua index e13f237..3696920 100644 --- a/widgets/table.lua +++ b/widgets/table.lua @@ -49,11 +49,16 @@ end local function new(content,args) args = args or {} local cols = 0 + local row_count = args.row_count or #content + for k,v in ipairs(content) do if #v > cols then cols = #v end end + + local col_count = math.max(args.column_count or 0, cols) + local main_l = wibox.layout.fixed.vertical() main_l.fit = function(self,context,width,height) @@ -87,4 +92,4 @@ local function new(content,args) end return setmetatable({}, { __call = function(_, ...) return new(...) end }) --- kate: space-indent on; indent-width 2; replace-tabs on; +-- kate: space-indent on; indent-width 4; replace-tabs on;