Set destructor = NULL in destroy func to prevent it being called twice
[luakit.git] / widgets / notebook.c
blob5972d2c778aeec1aaae021cfbf70a22788c4d6e9
1 /*
2 * widgets/notebook.c - gtk notebook widget
4 * Copyright (C) 2010 Mason Larobina <mason.larobina@gmail.com>
5 * Copyright (C) 2007-2009 Julien Danjou <julien@danjou.info>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* TODO
23 * - In the notebook destructor function detach all child widgets
24 * - Add `get_children()` method which returns a table of the child widgets
27 #include "luah.h"
28 #include "widgets/common.h"
30 static gint
31 luaH_notebook_current(lua_State *L)
33 widget_t *w = luaH_checkudata(L, 1, &widget_class);
34 gint n = gtk_notebook_get_n_pages(GTK_NOTEBOOK(w->widget));
35 if (n == 1)
36 lua_pushnumber(L, 1);
37 else
38 lua_pushnumber(L, gtk_notebook_get_current_page(
39 GTK_NOTEBOOK(w->widget)) + 1);
40 return 1;
43 static gint
44 luaH_notebook_atindex(lua_State *L)
46 widget_t *w = luaH_checkudata(L, 1, &widget_class);
47 gint i = luaL_checknumber(L, 2);
48 /* correct index */
49 if (i != -1) i--;
51 GtkWidget *widget = gtk_notebook_get_nth_page(GTK_NOTEBOOK(w->widget), i);
52 if (!widget)
53 return 0;
55 widget_t *child = g_object_get_data(G_OBJECT(widget), "widget");
56 luaH_object_push(L, child->ref);
57 return 1;
60 static gint
61 luaH_notebook_indexof(lua_State *L)
63 widget_t *w = luaH_checkudata(L, 1, &widget_class);
64 widget_t *child = luaH_checkudata(L, 2, &widget_class);
66 gint i = gtk_notebook_page_num(GTK_NOTEBOOK(w->widget), child->widget);
68 /* return index or nil */
69 if (!++i) return 0;
70 lua_pushnumber(L, i);
71 return 1;
74 static gint
75 luaH_notebook_remove(lua_State *L)
77 widget_t *w = luaH_checkudata(L, 1, &widget_class);
78 widget_t *child = luaH_checkudata(L, 2, &widget_class);
79 gint i = gtk_notebook_page_num(GTK_NOTEBOOK(w->widget), child->widget);
81 if (i != -1)
82 return 0;
84 GtkWidget *widget = gtk_notebook_get_nth_page(GTK_NOTEBOOK(w->widget), i);
85 g_object_ref(G_OBJECT(widget));
86 gtk_notebook_remove_page(GTK_NOTEBOOK(w->widget), i);
87 return 0;
90 /* Inserts a widget into the notebook widget at an index */
91 static gint
92 luaH_notebook_insert(lua_State *L)
94 widget_t *w = luaH_checkudata(L, 1, &widget_class);
95 widget_t *child = luaH_checkudata(L, 3, &widget_class);
96 gint i = luaL_checknumber(L, 2);
97 /* correct index */
98 if (i != -1) i--;
100 i = gtk_notebook_insert_page(GTK_NOTEBOOK(w->widget),
101 child->widget, NULL, i);
103 /* return new index or nil */
104 if (!++i) return 0;
105 lua_pushnumber(L, i);
106 return 1;
109 /* Appends a widget to the notebook widget */
110 static gint
111 luaH_notebook_append(lua_State *L)
113 widget_t *w = luaH_checkudata(L, 1, &widget_class);
114 widget_t *child = luaH_checkudata(L, 2, &widget_class);
115 gint i = gtk_notebook_append_page(GTK_NOTEBOOK(w->widget),
116 child->widget, NULL);
118 /* return new index or nil */
119 if (!++i) return 0;
120 lua_pushnumber(L, i);
121 return 1;
124 /* Return the number of widgets in the notebook */
125 static gint
126 luaH_notebook_count(lua_State *L)
128 widget_t *w = luaH_checkudata(L, 1, &widget_class);
129 lua_pushnumber(L, gtk_notebook_get_n_pages(GTK_NOTEBOOK(w->widget)));
130 return 1;
133 static gint
134 luaH_notebook_set_title(lua_State *L)
136 size_t len;
137 widget_t *w = luaH_checkudata(L, 1, &widget_class);
138 widget_t *child = luaH_checkudata(L, 2, &widget_class);
139 const gchar *title = luaL_checklstring(L, 3, &len);
140 gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(w->widget),
141 child->widget, title);
142 return 0;
145 static gint
146 luaH_notebook_get_title(lua_State *L)
148 widget_t *w = luaH_checkudata(L, 1, &widget_class);
149 widget_t *child = luaH_checkudata(L, 2, &widget_class);
150 lua_pushstring(L, gtk_notebook_get_tab_label_text(
151 GTK_NOTEBOOK(w->widget), child->widget));
152 return 1;
155 static gint
156 luaH_notebook_switch(lua_State *L)
158 widget_t *w = luaH_checkudata(L, 1, &widget_class);
159 gint i = luaL_checknumber(L, 2);
160 /* correct index */
161 if (i != -1) i--;
162 gtk_notebook_set_current_page(GTK_NOTEBOOK(w->widget), i);
163 lua_pushnumber(L, gtk_notebook_get_current_page(GTK_NOTEBOOK(w->widget)));
164 return 1;
167 static gint
168 luaH_notebook_index(lua_State *L, luakit_token_t token)
170 widget_t *w = luaH_checkudata(L, 1, &widget_class);
172 switch(token)
174 LUAKIT_WIDGET_INDEX_COMMON
176 /* push class methods */
177 PF_CASE(APPEND, luaH_notebook_append)
178 PF_CASE(ATINDEX, luaH_notebook_atindex)
179 PF_CASE(COUNT, luaH_notebook_count)
180 PF_CASE(CURRENT, luaH_notebook_current)
181 PF_CASE(GET_TITLE, luaH_notebook_get_title)
182 PF_CASE(INDEXOF, luaH_notebook_indexof)
183 PF_CASE(INSERT, luaH_notebook_insert)
184 PF_CASE(REMOVE, luaH_notebook_remove)
185 PF_CASE(SET_TITLE, luaH_notebook_set_title)
186 PF_CASE(SWITCH, luaH_notebook_switch)
187 /* push boolean properties */
188 PB_CASE(SHOW_TABS, gtk_notebook_get_show_tabs(GTK_NOTEBOOK(w->widget)))
189 PB_CASE(SHOW_BORDER, gtk_notebook_get_show_border(GTK_NOTEBOOK(w->widget)))
191 default:
192 break;
194 return 0;
197 static gint
198 luaH_notebook_newindex(lua_State *L, luakit_token_t token)
200 widget_t *w = luaH_checkudata(L, 1, &widget_class);
202 switch(token)
204 case L_TK_SHOW_TABS:
205 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(w->widget), luaH_checkboolean(L, 3));
206 break;
208 case L_TK_SHOW_BORDER:
209 gtk_notebook_set_show_border(GTK_NOTEBOOK(w->widget), luaH_checkboolean(L, 3));
210 break;
212 default:
213 return 0;
216 return luaH_object_emit_property_signal(L, 1);
219 static void
220 page_added_cb(GtkNotebook *n, GtkWidget *widget, guint i, widget_t *w)
222 (void) n;
224 widget_t *child = g_object_get_data(G_OBJECT(widget), "widget");
225 lua_State *L = globalconf.L;
226 luaH_object_push(L, w->ref);
227 luaH_object_push(L, child->ref);
228 lua_pushnumber(L, i + 1);
229 luaH_object_emit_signal(L, -3, "page-added", 2, 0);
230 lua_pop(L, 1);
233 static void
234 page_removed_cb(GtkNotebook *n, GtkWidget *widget, guint i, widget_t *w)
236 (void) i;
237 (void) n;
239 widget_t *child = g_object_get_data(G_OBJECT(widget), "widget");
240 lua_State *L = globalconf.L;
241 luaH_object_push(L, w->ref);
242 luaH_object_push(L, child->ref);
243 luaH_object_emit_signal(L, -2, "page-removed", 1, 0);
244 lua_pop(L, 1);
247 static void
248 switch_cb(GtkNotebook *n, GtkNotebookPage *p, guint i, widget_t *w)
250 (void) p;
251 GtkWidget *widget = gtk_notebook_get_nth_page(GTK_NOTEBOOK(n), i);
252 widget_t *child = g_object_get_data(G_OBJECT(widget), "widget");
254 lua_State *L = globalconf.L;
255 luaH_object_push(L, w->ref);
256 luaH_object_push(L, child->ref);
257 lua_pushnumber(L, i + 1);
258 luaH_object_emit_signal(L, -3, "switch-page", 2, 0);
259 lua_pop(L, 1);
262 widget_t *
263 widget_notebook(widget_t *w)
265 w->index = luaH_notebook_index;
266 w->newindex = luaH_notebook_newindex;
267 w->destructor = widget_destructor;
269 /* create and setup notebook widget */
270 w->widget = gtk_notebook_new();
271 g_object_set_data(G_OBJECT(w->widget), "widget", (gpointer) w);
272 gtk_notebook_set_show_border(GTK_NOTEBOOK(w->widget), FALSE);
273 gtk_notebook_set_scrollable(GTK_NOTEBOOK(w->widget), TRUE);
275 g_object_connect((GObject*)w->widget,
276 "signal::focus-in-event", (GCallback)focus_cb, w,
277 "signal::focus-out-event", (GCallback)focus_cb, w,
278 "signal::key-press-event", (GCallback)key_press_cb, w,
279 "signal::page-added", (GCallback)page_added_cb, w,
280 "signal::page-removed", (GCallback)page_removed_cb, w,
281 "signal::switch-page", (GCallback)switch_cb, w,
282 "signal::parent-set", (GCallback)parent_set_cb, w,
283 NULL);
285 gtk_widget_show(w->widget);
286 return w;
289 // vim: ft=c:et:sw=4:ts=8:sts=4:tw=80