From 5a0f7b7efe1fbcd2ea7997d54ae89388eb0ea2e6 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Thu, 26 May 2016 17:39:17 -0400 Subject: [PATCH] textbox: Enable the property system And add the missing documentation --- lib/wibox/widget/textbox.lua | 115 +++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 46 deletions(-) diff --git a/lib/wibox/widget/textbox.lua b/lib/wibox/widget/textbox.lua index 3d783df6..e486d450 100644 --- a/lib/wibox/widget/textbox.lua +++ b/lib/wibox/widget/textbox.lua @@ -12,11 +12,10 @@ local base = require("wibox.widget.base") local gdebug = require("gears.debug") local beautiful = require("beautiful") local lgi = require("lgi") +local util = require("awful.util") local Pango = lgi.Pango local PangoCairo = lgi.PangoCairo -local type = type local setmetatable = setmetatable -local pairs = pairs local textbox = { mt = {} } @@ -25,37 +24,37 @@ local textbox = { mt = {} } --- Set the DPI of a Pango layout local function setup_dpi(box, dpi) - if box.dpi ~= dpi then - box.dpi = dpi - box._ctx:set_resolution(dpi) - box._layout:context_changed() + if box._private.dpi ~= dpi then + box._private.dpi = dpi + box._private.ctx:set_resolution(dpi) + box._private.layout:context_changed() end end --- Setup a pango layout for the given textbox and dpi local function setup_layout(box, width, height, dpi) - box._layout.width = Pango.units_from_double(width) - box._layout.height = Pango.units_from_double(height) + box._private.layout.width = Pango.units_from_double(width) + box._private.layout.height = Pango.units_from_double(height) setup_dpi(box, dpi) end -- Draw the given textbox on the given cairo context in the given geometry function textbox:draw(context, cr, width, height) setup_layout(self, width, height, context.dpi) - cr:update_layout(self._layout) - local _, logical = self._layout:get_pixel_extents() + cr:update_layout(self._private.layout) + local _, logical = self._private.layout:get_pixel_extents() local offset = 0 - if self._valign == "center" then + if self._private.valign == "center" then offset = (height - logical.height) / 2 - elseif self._valign == "bottom" then + elseif self._private.valign == "bottom" then offset = height - logical.height end cr:move_to(0, offset) - cr:show_layout(self._layout) + cr:show_layout(self._private.layout) end local function do_fit_return(self) - local _, logical = self._layout:get_pixel_extents() + local _, logical = self._private.layout:get_pixel_extents() if logical.width == 0 or logical.height == 0 then return 0, 0 end @@ -97,8 +96,8 @@ end function textbox:get_preferred_size_at_dpi(dpi) local max_lines = 2^20 setup_dpi(self, dpi) - self._layout.width = -1 -- no width set - self._layout.height = -max_lines -- show this many lines per paragraph + self._private.layout.width = -1 -- no width set + self._private.layout.height = -max_lines -- show this many lines per paragraph return do_fit_return(self) end @@ -111,8 +110,8 @@ end function textbox:get_height_for_width_at_dpi(width, dpi) local max_lines = 2^20 setup_dpi(self, dpi) - self._layout.width = Pango.units_from_double(width) - self._layout.height = -max_lines -- show this many lines per paragraph + self._private.layout.width = Pango.units_from_double(width) + self._private.layout.height = -max_lines -- show this many lines per paragraph local _, h = do_fit_return(self) return h end @@ -126,7 +125,7 @@ end -- @treturn[2] boolean false -- @treturn[2] string Error message explaining why the markup was invalid. function textbox:set_markup_silently(text) - if self._markup == text then + if self._private.markup == text then return true end @@ -136,9 +135,9 @@ function textbox:set_markup_silently(text) return false, parsed.message or tostring(parsed) end - self._markup = text - self._layout.text = parsed - self._layout.attributes = attr + self._private.markup = text + self._private.layout.text = parsed + self._private.layout.attributes = attr self:emit_signal("widget::redraw_needed") self:emit_signal("widget::layout_changed") return true @@ -146,9 +145,12 @@ end --- Set the text of the textbox (with -- [Pango markup](https://developer.gnome.org/pango/stable/PangoMarkupFormat.html)). +-- @property markup -- @tparam string text The text to set. This can contain pango markup (e.g. -- `bold`). You can use `awful.util.escape` to escape -- parts of it. +-- @see text + function textbox:set_markup(text) local success, message = self:set_markup_silently(text) if not success then @@ -156,79 +158,100 @@ function textbox:set_markup(text) end end +function textbox:get_markup() + return self._private.markup +end + --- Set a textbox' text. +-- @property text -- @param text The text to display. Pango markup is ignored and shown as-is. +-- @see markup + function textbox:set_text(text) - if self._layout.text == text and self._layout.attributes == nil then + if self._private.layout.text == text and self._private.layout.attributes == nil then return end - self._markup = nil - self._layout.text = text - self._layout.attributes = nil + self._private.markup = nil + self._private.layout.text = text + self._private.layout.attributes = nil self:emit_signal("widget::redraw_needed") self:emit_signal("widget::layout_changed") end +function textbox:get_text() + return self._private.layout.text +end + --- Set a textbox' ellipsize mode. +-- @property ellipsize -- @param mode Where should long lines be shortened? "start", "middle" or "end" + function textbox:set_ellipsize(mode) local allowed = { none = "NONE", start = "START", middle = "MIDDLE", ["end"] = "END" } if allowed[mode] then - if self._layout:get_ellipsize() == allowed[mode] then + if self._private.layout:get_ellipsize() == allowed[mode] then return end - self._layout:set_ellipsize(allowed[mode]) + self._private.layout:set_ellipsize(allowed[mode]) self:emit_signal("widget::redraw_needed") self:emit_signal("widget::layout_changed") end end --- Set a textbox' wrap mode. +-- @property wrap -- @param mode Where to wrap? After "word", "char" or "word_char" + function textbox:set_wrap(mode) local allowed = { word = "WORD", char = "CHAR", word_char = "WORD_CHAR" } if allowed[mode] then - if self._layout:get_wrap() == allowed[mode] then + if self._private.layout:get_wrap() == allowed[mode] then return end - self._layout:set_wrap(allowed[mode]) + self._private.layout:set_wrap(allowed[mode]) self:emit_signal("widget::redraw_needed") self:emit_signal("widget::layout_changed") end end ---- Set a textbox' vertical alignment +--- The textbox' vertical alignment +-- @property valign -- @param mode Where should the textbox be drawn? "top", "center" or "bottom" + function textbox:set_valign(mode) local allowed = { top = true, center = true, bottom = true } if allowed[mode] then - if self._valign == mode then + if self._private.valign == mode then return end - self._valign = mode + self._private.valign = mode self:emit_signal("widget::redraw_needed") self:emit_signal("widget::layout_changed") end end ---- Set a textbox' horizontal alignment +--- Set a textbox' horizontal alignment. +-- @property align -- @param mode Where should the textbox be drawn? "left", "center" or "right" + function textbox:set_align(mode) local allowed = { left = "LEFT", center = "CENTER", right = "RIGHT" } if allowed[mode] then - if self._layout:get_alignment() == allowed[mode] then + if self._private.layout:get_alignment() == allowed[mode] then return end - self._layout:set_alignment(allowed[mode]) + self._private.layout:set_alignment(allowed[mode]) self:emit_signal("widget::redraw_needed") self:emit_signal("widget::layout_changed") end end --- Set a textbox' font +-- @property font -- @param font The font description as string + function textbox:set_font(font) - self._layout:set_font_description(beautiful.get_font(font)) + self._private.layout:set_font_description(beautiful.get_font(font)) self:emit_signal("widget::redraw_needed") self:emit_signal("widget::layout_changed") end @@ -239,17 +262,13 @@ end -- @treturn table A new textbox widget -- @function wibox.widget.textbox local function new(text, ignore_markup) - local ret = base.make_widget() + local ret = base.make_widget(nil, nil, {enable_properties = true}) - for k, v in pairs(textbox) do - if type(v) == "function" then - ret[k] = v - end - end + util.table.crush(ret, textbox, true) - ret._dpi = -1 - ret._ctx = PangoCairo.font_map_get_default():create_context() - ret._layout = Pango.Layout.new(ret._ctx) + ret._private.dpi = -1 + ret._private.ctx = PangoCairo.font_map_get_default():create_context() + ret._private.layout = Pango.Layout.new(ret._private.ctx) ret:set_ellipsize("end") ret:set_wrap("word_char") @@ -272,6 +291,10 @@ function textbox.mt.__call(_, ...) return new(...) end +--@DOC_widget_COMMON@ + +--@DOC_object_COMMON@ + return setmetatable(textbox, textbox.mt) -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80