1 /*
2    This file is part of darktable,
3    Copyright (C) 2015-2020 darktable developers.
4 
5    darktable is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9 
10    darktable is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with darktable.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 #include "bauhaus/bauhaus.h"
19 #include "gui/gtk.h"
20 #include "lua/types.h"
21 #include "lua/widget/common.h"
22 
23 static void combobox_init(lua_State *L);
24 static dt_lua_widget_type_t combobox_type = {
25   .name = "combobox",
26   .gui_init = combobox_init,
27   .gui_cleanup = NULL,
28   .alloc_size = sizeof(dt_lua_widget_t),
29   .parent= &widget_type
30 };
31 
32 
combobox_init(lua_State * L)33 static void combobox_init(lua_State*L)
34 {
35   lua_combobox combobox;
36   luaA_to(L,lua_combobox,&combobox,-1);
37   dt_bauhaus_combobox_from_widget(DT_BAUHAUS_WIDGET(combobox->widget),NULL);
38 
39 }
40 
combobox_len(lua_State * L)41 static int combobox_len(lua_State*L)
42 {
43   lua_combobox combobox;
44   luaA_to(L,lua_combobox,&combobox,1);
45   lua_pushinteger(L,dt_bauhaus_combobox_length(combobox->widget));
46   return 1;
47 }
48 
combobox_numindex(lua_State * L)49 static int combobox_numindex(lua_State*L)
50 {
51   lua_combobox combobox;
52   luaA_to(L,lua_combobox,&combobox,1);
53   int key = lua_tointeger(L,2);
54   int length = dt_bauhaus_combobox_length(combobox->widget);
55   if(lua_gettop(L) > 2) {
56     if(key <= 0 || key > length +1) {
57       return luaL_error(L,"Invalid index for combobox : %d\n",key);
58     } else if(key == length +1) {
59       const char * string = luaL_checkstring(L,3);
60       dt_bauhaus_combobox_add(combobox->widget,string);
61     } else if(lua_isnil(L,3)){
62       dt_bauhaus_combobox_remove_at(combobox->widget,key-1);
63     } else {
64       const char * string = luaL_checkstring(L,3);
65       dt_bauhaus_combobox_remove_at(combobox->widget,key-1);
66       dt_bauhaus_combobox_insert(combobox->widget,string,key-1);
67     }
68     return 0;
69   }
70   if(key <= 0 || key > length)
71   {
72     lua_pushnil(L);
73     return 1;
74   }
75   const GList *entries = dt_bauhaus_combobox_get_entries(combobox->widget);
76   dt_bauhaus_combobox_entry_t *entry = (dt_bauhaus_combobox_entry_t *)g_list_nth_data((GList *)entries, key - 1);
77   lua_pushstring(L, entry->label);
78   return 1;
79 }
80 
label_member(lua_State * L)81 static int label_member(lua_State *L)
82 {
83   lua_combobox combobox;
84   luaA_to(L,lua_combobox,&combobox,1);
85   if(lua_gettop(L) > 2) {
86     char tmp[256];
87     luaA_to(L,char_256,&tmp,3);
88     dt_bauhaus_widget_set_label(combobox->widget,NULL,tmp);
89     return 0;
90   }
91   lua_pushstring(L,dt_bauhaus_widget_get_label(combobox->widget));
92   return 1;
93 }
94 
editable_member(lua_State * L)95 static int editable_member(lua_State *L)
96 {
97   lua_combobox combobox;
98   luaA_to(L,lua_combobox,&combobox,1);
99   if(lua_gettop(L) > 2) {
100     gboolean editable = lua_toboolean(L,3);
101     dt_bauhaus_combobox_set_editable(combobox->widget,editable);
102     return 0;
103   }
104   lua_pushboolean(L,dt_bauhaus_combobox_get_editable(combobox->widget));
105   return 1;
106 }
107 
value_member(lua_State * L)108 static int value_member(lua_State*L)
109 {
110   lua_combobox combobox;
111   luaA_to(L,lua_combobox,&combobox,1);
112   int length = dt_bauhaus_combobox_length(combobox->widget);
113   if(lua_gettop(L) > 2) {
114     if(lua_isnil(L,3)) {
115       dt_bauhaus_combobox_set(combobox->widget,-1);
116     } else if(lua_isnumber(L,3)) {
117       int index = lua_tointeger(L,3) ;
118       if(index < 1 || index > length) {
119         return luaL_error(L,"Invalid index for combo box : %d\n",index);
120       }
121       dt_bauhaus_combobox_set(combobox->widget,index -1);
122     } else if(lua_isstring(L,3)&& dt_bauhaus_combobox_get_editable(combobox->widget)) {
123       const char * string = lua_tostring(L,3);
124       dt_bauhaus_combobox_set_text(combobox->widget,string);
125     } else {
126       return luaL_error(L,"Invalid type for combo box value\n");
127     }
128     return 0;
129   }
130   lua_pushstring(L,dt_bauhaus_combobox_get_text(combobox->widget));
131   return 1;
132 }
133 
selected_member(lua_State * L)134 static int selected_member(lua_State*L)
135 {
136   lua_combobox combobox;
137   luaA_to(L,lua_combobox,&combobox,1);
138   int length = dt_bauhaus_combobox_length(combobox->widget);
139   if(lua_gettop(L) > 2) {
140     if(lua_isnil(L,3)) {
141       dt_bauhaus_combobox_set(combobox->widget,-1);
142     } else if(lua_isnumber(L,3)) {
143       int index = lua_tointeger(L,3) ;
144       if(index < 0 || index > length) {
145         return luaL_error(L,"Invalid index for combo box : %d\n",index);
146       }
147       dt_bauhaus_combobox_set(combobox->widget,index -1);
148     } else {
149       return luaL_error(L,"Invalid type for combo box selected\n");
150     }
151     return 0;
152   }
153   lua_pushinteger(L,dt_bauhaus_combobox_get(combobox->widget) + 1);
154   return 1;
155 }
156 
changed_callback(GtkButton * widget,gpointer user_data)157 static void changed_callback(GtkButton *widget, gpointer user_data)
158 {
159   dt_lua_async_call_alien(dt_lua_widget_trigger_callback,
160       0,NULL,NULL,
161       LUA_ASYNC_TYPENAME,"lua_widget",user_data,
162       LUA_ASYNC_TYPENAME,"const char*","value-changed",
163       LUA_ASYNC_DONE);
164 }
165 
tostring_member(lua_State * L)166 static int tostring_member(lua_State *L)
167 {
168   lua_combobox widget;
169   luaA_to(L, lua_combobox, &widget, 1);
170   const gchar *text = dt_bauhaus_widget_get_label(widget->widget);
171   gchar *res = g_strdup_printf("%s (\"%s\")", G_OBJECT_TYPE_NAME(widget->widget), text ? text : "");
172   lua_pushstring(L, res);
173   g_free(res);
174   return 1;
175 }
176 
dt_lua_init_widget_combobox(lua_State * L)177 int dt_lua_init_widget_combobox(lua_State* L)
178 {
179   dt_lua_init_widget_type(L,&combobox_type,lua_combobox,DT_BAUHAUS_WIDGET_TYPE);
180 
181   lua_pushcfunction(L, tostring_member);
182   dt_lua_gtk_wrap(L);
183   dt_lua_type_setmetafield(L, lua_combobox, "__tostring");
184   lua_pushcfunction(L,combobox_len);
185   dt_lua_gtk_wrap(L);
186   lua_pushcfunction(L,combobox_numindex);
187   dt_lua_gtk_wrap(L);
188   dt_lua_type_register_number(L,lua_combobox);
189   lua_pushcfunction(L,value_member);
190   dt_lua_gtk_wrap(L);
191   dt_lua_type_register(L, lua_combobox, "value");
192   lua_pushcfunction(L,selected_member);
193   dt_lua_gtk_wrap(L);
194   dt_lua_type_register(L, lua_combobox, "selected");
195   dt_lua_widget_register_gtk_callback(L,lua_combobox,"value-changed","changed_callback",G_CALLBACK(changed_callback));
196   lua_pushcfunction(L,label_member);
197   dt_lua_gtk_wrap(L);
198   dt_lua_type_register(L, lua_combobox, "label");
199 
200   lua_pushcfunction(L,editable_member);
201   dt_lua_gtk_wrap(L);
202   dt_lua_type_register(L, lua_combobox, "editable");
203 
204   return 0;
205 }
206 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
207 // vim: shiftwidth=2 expandtab tabstop=2 cindent
208 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
209