2010-10-06 12:42:56 +02:00
|
|
|
---------------------------------------------------------------------------
|
|
|
|
-- @author Uli Schlachter
|
2011-02-27 23:41:45 +01:00
|
|
|
-- @author dodo
|
|
|
|
-- @copyright 2010, 2011 Uli Schlachter, dodo
|
2010-10-06 12:42:56 +02:00
|
|
|
-- @release @AWESOME_VERSION@
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
local base = require("wibox.widget.base")
|
|
|
|
local beautiful = require("beautiful")
|
2012-05-27 19:20:34 +02:00
|
|
|
local lgi = require("lgi")
|
|
|
|
local cairo = lgi.cairo
|
|
|
|
local Pango = lgi.Pango
|
|
|
|
local PangoCairo = lgi.PangoCairo
|
2010-10-06 12:42:56 +02:00
|
|
|
local type = type
|
|
|
|
local setmetatable = setmetatable
|
|
|
|
local pairs = pairs
|
2012-05-27 19:20:34 +02:00
|
|
|
local error = error
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2012-06-12 15:55:10 +02:00
|
|
|
-- wibox.widget.textbox
|
|
|
|
local textbox = { mt = {} }
|
2010-10-06 12:42:56 +02:00
|
|
|
|
|
|
|
-- Setup a pango layout for the given textbox and cairo context
|
2011-09-07 21:37:23 +02:00
|
|
|
local function setup_layout(box, width, height)
|
|
|
|
local layout = box._layout
|
2012-05-27 19:20:34 +02:00
|
|
|
layout.width = Pango.units_from_double(width)
|
|
|
|
layout.height = Pango.units_from_double(height)
|
2011-09-07 21:37:23 +02:00
|
|
|
end
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2011-09-07 21:37:23 +02:00
|
|
|
--- Draw the given textbox on the given cairo context in the given geometry
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.draw(box, wibox, cr, width, height)
|
2012-05-27 19:20:34 +02:00
|
|
|
cr:update_layout(box._layout)
|
textbox: Actually tell pango which space we have (FS#933)
In the textbox' draw() callback we forgot to set the pango layout's width and
height. Whoops.
This was tested with the following code which makes it visible when the textbox
draws outside of its assigned space:
local w = wibox({ screen = 1 })
w.y = 10
w.x = 10
w.width = 150
w.height = 150
w.visible = true
local wi = wibox.widget.base.make_widget()
local t = wibox.widget.textbox()
t:set_markup("Foo <b>bar</b> <i>Foobar</i> und so weiter")
wi.draw = function(d, wibox, cr, width, height)
cr:move_to(24.5, 0)
cr:line_to(24.5, 150)
cr:move_to(0, 24.5)
cr:line_to(150, 24.5)
cr:move_to(124.5, 0)
cr:line_to(124.5, 150)
cr:move_to(0, 124.5)
cr:line_to(150, 124.5)
cr:set_line_width(1)
cr:stroke()
cr:translate(25, 25)
t.draw(t, wibox, cr, 100, 100)
end
w:set_widget(wi)
Signed-off-by: Uli Schlachter <psychon@znc.in>
2011-10-19 19:05:25 +02:00
|
|
|
setup_layout(box, width, height)
|
2011-09-08 08:21:36 +02:00
|
|
|
local ink, logical = box._layout:get_pixel_extents()
|
2010-10-06 12:42:56 +02:00
|
|
|
local offset = 0
|
2010-10-07 14:22:44 +02:00
|
|
|
if box._valign == "center" then
|
2010-10-06 12:42:56 +02:00
|
|
|
offset = (height - logical.height) / 2
|
2010-10-07 14:22:44 +02:00
|
|
|
elseif box._valign == "bottom" then
|
2010-10-06 12:42:56 +02:00
|
|
|
offset = height - logical.height
|
|
|
|
end
|
2011-09-07 21:37:23 +02:00
|
|
|
cr:move_to(0, offset)
|
2012-05-27 19:20:34 +02:00
|
|
|
cr:show_layout(box._layout)
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Fit the given textbox
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.fit(box, width, height)
|
2011-09-07 21:37:23 +02:00
|
|
|
setup_layout(box, width, height)
|
|
|
|
local ink, logical = box._layout:get_pixel_extents()
|
|
|
|
return logical.width, logical.height
|
|
|
|
end
|
|
|
|
|
2010-10-06 12:42:56 +02:00
|
|
|
--- Set a textbox' text.
|
|
|
|
-- @param text The text to set. This can contain pango markup (e.g. <b>bold</b>)
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.set_markup(box, text)
|
2012-05-27 19:20:34 +02:00
|
|
|
local attr, parsed = Pango.parse_markup(text, -1, 0)
|
|
|
|
-- In case of error, attr is false and parsed is an error message
|
|
|
|
if not attr then error(parsed) end
|
|
|
|
|
|
|
|
box._layout.text = parsed
|
|
|
|
box._layout.attributes = attr
|
2010-10-06 12:42:56 +02:00
|
|
|
box:emit_signal("widget::updated")
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Set a textbox' text.
|
|
|
|
-- @param text The text to display. Pango markup is ignored and shown as-is.
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.set_text(box, text)
|
2012-05-27 19:20:34 +02:00
|
|
|
box._layout.text = text
|
|
|
|
box._layout.attributes = nil
|
2010-10-06 12:42:56 +02:00
|
|
|
box:emit_signal("widget::updated")
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Set a textbox' ellipsize mode.
|
|
|
|
-- @param mode Where should long lines be shortened? "start", "middle" or "end"
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.set_ellipsize(box, mode)
|
2012-05-27 19:20:34 +02:00
|
|
|
local allowed = { none = "NONE", start = "START", middle = "MIDDLE", ["end"] = "END" }
|
2010-10-06 12:42:56 +02:00
|
|
|
if allowed[mode] then
|
2012-05-27 19:20:34 +02:00
|
|
|
box._layout:set_ellipsize(allowed[mode])
|
2010-10-06 12:42:56 +02:00
|
|
|
box:emit_signal("widget::updated")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Set a textbox' wrap mode.
|
|
|
|
-- @param mode Where to wrap? After "word", "char" or "word_char"
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.set_wrap(box, mode)
|
2012-05-27 19:20:34 +02:00
|
|
|
local allowed = { word = "WORD", char = "CHAR", word_char = "WORD_CHAR" }
|
2010-10-06 12:42:56 +02:00
|
|
|
if allowed[mode] then
|
2012-05-27 19:20:34 +02:00
|
|
|
box._layout:set_wrap(allowed[mode])
|
2010-10-06 12:42:56 +02:00
|
|
|
box:emit_signal("widget::updated")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Set a textbox' vertical alignment
|
|
|
|
-- @param mode Where should the textbox be drawn? "top", "center" or "bottom"
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.set_valign(box, mode)
|
2010-10-06 12:42:56 +02:00
|
|
|
local allowed = { top = true, center = true, bottom = true }
|
|
|
|
if allowed[mode] then
|
2010-10-07 14:22:44 +02:00
|
|
|
box._valign = mode
|
2010-10-06 12:42:56 +02:00
|
|
|
box:emit_signal("widget::updated")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-27 23:41:45 +01:00
|
|
|
--- Set a textbox' horizontal alignment
|
|
|
|
-- @param mode Where should the textbox be drawn? "left", "center" or "right"
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.set_align(box, mode)
|
2012-05-27 19:20:34 +02:00
|
|
|
local allowed = { left = "LEFT", center = "CENTER", right = "RIGHT" }
|
2011-02-27 23:41:45 +01:00
|
|
|
if allowed[mode] then
|
2012-05-27 19:20:34 +02:00
|
|
|
box._layout:set_alignment(allowed[mode])
|
2011-02-27 23:41:45 +01:00
|
|
|
box:emit_signal("widget::updated")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-04-14 07:04:48 +02:00
|
|
|
--- Set a textbox' font
|
|
|
|
-- @param font The font description as string
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.set_font(box, font)
|
2011-09-07 21:37:23 +02:00
|
|
|
box._layout:set_font_description(beautiful.get_font(font))
|
2011-04-14 07:04:48 +02:00
|
|
|
end
|
|
|
|
|
2010-10-06 12:42:56 +02:00
|
|
|
-- Returns a new textbox
|
|
|
|
local function new()
|
|
|
|
local ret = base.make_widget()
|
|
|
|
|
2012-06-12 15:55:10 +02:00
|
|
|
for k, v in pairs(textbox) do
|
2010-10-06 12:42:56 +02:00
|
|
|
if type(v) == "function" then
|
|
|
|
ret[k] = v
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-05-27 20:14:56 +02:00
|
|
|
local ctx = PangoCairo.font_map_get_default():create_context()
|
|
|
|
ret._layout = Pango.Layout.new(ctx)
|
|
|
|
|
2011-09-07 21:37:23 +02:00
|
|
|
ret:set_ellipsize("end")
|
|
|
|
ret:set_wrap("word_char")
|
|
|
|
ret:set_valign("center")
|
|
|
|
ret:set_align("left")
|
|
|
|
ret:set_font()
|
2010-10-06 12:42:56 +02:00
|
|
|
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
|
2012-06-12 15:55:10 +02:00
|
|
|
function textbox.mt:__call(...)
|
|
|
|
return new(...)
|
|
|
|
end
|
|
|
|
|
|
|
|
return setmetatable(textbox, textbox.mt)
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2011-09-11 16:50:01 +02:00
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|