1 /* Monolith select layout class.
2 * - by Richard W.M. Jones <rich@annexia.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 * $Id: ml_select_layout.c,v 1.3 2002/12/02 10:27:18 rich Exp $
32 #include <pthr_iolib.h>
34 #include "ml_widget.h"
36 #include "ml_smarttext.h"
37 #include "ml_select_layout.h"
39 static void repaint (void *, ml_session, const char *, io_handle);
40 static struct ml_widget_property properties[];
42 struct ml_widget_operations select_layout_ops =
45 properties: properties,
48 struct ml_select_layout
50 struct ml_widget_operations *ops;
51 pool pool; /* Pool for allocations. */
52 ml_session session; /* Current session. */
53 vector tabs; /* Vector of tabs. */
54 int selected; /* Index of selected tab. */
55 const char *clazz; /* Class of top-level table. */
56 ml_widget top; /* "Top" widget (see manpage). */
57 ml_widget bottom; /* "Bottom" widget (see manpage). */
62 const char *name; /* Name of the tab. */
63 ml_widget w; /* Widget. */
65 /* Do not set this directly. Use make_action and del_action functions. */
66 const char *action_id;
69 static struct ml_widget_property properties[] =
72 offset: ml_offsetof (struct ml_select_layout, clazz),
73 type: ML_PROP_STRING },
74 { name: "select_layout.top",
75 offset: ml_offsetof (struct ml_select_layout, top),
76 type: ML_PROP_WIDGET },
77 { name: "select_layout.bottom",
78 offset: ml_offsetof (struct ml_select_layout, bottom),
79 type: ML_PROP_WIDGET },
84 new_ml_select_layout (pool pool, ml_session session)
86 ml_select_layout w = pmalloc (pool, sizeof *w);
88 w->ops = &select_layout_ops;
91 w->tabs = new_vector (pool, struct tab);
94 w->top = w->bottom = 0;
99 static void make_action (ml_select_layout w, struct tab *tab);
100 static void del_action (ml_select_layout w, struct tab *tab);
103 ml_select_layout_push_back (ml_select_layout w, const char *name, ml_widget _w)
109 make_action (w, &tab);
110 vector_push_back (w->tabs, tab);
114 ml_select_layout_pop_back (ml_select_layout w)
118 vector_pop_back (w->tabs, tab);
119 del_action (w, &tab);
124 ml_select_layout_push_front (ml_select_layout w,
125 const char *name, ml_widget _w)
131 make_action (w, &tab);
132 vector_push_front (w->tabs, tab);
136 ml_select_layout_pop_front (ml_select_layout w)
140 vector_pop_front (w->tabs, tab);
141 del_action (w, &tab);
146 ml_select_layout_get (ml_select_layout w, int i)
150 vector_get (w->tabs, i, tab);
155 ml_select_layout_insert (ml_select_layout w, int i,
156 const char *name, ml_widget _w)
162 make_action (w, &tab);
163 vector_insert (w->tabs, i, tab);
167 ml_select_layout_replace (ml_select_layout w, int i,
168 const char *name, ml_widget _w)
172 vector_get (w->tabs, i, tab);
173 del_action (w, &tab);
177 make_action (w, &tab);
178 vector_replace (w->tabs, i, tab);
182 ml_select_layout_erase (ml_select_layout w, int i)
186 vector_get (w->tabs, i, tab);
187 del_action (w, &tab);
189 vector_erase (w->tabs, i);
193 ml_select_layout_clear (ml_select_layout w)
197 for (i = 0; i < vector_size (w->tabs); ++i)
201 vector_get (w->tabs, i, tab);
202 del_action (w, &tab);
205 vector_clear (w->tabs);
209 ml_select_layout_size (ml_select_layout w)
211 return vector_size (w->tabs);
215 ml_select_layout_pack (ml_select_layout w, const char *name, ml_widget _w)
217 ml_select_layout_push_back (w, name, _w);
221 ml_select_layout_set_selection (ml_select_layout w, int i)
227 ml_select_layout_get_selection (ml_select_layout w)
233 repaint (void *vw, ml_session session, const char *windowid, io_handle io)
235 ml_select_layout w = (ml_select_layout) vw;
238 const char *clazz = w->clazz ? : "ml_select_layout";
240 /* Verify the selection is in range. If not, bring it into range. */
241 if (w->selected < 0) w->selected = 0;
242 else if (w->selected >= vector_size (w->tabs))
243 w->selected = vector_size (w->tabs) - 1;
245 /* Begin the table. */
246 io_fprintf (io, "<table class=\"%s\"><tr><td valign=\"top\">", clazz);
248 /* Left hand column. */
249 if (w->top) ml_widget_repaint (w->top, session, windowid, io);
251 io_fputs ("<table class=\"ml_select_layout_left\">", io);
253 for (i = 0; i < vector_size (w->tabs); ++i)
255 vector_get_ptr (w->tabs, i, tab);
257 io_fputs ("<tr>", io);
258 if (i == w->selected) io_fputs ("<th>", io);
259 else io_fputs ("<td>", io);
261 io_fprintf (io, "<a href=\"%s?ml_action=%s&ml_window=%s\">",
262 ml_session_script_name (w->session),
263 tab->action_id, windowid);
264 ml_plaintext_print (io, tab->name);
265 io_fputs ("</a>", io);
267 if (i == w->selected) io_fputs ("</th>", io);
268 else io_fputs ("</td>", io);
269 io_fputs ("</tr>\n", io);
272 io_fputs ("</table>", io);
274 if (w->bottom) ml_widget_repaint (w->bottom, session, windowid, io);
276 io_fputs ("</td>\n<td valign=\"top\">", io);
278 /* Right hand column: the widget. */
279 vector_get_ptr (w->tabs, w->selected, tab);
281 if (tab->w) ml_widget_repaint (tab->w, session, windowid, io);
283 io_fputs ("</td></tr></table>", io);
286 static void do_select (ml_session session, void *vargs);
290 ml_select_layout w; /* The widget. */
291 const char *action_id; /* The action ID. */
295 make_action (ml_select_layout w, struct tab *tab)
297 struct select_args *args = pmalloc (w->pool, sizeof *args);
300 args->action_id = tab->action_id =
301 ml_register_action (w->session, do_select, args);
305 del_action (ml_select_layout w, struct tab *tab)
307 ml_unregister_action (w->session, tab->action_id);
310 /* This function is called when the user clicks on one of the items on the
313 * Because items can move around, we didn't store the absolute item number
314 * in the struct select_args. Instead, we stored the action_id, which we'll
315 * use to search through the current tabs to find out which tab the
316 * user was trying to click.
319 do_select (ml_session session, void *vargs)
321 struct select_args *args = (struct select_args *) vargs;
322 const char *action_id = args->action_id;
323 ml_select_layout w = args->w;
327 for (i = 0; i < vector_size (w->tabs); ++i)
329 vector_get_ptr (w->tabs, i, tab);
331 if (strcmp (tab->action_id, action_id) == 0)
339 /* Don't worry if we don't find it. Perhaps the underlying code has
340 * deleted this item, but the browser window was not updated.