1 /*
2  * widgets/box.c - gtk hbox & vbox container widgets
3  *
4  * Copyright © 2010 Mason Larobina <mason.larobina@gmail.com>
5  *
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 3 of the License, or
9  * (at your option) any later version.
10  *
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.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include "luah.h"
22 #include "widgets/common.h"
23 
24 static gint
luaH_box_pack(lua_State * L)25 luaH_box_pack(lua_State *L)
26 {
27     widget_t *w = luaH_checkwidget(L, 1);
28     widget_t *child = luaH_checkwidget(L, 2);
29 
30     gint top = lua_gettop(L);
31     gboolean expand = FALSE, fill = FALSE, start = TRUE;
32     guint padding = 0;
33 
34     /* check for options table */
35     if (top > 2 && !lua_isnil(L, 3)) {
36         luaH_checktable(L, 3);
37 
38         /* pack child from start or end of container? */
39         if (luaH_rawfield(L, 3, "from"))
40             start = L_TK_END == l_tokenize(lua_tostring(L, -1)) ? FALSE : TRUE;
41 
42         /* expand? */
43         if (luaH_rawfield(L, 3, "expand"))
44             expand = lua_toboolean(L, -1) ? TRUE : FALSE;
45 
46         /* fill? */
47         if (luaH_rawfield(L, 3, "fill"))
48             fill = lua_toboolean(L, -1) ? TRUE : FALSE;
49 
50         /* padding? */
51         if (luaH_rawfield(L, 3, "padding"))
52             padding = (guint)lua_tonumber(L, -1);
53 
54         /* return stack to original state */
55         lua_settop(L, top);
56     }
57 
58     if (start)
59         gtk_box_pack_start(GTK_BOX(w->widget), GTK_WIDGET(child->widget),
60                 expand, fill, padding);
61     else
62         gtk_box_pack_end(GTK_BOX(w->widget), GTK_WIDGET(child->widget),
63                 expand, fill, padding);
64     return 0;
65 }
66 
67 /* direct wrapper around gtk_box_reorder_child */
68 static gint
luaH_box_reorder_child(lua_State * L)69 luaH_box_reorder_child(lua_State *L)
70 {
71     widget_t *w = luaH_checkwidget(L, 1);
72     widget_t *child = luaH_checkwidget(L, 2);
73     gint pos = luaL_checknumber(L, 3);
74     gtk_box_reorder_child(GTK_BOX(w->widget), GTK_WIDGET(child->widget), pos);
75     return 0;
76 }
77 
78 static gint
luaH_box_index(lua_State * L,widget_t * w,luakit_token_t token)79 luaH_box_index(lua_State *L, widget_t *w, luakit_token_t token)
80 {
81     switch(token) {
82       LUAKIT_WIDGET_INDEX_COMMON(w)
83       LUAKIT_WIDGET_CONTAINER_INDEX_COMMON(w)
84 
85       /* push class methods */
86       PF_CASE(PACK,         luaH_box_pack)
87       PF_CASE(REORDER,      luaH_box_reorder_child)
88       /* push boolean properties */
89       PB_CASE(HOMOGENEOUS,  gtk_box_get_homogeneous(GTK_BOX(w->widget)))
90       /* push string properties */
91       PN_CASE(SPACING,      gtk_box_get_spacing(GTK_BOX(w->widget)))
92 
93       PS_CASE(BG, g_object_get_data(G_OBJECT(w->widget), "bg"))
94 
95       default:
96         break;
97     }
98     return 0;
99 }
100 
101 static gint
luaH_box_newindex(lua_State * L,widget_t * w,luakit_token_t token)102 luaH_box_newindex(lua_State *L, widget_t *w, luakit_token_t token)
103 {
104     size_t len;
105     const gchar *tmp;
106     GdkRGBA c;
107 
108     switch(token) {
109       LUAKIT_WIDGET_NEWINDEX_COMMON(w)
110 
111       case L_TK_HOMOGENEOUS:
112         gtk_box_set_homogeneous(GTK_BOX(w->widget), luaH_checkboolean(L, 3));
113         break;
114 
115       case L_TK_SPACING:
116         gtk_box_set_spacing(GTK_BOX(w->widget), luaL_checknumber(L, 3));
117         break;
118 
119       case L_TK_BG:
120         tmp = luaL_checklstring(L, 3, &len);
121         if (!gdk_rgba_parse(&c, tmp))
122             luaL_argerror(L, 3, "unable to parse colour");
123 #if GTK_CHECK_VERSION(3,16,0)
124         widget_set_css_properties(w, "background-color", tmp, NULL);
125 #else
126         gtk_widget_override_background_color(GTK_WIDGET(w->widget), GTK_STATE_FLAG_NORMAL, &c);
127 #endif
128         g_object_set_data_full(G_OBJECT(w->widget), "bg", g_strdup(tmp), g_free);
129         break;
130 
131       default:
132         return 0;
133     }
134 
135     return luaH_object_property_signal(L, 1, token);
136 }
137 
138 widget_t *
widget_box(lua_State * UNUSED (L),widget_t * w,luakit_token_t token)139 widget_box(lua_State *UNUSED(L), widget_t *w, luakit_token_t token)
140 {
141     w->index = luaH_box_index;
142     w->newindex = luaH_box_newindex;
143 
144     w->widget = gtk_box_new((token == L_TK_VBOX) ?
145             GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL, 0);
146     gtk_box_set_homogeneous(GTK_BOX(w->widget), (token == L_TK_VBOX) ? FALSE : TRUE);
147 
148     g_object_connect(G_OBJECT(w->widget),
149       LUAKIT_WIDGET_SIGNAL_COMMON(w)
150       "signal::add",        G_CALLBACK(add_cb),        w,
151       NULL);
152     gtk_widget_show(w->widget);
153     return w;
154 }
155 
156 // vim: ft=c:et:sw=4:ts=8:sts=4:tw=80
157