draw: remove custom markup support
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
a4d914f0e4
commit
26da80f90a
|
@ -64,7 +64,6 @@ set(AWE_SRCS
|
|||
${SOURCE_DIR}/swindow.c
|
||||
${SOURCE_DIR}/common/buffer.c
|
||||
${SOURCE_DIR}/common/atoms.c
|
||||
${SOURCE_DIR}/common/markup.c
|
||||
${SOURCE_DIR}/common/socket.c
|
||||
${SOURCE_DIR}/common/util.c
|
||||
${SOURCE_DIR}/common/version.c
|
||||
|
|
1
README
1
README
|
@ -14,7 +14,6 @@ In order to build awesome itself, you need header files and libs of:
|
|||
- cairo built with xcb support
|
||||
- pango and pangocairo
|
||||
- libev
|
||||
- glib
|
||||
- Imlib2
|
||||
- dbus (optional, use -DWITH_DBUS=OFF with cmake to disable)
|
||||
- gperf
|
||||
|
|
|
@ -37,22 +37,13 @@ alpha channel to `aa' and will blend the green with the color under it.
|
|||
|
||||
TEXT FORMAT
|
||||
-----------
|
||||
You can use and mix Pango markup and awesome markup in text string.
|
||||
You can use Pango markup in text string.
|
||||
This allows to format the text rendered in widgets.
|
||||
Pango markup documentation can be found in the Pango documentation at
|
||||
http://library.gnome.org/devel/pango/stable/PangoMarkupFormat.html.
|
||||
|
||||
List of *awesome* markup elements and their attributes:
|
||||
|
||||
* bg
|
||||
- image: path to a background image
|
||||
- align: background image alignment
|
||||
- resize: resize background image to text size
|
||||
|
||||
A Pango markup example: <span weight="bold" foreground="#336699">...</span>.
|
||||
|
||||
An *awesome* markup example: <text align="right"/>.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
awesome(1) awesome-client(1)
|
||||
|
|
|
@ -104,7 +104,7 @@ mymainmenu = awful.menu.new({ items = { { "awesome", myawesomemenu, beautiful.aw
|
|||
}
|
||||
})
|
||||
|
||||
mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
|
||||
mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),
|
||||
menu = mymainmenu })
|
||||
|
||||
-- Create a systray
|
||||
|
|
1
client.c
1
client.c
|
@ -30,7 +30,6 @@
|
|||
#include "systray.h"
|
||||
#include "property.h"
|
||||
#include "wibox.h"
|
||||
#include "common/markup.h"
|
||||
#include "common/atoms.h"
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
|
182
common/markup.c
182
common/markup.c
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
* markup.c - markup functions
|
||||
*
|
||||
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "common/markup.h"
|
||||
|
||||
/** Callback to invoke when the opening tag of an element is seen.
|
||||
* Here is just copies element elements we do not care about, and copies
|
||||
* values we care.
|
||||
* \param context the context of GMarkup
|
||||
* \param element_name element name
|
||||
* \param attribute_names array of attribute names
|
||||
* \param attribute_values array of attribute values
|
||||
* \param user_data pointer to user data, here a markup_parser_data_t pointer
|
||||
* \param error a GError
|
||||
*/
|
||||
static void
|
||||
markup_parse_start_element(GMarkupParseContext *context __attribute__ ((unused)),
|
||||
const gchar *element_name,
|
||||
const gchar **attribute_names,
|
||||
const gchar **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **error __attribute__ ((unused)))
|
||||
{
|
||||
markup_parser_data_t *p = (markup_parser_data_t *) user_data;
|
||||
int i;
|
||||
|
||||
for(i = 0; p->elements[i]; i++)
|
||||
if(!a_strcmp(element_name, p->elements[i])) {
|
||||
(*p->on_element)(p, element_name, attribute_names,
|
||||
attribute_values);
|
||||
return;
|
||||
}
|
||||
|
||||
if(a_strcmp(element_name, "markup"))
|
||||
{
|
||||
buffer_addf(&p->text, "<%s", element_name);
|
||||
for(i = 0; attribute_names[i]; i++)
|
||||
{
|
||||
buffer_addf(&p->text, " %s=\"%s\"", attribute_names[i],
|
||||
attribute_values[i]);
|
||||
}
|
||||
buffer_addc(&p->text, '>');
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback to invoke when the closing tag of an element is seen. Note that
|
||||
* this is also called for empty tags like \<empty/\>.
|
||||
* Here is just copies element elements we do not care about.
|
||||
* \param context the context of GMarkup
|
||||
* \param element_name element name
|
||||
* \param user_data pointer to user data, here a markup_parser_data_t pointer
|
||||
* \param error a GError
|
||||
*/
|
||||
static void
|
||||
markup_parse_end_element(GMarkupParseContext *context __attribute__ ((unused)),
|
||||
const gchar *element_name,
|
||||
gpointer user_data,
|
||||
GError **error __attribute__ ((unused)))
|
||||
{
|
||||
markup_parser_data_t *p = (markup_parser_data_t *) user_data;
|
||||
int i;
|
||||
|
||||
for(i = 0; p->elements[i]; i++)
|
||||
if(!a_strcmp(element_name, p->elements[i]))
|
||||
return;
|
||||
|
||||
if(a_strcmp(element_name, "markup"))
|
||||
buffer_addf(&p->text, "</%s>", element_name);
|
||||
}
|
||||
|
||||
/** Callback to invoke when some text is seen (text is always inside an
|
||||
* element). Note that the text of an element may be spread over multiple calls
|
||||
* of this function. If the G_MARKUP_TREAT_CDATA_AS_TEXT flag is set, this
|
||||
* function is also called for the content of CDATA marked sections.
|
||||
* Here it recopies blindly the text in the text attribute of user_data.
|
||||
* \param context the context of GMarkup
|
||||
* \param text the text
|
||||
* \param text_len the text length
|
||||
* \param user_data pointer to user data, here a markup_parser_data_t pointer
|
||||
* \param error a GError
|
||||
*/
|
||||
static void
|
||||
markup_parse_text(GMarkupParseContext *context __attribute__ ((unused)),
|
||||
const gchar *text,
|
||||
gsize text_len,
|
||||
gpointer user_data,
|
||||
GError **error __attribute__ ((unused)))
|
||||
{
|
||||
markup_parser_data_t *p = (markup_parser_data_t *) user_data;
|
||||
|
||||
if (text_len) {
|
||||
buffer_grow(&p->text, text_len);
|
||||
buffer_add_xmlescaped(&p->text, text);
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a markup_parser_data_t structure with elements list.
|
||||
* \param a pointer to an allocated markup_parser_data_t which must be wiped
|
||||
* with markup_parser_data_wipe()
|
||||
*/
|
||||
void markup_parser_data_init(markup_parser_data_t *p)
|
||||
{
|
||||
buffer_init(&p->text);
|
||||
}
|
||||
|
||||
/** Wipe a markup_parser_data_t initialized with markup_parser_data_init.
|
||||
* \param p markup_parser_data_t address
|
||||
*/
|
||||
void
|
||||
markup_parser_data_wipe(markup_parser_data_t *p)
|
||||
{
|
||||
buffer_wipe(&p->text);
|
||||
}
|
||||
|
||||
/** Parse markup defined in data on the string str.
|
||||
* \param data A markup_parser_data_t allocated by markup_parser_data_new().
|
||||
* \param str A string to parse markup from.
|
||||
* \param slen String length.
|
||||
* \return True if success, false otherwise.
|
||||
*/
|
||||
bool
|
||||
markup_parse(markup_parser_data_t *data, const char *str, ssize_t slen)
|
||||
{
|
||||
static GMarkupParser const parser =
|
||||
{
|
||||
/* start_element */
|
||||
markup_parse_start_element,
|
||||
/* end_element */
|
||||
markup_parse_end_element,
|
||||
/* text */
|
||||
markup_parse_text,
|
||||
/* passthrough */
|
||||
NULL,
|
||||
/* error */
|
||||
NULL
|
||||
};
|
||||
GMarkupParseContext *mkp_ctx;
|
||||
GError *error = NULL;
|
||||
|
||||
if(slen <= 0)
|
||||
return false;
|
||||
|
||||
mkp_ctx = g_markup_parse_context_new(&parser, 0, data, NULL);
|
||||
|
||||
if(!g_markup_parse_context_parse(mkp_ctx, "<markup>", -1, &error)
|
||||
|| !g_markup_parse_context_parse(mkp_ctx, str, slen, &error)
|
||||
|| !g_markup_parse_context_parse(mkp_ctx, "</markup>", -1, &error)
|
||||
|| !g_markup_parse_context_end_parse(mkp_ctx, &error))
|
||||
{
|
||||
warn("unable to parse text \"%s\": %s", str, error ? error->message : "unknown error");
|
||||
if(error)
|
||||
g_error_free(error);
|
||||
g_markup_parse_context_free(mkp_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_markup_parse_context_free(mkp_ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* markup.h - markup header
|
||||
*
|
||||
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AWESOME_COMMON_MARKUP_H
|
||||
#define AWESOME_COMMON_MARKUP_H
|
||||
|
||||
#include "common/buffer.h"
|
||||
|
||||
typedef struct markup_parser_data_t markup_parser_data_t;
|
||||
|
||||
typedef void (markup_on_elem_f)(markup_parser_data_t *, const char *,
|
||||
const char **, const char **);
|
||||
|
||||
struct markup_parser_data_t
|
||||
{
|
||||
buffer_t text;
|
||||
const char * const *elements;
|
||||
markup_on_elem_f *on_element;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
void markup_parser_data_init(markup_parser_data_t *);
|
||||
void markup_parser_data_wipe(markup_parser_data_t *);
|
||||
bool markup_parse(markup_parser_data_t *data, const char *, ssize_t);
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
|
@ -1,8 +1,10 @@
|
|||
1
|
||||
align
|
||||
bar_data_add
|
||||
bar_properties_set
|
||||
bg
|
||||
bg_align
|
||||
bg_image
|
||||
bg_resize
|
||||
border_color
|
||||
border_padding
|
||||
border_width
|
||||
|
@ -57,7 +59,6 @@ Mod5
|
|||
mouse_enter
|
||||
mouse_leave
|
||||
name
|
||||
on
|
||||
ontop
|
||||
opacity
|
||||
orientation
|
||||
|
@ -84,7 +85,6 @@ ticks_gap
|
|||
titlebar
|
||||
top
|
||||
transient_for
|
||||
true
|
||||
type
|
||||
urgent
|
||||
valign
|
||||
|
@ -96,4 +96,3 @@ word
|
|||
word_char
|
||||
workarea
|
||||
wrap
|
||||
yes
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include "tokenize.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
East,
|
||||
|
@ -313,29 +311,6 @@ a_strncat(char *dst, ssize_t n, const char *src, ssize_t l)
|
|||
return dlen + a_strncpy(dst + dlen, n - dlen, src, l);
|
||||
}
|
||||
|
||||
/** \brief convert a string to a boolean value.
|
||||
*
|
||||
* The a_strtobool() function converts a string \c s into a boolean.
|
||||
* It recognizes the strings "true", "on", "yes" and "1".
|
||||
*
|
||||
* \param[in] s the string to convert
|
||||
* \return true if the string is recognized as possibly true, false otherwise.
|
||||
*/
|
||||
static inline bool
|
||||
a_strtobool(const char *s, ssize_t len)
|
||||
{
|
||||
switch(a_tokenize(s, len))
|
||||
{
|
||||
case A_TK_TRUE:
|
||||
case A_TK_YES:
|
||||
case A_TK_ON:
|
||||
case A_TK_1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define fatal(string, ...) _fatal(__LINE__, \
|
||||
__FUNCTION__, \
|
||||
string, ## __VA_ARGS__)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "common/xutil.h"
|
||||
#include "common/atoms.h"
|
||||
#include "common/tokenize.h"
|
||||
|
||||
/** Get the string value of an atom.
|
||||
* \param conn X connection.
|
||||
|
|
167
draw.c
167
draw.c
|
@ -32,7 +32,6 @@
|
|||
#include "structs.h"
|
||||
|
||||
#include "common/tokenize.h"
|
||||
#include "common/markup.h"
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
||||
|
@ -159,81 +158,28 @@ draw_font_delete(font_t **font)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_markup_on_element(markup_parser_data_t *p, const char *elem,
|
||||
const char **names, const char **values)
|
||||
/** Initialize a draw_text_context_t with text data.
|
||||
* \param data The draw text context to init.
|
||||
* \param str The text string to render.
|
||||
* \param slen The text string length.
|
||||
* \return True if everything is ok, false otherwise.
|
||||
*/
|
||||
bool
|
||||
draw_text_context_init(draw_text_context_t *data, const char *str, ssize_t slen)
|
||||
{
|
||||
draw_parser_data_t *data = p->priv;
|
||||
|
||||
/* hack: markup.c validates tags so we can avoid strcmps here */
|
||||
switch (*elem) {
|
||||
case 'b':
|
||||
if(elem[2] == '_') /* bg_margin */
|
||||
for(; *names; names++, values++)
|
||||
switch(a_tokenize(*names, -1))
|
||||
{
|
||||
case A_TK_LEFT:
|
||||
data->bg_margin.left = atoi(*values);
|
||||
break;
|
||||
case A_TK_TOP:
|
||||
data->bg_margin.top = atoi(*values);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else /* bg */
|
||||
for(; *names; names++, values++)
|
||||
switch(a_tokenize(*names, -1))
|
||||
{
|
||||
case A_TK_IMAGE:
|
||||
if(data->bg_image)
|
||||
image_delete(&data->bg_image);
|
||||
data->bg_image = image_new_from_file(*values);
|
||||
break;
|
||||
case A_TK_ALIGN:
|
||||
data->bg_align = draw_align_fromstr(*values, -1);
|
||||
break;
|
||||
case A_TK_RESIZE:
|
||||
data->bg_resize = a_strtobool(*values, -1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
draw_text_markup_expand(draw_parser_data_t *data,
|
||||
const char *str, ssize_t slen)
|
||||
{
|
||||
static char const * const elements[] = { "bg", "bg_margin", NULL };
|
||||
markup_parser_data_t p =
|
||||
{
|
||||
.elements = elements,
|
||||
.priv = data,
|
||||
.on_element = &draw_markup_on_element,
|
||||
};
|
||||
GError *error = NULL;
|
||||
bool ret = false;
|
||||
|
||||
markup_parser_data_init(&p);
|
||||
|
||||
if(!markup_parse(&p, str, slen))
|
||||
goto bailout;
|
||||
|
||||
if(!pango_parse_markup(p.text.s, p.text.len, 0, &data->attr_list, &data->text, NULL, &error))
|
||||
if(!pango_parse_markup(str, slen, 0, &data->attr_list, &data->text, NULL, &error))
|
||||
{
|
||||
warn("cannot parse pango markup: %s", error ? error->message : "unknown error");
|
||||
if(error)
|
||||
g_error_free(error);
|
||||
goto bailout;
|
||||
return false;
|
||||
}
|
||||
|
||||
data->len = a_strlen(data->text);
|
||||
ret = true;
|
||||
|
||||
bailout:
|
||||
markup_parser_data_wipe(&p);
|
||||
return ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Initialize a new draw context.
|
||||
|
@ -273,57 +219,17 @@ draw_context_init(draw_context_t *d, int phys_screen,
|
|||
* \param align Text alignment.
|
||||
* \param margin Margin to respect when drawing text.
|
||||
* \param area Area to draw to.
|
||||
* \param text Text to draw.
|
||||
* \param len Text to draw length.
|
||||
* \param data Optional parser data.
|
||||
* \param data Draw text context data.
|
||||
* \param ext Text extents.
|
||||
*/
|
||||
void
|
||||
draw_text(draw_context_t *ctx, font_t *font, PangoEllipsizeMode ellip, PangoWrapMode wrap,
|
||||
alignment_t align, padding_t *margin, area_t area, const char *text, ssize_t len,
|
||||
draw_parser_data_t *pdata, area_t *ext)
|
||||
draw_text(draw_context_t *ctx, draw_text_context_t *data, font_t *font,
|
||||
PangoEllipsizeMode ellip, PangoWrapMode wrap,
|
||||
alignment_t align, padding_t *margin, area_t area, area_t *ext)
|
||||
{
|
||||
int x, y;
|
||||
draw_parser_data_t parser_data;
|
||||
|
||||
if(!pdata)
|
||||
{
|
||||
draw_parser_data_init(&parser_data);
|
||||
if(draw_text_markup_expand(&parser_data, text, len))
|
||||
{
|
||||
text = parser_data.text;
|
||||
len = parser_data.len;
|
||||
}
|
||||
pdata = &parser_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
text = pdata->text;
|
||||
len = pdata->len;
|
||||
}
|
||||
|
||||
if(pdata->bg_image)
|
||||
{
|
||||
x = area.x;
|
||||
y = area.y;
|
||||
switch(pdata->bg_align)
|
||||
{
|
||||
case AlignCenter:
|
||||
x += (area.width - pdata->bg_image->width) / 2;
|
||||
break;
|
||||
case AlignRight:
|
||||
x += area.width- pdata->bg_image->width;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
draw_image(ctx,
|
||||
x + pdata->bg_margin.left,
|
||||
y + pdata->bg_margin.top,
|
||||
pdata->bg_resize ? area.height : 0, pdata->bg_image);
|
||||
}
|
||||
|
||||
pango_layout_set_text(ctx->layout, pdata->text, pdata->len);
|
||||
pango_layout_set_text(ctx->layout, data->text, data->len);
|
||||
pango_layout_set_width(ctx->layout,
|
||||
pango_units_from_double(area.width
|
||||
- (margin->left
|
||||
|
@ -332,7 +238,7 @@ draw_text(draw_context_t *ctx, font_t *font, PangoEllipsizeMode ellip, PangoWrap
|
|||
- (margin->top + margin->bottom));
|
||||
pango_layout_set_ellipsize(ctx->layout, ellip);
|
||||
pango_layout_set_wrap(ctx->layout, wrap);
|
||||
pango_layout_set_attributes(ctx->layout, pdata->attr_list);
|
||||
pango_layout_set_attributes(ctx->layout, data->attr_list);
|
||||
pango_layout_set_font_description(ctx->layout, font->desc);
|
||||
|
||||
x = area.x + margin->left;
|
||||
|
@ -364,9 +270,6 @@ draw_text(draw_context_t *ctx, font_t *font, PangoEllipsizeMode ellip, PangoWrap
|
|||
ctx->fg.alpha / 65535.0);
|
||||
pango_cairo_update_layout(ctx->cr, ctx->layout);
|
||||
pango_cairo_show_layout(ctx->cr, ctx->layout);
|
||||
|
||||
if (pdata == &parser_data)
|
||||
draw_parser_data_wipe(&parser_data);
|
||||
}
|
||||
|
||||
/** Setup color-source for cairo (gradient or mono).
|
||||
|
@ -657,14 +560,13 @@ draw_graph_line(draw_context_t *ctx, area_t rect, int *to, int cur_index,
|
|||
* \param y Y coordinate.
|
||||
* \param w Width.
|
||||
* \param h Height.
|
||||
* \param wanted_h Wanted height: if > 0, image will be resized.
|
||||
* \param ratio The ratio to apply to the image.
|
||||
* \param data The image pixels array.
|
||||
*/
|
||||
static void
|
||||
draw_image_from_argb_data(draw_context_t *ctx, int x, int y, int w, int h,
|
||||
int wanted_h, unsigned char *data)
|
||||
double ratio, unsigned char *data)
|
||||
{
|
||||
double ratio;
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *source;
|
||||
|
||||
|
@ -675,14 +577,8 @@ draw_image_from_argb_data(draw_context_t *ctx, int x, int y, int w, int h,
|
|||
cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, w));
|
||||
#endif
|
||||
cr = cairo_create(ctx->surface);
|
||||
if(wanted_h > 0 && h > 0)
|
||||
{
|
||||
ratio = (double) wanted_h / (double) h;
|
||||
cairo_scale(cr, ratio, ratio);
|
||||
cairo_set_source_surface(cr, source, x / ratio, y / ratio);
|
||||
}
|
||||
else
|
||||
cairo_set_source_surface(cr, source, x, y);
|
||||
cairo_scale(cr, ratio, ratio);
|
||||
cairo_set_source_surface(cr, source, x / ratio, y / ratio);
|
||||
|
||||
cairo_paint(cr);
|
||||
|
||||
|
@ -694,13 +590,13 @@ draw_image_from_argb_data(draw_context_t *ctx, int x, int y, int w, int h,
|
|||
* \param ctx Draw context to draw to.
|
||||
* \param x X coordinate.
|
||||
* \param y Y coordinate.
|
||||
* \param wanted_h Wanted height: if > 0, image will be resized.
|
||||
* \param ratio The ratio to apply to the image.
|
||||
* \param image The image to draw.
|
||||
*/
|
||||
void
|
||||
draw_image(draw_context_t *ctx, int x, int y, int wanted_h, image_t *image)
|
||||
draw_image(draw_context_t *ctx, int x, int y, double ratio, image_t *image)
|
||||
{
|
||||
draw_image_from_argb_data(ctx, x, y, image->width, image->height, wanted_h, image->data);
|
||||
draw_image_from_argb_data(ctx, x, y, image->width, image->height, ratio, image->data);
|
||||
}
|
||||
|
||||
/** Rotate a pixmap.
|
||||
|
@ -743,14 +639,12 @@ draw_rotate(draw_context_t *ctx,
|
|||
}
|
||||
|
||||
/** Return the width and height of a text in pixel.
|
||||
* \param data The draw context text data.
|
||||
* \param font Font to use.
|
||||
* \param text The text.
|
||||
* \param len The text length.
|
||||
* \param pdata The parser data to fill.
|
||||
* \return Text height and width.
|
||||
*/
|
||||
area_t
|
||||
draw_text_extents(font_t *font, const char *text, ssize_t len, draw_parser_data_t *parser_data)
|
||||
draw_text_extents(draw_text_context_t *data, font_t *font)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
@ -759,10 +653,7 @@ draw_text_extents(font_t *font, const char *text, ssize_t len, draw_parser_data_
|
|||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, globalconf.default_screen);
|
||||
area_t geom = { 0, 0, 0, 0 };
|
||||
|
||||
if(!len)
|
||||
return geom;
|
||||
|
||||
if(!draw_text_markup_expand(parser_data, text, len))
|
||||
if(data->len <= 0)
|
||||
return geom;
|
||||
|
||||
surface = cairo_xcb_surface_create(globalconf.connection,
|
||||
|
@ -773,8 +664,8 @@ draw_text_extents(font_t *font, const char *text, ssize_t len, draw_parser_data_
|
|||
|
||||
cr = cairo_create(surface);
|
||||
layout = pango_cairo_create_layout(cr);
|
||||
pango_layout_set_text(layout, parser_data->text, parser_data->len);
|
||||
pango_layout_set_attributes(layout, parser_data->attr_list);
|
||||
pango_layout_set_text(layout, data->text, data->len);
|
||||
pango_layout_set_attributes(layout, data->attr_list);
|
||||
pango_layout_set_font_description(layout, font->desc);
|
||||
pango_layout_get_pixel_extents(layout, NULL, &ext);
|
||||
g_object_unref(layout);
|
||||
|
|
28
draw.h
28
draw.h
|
@ -169,16 +169,10 @@ typedef struct
|
|||
PangoAttrList *attr_list;
|
||||
char *text;
|
||||
ssize_t len;
|
||||
struct
|
||||
{
|
||||
int top, left;
|
||||
} bg_margin;
|
||||
image_t *bg_image;
|
||||
alignment_t bg_align;
|
||||
bool bg_resize;
|
||||
} draw_parser_data_t;
|
||||
} draw_text_context_t;
|
||||
|
||||
void draw_text(draw_context_t *, font_t *, PangoEllipsizeMode, PangoWrapMode, alignment_t, padding_t *, area_t, const char *, ssize_t len, draw_parser_data_t *, area_t *);
|
||||
bool draw_text_context_init(draw_text_context_t *, const char *, ssize_t);
|
||||
void draw_text(draw_context_t *, draw_text_context_t *, font_t *, PangoEllipsizeMode, PangoWrapMode, alignment_t, padding_t *, area_t, area_t *);
|
||||
void draw_rectangle(draw_context_t *, area_t, float, bool, const xcolor_t *);
|
||||
void draw_rectangle_gradient(draw_context_t *, area_t, float, bool, vector_t,
|
||||
const xcolor_t *, const xcolor_t *, const xcolor_t *);
|
||||
|
@ -188,9 +182,9 @@ void draw_graph(draw_context_t *, area_t, int *, int *, int, position_t, vector_
|
|||
const xcolor_t *, const xcolor_t *, const xcolor_t *);
|
||||
void draw_graph_line(draw_context_t *, area_t, int *, int, position_t, vector_t,
|
||||
const xcolor_t *, const xcolor_t *, const xcolor_t *);
|
||||
void draw_image(draw_context_t *, int, int, int, image_t *);
|
||||
void draw_image(draw_context_t *, int, int, double, image_t *);
|
||||
void draw_rotate(draw_context_t *, xcb_drawable_t, xcb_drawable_t, int, int, int, int, double, int, int);
|
||||
area_t draw_text_extents(font_t *, const char *, ssize_t, draw_parser_data_t *);
|
||||
area_t draw_text_extents(draw_text_context_t *, font_t *);
|
||||
alignment_t draw_align_fromstr(const char *, ssize_t);
|
||||
const char *draw_align_tostr(alignment_t);
|
||||
|
||||
|
@ -212,19 +206,13 @@ xcolor_init_request_t xcolor_init_unchecked(xcolor_t *, const char *, ssize_t);
|
|||
bool xcolor_init_reply(xcolor_init_request_t);
|
||||
|
||||
static inline void
|
||||
draw_parser_data_init(draw_parser_data_t *pdata)
|
||||
{
|
||||
p_clear(pdata, 1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
draw_parser_data_wipe(draw_parser_data_t *pdata)
|
||||
draw_text_context_wipe(draw_text_context_t *pdata)
|
||||
{
|
||||
if(pdata)
|
||||
{
|
||||
pango_attr_list_unref(pdata->attr_list);
|
||||
if(pdata->attr_list)
|
||||
pango_attr_list_unref(pdata->attr_list);
|
||||
p_delete(&pdata->text);
|
||||
image_unref(&pdata->bg_image);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
-- Grab environment we need
|
||||
local math = math
|
||||
local image = image
|
||||
local pairs = pairs
|
||||
local otable = otable
|
||||
local capi =
|
||||
|
@ -72,13 +73,13 @@ function add(c, args)
|
|||
local closef
|
||||
if theme.titlebar_close_button_focus then
|
||||
closef = widget.button({ align = "right",
|
||||
image = theme.titlebar_close_button_focus })
|
||||
image = image(theme.titlebar_close_button_focus) })
|
||||
end
|
||||
|
||||
local close
|
||||
if theme.titlebar_close_button_normal then
|
||||
close = widget.button({ align = "right",
|
||||
image = theme.titlebar_close_button_normal })
|
||||
image = image(theme.titlebar_close_button_normal) })
|
||||
end
|
||||
|
||||
if close or closef then
|
||||
|
|
|
@ -15,6 +15,7 @@ local capi =
|
|||
client = client,
|
||||
button = button,
|
||||
widget = widget,
|
||||
image = image,
|
||||
mouse = mouse
|
||||
}
|
||||
local util = require("awful.util")
|
||||
|
@ -51,20 +52,24 @@ local function taglist_update (screen, w, label, buttons, data)
|
|||
end
|
||||
-- Update widgets text
|
||||
for k, tag in ipairs(tags) do
|
||||
w[k].text, w[k].bg = label(tag)
|
||||
if buttons then
|
||||
if not data[tag] then
|
||||
-- Replace press function by a new one calling with tags as
|
||||
-- argument.
|
||||
-- This is done here because order of tags can change
|
||||
data[tag] = {}
|
||||
for kb, b in ipairs(buttons) do
|
||||
-- Copy object
|
||||
data[tag][kb] = capi.button(b)
|
||||
data[tag][kb].press = function () b.press(tag) end
|
||||
local text, bg, bg_image, bg_resize = label(tag)
|
||||
w[k].text = text
|
||||
if text then
|
||||
w[k].bg, w[k].bg_image, w[k].bg_resize = bg, bg_image, bg_resize
|
||||
if buttons then
|
||||
if not data[tag] then
|
||||
-- Replace press function by a new one calling with tags as
|
||||
-- argument.
|
||||
-- This is done here because order of tags can change
|
||||
data[tag] = {}
|
||||
for kb, b in ipairs(buttons) do
|
||||
-- Copy object
|
||||
data[tag][kb] = capi.button(b)
|
||||
data[tag][kb].press = function () b.press(tag) end
|
||||
end
|
||||
end
|
||||
w[k]:buttons(data[tag])
|
||||
end
|
||||
w[k]:buttons(data[tag])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -112,7 +117,8 @@ end
|
|||
-- squares_sel Optional: a user provided image for selected squares.
|
||||
-- squares_unsel Optional: a user provided image for unselected squares.
|
||||
-- squares_resize Optional: true or false to resize squares.
|
||||
-- @return A string to print and a background color.
|
||||
-- @return A string to print, a background color, a background image and a
|
||||
-- background resize value.
|
||||
function taglist.label.all(t, args)
|
||||
if not args then args = {} end
|
||||
local theme = beautiful.get()
|
||||
|
@ -124,23 +130,26 @@ function taglist.label.all(t, args)
|
|||
local taglist_squares_unsel = args.squares_unsel or theme.taglist_squares_unsel
|
||||
local taglist_squares_resize = theme.taglist_squares_resize or args.squares_resize or "true"
|
||||
local font = args.font or theme.taglist_font or theme.font or ""
|
||||
local text = "<span font_desc='"..font.."'>"
|
||||
local background = ""
|
||||
local text = "<span font_desc='"..font.."'> "
|
||||
local sel = capi.client.focus
|
||||
local bg_color = nil
|
||||
local fg_color = nil
|
||||
local bg_image
|
||||
local bg_resize = false
|
||||
if t.selected then
|
||||
bg_color = bg_focus
|
||||
fg_color = fg_focus
|
||||
end
|
||||
if sel and sel:tags()[t] then
|
||||
if taglist_squares_sel then
|
||||
background = "resize=\"" .. taglist_squares_resize .. "\" image=\"" .. taglist_squares_sel .. "\""
|
||||
bg_image = capi.image(taglist_squares_sel)
|
||||
bg_resize = taglist_squares_resize == "true"
|
||||
end
|
||||
else
|
||||
local cls = t:clients()
|
||||
if #cls > 0 and taglist_squares_unsel then
|
||||
background = "resize=\"" .. taglist_squares_resize .. "\" image=\"" .. taglist_squares_unsel .. "\""
|
||||
bg_image = capi.image(taglist_squares_unsel)
|
||||
bg_resize = taglist_squares_resize == "true"
|
||||
end
|
||||
for k, c in pairs(cls) do
|
||||
if c.urgent then
|
||||
|
@ -151,12 +160,12 @@ function taglist.label.all(t, args)
|
|||
end
|
||||
end
|
||||
if fg_color then
|
||||
text = text .. "<bg "..background.." /> <span color='"..util.color_strip_alpha(fg_color).."'>"..util.escape(t.name).."</span> "
|
||||
text = text .. "<span color='"..util.color_strip_alpha(fg_color).."'>"..util.escape(t.name).."</span>"
|
||||
else
|
||||
text = text .. " <bg "..background.." />"..util.escape(t.name).." "
|
||||
text = text .. util.escape(t.name)
|
||||
end
|
||||
text = text .. "</span>"
|
||||
return text, bg_color
|
||||
text = text .. " </span>"
|
||||
return text, bg_color, bg_image, bg_resize
|
||||
end
|
||||
|
||||
--- Return labels for a taglist widget with all *non empty* tags from screen.
|
||||
|
@ -168,7 +177,8 @@ end
|
|||
-- fg_focus The foreground color for selected tag.
|
||||
-- bg_urgent The background color for urgent tags.
|
||||
-- fg_urgent The foreground color for urgent tags.
|
||||
-- @return A string to print.
|
||||
-- @return A string to print, a background color, a background image and a
|
||||
-- background resize value.
|
||||
function taglist.label.noempty(t, args)
|
||||
if #t:clients() > 0 or t.selected then
|
||||
return taglist.label.all(t, args)
|
||||
|
@ -195,6 +205,8 @@ local function tasklist_update(w, buttons, label, data)
|
|||
w[i] = capi.widget({ type = "imagebox", align = "flex" })
|
||||
w[i + 1] = capi.widget({ type = "textbox", align = "flex" })
|
||||
w[i + 1]:margin({ left = 2, right = 2 })
|
||||
w[i + 1].bg_resize = true
|
||||
w[i + 1].bg_align = "right"
|
||||
end
|
||||
-- Remove widgets
|
||||
elseif len > #clients then
|
||||
|
@ -220,7 +232,7 @@ local function tasklist_update(w, buttons, label, data)
|
|||
w[k]:buttons(data[c])
|
||||
w[k + 1]:buttons(data[c])
|
||||
end
|
||||
w[k + 1].text, w[k + 1].bg = label(clients[(k + 1) / 2])
|
||||
w[k + 1].text, w[k + 1].bg, w[k + 1].bg_image= label(clients[(k + 1) / 2])
|
||||
w[k].bg = w[k + 1].bg
|
||||
if w[k + 1].text then
|
||||
-- Set icon
|
||||
|
@ -275,13 +287,13 @@ local function widget_tasklist_label_common(c, args)
|
|||
local fg_urgent = args.fg_urgent or theme.tasklist_fg_urgent or theme.fg_urgent
|
||||
local bg_urgent = args.bg_urgent or theme.tasklist_bg_urgent or theme.bg_urgent
|
||||
local floating_icon = args.floating_icon or theme.tasklist_floating_icon
|
||||
local floating_icon_align = args.floating_icon_align or theme.tasklist_floating_icon_align or "right"
|
||||
local font = args.font or theme.tasklist_font or theme.font or ""
|
||||
local bg = nil
|
||||
local text = "<span font_desc='"..font.."'>"
|
||||
local name
|
||||
local status_image
|
||||
if client.floating.get(c) and floating_icon then
|
||||
text = text.."<bg image=\"" .. floating_icon .. "\" align=\"" .. floating_icon_align .. "\"/>"
|
||||
status_image = capi.image(floating_icon)
|
||||
end
|
||||
if c.minimized then
|
||||
name = util.escape(c.icon_name) or ""
|
||||
|
@ -302,7 +314,7 @@ local function widget_tasklist_label_common(c, args)
|
|||
text = text .. name
|
||||
end
|
||||
text = text .. "</span>"
|
||||
return text, bg
|
||||
return text, bg, status_image
|
||||
end
|
||||
|
||||
--- Return labels for a tasklist widget with clients from all tags and screen.
|
||||
|
@ -316,7 +328,7 @@ end
|
|||
-- fg_focus The foreground color for focused client.
|
||||
-- bg_urgent The background color for urgent clients.
|
||||
-- fg_urgent The foreground color for urgent clients.
|
||||
-- @return A string to print and a background color.
|
||||
-- @return A string to print, a background color and a status image.
|
||||
function tasklist.label.allscreen(c, screen, args)
|
||||
return widget_tasklist_label_common(c, args)
|
||||
end
|
||||
|
@ -332,7 +344,7 @@ end
|
|||
-- fg_focus The foreground color for focused client.
|
||||
-- bg_urgent The background color for urgent clients.
|
||||
-- fg_urgent The foreground color for urgent clients.
|
||||
-- @return A string to print and a background color.
|
||||
-- @return A string to print, a background color and a status image.
|
||||
function tasklist.label.alltags(c, screen, args)
|
||||
-- Only print client on the same screen as this widget
|
||||
if c.screen ~= screen then return end
|
||||
|
@ -350,7 +362,7 @@ end
|
|||
-- fg_focus The foreground color for focused client.
|
||||
-- bg_urgent The background color for urgent clients.
|
||||
-- fg_urgent The foreground color for urgent clients.
|
||||
-- @return A string to print and a background color.
|
||||
-- @return A string to print, a background color and a status image.
|
||||
function tasklist.label.currenttags(c, screen, args)
|
||||
-- Only print client on the same screen as this widget
|
||||
if c.screen ~= screen then return end
|
||||
|
@ -367,14 +379,14 @@ end
|
|||
-- @return A textbox widget configured as a button.
|
||||
function button(args)
|
||||
if not args or not args.image then return end
|
||||
args.type = "textbox"
|
||||
local img_release = args.image
|
||||
local img_press = img_release:crop(-2, -2, img_release.width, img_release.height)
|
||||
args.type = "imagebox"
|
||||
local w = capi.widget(args)
|
||||
local img_release = "<bg image=\"" .. args.image .. "\" resize=\"true\"/>"
|
||||
local img_press = "<bg_margin top=\"2\" left=\"2\"/><bg image=\"" .. args.image .. "\" resize=\"true\"/>"
|
||||
w.text = img_release
|
||||
w:buttons({ capi.button({}, 1, function () w.text = img_press end, function () w.text = img_release end) })
|
||||
function w.mouse_leave(s) w.text = img_release end
|
||||
function w.mouse_enter(s) if capi.mouse.coords().buttons[1] then w.text = img_press end end
|
||||
w.image = img_release
|
||||
w:buttons({ capi.button({}, 1, function () w.image = img_press end, function () w.image = img_release end) })
|
||||
function w.mouse_leave(s) w.image = img_release end
|
||||
function w.mouse_enter(s) if capi.mouse.coords().buttons[1] then w.image = img_press end end
|
||||
return w
|
||||
end
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "common/xutil.h"
|
||||
#include "common/xembed.h"
|
||||
#include "common/refcount.h"
|
||||
#include "common/tokenize.h"
|
||||
|
||||
/** Windows type */
|
||||
typedef enum
|
||||
|
|
|
@ -44,13 +44,15 @@ imagebox_geometry(widget_t *widget, int screen, int height, int width)
|
|||
{
|
||||
if(d->resize)
|
||||
{
|
||||
geometry.width = ((double) height / (double) d->image->height) * d->image->width;
|
||||
geometry.height = height;
|
||||
double ratio = (double) height / d->image->height;
|
||||
geometry.width = ratio * d->image->width;
|
||||
if(geometry.width > width)
|
||||
{
|
||||
geometry.width = 0;
|
||||
geometry.height = 0;
|
||||
}
|
||||
else
|
||||
geometry.height = height;
|
||||
}
|
||||
else if(d->image->width <= width)
|
||||
{
|
||||
|
@ -91,6 +93,7 @@ imagebox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry,
|
|||
draw_rectangle(ctx, geometry, 1.0, true, &d->bg);
|
||||
|
||||
int y = geometry.y;
|
||||
double ratio = d->resize ? (double) geometry.height / d->image->height : 1;
|
||||
switch(d->valign)
|
||||
{
|
||||
case AlignBottom:
|
||||
|
@ -103,7 +106,7 @@ imagebox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry,
|
|||
break;
|
||||
}
|
||||
|
||||
draw_image(ctx, geometry.x, y, d->resize ? ctx->height : 0, d->image);
|
||||
draw_image(ctx, geometry.x, y, ratio, d->image);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,18 +27,13 @@ extern awesome_t globalconf;
|
|||
/** The textbox private data structure */
|
||||
typedef struct
|
||||
{
|
||||
/** Textbox text */
|
||||
char *text;
|
||||
/** Textbox text length */
|
||||
ssize_t len;
|
||||
draw_text_context_t data;
|
||||
/** Textbox width */
|
||||
int width;
|
||||
/** Extents */
|
||||
area_t extents;
|
||||
PangoEllipsizeMode ellip;
|
||||
PangoWrapMode wrap;
|
||||
/** Draw parser data */
|
||||
draw_parser_data_t pdata;
|
||||
/** Border */
|
||||
struct
|
||||
{
|
||||
|
@ -51,6 +46,12 @@ typedef struct
|
|||
padding_t margin;
|
||||
/** Background color */
|
||||
xcolor_t bg;
|
||||
/** Background image */
|
||||
image_t *bg_image;
|
||||
/** Background resize to wibox height. */
|
||||
bool bg_resize;
|
||||
/** Background alignment */
|
||||
alignment_t bg_align;
|
||||
} textbox_data_t;
|
||||
|
||||
static area_t
|
||||
|
@ -65,14 +66,13 @@ textbox_geometry(widget_t *widget, int screen, int height, int width)
|
|||
geometry.width = d->width;
|
||||
else if(widget->align == AlignFlex)
|
||||
geometry.width = width;
|
||||
else
|
||||
else if(d->bg_image)
|
||||
{
|
||||
geometry.width = MIN(d->extents.width, width);
|
||||
|
||||
if(d->pdata.bg_image)
|
||||
geometry.width = MAX(geometry.width,
|
||||
d->pdata.bg_resize ? ((double) d->pdata.bg_image->width / (double) d->pdata.bg_image->height) * geometry.height : d->pdata.bg_image->width);
|
||||
double ratio = d->bg_resize ? (double) geometry.height / d->bg_image->height : 1;
|
||||
geometry.width = MIN(width, MAX(d->extents.width, MAX(d->width, d->bg_image->width * ratio)));
|
||||
}
|
||||
else
|
||||
geometry.width = MIN(d->extents.width, width);
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
@ -95,8 +95,30 @@ textbox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry,
|
|||
if(d->border.width > 0)
|
||||
draw_rectangle(ctx, geometry, d->border.width, false, &d->border.color);
|
||||
|
||||
draw_text(ctx, globalconf.font, d->ellip, d->wrap, d->align, &d->margin,
|
||||
geometry, d->text, d->len, &d->pdata, &d->extents);
|
||||
if(d->bg_image)
|
||||
{
|
||||
double ratio = d->bg_resize ? (double) geometry.height / d->bg_image->height : 1;
|
||||
/* check there is enough space to draw the image */
|
||||
if(ratio * d->bg_image->width <= geometry.width)
|
||||
{
|
||||
int x = geometry.x;
|
||||
int y = geometry.y;
|
||||
switch(d->bg_align)
|
||||
{
|
||||
case AlignCenter:
|
||||
x += (geometry.width - d->bg_image->width * ratio) / 2;
|
||||
break;
|
||||
case AlignRight:
|
||||
x += geometry.width - d->bg_image->width * ratio;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
draw_image(ctx, x, y, ratio, d->bg_image);
|
||||
}
|
||||
}
|
||||
|
||||
draw_text(ctx, &d->data, globalconf.font, d->ellip, d->wrap, d->align, &d->margin, geometry, &d->extents);
|
||||
}
|
||||
|
||||
/** Delete a textbox widget.
|
||||
|
@ -106,8 +128,7 @@ static void
|
|||
textbox_destructor(widget_t *w)
|
||||
{
|
||||
textbox_data_t *d = w->data;
|
||||
draw_parser_data_wipe(&d->pdata);
|
||||
p_delete(&d->text);
|
||||
draw_text_context_wipe(&d->data);
|
||||
p_delete(&d);
|
||||
}
|
||||
|
||||
|
@ -140,6 +161,9 @@ luaA_textbox_margin(lua_State *L)
|
|||
* \lfield align Text alignment, left, center or right.
|
||||
* \lfield margin Method to pass text margin: a table with top, left, right and bottom keys.
|
||||
* \lfield bg Background color.
|
||||
* \lfield bg_image Background image.
|
||||
* \lfield bg_align Background image alignment.
|
||||
* \lfield bg_resize Background resize.
|
||||
*/
|
||||
static int
|
||||
luaA_textbox_index(lua_State *L, awesome_token_t token)
|
||||
|
@ -149,6 +173,17 @@ luaA_textbox_index(lua_State *L, awesome_token_t token)
|
|||
|
||||
switch(token)
|
||||
{
|
||||
case A_TK_BG_RESIZE:
|
||||
lua_pushboolean(L, d->bg_resize);
|
||||
return 1;
|
||||
case A_TK_BG_ALIGN:
|
||||
lua_pushstring(L, draw_align_tostr(d->bg_align));
|
||||
return 1;
|
||||
case A_TK_BG_IMAGE:
|
||||
if(d->bg_image)
|
||||
return luaA_image_userdata_new(L, d->bg_image);
|
||||
else
|
||||
return 0;
|
||||
case A_TK_BG:
|
||||
return luaA_pushcolor(L, &d->bg);
|
||||
case A_TK_MARGIN:
|
||||
|
@ -164,8 +199,12 @@ luaA_textbox_index(lua_State *L, awesome_token_t token)
|
|||
luaA_pushcolor(L, &d->border.color);
|
||||
return 1;
|
||||
case A_TK_TEXT:
|
||||
lua_pushstring(L, d->text);
|
||||
return 1;
|
||||
if(d->data.len > 0)
|
||||
{
|
||||
lua_pushlstring(L, d->data.text, d->data.len);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case A_TK_WIDTH:
|
||||
lua_pushnumber(L, d->width);
|
||||
return 1;
|
||||
|
@ -214,9 +253,29 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token)
|
|||
widget_t **widget = luaA_checkudata(L, 1, "widget");
|
||||
const char *buf = NULL;
|
||||
textbox_data_t *d = (*widget)->data;
|
||||
image_t **image = NULL;
|
||||
|
||||
switch(token)
|
||||
{
|
||||
case A_TK_BG_ALIGN:
|
||||
buf = luaL_checklstring(L, 3, &len);
|
||||
d->bg_align = draw_align_fromstr(buf, len);
|
||||
break;
|
||||
case A_TK_BG_RESIZE:
|
||||
d->bg_resize = luaA_checkboolean(L, 3);
|
||||
break;
|
||||
case A_TK_BG_IMAGE:
|
||||
if(lua_isnil(L, 3)
|
||||
|| (image = luaA_checkudata(L, 3, "image")))
|
||||
{
|
||||
/* unref image */
|
||||
image_unref(&d->bg_image);
|
||||
if(image)
|
||||
d->bg_image = image_ref(image);
|
||||
else
|
||||
d->bg_image = NULL;
|
||||
}
|
||||
break;
|
||||
case A_TK_BG:
|
||||
if(lua_isnil(L, 3))
|
||||
p_clear(&d->bg, 1);
|
||||
|
@ -239,21 +298,26 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token)
|
|||
|| (buf = luaL_checklstring(L, 3, &len)))
|
||||
{
|
||||
/* delete */
|
||||
draw_parser_data_wipe(&d->pdata);
|
||||
/* reinit since we are giving it as arg to draw_text unconditionally */
|
||||
draw_parser_data_init(&d->pdata);
|
||||
p_delete(&d->text);
|
||||
draw_text_context_wipe(&d->data);
|
||||
p_clear(&d->data, 1);
|
||||
|
||||
if(buf)
|
||||
{
|
||||
a_iso2utf8(buf, len, &d->text, &d->len);
|
||||
d->extents = draw_text_extents(globalconf.font, d->text, d->len, &d->pdata);
|
||||
char *text;
|
||||
ssize_t tlen;
|
||||
/* if text has been converted to UTF-8 */
|
||||
if(draw_iso2utf8(buf, len, &text, &tlen))
|
||||
{
|
||||
draw_text_context_init(&d->data, text, tlen);
|
||||
p_delete(&text);
|
||||
}
|
||||
else
|
||||
draw_text_context_init(&d->data, buf, len);
|
||||
|
||||
d->extents = draw_text_extents(&d->data, globalconf.font);
|
||||
}
|
||||
else
|
||||
{
|
||||
d->len = 0;
|
||||
p_clear(&d->extents, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case A_TK_WIDTH:
|
||||
|
|
Loading…
Reference in New Issue