1 /*
2  * Copyright © 2016 Aidan Holm <aidanholm@gmail.com>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program 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
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #include "luah.h"
20 #include "widgets/common.h"
21 
22 static gint
gtk_policy_from_string(const gchar * str,GtkPolicyType * out)23 gtk_policy_from_string(const gchar *str, GtkPolicyType *out)
24 {
25     if (!strcmp(str, "always"))
26         *out = GTK_POLICY_ALWAYS;
27     else if (!strcmp(str, "auto"))
28         *out = GTK_POLICY_AUTOMATIC;
29     else if (!strcmp(str, "never"))
30         *out = GTK_POLICY_NEVER;
31 #if GTK_CHECK_VERSION(3,16,0)
32     else if (!strcmp(str, "external"))
33         *out = GTK_POLICY_EXTERNAL;
34 #endif
35     else
36         return 1;
37     return 0;
38 }
39 
40 static const gchar *
string_from_gtk_policy(GtkPolicyType policy)41 string_from_gtk_policy(GtkPolicyType policy)
42 {
43     switch (policy) {
44         case GTK_POLICY_ALWAYS:    return "always";
45         case GTK_POLICY_AUTOMATIC: return "auto";
46         case GTK_POLICY_NEVER:     return "never";
47 #if GTK_CHECK_VERSION(3,16,0)
48         case GTK_POLICY_EXTERNAL:  return "external";
49 #endif
50         default: return NULL;
51     }
52 }
53 
54 gint
luaH_widget_get_scrollbars(lua_State * L,widget_t * w)55 luaH_widget_get_scrollbars(lua_State *L, widget_t *w)
56 {
57     GtkPolicyType horz, vert;
58     gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(w->widget), &horz, &vert);
59 
60     lua_newtable(L);
61 
62     lua_pushliteral(L, "h");
63     lua_pushstring(L, string_from_gtk_policy(horz));
64     lua_rawset(L, -3);
65 
66     lua_pushliteral(L, "v");
67     lua_pushstring(L, string_from_gtk_policy(vert));
68     lua_rawset(L, -3);
69 
70     return 1;
71 }
72 
73 gint
luaH_widget_set_scrollbars(lua_State * L,widget_t * w)74 luaH_widget_set_scrollbars(lua_State *L, widget_t *w)
75 {
76     luaH_checktable(L, 3);
77 
78     GtkPolicyType horz, vert;
79     gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(w->widget), &horz, &vert);
80 
81     gint top = lua_gettop(L);
82     if (luaH_rawfield(L, 3, "h")) {
83         if (gtk_policy_from_string(lua_tostring(L, -1), &horz))
84             luaL_error(L, "Bad horizontal scrollbar policy");
85     }
86     if (luaH_rawfield(L, 3, "v")) {
87         if (gtk_policy_from_string(lua_tostring(L, -1), &vert))
88             luaL_error(L, "Bad vertical scrollbar policy");
89     }
90     lua_settop(L, top);
91 
92     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w->widget), horz, vert);
93     return 1;
94 }
95 
96 gint
luaH_scrolled_get_scroll(lua_State * L,widget_t * w)97 luaH_scrolled_get_scroll(lua_State *L, widget_t *w)
98 {
99     GtkAdjustment *horz = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(w->widget));
100     GtkAdjustment *vert = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(w->widget));
101 
102     lua_newtable(L);
103 
104     lua_pushliteral(L, "x");
105     lua_pushnumber(L, gtk_adjustment_get_value(horz));
106     lua_rawset(L, -3);
107 
108     lua_pushliteral(L, "y");
109     lua_pushnumber(L, gtk_adjustment_get_value(vert));
110     lua_rawset(L, -3);
111 
112     lua_pushliteral(L, "xmax");
113     lua_pushnumber(L, gtk_adjustment_get_upper(horz));
114     lua_rawset(L, -3);
115 
116     lua_pushliteral(L, "ymax");
117     lua_pushnumber(L, gtk_adjustment_get_upper(vert));
118     lua_rawset(L, -3);
119 
120     return 1;
121 }
122 
123 gint
luaH_scrolled_set_scroll(lua_State * L,widget_t * w)124 luaH_scrolled_set_scroll(lua_State *L, widget_t *w)
125 {
126     luaH_checktable(L, 3);
127 
128     GtkAdjustment *horz = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(w->widget));
129     GtkAdjustment *vert = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(w->widget));
130 
131     gint top = lua_gettop(L);
132     if (luaH_rawfield(L, 3, "x"))
133         gtk_adjustment_set_value(horz, lua_tonumber(L, -1));
134     if (luaH_rawfield(L, 3, "y"))
135         gtk_adjustment_set_value(vert, lua_tonumber(L, -1));
136     lua_settop(L, top);
137 
138     return 0;
139 }
140 
141 static gint
luaH_scrolled_index(lua_State * L,widget_t * w,luakit_token_t token)142 luaH_scrolled_index(lua_State *L, widget_t *w, luakit_token_t token)
143 {
144     switch(token) {
145       LUAKIT_WIDGET_INDEX_COMMON(w)
146       LUAKIT_WIDGET_BIN_INDEX_COMMON(w)
147       LUAKIT_WIDGET_CONTAINER_INDEX_COMMON(w)
148 
149       case L_TK_SCROLLBARS:
150         return luaH_widget_get_scrollbars(L, w);
151 
152       case L_TK_SCROLL:
153         return luaH_scrolled_get_scroll(L, w);
154 
155       default:
156         break;
157     }
158     return 0;
159 }
160 
161 static gint
luaH_scrolled_newindex(lua_State * L,widget_t * w,luakit_token_t token)162 luaH_scrolled_newindex(lua_State *L, widget_t *w, luakit_token_t token)
163 {
164     switch(token) {
165       LUAKIT_WIDGET_NEWINDEX_COMMON(w)
166       LUAKIT_WIDGET_BIN_NEWINDEX_COMMON(w)
167 
168       case L_TK_SCROLLBARS:
169         luaH_widget_set_scrollbars(L, w);
170         break;
171 
172       case L_TK_SCROLL:
173         luaH_scrolled_set_scroll(L, w);
174         break;
175 
176       default:
177         break;
178     }
179 
180     return luaH_object_property_signal(L, 1, token);
181 }
182 
183 widget_t *
widget_scrolled(lua_State * UNUSED (L),widget_t * w,luakit_token_t UNUSED (token))184 widget_scrolled(lua_State *UNUSED(L), widget_t *w, luakit_token_t UNUSED(token))
185 {
186     w->index = luaH_scrolled_index;
187     w->newindex = luaH_scrolled_newindex;
188 
189 #if GTK_CHECK_VERSION(3,2,0)
190     w->widget = gtk_scrolled_window_new(NULL, NULL);
191 #endif
192 
193     g_object_connect(G_OBJECT(w->widget),
194         LUAKIT_WIDGET_SIGNAL_COMMON(w)
195         NULL);
196 
197     gtk_widget_show(w->widget);
198     return w;
199 }
200 
201 // vim: ft=c:et:sw=4:ts=8:sts=4:tw=80
202