image: check image width and height
[awesome.git] / widgets / textbox.c
blob43b4f1cc581991e1a134ca9386e92b7c0f7cafbb
1 /*
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.
22 #include "widget.h"
23 #include "common/tokenize.h"
25 extern awesome_t globalconf;
27 /** The textbox private data structure */
28 typedef struct
30 /** Textbox text */
31 char *text;
32 /** Textbox text length */
33 size_t len;
34 /** Textbox width */
35 int width;
36 /** Extents */
37 int extents;
38 PangoEllipsizeMode ellip;
39 PangoWrapMode wrap;
40 /** Draw parser data */
41 draw_parser_data_t pdata;
42 } textbox_data_t;
44 static area_t
45 textbox_geometry(widget_t *widget, int screen, int height, int width)
47 area_t geometry;
48 textbox_data_t *d = widget->data;
50 geometry.height = height;
52 if(d->width)
53 geometry.width = d->width;
54 else if(widget->align == AlignFlex)
55 geometry.width = width;
56 else
58 geometry.width = MIN(d->extents, width);
60 if(d->pdata.bg_image)
61 geometry.width = MAX(geometry.width,
62 d->pdata.bg_resize ? ((double) d->pdata.bg_image->width / (double) d->pdata.bg_image->height) * geometry.height : d->pdata.bg_image->width);
65 return geometry;
68 /** Draw a textbox widget.
69 * \param widget The widget.
70 * \param ctx The draw context.
71 * \param screen The screen.
72 * \param p A pointer to the object we're draw onto.
74 static void
75 textbox_draw(widget_t *widget, draw_context_t *ctx, area_t geometry,
76 int screen, wibox_t *p)
78 textbox_data_t *d = widget->data;
79 draw_text(ctx, globalconf.font, d->ellip, d->wrap, geometry, d->text, d->len, &d->pdata);
82 /** Delete a textbox widget.
83 * \param w The widget to destroy.
85 static void
86 textbox_destructor(widget_t *w)
88 textbox_data_t *d = w->data;
89 draw_parser_data_wipe(&d->pdata);
90 p_delete(&d->text);
91 p_delete(&d);
94 /** Textbox widget.
95 * \param L The Lua VM state.
96 * \param token The key token.
97 * \return The number of elements pushed on stack.
98 * \luastack
99 * \lfield text The text to display.
100 * \lfield width The width of the textbox. Set to 0 for auto.
101 * \lfield wrap The wrap mode: word, char, word_char.
102 * \lfield ellipsize The ellipsize mode: start, middle or end.
104 static int
105 luaA_textbox_index(lua_State *L, awesome_token_t token)
107 widget_t **widget = luaA_checkudata(L, 1, "widget");
108 textbox_data_t *d = (*widget)->data;
110 switch(token)
112 case A_TK_TEXT:
113 lua_pushstring(L, d->text);
114 return 1;
115 case A_TK_WIDTH:
116 lua_pushnumber(L, d->width);
117 return 1;
118 case A_TK_WRAP:
119 switch(d->wrap)
121 default:
122 lua_pushliteral(L, "word");
123 break;
124 case A_TK_CHAR:
125 lua_pushliteral(L, "char");
126 break;
127 case A_TK_WORD_CHAR:
128 lua_pushliteral(L, "word_char");
129 break;
131 return 1;
132 case A_TK_ELLIPSIZE:
133 switch(d->ellip)
135 case A_TK_START:
136 lua_pushliteral(L, "start");
137 break;
138 case A_TK_MIDDLE:
139 lua_pushliteral(L, "middle");
140 break;
141 default:
142 lua_pushliteral(L, "end");
143 break;
145 return 1;
146 default:
147 return 0;
151 /** The __newindex method for a textbox object.
152 * \param L The Lua VM state.
153 * \param token The key token.
154 * \return The number of elements pushed on stack.
156 static int
157 luaA_textbox_newindex(lua_State *L, awesome_token_t token)
159 size_t len = 0;
160 widget_t **widget = luaA_checkudata(L, 1, "widget");
161 const char *buf = NULL;
162 textbox_data_t *d = (*widget)->data;
164 switch(token)
166 case A_TK_TEXT:
167 if(lua_isnil(L, 3)
168 || (buf = luaL_checklstring(L, 3, &len)))
170 /* delete */
171 draw_parser_data_wipe(&d->pdata);
172 /* reinit since we are giving it as arg to draw_text unconditionally */
173 draw_parser_data_init(&d->pdata);
174 p_delete(&d->text);
176 /* re-init */
177 d->len = len;
178 if(buf)
180 a_iso2utf8(&d->text, buf, len);
181 d->extents = draw_text_extents(globalconf.font, d->text, d->len, &d->pdata).width;
183 else
184 d->extents = 0;
186 break;
187 case A_TK_WIDTH:
188 d->width = luaL_checknumber(L, 3);
189 break;
190 case A_TK_WRAP:
191 if((buf = luaL_checklstring(L, 3, &len)))
192 switch(a_tokenize(buf, len))
194 case A_TK_WORD:
195 d->wrap = PANGO_WRAP_WORD;
196 break;
197 case A_TK_CHAR:
198 d->wrap = PANGO_WRAP_CHAR;
199 break;
200 case A_TK_WORD_CHAR:
201 d->wrap = PANGO_WRAP_WORD_CHAR;
202 break;
203 default:
204 break;
206 break;
207 case A_TK_ELLIPSIZE:
208 if((buf = luaL_checklstring(L, 3, &len)))
209 switch(a_tokenize(buf, len))
211 case A_TK_START:
212 d->ellip = PANGO_ELLIPSIZE_START;
213 break;
214 case A_TK_MIDDLE:
215 d->ellip = PANGO_ELLIPSIZE_MIDDLE;
216 break;
217 case A_TK_END:
218 d->ellip = PANGO_ELLIPSIZE_END;
219 break;
220 default:
221 break;
223 break;
224 default:
225 return 0;
228 widget_invalidate_bywidget(*widget);
230 return 0;
233 /** Create a new textbox widget.
234 * \param align Widget alignment.
235 * \return A brand new widget.
237 widget_t *
238 textbox_new(alignment_t align)
240 widget_t *w;
241 textbox_data_t *d;
243 w = p_new(widget_t, 1);
244 widget_common_new(w);
245 w->align = align;
246 w->align_supported |= AlignFlex;
247 w->draw = textbox_draw;
248 w->index = luaA_textbox_index;
249 w->newindex = luaA_textbox_newindex;
250 w->destructor = textbox_destructor;
251 w->geometry = textbox_geometry;
252 w->data = d = p_new(textbox_data_t, 1);
253 d->ellip = PANGO_ELLIPSIZE_END;
255 return w;
258 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80