aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/ui.lua12
-rw-r--r--modules/textadept/menu.lua38
-rw-r--r--src/textadept.c64
3 files changed, 82 insertions, 32 deletions
diff --git a/core/ui.lua b/core/ui.lua
index 4cbdab4d..a4ceeac2 100644
--- a/core/ui.lua
+++ b/core/ui.lua
@@ -10,7 +10,11 @@ local ui = ui
-- @field context_menu
-- The buffer's context menu, a [`ui.menu()`](#menu).
-- This is a low-level field. You probably want to use the higher-level
--- `textadept.menu.set_contextmenu()`.
+-- `textadept.menu.set_contextmenus()`.
+-- @field tab_context_menu
+-- The context menu for the buffer's tab, a [`ui.menu()`](#menu).
+-- This is a low-level field. You probably want to use the higher-level
+-- `textadept.menu.set_contextmenus()`.
-- @field clipboard_text (string)
-- The text on the clipboard.
-- @field statusbar_text (string, Write-only)
@@ -437,8 +441,8 @@ local goto_view
-- Low-level function for creating a menu from table *menu_table* and returning
-- the userdata.
-- You probably want to use the higher-level `textadept.menu.set_menubar()`
--- or `textadept.menu.set_contextmenu()` functions. Emits a `MENU_CLICKED` event
--- when a menu item is selected.
+-- or `textadept.menu.set_contextmenus()` functions. Emits a `MENU_CLICKED`
+-- event when a menu item is selected.
-- @param menu_table A table defining the menu. It is an ordered list of tables
-- with a string menu item, integer menu ID, and optional GDK keycode and
-- modifier mask. The latter two are used to display key shortcuts in the
@@ -449,7 +453,7 @@ local goto_view
-- @usage ui.menu{{'_New', 1, string.byte('n'), 4}} -- 'Ctrl+N'
-- @see events.MENU_CLICKED
-- @see textadept.menu.set_menubar
--- @see textadept.menu.set_contextmenu
+-- @see textadept.menu.set_contextmenus
-- @class function
-- @name menu
local menu
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index e064e4e0..12ee2d1e 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -213,6 +213,16 @@ local context_menu = {
{_L['Select _All'], buffer.select_all}
}
+-- The default tabbar context menu.
+local tab_context_menu = {
+ {_L['_Close'], io.close_buffer},
+ SEPARATOR,
+ {_L['_Save'], io.save_file},
+ {_L['Save _As'], io.save_file_as},
+ SEPARATOR,
+ {_L['Re_load'], io.reload_file},
+}
+
-- Returns the GDK integer keycode and modifier mask for a key sequence.
-- This is used for creating menu accelerators.
-- @param key_seq The string key sequence.
@@ -324,19 +334,34 @@ M.set_menubar(menubar)
---
-- Sets `ui.context_menu` from menu item list *menu*.
+-- Deprecated in favor of `set_contextmenus()`.
+-- @param menu The menu table to create the context menu from.
+-- @see set_contextmenus
+-- @name set_contextmenu
+function M.set_contextmenu(menu) M.set_contextmenus(menu) end
+
+---
+-- Sets `ui.context_menu` and `ui.tab_context_menu` from menu item lists
+-- *buffer_menu* and *tab_menu*, respectively.
-- Menu items are tables containing menu text and either a function to call or
-- a table containing a function with its parameters to call when an item is
-- clicked. Menu items may also be sub-menus, ordered lists of menu items with
-- an additional `title` key for the sub-menu's title text.
--- @param menu The menu table to create the context menu from.
+-- @param buffer_menu Optional menu table to create the buffer context menu
+-- from. If `nil`, uses the default context menu.
+-- @param tab_menu Optional menu table to create the tabbar context menu from.
+-- If `nil`, uses the default tab context menu.
-- @see ui.context_menu
+-- @see ui.tab_context_menu
-- @see ui.menu
--- @name set_contextmenu
-function M.set_contextmenu(menu)
+-- @name set_contextmenus
+function M.set_contextmenus(buffer_menu, tab_menu)
contextmenu_actions = {}
- ui.context_menu = ui.menu(read_menu_table(menu, true))
+ ui.context_menu = ui.menu(read_menu_table(buffer_menu or context_menu, true))
+ ui.tab_context_menu = ui.menu(read_menu_table(tab_menu or tab_context_menu,
+ true))
end
-if not CURSES then M.set_contextmenu(context_menu) end
+if not CURSES then M.set_contextmenus() end
---
-- Prompts the user to select a menu command to run.
@@ -364,7 +389,8 @@ if not CURSES then
-- Set a language-specific context menu or the default one.
local function set_language_contextmenu()
local lang = _G.buffer:get_lexer()
- M.set_contextmenu(_M[lang] and _M[lang].context_menu or context_menu)
+ M.set_contextmenus(_M[lang] and _M[lang].context_menu,
+ _M[lang] and _M[lang].tab_context_menu)
end
events.connect(events.LEXER_LOADED, set_language_contextmenu)
events.connect(events.BUFFER_AFTER_SWITCH, set_language_contextmenu)
diff --git a/src/textadept.c b/src/textadept.c
index 737d20c5..95d763fb 100644
--- a/src/textadept.c
+++ b/src/textadept.c
@@ -1839,12 +1839,51 @@ static void w_quit_osx(GtkosxApplication*_, void*__) {
* the specified buffer.
* Generates 'buffer_before_switch' and 'buffer_after_switch' events.
*/
-static void t_tabchange(GtkNotebook*_, void*__, int page_num, void*___) {
+static void t_tabchange(GtkNotebook*_, GtkWidget*__, int page_num, void*___) {
if (tab_sync) return;
lL_event(lua, "buffer_before_switch", -1);
lL_gotodoc(lua, focused_view, page_num + 1, FALSE);
lL_event(lua, "buffer_after_switch", -1);
}
+
+/**
+ * Shows the context menu for a widget based on a mouse event.
+ * @param L The Lua state.
+ * @param event An optional GTK mouse button event.
+ * @param field The ui table field that contains the context menu.
+ */
+static void lL_showcontextmenu(lua_State *L, void *event, char *field) {
+ lua_getglobal(L, "ui");
+ if (lua_istable(L, -1)) {
+ lua_getfield(L, -1, field);
+ if (lua_isuserdata(L, -1)) {
+ GtkWidget *menu = (GtkWidget *)lua_touserdata(L, -1);
+ gtk_widget_show_all(menu);
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
+ event ? ((GdkEventButton *)event)->button : 0,
+ gdk_event_get_time((GdkEvent *)event));
+ }
+ lua_pop(L, 1); // ui context menu field
+ } else lua_pop(L, 1); // non-table
+}
+
+/** Signal for a tabbar mouse click. */
+static int t_tabbuttonpress(GtkWidget*_, GdkEventButton *event, void*__) {
+ if (event->type != GDK_BUTTON_PRESS || event->button != 3) return FALSE;
+ GtkNotebook *tabs = GTK_NOTEBOOK(tabbar);
+ for (int i = 0; i < gtk_notebook_get_n_pages(tabs); i++) {
+ GtkWidget *page = gtk_notebook_get_nth_page(tabs, i);
+ GtkWidget *label = gtk_notebook_get_tab_label(tabs, page);
+ int x0, y0;
+ gdk_window_get_origin(gtk_widget_get_window(label), &x0, &y0);
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(label, &allocation);
+ if (event->x_root > x0 + allocation.x + allocation.width) continue;
+ gtk_notebook_set_current_page(tabs, i);
+ return (lL_showcontextmenu(lua, (void *)event, "tab_context_menu"), TRUE);
+ }
+ return FALSE;
+}
#endif // if GTK
/**
@@ -1900,30 +1939,10 @@ static int s_keypress(GtkWidget*_, GdkEventKey *event, void*__) {
event->state & GDK_META_MASK, -1);
}
-/**
- * Shows the context menu for a Scintilla view based on a mouse event.
- * @param L The Lua state.
- * @param event An optional GTK mouse button event.
- */
-static void lL_showcontextmenu(lua_State *L, void *event) {
- lua_getglobal(L, "ui");
- if (lua_istable(L, -1)) {
- lua_getfield(L, -1, "context_menu");
- if (lua_isuserdata(L, -1)) {
- GtkWidget *menu = (GtkWidget *)lua_touserdata(L, -1);
- gtk_widget_show_all(menu);
- gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
- event ? ((GdkEventButton *)event)->button : 0,
- gdk_event_get_time((GdkEvent *)event));
- }
- lua_pop(L, 1); // ui.context_menu
- } else lua_pop(L, 1); // non-table
-}
-
/** Signal for a Scintilla mouse click. */
static int s_buttonpress(GtkWidget*_, GdkEventButton *event, void*__) {
if (event->type == GDK_BUTTON_PRESS && event->button == 3)
- return (lL_showcontextmenu(lua, (void *)event), TRUE);
+ return (lL_showcontextmenu(lua, (void *)event, "context_menu"), TRUE);
return FALSE;
}
#endif
@@ -2272,6 +2291,7 @@ static void new_window() {
tabbar = gtk_notebook_new();
signal(tabbar, "switch-page", t_tabchange);
+ signal(tabbar, "button-press-event", t_tabbuttonpress);
gtk_notebook_set_scrollable(GTK_NOTEBOOK(tabbar), TRUE);
gtk_box_pack_start(GTK_BOX(vbox), tabbar, FALSE, FALSE, 0);
gtk_widget_set_can_focus(tabbar, FALSE);