aboutsummaryrefslogtreecommitdiff
path: root/src/lua_interface.c
diff options
context:
space:
mode:
authormitchell <70453897+667e-11@users.noreply.github.com>2007-09-23 14:09:16 -0400
committermitchell <70453897+667e-11@users.noreply.github.com>2007-09-23 14:09:16 -0400
commit80273cd17e8d0b39670c1618a98848a9540e071d (patch)
tree262a51080816d02ec21ab533c595ee3d070e19aa /src/lua_interface.c
parent8e30b52bf0da10e091e2d8b93fa362186cc625fe (diff)
downloadtextadept-80273cd17e8d0b39670c1618a98848a9540e071d.tar.gz
textadept-80273cd17e8d0b39670c1618a98848a9540e071d.zip
Added dynamically defined GTK menus and menubar.
Diffstat (limited to 'src/lua_interface.c')
-rw-r--r--src/lua_interface.c79
1 files changed, 63 insertions, 16 deletions
diff --git a/src/lua_interface.c b/src/lua_interface.c
index 6fbb50fa..2029a1a8 100644
--- a/src/lua_interface.c
+++ b/src/lua_interface.c
@@ -41,7 +41,8 @@ LF l_cf_ta_buffer_new(LS *lua),
l_cf_ta_goto_window(LS *lua),
l_cf_view_goto_buffer(LS *lua),
l_cf_pm_focus(LS *lua), l_cf_pm_clear(LS *lua), l_cf_pm_activate(LS *lua),
- l_cf_find_focus(LS *lua);
+ l_cf_find_focus(LS *lua),
+ l_cf_gtkmenu(LS *lua);
const char
*views_dne = "textadept.views doesn't exist or was overridden.",
@@ -73,6 +74,7 @@ void l_init(int argc, char **argv) {
l_cfunc(lua, l_cf_ta_goto_window, "goto_view");
l_cfunc(lua, l_cf_ta_get_split_table, "get_split_table");
l_cfunc(lua, l_cf_ta_focus_command, "focus_command");
+ l_cfunc(lua, l_cf_gtkmenu, "gtkmenu");
l_mt(lua, "_textadept_mt", l_ta_mt_index, l_ta_mt_newindex);
lua_setglobal(lua, "textadept");
lua_pushstring(lua, textadept_home); lua_setglobal(lua, "_HOME");
@@ -303,6 +305,33 @@ void l_close() {
lua_close(lua);
}
+GtkWidget* l_create_gtkmenu(LS *lua, GCallback callback, bool submenu=false) {
+ GtkWidget *menu = gtk_menu_new(), *menu_item = 0, *submenu_root = 0;
+ const char *label;
+ lua_getfield(lua, -1, "title");
+ if (!lua_isnil(lua, -1) || submenu) { // title required for submenu
+ label = !lua_isnil(lua, -1) ? lua_tostring(lua, -1) : "notitle";
+ submenu_root = gtk_menu_item_new_with_mnemonic(label);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(submenu_root), menu);
+ } lua_pop(lua, 1); // title
+ lua_pushnil(lua);
+ while (lua_next(lua, -2)) {
+ if (lua_type(lua, -2) == LUA_TNUMBER && lua_isstring(lua, -1)) {
+ label = lua_tostring(lua, -1);
+ if (g_str_has_prefix(label, "gtk-"))
+ menu_item = gtk_image_menu_item_new_from_stock(label, NULL);
+ else if (streq(label, "separator"))
+ menu_item = gtk_separator_menu_item_new();
+ else menu_item = gtk_menu_item_new_with_mnemonic(label);
+ g_signal_connect(menu_item, "activate", callback, 0);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ } else if (lua_istable(lua, -1))
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu),
+ l_create_gtkmenu(lua, callback, true));
+ lua_pop(lua, 1); // value
+ } return !submenu_root ? menu : submenu_root;
+}
+
// Notification/signal handlers
bool l_is_ta_table_function(const char *table, const char *function) {
@@ -342,6 +371,12 @@ bool l_handle_signal(const char *s) {
return l_is_ta_table_function("events", s) ? l_call_function(0, 1) : true;
}
+bool l_handle_signal(const char *s, const char *arg) {
+ if (!l_is_ta_table_function("events", s)) return false;
+ lua_pushstring(lua, arg);
+ return l_call_function(1, 1);
+}
+
bool l_handle_keypress(int keyval, GdkEventKey *event) {
if (!l_is_ta_table_function("events", "keypress")) return false;
lua_pushinteger(lua, keyval);
@@ -473,20 +508,8 @@ void l_pm_popup_context_menu(GdkEventButton *event, GCallback callback) {
return;
}
if (l_call_function(1, 1, true) && lua_istable(lua, -1)) {
- GtkWidget *menu = gtk_menu_new();
- lua_pushnil(lua);
- while (lua_next(lua, -2)) {
- GtkWidget *menu_item;
- const char *label = lua_tostring(lua, -1);
- if (g_str_has_prefix(label, "gtk-"))
- menu_item = gtk_image_menu_item_new_from_stock(label, NULL);
- else if (streq(label, "separator"))
- menu_item = gtk_separator_menu_item_new();
- else menu_item = gtk_menu_item_new_with_mnemonic(label);
- g_signal_connect(menu_item, "activate", callback, 0);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
- lua_pop(lua, 1); // value
- } lua_pop(lua, 1); // returned table
+ GtkWidget *menu = l_create_gtkmenu(lua, callback);
+ lua_pop(lua, 1); // returned table
gtk_widget_show_all(menu);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
event ? event->button : 0,
@@ -751,7 +774,18 @@ LF l_ta_mt_newindex(LS *lua) {
set_docstatusbar_text(lua_tostring(lua, 3));
else if (streq(key, "focused_doc_pointer") || streq(key, "clipboard_text"))
luaL_error(lua, "'%s' is read-only.", key);
- else lua_rawset(lua, 1);
+ else if (streq(key, "menubar")) {
+ const char *errmsg = "textadept.menubar must be a table of menus.";
+ if (!lua_istable(lua, 3)) luaL_error(lua, errmsg);
+ GtkWidget *menubar = gtk_menu_bar_new();
+ lua_pushnil(lua);
+ while (lua_next(lua, 3)) {
+ if (!lua_isuserdata(lua, -1)) luaL_error(lua, errmsg);
+ GtkWidget *menu_item = l_togtkwidget(lua, -1);
+ gtk_menu_bar_append(GTK_MENU_BAR(menubar), menu_item);
+ lua_pop(lua, 1); // value
+ } set_menubar(menubar);
+ } else lua_rawset(lua, 1);
return 0;
}
@@ -946,3 +980,16 @@ LF l_cf_pm_activate(LS *) {
}
LF l_cf_find_focus(LS *) { find_toggle_focus(); return 0; }
+
+static void t_menu_activate(GtkWidget *menu_item, gpointer) {
+ GtkWidget *label = gtk_bin_get_child(GTK_BIN(menu_item));
+ const char *text = gtk_label_get_text(GTK_LABEL(label));
+ l_handle_signal("menu_clicked", text);
+}
+
+LF l_cf_gtkmenu(LS *lua) {
+ luaL_checktype(lua, 1, LUA_TTABLE);
+ GtkWidget *menu = l_create_gtkmenu(lua, G_CALLBACK(t_menu_activate));
+ lua_pushlightuserdata(lua, const_cast<GtkWidget*>(menu));
+ return 1;
+}