2 * textbox.c - text box widget
4 * Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "common/tokenize.h"
25 extern awesome_t globalconf
;
27 /** The textbox private data structure */
30 draw_text_context_t data
;
35 PangoEllipsizeMode ellip
;
47 /** Background color */
49 /** Background image */
51 /** Background resize to wibox height. */
53 /** Background alignment */
58 textbox_geometry(widget_t
*widget
, int screen
, int height
, int width
)
61 textbox_data_t
*d
= widget
->data
;
63 geometry
.height
= height
;
66 geometry
.width
= d
->width
;
67 else if(widget
->align
== AlignFlex
)
68 geometry
.width
= width
;
71 double ratio
= d
->bg_resize
? (double) geometry
.height
/ d
->bg_image
->height
: 1;
72 geometry
.width
= MIN(width
, MAX(d
->extents
.width
+ d
->margin
.left
+ d
->margin
.right
, MAX(d
->width
, d
->bg_image
->width
* ratio
)));
75 geometry
.width
= MIN(d
->extents
.width
+ d
->margin
.left
+ d
->margin
.right
, width
);
80 /** Draw a textbox widget.
81 * \param widget The widget.
82 * \param ctx The draw context.
83 * \param screen The screen.
84 * \param p A pointer to the object we're draw onto.
87 textbox_draw(widget_t
*widget
, draw_context_t
*ctx
, area_t geometry
,
88 int screen
, wibox_t
*p
)
90 textbox_data_t
*d
= widget
->data
;
93 draw_rectangle(ctx
, geometry
, 1.0, true, &d
->bg
);
95 if(d
->border
.width
> 0)
96 draw_rectangle(ctx
, geometry
, d
->border
.width
, false, &d
->border
.color
);
100 double ratio
= d
->bg_resize
? (double) geometry
.height
/ d
->bg_image
->height
: 1;
101 /* check there is enough space to draw the image */
102 if(ratio
* d
->bg_image
->width
<= geometry
.width
)
109 x
+= (geometry
.width
- d
->bg_image
->width
* ratio
) / 2;
112 x
+= geometry
.width
- d
->bg_image
->width
* ratio
;
117 draw_image(ctx
, x
, y
, ratio
, d
->bg_image
);
121 draw_text(ctx
, &d
->data
, d
->ellip
, d
->wrap
, d
->align
, &d
->margin
, geometry
, &d
->extents
);
124 /** Delete a textbox widget.
125 * \param w The widget to destroy.
128 textbox_destructor(widget_t
*w
)
130 textbox_data_t
*d
= w
->data
;
131 draw_text_context_wipe(&d
->data
);
136 luaA_textbox_margin(lua_State
*L
)
138 widget_t
**widget
= luaA_checkudata(L
, 1, "widget");
139 textbox_data_t
*d
= (*widget
)->data
;
141 if(lua_gettop(L
) == 2)
143 d
->margin
= luaA_getopt_padding(L
, 3, &d
->margin
);
144 widget_invalidate_bywidget(*widget
);
147 return luaA_pushpadding(L
, &d
->margin
);
151 * \param L The Lua VM state.
152 * \param token The key token.
153 * \return The number of elements pushed on stack.
155 * \lfield text The text to display.
156 * \lfield width The width of the textbox. Set to 0 for auto.
157 * \lfield wrap The wrap mode: word, char, word_char.
158 * \lfield ellipsize The ellipsize mode: start, middle or end.
159 * \lfield border_width The border width to draw around.
160 * \lfield border_color The border color.
161 * \lfield align Text alignment, left, center or right.
162 * \lfield margin Method to pass text margin: a table with top, left, right and bottom keys.
163 * \lfield bg Background color.
164 * \lfield bg_image Background image.
165 * \lfield bg_align Background image alignment.
166 * \lfield bg_resize Background resize.
169 luaA_textbox_index(lua_State
*L
, awesome_token_t token
)
171 widget_t
**widget
= luaA_checkudata(L
, 1, "widget");
172 textbox_data_t
*d
= (*widget
)->data
;
177 lua_pushboolean(L
, d
->bg_resize
);
180 lua_pushstring(L
, draw_align_tostr(d
->bg_align
));
184 return luaA_image_userdata_new(L
, d
->bg_image
);
188 return luaA_pushcolor(L
, &d
->bg
);
190 lua_pushcfunction(L
, luaA_textbox_margin
);
193 lua_pushstring(L
, draw_align_tostr(d
->align
));
195 case A_TK_BORDER_WIDTH
:
196 lua_pushnumber(L
, d
->border
.width
);
198 case A_TK_BORDER_COLOR
:
199 luaA_pushcolor(L
, &d
->border
.color
);
204 lua_pushlstring(L
, d
->data
.text
, d
->data
.len
);
209 lua_pushnumber(L
, d
->width
);
215 lua_pushliteral(L
, "word");
218 lua_pushliteral(L
, "char");
221 lua_pushliteral(L
, "word_char");
229 lua_pushliteral(L
, "start");
232 lua_pushliteral(L
, "middle");
235 lua_pushliteral(L
, "end");
244 /** The __newindex method for a textbox object.
245 * \param L The Lua VM state.
246 * \param token The key token.
247 * \return The number of elements pushed on stack.
250 luaA_textbox_newindex(lua_State
*L
, awesome_token_t token
)
253 widget_t
**widget
= luaA_checkudata(L
, 1, "widget");
254 const char *buf
= NULL
;
255 textbox_data_t
*d
= (*widget
)->data
;
256 image_t
**image
= NULL
;
261 buf
= luaL_checklstring(L
, 3, &len
);
262 d
->bg_align
= draw_align_fromstr(buf
, len
);
265 d
->bg_resize
= luaA_checkboolean(L
, 3);
269 || (image
= luaA_checkudata(L
, 3, "image")))
272 image_unref(&d
->bg_image
);
274 d
->bg_image
= image_ref(image
);
282 else if((buf
= luaL_checklstring(L
, 3, &len
)))
283 xcolor_init_reply(xcolor_init_unchecked(&d
->bg
, buf
, len
));
286 if((buf
= luaL_checklstring(L
, 3, &len
)))
287 d
->align
= draw_align_fromstr(buf
, len
);
289 case A_TK_BORDER_COLOR
:
290 if((buf
= luaL_checklstring(L
, 3, &len
)))
291 xcolor_init_reply(xcolor_init_unchecked(&d
->border
.color
, buf
, len
));
293 case A_TK_BORDER_WIDTH
:
294 d
->border
.width
= luaL_checknumber(L
, 3);
298 || (buf
= luaL_checklstring(L
, 3, &len
)))
301 draw_text_context_wipe(&d
->data
);
302 p_clear(&d
->data
, 1);
308 /* if text has been converted to UTF-8 */
309 if(draw_iso2utf8(buf
, len
, &text
, &tlen
))
311 draw_text_context_init(&d
->data
, text
, tlen
);
315 draw_text_context_init(&d
->data
, buf
, len
);
317 d
->extents
= draw_text_extents(&d
->data
);
320 p_clear(&d
->extents
, 1);
324 d
->width
= luaL_checknumber(L
, 3);
327 if((buf
= luaL_checklstring(L
, 3, &len
)))
328 switch(a_tokenize(buf
, len
))
331 d
->wrap
= PANGO_WRAP_WORD
;
334 d
->wrap
= PANGO_WRAP_CHAR
;
337 d
->wrap
= PANGO_WRAP_WORD_CHAR
;
344 if((buf
= luaL_checklstring(L
, 3, &len
)))
345 switch(a_tokenize(buf
, len
))
348 d
->ellip
= PANGO_ELLIPSIZE_START
;
351 d
->ellip
= PANGO_ELLIPSIZE_MIDDLE
;
354 d
->ellip
= PANGO_ELLIPSIZE_END
;
364 widget_invalidate_bywidget(*widget
);
369 /** Create a new textbox widget.
370 * \param w The widget to initialize.
371 * \return A brand new widget.
374 widget_textbox(widget_t
*w
)
376 w
->align_supported
|= AlignFlex
;
377 w
->draw
= textbox_draw
;
378 w
->index
= luaA_textbox_index
;
379 w
->newindex
= luaA_textbox_newindex
;
380 w
->destructor
= textbox_destructor
;
381 w
->geometry
= textbox_geometry
;
383 textbox_data_t
*d
= w
->data
= p_new(textbox_data_t
, 1);
384 d
->ellip
= PANGO_ELLIPSIZE_END
;
389 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80