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 oopango = require("oopango")
|
|
|
|
local oocairo = require("oocairo")
|
|
|
|
local base = require("wibox.widget.base")
|
|
|
|
local beautiful = require("beautiful")
|
|
|
|
local type = type
|
|
|
|
local unpack = unpack
|
|
|
|
local setmetatable = setmetatable
|
|
|
|
local pairs = pairs
|
|
|
|
|
|
|
|
module("wibox.widget.textbox")
|
|
|
|
|
2010-10-06 15:11:20 +02:00
|
|
|
local function layout_create(cr)
|
|
|
|
if oopango.cairo_layout_create then
|
|
|
|
return oopango.cairo_layout_create(cr)
|
|
|
|
end
|
|
|
|
return oopango.cairo.layout_create(cr)
|
|
|
|
end
|
|
|
|
|
2011-09-07 21:37:23 +02:00
|
|
|
local function layout_update(cr, layout)
|
2010-10-06 15:11:20 +02:00
|
|
|
if oopango.cairo_update_layout then
|
|
|
|
oopango.cairo_update_layout(cr, layout)
|
|
|
|
else
|
|
|
|
oopango.cairo.update_layout(cr, layout)
|
2011-09-07 21:37:23 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function layout_show(cr, layout)
|
|
|
|
if oopango.cairo_show_layout then
|
|
|
|
oopango.cairo_show_layout(cr, layout)
|
|
|
|
else
|
2010-10-06 15:11:20 +02:00
|
|
|
oopango.cairo.show_layout(cr, layout)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
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
|
2010-10-06 12:42:56 +02:00
|
|
|
layout:set_width(oopango.units_from_number(width))
|
|
|
|
layout:set_height(oopango.units_from_number(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
|
|
|
|
function draw(box, wibox, cr, width, height)
|
|
|
|
layout_update(cr, 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)
|
|
|
|
layout_show(cr, box._layout)
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Fit the given textbox
|
|
|
|
function 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
|
|
|
|
|
|
|
|
-- Return a pango layout which can be used if no cairo context is available
|
|
|
|
local function get_temp_layout()
|
|
|
|
local surface = oocairo.image_surface_create("argb32", 0, 0)
|
|
|
|
local cr = oocairo.context_create(surface)
|
|
|
|
return layout_create(cr)
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
2011-09-07 21:37:23 +02:00
|
|
|
local temp_layout
|
2011-01-08 13:55:36 +01:00
|
|
|
-- Test if a text is valid for a textbox. If it isn't, a lua error will be thrown.
|
|
|
|
local function check_text(text, markup)
|
2011-09-07 21:37:23 +02:00
|
|
|
if not temp_layout then
|
|
|
|
temp_layout = get_temp_layout()
|
|
|
|
end
|
2011-01-08 13:55:36 +01:00
|
|
|
|
|
|
|
if markup then
|
2011-09-07 21:37:23 +02:00
|
|
|
temp_layout:set_markup(text)
|
2011-01-08 13:55:36 +01:00
|
|
|
else
|
2011-09-07 21:37:23 +02:00
|
|
|
temp_layout:set_text(text)
|
2011-01-08 13:55:36 +01:00
|
|
|
end
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Set a textbox' text.
|
|
|
|
-- @param text The text to set. This can contain pango markup (e.g. <b>bold</b>)
|
|
|
|
function set_markup(box, text)
|
2011-01-08 13:55:36 +01:00
|
|
|
check_text(text, true)
|
2011-09-07 21:37:23 +02:00
|
|
|
box._layout:set_markup(text)
|
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.
|
|
|
|
function set_text(box, text)
|
2011-01-08 13:55:36 +01:00
|
|
|
check_text(text, false)
|
2011-09-07 21:37:23 +02:00
|
|
|
box._layout:set_text(text)
|
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"
|
|
|
|
function set_ellipsize(box, mode)
|
|
|
|
local allowed = { none = true, start = true, middle = true, ["end"] = true }
|
|
|
|
if allowed[mode] then
|
2011-09-07 21:37:23 +02:00
|
|
|
box._layout:set_ellipsize(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"
|
|
|
|
function set_wrap(box, mode)
|
|
|
|
local allowed = { word = true, char = true, word_char = true }
|
|
|
|
if allowed[mode] then
|
2011-09-07 21:37:23 +02:00
|
|
|
box._layout:set_wrap(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"
|
|
|
|
function set_valign(box, mode)
|
|
|
|
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"
|
|
|
|
function set_align(box, mode)
|
|
|
|
local allowed = { left = true, center = true, right = true }
|
|
|
|
if allowed[mode] then
|
2011-09-07 21:37:23 +02:00
|
|
|
box._layout:set_alignment(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
|
|
|
|
function 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()
|
|
|
|
|
|
|
|
for k, v in pairs(_M) do
|
|
|
|
if type(v) == "function" then
|
|
|
|
ret[k] = v
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-09-07 21:37:23 +02:00
|
|
|
-- Spot the hack: Temporary surface to make pango happy
|
|
|
|
ret._layout = get_temp_layout()
|
|
|
|
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
|
|
|
|
|
|
|
|
setmetatable(_M, { __call = function (_, ...) return new(...) end })
|
|
|
|
|
2011-09-11 16:50:01 +02:00
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|