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.
25 #include "common/tokenize.h"
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
)
60 textbox_data_t
*d
= widget
->data
;
61 area_t geometry
= d
->extents
;
62 geometry
.width
+= d
->margin
.left
+ d
->margin
.left
;
63 geometry
.height
+= d
->margin
.bottom
+ d
->margin
.top
;
67 int bgi_height
= image_getheight(d
->bg_image
);
68 int bgi_width
= image_getwidth(d
->bg_image
);
69 double ratio
= d
->bg_resize
? (double) geometry
.height
/ bgi_height
: 1;
70 geometry
.width
= MAX(d
->extents
.width
+ d
->margin
.left
+ d
->margin
.right
, MAX(d
->width
, bgi_width
* ratio
));
73 geometry
.x
= geometry
.y
= 0;
79 textbox_extents(lua_State
*L
, widget_t
*widget
)
81 return textbox_geometry(widget
, 0);
84 /** Draw a textbox widget.
85 * \param widget The widget.
86 * \param ctx The draw context.
87 * \param p A pointer to the object we're draw onto.
90 textbox_draw(widget_t
*widget
, draw_context_t
*ctx
, area_t geometry
, wibox_t
*p
)
92 textbox_data_t
*d
= widget
->data
;
95 draw_rectangle(ctx
, geometry
, 1.0, true, &d
->bg
);
97 if(d
->border
.width
> 0)
98 draw_rectangle(ctx
, geometry
, d
->border
.width
, false, &d
->border
.color
);
102 int bgi_height
= image_getheight(d
->bg_image
);
103 int bgi_width
= image_getwidth(d
->bg_image
);
104 double ratio
= d
->bg_resize
? (double) geometry
.height
/ bgi_height
: 1;
105 /* check there is enough space to draw the image */
106 if(ratio
* bgi_width
<= geometry
.width
)
113 x
+= (geometry
.width
- bgi_width
* ratio
) / 2;
116 x
+= geometry
.width
- bgi_width
* ratio
;
119 y
+= geometry
.height
- bgi_height
* ratio
;
122 y
+= (geometry
.height
- bgi_height
* ratio
) / 2;
127 draw_image(ctx
, x
, y
, ratio
, d
->bg_image
);
131 geometry
.y
+= (geometry
.height
- textbox_geometry(widget
, ctx
->phys_screen
).height
) / 2;
132 draw_text(ctx
, &d
->data
, d
->ellip
, d
->wrap
, d
->align
, &d
->margin
, geometry
, &d
->extents
);
135 /** Delete a textbox widget.
136 * \param w The widget to destroy.
139 textbox_destructor(widget_t
*w
)
141 textbox_data_t
*d
= w
->data
;
142 draw_text_context_wipe(&d
->data
);
147 luaA_textbox_margin(lua_State
*L
)
149 widget_t
*widget
= luaA_checkudata(L
, 1, &widget_class
);
150 textbox_data_t
*d
= widget
->data
;
152 if(lua_gettop(L
) == 2)
154 d
->margin
= luaA_getopt_padding(L
, 2, &d
->margin
);
155 widget_invalidate_bywidget(widget
);
158 return luaA_pushpadding(L
, &d
->margin
);
162 * \param L The Lua VM state.
163 * \param token The key token.
164 * \return The number of elements pushed on stack.
166 * \lfield text The text to display.
167 * \lfield width The width of the textbox. Set to 0 for auto.
168 * \lfield wrap The wrap mode: word, char, word_char.
169 * \lfield ellipsize The ellipsize mode: start, middle or end.
170 * \lfield border_width The border width to draw around.
171 * \lfield border_color The border color.
172 * \lfield align Text alignment, left, center or right.
173 * \lfield margin Method to pass text margin: a table with top, left, right and bottom keys.
174 * \lfield bg Background color.
175 * \lfield bg_image Background image.
176 * \lfield bg_align Background image alignment, left, center, right, bottom, top or middle
177 * \lfield bg_resize Background resize.
180 luaA_textbox_index(lua_State
*L
, awesome_token_t token
)
182 widget_t
*widget
= luaA_checkudata(L
, 1, &widget_class
);
183 textbox_data_t
*d
= widget
->data
;
188 lua_pushboolean(L
, d
->bg_resize
);
191 lua_pushstring(L
, draw_align_tostr(d
->bg_align
));
194 return luaA_object_push(L
, d
->bg_image
);
196 return luaA_pushcolor(L
, &d
->bg
);
198 lua_pushcfunction(L
, luaA_textbox_margin
);
201 lua_pushstring(L
, draw_align_tostr(d
->align
));
203 case A_TK_BORDER_WIDTH
:
204 lua_pushnumber(L
, d
->border
.width
);
206 case A_TK_BORDER_COLOR
:
207 luaA_pushcolor(L
, &d
->border
.color
);
212 lua_pushlstring(L
, d
->data
.text
, d
->data
.len
);
217 lua_pushnumber(L
, d
->width
);
223 lua_pushliteral(L
, "word");
226 lua_pushliteral(L
, "char");
229 lua_pushliteral(L
, "word_char");
237 lua_pushliteral(L
, "start");
240 lua_pushliteral(L
, "middle");
243 lua_pushliteral(L
, "end");
252 /** The __newindex method for a textbox object.
253 * \param L The Lua VM state.
254 * \param token The key token.
255 * \return The number of elements pushed on stack.
258 luaA_textbox_newindex(lua_State
*L
, awesome_token_t token
)
261 widget_t
*widget
= luaA_checkudata(L
, 1, &widget_class
);
262 const char *buf
= NULL
;
263 textbox_data_t
*d
= widget
->data
;
268 buf
= luaL_checklstring(L
, 3, &len
);
269 d
->bg_align
= draw_align_fromstr(buf
, len
);
272 d
->bg_resize
= luaA_checkboolean(L
, 3);
275 luaA_object_unref_item(L
, 1, d
->bg_image
);
276 d
->bg_image
= luaA_object_ref_item(L
, 1, 3);
281 else if((buf
= luaL_checklstring(L
, 3, &len
)))
282 color_init_reply(color_init_unchecked(&d
->bg
, buf
, len
));
285 if((buf
= luaL_checklstring(L
, 3, &len
)))
286 d
->align
= draw_align_fromstr(buf
, len
);
288 case A_TK_BORDER_COLOR
:
289 if((buf
= luaL_checklstring(L
, 3, &len
)))
290 color_init_reply(color_init_unchecked(&d
->border
.color
, buf
, len
));
292 case A_TK_BORDER_WIDTH
:
293 d
->border
.width
= luaL_checknumber(L
, 3);
297 || (buf
= luaL_checklstring(L
, 3, &len
)))
300 draw_text_context_wipe(&d
->data
);
301 p_clear(&d
->data
, 1);
307 /* if text has been converted to UTF-8 */
308 if(draw_iso2utf8(buf
, len
, &text
, &tlen
))
310 draw_text_context_init(&d
->data
, text
, tlen
);
314 draw_text_context_init(&d
->data
, buf
, len
);
316 d
->extents
= draw_text_extents(&d
->data
);
319 p_clear(&d
->extents
, 1);
323 d
->width
= luaL_checknumber(L
, 3);
326 if((buf
= luaL_checklstring(L
, 3, &len
)))
327 switch(a_tokenize(buf
, len
))
330 d
->wrap
= PANGO_WRAP_WORD
;
333 d
->wrap
= PANGO_WRAP_CHAR
;
336 d
->wrap
= PANGO_WRAP_WORD_CHAR
;
343 if((buf
= luaL_checklstring(L
, 3, &len
)))
344 switch(a_tokenize(buf
, len
))
347 d
->ellip
= PANGO_ELLIPSIZE_START
;
350 d
->ellip
= PANGO_ELLIPSIZE_MIDDLE
;
353 d
->ellip
= PANGO_ELLIPSIZE_END
;
363 widget_invalidate_bywidget(widget
);
368 /** Create a new textbox widget.
369 * \param w The widget to initialize.
370 * \return A brand new widget.
373 widget_textbox(widget_t
*w
)
375 w
->draw
= textbox_draw
;
376 w
->index
= luaA_textbox_index
;
377 w
->newindex
= luaA_textbox_newindex
;
378 w
->destructor
= textbox_destructor
;
379 w
->geometry
= textbox_geometry
;
380 w
->extents
= textbox_extents
;
382 textbox_data_t
*d
= w
->data
= p_new(textbox_data_t
, 1);
383 d
->ellip
= PANGO_ELLIPSIZE_END
;
388 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80