Merge branch 'kill-tree-menu' into 'master'

Menu removal, part 2

See merge request GNOME/gtk!1270
This commit is contained in:
Matthias Clasen 2019-12-30 01:46:29 +00:00
commit e12a580b0b
138 changed files with 1902 additions and 23475 deletions

View File

@ -419,7 +419,7 @@ demo_application_window_load_state (DemoApplicationWindow *win)
static void
demo_application_window_init (DemoApplicationWindow *window)
{
GtkWidget *menu;
GtkWidget *popover;
window->width = -1;
window->height = -1;
@ -428,8 +428,8 @@ demo_application_window_init (DemoApplicationWindow *window)
gtk_widget_init_template (GTK_WIDGET (window));
menu = gtk_menu_new_from_model (window->toolmenu);
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (window->menutool), menu);
popover = gtk_popover_menu_new_from_model (window->menutool, window->toolmenu);
gtk_menu_tool_button_set_popover (GTK_MENU_TOOL_BUTTON (window->menutool), popover);
g_action_map_add_action_entries (G_ACTION_MAP (window),
win_entries, G_N_ELEMENTS (win_entries),

View File

@ -38,7 +38,22 @@ help_activate (GSimpleAction *action,
g_print ("Help not available\n");
}
static void
not_implemented (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_print ("Action “%s” not implemented\n", g_action_get_name (G_ACTION (action)));
}
static GActionEntry win_entries[] = {
{ "new", not_implemented, NULL, NULL, NULL },
{ "open", not_implemented, NULL, NULL, NULL },
{ "save", not_implemented, NULL, NULL, NULL },
{ "save-as", not_implemented, NULL, NULL, NULL },
{ "copy", not_implemented, NULL, NULL, NULL },
{ "cut", not_implemented, NULL, NULL, NULL },
{ "paste", not_implemented, NULL, NULL, NULL },
{ "quit", quit_activate, NULL, NULL, NULL },
{ "about", about_activate, NULL, NULL, NULL },
{ "help", help_activate, NULL, NULL, NULL }
@ -50,8 +65,6 @@ do_builder (GtkWidget *do_widget)
static GtkWidget *window = NULL;
GtkWidget *toolbar;
GActionGroup *actions;
GtkAccelGroup *accel_group;
GtkWidget *item;
if (!window)
{
@ -72,44 +85,6 @@ do_builder (GtkWidget *do_widget)
win_entries, G_N_ELEMENTS (win_entries),
window);
gtk_widget_insert_action_group (window, "win", actions);
accel_group = gtk_accel_group_new ();
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
item = (GtkWidget*)gtk_builder_get_object (builder, "new_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_n, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = (GtkWidget*)gtk_builder_get_object (builder, "open_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = (GtkWidget*)gtk_builder_get_object (builder, "save_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_s, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = (GtkWidget*)gtk_builder_get_object (builder, "quit_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = (GtkWidget*)gtk_builder_get_object (builder, "copy_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = (GtkWidget*)gtk_builder_get_object (builder, "cut_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_x, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = (GtkWidget*)gtk_builder_get_object (builder, "paste_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_v, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
item = (GtkWidget*)gtk_builder_get_object (builder, "help_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_F1, 0, GTK_ACCEL_VISIBLE);
item = (GtkWidget*)gtk_builder_get_object (builder, "about_item");
gtk_widget_add_accelerator (item, "activate", accel_group,
GDK_KEY_F7, 0, GTK_ACCEL_VISIBLE);
g_object_set_data_full (G_OBJECT(window), "builder", builder, g_object_unref);
}

View File

@ -1,551 +0,0 @@
/* Change Display
*
* Demonstrates migrating a window between different displays.
* A display is a mouse and keyboard with some number of
* associated monitors. The neat thing about having multiple
* displays is that they can be on a completely separate
* computers, as long as there is a network connection to the
* computer where the application is running.
*
* Only some of the windowing systems where GTK runs have the
* concept of multiple displays. (The X Window System is the
* main example.) Other windowing systems can only handle one
* keyboard and mouse, and combine all monitors into
* a single display.
*
* This is a moderately complex example, and demonstrates:
*
* - Tracking the currently open displays
*
* - Changing the display for a window
*
* - Letting the user choose a window by clicking on it
*
* - Using GtkListStore and GtkTreeView
*
* - Using GtkDialog
*/
#include <string.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
/* The ChangeDisplayInfo structure corresponds to a toplevel window and
* holds pointers to widgets inside the toplevel window along with other
* information about the contents of the window.
* This is a common organizational structure in real applications.
*/
typedef struct _ChangeDisplayInfo ChangeDisplayInfo;
struct _ChangeDisplayInfo
{
GtkWidget *window;
GtkSizeGroup *size_group;
GtkTreeModel *display_model;
GdkDisplay *current_display;
};
/* These enumerations provide symbolic names for the columns
* in the two GtkListStore models.
*/
enum
{
DISPLAY_COLUMN_NAME,
DISPLAY_COLUMN_DISPLAY,
DISPLAY_NUM_COLUMNS
};
enum
{
SCREEN_COLUMN_NUMBER,
SCREEN_COLUMN_SCREEN,
SCREEN_NUM_COLUMNS
};
/* Finds the toplevel window under the mouse pointer, if any.
*/
static GtkWidget *
find_toplevel_at_pointer (GdkDisplay *display)
{
GdkSurface *pointer_window;
GtkWidget *widget = NULL;
pointer_window = gdk_device_get_surface_at_position (gtk_get_current_event_device (), NULL, NULL);
if (pointer_window)
widget = GTK_WIDGET (gtk_native_get_for_surface (pointer_window));
return widget;
}
static void
released_cb (GtkGestureClick *gesture,
guint n_press,
gdouble x,
gdouble y,
gboolean *clicked)
{
*clicked = TRUE;
}
/* Asks the user to click on a window, then waits for them click
* the mouse. When the mouse is released, returns the toplevel
* window under the pointer, or NULL, if there is none.
*/
static GtkWidget *
query_for_toplevel (GdkDisplay *display,
const char *prompt)
{
GtkWidget *popup, *label, *frame;
GdkCursor *cursor;
GtkWidget *toplevel = NULL;
GdkDevice *device;
popup = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_display (GTK_WINDOW (popup), display);
gtk_window_set_modal (GTK_WINDOW (popup), TRUE);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (popup), frame);
label = gtk_label_new (prompt);
g_object_set (label, "margin", 10, NULL);
gtk_container_add (GTK_CONTAINER (frame), label);
gtk_widget_show (popup);
cursor = gdk_cursor_new_from_name ("crosshair", NULL);
device = gtk_get_current_event_device ();
if (gdk_seat_grab (gdk_device_get_seat (device),
gtk_native_get_surface (GTK_NATIVE (popup)),
GDK_SEAT_CAPABILITY_ALL_POINTING,
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
{
GtkGesture *gesture = gtk_gesture_click_new ();
gboolean clicked = FALSE;
g_signal_connect (gesture, "released",
G_CALLBACK (released_cb), &clicked);
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
/* Process events until clicked is set by our button release event handler.
* We pass in may_block=TRUE since we want to wait if there
* are no events currently.
*/
while (!clicked)
g_main_context_iteration (NULL, TRUE);
gdk_seat_ungrab (gdk_device_get_seat (device));
toplevel = find_toplevel_at_pointer (display);
if (toplevel == popup)
toplevel = NULL;
}
g_object_unref (cursor);
gtk_widget_destroy (popup);
return toplevel;
}
/* Prompts the user for a toplevel window to move, and then moves
* that window to the currently selected display
*/
static void
query_change_display (ChangeDisplayInfo *info)
{
GdkDisplay *display = gtk_widget_get_display (info->window);
GtkWidget *toplevel;
toplevel = query_for_toplevel (display,
"Please select the toplevel\n"
"to move to the new display");
if (toplevel)
gtk_window_set_display (GTK_WINDOW (toplevel), info->current_display);
else
gdk_display_beep (display);
}
/* Called when the user clicks on a button in our dialog or
* closes the dialog through the window manager. Unless the
* "Change" button was clicked, we destroy the dialog.
*/
static void
response_cb (GtkDialog *dialog,
gint response_id,
ChangeDisplayInfo *info)
{
if (response_id == GTK_RESPONSE_OK)
query_change_display (info);
else
gtk_widget_destroy (GTK_WIDGET (dialog));
}
/* Called when the user clicks on "Open..." in the display
* frame. Prompts for a new display, and then opens a connection
* to that display.
*/
static void
open_display_cb (GtkWidget *button,
ChangeDisplayInfo *info)
{
GtkWidget *content_area;
GtkWidget *dialog;
GtkWidget *display_entry;
GtkWidget *dialog_label;
gchar *new_screen_name = NULL;
GdkDisplay *result = NULL;
dialog = gtk_dialog_new_with_buttons ("Open Display",
GTK_WINDOW (info->window),
GTK_DIALOG_MODAL,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_OK"), GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
display_entry = gtk_entry_new ();
gtk_entry_set_activates_default (GTK_ENTRY (display_entry), TRUE);
dialog_label =
gtk_label_new ("Please enter the name of\nthe new display\n");
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_container_add (GTK_CONTAINER (content_area), dialog_label);
gtk_container_add (GTK_CONTAINER (content_area), display_entry);
gtk_widget_grab_focus (display_entry);
while (!result)
{
gint response_id = gtk_dialog_run (GTK_DIALOG (dialog));
if (response_id != GTK_RESPONSE_OK)
break;
new_screen_name = gtk_editable_get_chars (GTK_EDITABLE (display_entry),
0, -1);
if (strcmp (new_screen_name, "") != 0)
{
result = gdk_display_open (new_screen_name);
if (!result)
{
gchar *error_msg =
g_strdup_printf ("Can't open display:\n\t%s\nplease try another one\n",
new_screen_name);
gtk_label_set_text (GTK_LABEL (dialog_label), error_msg);
g_free (error_msg);
}
g_free (new_screen_name);
}
}
gtk_widget_destroy (dialog);
}
/* Called when the user clicks on the "Close" button in the
* "Display" frame. Closes the selected display.
*/
static void
close_display_cb (GtkWidget *button,
ChangeDisplayInfo *info)
{
if (info->current_display)
gdk_display_close (info->current_display);
}
/* Called when the selected row in the display list changes.
* Updates info->current_display, then refills the list of
* screens.
*/
static void
display_changed_cb (GtkTreeSelection *selection,
ChangeDisplayInfo *info)
{
GtkTreeModel *model;
GtkTreeIter iter;
if (info->current_display)
g_object_unref (info->current_display);
if (gtk_tree_selection_get_selected (selection, &model, &iter))
gtk_tree_model_get (model, &iter,
DISPLAY_COLUMN_DISPLAY, &info->current_display,
-1);
else
info->current_display = NULL;
}
/* This function is used both for creating the "Display" and
* "Screen" frames, since they have a similar structure. The
* caller hooks up the right context for the value returned
* in tree_view, and packs any relevant buttons into button_vbox.
*/
static void
create_frame (ChangeDisplayInfo *info,
const char *title,
GtkWidget **frame,
GtkWidget **tree_view,
GtkWidget **button_vbox)
{
GtkTreeSelection *selection;
GtkWidget *scrollwin;
GtkWidget *hbox;
*frame = gtk_frame_new (title);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
g_object_set (hbox, "margin", 8, NULL);
gtk_container_add (GTK_CONTAINER (*frame), hbox);
scrollwin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin),
GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (hbox), scrollwin);
*tree_view = gtk_tree_view_new ();
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE);
gtk_container_add (GTK_CONTAINER (scrollwin), *tree_view);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (*tree_view));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
*button_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add (GTK_CONTAINER (hbox), *button_vbox);
if (!info->size_group)
info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_size_group_add_widget (GTK_SIZE_GROUP (info->size_group), *button_vbox);
}
/* If we have a stack of buttons, it often looks better if their contents
* are left-aligned, rather than centered. This function creates a button
* and left-aligns it contents.
*/
GtkWidget *
left_align_button_new (const char *label)
{
GtkWidget *button = gtk_button_new_with_mnemonic (label);
GtkWidget *child = gtk_bin_get_child (GTK_BIN (button));
gtk_widget_set_halign (child, GTK_ALIGN_START);
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
return button;
}
/* Creates the "Display" frame in the main window.
*/
GtkWidget *
create_display_frame (ChangeDisplayInfo *info)
{
GtkWidget *frame;
GtkWidget *tree_view;
GtkWidget *button_vbox;
GtkTreeViewColumn *column;
GtkTreeSelection *selection;
GtkWidget *button;
create_frame (info, "Display", &frame, &tree_view, &button_vbox);
button = left_align_button_new ("_Open...");
g_signal_connect (button, "clicked", G_CALLBACK (open_display_cb), info);
gtk_container_add (GTK_CONTAINER (button_vbox), button);
button = left_align_button_new ("_Close");
g_signal_connect (button, "clicked", G_CALLBACK (close_display_cb), info);
gtk_container_add (GTK_CONTAINER (button_vbox), button);
info->display_model = (GtkTreeModel *)gtk_list_store_new (DISPLAY_NUM_COLUMNS,
G_TYPE_STRING,
GDK_TYPE_DISPLAY);
gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), info->display_model);
column = gtk_tree_view_column_new_with_attributes ("Name",
gtk_cell_renderer_text_new (),
"text", DISPLAY_COLUMN_NAME,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
g_signal_connect (selection, "changed",
G_CALLBACK (display_changed_cb), info);
return frame;
}
/* Called when one of the currently open displays is closed.
* Remove it from our list of displays.
*/
static void
display_closed_cb (GdkDisplay *display,
gboolean is_error,
ChangeDisplayInfo *info)
{
GtkTreeIter iter;
gboolean valid;
for (valid = gtk_tree_model_get_iter_first (info->display_model, &iter);
valid;
valid = gtk_tree_model_iter_next (info->display_model, &iter))
{
GdkDisplay *tmp_display;
gtk_tree_model_get (info->display_model, &iter,
DISPLAY_COLUMN_DISPLAY, &tmp_display,
-1);
if (tmp_display == display)
{
gtk_list_store_remove (GTK_LIST_STORE (info->display_model), &iter);
break;
}
}
}
/* Adds a new display to our list of displays, and connects
* to the "closed" signal so that we can remove it from the
* list of displays again.
*/
static void
add_display (ChangeDisplayInfo *info,
GdkDisplay *display)
{
const gchar *name = gdk_display_get_name (display);
GtkTreeIter iter;
gtk_list_store_append (GTK_LIST_STORE (info->display_model), &iter);
gtk_list_store_set (GTK_LIST_STORE (info->display_model), &iter,
DISPLAY_COLUMN_NAME, name,
DISPLAY_COLUMN_DISPLAY, display,
-1);
g_signal_connect (display, "closed",
G_CALLBACK (display_closed_cb), info);
}
/* Called when a new display is opened
*/
static void
display_opened_cb (GdkDisplayManager *manager,
GdkDisplay *display,
ChangeDisplayInfo *info)
{
add_display (info, display);
}
/* Adds all currently open displays to our list of displays,
* and set up a signal connection so that we'll be notified
* when displays are opened in the future as well.
*/
static void
initialize_displays (ChangeDisplayInfo *info)
{
GdkDisplayManager *manager = gdk_display_manager_get ();
GSList *displays = gdk_display_manager_list_displays (manager);
GSList *tmp_list;
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
add_display (info, tmp_list->data);
g_slist_free (tmp_list);
g_signal_connect (manager, "display-opened",
G_CALLBACK (display_opened_cb), info);
}
/* Cleans up when the toplevel is destroyed; we remove the
* connections we use to track currently open displays, then
* free the ChangeDisplayInfo structure.
*/
static void
destroy_info (ChangeDisplayInfo *info)
{
GdkDisplayManager *manager = gdk_display_manager_get ();
GSList *displays = gdk_display_manager_list_displays (manager);
GSList *tmp_list;
g_signal_handlers_disconnect_by_func (manager,
display_opened_cb,
info);
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
g_signal_handlers_disconnect_by_func (tmp_list->data,
display_closed_cb,
info);
g_slist_free (tmp_list);
g_object_unref (info->size_group);
g_object_unref (info->display_model);
if (info->current_display)
g_object_unref (info->current_display);
g_free (info);
}
static void
destroy_cb (GObject *object,
ChangeDisplayInfo **info)
{
destroy_info (*info);
*info = NULL;
}
/* Main entry point. If the dialog for this demo doesn't yet exist, creates
* it. Otherwise, destroys it.
*/
GtkWidget *
do_changedisplay (GtkWidget *do_widget)
{
static ChangeDisplayInfo *info = NULL;
if (!info)
{
GtkWidget *content_area;
GtkWidget *vbox;
GtkWidget *frame;
info = g_new0 (ChangeDisplayInfo, 1);
info->window = gtk_dialog_new_with_buttons ("Change Display",
GTK_WINDOW (do_widget),
0,
"Close", GTK_RESPONSE_CLOSE,
"Change", GTK_RESPONSE_OK,
NULL);
gtk_window_set_default_size (GTK_WINDOW (info->window), 300, 400);
g_signal_connect (info->window, "response",
G_CALLBACK (response_cb), info);
g_signal_connect (info->window, "destroy",
G_CALLBACK (destroy_cb), &info);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (info->window));
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
g_object_set (vbox, "margin", 8, NULL);
gtk_container_add (GTK_CONTAINER (content_area), vbox);
frame = create_display_frame (info);
gtk_container_add (GTK_CONTAINER (vbox), frame);
initialize_displays (info);
gtk_widget_show (info->window);
return info->window;
}
else
{
gtk_widget_destroy (info->window);
return NULL;
}
}

View File

@ -164,17 +164,19 @@ drag_data_received (GtkWidget *widget,
}
static void
copy_image (GtkMenuItem *item,
gpointer data)
copy_image (GSimpleAction *action,
GVariant *value,
gpointer data)
{
GdkClipboard *clipboard;
GdkPaintable *paintable;
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
paintable = get_image_paintable (GTK_IMAGE (data));
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
g_print ("copy image\n");
if (GDK_IS_TEXTURE (paintable))
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
{
g_print ("set clipboard\n");
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
}
if (paintable)
g_object_unref (paintable);
@ -196,16 +198,12 @@ paste_image_received (GObject *source,
}
static void
paste_image (GtkMenuItem *item,
gpointer data)
paste_image (GSimpleAction *action,
GVariant *value,
gpointer data)
{
GdkClipboard *clipboard;
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
gdk_clipboard_read_texture_async (clipboard,
NULL,
paste_image_received,
data);
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
gdk_clipboard_read_texture_async (clipboard, NULL, paste_image_received, data);
}
static void
@ -215,22 +213,23 @@ pressed_cb (GtkGesture *gesture,
double y,
GtkWidget *image)
{
GtkWidget *menu;
GtkWidget *item;
GtkWidget *popover;
GMenu *menu;
GMenuItem *item;
menu = gtk_menu_new ();
menu = g_menu_new ();
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
g_menu_append_item (menu, item);
item = gtk_menu_item_new_with_mnemonic (_("_Copy"));
g_signal_connect (item, "activate", G_CALLBACK (copy_image), image);
gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
g_menu_append_item (menu, item);
item = gtk_menu_item_new_with_mnemonic (_("_Paste"));
g_signal_connect (item, "activate", G_CALLBACK (paste_image), image);
gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
popover = gtk_popover_menu_new_from_model (image, G_MENU_MODEL (menu));
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &(GdkRectangle) { x, y, 1, 1});
gtk_popover_popup (GTK_POPOVER (popover));
g_object_unref (menu);
}
GtkWidget *
@ -243,6 +242,11 @@ do_clipboard (GtkWidget *do_widget)
GtkWidget *entry, *button;
GtkWidget *image;
GtkGesture *gesture;
GActionEntry entries[] = {
{ "copy", copy_image, NULL, NULL, NULL },
{ "paste", paste_image, NULL, NULL, NULL },
};
GActionGroup *actions;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window),
@ -324,6 +328,13 @@ do_clipboard (GtkWidget *do_widget)
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
actions = G_ACTION_GROUP (g_simple_action_group_new ());
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
gtk_widget_insert_action_group (image, "clipboard", actions);
g_object_unref (actions);
/* Create the second image */
image = gtk_image_new_from_icon_name ("process-stop");
gtk_container_add (GTK_CONTAINER (hbox), image);
@ -348,6 +359,13 @@ do_clipboard (GtkWidget *do_widget)
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
actions = G_ACTION_GROUP (g_simple_action_group_new ());
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
gtk_widget_insert_action_group (image, "clipboard", actions);
g_object_unref (actions);
}
if (!gtk_widget_get_visible (window))

View File

@ -149,7 +149,6 @@
<file>application_demo.c</file>
<file>assistant.c</file>
<file>builder.c</file>
<file>changedisplay.c</file>
<file>clipboard.c</file>
<file>colorsel.c</file>
<file>combobox.c</file>
@ -191,7 +190,6 @@
<file>listbox.c</file>
<file>list_store.c</file>
<file>markup.c</file>
<file>menus.c</file>
<file>modelbutton.c</file>
<file>overlay.c</file>
<file>overlay2.c</file>

View File

@ -22,6 +22,75 @@
</row>
</data>
</object>
<menu id="menubar">
<submenu>
<attribute name="label" translatable="yes">_File</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_New</attribute>
<attribute name="action">win.new</attribute>
<attribute name="accel">&lt;Primary&gt;n</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Open</attribute>
<attribute name="action">win.open</attribute>
<attribute name="accel">&lt;Primary&gt;o</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Save</attribute>
<attribute name="action">win.save</attribute>
<attribute name="accel">&lt;Primary&gt;s</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Save _As</attribute>
<attribute name="action">win.save-as</attribute>
<attribute name="accel">&lt;Primary&gt;q</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">win.quit</attribute>
<attribute name="accel">&lt;Primary&gt;&lt;Shift&gt;s</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Edit</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_Copy</attribute>
<attribute name="action">win.copy</attribute>
<attribute name="accel">&lt;Primary&gt;c</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Cut</attribute>
<attribute name="action">win.cut</attribute>
<attribute name="accel">&lt;Primary&gt;x</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Paste</attribute>
<attribute name="action">win.paste</attribute>
<attribute name="accel">&lt;Primary&gt;v</attribute>
</item>
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Help</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="action">win.help</attribute>
<attribute name="accel">F1</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About</attribute>
<attribute name="action">win.about</attribute>
<attribute name="accel">F7</attribute>
</item>
</section>
</submenu>
</menu>
<object class="GtkAboutDialog" id="aboutdialog1">
<property name="program-name" translatable="yes">Builder demo</property>
<property name="logo-icon-name" translatable="yes">gtk3-demo</property>
@ -37,109 +106,8 @@
<object class="GtkBox" id="vbox1">
<property name="orientation">vertical</property>
<child>
<object class="GtkMenuBar" id="menubar1">
<child internal-child="accessible">
<object class="AtkObject" id="a11y-menubar">
<property name="AtkObject::accessible-name">The menubar</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="label" translatable="yes">_File</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu">
<child>
<object class="GtkMenuItem" id="new_item">
<property name="label" translatable="yes">_New</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="open_item">
<property name="label" translatable="yes">_Open</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="save_item">
<property name="label" translatable="yes">_Save</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="save_as_item">
<property name="label" translatable="yes">Save _As</property>
<property name="use-underline">1</property>
<accelerator key="s" modifiers="primary | shift-mask" signal="activate"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem"/>
</child>
<child>
<object class="GtkMenuItem" id="quit_item">
<property name="label" translatable="yes">_Quit</property>
<property name="use-underline">1</property>
<property name="action-name">win.quit</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="label" translatable="yes">_Edit</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu">
<child>
<object class="GtkMenuItem" id="copy_item">
<property name="label" translatable="yes">_Copy</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="cut_item">
<property name="label" translatable="yes">_Cut</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="paste_item">
<property name="label" translatable="yes">_Paste</property>
<property name="use-underline">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="label" translatable="yes">_Help</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu">
<child>
<object class="GtkMenuItem" id="help_item">
<property name="label" translatable="yes">_Help</property>
<property name="use-underline">1</property>
<property name="action-name">win.help</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="about_item">
<property name="label" translatable="yes">_About</property>
<property name="use-underline">1</property>
<property name="action-name">win.about</property>
</object>
</child>
</object>
</child>
</object>
</child>
<object class="GtkPopoverMenuBar" id="menubar1">
<property name="menu-model">menubar</property>
</object>
</child>
<child>

View File

@ -94,7 +94,7 @@ deserialize_widget (GtkDemoWidget *demo)
static double pos_x, pos_y;
static void
new_label_cb (GtkMenuItem *item,
new_label_cb (GtkWidget *button,
gpointer data)
{
GtkFixed *fixed = data;
@ -102,10 +102,12 @@ new_label_cb (GtkMenuItem *item,
widget = gtk_label_new ("Label");
gtk_fixed_put (fixed, widget, pos_x, pos_y);
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
}
static void
new_spinner_cb (GtkMenuItem *item,
new_spinner_cb (GtkWidget *button,
gpointer data)
{
GtkFixed *fixed = data;
@ -115,33 +117,39 @@ new_spinner_cb (GtkMenuItem *item,
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "demo");
gtk_spinner_start (GTK_SPINNER (widget));
gtk_fixed_put (fixed, widget, pos_x, pos_y);
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
}
static void
copy_cb (GtkWidget *child)
copy_cb (GtkWidget *button, GtkWidget *child)
{
GdkClipboard *clipboard;
GtkDemoWidget *demo;
g_print ("Copy %s\n", G_OBJECT_TYPE_NAME (child));
demo = serialize_widget (child);
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
gdk_clipboard_set (clipboard, GTK_TYPE_DEMO_WIDGET, demo);
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
}
static void
delete_cb (GtkWidget *child)
delete_cb (GtkWidget *button, GtkWidget *child)
{
gtk_widget_destroy (child);
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
}
static void
cut_cb (GtkWidget *child)
cut_cb (GtkWidget *button, GtkWidget *child)
{
copy_cb (child);
delete_cb (child);
copy_cb (button, child);
delete_cb (button, child);
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
}
static void
@ -177,7 +185,7 @@ value_read (GObject *source,
}
static void
paste_cb (GtkWidget *fixed)
paste_cb (GtkWidget *button, GtkWidget *fixed)
{
GdkClipboard *clipboard;
@ -189,6 +197,8 @@ paste_cb (GtkWidget *fixed)
}
else
g_print ("Don't know how to handle clipboard contents\n");
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
}
static void
@ -207,7 +217,7 @@ edit_label_done (GtkWidget *entry, gpointer data)
}
static void
edit_cb (GtkWidget *child)
edit_cb (GtkWidget *button, GtkWidget *child)
{
GtkWidget *fixed = gtk_widget_get_parent (child);
int x, y;
@ -233,6 +243,9 @@ edit_cb (GtkWidget *child)
g_object_get (child, "active", &active, NULL);
g_object_set (child, "active", !active, NULL);
}
if (button)
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
}
static void
@ -250,65 +263,65 @@ pressed_cb (GtkGesture *gesture,
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
{
GdkRectangle rect;
GtkWidget *menu;
GtkWidget *box;
GtkWidget *item;
GdkClipboard *clipboard;
pos_x = x;
pos_y = y;
menu = gtk_menu_new ();
item = gtk_menu_item_new_with_label ("New Label");
g_signal_connect (item, "activate", G_CALLBACK (new_label_cb), widget);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("New Spinner");
g_signal_connect (item, "activate", G_CALLBACK (new_spinner_cb), widget);
gtk_container_add (GTK_CONTAINER (menu), item);
menu = gtk_popover_new (widget);
gtk_popover_set_has_arrow (GTK_POPOVER (menu), FALSE);
gtk_popover_set_pointing_to (GTK_POPOVER (menu), &(GdkRectangle){ x, y, 1, 1});
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (menu), box);
item = gtk_separator_menu_item_new ();
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_button_new_with_label ("New Label");
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
g_signal_connect (item, "clicked", G_CALLBACK (new_label_cb), widget);
gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_button_new_with_label ("New Spinner");
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
g_signal_connect (item, "clicked", G_CALLBACK (new_spinner_cb), widget);
gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_menu_item_new_with_label ("Edit");
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_button_new_with_label ("Edit");
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
gtk_widget_set_sensitive (item, child != NULL && child != widget);
g_signal_connect_swapped (item, "activate", G_CALLBACK (edit_cb), child);
gtk_container_add (GTK_CONTAINER (menu), item);
g_signal_connect (item, "clicked", G_CALLBACK (edit_cb), child);
gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_separator_menu_item_new ();
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_menu_item_new_with_label ("Cut");
item = gtk_button_new_with_label ("Cut");
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
gtk_widget_set_sensitive (item, child != NULL && child != widget);
g_signal_connect_swapped (item, "activate", G_CALLBACK (cut_cb), child);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("Copy");
g_signal_connect (item, "clicked", G_CALLBACK (cut_cb), child);
gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_button_new_with_label ("Copy");
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
gtk_widget_set_sensitive (item, child != NULL && child != widget);
g_signal_connect_swapped (item, "activate", G_CALLBACK (copy_cb), child);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("Paste");
g_signal_connect (item, "clicked", G_CALLBACK (copy_cb), child);
gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_button_new_with_label ("Paste");
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
gtk_widget_set_sensitive (item,
gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_DEMO_WIDGET));
g_signal_connect_swapped (item, "activate", G_CALLBACK (paste_cb), widget);
gtk_container_add (GTK_CONTAINER (menu), item);
item = gtk_menu_item_new_with_label ("Delete");
g_signal_connect (item, "clicked", G_CALLBACK (paste_cb), widget);
gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_button_new_with_label ("Delete");
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
gtk_widget_set_sensitive (item, child != NULL && child != widget);
g_signal_connect_swapped (item, "activate", G_CALLBACK (delete_cb), child);
gtk_container_add (GTK_CONTAINER (menu), item);
g_signal_connect (item, "clicked", G_CALLBACK (delete_cb), child);
gtk_container_add (GTK_CONTAINER (box), item);
rect.x = x;
rect.y = y;
rect.width = 0;
rect.height = 0;
gtk_menu_popup_at_rect (GTK_MENU (menu),
gtk_native_get_surface (gtk_widget_get_native (widget)),
&rect,
GDK_GRAVITY_NORTH_WEST,
GDK_GRAVITY_NORTH_WEST,
NULL);
return;
gtk_popover_popup (GTK_POPOVER (menu));
}
}
@ -328,7 +341,7 @@ released_cb (GtkGesture *gesture,
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY)
{
if (child != NULL && child != widget)
edit_cb (child);
edit_cb (NULL, child);
}
}

View File

@ -414,7 +414,7 @@ draw_menubar (GtkWidget *widget,
frame_context = get_style (NULL, "frame");
border_context = get_style (frame_context, "border");
/* This information is taken from the GtkMenuBar docs, see "CSS nodes" */
/* This information is taken from the GtkPopoverMenuBar docs, see "CSS nodes" */
menubar_context = get_style (NULL, "menubar");
hovered_menuitem_context = get_style (menubar_context, "menuitem:hover");
menuitem_context = get_style (menubar_context, "menuitem");

View File

@ -1,19 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface domain="gtk40">
<object class="GtkMenu" id="menu1">
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="label" translatable="yes">Email message</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem2">
<property name="label" translatable="yes">Embed message</property>
<property name="use-underline">1</property>
</object>
</child>
</object>
<menu id="menu1">
<section>
<item>
<attribute name="label" translatable="yes">Email message</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Embed message</attribute>
</item>
</section>
</menu>
<template class="GtkMessageRow" parent="GtkListBoxRow">
<child>
<object class="GtkGrid" id="grid1">
@ -171,7 +167,7 @@
<object class="GtkMenuButton" id="more-button">
<property name="can-focus">1</property>
<property name="receives-default">1</property>
<property name="popup">menu1</property>
<property name="menu-model">menu1</property>
<property name="relief">none</property>
<property name="label" translatable="yes">More...</property>
</object>

View File

@ -1003,32 +1003,6 @@ row_activated_cb (GtkWidget *tree_view,
run_example_for_row (window, model, &iter);
}
static void
start_cb (GtkMenuItem *item, GtkWidget *scrollbar)
{
GtkAdjustment *adj;
adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (scrollbar));
gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
}
static void
end_cb (GtkMenuItem *item, GtkWidget *scrollbar)
{
GtkAdjustment *adj;
adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (scrollbar));
gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
}
static gboolean
scrollbar_popup (GtkWidget *scrollbar, GtkWidget *menu)
{
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
return TRUE;
}
static void
activate (GApplication *app)
{
@ -1037,10 +1011,6 @@ activate (GApplication *app)
GtkWidget *widget;
GtkTreeModel *model;
GtkTreeIter iter;
GtkWidget *sw;
GtkWidget *scrollbar;
GtkWidget *menu;
GtkWidget *item;
static GActionEntry win_entries[] = {
{ "run", activate_run, NULL, NULL, NULL }
@ -1062,21 +1032,6 @@ activate (GApplication *app)
treeview = (GtkWidget *)gtk_builder_get_object (builder, "treeview");
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
sw = (GtkWidget *)gtk_builder_get_object (builder, "source-scrolledwindow");
scrollbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (sw));
menu = gtk_menu_new ();
item = gtk_menu_item_new_with_label ("Start");
g_signal_connect (item, "activate", G_CALLBACK (start_cb), scrollbar);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = gtk_menu_item_new_with_label ("End");
g_signal_connect (item, "activate", G_CALLBACK (end_cb), scrollbar);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
g_signal_connect (scrollbar, "popup-menu", G_CALLBACK (scrollbar_popup), menu);
load_file (gtk_demos[0].name, gtk_demos[0].filename);
populate_model (model);

View File

@ -1,147 +0,0 @@
/* Menus
*
* There are several widgets involved in displaying menus. The
* GtkMenuBar widget is a menu bar, which normally appears horizontally
* at the top of an application, but can also be layed out vertically.
* The GtkMenu widget is the actual menu that pops up. Both GtkMenuBar
* and GtkMenu are subclasses of GtkMenuShell; a GtkMenuShell contains
* menu items (GtkMenuItem). Each menu item contains text and/or images
* and can be selected by the user.
*
* There are several kinds of menu item, including plain GtkMenuItem,
* GtkCheckMenuItem which can be checked/unchecked, GtkRadioMenuItem
* which is a check menu item that's in a mutually exclusive group,
* GtkSeparatorMenuItem which is a separator bar, GtkTearoffMenuItem
* which allows a GtkMenu to be torn off, and GtkImageMenuItem which
* can place a GtkImage or other widget next to the menu text.
*
* A GtkMenuItem can have a submenu, which is simply a GtkMenu to pop
* up when the menu item is selected. Typically, all menu items in a menu bar
* have submenus.
*/
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <stdio.h>
static GtkWidget *
create_menu (gint depth)
{
GtkWidget *menu;
GtkRadioMenuItem *last_item;
char buf[32];
int i, j;
if (depth < 1)
return NULL;
menu = gtk_menu_new ();
last_item = NULL;
for (i = 0, j = 1; i < 5; i++, j++)
{
GtkWidget *menu_item;
sprintf (buf, "item %2d - %d", depth, j);
menu_item = gtk_radio_menu_item_new_with_label_from_widget (NULL, buf);
gtk_radio_menu_item_join_group (GTK_RADIO_MENU_ITEM (menu_item), last_item);
last_item = GTK_RADIO_MENU_ITEM (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
if (i == 3)
gtk_widget_set_sensitive (menu_item, FALSE);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), create_menu (depth - 1));
}
return menu;
}
static void
change_orientation (GtkWidget *button,
GtkWidget *menubar)
{
GtkWidget *parent;
GtkOrientation orientation;
parent = gtk_widget_get_parent (menubar);
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (parent));
gtk_orientable_set_orientation (GTK_ORIENTABLE (parent), 1 - orientation);
}
static GtkWidget *window = NULL;
GtkWidget *
do_menus (GtkWidget *do_widget)
{
GtkWidget *box;
GtkWidget *box1;
GtkWidget *box2;
GtkWidget *button;
if (!window)
{
GtkWidget *menubar;
GtkWidget *menu;
GtkWidget *menuitem;
GtkAccelGroup *accel_group;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Menus");
g_signal_connect (window, "destroy",
G_CALLBACK(gtk_widget_destroyed), &window);
accel_group = gtk_accel_group_new ();
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_add (GTK_CONTAINER (window), box);
box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (box), box1);
menubar = gtk_menu_bar_new ();
gtk_widget_set_hexpand (menubar, TRUE);
gtk_container_add (GTK_CONTAINER (box1), menubar);
menu = create_menu (2);
menuitem = gtk_menu_item_new_with_label ("test\nline2");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
menuitem = gtk_menu_item_new_with_label ("foo");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3));
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
menuitem = gtk_menu_item_new_with_label ("bar");
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4));
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
gtk_container_add (GTK_CONTAINER (box1), box2);
button = gtk_button_new_with_label ("Flip");
g_signal_connect (button, "clicked",
G_CALLBACK (change_orientation), menubar);
gtk_container_add (GTK_CONTAINER (box2), button);
button = gtk_button_new_with_label ("Close");
g_signal_connect_swapped (button, "clicked",
G_CALLBACK(gtk_widget_destroy), window);
gtk_container_add (GTK_CONTAINER (box2), button);
gtk_window_set_default_widget (GTK_WINDOW (window), button);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@ -4,7 +4,6 @@ demos = files([
'application_demo.c',
'assistant.c',
'builder.c',
'changedisplay.c',
'clipboard.c',
'colorsel.c',
'combobox.c',
@ -44,7 +43,6 @@ demos = files([
'flowbox.c',
'list_store.c',
'markup.c',
'menus.c',
'modelbutton.c',
'overlay.c',
'overlay2.c',

View File

@ -1053,27 +1053,6 @@ row_activated (GtkListBox *box, GtkListBoxRow *row)
}
}
static void
set_accel (GtkApplication *app, GtkWidget *widget)
{
GtkWidget *accel_label;
const gchar *action;
gchar **accels;
guint key;
GdkModifierType mods;
accel_label = gtk_bin_get_child (GTK_BIN (widget));
g_assert (GTK_IS_ACCEL_LABEL (accel_label));
action = gtk_actionable_get_action_name (GTK_ACTIONABLE (widget));
accels = gtk_application_get_accels_for_action (app, action);
gtk_accelerator_parse (accels[0], &key, &mods);
gtk_accel_label_set_accel (GTK_ACCEL_LABEL (accel_label), key, mods);
g_strfreev (accels);
}
typedef struct
{
GtkTextView tv;
@ -1863,13 +1842,6 @@ activate (GApplication *app)
g_object_set_data (G_OBJECT (widget2), "range_to_spin", widget3);
g_object_set_data (G_OBJECT (widget), "print_button", widget4);
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "quitmenuitem")));
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "deletemenuitem")));
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "searchmenuitem")));
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "darkmenuitem")));
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "aboutmenuitem")));
set_accel (GTK_APPLICATION (app), GTK_WIDGET (gtk_builder_get_object (builder, "bgmenuitem")));
widget2 = (GtkWidget *)gtk_builder_get_object (builder, "tooltextview");
widget = (GtkWidget *)gtk_builder_get_object (builder, "toolbutton1");

View File

@ -1814,260 +1814,6 @@ microphone-sensitivity-medium-symbolic</property>
<property name="menu-model">menu_bar_model</property>
</object>
</child>
<child>
<object class="GtkMenuBar">
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="label" translatable="yes">File</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu" id="menu1">
<child>
<object class="GtkMenuItem" id="menuitem101">
<property name="label" translatable="yes">_New</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem102">
<property name="label" translatable="yes">_Open</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem103">
<property name="label" translatable="yes">_Save</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem104">
<property name="label" translatable="yes">Save _As</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem1"/>
</child>
<child>
<object class="GtkMenuItem" id="quitmenuitem">
<property name="label" translatable="yes">_Quit</property>
<property name="use-underline">1</property>
<property name="action-name">app.quit</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem2">
<property name="label" translatable="yes">Edit</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu" id="menu2">
<child>
<object class="GtkMenuItem" id="menuitem106">
<property name="label" translatable="yes">Cu_t</property>
<property name="can-focus">1</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem107">
<property name="label" translatable="yes">_Copy</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem108">
<property name="label" translatable="yes">_Paste</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="deletemenuitem">
<property name="label" translatable="yes">_Delete</property>
<property name="use-underline">1</property>
<property name="action-name">win.delete</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="searchmenuitem">
<property name="label" translatable="yes">_Search</property>
<property name="use-underline">1</property>
<property name="action-name">win.search</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="checksmenuitem">
<property name="label">_Checks</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu" id="checkssubmenu">
<child>
<object class="GtkCheckMenuItem" id="checkmenuitem1">
<property name="label">_Check</property>
<property name="active">1</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="checkmenuitem2">
<property name="label">_Check</property>
<property name="active">1</property>
<property name="sensitive">0</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="checkmenuitem3">
<property name="label">_Check</property>
<property name="inconsistent">1</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="checkmenuitem4">
<property name="label">_Check</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="checkmenuitem5">
<property name="label">_Check</property>
<property name="sensitive">0</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="checkmenuitem6">
<property name="label">_Check</property>
<property name="inconsistent">1</property>
<property name="sensitive">0</property>
<property name="use-underline">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="radiosmenuitem">
<property name="label">_Radios</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu" id="radiossubmenu">
<child>
<object class="GtkRadioMenuItem" id="radiomenuitem1">
<property name="label">_Radio</property>
<property name="active">1</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="radiomenuitem2">
<property name="label">_Radio</property>
<property name="active">1</property>
<property name="sensitive">0</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="radiomenuitem3">
<property name="label">_Radio</property>
<property name="inconsistent">1</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="radiomenuitem4">
<property name="label">_Radio</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="radiomenuitem5">
<property name="label">_Radio</property>
<property name="sensitive">0</property>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkRadioMenuItem" id="radiomenuitem6">
<property name="label">_Radio</property>
<property name="inconsistent">1</property>
<property name="sensitive">0</property>
<property name="use-underline">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem3">
<property name="label" translatable="yes">View</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu" id="view-menu">
<child>
<object class="GtkCheckMenuItem" id="darkmenuitem">
<property name="label">_Dark theme</property>
<property name="use-underline">1</property>
<property name="action-name">win.dark</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="toolbarmenuitem">
<property name="label">_Toolbar</property>
<property name="active">1</property>
<property name="use-underline">1</property>
<property name="action-name">win.toolbar</property>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="statusbarmenuitem">
<property name="label">_Statusbar</property>
<property name="active">1</property>
<property name="use-underline">1</property>
<property name="action-name">win.statusbar</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="bgmenuitem">
<property name="label">_Select Background</property>
<property name="use-underline">1</property>
<property name="action-name">win.background</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem4">
<property name="label" translatable="yes">Help</property>
<property name="use-underline">1</property>
<child type="submenu">
<object class="GtkMenu" id="menu3">
<child>
<object class="GtkMenuItem" id="aboutmenuitem">
<property name="label" translatable="yes">_About</property>
<property name="use-underline">1</property>
<property name="action-name">app.about</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToolbar" id="toolbar">
<child>

View File

@ -544,8 +544,6 @@ GdkSeatCapabilities
GdkGrabStatus
GdkSeatGrabPrepareFunc
gdk_seat_get_display
gdk_seat_grab
gdk_seat_ungrab
gdk_seat_get_capabilities
gdk_seat_get_pointer
gdk_seat_get_keyboard

View File

@ -314,8 +314,8 @@
be connected to an action just by setting the ::action-name
property. If the action has a parameter, you will also need
to set the ::action-target property.
Widgets that implement GtkAction include GtkSwitch, GtkButton,
GtkMenuItem and their respective subclasses.
Widgets that implement GtkActionable include GtkSwitch, GtkButton,
and their respective subclasses.
</para>
<para>

View File

@ -217,12 +217,6 @@
<title>Menus, Combo Box, Toolbar</title>
<xi:include href="xml/gtkcombobox.xml" />
<xi:include href="xml/gtkcomboboxtext.xml" />
<xi:include href="xml/gtkmenu.xml" />
<xi:include href="xml/gtkmenubar.xml" />
<xi:include href="xml/gtkmenuitem.xml" />
<xi:include href="xml/gtkradiomenuitem.xml" />
<xi:include href="xml/gtkcheckmenuitem.xml" />
<xi:include href="xml/gtkseparatormenuitem.xml" />
<xi:include href="xml/gtktoolshell.xml" />
<xi:include href="xml/gtktoolbar.xml" />
<xi:include href="xml/gtktoolitem.xml" />
@ -311,7 +305,6 @@
<xi:include href="xml/gtkwidget.xml" />
<xi:include href="xml/gtkcontainer.xml" />
<xi:include href="xml/gtkbin.xml" />
<xi:include href="xml/gtkmenushell.xml" />
<xi:include href="xml/gtkrange.xml" />
<xi:include href="xml/gtkimcontext.xml" />
<xi:include href="xml/gtknativedialog.xml" />

View File

@ -674,34 +674,6 @@ GTK_CHECK_BUTTON_GET_CLASS
gtk_check_button_get_type
</SECTION>
<SECTION>
<FILE>gtkcheckmenuitem</FILE>
GtkCheckMenuItem
GtkCheckMenuItemClass
<TITLE>GtkCheckMenuItem</TITLE>
gtk_check_menu_item_new
gtk_check_menu_item_new_with_label
gtk_check_menu_item_new_with_mnemonic
gtk_check_menu_item_get_active
gtk_check_menu_item_set_active
gtk_check_menu_item_toggled
gtk_check_menu_item_get_inconsistent
gtk_check_menu_item_set_inconsistent
gtk_check_menu_item_set_draw_as_radio
gtk_check_menu_item_get_draw_as_radio
<SUBSECTION Standard>
GTK_CHECK_MENU_ITEM
GTK_IS_CHECK_MENU_ITEM
GTK_TYPE_CHECK_MENU_ITEM
GTK_CHECK_MENU_ITEM_CLASS
GTK_IS_CHECK_MENU_ITEM_CLASS
GTK_CHECK_MENU_ITEM_GET_CLASS
<SUBSECTION Private>
GtkCheckMenuItemPrivate
gtk_check_menu_item_get_type
</SECTION>
<SECTION>
<FILE>gtkcolorbutton</FILE>
<TITLE>GtkColorButton</TITLE>
@ -1830,79 +1802,15 @@ GTK_MAP_LIST_MODEL_GET_CLASS
gtk_map_list_model_get_type
</SECTION>
<SECTION>
<FILE>gtkmenu</FILE>
<TITLE>GtkMenu</TITLE>
GtkMenu
gtk_menu_new
gtk_menu_new_from_model
GtkPopoverMenuFlags
gtk_menu_reorder_child
gtk_menu_popup_at_rect
gtk_menu_popup_at_widget
gtk_menu_popup_at_pointer
gtk_menu_set_accel_group
gtk_menu_get_accel_group
gtk_menu_set_accel_path
gtk_menu_get_accel_path
gtk_menu_set_monitor
gtk_menu_get_monitor
gtk_menu_place_on_monitor
gtk_menu_set_reserve_toggle_size
gtk_menu_get_reserve_toggle_size
<SUBSECTION>
gtk_menu_popdown
gtk_menu_reposition
gtk_menu_get_active
gtk_menu_set_active
gtk_menu_attach_to_widget
gtk_menu_detach
gtk_menu_get_attach_widget
gtk_menu_get_for_attach_widget
GtkMenuDetachFunc
<SUBSECTION Standard>
GTK_MENU
GTK_IS_MENU
GTK_TYPE_MENU
GTK_MENU_CLASS
GTK_IS_MENU_CLASS
GTK_MENU_GET_CLASS
<SUBSECTION Private>
GtkMenuPrivate
gtk_menu_get_type
</SECTION>
<SECTION>
<FILE>gtkmenubar</FILE>
<TITLE>GtkMenuBar</TITLE>
GtkMenuBar
gtk_menu_bar_new
gtk_menu_bar_new_from_model
<SUBSECTION Standard>
GTK_MENU_BAR
GTK_IS_MENU_BAR
GTK_TYPE_MENU_BAR
GTK_MENU_BAR_CLASS
GTK_IS_MENU_BAR_CLASS
GTK_MENU_BAR_GET_CLASS
<SUBSECTION Private>
GtkMenuBarPrivate
gtk_menu_bar_get_type
</SECTION>
<SECTION>
<FILE>gtkmenubutton</FILE>
<TITLE>GtkMenuButton</TITLE>
GtkMenuButton
gtk_menu_button_new
gtk_menu_button_set_popup
gtk_menu_button_get_popup
gtk_menu_button_set_popover
gtk_menu_button_get_popover
gtk_menu_button_set_menu_model
gtk_menu_button_get_menu_model
gtk_menu_button_set_use_popover
gtk_menu_button_get_use_popover
GtkArrowType
gtk_menu_button_set_direction
gtk_menu_button_get_direction
@ -1916,6 +1824,7 @@ gtk_menu_button_set_relief
gtk_menu_button_get_relief
gtk_menu_button_popup
gtk_menu_button_popdown
GtkMenuButtonCreatePopupFunc
gtk_menu_button_set_create_popup_func
<SUBSECTION Standard>
GTK_TYPE_MENU_BUTTON
@ -1929,72 +1838,6 @@ GtkMenuButtonPrivate
gtk_menu_button_get_type
</SECTION>
<SECTION>
<FILE>gtkmenuitem</FILE>
<TITLE>GtkMenuItem</TITLE>
GtkMenuItem
GtkMenuItemClass
gtk_menu_item_new
gtk_menu_item_new_with_label
gtk_menu_item_new_with_mnemonic
gtk_menu_item_get_label
gtk_menu_item_set_label
gtk_menu_item_get_use_underline
gtk_menu_item_set_use_underline
gtk_menu_item_set_submenu
gtk_menu_item_get_submenu
gtk_menu_item_set_accel_path
gtk_menu_item_get_accel_path
gtk_menu_item_select
gtk_menu_item_deselect
gtk_menu_item_activate
gtk_menu_item_toggle_size_request
gtk_menu_item_toggle_size_allocate
gtk_menu_item_get_reserve_indicator
gtk_menu_item_set_reserve_indicator
<SUBSECTION Standard>
GTK_MENU_ITEM
GTK_IS_MENU_ITEM
GTK_TYPE_MENU_ITEM
GTK_MENU_ITEM_CLASS
GTK_IS_MENU_ITEM_CLASS
GTK_MENU_ITEM_GET_CLASS
<SUBSECTION Private>
GtkMenuItemPrivate
gtk_menu_item_get_type
</SECTION>
<SECTION>
<FILE>gtkmenushell</FILE>
<TITLE>GtkMenuShell</TITLE>
GtkMenuShell
gtk_menu_shell_append
gtk_menu_shell_prepend
gtk_menu_shell_insert
gtk_menu_shell_deactivate
gtk_menu_shell_select_item
gtk_menu_shell_select_first
gtk_menu_shell_deselect
gtk_menu_shell_activate_item
gtk_menu_shell_cancel
gtk_menu_shell_set_take_focus
gtk_menu_shell_get_take_focus
gtk_menu_shell_get_selected_item
gtk_menu_shell_get_parent_shell
gtk_menu_shell_bind_model
GtkMenuDirectionType
<SUBSECTION Standard>
GTK_MENU_SHELL
GTK_IS_MENU_SHELL
GTK_TYPE_MENU_SHELL
GTK_MENU_SHELL_CLASS
GTK_IS_MENU_SHELL_CLASS
GTK_MENU_SHELL_GET_CLASS
<SUBSECTION Private>
GtkMenuShellPrivate
gtk_menu_shell_get_type
</SECTION>
<SECTION>
<FILE>gtkmessagedialog</FILE>
<TITLE>GtkMessageDialog</TITLE>
@ -2257,31 +2100,6 @@ GtkRadioButtonPrivate
gtk_radio_button_get_type
</SECTION>
<SECTION>
<FILE>gtkradiomenuitem</FILE>
<TITLE>GtkRadioMenuItem</TITLE>
GtkRadioMenuItem
gtk_radio_menu_item_new
gtk_radio_menu_item_new_with_label
gtk_radio_menu_item_new_with_mnemonic
gtk_radio_menu_item_new_from_widget
gtk_radio_menu_item_new_with_label_from_widget
gtk_radio_menu_item_new_with_mnemonic_from_widget
gtk_radio_menu_item_set_group
gtk_radio_menu_item_get_group
gtk_radio_menu_item_join_group
<SUBSECTION Standard>
GTK_RADIO_MENU_ITEM
GTK_IS_RADIO_MENU_ITEM
GTK_TYPE_RADIO_MENU_ITEM
GTK_RADIO_MENU_ITEM_CLASS
GTK_IS_RADIO_MENU_ITEM_CLASS
GTK_RADIO_MENU_ITEM_GET_CLASS
<SUBSECTION Private>
GtkRadioMenuItemPrivate
gtk_radio_menu_item_get_type
</SECTION>
<SECTION>
<FILE>gtkrange</FILE>
<TITLE>GtkRange</TITLE>
@ -2588,22 +2406,6 @@ gtk_separator_get_type
GtkSeparatorPrivate
</SECTION>
<SECTION>
<FILE>gtkseparatormenuitem</FILE>
<TITLE>GtkSeparatorMenuItem</TITLE>
GtkSeparatorMenuItem
gtk_separator_menu_item_new
<SUBSECTION Standard>
GTK_SEPARATOR_MENU_ITEM
GTK_SEPARATOR_MENU_ITEM_CLASS
GTK_SEPARATOR_MENU_ITEM_GET_CLASS
GTK_IS_SEPARATOR_MENU_ITEM
GTK_IS_SEPARATOR_MENU_ITEM_CLASS
GTK_TYPE_SEPARATOR_MENU_ITEM
<SUBSECTION Private>
gtk_separator_menu_item_get_type
</SECTION>
<SECTION>
<FILE>gtksettings</FILE>
<TITLE>GtkSettings</TITLE>
@ -3278,9 +3080,8 @@ gtk_tool_item_get_orientation
gtk_tool_item_get_toolbar_style
gtk_tool_item_get_text_alignment
gtk_tool_item_get_text_orientation
gtk_tool_item_retrieve_proxy_menu_item
gtk_tool_item_get_proxy_menu_item
gtk_tool_item_set_proxy_menu_item
gtk_tool_item_set_overflow_text
gtk_tool_item_get_overflow_text
gtk_tool_item_rebuild_menu
gtk_tool_item_toolbar_reconfigured
gtk_tool_item_get_text_size_group
@ -3354,8 +3155,8 @@ GtkToolButtonPrivate
<TITLE>GtkMenuToolButton</TITLE>
GtkMenuToolButton
gtk_menu_tool_button_new
gtk_menu_tool_button_set_menu
gtk_menu_tool_button_get_menu
gtk_menu_tool_button_set_popover
gtk_menu_tool_button_get_popover
gtk_menu_tool_button_set_arrow_tooltip_text
gtk_menu_tool_button_set_arrow_tooltip_markup
@ -3898,9 +3699,6 @@ gtk_tree_view_get_search_equal_func
gtk_tree_view_set_search_equal_func
gtk_tree_view_get_search_entry
gtk_tree_view_set_search_entry
GtkTreeViewSearchPositionFunc
gtk_tree_view_get_search_position_func
gtk_tree_view_set_search_position_func
gtk_tree_view_get_fixed_height_mode
gtk_tree_view_set_fixed_height_mode
gtk_tree_view_get_hover_selection

View File

@ -44,7 +44,6 @@ gtk_cell_renderer_text_get_type
gtk_cell_renderer_toggle_get_type
gtk_cell_view_get_type
gtk_check_button_get_type
gtk_check_menu_item_get_type
gtk_color_button_get_type
gtk_color_chooser_get_type
gtk_color_chooser_dialog_get_type
@ -119,11 +118,7 @@ gtk_map_list_model_get_type
gtk_media_controls_get_type
gtk_media_file_get_type
gtk_media_stream_get_type
gtk_menu_bar_get_type
gtk_menu_button_get_type
gtk_menu_get_type
gtk_menu_item_get_type
gtk_menu_shell_get_type
gtk_menu_tool_button_get_type
gtk_message_dialog_get_type
gtk_mount_operation_get_type
@ -152,7 +147,6 @@ gtk_print_settings_get_type
@DISABLE_ON_W32@gtk_print_unix_dialog_get_type
gtk_progress_bar_get_type
gtk_radio_button_get_type
gtk_radio_menu_item_get_type
gtk_radio_tool_button_get_type
gtk_range_get_type
gtk_recent_manager_get_type
@ -167,7 +161,6 @@ gtk_search_bar_get_type
gtk_search_entry_get_type
gtk_selection_model_get_type
gtk_separator_get_type
gtk_separator_menu_item_get_type
gtk_separator_tool_item_get_type
gtk_settings_get_type
gtk_shortcut_label_get_type
@ -206,7 +199,6 @@ gtk_tool_button_get_type
gtk_tool_item_get_type
gtk_tree_drag_dest_get_type
gtk_tree_drag_source_get_type
gtk_tree_expander_get_type
gtk_tree_list_model_get_type
gtk_tree_list_row_get_type
gtk_tree_model_filter_get_type

View File

@ -1,4 +1,6 @@
private_headers = [
'imm-extra.h',
'gtkbitmaskprivateimpl.h',
'gdkpixbufutilsprivate.h',
'gtkaccelgroupprivate.h',
'gtkaccelmapprivate.h',
@ -15,7 +17,6 @@ private_headers = [
'gtkbuttonprivate.h',
'gtkcellareaboxcontextprivate.h',
'gtkcheckbuttonprivate.h',
'gtkcheckmenuitemprivate.h',
'gtkcolorchooserprivate.h',
'gtkcoloreditorprivate.h',
'gtkcolorplaneprivate.h',
@ -35,6 +36,7 @@ private_headers = [
'gtkcssarrayvalueprivate.h',
'gtkcssbgsizevalueprivate.h',
'gtkcssbordervalueprivate.h',
'gtkcssboxesprivate.h',
'gtkcsscalcvalueprivate.h',
'gtkcsscolorvalueprivate.h',
'gtkcsscornervalueprivate.h',
@ -135,9 +137,6 @@ private_headers = [
'gtkmagnifierprivate.h',
'gtkmediafileprivate.h',
'gtkmenubuttonprivate.h',
'gtkmenuitemprivate.h',
'gtkmenuprivate.h',
'gtkmenushellprivate.h',
'gtkmodulesprivate.h',
'gtkmountoperationprivate.h',
'gtknativedialogprivate.h',

View File

@ -305,6 +305,18 @@
</para>
</section>
<section>
<title>Stop using grabs</title>
<para>
GTK 4 no longer provides the gdk_device_grab() or gdk_seat_grab() apis.
</para>
<para>
If you need to dismiss a popup when the user clicks outside (a common
use for grabs), you can use the GdkSurface #GdkSurface:autohide property instead.
GtkPopover also has a #GtkPopover:autohide property.
</para>
</section>
<section>
<title>Adapt to coordinate API changes</title>
<para>
@ -673,7 +685,7 @@
<section>
<title>Adapt to changes in the API of GtkEntry, GtkSearchEntry and GtkSpinButton</title>
<para>
The GtkEditable has been made more useful, and the core functionality of
The GtkEditable interface has been made more useful, and the core functionality of
GtkEntry has been broken out as a GtkText widget. GtkEntry, GtkSearchEntry,
GtkSpinButton and the new GtkPasswordEntry now use a GtkText widget internally
and implement GtkEditable. In particular, this means that it is no longer
@ -851,6 +863,36 @@
</para>
</section>
<section>
<title>GtkMenu, GtkMenuBar and GtkMenuItem are gone</title>
<para>
These widgets were heavily relying on X11-centric concepts such as
override-redirect windows and grabs, and were hard to adjust to other
windowing systems.
</para>
<para>
Menus can already be replaced using GtkPopoverMenu in GTK 3. Additionally,
GTK 4 introduces GtkPopoverMenuBar to replace menubars. These new widgets
can only be constructed from menu models, so the porting effort involves
switching to menu models and actions.
</para>
<para>
Since menus are gone, GtkMenuButton and GtkMenuToolButton also lost their
ability to show menus, and need to be used with popovers in GTK 4.
</para>
</section>
<section>
<title>GtkToolbar overflow handling has changed</title>
<para>
The handling of overflow in toolbars has been simplified.
Instead of creating a proxy menuitem and setting it with
gtk_tool_item_set_proxy_menu_item(), you simply provide
a label for the overflow menu with gtk_tool_item_set_overflow_text().
GTK will figure out itself whether to create a check- or
radioitem as proxy.
</para>
</section>
</section>
</chapter>

View File

@ -162,9 +162,6 @@
<link linkend="GtkPaned">
<inlinegraphic fileref="panes.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkMenuBar">
<inlinegraphic fileref="menubar.png" format="PNG"></inlinegraphic>
</link>
<link linkend="GtkToolbar">
<inlinegraphic fileref="toolbar.png" format="PNG"></inlinegraphic>
</link>

View File

@ -152,8 +152,8 @@ create_menu_button (void)
image = gtk_image_new ();
gtk_image_set_from_icon_name (GTK_IMAGE (image), "emblem-system-symbolic");
gtk_container_add (GTK_CONTAINER (widget), image);
menu = gtk_menu_new ();
gtk_menu_button_set_popup (GTK_MENU_BUTTON (widget), menu);
menu = gtk_popover_new (NULL);
gtk_menu_button_set_popover (GTK_MENU_BUTTON (widget), menu);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
gtk_container_add (GTK_CONTAINER (vbox), widget);
@ -800,32 +800,6 @@ create_toolbar (void)
return new_widget_info ("toolbar", widget, SMALL);
}
static WidgetInfo *
create_menubar (void)
{
GtkWidget *widget, *vbox, *item;
widget = gtk_menu_bar_new ();
item = gtk_menu_item_new_with_mnemonic ("_File");
gtk_menu_shell_append (GTK_MENU_SHELL (widget), item);
item = gtk_menu_item_new_with_mnemonic ("_Edit");
gtk_menu_shell_append (GTK_MENU_SHELL (widget), item);
item = gtk_menu_item_new_with_mnemonic ("_Help");
gtk_menu_shell_append (GTK_MENU_SHELL (widget), item);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_container_add (GTK_CONTAINER (vbox), widget);
gtk_container_add (GTK_CONTAINER (vbox),
gtk_label_new ("Menu Bar"));
return new_widget_info ("menubar", vbox, SMALL);
}
static WidgetInfo *
create_message_dialog (void)
{
@ -1438,7 +1412,6 @@ get_all_widgets (void)
retval = g_list_prepend (retval, create_image ());
retval = g_list_prepend (retval, create_label ());
retval = g_list_prepend (retval, create_link_button ());
retval = g_list_prepend (retval, create_menubar ());
retval = g_list_prepend (retval, create_message_dialog ());
retval = g_list_prepend (retval, create_notebook ());
retval = g_list_prepend (retval, create_panes ());

View File

@ -266,6 +266,16 @@ void gdk_surface_get_geometry (GdkSurface *surface,
GdkGLContext *gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
GdkGrabStatus gdk_seat_grab (GdkSeat *seat,
GdkSurface *surface,
GdkSeatCapabilities capabilities,
gboolean owner_events,
GdkCursor *cursor,
const GdkEvent *event,
GdkSeatGrabPrepareFunc prepare_func,
gpointer prepare_func_data);
void gdk_seat_ungrab (GdkSeat *seat);
G_END_DECLS
#endif /* __GDK_INTERNALS_H__ */

View File

@ -25,6 +25,7 @@
#include "gdkseatprivate.h"
#include "gdkdeviceprivate.h"
#include "gdkintl.h"
#include "gdkinternals.h"
/**
* SECTION:gdkseat

View File

@ -82,18 +82,6 @@ struct _GdkSeat
GDK_AVAILABLE_IN_ALL
GType gdk_seat_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GdkGrabStatus gdk_seat_grab (GdkSeat *seat,
GdkSurface *surface,
GdkSeatCapabilities capabilities,
gboolean owner_events,
GdkCursor *cursor,
const GdkEvent *event,
GdkSeatGrabPrepareFunc prepare_func,
gpointer prepare_func_data);
GDK_AVAILABLE_IN_ALL
void gdk_seat_ungrab (GdkSeat *seat);
GDK_AVAILABLE_IN_ALL
GdkDisplay * gdk_seat_get_display (GdkSeat *seat);

View File

@ -25,7 +25,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkBooleanCellAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkButtonAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellAccessibleParent, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCheckMenuItemAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkComboBoxAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkContainerAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkContainerCellAccessible, g_object_unref)
@ -43,17 +42,13 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLinkButtonAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkListBoxAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkListBoxRowAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLockButtonAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuButtonAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuItemAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuShellAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkNotebookAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkNotebookPageAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPanedAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPopoverAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkProgressBarAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioButtonAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioMenuItemAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRangeAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRendererCellAccessible, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkScaleAccessible, g_object_unref)

View File

@ -1,128 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2002 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "gtkcheckmenuitemaccessible.h"
G_DEFINE_TYPE (GtkCheckMenuItemAccessible, gtk_check_menu_item_accessible, GTK_TYPE_MENU_ITEM_ACCESSIBLE)
static void
toggled_cb (GtkWidget *widget)
{
AtkObject *accessible;
GtkCheckMenuItem *check_menu_item;
gboolean active;
check_menu_item = GTK_CHECK_MENU_ITEM (widget);
active = gtk_check_menu_item_get_active (check_menu_item);
accessible = gtk_widget_get_accessible (widget);
atk_object_notify_state_change (accessible, ATK_STATE_CHECKED, active);
}
static void
gtk_check_menu_item_accessible_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (gtk_check_menu_item_accessible_parent_class)->initialize (obj, data);
g_signal_connect (data, "toggled", G_CALLBACK (toggled_cb), NULL);
obj->role = ATK_ROLE_CHECK_MENU_ITEM;
}
static AtkStateSet *
gtk_check_menu_item_accessible_ref_state_set (AtkObject *accessible)
{
AtkStateSet *state_set;
GtkCheckMenuItem *check_menu_item;
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
if (widget == NULL)
return NULL;
state_set = ATK_OBJECT_CLASS (gtk_check_menu_item_accessible_parent_class)->ref_state_set (accessible);
check_menu_item = GTK_CHECK_MENU_ITEM (widget);
if (gtk_check_menu_item_get_active (check_menu_item))
atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
if (gtk_check_menu_item_get_inconsistent (check_menu_item))
{
atk_state_set_remove_state (state_set, ATK_STATE_ENABLED);
atk_state_set_add_state (state_set, ATK_STATE_INDETERMINATE);
}
return state_set;
}
static void
gtk_check_menu_item_accessible_notify_gtk (GObject *obj,
GParamSpec *pspec)
{
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (obj);
AtkObject *atk_obj;
gboolean sensitive;
gboolean inconsistent;
gboolean active;
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (check_menu_item));
sensitive = gtk_widget_get_sensitive (GTK_WIDGET (check_menu_item));
inconsistent = gtk_check_menu_item_get_inconsistent (check_menu_item);
active = gtk_check_menu_item_get_active (check_menu_item);
if (strcmp (pspec->name, "inconsistent") == 0)
{
atk_object_notify_state_change (atk_obj, ATK_STATE_INDETERMINATE, inconsistent);
atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
}
else if (strcmp (pspec->name, "sensitive") == 0)
{
/* Need to override gailwidget behavior of notifying for ENABLED */
atk_object_notify_state_change (atk_obj, ATK_STATE_SENSITIVE, sensitive);
atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent));
}
else if (strcmp (pspec->name, "active") == 0)
{
atk_object_notify_state_change (atk_obj, ATK_STATE_CHECKED, active);
}
else
GTK_WIDGET_ACCESSIBLE_CLASS (gtk_check_menu_item_accessible_parent_class)->notify_gtk (obj, pspec);
}
static void
gtk_check_menu_item_accessible_class_init (GtkCheckMenuItemAccessibleClass *klass)
{
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
widget_class->notify_gtk = gtk_check_menu_item_accessible_notify_gtk;
class->ref_state_set = gtk_check_menu_item_accessible_ref_state_set;
class->initialize = gtk_check_menu_item_accessible_initialize;
}
static void
gtk_check_menu_item_accessible_init (GtkCheckMenuItemAccessible *item)
{
}

View File

@ -1,57 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2002 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_CHECK_MENU_ITEM_ACCESSIBLE_H__
#define __GTK_CHECK_MENU_ITEM_ACCESSIBLE_H__
#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk-a11y.h> can be included directly."
#endif
#include <gtk/a11y/gtkmenuitemaccessible.h>
G_BEGIN_DECLS
#define GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE (gtk_check_menu_item_accessible_get_type ())
#define GTK_CHECK_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE, GtkCheckMenuItemAccessible))
#define GTK_CHECK_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE, GtkCheckMenuItemAccessibleClass))
#define GTK_IS_CHECK_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE))
#define GTK_IS_CHECK_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE))
#define GTK_CHECK_MENU_ITEM_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE, GtkCheckMenuItemAccessibleClass))
typedef struct _GtkCheckMenuItemAccessible GtkCheckMenuItemAccessible;
typedef struct _GtkCheckMenuItemAccessibleClass GtkCheckMenuItemAccessibleClass;
typedef struct _GtkCheckMenuItemAccessiblePrivate GtkCheckMenuItemAccessiblePrivate;
struct _GtkCheckMenuItemAccessible
{
GtkMenuItemAccessible parent;
GtkCheckMenuItemAccessiblePrivate *priv;
};
struct _GtkCheckMenuItemAccessibleClass
{
GtkMenuItemAccessibleClass parent_class;
};
GDK_AVAILABLE_IN_ALL
GType gtk_check_menu_item_accessible_get_type (void);
G_END_DECLS
#endif /* __GTK_CHECK_MENU_ITEM_ACCESSIBLE_H__ */

View File

@ -1,99 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkmenuaccessible.h"
#include "gtkwidgetaccessibleprivate.h"
#include <gtk/gtk.h>
G_DEFINE_TYPE (GtkMenuAccessible, gtk_menu_accessible, GTK_TYPE_MENU_SHELL_ACCESSIBLE)
static void
gtk_menu_accessible_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (gtk_menu_accessible_parent_class)->initialize (obj, data);
obj->role = ATK_ROLE_MENU;
_gtk_widget_accessible_set_layer (GTK_WIDGET_ACCESSIBLE (obj), ATK_LAYER_POPUP);
}
static AtkObject *
gtk_menu_accessible_get_parent (AtkObject *accessible)
{
AtkObject *parent;
GtkWidget *widget, *parent_widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
if (widget == NULL)
return NULL;
parent = accessible->accessible_parent;
if (parent != NULL)
return parent;
/* If the menu is attached to a menu item or a button (Gnome Menu)
* report the menu item as parent.
*/
parent_widget = gtk_menu_get_attach_widget (GTK_MENU (widget));
if (!GTK_IS_MENU_ITEM (parent_widget) &&
!GTK_IS_BUTTON (parent_widget) &&
!GTK_IS_COMBO_BOX (parent_widget))
parent_widget = gtk_widget_get_parent (widget);
if (parent_widget == NULL)
return NULL;
parent = gtk_widget_get_accessible (parent_widget);
atk_object_set_parent (accessible, parent);
return parent;
}
static gint
gtk_menu_accessible_get_index_in_parent (AtkObject *accessible)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
if (widget == NULL)
return -1;
if (gtk_menu_get_attach_widget (GTK_MENU (widget)))
return 0;
return ATK_OBJECT_CLASS (gtk_menu_accessible_parent_class)->get_index_in_parent (accessible);
}
static void
gtk_menu_accessible_class_init (GtkMenuAccessibleClass *klass)
{
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->get_parent = gtk_menu_accessible_get_parent;
class->get_index_in_parent = gtk_menu_accessible_get_index_in_parent;
class->initialize = gtk_menu_accessible_initialize;
}
static void
gtk_menu_accessible_init (GtkMenuAccessible *accessible)
{
}

View File

@ -1,57 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2001 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_MENU_ACCESSIBLE_H__
#define __GTK_MENU_ACCESSIBLE_H__
#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk-a11y.h> can be included directly."
#endif
#include <gtk/a11y/gtkmenushellaccessible.h>
G_BEGIN_DECLS
#define GTK_TYPE_MENU_ACCESSIBLE (gtk_menu_accessible_get_type ())
#define GTK_MENU_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ACCESSIBLE, GtkMenuAccessible))
#define GTK_MENU_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_ACCESSIBLE, GtkMenuAccessibleClass))
#define GTK_IS_MENU_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_ACCESSIBLE))
#define GTK_IS_MENU_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_ACCESSIBLE))
#define GTK_MENU_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_ACCESSIBLE, GtkMenuAccessibleClass))
typedef struct _GtkMenuAccessible GtkMenuAccessible;
typedef struct _GtkMenuAccessibleClass GtkMenuAccessibleClass;
typedef struct _GtkMenuAccessiblePrivate GtkMenuAccessiblePrivate;
struct _GtkMenuAccessible
{
GtkMenuShellAccessible parent;
GtkMenuAccessiblePrivate *priv;
};
struct _GtkMenuAccessibleClass
{
GtkMenuShellAccessibleClass parent_class;
};
GDK_AVAILABLE_IN_ALL
GType gtk_menu_accessible_get_type (void);
G_END_DECLS
#endif /* __GTK_MENU_ACCESSIBLE_H__ */

View File

@ -37,22 +37,12 @@ static gint
gtk_menu_button_accessible_get_n_children (AtkObject* obj)
{
GtkWidget *widget;
GtkWidget *submenu;
gint count = 0;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return count;
submenu = GTK_WIDGET (gtk_menu_button_get_popup (GTK_MENU_BUTTON (widget)));
if (submenu)
{
GList *children;
children = gtk_container_get_children (GTK_CONTAINER (submenu));
count = g_list_length (children);
g_list_free (children);
}
return count;
}
@ -62,28 +52,11 @@ gtk_menu_button_accessible_ref_child (AtkObject *obj,
{
AtkObject *accessible = NULL;
GtkWidget *widget;
GtkWidget *submenu;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return NULL;
submenu = GTK_WIDGET (gtk_menu_button_get_popup (GTK_MENU_BUTTON (widget)));
if (submenu)
{
GList *children;
GList *tmp_list;
children = gtk_container_get_children (GTK_CONTAINER (submenu));
tmp_list = g_list_nth (children, i);
if (tmp_list)
{
accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
g_object_ref (accessible);
}
g_list_free (children);
}
return accessible;
}

View File

@ -1,926 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2001, 2002, 2003 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <glib/gi18n-lib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "gtkmenuitemaccessible.h"
#include "gtkwidgetaccessibleprivate.h"
#include "gtk/gtkmenuitemprivate.h"
struct _GtkMenuItemAccessiblePrivate
{
gchar *text;
gboolean selected;
};
#define KEYBINDING_SEPARATOR ";"
static void menu_item_select (GtkMenuItem *item);
static void menu_item_deselect (GtkMenuItem *item);
static GtkWidget *get_label_from_container (GtkWidget *container);
static gchar *get_text_from_label_widget (GtkWidget *widget);
static gint menu_item_insert_gtk (GtkMenuShell *shell,
GtkWidget *widget,
gint position);
static gint menu_item_remove_gtk (GtkContainer *container,
GtkWidget *widget);
static void atk_action_interface_init (AtkActionIface *iface);
static void atk_selection_interface_init (AtkSelectionIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkMenuItemAccessible, gtk_menu_item_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
G_ADD_PRIVATE (GtkMenuItemAccessible)
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init);
G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
static void
gtk_menu_item_accessible_initialize (AtkObject *obj,
gpointer data)
{
GtkWidget *widget;
GtkWidget *parent;
GtkWidget *menu;
ATK_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->initialize (obj, data);
g_signal_connect (data, "select", G_CALLBACK (menu_item_select), NULL);
g_signal_connect (data, "deselect", G_CALLBACK (menu_item_deselect), NULL);
widget = GTK_WIDGET (data);
if ((gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_PRELIGHT) != 0)
GTK_MENU_ITEM_ACCESSIBLE (obj)->priv->selected = TRUE;
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU (parent))
{
GtkWidget *parent_widget;
parent_widget = gtk_menu_get_attach_widget (GTK_MENU (parent));
if (!GTK_IS_MENU_ITEM (parent_widget))
parent_widget = gtk_widget_get_parent (widget);
if (parent_widget)
atk_object_set_parent (obj, gtk_widget_get_accessible (parent_widget));
}
_gtk_widget_accessible_set_layer (GTK_WIDGET_ACCESSIBLE (obj), ATK_LAYER_POPUP);
obj->role = ATK_ROLE_MENU_ITEM;
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (data));
if (menu)
{
g_signal_connect (menu, "insert", G_CALLBACK (menu_item_insert_gtk), NULL);
g_signal_connect (menu, "remove", G_CALLBACK (menu_item_remove_gtk), NULL);
}
}
static gint
gtk_menu_item_accessible_get_n_children (AtkObject *obj)
{
GtkWidget *widget;
GtkWidget *submenu;
gint count = 0;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return count;
submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
if (submenu)
{
GList *children;
children = gtk_container_get_children (GTK_CONTAINER (submenu));
count = g_list_length (children);
g_list_free (children);
}
return count;
}
static AtkObject *
gtk_menu_item_accessible_ref_child (AtkObject *obj,
gint i)
{
AtkObject *accessible;
GtkWidget *widget;
GtkWidget *submenu;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return NULL;
accessible = NULL;
submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
if (submenu)
{
GList *children;
GList *tmp_list;
children = gtk_container_get_children (GTK_CONTAINER (submenu));
tmp_list = g_list_nth (children, i);
if (tmp_list)
{
accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
g_object_ref (accessible);
}
g_list_free (children);
}
return accessible;
}
static AtkStateSet *
gtk_menu_item_accessible_ref_state_set (AtkObject *obj)
{
AtkObject *menu_item;
AtkStateSet *state_set, *parent_state_set;
state_set = ATK_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->ref_state_set (obj);
atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE);
if (GTK_MENU_ITEM_ACCESSIBLE (obj)->priv->selected)
atk_state_set_add_state (state_set, ATK_STATE_SELECTED);
menu_item = atk_object_get_parent (obj);
if (menu_item)
{
if (!GTK_IS_MENU_ITEM (gtk_accessible_get_widget (GTK_ACCESSIBLE (menu_item))))
return state_set;
parent_state_set = atk_object_ref_state_set (menu_item);
if (!atk_state_set_contains_state (parent_state_set, ATK_STATE_SELECTED))
{
atk_state_set_remove_state (state_set, ATK_STATE_FOCUSED);
atk_state_set_remove_state (state_set, ATK_STATE_SHOWING);
}
g_object_unref (parent_state_set);
}
return state_set;
}
static AtkRole
gtk_menu_item_accessible_get_role (AtkObject *obj)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget != NULL &&
gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)))
return ATK_ROLE_MENU;
return ATK_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->get_role (obj);
}
static const gchar *
gtk_menu_item_accessible_get_name (AtkObject *obj)
{
const gchar *name;
GtkWidget *widget;
GtkWidget *label;
GtkMenuItemAccessible *accessible;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return NULL;
name = ATK_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->get_name (obj);
if (name)
return name;
accessible = GTK_MENU_ITEM_ACCESSIBLE (obj);
label = get_label_from_container (widget);
g_free (accessible->priv->text);
accessible->priv->text = get_text_from_label_widget (label);
return accessible->priv->text;
}
static void
gtk_menu_item_accessible_finalize (GObject *object)
{
GtkMenuItemAccessible *accessible = GTK_MENU_ITEM_ACCESSIBLE (object);
g_free (accessible->priv->text);
G_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->finalize (object);
}
static void
gtk_menu_item_accessible_notify_gtk (GObject *obj,
GParamSpec *pspec)
{
AtkObject* atk_obj;
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
if (strcmp (pspec->name, "label") == 0)
{
if (atk_obj->name == NULL)
g_object_notify (G_OBJECT (atk_obj), "accessible-name");
g_signal_emit_by_name (atk_obj, "visible-data-changed");
}
else
GTK_WIDGET_ACCESSIBLE_CLASS (gtk_menu_item_accessible_parent_class)->notify_gtk (obj, pspec);
}
static void
gtk_menu_item_accessible_class_init (GtkMenuItemAccessibleClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
widget_class->notify_gtk = gtk_menu_item_accessible_notify_gtk;
gobject_class->finalize = gtk_menu_item_accessible_finalize;
class->get_n_children = gtk_menu_item_accessible_get_n_children;
class->ref_child = gtk_menu_item_accessible_ref_child;
class->ref_state_set = gtk_menu_item_accessible_ref_state_set;
class->initialize = gtk_menu_item_accessible_initialize;
class->get_name = gtk_menu_item_accessible_get_name;
class->get_role = gtk_menu_item_accessible_get_role;
}
static void
gtk_menu_item_accessible_init (GtkMenuItemAccessible *menu_item)
{
menu_item->priv = gtk_menu_item_accessible_get_instance_private (menu_item);
}
static GtkWidget *
get_label_from_container (GtkWidget *container)
{
GtkWidget *label;
GList *children, *tmp_list;
if (!GTK_IS_CONTAINER (container))
return NULL;
children = gtk_container_get_children (GTK_CONTAINER (container));
label = NULL;
for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
{
if (GTK_IS_LABEL (tmp_list->data))
{
label = tmp_list->data;
break;
}
else if (GTK_IS_CELL_VIEW (tmp_list->data))
{
label = tmp_list->data;
break;
}
else if (GTK_IS_BOX (tmp_list->data))
{
label = get_label_from_container (GTK_WIDGET (tmp_list->data));
if (label)
break;
}
}
g_list_free (children);
return label;
}
static gchar *
get_text_from_label_widget (GtkWidget *label)
{
if (GTK_IS_LABEL (label))
return g_strdup (gtk_label_get_text (GTK_LABEL (label)));
else if (GTK_IS_CELL_VIEW (label))
{
GList *cells, *l;
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreePath *path;
GtkCellArea *area;
gchar *text;
model = gtk_cell_view_get_model (GTK_CELL_VIEW (label));
path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (label));
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_path_free (path);
area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (label));
gtk_cell_area_apply_attributes (area, model, &iter, FALSE, FALSE);
cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (label));
text = NULL;
for (l = cells; l; l = l->next)
{
GtkCellRenderer *cell = l->data;
if (GTK_IS_CELL_RENDERER_TEXT (cell))
{
g_object_get (cell, "text", &text, NULL);
break;
}
}
g_list_free (cells);
return text;
}
return NULL;
}
static void
ensure_menus_unposted (GtkMenuItemAccessible *menu_item)
{
AtkObject *parent;
GtkWidget *widget;
parent = atk_object_get_parent (ATK_OBJECT (menu_item));
while (parent)
{
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));
if (GTK_IS_MENU (widget))
{
if (gtk_widget_get_mapped (widget))
gtk_menu_shell_cancel (GTK_MENU_SHELL (widget));
return;
}
parent = atk_object_get_parent (parent);
}
}
static gboolean
gtk_menu_item_accessible_do_action (AtkAction *action,
gint i)
{
GtkWidget *item, *item_parent;
gboolean item_mapped;
item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
if (item == NULL)
return FALSE;
if (i != 0)
return FALSE;
if (!gtk_widget_get_sensitive (item) || !gtk_widget_get_visible (item))
return FALSE;
item_parent = gtk_widget_get_parent (item);
if (!GTK_IS_MENU_SHELL (item_parent))
return FALSE;
gtk_menu_shell_select_item (GTK_MENU_SHELL (item_parent), item);
item_mapped = gtk_widget_get_mapped (item);
/* This is what is called when <Return> is pressed for a menu item.
* The last argument means 'force hide'.
*/
g_signal_emit_by_name (item_parent, "activate-current", 1);
if (!item_mapped)
ensure_menus_unposted (GTK_MENU_ITEM_ACCESSIBLE (action));
return TRUE;
}
static gint
gtk_menu_item_accessible_get_n_actions (AtkAction *action)
{
GtkWidget *item;
item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
if (item == NULL)
return 0;
if (!_gtk_menu_item_is_selectable (item))
return 0;
return 1;
}
static const gchar *
gtk_menu_item_accessible_action_get_name (AtkAction *action,
gint i)
{
if (i == 0 && gtk_menu_item_accessible_get_n_actions (action) > 0)
return "click";
return NULL;
}
static const gchar *
gtk_menu_item_accessible_action_get_localized_name (AtkAction *action,
gint i)
{
if (i == 0 && gtk_menu_item_accessible_get_n_actions (action) > 0)
return C_("Action name", "Click");
return NULL;
}
static const gchar *
gtk_menu_item_accessible_action_get_description (AtkAction *action,
gint i)
{
if (i == 0 && gtk_menu_item_accessible_get_n_actions (action) > 0)
return C_("Action description", "Clicks the menuitem");
return NULL;
}
static gboolean
find_accel_by_widget (GtkAccelKey *key,
GClosure *closure,
gpointer data)
{
/* We assume that closure->data points to the widget
* pending gtk_widget_get_accel_closures being made public
*/
return data == (gpointer) closure->data;
}
static gboolean
find_accel_by_closure (GtkAccelKey *key,
GClosure *closure,
gpointer data)
{
return data == (gpointer) closure;
}
static GtkWidget *
find_item_label (GtkWidget *item)
{
GtkWidget *child;
child = gtk_bin_get_child (GTK_BIN (item));
if (GTK_IS_CONTAINER (child))
{
GList *children, *l;
children = gtk_container_get_children (GTK_CONTAINER (child));
for (l = children; l; l = l->next)
{
if (GTK_IS_LABEL (l->data))
{
child = l->data;
break;
}
}
g_list_free (children);
}
if (GTK_IS_LABEL (child))
return child;
return NULL;
}
/* This function returns a string of the form A;B;C where A is
* the keybinding for the widget; B is the keybinding to traverse
* from the menubar and C is the accelerator. The items in the
* keybinding to traverse from the menubar are separated by :.
*/
static const gchar *
gtk_menu_item_accessible_get_keybinding (AtkAction *action,
gint i)
{
gchar *keybinding = NULL;
gchar *item_keybinding = NULL;
gchar *full_keybinding = NULL;
gchar *accelerator = NULL;
GtkWidget *item;
GtkWidget *temp_item;
GtkWidget *child;
GtkWidget *parent;
item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
if (item == NULL)
return NULL;
if (i != 0)
return NULL;
temp_item = item;
while (TRUE)
{
GdkModifierType mnemonic_modifier = 0;
guint key_val;
gchar *key, *temp_keybinding;
if (gtk_bin_get_child (GTK_BIN (temp_item)) == NULL)
return NULL;
parent = gtk_widget_get_ancestor (temp_item, GTK_TYPE_MENU_SHELL);
if (!parent)
/* parent can be NULL when activating a window from the panel */
return NULL;
if (GTK_IS_MENU_BAR (parent))
{
GtkRoot *root;
root = gtk_widget_get_root (parent);
if (root && GTK_IS_WINDOW (root))
mnemonic_modifier = gtk_window_get_mnemonic_modifier (GTK_WINDOW (root));
}
child = find_item_label (temp_item);
if (GTK_IS_LABEL (child))
{
key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (child));
if (key_val != GDK_KEY_VoidSymbol)
{
key = gtk_accelerator_name (key_val, mnemonic_modifier);
if (full_keybinding)
temp_keybinding = g_strconcat (key, ":", full_keybinding, NULL);
else
temp_keybinding = g_strdup (key);
if (temp_item == item)
item_keybinding = g_strdup (key);
g_free (key);
g_free (full_keybinding);
full_keybinding = temp_keybinding;
}
else
{
/* No keybinding */
g_free (full_keybinding);
full_keybinding = NULL;
break;
}
}
/* We have reached the menu bar so we are finished */
if (GTK_IS_MENU_BAR (parent))
break;
g_return_val_if_fail (GTK_IS_MENU (parent), NULL);
temp_item = gtk_menu_get_attach_widget (GTK_MENU (parent));
if (!GTK_IS_MENU_ITEM (temp_item))
{
/* Menu is attached to something other than a menu item;
* probably an option menu
*/
g_free (full_keybinding);
full_keybinding = NULL;
break;
}
}
parent = gtk_widget_get_ancestor (item, GTK_TYPE_MENU_SHELL);
if (GTK_IS_MENU (parent))
{
child = find_item_label (item);
if (GTK_IS_ACCEL_LABEL (child))
{
guint accel_key;
GdkModifierType accel_mods;
gtk_accel_label_get_accel (GTK_ACCEL_LABEL (child), &accel_key, &accel_mods);
if (accel_key)
accelerator = gtk_accelerator_name (accel_key, accel_mods);
}
if (!accelerator)
{
GtkAccelGroup *group;
GtkAccelKey *key = NULL;
group = gtk_menu_get_accel_group (GTK_MENU (parent));
if (group)
key = gtk_accel_group_find (group, find_accel_by_widget, item);
else if (GTK_IS_ACCEL_LABEL (child))
{
GtkAccelLabel *accel_label;
GClosure *accel_closure;
accel_label = GTK_ACCEL_LABEL (child);
g_object_get (accel_label, "accel-closure", &accel_closure, NULL);
if (accel_closure)
{
key = gtk_accel_group_find (gtk_accel_group_from_accel_closure (accel_closure),
find_accel_by_closure,
accel_closure);
g_closure_unref (accel_closure);
}
}
if (key)
accelerator = gtk_accelerator_name (key->accel_key, key->accel_mods);
}
}
/* Concatenate the bindings */
if (item_keybinding || full_keybinding || accelerator)
{
gchar *temp;
if (item_keybinding)
{
keybinding = g_strconcat (item_keybinding, KEYBINDING_SEPARATOR, NULL);
g_free (item_keybinding);
}
else
keybinding = g_strdup (KEYBINDING_SEPARATOR);
if (full_keybinding)
{
temp = g_strconcat (keybinding, full_keybinding,
KEYBINDING_SEPARATOR, NULL);
g_free (full_keybinding);
}
else
temp = g_strconcat (keybinding, KEYBINDING_SEPARATOR, NULL);
g_free (keybinding);
keybinding = temp;
if (accelerator)
{
temp = g_strconcat (keybinding, accelerator, NULL);
g_free (accelerator);
g_free (keybinding);
keybinding = temp;
}
}
return keybinding;
}
static void
atk_action_interface_init (AtkActionIface *iface)
{
iface->do_action = gtk_menu_item_accessible_do_action;
iface->get_n_actions = gtk_menu_item_accessible_get_n_actions;
iface->get_name = gtk_menu_item_accessible_action_get_name;
iface->get_localized_name = gtk_menu_item_accessible_action_get_localized_name;
iface->get_description = gtk_menu_item_accessible_action_get_description;
iface->get_keybinding = gtk_menu_item_accessible_get_keybinding;
}
static void
menu_item_selection (GtkMenuItem *item,
gboolean selected)
{
AtkObject *obj, *parent;
gint i;
obj = gtk_widget_get_accessible (GTK_WIDGET (item));
GTK_MENU_ITEM_ACCESSIBLE (obj)->priv->selected = selected;
atk_object_notify_state_change (obj, ATK_STATE_SELECTED, selected);
for (i = 0; i < atk_object_get_n_accessible_children (obj); i++)
{
AtkObject *child;
child = atk_object_ref_accessible_child (obj, i);
atk_object_notify_state_change (child, ATK_STATE_SHOWING, selected);
g_object_unref (child);
}
parent = atk_object_get_parent (obj);
g_signal_emit_by_name (parent, "selection-changed");
}
static gboolean
gtk_menu_item_accessible_add_selection (AtkSelection *selection,
gint i)
{
GtkMenuShell *shell;
GList *kids;
guint length;
GtkWidget *widget;
GtkWidget *menu;
GtkWidget *child;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
if (menu == NULL)
return FALSE;
shell = GTK_MENU_SHELL (menu);
kids = gtk_container_get_children (GTK_CONTAINER (shell));
length = g_list_length (kids);
if (i < 0 || i > length)
{
g_list_free (kids);
return FALSE;
}
child = g_list_nth_data (kids, i);
g_list_free (kids);
g_return_val_if_fail (GTK_IS_MENU_ITEM (child), FALSE);
gtk_menu_shell_select_item (shell, GTK_WIDGET (child));
return TRUE;
}
static gboolean
gtk_menu_item_accessible_clear_selection (AtkSelection *selection)
{
GtkWidget *widget;
GtkWidget *menu;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
if (menu == NULL)
return FALSE;
gtk_menu_shell_deselect (GTK_MENU_SHELL (menu));
return TRUE;
}
static AtkObject *
gtk_menu_item_accessible_ref_selection (AtkSelection *selection,
gint i)
{
GtkMenuShell *shell;
AtkObject *obj;
GtkWidget *widget;
GtkWidget *menu;
GtkWidget *item;
if (i != 0)
return NULL;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return NULL;
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
if (menu == NULL)
return NULL;
shell = GTK_MENU_SHELL (menu);
item = gtk_menu_shell_get_selected_item (shell);
if (item != NULL)
{
obj = gtk_widget_get_accessible (item);
g_object_ref (obj);
return obj;
}
return NULL;
}
static gint
gtk_menu_item_accessible_get_selection_count (AtkSelection *selection)
{
GtkMenuShell *shell;
GtkWidget *widget;
GtkWidget *menu;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return 0;
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
if (menu == NULL)
return 0;
shell = GTK_MENU_SHELL (menu);
if (gtk_menu_shell_get_selected_item (shell) != NULL)
return 1;
return 0;
}
static gboolean
gtk_menu_item_accessible_is_child_selected (AtkSelection *selection,
gint i)
{
GtkMenuShell *shell;
gint j;
GtkWidget *widget;
GtkWidget *menu;
GtkWidget *item;
GList *kids;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
if (menu == NULL)
return FALSE;
shell = GTK_MENU_SHELL (menu);
item = gtk_menu_shell_get_selected_item (shell);
if (item == NULL)
return FALSE;
kids = gtk_container_get_children (GTK_CONTAINER (shell));
j = g_list_index (kids, item);
g_list_free (kids);
return j==i;
}
static gboolean
gtk_menu_item_accessible_remove_selection (AtkSelection *selection,
gint i)
{
GtkMenuShell *shell;
GtkWidget *widget;
GtkWidget *menu;
GtkWidget *item;
if (i != 0)
return FALSE;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
if (menu == NULL)
return FALSE;
shell = GTK_MENU_SHELL (menu);
item = gtk_menu_shell_get_selected_item (shell);
if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)))
gtk_menu_shell_deselect (shell);
return TRUE;
}
static void
atk_selection_interface_init (AtkSelectionIface *iface)
{
iface->add_selection = gtk_menu_item_accessible_add_selection;
iface->clear_selection = gtk_menu_item_accessible_clear_selection;
iface->ref_selection = gtk_menu_item_accessible_ref_selection;
iface->get_selection_count = gtk_menu_item_accessible_get_selection_count;
iface->is_child_selected = gtk_menu_item_accessible_is_child_selected;
iface->remove_selection = gtk_menu_item_accessible_remove_selection;
}
static gint
menu_item_insert_gtk (GtkMenuShell *shell,
GtkWidget *widget,
gint position)
{
GtkWidget *parent_widget;
g_return_val_if_fail (GTK_IS_MENU (shell), 1);
parent_widget = gtk_menu_get_attach_widget (GTK_MENU (shell));
if (GTK_IS_MENU_ITEM (parent_widget))
GTK_CONTAINER_ACCESSIBLE_CLASS (gtk_menu_item_accessible_parent_class)->add_gtk (GTK_CONTAINER (shell), widget, gtk_widget_get_accessible (parent_widget));
return 1;
}
static gint
menu_item_remove_gtk (GtkContainer *container,
GtkWidget *widget)
{
GtkWidget *parent_widget;
g_return_val_if_fail (GTK_IS_MENU (container), 1);
parent_widget = gtk_menu_get_attach_widget (GTK_MENU (container));
if (GTK_IS_MENU_ITEM (parent_widget))
{
GTK_CONTAINER_ACCESSIBLE_CLASS (gtk_menu_item_accessible_parent_class)->remove_gtk (container, widget, gtk_widget_get_accessible (parent_widget));
}
return 1;
}
static void
menu_item_select (GtkMenuItem *item)
{
menu_item_selection (item, TRUE);
}
static void
menu_item_deselect (GtkMenuItem *item)
{
menu_item_selection (item, FALSE);
}

View File

@ -1,57 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2001 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_MENU_ITEM_ACCESSIBLE_H__
#define __GTK_MENU_ITEM_ACCESSIBLE_H__
#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk-a11y.h> can be included directly."
#endif
#include <gtk/a11y/gtkcontaineraccessible.h>
G_BEGIN_DECLS
#define GTK_TYPE_MENU_ITEM_ACCESSIBLE (gtk_menu_item_accessible_get_type ())
#define GTK_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ITEM_ACCESSIBLE, GtkMenuItemAccessible))
#define GTK_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_ITEM_ACCESSIBLE, GtkMenuItemAccessibleClass))
#define GTK_IS_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_ITEM_ACCESSIBLE))
#define GTK_IS_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_ITEM_ACCESSIBLE))
#define GTK_MENU_ITEM_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_ITEM_ACCESSIBLE, GtkMenuItemAccessibleClass))
typedef struct _GtkMenuItemAccessible GtkMenuItemAccessible;
typedef struct _GtkMenuItemAccessibleClass GtkMenuItemAccessibleClass;
typedef struct _GtkMenuItemAccessiblePrivate GtkMenuItemAccessiblePrivate;
struct _GtkMenuItemAccessible
{
GtkContainerAccessible parent;
GtkMenuItemAccessiblePrivate *priv;
};
struct _GtkMenuItemAccessibleClass
{
GtkContainerAccessibleClass parent_class;
};
GDK_AVAILABLE_IN_ALL
GType gtk_menu_item_accessible_get_type (void);
G_END_DECLS
#endif /* __GTK_MENU_ITEM_ACCESSIBLE_H__ */

View File

@ -1,199 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2001 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gtkmenushellaccessible.h"
static void atk_selection_interface_init (AtkSelectionIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkMenuShellAccessible, gtk_menu_shell_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init))
static void
gtk_menu_shell_accessible_initialize (AtkObject *accessible,
gpointer data)
{
ATK_OBJECT_CLASS (gtk_menu_shell_accessible_parent_class)->initialize (accessible, data);
accessible->role = ATK_ROLE_UNKNOWN;
}
static void
gtk_menu_shell_accessible_class_init (GtkMenuShellAccessibleClass *klass)
{
AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
atk_object_class->initialize = gtk_menu_shell_accessible_initialize;
}
static void
gtk_menu_shell_accessible_init (GtkMenuShellAccessible *menu_shell)
{
}
static gboolean
gtk_menu_shell_accessible_add_selection (AtkSelection *selection,
gint i)
{
GList *kids;
GtkWidget *item;
guint length;
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
kids = gtk_container_get_children (GTK_CONTAINER (widget));
length = g_list_length (kids);
if (i < 0 || i > length)
{
g_list_free (kids);
return FALSE;
}
item = g_list_nth_data (kids, i);
g_list_free (kids);
g_return_val_if_fail (GTK_IS_MENU_ITEM (item), FALSE);
gtk_menu_shell_select_item (GTK_MENU_SHELL (widget), item);
return TRUE;
}
static gboolean
gtk_menu_shell_accessible_clear_selection (AtkSelection *selection)
{
GtkMenuShell *shell;
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
shell = GTK_MENU_SHELL (widget);
gtk_menu_shell_deselect (shell);
return TRUE;
}
static AtkObject *
gtk_menu_shell_accessible_ref_selection (AtkSelection *selection,
gint i)
{
GtkMenuShell *shell;
AtkObject *obj;
GtkWidget *widget;
GtkWidget *item;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return NULL;
if (i != 0)
return NULL;
shell = GTK_MENU_SHELL (widget);
item = gtk_menu_shell_get_selected_item (shell);
if (item != NULL)
{
obj = gtk_widget_get_accessible (item);
g_object_ref (obj);
return obj;
}
return NULL;
}
static gint
gtk_menu_shell_accessible_get_selection_count (AtkSelection *selection)
{
GtkMenuShell *shell;
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return 0;
shell = GTK_MENU_SHELL (widget);
if (gtk_menu_shell_get_selected_item (shell) != NULL)
return 1;
return 0;
}
static gboolean
gtk_menu_shell_accessible_is_child_selected (AtkSelection *selection,
gint i)
{
GtkMenuShell *shell;
GList *kids;
gint j;
GtkWidget *widget;
GtkWidget *item;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
shell = GTK_MENU_SHELL (widget);
item = gtk_menu_shell_get_selected_item (shell);
if (item == NULL)
return FALSE;
kids = gtk_container_get_children (GTK_CONTAINER (shell));
j = g_list_index (kids, item);
g_list_free (kids);
return j==i;
}
static gboolean
gtk_menu_shell_accessible_remove_selection (AtkSelection *selection,
gint i)
{
GtkMenuShell *shell;
GtkWidget *widget;
GtkWidget *item;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection));
if (widget == NULL)
return FALSE;
if (i != 0)
return FALSE;
shell = GTK_MENU_SHELL (widget);
item = gtk_menu_shell_get_selected_item (shell);
if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item)))
gtk_menu_shell_deselect (shell);
return TRUE;
}
static void
atk_selection_interface_init (AtkSelectionIface *iface)
{
iface->add_selection = gtk_menu_shell_accessible_add_selection;
iface->clear_selection = gtk_menu_shell_accessible_clear_selection;
iface->ref_selection = gtk_menu_shell_accessible_ref_selection;
iface->get_selection_count = gtk_menu_shell_accessible_get_selection_count;
iface->is_child_selected = gtk_menu_shell_accessible_is_child_selected;
iface->remove_selection = gtk_menu_shell_accessible_remove_selection;
}

View File

@ -1,57 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2001 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_MENU_SHELL_ACCESSIBLE_H__
#define __GTK_MENU_SHELL_ACCESSIBLE_H__
#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk-a11y.h> can be included directly."
#endif
#include <gtk/a11y/gtkcontaineraccessible.h>
G_BEGIN_DECLS
#define GTK_TYPE_MENU_SHELL_ACCESSIBLE (gtk_menu_shell_accessible_get_type ())
#define GTK_MENU_SHELL_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_SHELL_ACCESSIBLE, GtkMenuShellAccessible))
#define GTK_MENU_SHELL_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_SHELL_ACCESSIBLE, GtkMenuShellAccessibleClass))
#define GTK_IS_MENU_SHELL_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_SHELL_ACCESSIBLE))
#define GTK_IS_MENU_SHELL_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_SHELL_ACCESSIBLE))
#define GTK_MENU_SHELL_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_SHELL_ACCESSIBLE, GtkMenuShellAccessibleClass))
typedef struct _GtkMenuShellAccessible GtkMenuShellAccessible;
typedef struct _GtkMenuShellAccessibleClass GtkMenuShellAccessibleClass;
typedef struct _GtkMenuShellAccessiblePrivate GtkMenuShellAccessiblePrivate;
struct _GtkMenuShellAccessible
{
GtkContainerAccessible parent;
GtkMenuShellAccessiblePrivate *priv;
};
struct _GtkMenuShellAccessibleClass
{
GtkContainerAccessibleClass parent_class;
};
GDK_AVAILABLE_IN_ALL
GType gtk_menu_shell_accessible_get_type (void);
G_END_DECLS
#endif /* __GTK_MENU_SHELL_ACCESSIBLE_H__ */

View File

@ -1,117 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2002 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gtkradiomenuitemaccessible.h"
struct _GtkRadioMenuItemAccessiblePrivate
{
GSList *old_group;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkRadioMenuItemAccessible,
gtk_radio_menu_item_accessible,
GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE)
static AtkRelationSet *
gtk_radio_menu_item_accessible_ref_relation_set (AtkObject *obj)
{
GtkWidget *widget;
AtkRelationSet *relation_set;
GSList *list;
GtkRadioMenuItemAccessible *radio_menu_item;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return NULL;
radio_menu_item = GTK_RADIO_MENU_ITEM_ACCESSIBLE (obj);
relation_set = ATK_OBJECT_CLASS (gtk_radio_menu_item_accessible_parent_class)->ref_relation_set (obj);
/* If the radio menu_item's group has changed remove the relation */
list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget));
if (radio_menu_item->priv->old_group != list)
{
AtkRelation *relation;
relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_MEMBER_OF);
atk_relation_set_remove (relation_set, relation);
}
if (!atk_relation_set_contains (relation_set, ATK_RELATION_MEMBER_OF))
{
/* Get the members of the menu_item group */
radio_menu_item->priv->old_group = list;
if (list)
{
AtkObject **accessible_array;
guint list_length;
AtkRelation* relation;
gint i = 0;
list_length = g_slist_length (list);
accessible_array = g_new (AtkObject *, list_length);
while (list != NULL)
{
GtkWidget* list_item = list->data;
accessible_array[i++] = gtk_widget_get_accessible (list_item);
list = list->next;
}
relation = atk_relation_new (accessible_array, list_length,
ATK_RELATION_MEMBER_OF);
g_free (accessible_array);
atk_relation_set_add (relation_set, relation);
/* Unref the relation so that it is not leaked */
g_object_unref (relation);
}
}
return relation_set;
}
static void
gtk_radio_menu_item_accessible_initialize (AtkObject *obj,
gpointer data)
{
ATK_OBJECT_CLASS (gtk_radio_menu_item_accessible_parent_class)->initialize (obj, data);
obj->role = ATK_ROLE_RADIO_MENU_ITEM;
}
static void
gtk_radio_menu_item_accessible_class_init (GtkRadioMenuItemAccessibleClass *klass)
{
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
class->ref_relation_set = gtk_radio_menu_item_accessible_ref_relation_set;
class->initialize = gtk_radio_menu_item_accessible_initialize;
}
static void
gtk_radio_menu_item_accessible_init (GtkRadioMenuItemAccessible *radio_menu_item)
{
radio_menu_item->priv = gtk_radio_menu_item_accessible_get_instance_private (radio_menu_item);
}

View File

@ -1,57 +0,0 @@
/* GTK+ - accessibility implementations
* Copyright 2002 Sun Microsystems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_RADIO_MENU_ITEM_ACCESSIBLE_H__
#define __GTK_RADIO_MENU_ITEM_ACCESSIBLE_H__
#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk-a11y.h> can be included directly."
#endif
#include <gtk/a11y/gtkcheckmenuitemaccessible.h>
G_BEGIN_DECLS
#define GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE (gtk_radio_menu_item_accessible_get_type ())
#define GTK_RADIO_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE, GtkRadioMenuItemAccessible))
#define GTK_RADIO_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE, GtkRadioMenuItemAccessibleClass))
#define GTK_IS_RADIO_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE))
#define GTK_IS_RADIO_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE))
#define GTK_RADIO_MENU_ITEM_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE, GtkRadioMenuItemAccessibleClass))
typedef struct _GtkRadioMenuItemAccessible GtkRadioMenuItemAccessible;
typedef struct _GtkRadioMenuItemAccessibleClass GtkRadioMenuItemAccessibleClass;
typedef struct _GtkRadioMenuItemAccessiblePrivate GtkRadioMenuItemAccessiblePrivate;
struct _GtkRadioMenuItemAccessible
{
GtkCheckMenuItemAccessible parent;
GtkRadioMenuItemAccessiblePrivate *priv;
};
struct _GtkRadioMenuItemAccessibleClass
{
GtkCheckMenuItemAccessibleClass parent_class;
};
GDK_AVAILABLE_IN_ALL
GType gtk_radio_menu_item_accessible_get_type (void);
G_END_DECLS
#endif /* __GTK_RADIO_MENU_ITEM_ACCESSIBLE_H__ */

View File

@ -22,8 +22,6 @@
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtkframe.h>
#include <gtk/gtkmenu.h>
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkwindow.h>
@ -91,25 +89,6 @@ gtk_toplevel_accessible_get_name (AtkObject *obj)
return g_get_prgname ();
}
static gboolean
is_attached_menu_window (GtkWidget *widget)
{
GtkWidget *child;
child = gtk_bin_get_child (GTK_BIN (widget));
if (GTK_IS_MENU (child))
{
GtkWidget *attach;
attach = gtk_menu_get_attach_widget (GTK_MENU (child));
/* Allow for menu belonging to the Panel Menu, which is a GtkButton */
if (GTK_IS_MENU_ITEM (attach) || GTK_IS_BUTTON (attach))
return TRUE;
}
return FALSE;
}
static void
gtk_toplevel_accessible_class_init (GtkToplevelAccessibleClass *klass)
{
@ -177,8 +156,7 @@ show_event_watcher (GSignalInvocationHint *ihint,
return TRUE;
widget = GTK_WIDGET (object);
if (gtk_widget_get_parent (widget) ||
is_attached_menu_window (widget))
if (gtk_widget_get_parent (widget))
return TRUE;
child = gtk_widget_get_accessible (widget);
@ -236,7 +214,6 @@ gtk_toplevel_accessible_init (GtkToplevelAccessible *toplevel)
widget = GTK_WIDGET (window);
if (!window ||
!gtk_widget_get_visible (widget) ||
is_attached_menu_window (widget) ||
gtk_widget_get_parent (GTK_WIDGET (window)))
{
GList *temp_l = l->next;

View File

@ -5,7 +5,6 @@ a11y_sources = files([
'gtkbuttonaccessible.c',
'gtkcellaccessible.c',
'gtkcellaccessibleparent.c',
'gtkcheckmenuitemaccessible.c',
'gtkcolorswatchaccessible.c',
'gtkcomboboxaccessible.c',
'gtkcontaineraccessible.c',
@ -24,10 +23,7 @@ a11y_sources = files([
'gtklistboxaccessible.c',
'gtklistboxrowaccessible.c',
'gtklockbuttonaccessible.c',
'gtkmenuaccessible.c',
'gtkmenubuttonaccessible.c',
'gtkmenuitemaccessible.c',
'gtkmenushellaccessible.c',
'gtknotebookaccessible.c',
'gtknotebookpageaccessible.c',
'gtkpanedaccessible.c',
@ -35,7 +31,6 @@ a11y_sources = files([
'gtkpopoveraccessible.c',
'gtkprogressbaraccessible.c',
'gtkradiobuttonaccessible.c',
'gtkradiomenuitemaccessible.c',
'gtkrangeaccessible.c',
'gtkrenderercellaccessible.c',
'gtkscaleaccessible.c',
@ -62,7 +57,6 @@ a11y_headers = files([
'gtkbuttonaccessible.h',
'gtkcellaccessible.h',
'gtkcellaccessibleparent.h',
'gtkcheckmenuitemaccessible.h',
'gtkcomboboxaccessible.h',
'gtkcontaineraccessible.h',
'gtkcontainercellaccessible.h',
@ -80,17 +74,13 @@ a11y_headers = files([
'gtklistboxaccessible.h',
'gtklistboxrowaccessible.h',
'gtklockbuttonaccessible.h',
'gtkmenuaccessible.h',
'gtkmenubuttonaccessible.h',
'gtkmenuitemaccessible.h',
'gtkmenushellaccessible.h',
'gtknotebookaccessible.h',
'gtknotebookpageaccessible.h',
'gtkpanedaccessible.h',
'gtkpopoveraccessible.h',
'gtkprogressbaraccessible.h',
'gtkradiobuttonaccessible.h',
'gtkradiomenuitemaccessible.h',
'gtkrangeaccessible.h',
'gtkrenderercellaccessible.h',
'gtkscaleaccessible.h',

View File

@ -32,7 +32,6 @@
#include <gtk/a11y/gtkbuttonaccessible.h>
#include <gtk/a11y/gtkcellaccessible.h>
#include <gtk/a11y/gtkcellaccessibleparent.h>
#include <gtk/a11y/gtkcheckmenuitemaccessible.h>
#include <gtk/a11y/gtkcomboboxaccessible.h>
#include <gtk/a11y/gtkcontaineraccessible.h>
#include <gtk/a11y/gtkcontainercellaccessible.h>
@ -50,17 +49,13 @@
#include <gtk/a11y/gtklistboxaccessible.h>
#include <gtk/a11y/gtklistboxrowaccessible.h>
#include <gtk/a11y/gtklockbuttonaccessible.h>
#include <gtk/a11y/gtkmenuaccessible.h>
#include <gtk/a11y/gtkmenubuttonaccessible.h>
#include <gtk/a11y/gtkmenuitemaccessible.h>
#include <gtk/a11y/gtkmenushellaccessible.h>
#include <gtk/a11y/gtknotebookaccessible.h>
#include <gtk/a11y/gtknotebookpageaccessible.h>
#include <gtk/a11y/gtkpanedaccessible.h>
#include <gtk/a11y/gtkpopoveraccessible.h>
#include <gtk/a11y/gtkprogressbaraccessible.h>
#include <gtk/a11y/gtkradiobuttonaccessible.h>
#include <gtk/a11y/gtkradiomenuitemaccessible.h>
#include <gtk/a11y/gtkrangeaccessible.h>
#include <gtk/a11y/gtkrenderercellaccessible.h>
#include <gtk/a11y/gtkscaleaccessible.h>

View File

@ -53,7 +53,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellRendererText, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellRendererToggle, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellView, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCheckButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCheckMenuItem, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkClipboard, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkColorButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkColorChooser, g_object_unref)
@ -105,9 +104,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLevelBar, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLinkButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkListStore, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLockButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuBar, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuItem, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuToolButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMessageDialog, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMountOperation, g_object_unref)
@ -124,7 +121,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPrintOperationPreview, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPrintSettings, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkProgressBar, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioMenuItem, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioToolButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRange, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRecentManager, g_object_unref)
@ -137,7 +133,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkScrolledWindow, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSearchBar, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSearchEntry, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparator, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparatorMenuItem, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparatorToolItem, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSettings, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkStackSidebar, g_object_unref)

View File

@ -76,7 +76,6 @@
#include <gtk/gtkcenterbox.h>
#include <gtk/gtkcenterlayout.h>
#include <gtk/gtkcheckbutton.h>
#include <gtk/gtkcheckmenuitem.h>
#include <gtk/gtkcolorbutton.h>
#include <gtk/gtkcolorchooser.h>
#include <gtk/gtkcolorchooserdialog.h>
@ -156,11 +155,7 @@
#include <gtk/gtkmediacontrols.h>
#include <gtk/gtkmediafile.h>
#include <gtk/gtkmediastream.h>
#include <gtk/gtkmenu.h>
#include <gtk/gtkmenubar.h>
#include <gtk/gtkmenubutton.h>
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkmenushell.h>
#include <gtk/gtkmenutoolbutton.h>
#include <gtk/gtkmessagedialog.h>
#include <gtk/gtkmountoperation.h>
@ -185,7 +180,6 @@
#include <gtk/gtkprintsettings.h>
#include <gtk/gtkprogressbar.h>
#include <gtk/gtkradiobutton.h>
#include <gtk/gtkradiomenuitem.h>
#include <gtk/gtkradiotoolbutton.h>
#include <gtk/gtkrange.h>
#include <gtk/gtkrecentmanager.h>
@ -202,7 +196,6 @@
#include <gtk/gtkselection.h>
#include <gtk/gtkselectionmodel.h>
#include <gtk/gtkseparator.h>
#include <gtk/gtkseparatormenuitem.h>
#include <gtk/gtkseparatortoolitem.h>
#include <gtk/gtksettings.h>
#include <gtk/gtkshortcutlabel.h>

View File

@ -57,45 +57,19 @@
* the accelerators which have been added to a particular widget. This widget is
* set by calling gtk_accel_label_set_accel_widget().
*
* For example, a #GtkMenuItem widget may have an accelerator added to emit
* For example, a menu item may have an accelerator added to emit
* the activate signal when the Ctrl+S key combination is pressed.
* A #GtkAccelLabel is created and added to the #GtkMenuItem, and
* gtk_accel_label_set_accel_widget() is called with the #GtkMenuItem as the
* A #GtkAccelLabel is created and added to the menu item widget, and
* gtk_accel_label_set_accel_widget() is called with the item as the
* second argument. The #GtkAccelLabel will now display Ctrl+S after its label.
*
* Note that creating a #GtkMenuItem with gtk_menu_item_new_with_label() (or
* one of the similar functions for #GtkCheckMenuItem and #GtkRadioMenuItem)
* automatically adds a #GtkAccelLabel to the #GtkMenuItem and calls
* gtk_accel_label_set_accel_widget() to set it up for you.
* Note that accel labels are typically set up automatically when menus
* are created.
*
* A #GtkAccelLabel will only display accelerators which have %GTK_ACCEL_VISIBLE
* set (see #GtkAccelFlags).
* A #GtkAccelLabel can display multiple accelerators and even signal names,
* though it is almost always used to display just one accelerator key.
*
* ## Creating a simple menu item with an accelerator key.
*
* |[<!-- language="C" -->
* GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
* GtkWidget *menu = gtk_menu_new ();
* GtkWidget *save_item;
* GtkAccelGroup *accel_group;
*
* // Create a GtkAccelGroup and add it to the window.
* accel_group = gtk_accel_group_new ();
* gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
*
* // Create the menu item using the convenience function.
* save_item = gtk_menu_item_new_with_label ("Save");
* gtk_container_add (GTK_CONTAINER (menu), save_item);
*
* // Now add the accelerator to the GtkMenuItem. Note that since we
* // called gtk_menu_item_new_with_label() to create the GtkMenuItem
* // the GtkAccelLabel is automatically set up to display the
* // GtkMenuItem accelerators. We just need to make sure we use
* // GTK_ACCEL_VISIBLE here.
* gtk_widget_add_accelerator (save_item, "activate", accel_group,
* GDK_KEY_s, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
* ]|
*
* # CSS nodes
@ -391,8 +365,8 @@ gtk_accel_label_get_accel_widget (GtkAccelLabel *accel_label)
* @accel_label: a #GtkAccelLabel.
*
* Returns the width needed to display the accelerator key(s).
* This is used by menus to align all of the #GtkMenuItem widgets, and shouldn't
* be needed by applications.
* This is used by menus to align all of the menu item widgets,
* and shouldn't be needed by applications.
*
* Returns: the width needed to display the accelerator key(s).
*/

View File

@ -52,7 +52,6 @@
#include "gtkentry.h"
#include "gtktogglebutton.h"
#include "gtkstylecontext.h"
#include "gtkmenuitem.h"
#include "gtkheaderbar.h"
#include "gtkdialogprivate.h"
#include "gtksearchbar.h"
@ -296,55 +295,6 @@ widget_notify_for_button_cb (GObject *source,
gtk_widget_hide (priv->show_more_button);
}
static void
forget_menu_item_activate_cb (GtkMenuItem *item,
gpointer user_data)
{
GtkAppChooserDialog *self = user_data;
GtkAppChooserDialogPrivate *priv = gtk_app_chooser_dialog_get_instance_private (self);
GAppInfo *info;
info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (self));
if (info != NULL)
{
g_app_info_remove_supports_type (info, priv->content_type, NULL);
gtk_app_chooser_refresh (GTK_APP_CHOOSER (self));
g_object_unref (info);
}
}
static GtkWidget *
build_forget_menu_item (GtkAppChooserDialog *self)
{
GtkWidget *retval;
retval = gtk_menu_item_new_with_label (_("Forget association"));
g_signal_connect (retval, "activate",
G_CALLBACK (forget_menu_item_activate_cb), self);
return retval;
}
static void
widget_populate_popup_cb (GtkAppChooserWidget *widget,
GtkMenu *menu,
GAppInfo *info,
gpointer user_data)
{
GtkAppChooserDialog *self = user_data;
GtkWidget *menu_item;
if (g_app_info_can_remove_supports_type (info))
{
menu_item = build_forget_menu_item (self);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
}
}
static void
construct_appchooser_widget (GtkAppChooserDialog *self)
{
@ -362,8 +312,6 @@ construct_appchooser_widget (GtkAppChooserDialog *self)
G_CALLBACK (widget_application_activated_cb), self);
g_signal_connect (priv->app_chooser_widget, "notify::show-other",
G_CALLBACK (widget_notify_for_button_cb), self);
g_signal_connect (priv->app_chooser_widget, "populate-popup",
G_CALLBACK (widget_populate_popup_cb), self);
/* Add the custom button to the new appchooser */
gtk_container_add (GTK_CONTAINER (priv->inner_box),

View File

@ -86,10 +86,6 @@ struct _GtkAppChooserWidgetClass {
void (* application_activated) (GtkAppChooserWidget *self,
GAppInfo *app_info);
void (* populate_popup) (GtkAppChooserWidget *self,
GtkMenu *menu,
GAppInfo *app_info);
};
struct _GtkAppChooserWidgetPrivate {
@ -150,7 +146,6 @@ enum {
enum {
SIGNAL_APPLICATION_SELECTED,
SIGNAL_APPLICATION_ACTIVATED,
SIGNAL_POPULATE_POPUP,
N_SIGNALS
};
@ -200,93 +195,6 @@ refresh_and_emit_app_selected (GtkAppChooserWidget *self,
priv->selected_app_info);
}
static GAppInfo *
get_app_info_for_coords (GtkAppChooserWidget *self,
double x,
double y)
{
GtkAppChooserWidgetPrivate *priv = gtk_app_chooser_widget_get_instance_private (self);
GtkTreePath *path = NULL;
GtkTreeIter iter;
GtkTreeModel *model;
GAppInfo *info;
gboolean recommended;
if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (priv->program_list),
x, y,
&path,
NULL, NULL, NULL))
return NULL;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->program_list));
if (!gtk_tree_model_get_iter (model, &iter, path))
{
gtk_tree_path_free (path);
return NULL;
}
/* we only allow interaction with recommended applications */
gtk_tree_model_get (model, &iter,
COLUMN_APP_INFO, &info,
COLUMN_RECOMMENDED, &recommended,
-1);
if (!recommended)
g_clear_object (&info);
return info;
}
static void
popup_menu_detach (GtkWidget *attach_widget,
GtkMenu *menu)
{
GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (attach_widget);
GtkAppChooserWidgetPrivate *priv = gtk_app_chooser_widget_get_instance_private (self);
priv->popup_menu = NULL;
}
static void
gtk_app_chooser_row_pressed_cb (GtkGesture *gesture,
int n_press,
double x,
double y,
gpointer user_data)
{
GtkAppChooserWidget *self = user_data;
GtkAppChooserWidgetPrivate *priv = gtk_app_chooser_widget_get_instance_private (self);
GAppInfo *info;
GtkWidget *menu;
GList *children;
gint n_children;
info = get_app_info_for_coords (self, x, y);
if (info == NULL)
return;
if (priv->popup_menu)
gtk_widget_destroy (priv->popup_menu);
priv->popup_menu = menu = gtk_menu_new ();
gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (self), popup_menu_detach);
g_signal_emit (self, signals[SIGNAL_POPULATE_POPUP], 0, menu, info);
g_object_unref (info);
/* see if clients added menu items to this container */
children = gtk_container_get_children (GTK_CONTAINER (menu));
n_children = g_list_length (children);
if (n_children > 0) /* actually popup the menu */
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
g_list_free (children);
}
static gboolean
path_is_heading (GtkTreeView *view,
GtkTreePath *path)
@ -1134,27 +1042,6 @@ gtk_app_chooser_widget_class_init (GtkAppChooserWidgetClass *klass)
G_TYPE_NONE,
1, G_TYPE_APP_INFO);
/**
* GtkAppChooserWidget::populate-popup:
* @self: the object which received the signal
* @menu: the #GtkMenu to populate
* @application: the current #GAppInfo
*
* Emitted when a context menu is about to popup over an application item.
* Clients can insert menu items into the provided #GtkMenu object in the
* callback of this signal; the context menu will be shown over the item
* if at least one item has been added to the menu.
*/
signals[SIGNAL_POPULATE_POPUP] =
g_signal_new (I_("populate-popup"),
GTK_TYPE_APP_CHOOSER_WIDGET,
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkAppChooserWidgetClass, populate_popup),
NULL, NULL,
_gtk_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE,
2, GTK_TYPE_MENU, G_TYPE_APP_INFO);
/* Bind class to template
*/
gtk_widget_class_set_template_from_resource (widget_class,
@ -1179,7 +1066,6 @@ gtk_app_chooser_widget_init (GtkAppChooserWidget *self)
GtkAppChooserWidgetPrivate *priv = gtk_app_chooser_widget_get_instance_private (self);
GtkTreeSelection *selection;
GtkTreeModel *sort;
GtkGesture *gesture;
gtk_widget_init_template (GTK_WIDGET (self));
@ -1212,12 +1098,6 @@ gtk_app_chooser_widget_init (GtkAppChooserWidget *self)
priv->monitor = g_app_info_monitor_get ();
g_signal_connect (priv->monitor, "changed",
G_CALLBACK (app_info_changed), self);
gesture = gtk_gesture_click_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
g_signal_connect (gesture, "pressed",
G_CALLBACK (gtk_app_chooser_row_pressed_cb), self);
gtk_widget_add_controller (priv->program_list, GTK_EVENT_CONTROLLER (gesture));
}
static GAppInfo *

View File

@ -25,7 +25,7 @@
#include "gtkwidgetprivate.h"
#include "gtkwindowprivate.h"
#include "gtkheaderbar.h"
#include "gtkmenubar.h"
#include "gtkpopovermenubar.h"
#include "gtkintl.h"
#include "gtksettings.h"
#include "gtkshortcutswindowprivate.h"
@ -70,7 +70,7 @@
* will display the application menu, but not the menubar.
*
* If the desktop environment does not display the menubar, then
* #GtkApplicationWindow will automatically show a #GtkMenuBar for it.
* #GtkApplicationWindow will automatically show a menubar for it.
* This behaviour can be overridden with the #GtkApplicationWindow:show-menubar
* property. If the desktop environment does not display the application
* menu, then it will automatically be included in the menubar or in the
@ -273,7 +273,7 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
g_menu_append_section (combined, NULL, G_MENU_MODEL (priv->app_menu_section));
g_menu_append_section (combined, NULL, G_MENU_MODEL (priv->menubar_section));
priv->menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (combined));
priv->menubar = gtk_popover_menu_bar_new_from_model (G_MENU_MODEL (combined));
gtk_widget_set_parent (priv->menubar, GTK_WIDGET (window));
g_object_unref (combined);
}

View File

@ -29,6 +29,7 @@
#include "gtkprivate.h"
#include "gtkeventcontrollerkey.h"
#include "gtknative.h"
#include "gtkbinlayout.h"
/**
@ -125,8 +126,6 @@ struct _GtkCellRendererAccelPrivate
GdkModifierType accel_mods;
guint accel_key;
guint keycode;
GdkSeat *grab_seat;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkCellRendererAccel, gtk_cell_renderer_accel, GTK_TYPE_CELL_RENDERER_TEXT)
@ -465,72 +464,19 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer *cell,
GtkCellRendererText *celltext = GTK_CELL_RENDERER_TEXT (cell);
GtkCellRendererAccel *accel = GTK_CELL_RENDERER_ACCEL (cell);
GtkCellRendererAccelPrivate *priv = gtk_cell_renderer_accel_get_instance_private (accel);
GtkWidget *label;
GtkWidget *editable;
gboolean is_editable;
GdkSeat *seat = NULL;
GdkSurface *surface;
/* If the cell isn't editable we return NULL. */
g_object_get (celltext, "editable", &is_editable, NULL);
if (!is_editable)
return NULL;
surface = gtk_native_get_surface (gtk_widget_get_native (widget));
if (event)
seat = gdk_event_get_seat (event);
else
{
GdkDevice *device;
device = gtk_get_current_event_device ();
if (device)
seat = gdk_device_get_seat (device);
}
if (!seat || !surface)
return NULL;
if (gdk_seat_grab (seat, surface,
GDK_SEAT_CAPABILITY_ALL, FALSE,
NULL, event, NULL, NULL) != GDK_GRAB_SUCCESS)
return NULL;
priv->grab_seat = seat;
editable = gtk_cell_editable_widget_new (cell, priv->accel_mode, path);
label = gtk_label_new (NULL);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
gtk_widget_set_state_flags (label, GTK_STATE_FLAG_SELECTED, TRUE);
/* This label is displayed in a treeview cell displaying an accelerator
* when the cell is clicked to change the acelerator.
*/
gtk_label_set_text (GTK_LABEL (label), _("New accelerator…"));
gtk_container_add (GTK_CONTAINER (editable), label);
gtk_grab_add (editable);
return GTK_CELL_EDITABLE (editable);
}
static void
gtk_cell_renderer_accel_ungrab (GtkCellRendererAccel *accel)
{
GtkCellRendererAccelPrivate *priv = gtk_cell_renderer_accel_get_instance_private (accel);
if (priv->grab_seat)
{
gdk_seat_ungrab (priv->grab_seat);
priv->grab_seat = NULL;
}
}
/* --------------------------------- */
typedef struct _GtkCellEditableWidget GtkCellEditableWidget;
@ -544,6 +490,7 @@ struct _GtkCellEditableWidget
GtkCellRendererAccelMode accel_mode;
gchar *path;
GtkCellRenderer *cell;
GtkWidget *label;
};
enum {
@ -662,7 +609,6 @@ key_controller_key_pressed (GtkEventControllerKey *key,
out:
gtk_grab_remove (widget);
gtk_cell_renderer_accel_ungrab (GTK_CELL_RENDERER_ACCEL (box->cell));
gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (widget));
gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (widget));
@ -678,10 +624,7 @@ key_controller_key_pressed (GtkEventControllerKey *key,
static void
gtk_cell_editable_widget_unrealize (GtkWidget *widget)
{
GtkCellEditableWidget *box = (GtkCellEditableWidget*)widget;
gtk_grab_remove (widget);
gtk_cell_renderer_accel_ungrab (GTK_CELL_RENDERER_ACCEL (box->cell));
GTK_WIDGET_CLASS (gtk_cell_editable_widget_parent_class)->unrealize (widget);
}
@ -736,6 +679,16 @@ gtk_cell_editable_widget_get_property (GObject *object,
}
}
static void
gtk_cell_editable_widget_dispose (GObject *object)
{
GtkCellEditableWidget *box = (GtkCellEditableWidget*)object;
g_clear_pointer (&box->label, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_cell_editable_widget_parent_class)->dispose (object);
}
static void
gtk_cell_editable_widget_finalize (GObject *object)
{
@ -753,6 +706,7 @@ gtk_cell_editable_widget_class_init (GtkCellEditableWidgetClass *class)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->finalize = gtk_cell_editable_widget_finalize;
object_class->dispose = gtk_cell_editable_widget_dispose;
object_class->set_property = gtk_cell_editable_widget_set_property;
object_class->get_property = gtk_cell_editable_widget_get_property;
@ -772,6 +726,7 @@ gtk_cell_editable_widget_class_init (GtkCellEditableWidgetClass *class)
g_param_spec_string ("path", NULL, NULL,
NULL, GTK_PARAM_READWRITE));
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("acceleditor"));
}
@ -804,5 +759,20 @@ gtk_cell_editable_widget_new (GtkCellRenderer *cell,
NULL);
box->cell = cell;
box->label = gtk_label_new (NULL);
gtk_widget_set_halign (box->label, GTK_ALIGN_START);
gtk_widget_set_valign (box->label, GTK_ALIGN_CENTER);
gtk_widget_set_state_flags (box->label, GTK_STATE_FLAG_SELECTED, TRUE);
/* This label is displayed in a treeview cell displaying an accelerator
* when the cell is clicked to change the acelerator.
*/
gtk_label_set_text (GTK_LABEL (box->label), _("New accelerator…"));
gtk_widget_set_parent (box->label, GTK_WIDGET (box));
gtk_grab_add (GTK_WIDGET (box));
return GTK_WIDGET (box);
}

View File

@ -1,623 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gtkcheckmenuitemprivate.h"
#include "gtkmenuitemprivate.h"
#include "gtkaccellabel.h"
#include "gtkmarshalers.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "a11y/gtkcheckmenuitemaccessible.h"
#include "gtkcssnodeprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkiconprivate.h"
/**
* SECTION:gtkcheckmenuitem
* @Short_description: A menu item with a check box
* @Title: GtkCheckMenuItem
*
* A #GtkCheckMenuItem is a menu item that maintains the state of a boolean
* value in addition to a #GtkMenuItem usual role in activating application
* code.
*
* A check box indicating the state of the boolean value is displayed
* at the left side of the #GtkMenuItem. Activating the #GtkMenuItem
* toggles the value.
*
* # CSS nodes
*
* |[<!-- language="plain" -->
* menuitem
* check.left
* <child>
* ]|
*
* GtkCheckMenuItem has a main CSS node with name menuitem, and a subnode
* with name check, which gets the .left or .right style class.
*/
typedef struct _GtkCheckMenuItemPrivate GtkCheckMenuItemPrivate;
struct _GtkCheckMenuItemPrivate
{
GtkWidget *indicator_widget;
guint active : 1;
guint draw_as_radio : 1;
guint inconsistent : 1;
};
enum {
TOGGLED,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_ACTIVE,
PROP_INCONSISTENT,
PROP_DRAW_AS_RADIO
};
static void gtk_check_menu_item_activate (GtkMenuItem *menu_item);
static void gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item,
gint *requisition);
static void gtk_check_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_check_menu_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gtk_check_menu_item_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state);
static void gtk_check_menu_item_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir);
static guint check_menu_item_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE_WITH_CODE (GtkCheckMenuItem, gtk_check_menu_item, GTK_TYPE_MENU_ITEM,
G_ADD_PRIVATE (GtkCheckMenuItem))
static void
gtk_check_menu_item_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkAllocation indicator_alloc;
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget);
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
gint toggle_size;
GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->size_allocate (widget,
width,
height,
baseline);
gtk_widget_measure (priv->indicator_widget,
GTK_ORIENTATION_HORIZONTAL,
-1,
&indicator_alloc.width, NULL,
NULL, NULL);
gtk_widget_measure (priv->indicator_widget,
GTK_ORIENTATION_VERTICAL,
-1,
&indicator_alloc.height, NULL,
NULL, NULL);
toggle_size = GTK_MENU_ITEM (check_menu_item)->priv->toggle_size;
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
indicator_alloc.x = (toggle_size - indicator_alloc.width) / 2;
else
indicator_alloc.x = width - toggle_size +
(toggle_size - indicator_alloc.width) / 2;
indicator_alloc.y = (height - indicator_alloc.height) / 2;
gtk_widget_size_allocate (priv->indicator_widget,
&indicator_alloc,
baseline);
}
static void
gtk_check_menu_item_finalize (GObject *object)
{
GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM (object);
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (item);
gtk_widget_unparent (priv->indicator_widget);
G_OBJECT_CLASS (gtk_check_menu_item_parent_class)->finalize (object);
}
static void
gtk_check_menu_item_class_init (GtkCheckMenuItemClass *klass)
{
GObjectClass *gobject_class;
GtkWidgetClass *widget_class;
GtkMenuItemClass *menu_item_class;
gobject_class = G_OBJECT_CLASS (klass);
widget_class = (GtkWidgetClass*) klass;
menu_item_class = (GtkMenuItemClass*) klass;
gobject_class->set_property = gtk_check_menu_item_set_property;
gobject_class->get_property = gtk_check_menu_item_get_property;
gobject_class->finalize = gtk_check_menu_item_finalize;
widget_class->size_allocate = gtk_check_menu_item_size_allocate;
widget_class->state_flags_changed = gtk_check_menu_item_state_flags_changed;
widget_class->direction_changed = gtk_check_menu_item_direction_changed;
g_object_class_install_property (gobject_class,
PROP_ACTIVE,
g_param_spec_boolean ("active",
P_("Active"),
P_("Whether the menu item is checked"),
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
g_object_class_install_property (gobject_class,
PROP_INCONSISTENT,
g_param_spec_boolean ("inconsistent",
P_("Inconsistent"),
P_("Whether to display an “inconsistent” state"),
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
g_object_class_install_property (gobject_class,
PROP_DRAW_AS_RADIO,
g_param_spec_boolean ("draw-as-radio",
P_("Draw as radio menu item"),
P_("Whether the menu item looks like a radio menu item"),
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
menu_item_class->activate = gtk_check_menu_item_activate;
menu_item_class->hide_on_activate = FALSE;
menu_item_class->toggle_size_request = gtk_check_menu_item_toggle_size_request;
klass->toggled = NULL;
/**
* GtkCheckMenuItem::toggled:
* @checkmenuitem: the object which received the signal.
*
* This signal is emitted when the state of the check box is changed.
*
* A signal handler can use gtk_check_menu_item_get_active()
* to discover the new state.
*/
check_menu_item_signals[TOGGLED] =
g_signal_new (I_("toggled"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkCheckMenuItemClass, toggled),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE);
gtk_widget_class_set_css_name (widget_class, I_("menuitem"));
}
/**
* gtk_check_menu_item_new:
*
* Creates a new #GtkCheckMenuItem.
*
* Returns: a new #GtkCheckMenuItem.
*/
GtkWidget*
gtk_check_menu_item_new (void)
{
return g_object_new (GTK_TYPE_CHECK_MENU_ITEM, NULL);
}
/**
* gtk_check_menu_item_new_with_label:
* @label: the string to use for the label.
*
* Creates a new #GtkCheckMenuItem with a label.
*
* Returns: a new #GtkCheckMenuItem.
*/
GtkWidget*
gtk_check_menu_item_new_with_label (const gchar *label)
{
return g_object_new (GTK_TYPE_CHECK_MENU_ITEM,
"label", label,
NULL);
}
/**
* gtk_check_menu_item_new_with_mnemonic:
* @label: The text of the button, with an underscore in front of the
* character
*
* Creates a new #GtkCheckMenuItem containing a label. The label
* will be created using gtk_label_new_with_mnemonic(), so underscores
* in @label indicate the mnemonic for the menu item.
*
* Returns: a new #GtkCheckMenuItem
*/
GtkWidget*
gtk_check_menu_item_new_with_mnemonic (const gchar *label)
{
return g_object_new (GTK_TYPE_CHECK_MENU_ITEM,
"label", label,
"use-underline", TRUE,
NULL);
}
/**
* gtk_check_menu_item_set_active:
* @check_menu_item: a #GtkCheckMenuItem.
* @is_active: boolean value indicating whether the check box is active.
*
* Sets the active state of the menu items check box.
*/
void
gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item,
gboolean is_active)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item));
is_active = is_active != 0;
if (priv->active != is_active)
gtk_menu_item_activate (GTK_MENU_ITEM (check_menu_item));
}
/**
* gtk_check_menu_item_get_active:
* @check_menu_item: a #GtkCheckMenuItem
*
* Returns whether the check menu item is active. See
* gtk_check_menu_item_set_active ().
*
* Returns: %TRUE if the menu item is checked.
*/
gboolean
gtk_check_menu_item_get_active (GtkCheckMenuItem *check_menu_item)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item), FALSE);
return priv->active;
}
static void
gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item,
gint *requisition)
{
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (menu_item));
gtk_widget_measure (priv->indicator_widget,
GTK_ORIENTATION_HORIZONTAL,
-1,
requisition, NULL,
NULL, NULL);
}
/**
* gtk_check_menu_item_toggled:
* @check_menu_item: a #GtkCheckMenuItem.
*
* Emits the #GtkCheckMenuItem::toggled signal.
*/
void
gtk_check_menu_item_toggled (GtkCheckMenuItem *check_menu_item)
{
g_signal_emit (check_menu_item, check_menu_item_signals[TOGGLED], 0);
}
static void
update_node_state (GtkCheckMenuItem *check_menu_item)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
GtkStateFlags state;
state = gtk_widget_get_state_flags (GTK_WIDGET (check_menu_item));
state &= ~(GTK_STATE_FLAG_CHECKED | GTK_STATE_FLAG_INCONSISTENT);
if (priv->inconsistent)
state |= GTK_STATE_FLAG_INCONSISTENT;
if (priv->active)
state |= GTK_STATE_FLAG_CHECKED;
gtk_widget_set_state_flags (priv->indicator_widget, state, TRUE);
}
/**
* gtk_check_menu_item_set_inconsistent:
* @check_menu_item: a #GtkCheckMenuItem
* @setting: %TRUE to display an inconsistent third state check
*
* If the user has selected a range of elements (such as some text or
* spreadsheet cells) that are affected by a boolean setting, and the
* current values in that range are inconsistent, you may want to
* display the check in an in between state. This function turns on
* in between display. Normally you would turn off the inconsistent
* state again if the user explicitly selects a setting. This has to be
* done manually, gtk_check_menu_item_set_inconsistent() only affects
* visual appearance, it doesnt affect the semantics of the widget.
*
**/
void
gtk_check_menu_item_set_inconsistent (GtkCheckMenuItem *check_menu_item,
gboolean setting)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item));
setting = setting != FALSE;
if (setting != priv->inconsistent)
{
priv->inconsistent = setting;
update_node_state (check_menu_item);
gtk_widget_queue_draw (GTK_WIDGET (check_menu_item));
g_object_notify (G_OBJECT (check_menu_item), "inconsistent");
}
}
/**
* gtk_check_menu_item_get_inconsistent:
* @check_menu_item: a #GtkCheckMenuItem
*
* Retrieves the value set by gtk_check_menu_item_set_inconsistent().
*
* Returns: %TRUE if inconsistent
**/
gboolean
gtk_check_menu_item_get_inconsistent (GtkCheckMenuItem *check_menu_item)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item), FALSE);
return priv->inconsistent;
}
/**
* gtk_check_menu_item_set_draw_as_radio:
* @check_menu_item: a #GtkCheckMenuItem
* @draw_as_radio: whether @check_menu_item is drawn like a #GtkRadioMenuItem
*
* Sets whether @check_menu_item is drawn like a #GtkRadioMenuItem
**/
void
gtk_check_menu_item_set_draw_as_radio (GtkCheckMenuItem *check_menu_item,
gboolean draw_as_radio)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
GtkCssNode *indicator_node;
g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item));
draw_as_radio = draw_as_radio != FALSE;
if (draw_as_radio != priv->draw_as_radio)
{
priv->draw_as_radio = draw_as_radio;
indicator_node = gtk_widget_get_css_node (priv->indicator_widget);
if (draw_as_radio)
gtk_css_node_set_name (indicator_node, I_("radio"));
else
gtk_css_node_set_name (indicator_node, I_("check"));
gtk_widget_queue_draw (GTK_WIDGET (check_menu_item));
g_object_notify (G_OBJECT (check_menu_item), "draw-as-radio");
}
}
/**
* gtk_check_menu_item_get_draw_as_radio:
* @check_menu_item: a #GtkCheckMenuItem
*
* Returns whether @check_menu_item looks like a #GtkRadioMenuItem
*
* Returns: Whether @check_menu_item looks like a #GtkRadioMenuItem
**/
gboolean
gtk_check_menu_item_get_draw_as_radio (GtkCheckMenuItem *check_menu_item)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item), FALSE);
return priv->draw_as_radio;
}
static void
gtk_check_menu_item_init (GtkCheckMenuItem *check_menu_item)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
priv->active = FALSE;
priv->indicator_widget = gtk_icon_new ("check");
gtk_widget_set_parent (priv->indicator_widget, GTK_WIDGET (check_menu_item));
update_node_state (check_menu_item);
}
static void
gtk_check_menu_item_activate (GtkMenuItem *menu_item)
{
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
priv->active = !priv->active;
gtk_check_menu_item_toggled (check_menu_item);
update_node_state (check_menu_item);
gtk_widget_queue_draw (GTK_WIDGET (check_menu_item));
GTK_MENU_ITEM_CLASS (gtk_check_menu_item_parent_class)->activate (menu_item);
g_object_notify (G_OBJECT (check_menu_item), "active");
}
static void
gtk_check_menu_item_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state)
{
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget);
update_node_state (check_menu_item);
GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->state_flags_changed (widget, previous_state);
}
static void
gtk_check_menu_item_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir)
{
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget);
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
GtkStyleContext *context;
GtkWidget *child;
context = gtk_widget_get_style_context (priv->indicator_widget);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
{
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT);
child = gtk_widget_get_last_child (widget);
if (child != priv->indicator_widget)
gtk_widget_insert_before (priv->indicator_widget, widget, NULL);
}
else
{
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT);
child = gtk_widget_get_first_child (widget);
if (child != priv->indicator_widget)
gtk_widget_insert_after (priv->indicator_widget, widget, NULL);
}
GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->direction_changed (widget, previous_dir);
}
static void
gtk_check_menu_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (object);
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
switch (prop_id)
{
case PROP_ACTIVE:
g_value_set_boolean (value, priv->active);
break;
case PROP_INCONSISTENT:
g_value_set_boolean (value, priv->inconsistent);
break;
case PROP_DRAW_AS_RADIO:
g_value_set_boolean (value, priv->draw_as_radio);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_check_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkCheckMenuItem *checkitem = GTK_CHECK_MENU_ITEM (object);
switch (prop_id)
{
case PROP_ACTIVE:
gtk_check_menu_item_set_active (checkitem, g_value_get_boolean (value));
break;
case PROP_INCONSISTENT:
gtk_check_menu_item_set_inconsistent (checkitem, g_value_get_boolean (value));
break;
case PROP_DRAW_AS_RADIO:
gtk_check_menu_item_set_draw_as_radio (checkitem, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/* Private */
/*
* _gtk_check_menu_item_set_active:
* @check_menu_item: a #GtkCheckMenuItem
* @is_active: whether the action is active or not
*
* Sets the #GtkCheckMenuItem:active property directly. This function does
* not emit signals or notifications: it is left to the caller to do so.
*/
void
_gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item,
gboolean is_active)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
priv->active = is_active;
update_node_state (check_menu_item);
}
GtkWidget *
_gtk_check_menu_item_get_indicator_widget (GtkCheckMenuItem *check_menu_item)
{
GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item);
return priv->indicator_widget;
}

View File

@ -1,102 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2001. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_CHECK_MENU_ITEM_H__
#define __GTK_CHECK_MENU_ITEM_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkmenuitem.h>
G_BEGIN_DECLS
#define GTK_TYPE_CHECK_MENU_ITEM (gtk_check_menu_item_get_type ())
#define GTK_CHECK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItem))
#define GTK_CHECK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItemClass))
#define GTK_IS_CHECK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CHECK_MENU_ITEM))
#define GTK_IS_CHECK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CHECK_MENU_ITEM))
#define GTK_CHECK_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItemClass))
typedef struct _GtkCheckMenuItem GtkCheckMenuItem;
typedef struct _GtkCheckMenuItemClass GtkCheckMenuItemClass;
struct _GtkCheckMenuItem
{
GtkMenuItem menu_item;
};
/**
* GtkCheckMenuItemClass:
* @parent_class: The parent class.
* @toggled: Signal emitted when the state of the check box is changed.
*/
struct _GtkCheckMenuItemClass
{
GtkMenuItemClass parent_class;
/*< public >*/
void (* toggled) (GtkCheckMenuItem *check_menu_item);
/*< private >*/
gpointer padding[8];
};
GDK_AVAILABLE_IN_ALL
GType gtk_check_menu_item_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_check_menu_item_new (void);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_check_menu_item_new_with_label (const gchar *label);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_check_menu_item_new_with_mnemonic (const gchar *label);
GDK_AVAILABLE_IN_ALL
void gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item,
gboolean is_active);
GDK_AVAILABLE_IN_ALL
gboolean gtk_check_menu_item_get_active (GtkCheckMenuItem *check_menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_check_menu_item_toggled (GtkCheckMenuItem *check_menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_check_menu_item_set_inconsistent (GtkCheckMenuItem *check_menu_item,
gboolean setting);
GDK_AVAILABLE_IN_ALL
gboolean gtk_check_menu_item_get_inconsistent (GtkCheckMenuItem *check_menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_check_menu_item_set_draw_as_radio (GtkCheckMenuItem *check_menu_item,
gboolean draw_as_radio);
GDK_AVAILABLE_IN_ALL
gboolean gtk_check_menu_item_get_draw_as_radio (GtkCheckMenuItem *check_menu_item);
G_END_DECLS
#endif /* __GTK_CHECK_MENU_ITEM_H__ */

View File

@ -32,12 +32,9 @@
#include "gtkliststore.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkmenuitem.h"
#include "gtkmenuprivate.h"
#include "gtkmenushellprivate.h"
#include "gtkprivate.h"
#include "gtktogglebutton.h"
#include "gtktreemenu.h"
#include "gtktreepopoverprivate.h"
#include "gtktypebuiltins.h"
#include "gtkeventcontrollerkey.h"
@ -361,6 +358,7 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
{
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
GtkComboBoxPrivate *priv = gtk_combo_box_get_instance_private (combo_box);
gint menu_width;
gtk_widget_size_allocate (priv->box,
&(GtkAllocation) {
@ -368,25 +366,19 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
width, height
}, baseline);
if (gtk_widget_get_visible (priv->popup_widget))
{
gint menu_width;
gtk_widget_set_size_request (priv->popup_widget, -1, -1);
gtk_widget_set_size_request (priv->popup_widget, -1, -1);
if (priv->popup_fixed_width)
gtk_widget_measure (priv->popup_widget, GTK_ORIENTATION_HORIZONTAL, -1,
&menu_width, NULL, NULL, NULL);
else
gtk_widget_measure (priv->popup_widget, GTK_ORIENTATION_HORIZONTAL, -1,
NULL, &menu_width, NULL, NULL);
if (priv->popup_fixed_width)
gtk_widget_measure (priv->popup_widget, GTK_ORIENTATION_HORIZONTAL, -1,
&menu_width, NULL, NULL, NULL);
else
gtk_widget_measure (priv->popup_widget, GTK_ORIENTATION_HORIZONTAL, -1,
NULL, &menu_width, NULL, NULL);
gtk_widget_set_size_request (priv->popup_widget,
MAX (width, menu_width), -1);
gtk_widget_set_size_request (priv->popup_widget,
MAX (width, menu_width), -1);
/* reposition the menu after giving it a new width */
gtk_menu_reposition (GTK_MENU (priv->popup_widget));
}
gtk_native_check_resize (GTK_NATIVE (priv->popup_widget));
}
static void
@ -834,7 +826,6 @@ gtk_combo_box_init (GtkComboBox *combo_box)
{
GtkComboBoxPrivate *priv = gtk_combo_box_get_instance_private (combo_box);
GtkStyleContext *context;
GtkTreeMenu *menu;
GtkEventController *controller;
priv->active = -1;
@ -854,20 +845,16 @@ gtk_combo_box_init (GtkComboBox *combo_box)
priv->id_column = -1;
g_type_ensure (GTK_TYPE_ICON);
g_type_ensure (GTK_TYPE_TREE_MENU);
g_type_ensure (GTK_TYPE_TREE_POPOVER);
gtk_widget_init_template (GTK_WIDGET (combo_box));
context = gtk_widget_get_style_context (priv->button);
gtk_style_context_remove_class (context, "toggle");
gtk_style_context_add_class (context, "combo");
menu = GTK_TREE_MENU (priv->popup_widget);
_gtk_tree_menu_set_row_separator_func (menu,
(GtkTreeViewRowSeparatorFunc)gtk_combo_box_row_separator_func,
combo_box, NULL);
gtk_menu_attach_to_widget (GTK_MENU (menu),
GTK_WIDGET (combo_box),
NULL);
gtk_tree_popover_set_row_separator_func (GTK_TREE_POPOVER (priv->popup_widget),
(GtkTreeViewRowSeparatorFunc)gtk_combo_box_row_separator_func,
combo_box, NULL);
controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_VERTICAL |
GTK_EVENT_CONTROLLER_SCROLL_DISCRETE);
@ -1174,8 +1161,7 @@ gtk_combo_box_menu_hide (GtkWidget *menu,
gtk_combo_box_child_hide (menu,user_data);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button),
FALSE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), FALSE);
}
static gboolean
@ -1217,54 +1203,19 @@ tree_column_row_is_sensitive (GtkComboBox *combo_box,
}
static void
update_menu_sensitivity (GtkComboBox *combo_box,
GtkWidget *menu)
{
GtkComboBoxPrivate *priv = gtk_combo_box_get_instance_private (combo_box);
GList *children, *child;
GtkWidget *item, *submenu;
GtkWidget *cell_view;
gboolean sensitive;
if (!priv->model)
return;
children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu));
for (child = children; child; child = child->next)
{
item = GTK_WIDGET (child->data);
cell_view = gtk_bin_get_child (GTK_BIN (item));
if (!GTK_IS_CELL_VIEW (cell_view))
continue;
submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (item));
if (submenu != NULL)
{
gtk_widget_set_sensitive (item, TRUE);
update_menu_sensitivity (combo_box, submenu);
}
else
{
sensitive = cell_layout_is_sensitive (GTK_CELL_LAYOUT (cell_view));
gtk_widget_set_sensitive (item, sensitive);
}
}
g_list_free (children);
}
static void
gtk_combo_box_menu_popup (GtkComboBox *combo_box)
gtk_combo_box_menu_popup (GtkComboBox *combo_box)
{
GtkComboBoxPrivate *priv = gtk_combo_box_get_instance_private (combo_box);
#if 0
gint active_item;
GtkWidget *active;
int width, min_width, nat_width;
#endif
update_menu_sensitivity (combo_box, priv->popup_widget);
gtk_tree_popover_open_submenu (GTK_TREE_POPOVER (priv->popup_widget), "main");
gtk_popover_popup (GTK_POPOVER (priv->popup_widget));
#if 0
active_item = -1;
if (gtk_tree_row_reference_valid (priv->active_row))
{
@ -1276,7 +1227,7 @@ gtk_combo_box_menu_popup (GtkComboBox *combo_box)
}
/* FIXME handle nested menus better */
gtk_menu_set_active (GTK_MENU (priv->popup_widget), active_item);
//gtk_tree_popover_set_active (GTK_TREE_POPOVER (priv->popup_widget), active_item);
width = gtk_widget_get_width (GTK_WIDGET (combo_box));
gtk_widget_set_size_request (priv->popup_widget, -1, -1);
@ -1294,8 +1245,6 @@ gtk_combo_box_menu_popup (GtkComboBox *combo_box)
gtk_menu_update_scroll_offset,
NULL);
g_object_set (priv->popup_widget, "menu-type-hint", GDK_SURFACE_TYPE_HINT_COMBO, NULL);
if (priv->cell_view == NULL)
{
g_object_set (priv->popup_widget,
@ -1374,14 +1323,7 @@ gtk_combo_box_menu_popup (GtkComboBox *combo_box)
GDK_GRAVITY_NORTH_WEST,
NULL);
}
/* Re-get the active item before selecting it, as a popped-up handler like
* that of FileChooserButton in folder mode can refilter the model, making
* the original active item pointer invalid. This seems ugly and makes some
* of the above code pointless in such cases, so hopefully we can FIXME. */
active = gtk_menu_get_active (GTK_MENU (priv->popup_widget));
if (active && gtk_widget_get_visible (active))
gtk_menu_shell_select_item (GTK_MENU_SHELL (priv->popup_widget), active);
#endif
}
/**
@ -1470,7 +1412,7 @@ gtk_combo_box_popdown (GtkComboBox *combo_box)
g_return_if_fail (GTK_IS_COMBO_BOX (combo_box));
gtk_menu_popdown (GTK_MENU (priv->popup_widget));
gtk_popover_popdown (GTK_POPOVER (priv->popup_widget));
}
static void
@ -2045,7 +1987,7 @@ gtk_combo_box_set_active_internal (GtkComboBox *combo_box,
if (!path)
{
gtk_menu_set_active (GTK_MENU (priv->popup_widget), -1);
gtk_tree_popover_set_active (GTK_TREE_POPOVER (priv->popup_widget), -1);
if (priv->cell_view)
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (priv->cell_view), NULL);
@ -2062,13 +2004,11 @@ gtk_combo_box_set_active_internal (GtkComboBox *combo_box,
priv->active_row =
gtk_tree_row_reference_new (priv->model, path);
/* FIXME handle nested menus better */
gtk_menu_set_active (GTK_MENU (priv->popup_widget),
gtk_tree_path_get_indices (path)[0]);
gtk_tree_popover_set_active (GTK_TREE_POPOVER (priv->popup_widget),
gtk_tree_path_get_indices (path)[0]);
if (priv->cell_view)
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (priv->cell_view),
path);
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (priv->cell_view), path);
}
g_signal_emit (combo_box, combo_box_signals[CHANGED], 0);
@ -2176,8 +2116,7 @@ gtk_combo_box_set_model (GtkComboBox *combo_box,
G_CALLBACK (gtk_combo_box_model_row_changed),
combo_box);
_gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget),
priv->model);
gtk_tree_popover_set_model (GTK_TREE_POPOVER (priv->popup_widget), priv->model);
if (priv->cell_view)
gtk_cell_view_set_model (GTK_CELL_VIEW (priv->cell_view),
@ -2499,8 +2438,7 @@ gtk_combo_box_dispose (GObject* object)
g_signal_handlers_disconnect_by_func (priv->popup_widget,
gtk_combo_box_menu_hide,
combo_box);
gtk_menu_detach (GTK_MENU (priv->popup_widget));
priv->popup_widget = NULL;
g_clear_pointer (&priv->popup_widget, gtk_widget_unparent);
}
gtk_combo_box_unset_model (combo_box);
@ -2681,9 +2619,9 @@ gtk_combo_box_set_row_separator_func (GtkComboBox *combo_box,
priv->row_separator_data = data;
priv->row_separator_destroy = destroy;
/* Make the TreeMenu rebuild itself using the new separator func */
_gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget), NULL);
_gtk_tree_menu_set_model (GTK_TREE_MENU (priv->popup_widget), priv->model);
gtk_tree_popover_set_row_separator_func (GTK_TREE_POPOVER (priv->popup_widget),
(GtkTreeViewRowSeparatorFunc)gtk_combo_box_row_separator_func,
combo_box, NULL);
gtk_widget_queue_draw (GTK_WIDGET (combo_box));
}

View File

@ -55,7 +55,6 @@
#include "gtkpopover.h"
#include "gtkprivate.h"
#include "gtkprogressbar.h"
#include "gtkseparatormenuitem.h"
#include "gtkselection.h"
#include "gtksettings.h"
#include "gtksnapshot.h"

View File

@ -160,7 +160,6 @@ typedef enum
ROW_TYPE_CURRENT_FOLDER,
ROW_TYPE_OTHER_SEPARATOR,
ROW_TYPE_OTHER,
ROW_TYPE_EMPTY_SELECTION,
ROW_TYPE_INVALID = -1
}
@ -292,7 +291,6 @@ static void model_free_row_data (GtkFileChooserButton *button,
GtkTreeIter *iter);
static void model_add_special (GtkFileChooserButton *button);
static void model_add_other (GtkFileChooserButton *button);
static void model_add_empty_selection (GtkFileChooserButton *button);
static void model_add_volumes (GtkFileChooserButton *button,
GSList *volumes);
static void model_add_bookmarks (GtkFileChooserButton *button,
@ -326,9 +324,6 @@ static void bookmarks_changed_cb (gpointer user_data);
static void combo_box_changed_cb (GtkComboBox *combo_box,
gpointer user_data);
static void combo_box_notify_popup_shown_cb (GObject *object,
GParamSpec *pspec,
gpointer user_data);
static void button_clicked_cb (GtkButton *real_button,
gpointer user_data);
@ -478,12 +473,9 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
priv->combo_box = gtk_combo_box_new ();
g_signal_connect (priv->combo_box, "changed", G_CALLBACK (combo_box_changed_cb), button);
g_signal_connect (priv->combo_box, "notify::popup-shown", G_CALLBACK (combo_box_notify_popup_shown_cb), button);
priv->icon_cell = gtk_cell_renderer_pixbuf_new ();
priv->name_cell = gtk_cell_renderer_text_new ();
g_object_set (priv->name_cell,
"xpad", 6,
NULL);
g_object_set (priv->name_cell, "xpad", 6, NULL);
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->combo_box), priv->icon_cell, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->combo_box),
@ -838,8 +830,6 @@ gtk_file_chooser_button_constructed (GObject *object)
model_add_other (button);
model_add_empty_selection (button);
priv->filter_model = gtk_tree_model_filter_new (priv->model, NULL);
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->filter_model),
filter_model_visible_func,
@ -1615,9 +1605,6 @@ model_get_type_position (GtkFileChooserButton *button,
retval++;
if (row_type == ROW_TYPE_EMPTY_SELECTION)
return retval;
g_assert_not_reached ();
return -1;
}
@ -2058,18 +2045,20 @@ model_add_other (GtkFileChooserButton *button)
GtkListStore *store;
GtkTreeIter iter;
gint pos;
GIcon *icon;
store = GTK_LIST_STORE (priv->model);
pos = model_get_type_position (button, ROW_TYPE_OTHER_SEPARATOR);
icon = g_themed_icon_new ("document-open-symbolic");
gtk_list_store_insert (store, &iter, pos);
gtk_list_store_set (store, &iter,
ICON_COLUMN, NULL,
DISPLAY_NAME_COLUMN, NULL,
TYPE_COLUMN, ROW_TYPE_OTHER_SEPARATOR,
DATA_COLUMN, NULL,
IS_FOLDER_COLUMN, FALSE,
-1);
ICON_COLUMN, icon,
DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
TYPE_COLUMN, ROW_TYPE_OTHER_SEPARATOR,
DATA_COLUMN, NULL,
IS_FOLDER_COLUMN, FALSE,
-1);
priv->has_other_separator = TRUE;
pos++;
@ -2081,29 +2070,6 @@ model_add_other (GtkFileChooserButton *button)
DATA_COLUMN, NULL,
IS_FOLDER_COLUMN, FALSE,
-1);
}
static void
model_add_empty_selection (GtkFileChooserButton *button)
{
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
GtkListStore *store;
GtkTreeIter iter;
gint pos;
GIcon *icon;
store = GTK_LIST_STORE (priv->model);
pos = model_get_type_position (button, ROW_TYPE_EMPTY_SELECTION);
icon = g_themed_icon_new ("document-open-symbolic");
gtk_list_store_insert (store, &iter, pos);
gtk_list_store_set (store, &iter,
ICON_COLUMN, icon,
DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
TYPE_COLUMN, ROW_TYPE_EMPTY_SELECTION,
DATA_COLUMN, NULL,
IS_FOLDER_COLUMN, FALSE,
-1);
g_object_unref (icon);
}
@ -2208,34 +2174,6 @@ filter_model_visible_func (GtkTreeModel *model,
}
}
break;
case ROW_TYPE_EMPTY_SELECTION:
{
gboolean popup_shown;
g_object_get (priv->combo_box,
"popup-shown", &popup_shown,
NULL);
if (popup_shown)
retval = FALSE;
else
{
GFile *selected;
/* When the combo box is not popped up... */
selected = get_selected_file (button);
if (selected)
retval = FALSE; /* ... nonempty selection means the ROW_TYPE_EMPTY_SELECTION is *not* visible... */
else
retval = TRUE; /* ... and empty selection means the ROW_TYPE_EMPTY_SELECTION *is* visible */
if (selected)
g_object_unref (selected);
}
break;
}
default:
retval = TRUE;
break;
@ -2372,7 +2310,7 @@ update_combo_box (GtkFileChooserButton *button)
{
/* No selection; switch to that row */
pos = model_get_type_position (button, ROW_TYPE_EMPTY_SELECTION);
pos = model_get_type_position (button, ROW_TYPE_OTHER_SEPARATOR);
}
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
@ -2731,51 +2669,6 @@ combo_box_changed_cb (GtkComboBox *combo_box,
g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
}
/* Calback for the "notify::popup-shown" signal on the combo box.
* When the combo is popped up, we dont want the ROW_TYPE_EMPTY_SELECTION to be visible
* at all; otherwise we would be showing a (None) item in the combo boxs popup.
*
* However, when the combo box is *not* popped up, we want the empty-selection row
* to be visible depending on the selection.
*
* Since all that is done through the filter_model_visible_func(), this means
* that we need to refilter the model when the combo box pops up - hence the
* present signal handler.
*/
static void
combo_box_notify_popup_shown_cb (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
gboolean popup_shown;
g_object_get (priv->combo_box,
"popup-shown", &popup_shown,
NULL);
/* Indicate that the ROW_TYPE_EMPTY_SELECTION will change visibility... */
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model));
/* If the combo box popup got dismissed, go back to showing the ROW_TYPE_EMPTY_SELECTION if needed */
if (!popup_shown)
{
GFile *selected = get_selected_file (button);
if (!selected)
{
int pos;
pos = model_get_type_position (button, ROW_TYPE_EMPTY_SELECTION);
select_combo_box_row_no_notify (button, pos);
}
else
g_object_unref (selected);
}
}
/* Button */
static void
button_clicked_cb (GtkButton *real_button,

View File

@ -28,7 +28,6 @@
#include "gtkcelllayout.h"
#include "gtkcellrendererpixbuf.h"
#include "gtkcellrenderertext.h"
#include "gtkcheckmenuitem.h"
#include "gtkcomboboxtext.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkdragsource.h"
@ -55,7 +54,6 @@
#include "gtkprivate.h"
#include "gtkrecentmanager.h"
#include "gtksearchentryprivate.h"
#include "gtkseparatormenuitem.h"
#include "gtksettings.h"
#include "gtksizegroup.h"
#include "gtksizerequest.h"

View File

@ -405,7 +405,6 @@ _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar)
button = gtk_menu_button_new ();
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu);
gtk_menu_button_set_use_popover (GTK_MENU_BUTTON (button), TRUE);
gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton");
gtk_style_context_add_class (gtk_widget_get_style_context (button), "appmenu");
image = gtk_image_new ();

View File

@ -41,12 +41,9 @@
#include "gtkintl.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkmenuitem.h"
#include "gtkmenushellprivate.h"
#include "gtknotebook.h"
#include "gtkpango.h"
#include "gtkprivate.h"
#include "gtkseparatormenuitem.h"
#include "gtkshow.h"
#include "gtksnapshot.h"
#include "gtkstylecontextprivate.h"
@ -74,8 +71,7 @@
* @Title: GtkLabel
*
* The #GtkLabel widget displays a small amount of text. As the name
* implies, most labels are used to label another widget such as a
* #GtkButton, a #GtkMenuItem, or a #GtkComboBox.
* implies, most labels are used to label another widget such as a #GtkButton.
*
* # CSS nodes
*
@ -1811,8 +1807,7 @@ gtk_label_mnemonic_activate (GtkWidget *widget,
{
if (gtk_widget_get_can_focus (parent) ||
(!group_cycling && GTK_WIDGET_GET_CLASS (parent)->activate_signal) ||
GTK_IS_NOTEBOOK (gtk_widget_get_parent (parent)) ||
GTK_IS_MENU_ITEM (parent))
GTK_IS_NOTEBOOK (gtk_widget_get_parent (parent)))
return gtk_widget_mnemonic_activate (parent, group_cycling);
parent = gtk_widget_get_parent (parent);
}
@ -1831,9 +1826,6 @@ gtk_label_setup_mnemonic (GtkLabel *label,
{
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
GtkWidget *widget = GTK_WIDGET (label);
GtkWidget *mnemonic_menu;
mnemonic_menu = g_object_get_qdata (G_OBJECT (label), quark_mnemonic_menu);
if (last_key != GDK_KEY_VoidSymbol)
{
@ -1844,13 +1836,6 @@ gtk_label_setup_mnemonic (GtkLabel *label,
widget);
priv->mnemonic_window = NULL;
}
if (mnemonic_menu)
{
_gtk_menu_shell_remove_mnemonic (GTK_MENU_SHELL (mnemonic_menu),
last_key,
widget);
mnemonic_menu = NULL;
}
}
if (priv->mnemonic_keyval == GDK_KEY_VoidSymbol)
@ -1858,32 +1843,7 @@ gtk_label_setup_mnemonic (GtkLabel *label,
connect_mnemonics_visible_notify (GTK_LABEL (widget));
if (GTK_IS_WINDOW (toplevel))
{
GtkWidget *menu_shell;
menu_shell = gtk_widget_get_ancestor (widget,
GTK_TYPE_MENU_SHELL);
if (menu_shell)
{
_gtk_menu_shell_add_mnemonic (GTK_MENU_SHELL (menu_shell),
priv->mnemonic_keyval,
widget);
mnemonic_menu = menu_shell;
}
if (!GTK_IS_MENU (menu_shell))
{
gtk_window_add_mnemonic (GTK_WINDOW (toplevel),
priv->mnemonic_keyval,
widget);
priv->mnemonic_window = GTK_WINDOW (toplevel);
}
}
done:
g_object_set_qdata (G_OBJECT (label), quark_mnemonic_menu, mnemonic_menu);
done:;
}
static void

View File

@ -30,7 +30,6 @@
#endif
#include <gtk/gtkwindow.h>
#include <gtk/gtkmenu.h>
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS

View File

@ -119,7 +119,6 @@
#include "gtkdndprivate.h"
#include "gtkmain.h"
#include "gtkmediafileprivate.h"
#include "gtkmenu.h"
#include "gtkmodulesprivate.h"
#include "gtkprivate.h"
#include "gtkrecentmanager.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,140 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_MENU_H__
#define __GTK_MENU_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkaccelgroup.h>
#include <gtk/gtkmenushell.h>
G_BEGIN_DECLS
#define GTK_TYPE_MENU (gtk_menu_get_type ())
#define GTK_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU, GtkMenu))
#define GTK_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU))
typedef struct _GtkMenu GtkMenu;
/**
* GtkMenuDetachFunc:
* @attach_widget: the #GtkWidget that the menu is being detached from.
* @menu: the #GtkMenu being detached.
*
* A user function supplied when calling gtk_menu_attach_to_widget() which
* will be called when the menu is later detached from the widget.
*/
typedef void (*GtkMenuDetachFunc) (GtkWidget *attach_widget,
GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
GType gtk_menu_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_new (void);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_new_from_model (GMenuModel *model);
GDK_AVAILABLE_IN_ALL
void gtk_menu_popup_at_rect (GtkMenu *menu,
GdkSurface *rect_surface,
const GdkRectangle *rect,
GdkGravity rect_anchor,
GdkGravity menu_anchor,
const GdkEvent *trigger_event);
GDK_AVAILABLE_IN_ALL
void gtk_menu_popup_at_widget (GtkMenu *menu,
GtkWidget *widget,
GdkGravity widget_anchor,
GdkGravity menu_anchor,
const GdkEvent *trigger_event);
GDK_AVAILABLE_IN_ALL
void gtk_menu_popup_at_pointer (GtkMenu *menu,
const GdkEvent *trigger_event);
GDK_AVAILABLE_IN_ALL
void gtk_menu_reposition (GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
void gtk_menu_popdown (GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_get_active (GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
void gtk_menu_set_active (GtkMenu *menu,
guint index);
GDK_AVAILABLE_IN_ALL
void gtk_menu_set_accel_group (GtkMenu *menu,
GtkAccelGroup *accel_group);
GDK_AVAILABLE_IN_ALL
GtkAccelGroup* gtk_menu_get_accel_group (GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
void gtk_menu_set_accel_path (GtkMenu *menu,
const gchar *accel_path);
GDK_AVAILABLE_IN_ALL
const gchar* gtk_menu_get_accel_path (GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
void gtk_menu_attach_to_widget (GtkMenu *menu,
GtkWidget *attach_widget,
GtkMenuDetachFunc detacher);
GDK_AVAILABLE_IN_ALL
void gtk_menu_detach (GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_get_attach_widget (GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
void gtk_menu_reorder_child (GtkMenu *menu,
GtkWidget *child,
gint position);
GDK_AVAILABLE_IN_ALL
void gtk_menu_set_monitor (GtkMenu *menu,
gint monitor_num);
GDK_AVAILABLE_IN_ALL
gint gtk_menu_get_monitor (GtkMenu *menu);
GDK_AVAILABLE_IN_ALL
void gtk_menu_place_on_monitor (GtkMenu *menu,
GdkMonitor *monitor);
GDK_AVAILABLE_IN_ALL
GList* gtk_menu_get_for_attach_widget (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
void gtk_menu_set_reserve_toggle_size (GtkMenu *menu,
gboolean reserve_toggle_size);
GDK_AVAILABLE_IN_ALL
gboolean gtk_menu_get_reserve_toggle_size (GtkMenu *menu);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenu, g_object_unref)
G_END_DECLS
#endif /* __GTK_MENU_H__ */

View File

@ -1,489 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
/**
* SECTION:gtkmenubar
* @Title: GtkMenuBar
* @Short_description: A subclass of GtkMenuShell which holds GtkMenuItem widgets
* @See_also: #GtkMenuShell, #GtkMenu, #GtkMenuItem
*
* The #GtkMenuBar is a subclass of #GtkMenuShell which contains one or
* more #GtkMenuItems. The result is a standard menu bar which can hold
* many menu items.
*
* # CSS nodes
*
* GtkMenuBar has a single CSS node with name menubar.
*/
#include "config.h"
#include "gtkmenubar.h"
#include "gtkmenubarprivate.h"
#include "gtkboxlayout.h"
#include "gtkbindings.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkmenuitemprivate.h"
#include "gtkmenuprivate.h"
#include "gtkmenushellprivate.h"
#include "gtksettings.h"
#include "gtksizerequest.h"
#include "gtkwindow.h"
#include "gtkcontainerprivate.h"
#include "gtkcheckmenuitem.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
#define MENU_BAR_POPUP_DELAY 0
typedef struct _GtkMenuBarPrivate GtkMenuBarPrivate;
typedef struct _GtkMenuBarClass GtkMenuBarClass;
struct _GtkMenuBar
{
GtkMenuShell menu_shell;
int toggle_size;
};
struct _GtkMenuBarClass
{
GtkMenuShellClass parent_class;
};
static void gtk_menu_bar_add (GtkContainer *container,
GtkWidget *widget);
static void gtk_menu_bar_remove (GtkContainer *container,
GtkWidget *widget);
static void gtk_menu_bar_root (GtkWidget *widget);
static void gtk_menu_bar_unroot (GtkWidget *widget);
static gint gtk_menu_bar_get_popup_delay (GtkMenuShell *menu_shell);
static void gtk_menu_bar_move_current (GtkMenuShell *menu_shell,
GtkMenuDirectionType direction);
static void gtk_menu_bar_insert (GtkMenuShell *menu_shell,
GtkWidget *child,
gint position);
G_DEFINE_TYPE (GtkMenuBar, gtk_menu_bar, GTK_TYPE_MENU_SHELL)
static GList *
gtk_menu_bar_get_items (GtkMenuShell *menu_shell)
{
GtkMenuBar *menu_bar = GTK_MENU_BAR (menu_shell);
GList *list = NULL;
GtkWidget *child;
for (child = gtk_widget_get_last_child (GTK_WIDGET (menu_bar));
child != NULL;
child = gtk_widget_get_prev_sibling (child))
{
list = g_list_prepend (list, child);
}
return list;
}
static void
gtk_menu_bar_finalize (GObject *object)
{
G_OBJECT_CLASS (gtk_menu_bar_parent_class)->finalize (object);
}
static void
gtk_menu_bar_dispose (GObject *object)
{
GtkMenuBar *menu_bar = GTK_MENU_BAR (object);
GtkWidget *child;
child = gtk_widget_get_first_child (GTK_WIDGET (menu_bar));
while (child)
{
GtkWidget *next = gtk_widget_get_next_sibling (child);
gtk_widget_unparent (child);
child = next;
}
G_OBJECT_CLASS (gtk_menu_bar_parent_class)->dispose (object);
}
static void
gtk_menu_bar_forall (GtkContainer *container,
GtkCallback callback,
gpointer data)
{
GtkMenuBar *menu_bar = GTK_MENU_BAR (container);
GtkWidget *child;
child = gtk_widget_get_first_child (GTK_WIDGET (menu_bar));
while (child)
{
GtkWidget *next = gtk_widget_get_next_sibling (child);
(*callback) (child, data);
child = next;
}
}
static void
gtk_menu_bar_class_init (GtkMenuBarClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
GtkMenuShellClass *menu_shell_class = GTK_MENU_SHELL_CLASS (class);
GtkBindingSet *binding_set;
object_class->finalize = gtk_menu_bar_finalize;
object_class->dispose = gtk_menu_bar_dispose;
widget_class->root = gtk_menu_bar_root;
widget_class->unroot = gtk_menu_bar_unroot;
container_class->add = gtk_menu_bar_add;
container_class->remove = gtk_menu_bar_remove;
container_class->forall = gtk_menu_bar_forall;
menu_shell_class->insert = gtk_menu_bar_insert;
menu_shell_class->submenu_placement = GTK_TOP_BOTTOM;
menu_shell_class->get_popup_delay = gtk_menu_bar_get_popup_delay;
menu_shell_class->move_current = gtk_menu_bar_move_current;
menu_shell_class->get_items = gtk_menu_bar_get_items;
binding_set = gtk_binding_set_by_class (class);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_Left, 0,
"move-current", 1,
GTK_TYPE_MENU_DIRECTION_TYPE,
GTK_MENU_DIR_PREV);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_KP_Left, 0,
"move-current", 1,
GTK_TYPE_MENU_DIRECTION_TYPE,
GTK_MENU_DIR_PREV);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_Right, 0,
"move-current", 1,
GTK_TYPE_MENU_DIRECTION_TYPE,
GTK_MENU_DIR_NEXT);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_KP_Right, 0,
"move-current", 1,
GTK_TYPE_MENU_DIRECTION_TYPE,
GTK_MENU_DIR_NEXT);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_Up, 0,
"move-current", 1,
GTK_TYPE_MENU_DIRECTION_TYPE,
GTK_MENU_DIR_PARENT);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_KP_Up, 0,
"move-current", 1,
GTK_TYPE_MENU_DIRECTION_TYPE,
GTK_MENU_DIR_PARENT);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_Down, 0,
"move-current", 1,
GTK_TYPE_MENU_DIRECTION_TYPE,
GTK_MENU_DIR_CHILD);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_KP_Down, 0,
"move-current", 1,
GTK_TYPE_MENU_DIRECTION_TYPE,
GTK_MENU_DIR_CHILD);
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_MENU_BAR);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
gtk_widget_class_set_css_name (widget_class, I_("menubar"));
}
static void
gtk_menu_bar_init (GtkMenuBar *menu_bar)
{
}
/**
* gtk_menu_bar_new:
*
* Creates a new #GtkMenuBar
*
* Returns: the new menu bar, as a #GtkWidget
*/
GtkWidget*
gtk_menu_bar_new (void)
{
return g_object_new (GTK_TYPE_MENU_BAR, NULL);
}
static GList *
get_menu_bars (GtkWindow *window)
{
return g_object_get_data (G_OBJECT (window), "gtk-menu-bar-list");
}
GList *
_gtk_menu_bar_get_viewable_menu_bars (GtkWindow *window)
{
GList *menu_bars;
GList *viewable_menu_bars = NULL;
for (menu_bars = get_menu_bars (window);
menu_bars;
menu_bars = menu_bars->next)
{
GtkWidget *widget = menu_bars->data;
gboolean viewable = TRUE;
while (widget)
{
if (!gtk_widget_get_mapped (widget))
viewable = FALSE;
widget = gtk_widget_get_parent (widget);
}
if (viewable)
viewable_menu_bars = g_list_prepend (viewable_menu_bars, menu_bars->data);
}
return g_list_reverse (viewable_menu_bars);
}
static void
set_menu_bars (GtkWindow *window,
GList *menubars)
{
g_object_set_data (G_OBJECT (window), I_("gtk-menu-bar-list"), menubars);
}
static void
add_to_window (GtkWindow *window,
GtkMenuBar *menubar)
{
GList *menubars = get_menu_bars (window);
set_menu_bars (window, g_list_prepend (menubars, menubar));
}
static void
remove_from_window (GtkWindow *window,
GtkMenuBar *menubar)
{
GList *menubars = get_menu_bars (window);
menubars = g_list_remove (menubars, menubar);
set_menu_bars (window, menubars);
}
static void
gtk_menu_bar_root (GtkWidget *widget)
{
GtkMenuBar *menubar = GTK_MENU_BAR (widget);
GtkWidget *toplevel;
GTK_WIDGET_CLASS (gtk_menu_bar_parent_class)->root (widget);
toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
add_to_window (GTK_WINDOW (toplevel), menubar);
}
static void
gtk_menu_bar_unroot (GtkWidget *widget)
{
GtkMenuBar *menubar = GTK_MENU_BAR (widget);
GtkWidget *toplevel;
toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
remove_from_window (GTK_WINDOW (toplevel), menubar);
GTK_WIDGET_CLASS (gtk_menu_bar_parent_class)->unroot (widget);
}
/**
* _gtk_menu_bar_cycle_focus:
* @menubar: a #GtkMenuBar
* @dir: direction in which to cycle the focus
*
* Move the focus between menubars in the toplevel.
**/
void
_gtk_menu_bar_cycle_focus (GtkMenuBar *menubar,
GtkDirectionType dir)
{
GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (menubar)));
GtkMenuItem *to_activate = NULL;
if (GTK_IS_WINDOW (toplevel))
{
GList *tmp_menubars = _gtk_menu_bar_get_viewable_menu_bars (GTK_WINDOW (toplevel));
GList *l;
GPtrArray *menubars;
gboolean found;
guint index;
menubars = g_ptr_array_sized_new (g_list_length (tmp_menubars));
for (l = tmp_menubars; l; l = l->next)
g_ptr_array_add (menubars, l->data);
gtk_widget_focus_sort (toplevel, dir, menubars);
found = g_ptr_array_find (menubars, menubar, &index);
if (found && index < menubars->len - 1)
{
GtkWidget *next = g_ptr_array_index (menubars, index + 1);
GtkMenuShell *new_menushell = GTK_MENU_SHELL (next);
GList *children = gtk_menu_shell_get_items (new_menushell);
if (children)
to_activate = children->data;
g_list_free (children);
}
g_ptr_array_free (menubars, TRUE);
}
gtk_menu_shell_cancel (GTK_MENU_SHELL (menubar));
if (to_activate)
g_signal_emit_by_name (to_activate, "activate_item");
}
static gint
gtk_menu_bar_get_popup_delay (GtkMenuShell *menu_shell)
{
return MENU_BAR_POPUP_DELAY;
}
static void
gtk_menu_bar_move_current (GtkMenuShell *menu_shell,
GtkMenuDirectionType direction)
{
GtkMenuBar *menubar = GTK_MENU_BAR (menu_shell);
if (gtk_widget_get_direction (GTK_WIDGET (menubar)) == GTK_TEXT_DIR_RTL)
{
switch (direction)
{
case GTK_MENU_DIR_PREV:
direction = GTK_MENU_DIR_NEXT;
break;
case GTK_MENU_DIR_NEXT:
direction = GTK_MENU_DIR_PREV;
break;
case GTK_MENU_DIR_PARENT:
case GTK_MENU_DIR_CHILD:
default:
break;
}
}
GTK_MENU_SHELL_CLASS (gtk_menu_bar_parent_class)->move_current (menu_shell, direction);
}
/**
* gtk_menu_bar_new_from_model:
* @model: a #GMenuModel
*
* Creates a new #GtkMenuBar and populates it with menu items
* and submenus according to @model.
*
* The created menu items are connected to actions found in the
* #GtkApplicationWindow to which the menu bar belongs - typically
* by means of being contained within the #GtkApplicationWindows
* widget hierarchy.
*
* Returns: a new #GtkMenuBar
*/
GtkWidget *
gtk_menu_bar_new_from_model (GMenuModel *model)
{
GtkWidget *menubar;
g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL);
menubar = gtk_menu_bar_new ();
gtk_menu_shell_bind_model (GTK_MENU_SHELL (menubar), model, NULL, FALSE);
return menubar;
}
static void
gtk_menu_bar_add (GtkContainer *container,
GtkWidget *widget)
{
gtk_widget_set_parent (widget, GTK_WIDGET (container));
}
static void
gtk_menu_bar_remove (GtkContainer *container,
GtkWidget *widget)
{
gtk_widget_unparent (widget);
GTK_CONTAINER_CLASS (gtk_menu_bar_parent_class)->remove (container, widget);
}
static void
gtk_menu_bar_reorder_child (GtkMenuBar *menu_bar,
GtkWidget *child,
gint position)
{
GtkWidget *sibling = NULL;
int i;
if (position < 0)
sibling = gtk_widget_get_last_child (GTK_WIDGET (menu_bar));
for (i = 0; i < position; i++)
{
if (sibling == NULL)
sibling = gtk_widget_get_first_child (GTK_WIDGET (menu_bar));
else
sibling = gtk_widget_get_next_sibling (sibling);
}
gtk_widget_insert_after (child, GTK_WIDGET (menu_bar), sibling);
}
static void
gtk_menu_bar_insert (GtkMenuShell *menu_shell,
GtkWidget *child,
gint position)
{
GtkMenuBar *menu_bar = GTK_MENU_BAR (menu_shell);
gtk_widget_set_parent (child, GTK_WIDGET (menu_bar));
gtk_menu_bar_reorder_child (menu_bar, child, position);
}

View File

@ -1,56 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_MENU_BAR_H__
#define __GTK_MENU_BAR_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkmenushell.h>
G_BEGIN_DECLS
#define GTK_TYPE_MENU_BAR (gtk_menu_bar_get_type ())
#define GTK_MENU_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_BAR, GtkMenuBar))
#define GTK_IS_MENU_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_BAR))
typedef struct _GtkMenuBar GtkMenuBar;
GDK_AVAILABLE_IN_ALL
GType gtk_menu_bar_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_bar_new (void);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_bar_new_from_model (GMenuModel *model);
G_END_DECLS
#endif /* __GTK_MENU_BAR_H__ */

View File

@ -1,43 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_MENU_BAR_PRIVATE_H__
#define __GTK_MENU_BAR_PRIVATE_H__
#include <gtk/gtkmenubar.h>
G_BEGIN_DECLS
void _gtk_menu_bar_cycle_focus (GtkMenuBar *menubar,
GtkDirectionType dir);
GList* _gtk_menu_bar_get_viewable_menu_bars (GtkWindow *window);
G_END_DECLS
#endif /* __GTK_MENU_BAR_PRIVATE_H__ */

View File

@ -24,8 +24,8 @@
* @title: GtkMenuButton
*
* The #GtkMenuButton widget is used to display a popup when clicked on.
* This popup can be provided either as a #GtkMenu, a #GtkPopover or an
* abstract #GMenuModel.
* This popup can be provided either as a #GtkPopover or as an abstract
* #GMenuModel.
*
* The #GtkMenuButton widget can show either an icon (set with the
* #GtkMenuButton:icon-name property) or a label (set with the
@ -146,7 +146,6 @@ struct _GtkMenuButtonClass
struct _GtkMenuButtonPrivate
{
GtkWidget *button;
GtkWidget *menu; /* The menu and the popover are mutually exclusive */
GtkWidget *popover; /* Only one at a time can be set */
GMenuModel *model;
@ -157,18 +156,14 @@ struct _GtkMenuButtonPrivate
GtkWidget *align_widget;
GtkWidget *arrow_widget;
GtkArrowType arrow_type;
guint use_popover : 1;
};
enum
{
PROP_0,
PROP_POPUP,
PROP_MENU_MODEL,
PROP_ALIGN_WIDGET,
PROP_DIRECTION,
PROP_USE_POPOVER,
PROP_POPOVER,
PROP_ICON_NAME,
PROP_LABEL,
@ -192,9 +187,6 @@ gtk_menu_button_set_property (GObject *object,
switch (property_id)
{
case PROP_POPUP:
gtk_menu_button_set_popup (self, g_value_get_object (value));
break;
case PROP_MENU_MODEL:
gtk_menu_button_set_menu_model (self, g_value_get_object (value));
break;
@ -204,9 +196,6 @@ gtk_menu_button_set_property (GObject *object,
case PROP_DIRECTION:
gtk_menu_button_set_direction (self, g_value_get_enum (value));
break;
case PROP_USE_POPOVER:
gtk_menu_button_set_use_popover (self, g_value_get_boolean (value));
break;
case PROP_POPOVER:
gtk_menu_button_set_popover (self, g_value_get_object (value));
break;
@ -234,9 +223,6 @@ gtk_menu_button_get_property (GObject *object,
switch (property_id)
{
case PROP_POPUP:
g_value_set_object (value, priv->menu);
break;
case PROP_MENU_MODEL:
g_value_set_object (value, priv->model);
break;
@ -246,9 +232,6 @@ gtk_menu_button_get_property (GObject *object,
case PROP_DIRECTION:
g_value_set_enum (value, priv->arrow_type);
break;
case PROP_USE_POPOVER:
g_value_set_boolean (value, priv->use_popover);
break;
case PROP_POPOVER:
g_value_set_object (value, priv->popover);
break;
@ -275,171 +258,11 @@ gtk_menu_button_state_flags_changed (GtkWidget *widget,
if (!gtk_widget_is_sensitive (widget))
{
if (priv->menu)
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
else if (priv->popover)
if (priv->popover)
gtk_widget_hide (priv->popover);
}
}
static void
popup_menu (GtkMenuButton *menu_button,
GdkEvent *event)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
GdkGravity widget_anchor = GDK_GRAVITY_SOUTH_WEST;
GdkGravity menu_anchor = GDK_GRAVITY_NORTH_WEST;
if (!priv->menu)
return;
switch (priv->arrow_type)
{
case GTK_ARROW_UP:
g_object_set (priv->menu,
"anchor-hints", (GDK_ANCHOR_FLIP_Y |
GDK_ANCHOR_SLIDE |
GDK_ANCHOR_RESIZE),
NULL);
switch (gtk_widget_get_halign (priv->menu))
{
default:
case GTK_ALIGN_FILL:
case GTK_ALIGN_START:
case GTK_ALIGN_BASELINE:
widget_anchor = GDK_GRAVITY_NORTH_WEST;
menu_anchor = GDK_GRAVITY_SOUTH_WEST;
break;
case GTK_ALIGN_END:
widget_anchor = GDK_GRAVITY_NORTH_EAST;
menu_anchor = GDK_GRAVITY_SOUTH_EAST;
break;
case GTK_ALIGN_CENTER:
widget_anchor = GDK_GRAVITY_NORTH;
menu_anchor = GDK_GRAVITY_SOUTH;
break;
}
break;
case GTK_ARROW_DOWN:
/* In the common case the menu button is showing a dropdown menu, set the
* corresponding type hint on the toplevel, so the WM can omit the top side
* of the shadows.
*/
g_object_set (priv->menu,
"anchor-hints", (GDK_ANCHOR_FLIP_Y |
GDK_ANCHOR_SLIDE |
GDK_ANCHOR_RESIZE),
"menu-type-hint", GDK_SURFACE_TYPE_HINT_DROPDOWN_MENU,
NULL);
switch (gtk_widget_get_halign (priv->menu))
{
default:
case GTK_ALIGN_FILL:
case GTK_ALIGN_START:
case GTK_ALIGN_BASELINE:
widget_anchor = GDK_GRAVITY_SOUTH_WEST;
menu_anchor = GDK_GRAVITY_NORTH_WEST;
break;
case GTK_ALIGN_END:
widget_anchor = GDK_GRAVITY_SOUTH_EAST;
menu_anchor = GDK_GRAVITY_NORTH_EAST;
break;
case GTK_ALIGN_CENTER:
widget_anchor = GDK_GRAVITY_SOUTH;
menu_anchor = GDK_GRAVITY_NORTH;
break;
}
break;
case GTK_ARROW_LEFT:
g_object_set (priv->menu,
"anchor-hints", (GDK_ANCHOR_FLIP_X |
GDK_ANCHOR_SLIDE |
GDK_ANCHOR_RESIZE),
NULL);
switch (gtk_widget_get_valign (priv->menu))
{
default:
case GTK_ALIGN_FILL:
case GTK_ALIGN_START:
case GTK_ALIGN_BASELINE:
widget_anchor = GDK_GRAVITY_NORTH_WEST;
menu_anchor = GDK_GRAVITY_NORTH_EAST;
break;
case GTK_ALIGN_END:
widget_anchor = GDK_GRAVITY_SOUTH_WEST;
menu_anchor = GDK_GRAVITY_SOUTH_EAST;
break;
case GTK_ALIGN_CENTER:
widget_anchor = GDK_GRAVITY_WEST;
menu_anchor = GDK_GRAVITY_EAST;
break;
}
break;
case GTK_ARROW_RIGHT:
g_object_set (priv->menu,
"anchor-hints", (GDK_ANCHOR_FLIP_X |
GDK_ANCHOR_SLIDE |
GDK_ANCHOR_RESIZE),
NULL);
switch (gtk_widget_get_valign (priv->menu))
{
default:
case GTK_ALIGN_FILL:
case GTK_ALIGN_START:
case GTK_ALIGN_BASELINE:
widget_anchor = GDK_GRAVITY_NORTH_EAST;
menu_anchor = GDK_GRAVITY_NORTH_WEST;
break;
case GTK_ALIGN_END:
widget_anchor = GDK_GRAVITY_SOUTH_EAST;
menu_anchor = GDK_GRAVITY_SOUTH_WEST;
break;
case GTK_ALIGN_CENTER:
widget_anchor = GDK_GRAVITY_EAST;
menu_anchor = GDK_GRAVITY_WEST;
break;
}
break;
case GTK_ARROW_NONE:
g_object_set (priv->menu,
"anchor-hints", (GDK_ANCHOR_FLIP_Y |
GDK_ANCHOR_SLIDE |
GDK_ANCHOR_RESIZE),
NULL);
break;
default:
break;
}
gtk_menu_popup_at_widget (GTK_MENU (priv->menu),
GTK_WIDGET (menu_button),
widget_anchor,
menu_anchor,
event);
}
static void
gtk_menu_button_toggled (GtkMenuButton *menu_button)
{
@ -452,26 +275,7 @@ gtk_menu_button_toggled (GtkMenuButton *menu_button)
priv->create_popup_func (menu_button, priv->create_popup_user_data);
}
if (priv->menu)
{
if (active && !gtk_widget_get_visible (priv->menu))
{
GdkEvent *event;
event = gtk_get_current_event ();
popup_menu (menu_button, event);
if (!event ||
gdk_event_get_event_type (event) == GDK_KEY_PRESS ||
gdk_event_get_event_type (event) == GDK_KEY_RELEASE)
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
if (event)
g_object_unref (event);
}
}
else if (priv->popover)
if (priv->popover)
{
if (active)
gtk_popover_popup (GTK_POPOVER (priv->popover));
@ -523,9 +327,7 @@ gtk_menu_button_focus (GtkWidget *widget,
GtkMenuButton *button = GTK_MENU_BUTTON (widget);
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (button);
if (priv->menu && gtk_widget_get_visible (priv->menu))
return gtk_widget_child_focus (priv->menu, direction);
else if (priv->popover && gtk_widget_get_visible (priv->popover))
if (priv->popover && gtk_widget_get_visible (priv->popover))
return gtk_widget_child_focus (priv->popover, direction);
else
return GTK_WIDGET_CLASS (gtk_menu_button_parent_class)->focus (widget, direction);
@ -546,24 +348,10 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
widget_class->state_flags_changed = gtk_menu_button_state_flags_changed;
widget_class->focus = gtk_menu_button_focus;
/**
* GtkMenuButton:popup:
*
* The #GtkMenu that will be popped up when the button is clicked.
*/
menu_button_props[PROP_POPUP] =
g_param_spec_object ("popup",
P_("Popup"),
P_("The dropdown menu."),
GTK_TYPE_MENU,
GTK_PARAM_READWRITE);
/**
* GtkMenuButton:menu-model:
*
* The #GMenuModel from which the popup will be created.
* Depending on the #GtkMenuButton:use-popover property, that may
* be a menu or a popover.
*
* See gtk_menu_button_set_menu_model() for the interaction with the
* #GtkMenuButton:popup property.
@ -601,19 +389,6 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass)
GTK_ARROW_DOWN,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkMenuButton:use-popover:
*
* Whether to construct a #GtkPopover from the menu model,
* or a #GtkMenu.
*/
menu_button_props[PROP_USE_POPOVER] =
g_param_spec_boolean ("use-popover",
P_("Use a popover"),
P_("Use a popover instead of a menu"),
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkMenuButton:popover:
*
@ -699,7 +474,6 @@ gtk_menu_button_init (GtkMenuButton *menu_button)
GtkStyleContext *context;
priv->arrow_type = GTK_ARROW_DOWN;
priv->use_popover = TRUE;
priv->button = gtk_toggle_button_new ();
gtk_widget_set_parent (priv->button, GTK_WIDGET (menu_button));
@ -727,11 +501,16 @@ gtk_menu_button_new (void)
return g_object_new (GTK_TYPE_MENU_BUTTON, NULL);
}
/* Callback for the "deactivate" signal on the pop-up menu.
* This is used so that we unset the state of the toggle button
* when the pop-up menu disappears.
* Also used for the "close" signal on the popover.
*/
static void
update_sensitivity (GtkMenuButton *menu_button)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
gtk_widget_set_sensitive (priv->button,
priv->popover != NULL ||
priv->create_popup_func != NULL);
}
static gboolean
menu_deactivate_cb (GtkMenuButton *menu_button)
{
@ -742,110 +521,6 @@ menu_deactivate_cb (GtkMenuButton *menu_button)
return TRUE;
}
static void
menu_detacher (GtkWidget *widget,
GtkMenu *menu)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (GTK_MENU_BUTTON (widget));
g_return_if_fail (priv->menu == (GtkWidget *) menu);
priv->menu = NULL;
}
static void
update_sensitivity (GtkMenuButton *menu_button)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
gtk_widget_set_sensitive (priv->button,
priv->menu != NULL ||
priv->popover != NULL ||
priv->create_popup_func != NULL);
}
/**
* gtk_menu_button_set_popup:
* @menu_button: a #GtkMenuButton
* @menu: (nullable): a #GtkMenu, or %NULL to unset and disable the button
*
* Sets the #GtkMenu that will be popped up when the @menu_button is clicked, or
* %NULL to dissociate any existing menu and disable the button.
*
* If #GtkMenuButton:menu-model or #GtkMenuButton:popover are set, those objects
* are dissociated from the @menu_button, and those properties are set to %NULL.
*/
void
gtk_menu_button_set_popup (GtkMenuButton *menu_button,
GtkWidget *menu)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
g_object_freeze_notify (G_OBJECT (menu_button));
g_clear_object (&priv->model);
if (priv->menu == GTK_WIDGET (menu))
return;
if (priv->menu)
{
if (gtk_widget_get_visible (priv->menu))
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
g_signal_handlers_disconnect_by_func (priv->menu,
menu_deactivate_cb,
menu_button);
gtk_menu_detach (GTK_MENU (priv->menu));
}
priv->menu = menu;
if (priv->menu)
{
gtk_menu_attach_to_widget (GTK_MENU (priv->menu), GTK_WIDGET (menu_button),
menu_detacher);
gtk_widget_set_visible (priv->menu, FALSE);
g_signal_connect_swapped (priv->menu, "deactivate",
G_CALLBACK (menu_deactivate_cb), menu_button);
}
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_POPUP]);
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_MENU_MODEL]);
if (menu && priv->popover)
gtk_menu_button_set_popover (menu_button, NULL);
update_sensitivity (menu_button);
g_object_thaw_notify (G_OBJECT (menu_button));
}
/**
* gtk_menu_button_get_popup:
* @menu_button: a #GtkMenuButton
*
* Returns the #GtkMenu that pops out of the button.
* If the button does not use a #GtkMenu, this function
* returns %NULL.
*
* Returns: (nullable) (transfer none): a #GtkMenu or %NULL
*/
GtkMenu *
gtk_menu_button_get_popup (GtkMenuButton *menu_button)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
g_return_val_if_fail (GTK_IS_MENU_BUTTON (menu_button), NULL);
return GTK_MENU (priv->menu);
}
/**
* gtk_menu_button_set_menu_model:
* @menu_button: a #GtkMenuButton
@ -855,14 +530,11 @@ gtk_menu_button_get_popup (GtkMenuButton *menu_button)
* Sets the #GMenuModel from which the popup will be constructed,
* or %NULL to dissociate any existing menu model and disable the button.
*
* Depending on the value of #GtkMenuButton:use-popover, either a
* #GtkMenu will be created with gtk_menu_new_from_model(), or a
* #GtkPopover with gtk_popover_new_from_model(). In either case,
* actions will be connected as documented for these functions.
* A #GtkPopover will be created from the menu model with gtk_popover_menu_new_from_model().
* Actions will be connected as documented for this function.
*
* If #GtkMenuButton:popup or #GtkMenuButton:popover are already set, those
* widgets are dissociated from the @menu_button, and those properties are set
* to %NULL.
* If #GtkMenuButton:popover is already set, it will be dissociated from the @menu_button,
* and the property is set to %NULL.
*/
void
gtk_menu_button_set_menu_model (GtkMenuButton *menu_button,
@ -880,25 +552,13 @@ gtk_menu_button_set_menu_model (GtkMenuButton *menu_button,
if (menu_model)
{
if (priv->use_popover)
{
GtkWidget *popover;
GtkWidget *popover;
popover = gtk_popover_menu_new_from_model (GTK_WIDGET (menu_button), menu_model);
gtk_menu_button_set_popover (menu_button, popover);
}
else
{
GtkWidget *menu;
menu = gtk_menu_new_from_model (menu_model);
gtk_widget_show (menu);
gtk_menu_button_set_popup (menu_button, menu);
}
popover = gtk_popover_menu_new_from_model (GTK_WIDGET (menu_button), menu_model);
gtk_menu_button_set_popover (menu_button, popover);
}
else
{
gtk_menu_button_set_popup (menu_button, NULL);
gtk_menu_button_set_popover (menu_button, NULL);
}
@ -1086,15 +746,6 @@ gtk_menu_button_dispose (GObject *object)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (GTK_MENU_BUTTON (object));
if (priv->menu)
{
g_signal_handlers_disconnect_by_func (priv->menu,
menu_deactivate_cb,
object);
gtk_menu_detach (GTK_MENU (priv->menu));
priv->menu = NULL;
}
if (priv->popover)
{
g_signal_handlers_disconnect_by_func (priv->popover,
@ -1118,59 +769,6 @@ gtk_menu_button_dispose (GObject *object)
G_OBJECT_CLASS (gtk_menu_button_parent_class)->dispose (object);
}
/**
* gtk_menu_button_set_use_popover:
* @menu_button: a #GtkMenuButton
* @use_popover: %TRUE to construct a popover from the menu model
*
* Sets whether to construct a #GtkPopover instead of #GtkMenu
* when gtk_menu_button_set_menu_model() is called. Note that
* this property is only consulted when a new menu model is set.
*/
void
gtk_menu_button_set_use_popover (GtkMenuButton *menu_button,
gboolean use_popover)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
use_popover = use_popover != FALSE;
if (priv->use_popover == use_popover)
return;
priv->use_popover = use_popover;
g_object_freeze_notify (G_OBJECT (menu_button));
if (priv->model)
gtk_menu_button_set_menu_model (menu_button, priv->model);
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_USE_POPOVER]);
g_object_thaw_notify (G_OBJECT (menu_button));
}
/**
* gtk_menu_button_get_use_popover:
* @menu_button: a #GtkMenuButton
*
* Returns whether a #GtkPopover or a #GtkMenu will be constructed
* from the menu model.
*
* Returns: %TRUE if using a #GtkPopover
*/
gboolean
gtk_menu_button_get_use_popover (GtkMenuButton *menu_button)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
g_return_val_if_fail (GTK_IS_MENU_BUTTON (menu_button), FALSE);
return priv->use_popover;
}
/**
* gtk_menu_button_set_popover:
* @menu_button: a #GtkMenuButton
@ -1179,8 +777,8 @@ gtk_menu_button_get_use_popover (GtkMenuButton *menu_button)
* Sets the #GtkPopover that will be popped up when the @menu_button is clicked,
* or %NULL to dissociate any existing popover and disable the button.
*
* If #GtkMenuButton:menu-model or #GtkMenuButton:popup are set, those objects
* are dissociated from the @menu_button, and those properties are set to %NULL.
* If #GtkMenuButton:menu-model is set, the menu model is dissociated from the
* @menu_button, and the property is set to %NULL.
*/
void
gtk_menu_button_set_popover (GtkMenuButton *menu_button,
@ -1222,9 +820,6 @@ gtk_menu_button_set_popover (GtkMenuButton *menu_button,
update_popover_direction (menu_button);
}
if (popover && priv->menu)
gtk_menu_button_set_popup (menu_button, NULL);
update_sensitivity (menu_button);
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_POPOVER]);
@ -1446,14 +1041,13 @@ gtk_menu_button_add_child (GtkMenuButton *menu_button,
* Sets @func to be called when a popup is about to be shown.
* @func should use one of
*
* - gtk_menu_button_set_popup()
* - gtk_menu_button_set_popover()
* - gtk_menu_button_set_menu_model()
*
* to set a popoup for @menu_button.
* to set a popup for @menu_button.
* If @func is non-%NULL, @menu_button will always be sensitive.
*
* Using this function will NOT reset the menu widget attached to @menu_button.
* Using this function will not reset the menu widget attached to @menu_button.
* Instead, this can be done manually in @func.
*/
void

View File

@ -26,7 +26,6 @@
#endif
#include <gtk/gtktogglebutton.h>
#include <gtk/gtkmenu.h>
#include <gtk/gtkpopover.h>
G_BEGIN_DECLS
@ -54,12 +53,6 @@ GType gtk_menu_button_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_menu_button_new (void);
GDK_AVAILABLE_IN_ALL
void gtk_menu_button_set_popup (GtkMenuButton *menu_button,
GtkWidget *menu);
GDK_AVAILABLE_IN_ALL
GtkMenu *gtk_menu_button_get_popup (GtkMenuButton *menu_button);
GDK_AVAILABLE_IN_ALL
void gtk_menu_button_set_popover (GtkMenuButton *menu_button,
GtkWidget *popover);
@ -84,13 +77,6 @@ void gtk_menu_button_set_align_widget (GtkMenuButton *menu_button,
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_menu_button_get_align_widget (GtkMenuButton *menu_button);
GDK_AVAILABLE_IN_ALL
void gtk_menu_button_set_use_popover (GtkMenuButton *menu_button,
gboolean use_popover);
GDK_AVAILABLE_IN_ALL
gboolean gtk_menu_button_get_use_popover (GtkMenuButton *menu_button);
GDK_AVAILABLE_IN_ALL
void gtk_menu_button_set_icon_name (GtkMenuButton *menu_button,
const char *icon_name);

File diff suppressed because it is too large Load Diff

View File

@ -1,158 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_MENU_ITEM_H__
#define __GTK_MENU_ITEM_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkbin.h>
G_BEGIN_DECLS
#define GTK_TYPE_MENU_ITEM (gtk_menu_item_get_type ())
#define GTK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ITEM, GtkMenuItem))
#define GTK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_ITEM, GtkMenuItemClass))
#define GTK_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_ITEM))
#define GTK_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_ITEM))
#define GTK_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_ITEM, GtkMenuItemClass))
typedef struct _GtkMenuItem GtkMenuItem;
typedef struct _GtkMenuItemClass GtkMenuItemClass;
typedef struct _GtkMenuItemPrivate GtkMenuItemPrivate;
struct _GtkMenuItem
{
GtkBin bin;
/*< private >*/
GtkMenuItemPrivate *priv;
};
/**
* GtkMenuItemClass:
* @parent_class: The parent class.
* @hide_on_activate: If %TRUE, then we should always
* hide the menu when the %GtkMenuItem is activated. Otherwise,
* it is up to the caller.
* @activate: Signal emitted when the item is activated.
* @activate_item: Signal emitted when the item is activated, but also
* if the menu item has a submenu.
* @toggle_size_request:
* @toggle_size_allocate:
* @set_label: Sets @text on the #GtkMenuItem label
* @get_label: Gets @text from the #GtkMenuItem label
* @select: Signal emitted when the item is selected.
* @deselect: Signal emitted when the item is deselected.
*/
struct _GtkMenuItemClass
{
GtkBinClass parent_class;
/*< public >*/
/* If the following flag is true, then we should always
* hide the menu when the MenuItem is activated. Otherwise,
* it is up to the caller. For instance, when navigating
* a menu with the keyboard, <Space> doesn't hide, but
* <Return> does.
*/
guint hide_on_activate : 1;
void (* activate) (GtkMenuItem *menu_item);
void (* activate_item) (GtkMenuItem *menu_item);
void (* toggle_size_request) (GtkMenuItem *menu_item,
gint *requisition);
void (* toggle_size_allocate) (GtkMenuItem *menu_item,
gint allocation);
void (* set_label) (GtkMenuItem *menu_item,
const gchar *label);
const gchar * (* get_label) (GtkMenuItem *menu_item);
void (* select) (GtkMenuItem *menu_item);
void (* deselect) (GtkMenuItem *menu_item);
/*< private >*/
gpointer padding[8];
};
GDK_AVAILABLE_IN_ALL
GType gtk_menu_item_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_item_new (void);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_item_new_with_label (const gchar *label);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_item_new_with_mnemonic (const gchar *label);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_set_submenu (GtkMenuItem *menu_item,
GtkWidget *submenu);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_menu_item_get_submenu (GtkMenuItem *menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_select (GtkMenuItem *menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_deselect (GtkMenuItem *menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_activate (GtkMenuItem *menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_toggle_size_request (GtkMenuItem *menu_item,
gint *requisition);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_toggle_size_allocate (GtkMenuItem *menu_item,
gint allocation);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_set_accel_path (GtkMenuItem *menu_item,
const gchar *accel_path);
GDK_AVAILABLE_IN_ALL
const gchar * gtk_menu_item_get_accel_path (GtkMenuItem *menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_set_label (GtkMenuItem *menu_item,
const gchar *label);
GDK_AVAILABLE_IN_ALL
const gchar * gtk_menu_item_get_label (GtkMenuItem *menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_set_use_underline (GtkMenuItem *menu_item,
gboolean setting);
GDK_AVAILABLE_IN_ALL
gboolean gtk_menu_item_get_use_underline (GtkMenuItem *menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_menu_item_set_reserve_indicator (GtkMenuItem *menu_item,
gboolean reserve);
GDK_AVAILABLE_IN_ALL
gboolean gtk_menu_item_get_reserve_indicator (GtkMenuItem *menu_item);
G_END_DECLS
#endif /* __GTK_MENU_ITEM_H__ */

View File

@ -1,63 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_MENU_ITEM_PRIVATE_H__
#define __GTK_MENU_ITEM_PRIVATE_H__
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkmenushell.h>
#include <gtk/gtkactionhelperprivate.h>
#include <gtk/gtkcssnodeprivate.h>
#include <gtk/gtkeventcontrollermotion.h>
G_BEGIN_DECLS
struct _GtkMenuItemPrivate
{
GtkWidget *submenu;
guint16 toggle_size;
guint16 accelerator_width;
guint timer;
const char *accel_path;
GtkActionHelper *action_helper;
GtkWidget *arrow_widget;
guint submenu_placement : 1;
guint submenu_direction : 1;
guint from_menubar : 1;
guint reserve_indicator : 1;
};
void _gtk_menu_item_refresh_accel_path (GtkMenuItem *menu_item,
const gchar *prefix,
GtkAccelGroup *accel_group,
gboolean group_changed);
gboolean _gtk_menu_item_is_selectable (GtkWidget *menu_item);
void _gtk_menu_item_popup_submenu (GtkWidget *menu_item,
gboolean with_delay);
void _gtk_menu_item_popdown_submenu (GtkWidget *menu_item);
GtkMenuShell *
gtk_menu_item_get_menu_shell (GtkMenuItem *menu_item);
G_END_DECLS
#endif /* __GTK_MENU_ITEM_PRIVATE_H__ */

View File

@ -1,96 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_MENU_PRIVATE_H__
#define __GTK_MENU_PRIVATE_H__
#include <gtk/gtkmenu.h>
#include <gtk/gtkcssnodeprivate.h>
#include <gtk/gtkgestureclick.h>
G_BEGIN_DECLS
typedef struct _GtkMenuClass GtkMenuClass;
typedef struct _GtkMenuPrivate GtkMenuPrivate;
struct _GtkMenu
{
GtkMenuShell menu_shell;
GtkMenuPrivate *priv;
};
struct _GtkMenuClass
{
GtkMenuShellClass parent_class;
};
struct _GtkMenuPrivate
{
GtkWidget *parent_menu_item;
GtkWidget *old_active_menu_item;
GtkAccelGroup *accel_group;
const char *accel_path;
GdkSurface *rect_surface;
GdkRectangle rect;
GtkWidget *widget;
GdkGravity rect_anchor;
GdkGravity menu_anchor;
GdkAnchorHints anchor_hints;
gint rect_anchor_dx;
gint rect_anchor_dy;
GdkSurfaceTypeHint menu_type_hint;
guint toggle_size;
guint accel_size;
/* Do _not_ touch these widgets directly. We hide the reference
* count from the toplevel to the menu, so it must be restored
* before operating on these widgets
*/
GtkWidget *toplevel;
GtkWidget *swin;
GtkWidget *box;
guint needs_destruction_ref : 1;
guint ignore_button_release : 1;
guint no_toggle_size : 1;
gint monitor_num;
};
G_GNUC_INTERNAL
void gtk_menu_update_scroll_offset (GtkMenu *menu,
const GdkRectangle *flipped_rect,
const GdkRectangle *final_rect,
gboolean flipped_x,
gboolean flipped_y,
gpointer user_data);
G_END_DECLS
#endif /* __GTK_MENU_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,135 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_MENU_SHELL_H__
#define __GTK_MENU_SHELL_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkcontainer.h>
G_BEGIN_DECLS
#define GTK_TYPE_MENU_SHELL (gtk_menu_shell_get_type ())
#define GTK_MENU_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_SHELL, GtkMenuShell))
#define GTK_MENU_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_SHELL, GtkMenuShellClass))
#define GTK_IS_MENU_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_SHELL))
#define GTK_IS_MENU_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_SHELL))
#define GTK_MENU_SHELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_SHELL, GtkMenuShellClass))
typedef struct _GtkMenuShell GtkMenuShell;
typedef struct _GtkMenuShellClass GtkMenuShellClass;
typedef struct _GtkMenuShellPrivate GtkMenuShellPrivate;
struct _GtkMenuShell
{
GtkContainer container;
/*< private >*/
GtkMenuShellPrivate *priv;
};
struct _GtkMenuShellClass
{
GtkContainerClass parent_class;
guint submenu_placement : 1;
void (*deactivate) (GtkMenuShell *menu_shell);
void (*selection_done) (GtkMenuShell *menu_shell);
void (*move_current) (GtkMenuShell *menu_shell,
GtkMenuDirectionType direction);
void (*activate_current) (GtkMenuShell *menu_shell,
gboolean force_hide);
void (*cancel) (GtkMenuShell *menu_shell);
void (*select_item) (GtkMenuShell *menu_shell,
GtkWidget *menu_item);
void (*insert) (GtkMenuShell *menu_shell,
GtkWidget *child,
gint position);
gint (*get_popup_delay) (GtkMenuShell *menu_shell);
gboolean (*move_selected) (GtkMenuShell *menu_shell,
gint distance);
GList * (*get_items) (GtkMenuShell *menu_shell);
/*< private >*/
gpointer padding[8];
};
GDK_AVAILABLE_IN_ALL
GType gtk_menu_shell_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_append (GtkMenuShell *menu_shell,
GtkWidget *child);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_prepend (GtkMenuShell *menu_shell,
GtkWidget *child);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_insert (GtkMenuShell *menu_shell,
GtkWidget *child,
gint position);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_deactivate (GtkMenuShell *menu_shell);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_select_item (GtkMenuShell *menu_shell,
GtkWidget *menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_deselect (GtkMenuShell *menu_shell);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_activate_item (GtkMenuShell *menu_shell,
GtkWidget *menu_item,
gboolean force_deactivate);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_select_first (GtkMenuShell *menu_shell,
gboolean search_sensitive);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_cancel (GtkMenuShell *menu_shell);
GDK_AVAILABLE_IN_ALL
gboolean gtk_menu_shell_get_take_focus (GtkMenuShell *menu_shell);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_set_take_focus (GtkMenuShell *menu_shell,
gboolean take_focus);
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_menu_shell_get_selected_item (GtkMenuShell *menu_shell);
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_menu_shell_get_parent_shell (GtkMenuShell *menu_shell);
GDK_AVAILABLE_IN_ALL
void gtk_menu_shell_bind_model (GtkMenuShell *menu_shell,
GMenuModel *model,
const gchar *action_namespace,
gboolean with_separators);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuShell, g_object_unref)
G_END_DECLS
#endif /* __GTK_MENU_SHELL_H__ */

View File

@ -1,98 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_MENU_SHELL_PRIVATE_H__
#define __GTK_MENU_SHELL_PRIVATE_H__
#include <gtk/gtkmenushell.h>
#include <gtk/gtkmnemonichash.h>
#include <gtk/gtkkeyhash.h>
#include <gtk/gtkmenutrackerprivate.h>
#include <gtk/gtkeventcontroller.h>
G_BEGIN_DECLS
/* Placement of submenus */
typedef enum
{
GTK_TOP_BOTTOM,
GTK_LEFT_RIGHT
} GtkSubmenuPlacement;
struct _GtkMenuShellPrivate
{
GtkWidget *active_menu_item; /* This is not an "active" menu item
* (there is no such thing) but rather,
* the selected menu item in that MenuShell,
* if there is one.
*/
GtkWidget *parent_menu_shell;
GtkMenuTracker *tracker; // if bound to a GMenuModel
guint button;
guint32 activate_time;
guint active : 1;
guint have_grab : 1;
guint have_xgrab : 1;
guint ignore_enter : 1;
guint keyboard_mode : 1;
guint take_focus : 1;
guint activated_submenu : 1;
guint in_unselectable_item : 1; /* This flag is a crutch to keep
* mnemonics in the same menu if
* the user moves the mouse over
* an unselectable menuitem.
*/
guint selection_done_coming_soon : 1; /* Set TRUE when a selection-done
* signal is coming soon (when checked
* from inside of a "hide" handler).
*/
GtkMnemonicHash *mnemonic_hash;
GtkKeyHash *key_hash;
GdkDevice *grab_pointer;
GtkEventController *key_controller;
};
void _gtk_menu_shell_select_last (GtkMenuShell *menu_shell,
gboolean search_sensitive);
gint _gtk_menu_shell_get_popup_delay (GtkMenuShell *menu_shell);
void _gtk_menu_shell_set_grab_device (GtkMenuShell *menu_shell,
GdkDevice *device);
GdkDevice *_gtk_menu_shell_get_grab_device (GtkMenuShell *menu_shell);
void _gtk_menu_shell_add_mnemonic (GtkMenuShell *menu_shell,
guint keyval,
GtkWidget *target);
void _gtk_menu_shell_remove_mnemonic (GtkMenuShell *menu_shell,
guint keyval,
GtkWidget *target);
void _gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell);
void _gtk_menu_shell_set_keyboard_mode (GtkMenuShell *menu_shell,
gboolean keyboard_mode);
gboolean _gtk_menu_shell_get_keyboard_mode (GtkMenuShell *menu_shell);
GList *gtk_menu_shell_get_items (GtkMenuShell *menu_shell);
G_END_DECLS
#endif /* __GTK_MENU_SHELL_PRIVATE_H__ */

View File

@ -25,7 +25,6 @@
#include "gtkmenubutton.h"
#include "gtkmenubuttonprivate.h"
#include "gtkbox.h"
#include "gtkmenu.h"
#include "gtkpopover.h"
#include "gtkmain.h"
#include "gtksizerequest.h"
@ -51,16 +50,8 @@
* # GtkMenuToolButton as GtkBuildable
*
* The GtkMenuToolButton implementation of the GtkBuildable interface
* supports adding a menu by specifying menu as the type attribute
* supports adding a popover by specifying popover as the type attribute
* of a <child> element.
*
* An example for a UI definition fragment with menus:
* |[
* <object class="GtkMenuToolButton">
* <child type="menu">
* <object class="GtkMenu"/>
* </child>
* </object>
* ]|
*/
@ -104,7 +95,6 @@ enum
enum
{
PROP_0,
PROP_MENU,
PROP_POPOVER
};
@ -208,10 +198,6 @@ gtk_menu_tool_button_set_property (GObject *object,
switch (prop_id)
{
case PROP_MENU:
gtk_menu_tool_button_set_menu (button, g_value_get_object (value));
break;
case PROP_POPOVER:
gtk_menu_tool_button_set_popover (button, g_value_get_object (value));
break;
@ -232,10 +218,6 @@ gtk_menu_tool_button_get_property (GObject *object,
switch (prop_id)
{
case PROP_MENU:
g_value_set_object (value, gtk_menu_button_get_popup (GTK_MENU_BUTTON (button->priv->arrow_button)));
break;
case PROP_POPOVER:
g_value_set_object (value, gtk_menu_button_get_popover (GTK_MENU_BUTTON (button->priv->arrow_button)));
break;
@ -282,13 +264,6 @@ gtk_menu_tool_button_class_init (GtkMenuToolButtonClass *klass)
NULL,
G_TYPE_NONE, 0);
g_object_class_install_property (object_class,
PROP_MENU,
g_param_spec_object ("menu",
P_("Menu"),
P_("The dropdown menu"),
GTK_TYPE_MENU,
GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_POPOVER,
g_param_spec_object ("popover",
@ -320,9 +295,6 @@ gtk_menu_tool_button_init (GtkMenuToolButton *button)
arrow_button = gtk_menu_button_new ();
gtk_container_add (GTK_CONTAINER (box), arrow_button);
/* the arrow button is insentive until we set a menu */
gtk_widget_set_sensitive (arrow_button, FALSE);
gtk_container_add (GTK_CONTAINER (button), box);
gtk_menu_button_set_align_widget (GTK_MENU_BUTTON (arrow_button),
GTK_WIDGET (button));
@ -338,10 +310,7 @@ gtk_menu_tool_button_buildable_add_child (GtkBuildable *buildable,
GObject *child,
const gchar *type)
{
if (type && strcmp (type, "menu") == 0)
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (buildable),
GTK_WIDGET (child));
else if (type && strcmp (type, "popover") == 0)
if (type && strcmp (type, "popover") == 0)
gtk_menu_tool_button_set_popover (GTK_MENU_TOOL_BUTTON (buildable),
GTK_WIDGET (child));
else
@ -390,55 +359,6 @@ _show_menu_emit (GtkMenuButton *menu_button,
g_signal_emit (button, signals[SHOW_MENU], 0);
}
/**
* gtk_menu_tool_button_set_menu:
* @button: a #GtkMenuToolButton
* @menu: the #GtkMenu associated with #GtkMenuToolButton
*
* Sets the #GtkMenu that is popped up when the user clicks on the arrow.
* If @menu is NULL, the arrow button becomes insensitive.
**/
void
gtk_menu_tool_button_set_menu (GtkMenuToolButton *button,
GtkWidget *menu)
{
GtkMenuToolButtonPrivate *priv;
g_return_if_fail (GTK_IS_MENU_TOOL_BUTTON (button));
g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
priv = button->priv;
gtk_menu_button_set_popup (GTK_MENU_BUTTON (priv->arrow_button), menu);
gtk_menu_button_set_create_popup_func (GTK_MENU_BUTTON (priv->arrow_button),
_show_menu_emit, NULL, NULL);
g_object_notify (G_OBJECT (button), "menu");
}
/**
* gtk_menu_tool_button_get_menu:
* @button: a #GtkMenuToolButton
*
* Gets the #GtkMenu associated with #GtkMenuToolButton.
*
* Returns: (transfer none): the #GtkMenu associated
* with #GtkMenuToolButton
**/
GtkWidget *
gtk_menu_tool_button_get_menu (GtkMenuToolButton *button)
{
GtkMenu *ret;
g_return_val_if_fail (GTK_IS_MENU_TOOL_BUTTON (button), NULL);
ret = gtk_menu_button_get_popup (GTK_MENU_BUTTON (button->priv->arrow_button));
if (!ret)
return NULL;
return GTK_WIDGET (ret);
}
void
gtk_menu_tool_button_set_popover (GtkMenuToolButton *button,
GtkWidget *popover)

View File

@ -40,11 +40,6 @@ GDK_AVAILABLE_IN_ALL
GtkToolItem *gtk_menu_tool_button_new (GtkWidget *icon_widget,
const gchar *label);
GDK_AVAILABLE_IN_ALL
void gtk_menu_tool_button_set_menu (GtkMenuToolButton *button,
GtkWidget *menu);
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_menu_tool_button_get_menu (GtkMenuToolButton *button);
GDK_AVAILABLE_IN_ALL
void gtk_menu_tool_button_set_popover (GtkMenuToolButton *button,
GtkWidget *popover);

View File

@ -1,505 +0,0 @@
/*
* Copyright © 2011, 2013 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#include "config.h"
#include "gtkmodelmenuitemprivate.h"
#include "gtkaccellabel.h"
#include "gtklabel.h"
#include "gtkcheckmenuitemprivate.h"
#include "gtkimage.h"
#include "gtkbox.h"
struct _GtkModelMenuItem
{
GtkCheckMenuItem parent_instance;
GtkMenuTrackerItemRole role;
gboolean has_indicator;
};
typedef GtkCheckMenuItemClass GtkModelMenuItemClass;
G_DEFINE_TYPE (GtkModelMenuItem, gtk_model_menu_item, GTK_TYPE_CHECK_MENU_ITEM)
enum
{
PROP_0,
PROP_ACTION_ROLE,
PROP_ICON,
PROP_TEXT,
PROP_TOGGLED,
PROP_ACCEL
};
static void
gtk_model_menu_item_toggle_size_request (GtkMenuItem *menu_item,
gint *requisition)
{
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (menu_item);
if (item->has_indicator)
GTK_MENU_ITEM_CLASS (gtk_model_menu_item_parent_class)
->toggle_size_request (menu_item, requisition);
else
*requisition = 0;
}
static void
gtk_model_menu_item_activate (GtkMenuItem *item)
{
/* block the automatic toggle behaviour -- just do nothing */
}
static void
gtk_model_menu_item_set_has_indicator (GtkModelMenuItem *item,
gboolean has_indicator)
{
if (has_indicator == item->has_indicator)
return;
item->has_indicator = has_indicator;
gtk_widget_set_visible (_gtk_check_menu_item_get_indicator_widget (GTK_CHECK_MENU_ITEM (item)),
item->has_indicator);
}
static void
gtk_model_menu_item_set_action_role (GtkModelMenuItem *item,
GtkMenuTrackerItemRole role)
{
AtkObject *accessible;
AtkRole a11y_role;
if (role == item->role)
return;
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), role == GTK_MENU_TRACKER_ITEM_ROLE_RADIO);
gtk_model_menu_item_set_has_indicator (item, role != GTK_MENU_TRACKER_ITEM_ROLE_NORMAL);
accessible = gtk_widget_get_accessible (GTK_WIDGET (item));
switch (role)
{
case GTK_MENU_TRACKER_ITEM_ROLE_NORMAL:
a11y_role = ATK_ROLE_MENU_ITEM;
break;
case GTK_MENU_TRACKER_ITEM_ROLE_CHECK:
a11y_role = ATK_ROLE_CHECK_MENU_ITEM;
break;
case GTK_MENU_TRACKER_ITEM_ROLE_RADIO:
a11y_role = ATK_ROLE_RADIO_MENU_ITEM;
break;
default:
g_assert_not_reached ();
}
atk_object_set_role (accessible, a11y_role);
g_object_notify (G_OBJECT (item), "action-role");
}
static void
gtk_model_menu_item_set_icon (GtkModelMenuItem *item,
GIcon *icon)
{
GtkWidget *child;
g_return_if_fail (GTK_IS_MODEL_MENU_ITEM (item));
g_return_if_fail (icon == NULL || G_IS_ICON (icon));
child = gtk_bin_get_child (GTK_BIN (item));
/* There are only three possibilities here:
*
* - no child
* - accel label child
* - already a box
*
* Handle the no-child case by having GtkMenuItem create the accel
* label, then we will only have two possible cases.
*/
if (child == NULL)
{
gtk_menu_item_get_label (GTK_MENU_ITEM (item));
child = gtk_bin_get_child (GTK_BIN (item));
g_assert (GTK_IS_ACCEL_LABEL (child));
}
/* If it is a box, make sure there are no images inside of it already.
*/
if (GTK_IS_BOX (child))
{
GList *children;
children = gtk_container_get_children (GTK_CONTAINER (child));
while (children)
{
if (GTK_IS_IMAGE (children->data))
gtk_widget_destroy (children->data);
children = g_list_delete_link (children, children);
}
}
else
{
GtkWidget *box;
if (icon == NULL)
return;
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
/* Reparent the child without destroying it */
g_object_ref (child);
gtk_container_remove (GTK_CONTAINER (item), child);
gtk_container_add (GTK_CONTAINER (box), child);
g_object_unref (child);
gtk_container_add (GTK_CONTAINER (item), box);
/* Now we have a box */
child = box;
}
g_assert (GTK_IS_BOX (child));
/* child is now a box containing a label and no image. Add the icon,
* if appropriate.
*/
if (icon != NULL)
{
GtkWidget *image;
image = gtk_image_new_from_gicon (icon);
gtk_image_set_pixel_size (GTK_IMAGE (image), 16);
gtk_box_insert_child_after (GTK_BOX (child), image, NULL);
}
g_object_notify (G_OBJECT (item), "icon");
}
static GIcon *
gtk_model_menu_item_get_icon (GtkModelMenuItem *item)
{
GtkWidget *child;
GIcon *icon = NULL;
child = gtk_bin_get_child (GTK_BIN (item));
if (GTK_IS_BOX (child))
{
GList *children, *l;
children = gtk_container_get_children (GTK_CONTAINER (child));
for (l = children; l; l = l->next)
{
if (GTK_IS_IMAGE (l->data))
{
icon = gtk_image_get_gicon (GTK_IMAGE (l->data));
break;
}
}
g_list_free (children);
}
return icon;
}
static void
gtk_model_menu_item_set_text (GtkModelMenuItem *item,
const gchar *text)
{
GtkWidget *child;
GList *children;
child = gtk_bin_get_child (GTK_BIN (item));
if (child == NULL)
{
gtk_menu_item_get_label (GTK_MENU_ITEM (item));
child = gtk_bin_get_child (GTK_BIN (item));
g_assert (GTK_IS_ACCEL_LABEL (child));
}
if (GTK_IS_LABEL (child))
{
gtk_label_set_text_with_mnemonic (GTK_LABEL (child), text);
return;
}
else if (GTK_IS_ACCEL_LABEL (child))
{
gtk_accel_label_set_label (GTK_ACCEL_LABEL (child), text);
return;
}
if (!GTK_IS_CONTAINER (child))
return;
children = gtk_container_get_children (GTK_CONTAINER (child));
while (children)
{
if (GTK_IS_LABEL (children->data))
gtk_label_set_label (GTK_LABEL (children->data), text);
children = g_list_delete_link (children, children);
}
g_object_notify (G_OBJECT (item), "text");
}
static const gchar *
gtk_model_menu_item_get_text (GtkModelMenuItem *item)
{
GtkWidget *child;
child = gtk_bin_get_child (GTK_BIN (item));
if (GTK_IS_LABEL (child))
return gtk_label_get_text (GTK_LABEL (child));
else if (GTK_IS_ACCEL_LABEL (child))
return gtk_accel_label_get_label (GTK_ACCEL_LABEL (child));
if (GTK_IS_CONTAINER (child))
{
GList *children, *l;
const gchar *text = NULL;
children = gtk_container_get_children (GTK_CONTAINER (child));
for (l = children; l; l = l->next)
{
if (GTK_IS_LABEL (l->data))
{
text = gtk_label_get_text (GTK_LABEL (l->data));
break;
}
}
g_list_free (children);
return text;
}
return NULL;
}
static void
gtk_model_menu_item_set_accel (GtkModelMenuItem *item,
const gchar *accel)
{
GtkWidget *child;
GList *children;
GdkModifierType modifiers;
guint key;
if (accel)
{
gtk_accelerator_parse (accel, &key, &modifiers);
if (!key)
modifiers = 0;
}
else
{
key = 0;
modifiers = 0;
}
child = gtk_bin_get_child (GTK_BIN (item));
if (child == NULL)
{
gtk_menu_item_get_label (GTK_MENU_ITEM (item));
child = gtk_bin_get_child (GTK_BIN (item));
g_assert (GTK_IS_LABEL (child));
}
if (GTK_IS_ACCEL_LABEL (child))
{
gtk_accel_label_set_accel (GTK_ACCEL_LABEL (child), key, modifiers);
return;
}
if (!GTK_IS_CONTAINER (child))
return;
children = gtk_container_get_children (GTK_CONTAINER (child));
while (children)
{
if (GTK_IS_ACCEL_LABEL (children->data))
gtk_accel_label_set_accel (children->data, key, modifiers);
children = g_list_delete_link (children, children);
}
}
static gchar *
gtk_model_menu_item_get_accel (GtkModelMenuItem *item)
{
GtkWidget *child;
GtkWidget *accel_label = NULL;
child = gtk_bin_get_child (GTK_BIN (item));
if (GTK_IS_ACCEL_LABEL (child))
accel_label = child;
else if (GTK_IS_CONTAINER (child))
{
GList *children, *l;
children = gtk_container_get_children (GTK_CONTAINER (child));
for (l = children; l; l = l->next)
{
if (GTK_IS_ACCEL_LABEL (l->data))
{
accel_label = GTK_WIDGET (l->data);
break;
}
}
g_list_free (children);
}
if (accel_label)
{
guint key;
GdkModifierType mods;
gtk_accel_label_get_accel (GTK_ACCEL_LABEL (accel_label), &key, &mods);
return gtk_accelerator_name (key, mods);
}
return NULL;
}
static void
gtk_model_menu_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (object);
switch (prop_id)
{
case PROP_ACTION_ROLE:
g_value_set_enum (value, item->role);
break;
case PROP_ICON:
g_value_set_object (value, gtk_model_menu_item_get_icon (item));
break;
case PROP_TEXT:
g_value_set_string (value, gtk_model_menu_item_get_text (item));
break;
case PROP_TOGGLED:
g_value_set_boolean (value, gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)));
break;
case PROP_ACCEL:
g_value_take_string (value, gtk_model_menu_item_get_accel (item));
break;
default:
g_assert_not_reached ();
}
}
static void
gtk_model_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (object);
switch (prop_id)
{
case PROP_ACTION_ROLE:
gtk_model_menu_item_set_action_role (item, g_value_get_enum (value));
break;
case PROP_ICON:
gtk_model_menu_item_set_icon (item, g_value_get_object (value));
break;
case PROP_TEXT:
gtk_model_menu_item_set_text (item, g_value_get_string (value));
break;
case PROP_TOGGLED:
_gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_value_get_boolean (value));
g_object_notify (object, "active");
break;
case PROP_ACCEL:
gtk_model_menu_item_set_accel (item, g_value_get_string (value));
break;
default:
g_assert_not_reached ();
}
}
static void
gtk_model_menu_item_init (GtkModelMenuItem *item)
{
item->has_indicator = FALSE;
gtk_widget_hide (_gtk_check_menu_item_get_indicator_widget (GTK_CHECK_MENU_ITEM (item)));
}
static void
gtk_model_menu_item_class_init (GtkModelMenuItemClass *class)
{
GtkMenuItemClass *item_class = GTK_MENU_ITEM_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
item_class->toggle_size_request = gtk_model_menu_item_toggle_size_request;
item_class->activate = gtk_model_menu_item_activate;
object_class->get_property = gtk_model_menu_item_get_property;
object_class->set_property = gtk_model_menu_item_set_property;
g_object_class_install_property (object_class, PROP_ACTION_ROLE,
g_param_spec_enum ("action-role", "action role", "action role",
GTK_TYPE_MENU_TRACKER_ITEM_ROLE,
GTK_MENU_TRACKER_ITEM_ROLE_NORMAL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
g_object_class_install_property (object_class, PROP_ICON,
g_param_spec_object ("icon", "icon", "icon", G_TYPE_ICON,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
g_object_class_install_property (object_class, PROP_TEXT,
g_param_spec_string ("text", "text", "text", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
g_object_class_install_property (object_class, PROP_TOGGLED,
g_param_spec_boolean ("toggled", "toggled", "toggled", FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
g_object_class_install_property (object_class, PROP_ACCEL,
g_param_spec_string ("accel", "accel", "accel", NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), ATK_ROLE_MENU_ITEM);
}
GtkWidget *
gtk_model_menu_item_new (void)
{
return g_object_new (GTK_TYPE_MODEL_MENU_ITEM, NULL);
}

View File

@ -1,40 +0,0 @@
/*
* Copyright © 2011 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the licence, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#ifndef __GTK_MODEL_MENU_ITEM_PRIVATE_H__
#define __GTK_MODEL_MENU_ITEM_PRIVATE_H__
#include <gtk/gtkcheckmenuitem.h>
#include <gtk/gtkmenutrackeritemprivate.h>
#define GTK_TYPE_MODEL_MENU_ITEM (gtk_model_menu_item_get_type ())
#define GTK_MODEL_MENU_ITEM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
GTK_TYPE_MODEL_MENU_ITEM, GtkModelMenuItem))
#define GTK_IS_MODEL_MENU_ITEM(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
GTK_TYPE_MODEL_MENU_ITEM))
typedef struct _GtkModelMenuItem GtkModelMenuItem;
G_GNUC_INTERNAL
GType gtk_model_menu_item_get_type (void) G_GNUC_CONST;
G_GNUC_INTERNAL
GtkWidget * gtk_model_menu_item_new (void);
#endif /* __GTK_MODEL_MENU_ITEM_PRIVATE_H__ */

View File

@ -48,12 +48,13 @@
#include "gtkcellrendererpixbuf.h"
#include "gtkscrolledwindow.h"
#include "gtkicontheme.h"
#include "gtkmenuitem.h"
#include "gtkmain.h"
#include "gtksettings.h"
#include "gtkstylecontextprivate.h"
#include "gtkdialogprivate.h"
#include "gtkgestureclick.h"
#include "gtkmodelbuttonprivate.h"
#include "gtkpopover.h"
#include <glib/gprintf.h>
@ -1296,7 +1297,7 @@ update_process_list_store (GtkMountOperation *mount_operation,
}
static void
on_end_process_activated (GtkMenuItem *item,
on_end_process_activated (GtkModelButton *button,
gpointer user_data)
{
GtkMountOperation *op = GTK_MOUNT_OPERATION (user_data);
@ -1371,18 +1372,18 @@ do_popup_menu_for_process_tree_view (GtkWidget *widget,
{
GtkWidget *menu;
GtkWidget *item;
gdouble x, y;
double x, y;
menu = gtk_menu_new ();
menu = gtk_popover_new (widget);
gtk_style_context_add_class (gtk_widget_get_style_context (menu),
GTK_STYLE_CLASS_CONTEXT_MENU);
item = gtk_menu_item_new_with_mnemonic (_("_End Process"));
g_signal_connect (item, "activate",
item = gtk_model_button_new ();
g_object_set (item, "text", _("_End Process"), NULL);
g_signal_connect (item, "clicked",
G_CALLBACK (on_end_process_activated),
op);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show (menu);
gtk_container_add (GTK_CONTAINER (menu), item);
if (event && gdk_event_triggers_context_menu (event) &&
gdk_event_get_coords (event, &x, &y))
@ -1407,9 +1408,11 @@ do_popup_menu_for_process_tree_view (GtkWidget *widget,
/* don't popup a menu if the user right-clicked in an area with no rows */
return FALSE;
}
gtk_popover_set_pointing_to (GTK_POPOVER (menu), &(GdkRectangle){ x, y, 1, 1});
}
gtk_menu_popup_at_pointer (GTK_MENU (menu), event);
gtk_popover_popup (GTK_POPOVER (menu));
return TRUE;
}

View File

@ -2555,46 +2555,10 @@ gtk_notebook_popup_menu (GtkWidget *widget)
{
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
GtkNotebookPrivate *priv = notebook->priv;
GtkNotebookPage *page;
GtkWidget *tab_label = NULL;
if (priv->menu)
{
if (priv->focus_tab)
{
page = priv->focus_tab->data;
tab_label = page->tab_label;
}
if (tab_label)
{
g_object_set (priv->menu,
"anchor-hints", (GDK_ANCHOR_FLIP_Y |
GDK_ANCHOR_SLIDE |
GDK_ANCHOR_RESIZE),
NULL);
gtk_menu_popup_at_widget (GTK_MENU (priv->menu),
tab_label,
GDK_GRAVITY_SOUTH_WEST,
GDK_GRAVITY_NORTH_WEST,
NULL);
}
else
{
g_object_set (priv->menu,
"anchor-hints", (GDK_ANCHOR_SLIDE |
GDK_ANCHOR_RESIZE),
NULL);
gtk_menu_popup_at_widget (GTK_MENU (priv->menu),
widget,
GDK_GRAVITY_NORTH_WEST,
GDK_GRAVITY_NORTH_WEST,
NULL);
}
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
gtk_popover_popup (GTK_POPOVER (priv->menu));
return TRUE;
}

View File

@ -29,7 +29,6 @@
#include "gtkgestureclick.h"
#include "gtkbox.h"
#include "gtkimage.h"
#include "gtkcheckmenuitem.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkmarshalers.h"

View File

@ -40,10 +40,8 @@
#include "gtkintl.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkmenuitem.h"
#include "gtkmountoperation.h"
#include "gtkscrolledwindow.h"
#include "gtkseparatormenuitem.h"
#include "gtksettings.h"
#include "gtktrashmonitor.h"
#include "gtktypebuiltins.h"
@ -195,10 +193,6 @@ struct _GtkPlacesSidebarClass {
void (* open_location) (GtkPlacesSidebar *sidebar,
GFile *location,
GtkPlacesOpenFlags open_flags);
void (* populate_popup) (GtkPlacesSidebar *sidebar,
GtkMenu *menu,
GFile *selected_item,
GVolume *selected_volume);
void (* show_error_message) (GtkPlacesSidebar *sidebar,
const gchar *primary,
const gchar *secondary);

View File

@ -29,6 +29,7 @@
#include "gtkplacesviewrowprivate.h"
#include "gtktypebuiltins.h"
#include "gtkeventcontrollerkey.h"
#include "gtkpopovermenu.h"
/*
* SECTION:gtkplacesview
@ -86,6 +87,8 @@ struct _GtkPlacesViewPrivate
GCancellable *networks_fetching_cancellable;
GtkPlacesViewRow *row_for_action;
guint local_only : 1;
guint should_open_location : 1;
guint should_pulse_entry : 1;
@ -425,6 +428,17 @@ gtk_places_view_finalize (GObject *object)
G_OBJECT_CLASS (gtk_places_view_parent_class)->finalize (object);
}
static void
gtk_places_view_dispose (GObject *object)
{
GtkPlacesView *self = (GtkPlacesView *)object;
GtkPlacesViewPrivate *priv = gtk_places_view_get_instance_private (self);
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_places_view_parent_class)->dispose (object);
}
static void
gtk_places_view_get_property (GObject *object,
guint prop_id,
@ -443,6 +457,10 @@ gtk_places_view_get_property (GObject *object,
g_value_set_boolean (value, gtk_places_view_get_loading (self));
break;
case PROP_OPEN_FLAGS:
g_value_set_flags (value, gtk_places_view_get_open_flags (self));
break;
case PROP_FETCHING_NETWORKS:
g_value_set_boolean (value, gtk_places_view_get_fetching_networks (self));
break;
@ -466,6 +484,10 @@ gtk_places_view_set_property (GObject *object,
gtk_places_view_set_local_only (self, g_value_get_boolean (value));
break;
case PROP_OPEN_FLAGS:
gtk_places_view_set_open_flags (self, g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -1521,58 +1543,41 @@ mount_volume (GtkPlacesView *view,
g_object_unref (operation);
}
/* Callback used when the file list's popup menu is detached */
static void
popup_menu_detach_cb (GtkWidget *attach_widget,
GtkMenu *menu)
open_cb (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
GtkPlacesViewPrivate *priv;
GtkPlacesView *self = GTK_PLACES_VIEW (widget);
GtkPlacesViewPrivate *priv = gtk_places_view_get_instance_private (self);
GtkPlacesOpenFlags flags = GTK_PLACES_OPEN_NORMAL;
priv = gtk_places_view_get_instance_private (GTK_PLACES_VIEW (attach_widget));
priv->popup_menu = NULL;
if (priv->row_for_action == NULL)
return;
if (strcmp (action_name, "location.open") == 0)
flags = GTK_PLACES_OPEN_NORMAL;
else if (strcmp (action_name, "location.open-tab") == 0)
flags = GTK_PLACES_OPEN_NEW_TAB;
else if (strcmp (action_name, "location.open-window") == 0)
flags = GTK_PLACES_OPEN_NEW_WINDOW;
activate_row (self, priv->row_for_action, flags);
}
static void
open_cb (GtkMenuItem *item,
GtkPlacesViewRow *row)
mount_cb (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
GtkPlacesView *self;
self = GTK_PLACES_VIEW (gtk_widget_get_ancestor (GTK_WIDGET (row), GTK_TYPE_PLACES_VIEW));
activate_row (self, row, GTK_PLACES_OPEN_NORMAL);
}
static void
open_in_new_tab_cb (GtkMenuItem *item,
GtkPlacesViewRow *row)
{
GtkPlacesView *self;
self = GTK_PLACES_VIEW (gtk_widget_get_ancestor (GTK_WIDGET (row), GTK_TYPE_PLACES_VIEW));
activate_row (self, row, GTK_PLACES_OPEN_NEW_TAB);
}
static void
open_in_new_window_cb (GtkMenuItem *item,
GtkPlacesViewRow *row)
{
GtkPlacesView *self;
self = GTK_PLACES_VIEW (gtk_widget_get_ancestor (GTK_WIDGET (row), GTK_TYPE_PLACES_VIEW));
activate_row (self, row, GTK_PLACES_OPEN_NEW_WINDOW);
}
static void
mount_cb (GtkMenuItem *item,
GtkPlacesViewRow *row)
{
GtkPlacesViewPrivate *priv;
GtkWidget *view;
GtkPlacesView *self = GTK_PLACES_VIEW (widget);
GtkPlacesViewPrivate *priv = gtk_places_view_get_instance_private (self);
GVolume *volume;
view = gtk_widget_get_ancestor (GTK_WIDGET (row), GTK_TYPE_PLACES_VIEW);
priv = gtk_places_view_get_instance_private (GTK_PLACES_VIEW (view));
volume = gtk_places_view_row_get_volume (row);
if (priv->row_for_action == NULL)
return;
volume = gtk_places_view_row_get_volume (priv->row_for_action);
/*
* When the mount item is activated, it's expected that
@ -1581,23 +1586,27 @@ mount_cb (GtkMenuItem *item,
*/
priv->should_open_location = FALSE;
gtk_places_view_row_set_busy (row, TRUE);
mount_volume (GTK_PLACES_VIEW (view), volume);
gtk_places_view_row_set_busy (priv->row_for_action, TRUE);
mount_volume (self, volume);
}
static void
unmount_cb (GtkMenuItem *item,
GtkPlacesViewRow *row)
unmount_cb (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
GtkWidget *view;
GtkPlacesView *self = GTK_PLACES_VIEW (widget);
GtkPlacesViewPrivate *priv = gtk_places_view_get_instance_private (self);
GMount *mount;
view = gtk_widget_get_ancestor (GTK_WIDGET (row), GTK_TYPE_PLACES_VIEW);
mount = gtk_places_view_row_get_mount (row);
if (priv->row_for_action == NULL)
return;
gtk_places_view_row_set_busy (row, TRUE);
mount = gtk_places_view_row_get_mount (priv->row_for_action);
unmount_mount (GTK_PLACES_VIEW (view), mount);
gtk_places_view_row_set_busy (priv->row_for_action, TRUE);
unmount_mount (self, mount);
}
static void
@ -1646,88 +1655,58 @@ populate_available_protocols_grid (GtkGrid *grid)
attach_protocol_row_to_grid (grid, _("WebDAV"), _("dav:// or davs://"));
}
/* Constructs the popup menu if needed */
static void
build_popup_menu (GtkPlacesView *view,
GtkPlacesViewRow *row)
static GMenuModel *
get_menu_model (void)
{
GtkPlacesViewPrivate *priv;
GtkWidget *item;
GMount *mount;
GFile *file;
gboolean is_network;
GMenu *menu;
GMenu *section;
GMenuItem *item;
priv = gtk_places_view_get_instance_private (view);
mount = gtk_places_view_row_get_mount (row);
file = gtk_places_view_row_get_file (row);
is_network = gtk_places_view_row_get_is_network (row);
menu = g_menu_new ();
section = g_menu_new ();
item = g_menu_item_new (_("_Open"), "location.open");
g_menu_append_item (section, item);
g_object_unref (item);
priv->popup_menu = gtk_menu_new ();
gtk_style_context_add_class (gtk_widget_get_style_context (priv->popup_menu),
GTK_STYLE_CLASS_CONTEXT_MENU);
item = g_menu_item_new (_("Open in New _Tab"), "location.open-tab");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
gtk_menu_attach_to_widget (GTK_MENU (priv->popup_menu),
GTK_WIDGET (view),
popup_menu_detach_cb);
item = g_menu_item_new (_("Open in New _Window"), "location.open-window");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
/* Open item is always present */
item = gtk_menu_item_new_with_mnemonic (_("_Open"));
g_signal_connect (item,
"activate",
G_CALLBACK (open_cb),
row);
gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item);
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
g_object_unref (section);
if (priv->open_flags & GTK_PLACES_OPEN_NEW_TAB)
{
item = gtk_menu_item_new_with_mnemonic (_("Open in New _Tab"));
g_signal_connect (item,
"activate",
G_CALLBACK (open_in_new_tab_cb),
row);
gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item);
}
section = g_menu_new ();
item = g_menu_item_new (_("_Disconnect"), "location.disconnect");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
if (priv->open_flags & GTK_PLACES_OPEN_NEW_WINDOW)
{
item = gtk_menu_item_new_with_mnemonic (_("Open in New _Window"));
g_signal_connect (item,
"activate",
G_CALLBACK (open_in_new_window_cb),
row);
gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item);
}
item = g_menu_item_new (_("_Unmount"), "location.unmount");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
/*
* The only item that contains a file up to now is the Computer
* item, which cannot be mounted or unmounted.
*/
if (file)
return;
/* Separator */
item = gtk_separator_menu_item_new ();
gtk_menu_shell_insert (GTK_MENU_SHELL (priv->popup_menu), item, -1);
item = g_menu_item_new (_("_Connect"), "location.connect");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
/* Mount/Unmount items */
if (mount)
{
item = gtk_menu_item_new_with_mnemonic (is_network ? _("_Disconnect") : _("_Unmount"));
g_signal_connect (item,
"activate",
G_CALLBACK (unmount_cb),
row);
gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item);
}
else
{
item = gtk_menu_item_new_with_mnemonic (is_network ? _("_Connect") : _("_Mount"));
g_signal_connect (item,
"activate",
G_CALLBACK (mount_cb),
row);
gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item);
}
item = g_menu_item_new (_("_Mount"), "location.mount");
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
g_menu_append_item (section, item);
g_object_unref (item);
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
g_object_unref (section);
return G_MENU_MODEL (menu);
}
static void
@ -1736,15 +1715,44 @@ popup_menu (GtkPlacesViewRow *row,
{
GtkPlacesViewPrivate *priv;
GtkWidget *view;
GMount *mount;
GFile *file;
gboolean is_network;
view = gtk_widget_get_ancestor (GTK_WIDGET (row), GTK_TYPE_PLACES_VIEW);
priv = gtk_places_view_get_instance_private (GTK_PLACES_VIEW (view));
g_clear_pointer (&priv->popup_menu, gtk_widget_destroy);
mount = gtk_places_view_row_get_mount (row);
file = gtk_places_view_row_get_file (row);
is_network = gtk_places_view_row_get_is_network (row);
build_popup_menu (GTK_PLACES_VIEW (view), row);
gtk_widget_action_set_enabled (GTK_WIDGET (view), "location.disconnect",
!file && mount && is_network);
gtk_widget_action_set_enabled (GTK_WIDGET (view), "location.unmount",
!file && mount && !is_network);
gtk_widget_action_set_enabled (GTK_WIDGET (view), "location.connect",
!file && !mount && is_network);
gtk_widget_action_set_enabled (GTK_WIDGET (view), "location.mount",
!file && !mount && !is_network);
if (!priv->popup_menu)
{
GMenuModel *model = get_menu_model ();
gtk_menu_popup_at_pointer (GTK_MENU (priv->popup_menu), (GdkEvent *) event);
priv->popup_menu = gtk_popover_menu_new_from_model (GTK_WIDGET (view), model);
gtk_popover_set_position (GTK_POPOVER (priv->popup_menu), GTK_POS_BOTTOM);
gtk_popover_set_has_arrow (GTK_POPOVER (priv->popup_menu), FALSE);
gtk_widget_set_halign (priv->popup_menu, GTK_ALIGN_START);
g_object_unref (model);
}
gtk_widget_set_halign (priv->popup_menu, GTK_ALIGN_CENTER);
gtk_popover_set_relative_to (GTK_POPOVER (priv->popup_menu), GTK_WIDGET (row));
priv->row_for_action = row;
gtk_popover_popup (GTK_POPOVER (priv->popup_menu));
}
static gboolean
@ -2236,6 +2244,7 @@ gtk_places_view_class_init (GtkPlacesViewClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = gtk_places_view_finalize;
object_class->dispose = gtk_places_view_dispose;
object_class->constructed = gtk_places_view_constructed;
object_class->get_property = gtk_places_view_get_property;
object_class->set_property = gtk_places_view_set_property;
@ -2344,6 +2353,14 @@ gtk_places_view_class_init (GtkPlacesViewClass *klass)
gtk_widget_class_bind_template_callback (widget_class, on_listbox_row_activated);
gtk_widget_class_bind_template_callback (widget_class, on_recent_servers_listbox_row_activated);
gtk_widget_class_install_action (widget_class, "location.open", NULL, open_cb);
gtk_widget_class_install_action (widget_class, "location.open-tab", NULL, open_cb);
gtk_widget_class_install_action (widget_class, "location.open-window", NULL, open_cb);
gtk_widget_class_install_action (widget_class, "location.mount", NULL, mount_cb);
gtk_widget_class_install_action (widget_class, "location.connect", NULL, mount_cb);
gtk_widget_class_install_action (widget_class, "location.unmount", NULL, unmount_cb);
gtk_widget_class_install_action (widget_class, "location.disconnect", NULL, unmount_cb);
gtk_widget_class_set_css_name (widget_class, I_("placesview"));
}
@ -2360,6 +2377,9 @@ gtk_places_view_init (GtkPlacesView *self)
priv->path_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
priv->space_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "location.open-tab", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "location.open-window", FALSE);
gtk_widget_init_template (GTK_WIDGET (self));
controller = gtk_event_controller_key_new ();
@ -2427,11 +2447,17 @@ gtk_places_view_set_open_flags (GtkPlacesView *view,
priv = gtk_places_view_get_instance_private (view);
if (priv->open_flags != flags)
{
priv->open_flags = flags;
g_object_notify_by_pspec (G_OBJECT (view), properties[PROP_OPEN_FLAGS]);
}
if (priv->open_flags == flags)
return;
priv->open_flags = flags;
gtk_widget_action_set_enabled (GTK_WIDGET (view), "location.open-tab",
(flags & GTK_PLACES_OPEN_NEW_TAB) != 0);
gtk_widget_action_set_enabled (GTK_WIDGET (view), "location.open-window",
(flags & GTK_PLACES_OPEN_NEW_WINDOW) != 0);
g_object_notify_by_pspec (G_OBJECT (view), properties[PROP_OPEN_FLAGS]);
}
/*

View File

@ -33,25 +33,17 @@
* The position of a popover relative to the widget it is attached to
* can also be changed through gtk_popover_set_position().
*
* By default, #GtkPopover performs a GTK+ grab, in order to ensure
* input events get redirected to it while it is shown, and also so
* the popover is dismissed in the expected situations (clicks outside
* the popover, or the Esc key being pressed). If no such modal behavior
* is desired on a popover, gtk_popover_set_autohide() may be called
* on it to tweak its behavior.
* By default, #GtkPopover performs a grab, in order to ensure input events
* get redirected to it while it is shown, and also so the popover is dismissed
* in the expected situations (clicks outside the popover, or the Escape key
* being pressed). If no such modal behavior is desired on a popover,
* gtk_popover_set_autohide() may be called on it to tweak its behavior.
*
* ## GtkPopover as menu replacement
*
* GtkPopover is often used to replace menus. To facilitate this, it
* supports being populated from a #GMenuModel, using
* gtk_popover_menu_new_from_model(). In addition to all the regular
* menu model features, this function supports rendering sections in
* the model in a more compact form, as a row of icon buttons instead
* of menu items.
*
* To use this rendering, set the display-hint attribute of the
* section to horizontal-buttons and set the icons of your items
* with the verb-icon attribute.
* GtkPopover is often used to replace menus. The best was to do this
* is to use the #GtkPopoverMenu subclass which supports being populated
* from a #GMenuModel with gtk_popover_menu_new_from_model().
*
* |[
* <section>
@ -85,23 +77,23 @@
*
* The contents child node always gets the .background style class and
* the popover itself gets the .menu style class if the popover is
* menu-like (ie #GtkPopoverMenu).
* menu-like (i.e. #GtkPopoverMenu).
*
* Particular uses of GtkPopover, such as touch selection popups
* or magnifiers in #GtkEntry or #GtkTextView get style classes
* like .touch-selection or .magnifier to differentiate from
* plain popovers.
* Particular uses of GtkPopover, such as touch selection popups or magnifiers
* in #GtkEntry or #GtkTextView get style classes like .touch-selection or .magnifier
* to differentiate from plain popovers.
*
* When styling a popover directly, the popover node should usually
* not have any background.
*
* Note that, in order to accomplish appropriate arrow visuals, #GtkPopover uses
* custom drawing for the arrow node. This makes it possible for the arrow to change
* its shape dynamically, but it also limits the possibilities of styling it using CSS.
* In particular, the arrow gets drawn over the content node's border so they look
* like one shape, which means that the border-width of the content node and the arrow
* node should be the same. The arrow also does not support any border shape other than
* solid, no border-radius, only one border width (border-bottom-width is used) and no box-shadow.
* custom drawing for the arrow node. This makes it possible for the arrow to
* change its shape dynamically, but it also limits the possibilities of styling
* it using CSS. In particular, the arrow gets drawn over the content node's
* border so they look like one shape, which means that the border-width of
* the content node and the arrow node should be the same. The arrow also does
* not support any border shape other than solid, no border-radius, only one
* border width (border-bottom-width is used) and no box-shadow.
*/
#include "config.h"

View File

@ -43,74 +43,22 @@
* @Title: GtkPopoverMenu
*
* GtkPopoverMenu is a subclass of #GtkPopover that treats its
* children like menus and allows switching between them. It is
* meant to be used primarily together with #GtkModelButton, but
* any widget can be used, such as #GtkSpinButton or #GtkScale.
* In this respect, GtkPopoverMenu is more flexible than popovers
* that are created from a #GMenuModel with gtk_popover_new_from_model().
* children like menus and allows switching between them. It
* can open submenus as traditional, nested submenus, or in a
* more touch-friendly sliding fashion.
*
* To add a child as a submenu, use gtk_popover_menu_add_submenu().
* To let the user open this submenu, add a #GtkModelButton whose
* #GtkModelButton:menu-name property is set to the name you've given
* to the submenu.
* GtkPopoverMenu is meant to be used primarily with menu models,
* using gtk_popover_menu_new_from_model(). If you need to put other
* widgets such as #GtkSpinButton or #GtkSwitch into a popover,
* use a #GtkPopover.
*
* To add a named submenu in a ui file, set the #GtkWidget:name property
* of the widget that you are adding as a child of the popover menu.
* In addition to all the regular menu model features, this function
* supports rendering sections in the model in a more compact form,
* as a row of image buttons instead of menu items.
*
* By convention, the first child of a submenu should be a #GtkModelButton
* to switch back to the parent menu. Such a button should use the
* #GtkModelButton:inverted and #GtkModelButton:centered properties
* to achieve a title-like appearance and place the submenu indicator
* at the opposite side. To switch back to the main menu, use "main"
* as the menu name.
*
* # Example
*
* |[
* <object class="GtkPopoverMenu">
* <child>
* <object class="GtkBox">
* <property name="visible">True</property>
* <property name="margin">10</property>
* <child>
* <object class="GtkModelButton">
* <property name="visible">True</property>
* <property name="action-name">win.frob</property>
* <property name="text" translatable="yes">Frob</property>
* </object>
* </child>
* <child>
* <object class="GtkModelButton">
* <property name="visible">True</property>
* <property name="menu-name">more</property>
* <property name="text" translatable="yes">More</property>
* </object>
* </child>
* </object>
* </child>
* <child>
* <object class="GtkBox">
* <property name="visible">True</property>
* <property name="margin">10</property>
* <property name="name">more</property>
* <child>
* <object class="GtkModelButton">
* <property name="visible">True</property>
* <property name="action-name">win.foo</property>
* <property name="text" translatable="yes">Foo</property>
* </object>
* </child>
* <child>
* <object class="GtkModelButton">
* <property name="visible">True</property>
* <property name="action-name">win.bar</property>
* <property name="text" translatable="yes">Bar</property>
* </object>
* </child>
* </object>
* </child>
* </object>
* ]|
* To use this rendering, set the display-hint attribute of the
* section to horizontal-buttons and set the icons of your items
* with the verb-icon attribute.
*
* # CSS Nodes
*
@ -184,7 +132,10 @@ gtk_popover_menu_set_active_item (GtkPopoverMenu *menu,
if (menu->active_item != item)
{
if (menu->active_item)
gtk_widget_unset_state_flags (menu->active_item, GTK_STATE_FLAG_SELECTED);
{
gtk_widget_unset_state_flags (menu->active_item, GTK_STATE_FLAG_SELECTED);
g_object_remove_weak_pointer (G_OBJECT (menu->active_item), (gpointer *)&menu->active_item);
}
menu->active_item = item;
@ -192,6 +143,8 @@ gtk_popover_menu_set_active_item (GtkPopoverMenu *menu,
{
GtkWidget *popover;
g_object_add_weak_pointer (G_OBJECT (menu->active_item), (gpointer *)&menu->active_item);
gtk_widget_set_state_flags (menu->active_item, GTK_STATE_FLAG_SELECTED, FALSE);
if (GTK_IS_MODEL_BUTTON (item))
g_object_get (item, "popover", &popover, NULL);
@ -277,6 +230,12 @@ gtk_popover_menu_dispose (GObject *object)
{
GtkPopoverMenu *popover = GTK_POPOVER_MENU (object);
if (popover->active_item)
{
g_object_remove_weak_pointer (G_OBJECT (popover->active_item), (gpointer *)&popover->active_item);
popover->active_item = NULL;
}
g_clear_object (&popover->model);
G_OBJECT_CLASS (gtk_popover_menu_parent_class)->dispose (object);
@ -528,7 +487,7 @@ gtk_popover_menu_new (GtkWidget *relative_to)
return popover;
}
/**
/*<private>
* gtk_popover_menu_open_submenu:
* @popover: a #GtkPopoverMenu
* @name: the name of the menu to switch to
@ -606,12 +565,10 @@ gtk_popover_menu_new_from_model (GtkWidget *relative_to,
* @model. The popover is pointed to the @relative_to widget.
*
* The created buttons are connected to actions found in the
* #GtkApplicationWindow to which the popover belongs - typically
* by means of being attached to a widget that is contained within
* the #GtkApplicationWindows widget hierarchy.
*
* Actions can also be added using gtk_widget_insert_action_group()
* on the menus attach widget or on any of its parent widgets.
* action groups that are accessible from the @relative-to widget.
* This includes the #GtkApplicationWindow to which the popover
* belongs. Actions can also be added using gtk_widget_insert_action_group()
* on the @relative-to widget or on any of its parent widgets.
*
* The only flag that is supported currently is
* #GTK_POPOVER_MENU_NESTED, which makes GTK create traditional,
@ -636,6 +593,17 @@ gtk_popover_menu_new_from_model_full (GtkWidget *relative_to,
return popover;
}
/**
* gtk_popover_menu_set_model:
* @popover: a #GtkPopoverMenu
* @model: (nullable): a #GtkMenuModel, or %NULL
*
* Sets a new menu model on @popover.
*
* The existing contents of @popover are removed, and
* the @popover is populated with new contents according
* to @model.
*/
void
gtk_popover_menu_set_menu_model (GtkPopoverMenu *popover,
GMenuModel *model)
@ -659,6 +627,14 @@ gtk_popover_menu_set_menu_model (GtkPopoverMenu *popover,
}
}
/**
* gtk_popover_menu_get_menu_model:
* @popover: a #GtkPopoverMenu
*
* Returns the menu model used to populate the popover.
*
* Returns: the menu model of @popover
*/
GMenuModel *
gtk_popover_menu_get_menu_model (GtkPopoverMenu *popover)
{

View File

@ -24,9 +24,11 @@
* @Short_description: A menu bar with popovers
* @See_also: #GtkPopover, #GtkPopoverMenu, #GMenuModel
*
* The #GtkPopoverBar presents a horizontal bar of items that pop
* up popover menus when clicked. The only way to create instances
* of GtkPopoverBar is from a #GMenuModel.
* GtkPopoverMenuBar presents a horizontal bar of items that pop
* up popover menus when clicked.
*
* The only way to create instances of GtkPopoverMenuBar is
* from a #GMenuModel.
*
* # CSS nodes
*
@ -38,9 +40,8 @@
* popover
* ]|
*
* GtkMenuBar has a single CSS node with name menubar, below which
* each item has its CSS node, and below that the corresponding
* popover.
* GtkPopoverMenuBar has a single CSS node with name menubar, below which
* each item has its CSS node, and below that the corresponding popover.
*
* The item whose popover is currently open gets the .active
* style class.
@ -50,6 +51,7 @@
#include "config.h"
#include "gtkpopovermenubar.h"
#include "gtkpopovermenubarprivate.h"
#include "gtkpopovermenu.h"
#include "gtkboxlayout.h"
@ -471,7 +473,6 @@ gtk_popover_menu_bar_get_property (GObject *object,
}
}
static void
gtk_popover_menu_bar_dispose (GObject *object)
{
@ -487,6 +488,90 @@ gtk_popover_menu_bar_dispose (GObject *object)
G_OBJECT_CLASS (gtk_popover_menu_bar_parent_class)->dispose (object);
}
static GList *
get_menu_bars (GtkWindow *window)
{
return g_object_get_data (G_OBJECT (window), "gtk-menu-bar-list");
}
GList *
gtk_popover_menu_bar_get_viewable_menu_bars (GtkWindow *window)
{
GList *menu_bars;
GList *viewable_menu_bars = NULL;
for (menu_bars = get_menu_bars (window);
menu_bars;
menu_bars = menu_bars->next)
{
GtkWidget *widget = menu_bars->data;
gboolean viewable = TRUE;
while (widget)
{
if (!gtk_widget_get_mapped (widget))
viewable = FALSE;
widget = gtk_widget_get_parent (widget);
}
if (viewable)
viewable_menu_bars = g_list_prepend (viewable_menu_bars, menu_bars->data);
}
return g_list_reverse (viewable_menu_bars);
}
static void
set_menu_bars (GtkWindow *window,
GList *menubars)
{
g_object_set_data (G_OBJECT (window), I_("gtk-menu-bar-list"), menubars);
}
static void
add_to_window (GtkWindow *window,
GtkPopoverMenuBar *bar)
{
GList *menubars = get_menu_bars (window);
set_menu_bars (window, g_list_prepend (menubars, bar));
}
static void
remove_from_window (GtkWindow *window,
GtkPopoverMenuBar *bar)
{
GList *menubars = get_menu_bars (window);
menubars = g_list_remove (menubars, bar);
set_menu_bars (window, menubars);
}
static void
gtk_popover_menu_bar_root (GtkWidget *widget)
{
GtkPopoverMenuBar *bar = GTK_POPOVER_MENU_BAR (widget);
GtkWidget *toplevel;
GTK_WIDGET_CLASS (gtk_popover_menu_bar_parent_class)->root (widget);
toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
add_to_window (GTK_WINDOW (toplevel), bar);
}
static void
gtk_popover_menu_bar_unroot (GtkWidget *widget)
{
GtkPopoverMenuBar *bar = GTK_POPOVER_MENU_BAR (widget);
GtkWidget *toplevel;
toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
remove_from_window (GTK_WINDOW (toplevel), bar);
GTK_WIDGET_CLASS (gtk_popover_menu_bar_parent_class)->unroot (widget);
}
static void
gtk_popover_menu_bar_class_init (GtkPopoverMenuBarClass *klass)
{
@ -497,6 +582,8 @@ gtk_popover_menu_bar_class_init (GtkPopoverMenuBarClass *klass)
object_class->set_property = gtk_popover_menu_bar_set_property;
object_class->get_property = gtk_popover_menu_bar_get_property;
widget_class->root = gtk_popover_menu_bar_root;
widget_class->unroot = gtk_popover_menu_bar_unroot;
widget_class->focus = gtk_popover_menu_bar_focus;
/**
@ -504,8 +591,7 @@ gtk_popover_menu_bar_class_init (GtkPopoverMenuBarClass *klass)
*
* The #GMenuModel from which the menu bar is created.
*
* The model should only contain submenus as toplevel
* items.
* The model should only contain submenus as toplevel elements.
*/
bar_props[PROP_MENU_MODEL] =
g_param_spec_object ("menu-model",
@ -605,3 +691,12 @@ gtk_popover_menu_bar_get_menu_model (GtkPopoverMenuBar *bar)
return bar->model;
}
void
gtk_popover_menu_bar_select_first (GtkPopoverMenuBar *bar)
{
GtkPopoverMenuBarItem *item;
item = GTK_POPOVER_MENU_BAR_ITEM (gtk_widget_get_first_child (GTK_WIDGET (bar)));
set_active_item (bar, item, TRUE);
}

View File

@ -1,5 +1,5 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* Copyright © 2019 Carlos Garnacho <carlosg@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -15,17 +15,17 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_CHECK_MENU_ITEM_PRIVATE_H__
#define __GTK_CHECK_MENU_ITEM_PRIVATE_H__
#ifndef __GTK_POPOVER_MENU_BAR_PRIVATE_H__
#define __GTK_POPOVER_MENU_BAR_PRIVATE_H__
#include <gtk/gtkcheckmenuitem.h>
#include "gtkpopovermenubar.h"
G_BEGIN_DECLS
void _gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item,
gboolean is_active);
GtkWidget * _gtk_check_menu_item_get_indicator_widget (GtkCheckMenuItem *check_menu_item);
void gtk_popover_menu_bar_select_first (GtkPopoverMenuBar *bar);
GList* gtk_popover_menu_bar_get_viewable_menu_bars (GtkWindow *window);
G_END_DECLS
#endif /* __GTK_CHECK_MENU_ITEM_PRIVATE_H__ */
#endif /* __GTK_POPOVER_PRIVATE_H__ */

View File

@ -1722,7 +1722,7 @@ gtk_print_operation_run_with_dialog (GtkPrintOperation *op,
if (parent == NULL)
{
invisible = gtk_window_new (GTK_WINDOW_POPUP);
invisible = gtk_window_new (GTK_WINDOW_TOPLEVEL);
parentHWnd = get_parent_hwnd (invisible);
}
else

View File

@ -1,616 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gtkaccellabel.h"
#include "gtkcheckmenuitemprivate.h"
#include "gtkmarshalers.h"
#include "gtkradiomenuitem.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "a11y/gtkradiomenuitemaccessible.h"
/**
* SECTION:gtkradiomenuitem
* @Short_description: A choice from multiple check menu items
* @Title: GtkRadioMenuItem
* @See_also: #GtkMenuItem, #GtkCheckMenuItem
*
* A radio menu item is a check menu item that belongs to a group. At each
* instant exactly one of the radio menu items from a group is selected.
*
* The group list does not need to be freed, as each #GtkRadioMenuItem will
* remove itself and its list item when it is destroyed.
*
* The correct way to create a group of radio menu items is approximatively
* this:
*
* ## How to create a group of radio menu items.
*
* |[<!-- language="C" -->
* GSList *group = NULL;
* GtkWidget *item;
* gint i;
*
* for (i = 0; i < 5; i++)
* {
* item = gtk_radio_menu_item_new_with_label (group, "This is an example");
* group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
* if (i == 1)
* gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
* }
* ]|
*
* # CSS nodes
*
* |[<!-- language="plain" -->
* menuitem
* radio.left
* <child>
* ]|
*
* GtkRadioMenuItem has a main CSS node with name menuitem, and a subnode
* with name radio, which gets the .left or .right style class.
*/
typedef struct _GtkRadioMenuItemPrivate GtkRadioMenuItemPrivate;
typedef struct _GtkRadioMenuItemClass GtkRadioMenuItemClass;
struct _GtkRadioMenuItem
{
GtkCheckMenuItem check_menu_item;
};
struct _GtkRadioMenuItemClass
{
GtkCheckMenuItemClass parent_class;
void (*group_changed) (GtkRadioMenuItem *radio_menu_item);
};
struct _GtkRadioMenuItemPrivate
{
GSList *group;
};
enum {
PROP_0,
PROP_GROUP
};
static void gtk_radio_menu_item_destroy (GtkWidget *widget);
static void gtk_radio_menu_item_activate (GtkMenuItem *menu_item);
static void gtk_radio_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_radio_menu_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static guint group_changed_signal = 0;
G_DEFINE_TYPE_WITH_PRIVATE (GtkRadioMenuItem, gtk_radio_menu_item, GTK_TYPE_CHECK_MENU_ITEM)
/**
* gtk_radio_menu_item_new:
* @group: (element-type GtkRadioMenuItem) (allow-none): the group to which the
* radio menu item is to be attached, or %NULL
*
* Creates a new #GtkRadioMenuItem.
*
* Returns: a new #GtkRadioMenuItem
*/
GtkWidget*
gtk_radio_menu_item_new (GSList *group)
{
GtkRadioMenuItem *radio_menu_item;
radio_menu_item = g_object_new (GTK_TYPE_RADIO_MENU_ITEM, NULL);
gtk_radio_menu_item_set_group (radio_menu_item, group);
return GTK_WIDGET (radio_menu_item);
}
static void
gtk_radio_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkRadioMenuItem *radio_menu_item;
radio_menu_item = GTK_RADIO_MENU_ITEM (object);
switch (prop_id)
{
GSList *slist;
case PROP_GROUP:
slist = g_value_get_object (value);
if (slist)
slist = gtk_radio_menu_item_get_group ((GtkRadioMenuItem*) g_value_get_object (value));
gtk_radio_menu_item_set_group (radio_menu_item, slist);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_radio_menu_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* gtk_radio_menu_item_set_group:
* @radio_menu_item: a #GtkRadioMenuItem.
* @group: (element-type GtkRadioMenuItem) (allow-none): the new group, or %NULL.
*
* Sets the group of a radio menu item, or changes it.
*/
void
gtk_radio_menu_item_set_group (GtkRadioMenuItem *radio_menu_item,
GSList *group)
{
GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item);
GtkWidget *old_group_singleton = NULL;
GtkWidget *new_group_singleton = NULL;
g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item));
if (priv->group == group)
return;
if (priv->group)
{
GSList *slist;
priv->group = g_slist_remove (priv->group, radio_menu_item);
if (priv->group && !priv->group->next)
old_group_singleton = g_object_ref (priv->group->data);
for (slist = priv->group; slist; slist = slist->next)
{
GtkRadioMenuItem *tmp_item = slist->data;
GtkRadioMenuItemPrivate *tmp_priv = gtk_radio_menu_item_get_instance_private (tmp_item);
tmp_priv->group = priv->group;
}
}
if (group && !group->next)
new_group_singleton = g_object_ref (group->data);
priv->group = g_slist_prepend (group, radio_menu_item);
if (group)
{
GSList *slist;
for (slist = group; slist; slist = slist->next)
{
GtkRadioMenuItem *tmp_item = slist->data;
GtkRadioMenuItemPrivate *tmp_priv = gtk_radio_menu_item_get_instance_private (tmp_item);
tmp_priv->group = priv->group;
}
_gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (radio_menu_item), FALSE);
}
else
{
_gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (radio_menu_item), TRUE);
/* gtk_widget_set_state (GTK_WIDGET (radio_menu_item), GTK_STATE_ACTIVE);
*/
}
g_object_ref (radio_menu_item);
g_object_notify (G_OBJECT (radio_menu_item), "group");
g_signal_emit (radio_menu_item, group_changed_signal, 0);
if (old_group_singleton)
{
g_signal_emit (old_group_singleton, group_changed_signal, 0);
g_object_unref (old_group_singleton);
}
if (new_group_singleton)
{
g_signal_emit (new_group_singleton, group_changed_signal, 0);
g_object_unref (new_group_singleton);
}
g_object_unref (radio_menu_item);
}
/**
* gtk_radio_menu_item_new_with_label:
* @group: (element-type GtkRadioMenuItem) (allow-none):
* group the radio menu item is inside, or %NULL
* @label: the text for the label
*
* Creates a new #GtkRadioMenuItem whose child is a simple #GtkLabel.
*
* Returns: (transfer none): A new #GtkRadioMenuItem
*/
GtkWidget*
gtk_radio_menu_item_new_with_label (GSList *group,
const gchar *label)
{
return g_object_new (GTK_TYPE_RADIO_MENU_ITEM,
"group", (group) ? group->data : NULL,
"label", label,
NULL);
}
/**
* gtk_radio_menu_item_new_with_mnemonic:
* @group: (element-type GtkRadioMenuItem) (allow-none):
* group the radio menu item is inside, or %NULL
* @label: the text of the button, with an underscore in front of the
* mnemonic character
*
* Creates a new #GtkRadioMenuItem containing a label. The label
* will be created using gtk_label_new_with_mnemonic(), so underscores
* in @label indicate the mnemonic for the menu item.
*
* Returns: a new #GtkRadioMenuItem
*/
GtkWidget*
gtk_radio_menu_item_new_with_mnemonic (GSList *group,
const gchar *label)
{
return g_object_new (GTK_TYPE_RADIO_MENU_ITEM,
"group", (group) ? group->data : NULL,
"label", label,
"use-underline", TRUE,
NULL);
}
/**
* gtk_radio_menu_item_new_from_widget: (constructor)
* @group: (allow-none): An existing #GtkRadioMenuItem
*
* Creates a new #GtkRadioMenuItem adding it to the same group as @group.
*
* Returns: (transfer none): The new #GtkRadioMenuItem
**/
GtkWidget *
gtk_radio_menu_item_new_from_widget (GtkRadioMenuItem *group)
{
GSList *list = NULL;
g_return_val_if_fail (group == NULL || GTK_IS_RADIO_MENU_ITEM (group), NULL);
if (group)
list = gtk_radio_menu_item_get_group (group);
return gtk_radio_menu_item_new (list);
}
/**
* gtk_radio_menu_item_new_with_mnemonic_from_widget: (constructor)
* @group: (allow-none): An existing #GtkRadioMenuItem
* @label: (allow-none): the text of the button, with an underscore in front of the
* mnemonic character
*
* Creates a new GtkRadioMenuItem containing a label. The label will be
* created using gtk_label_new_with_mnemonic(), so underscores in label
* indicate the mnemonic for the menu item.
*
* The new #GtkRadioMenuItem is added to the same group as @group.
*
* Returns: (transfer none): The new #GtkRadioMenuItem
**/
GtkWidget *
gtk_radio_menu_item_new_with_mnemonic_from_widget (GtkRadioMenuItem *group,
const gchar *label)
{
GSList *list = NULL;
g_return_val_if_fail (group == NULL || GTK_IS_RADIO_MENU_ITEM (group), NULL);
if (group)
list = gtk_radio_menu_item_get_group (group);
return gtk_radio_menu_item_new_with_mnemonic (list, label);
}
/**
* gtk_radio_menu_item_new_with_label_from_widget: (constructor)
* @group: (allow-none): an existing #GtkRadioMenuItem
* @label: (allow-none): the text for the label
*
* Creates a new GtkRadioMenuItem whose child is a simple GtkLabel.
* The new #GtkRadioMenuItem is added to the same group as @group.
*
* Returns: (transfer none): The new #GtkRadioMenuItem
**/
GtkWidget *
gtk_radio_menu_item_new_with_label_from_widget (GtkRadioMenuItem *group,
const gchar *label)
{
GSList *list = NULL;
g_return_val_if_fail (group == NULL || GTK_IS_RADIO_MENU_ITEM (group), NULL);
if (group)
list = gtk_radio_menu_item_get_group (group);
return gtk_radio_menu_item_new_with_label (list, label);
}
/**
* gtk_radio_menu_item_get_group:
* @radio_menu_item: a #GtkRadioMenuItem
*
* Returns the group to which the radio menu item belongs, as a #GList of
* #GtkRadioMenuItem. The list belongs to GTK+ and should not be freed.
*
* Returns: (element-type GtkRadioMenuItem) (transfer none): the group
* of @radio_menu_item
*/
GSList*
gtk_radio_menu_item_get_group (GtkRadioMenuItem *radio_menu_item)
{
GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item);
g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item), NULL);
return priv->group;
}
static void
gtk_radio_menu_item_class_init (GtkRadioMenuItemClass *klass)
{
GObjectClass *gobject_class;
GtkWidgetClass *widget_class;
GtkMenuItemClass *menu_item_class;
gobject_class = G_OBJECT_CLASS (klass);
widget_class = GTK_WIDGET_CLASS (klass);
menu_item_class = GTK_MENU_ITEM_CLASS (klass);
gobject_class->set_property = gtk_radio_menu_item_set_property;
gobject_class->get_property = gtk_radio_menu_item_get_property;
widget_class->destroy = gtk_radio_menu_item_destroy;
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE);
menu_item_class->activate = gtk_radio_menu_item_activate;
/**
* GtkRadioMenuItem:group:
*
* The radio menu item whose group this widget belongs to.
*/
g_object_class_install_property (gobject_class,
PROP_GROUP,
g_param_spec_object ("group",
P_("Group"),
P_("The radio menu item whose group this widget belongs to."),
GTK_TYPE_RADIO_MENU_ITEM,
GTK_PARAM_WRITABLE));
/**
* GtkStyle::group-changed:
* @style: the object which received the signal
*
* Emitted when the group of radio menu items that a radio menu item belongs
* to changes. This is emitted when a radio menu item switches from
* being alone to being part of a group of 2 or more menu items, or
* vice-versa, and when a button is moved from one group of 2 or
* more menu items ton a different one, but not when the composition
* of the group that a menu item belongs to changes.
*/
group_changed_signal = g_signal_new (I_("group-changed"),
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkRadioMenuItemClass, group_changed),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
}
static void
gtk_radio_menu_item_init (GtkRadioMenuItem *radio_menu_item)
{
GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item);
priv->group = g_slist_prepend (NULL, radio_menu_item);
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (radio_menu_item), TRUE);
}
static void
gtk_radio_menu_item_destroy (GtkWidget *widget)
{
GtkRadioMenuItem *radio_menu_item = GTK_RADIO_MENU_ITEM (widget);
GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item);
GtkWidget *old_group_singleton = NULL;
GSList *tmp_list;
gboolean was_in_group;
was_in_group = priv->group && priv->group->next;
priv->group = g_slist_remove (priv->group, radio_menu_item);
if (priv->group && !priv->group->next)
old_group_singleton = priv->group->data;
tmp_list = priv->group;
while (tmp_list)
{
GtkRadioMenuItem *tmp_item = tmp_list->data;
GtkRadioMenuItemPrivate *tmp_priv = gtk_radio_menu_item_get_instance_private (tmp_item);
tmp_list = tmp_list->next;
tmp_priv->group = priv->group;
}
/* this radio menu item is no longer in the group */
priv->group = NULL;
if (old_group_singleton)
g_signal_emit (old_group_singleton, group_changed_signal, 0);
if (was_in_group)
g_signal_emit (radio_menu_item, group_changed_signal, 0);
GTK_WIDGET_CLASS (gtk_radio_menu_item_parent_class)->destroy (widget);
}
static void
gtk_radio_menu_item_activate (GtkMenuItem *menu_item)
{
GtkRadioMenuItem *radio_menu_item = GTK_RADIO_MENU_ITEM (menu_item);
GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item);
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
GtkCheckMenuItem *tmp_menu_item;
GSList *tmp_list;
gboolean active;
gint toggled;
toggled = FALSE;
active = gtk_check_menu_item_get_active (check_menu_item);
if (active)
{
tmp_menu_item = NULL;
tmp_list = priv->group;
while (tmp_list)
{
tmp_menu_item = tmp_list->data;
tmp_list = tmp_list->next;
if (gtk_check_menu_item_get_active (tmp_menu_item) &&
tmp_menu_item != check_menu_item)
break;
tmp_menu_item = NULL;
}
if (tmp_menu_item)
{
toggled = TRUE;
_gtk_check_menu_item_set_active (check_menu_item, !active);
}
}
else
{
toggled = TRUE;
_gtk_check_menu_item_set_active (check_menu_item, !active);
tmp_list = priv->group;
while (tmp_list)
{
tmp_menu_item = tmp_list->data;
tmp_list = tmp_list->next;
if (gtk_check_menu_item_get_active (tmp_menu_item) &&
tmp_menu_item != check_menu_item)
{
gtk_menu_item_activate (GTK_MENU_ITEM (tmp_menu_item));
break;
}
}
}
if (toggled)
{
gtk_check_menu_item_toggled (check_menu_item);
}
gtk_widget_queue_draw (GTK_WIDGET (radio_menu_item));
}
/**
* gtk_radio_menu_item_join_group:
* @radio_menu_item: a #GtkRadioMenuItem
* @group_source: (allow-none): a #GtkRadioMenuItem whose group we are
* joining, or %NULL to remove the @radio_menu_item from its current
* group
*
* Joins a #GtkRadioMenuItem object to the group of another #GtkRadioMenuItem
* object.
*
* This function should be used by language bindings to avoid the memory
* manangement of the opaque #GSList of gtk_radio_menu_item_get_group()
* and gtk_radio_menu_item_set_group().
*
* A common way to set up a group of #GtkRadioMenuItem instances is:
*
* |[
* GtkRadioMenuItem *last_item = NULL;
*
* while ( ...more items to add... )
* {
* GtkRadioMenuItem *radio_item;
*
* radio_item = gtk_radio_menu_item_new (...);
*
* gtk_radio_menu_item_join_group (radio_item, last_item);
* last_item = radio_item;
* }
* ]|
*/
void
gtk_radio_menu_item_join_group (GtkRadioMenuItem *radio_menu_item,
GtkRadioMenuItem *group_source)
{
g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item));
g_return_if_fail (group_source == NULL || GTK_IS_RADIO_MENU_ITEM (group_source));
if (group_source != NULL)
{
GSList *group = gtk_radio_menu_item_get_group (group_source);
if (group == NULL)
{
/* if the group source does not have a group, we force one */
gtk_radio_menu_item_set_group (group_source, NULL);
group = gtk_radio_menu_item_get_group (group_source);
}
gtk_radio_menu_item_set_group (radio_menu_item, group);
}
else
gtk_radio_menu_item_set_group (radio_menu_item, NULL);
}

View File

@ -1,75 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_RADIO_MENU_ITEM_H__
#define __GTK_RADIO_MENU_ITEM_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkcheckmenuitem.h>
G_BEGIN_DECLS
#define GTK_TYPE_RADIO_MENU_ITEM (gtk_radio_menu_item_get_type ())
#define GTK_RADIO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_RADIO_MENU_ITEM, GtkRadioMenuItem))
#define GTK_IS_RADIO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_RADIO_MENU_ITEM))
typedef struct _GtkRadioMenuItem GtkRadioMenuItem;
GDK_AVAILABLE_IN_ALL
GType gtk_radio_menu_item_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_radio_menu_item_new (GSList *group);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_radio_menu_item_new_with_label (GSList *group,
const gchar *label);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_radio_menu_item_new_with_mnemonic (GSList *group,
const gchar *label);
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_radio_menu_item_new_from_widget (GtkRadioMenuItem *group);
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_radio_menu_item_new_with_mnemonic_from_widget (GtkRadioMenuItem *group,
const gchar *label);
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_radio_menu_item_new_with_label_from_widget (GtkRadioMenuItem *group,
const gchar *label);
GDK_AVAILABLE_IN_ALL
GSList* gtk_radio_menu_item_get_group (GtkRadioMenuItem *radio_menu_item);
GDK_AVAILABLE_IN_ALL
void gtk_radio_menu_item_set_group (GtkRadioMenuItem *radio_menu_item,
GSList *group);
GDK_AVAILABLE_IN_ALL
void gtk_radio_menu_item_join_group (GtkRadioMenuItem *radio_menu_item,
GtkRadioMenuItem *group_source);
G_END_DECLS
#endif /* __GTK_RADIO_MENU_ITEM_H__ */

View File

@ -1,94 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
#include "gtkseparatormenuitem.h"
#include "gtkintl.h"
#include "gtkstylecontext.h"
/**
* SECTION:gtkseparatormenuitem
* @Short_description: A separator used in menus
* @Title: GtkSeparatorMenuItem
*
* The #GtkSeparatorMenuItem is a separator used to group
* items within a menu. It displays a horizontal line with a shadow to
* make it appear sunken into the interface.
*
* # CSS nodes
*
* GtkSeparatorMenuItem has a single CSS node with name separator.
*/
typedef struct _GtkSeparatorMenuItemClass GtkSeparatorMenuItemClass;
struct _GtkSeparatorMenuItem
{
GtkMenuItem menu_item;
};
struct _GtkSeparatorMenuItemClass
{
GtkMenuItemClass parent_class;
};
G_DEFINE_TYPE (GtkSeparatorMenuItem, gtk_separator_menu_item, GTK_TYPE_MENU_ITEM)
static const char *
gtk_separator_menu_item_get_label (GtkMenuItem *item)
{
return "";
}
static void
gtk_separator_menu_item_class_init (GtkSeparatorMenuItemClass *class)
{
GTK_CONTAINER_CLASS (class)->child_type = NULL;
GTK_MENU_ITEM_CLASS (class)->get_label = gtk_separator_menu_item_get_label;
gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), ATK_ROLE_SEPARATOR);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), I_("separator"));
}
static void
gtk_separator_menu_item_init (GtkSeparatorMenuItem *item)
{
}
/**
* gtk_separator_menu_item_new:
*
* Creates a new #GtkSeparatorMenuItem.
*
* Returns: a new #GtkSeparatorMenuItem.
*/
GtkWidget *
gtk_separator_menu_item_new (void)
{
return g_object_new (GTK_TYPE_SEPARATOR_MENU_ITEM, NULL);
}

View File

@ -1,53 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_SEPARATOR_MENU_ITEM_H__
#define __GTK_SEPARATOR_MENU_ITEM_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkmenuitem.h>
G_BEGIN_DECLS
#define GTK_TYPE_SEPARATOR_MENU_ITEM (gtk_separator_menu_item_get_type ())
#define GTK_SEPARATOR_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEPARATOR_MENU_ITEM, GtkSeparatorMenuItem))
#define GTK_IS_SEPARATOR_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEPARATOR_MENU_ITEM))
typedef struct _GtkSeparatorMenuItem GtkSeparatorMenuItem;
GDK_AVAILABLE_IN_ALL
GType gtk_separator_menu_item_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget* gtk_separator_menu_item_new (void);
G_END_DECLS
#endif /* __GTK_SEPARATOR_MENU_ITEM_H__ */

View File

@ -23,7 +23,6 @@
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkseparatormenuitem.h"
#include "gtkstylecontext.h"
#include "gtktoolbarprivate.h"
#include "gtkwidgetprivate.h"
@ -69,7 +68,6 @@ enum {
PROP_DRAW
};
static gboolean gtk_separator_tool_item_create_menu_proxy (GtkToolItem *item);
static void gtk_separator_tool_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
@ -88,19 +86,15 @@ gtk_separator_tool_item_class_init (GtkSeparatorToolItemClass *class)
{
GObjectClass *object_class;
GtkContainerClass *container_class;
GtkToolItemClass *toolitem_class;
GtkWidgetClass *widget_class;
object_class = (GObjectClass *)class;
container_class = (GtkContainerClass *)class;
toolitem_class = (GtkToolItemClass *)class;
widget_class = (GtkWidgetClass *)class;
object_class->set_property = gtk_separator_tool_item_set_property;
object_class->get_property = gtk_separator_tool_item_get_property;
toolitem_class->create_menu_proxy = gtk_separator_tool_item_create_menu_proxy;
container_class->add = gtk_separator_tool_item_add;
g_object_class_install_property (object_class,
@ -126,18 +120,6 @@ gtk_separator_tool_item_add (GtkContainer *container,
g_warning ("attempt to add a child to a GtkSeparatorToolItem");
}
static gboolean
gtk_separator_tool_item_create_menu_proxy (GtkToolItem *item)
{
GtkWidget *menu_item = NULL;
menu_item = gtk_separator_menu_item_new ();
gtk_tool_item_set_proxy_menu_item (item, MENU_ID, menu_item);
return TRUE;
}
static void
gtk_separator_tool_item_set_property (GObject *object,
guint prop_id,

View File

@ -52,7 +52,6 @@
#include "gtkpango.h"
#include "gtkpopovermenu.h"
#include "gtkprivate.h"
#include "gtkseparatormenuitem.h"
#include "gtkselection.h"
#include "gtksettings.h"
#include "gtksnapshot.h"

View File

@ -37,7 +37,6 @@
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkrenderbackgroundprivate.h"
#include "gtkseparatormenuitem.h"
#include "gtksettings.h"
#include "gtktextiterprivate.h"
#include "gtkimmulticontext.h"

View File

@ -19,7 +19,6 @@
#include "config.h"
#include "gtktoggletoolbutton.h"
#include "gtkcheckmenuitem.h"
#include "gtklabel.h"
#include "gtktogglebutton.h"
#include "gtkintl.h"
@ -72,12 +71,8 @@ static void gtk_toggle_tool_button_get_property (GObject *object
GValue *value,
GParamSpec *pspec);
static gboolean gtk_toggle_tool_button_create_menu_proxy (GtkToolItem *button);
static void button_toggled (GtkWidget *widget,
GtkToggleToolButton *button);
static void menu_item_activated (GtkWidget *widget,
GtkToggleToolButton *button);
static guint toggle_signals[LAST_SIGNAL] = { 0 };
@ -89,17 +84,14 @@ static void
gtk_toggle_tool_button_class_init (GtkToggleToolButtonClass *klass)
{
GObjectClass *object_class;
GtkToolItemClass *toolitem_class;
GtkToolButtonClass *toolbutton_class;
object_class = (GObjectClass *)klass;
toolitem_class = (GtkToolItemClass *)klass;
toolbutton_class = (GtkToolButtonClass *)klass;
object_class->set_property = gtk_toggle_tool_button_set_property;
object_class->get_property = gtk_toggle_tool_button_get_property;
toolitem_class->create_menu_proxy = gtk_toggle_tool_button_create_menu_proxy;
toolbutton_class->button_type = GTK_TYPE_TOGGLE_BUTTON;
/**
@ -189,94 +181,6 @@ gtk_toggle_tool_button_get_property (GObject *object,
}
}
static gboolean
gtk_toggle_tool_button_create_menu_proxy (GtkToolItem *item)
{
GtkToolButton *tool_button = GTK_TOOL_BUTTON (item);
GtkToggleToolButton *toggle_tool_button = GTK_TOGGLE_TOOL_BUTTON (item);
GtkWidget *menu_item = NULL;
gboolean use_mnemonic = TRUE;
const char *label;
GtkWidget *label_widget;
const gchar *label_text;
if (_gtk_tool_item_create_menu_proxy (item))
return TRUE;
label_widget = gtk_tool_button_get_label_widget (tool_button);
label_text = gtk_tool_button_get_label (tool_button);
if (GTK_IS_LABEL (label_widget))
{
label = gtk_label_get_label (GTK_LABEL (label_widget));
use_mnemonic = gtk_label_get_use_underline (GTK_LABEL (label_widget));
}
else if (label_text)
{
label = label_text;
use_mnemonic = gtk_tool_button_get_use_underline (tool_button);
}
else
{
label = "";
}
if (use_mnemonic)
menu_item = gtk_check_menu_item_new_with_mnemonic (label);
else
menu_item = gtk_check_menu_item_new_with_label (label);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item),
toggle_tool_button->priv->active);
if (GTK_IS_RADIO_TOOL_BUTTON (toggle_tool_button))
{
gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menu_item),
TRUE);
}
g_signal_connect_closure_by_id (menu_item,
g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
g_cclosure_new_object (G_CALLBACK (menu_item_activated),
G_OBJECT (toggle_tool_button)),
FALSE);
gtk_tool_item_set_proxy_menu_item (item, MENU_ID, menu_item);
return TRUE;
}
/* There are two activatable widgets, a toggle button and a menu item.
*
* If a widget is activated and the state of the tool button is the same as
* the new state of the activated widget, then the other widget was the one
* that was activated by the user and updated the tool buttons state.
*
* If the state of the tool button is not the same as the new state of the
* activated widget, then the activation was activated by the user, and the
* widget needs to make sure the tool button is updated before the other
* widget is activated. This will make sure the other widget a tool button
* in a state that matches its own new state.
*/
static void
menu_item_activated (GtkWidget *menu_item,
GtkToggleToolButton *toggle_tool_button)
{
GtkToolButton *tool_button = GTK_TOOL_BUTTON (toggle_tool_button);
gboolean menu_active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_item));
if (toggle_tool_button->priv->active != menu_active)
{
toggle_tool_button->priv->active = menu_active;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_tool_button_get_button (tool_button)),
toggle_tool_button->priv->active);
g_object_notify (G_OBJECT (toggle_tool_button), "active");
g_signal_emit (toggle_tool_button, toggle_signals[TOGGLED], 0);
}
}
static void
button_toggled (GtkWidget *widget,
GtkToggleToolButton *toggle_tool_button)
@ -287,17 +191,8 @@ button_toggled (GtkWidget *widget,
if (toggle_tool_button->priv->active != toggle_active)
{
GtkWidget *menu_item;
toggle_tool_button->priv->active = toggle_active;
if ((menu_item =
gtk_tool_item_get_proxy_menu_item (GTK_TOOL_ITEM (toggle_tool_button), MENU_ID)))
{
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item),
toggle_tool_button->priv->active);
}
g_object_notify (G_OBJECT (toggle_tool_button), "active");
g_signal_emit (toggle_tool_button, toggle_signals[TOGGLED], 0);
}

View File

@ -51,11 +51,8 @@
#include "gtkpopovermenuprivate.h"
#include "gtkmodelbuttonprivate.h"
#include "gtkseparator.h"
#include "gtkradiomenuitem.h"
#include "gtkcheckmenuitem.h"
#include "gtkradiobutton.h"
#include "gtkradiotoolbutton.h"
#include "gtkseparatormenuitem.h"
#include "gtkseparatortoolitem.h"
#include "gtktoolshell.h"
#include "gtktypebuiltins.h"
@ -64,6 +61,7 @@
#include "gtkwindowprivate.h"
#include "gtkgestureclick.h"
#include "gtkbuttonprivate.h"
#include "gtkmenubutton.h"
/**
@ -143,7 +141,6 @@ struct _GtkToolbarPrivate
GtkToolbarStyle style;
GtkToolItem *highlight_tool_item;
GtkWidget *arrow;
GtkWidget *arrow_button;
GtkAllocation prev_allocation;
@ -233,13 +230,6 @@ static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar
GtkToolbarStyle style);
static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
gboolean focus_home);
static void gtk_toolbar_arrow_button_press (GtkGesture *gesture,
int n_press,
double x,
double y,
GtkToolbar *toolbar);
static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
GtkToolbar *toolbar);
static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
static void gtk_toolbar_reconfigured (GtkToolbar *toolbar);
@ -306,7 +296,9 @@ static void toolbar_content_set_size_request (ToolbarContent
gint height);
static void toolbar_content_toolbar_reconfigured (ToolbarContent *content,
GtkToolbar *toolbar);
static GtkWidget * toolbar_content_retrieve_menu_item (ToolbarContent *content);
static const char * toolbar_content_get_overflow_text (ToolbarContent *content);
static GtkButtonRole toolbar_content_get_button_role (ToolbarContent *content);
static gboolean toolbar_content_get_active (ToolbarContent *content);
static gboolean toolbar_content_has_proxy_menu_item (ToolbarContent *content);
static gboolean toolbar_content_is_separator (ToolbarContent *content);
static void toolbar_content_set_expand (ToolbarContent *content,
@ -316,6 +308,8 @@ static void toolbar_tool_shell_iface_init (GtkToolShellIface
static GtkOrientation toolbar_get_orientation (GtkToolShell *shell);
static GtkToolbarStyle toolbar_get_style (GtkToolShell *shell);
static void toolbar_rebuild_menu (GtkToolShell *shell);
static void create_popup_func (GtkMenuButton *button,
gpointer data);
G_DEFINE_TYPE_WITH_CODE (GtkToolbar, gtk_toolbar, GTK_TYPE_CONTAINER,
@ -558,18 +552,11 @@ gtk_toolbar_init (GtkToolbar *toolbar)
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (toolbar));
priv->arrow_button = gtk_toggle_button_new ();
g_signal_connect (gtk_button_get_gesture (GTK_BUTTON (priv->arrow_button)), "pressed",
G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
g_signal_connect (priv->arrow_button, "clicked",
G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
priv->arrow_button = gtk_menu_button_new ();
gtk_menu_button_set_create_popup_func (GTK_MENU_BUTTON (priv->arrow_button), create_popup_func, toolbar, NULL);
gtk_widget_set_focus_on_click (priv->arrow_button, FALSE);
priv->arrow = gtk_image_new_from_icon_name ("pan-down-symbolic");
gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
gtk_widget_set_parent (priv->arrow_button, widget);
/* which child position a drop will occur at */
@ -656,9 +643,7 @@ gtk_toolbar_snapshot (GtkWidget *widget,
toolbar_content_snapshot (content, GTK_CONTAINER (widget), snapshot);
}
gtk_widget_snapshot_child (widget,
priv->arrow_button,
snapshot);
gtk_widget_snapshot_child (widget, priv->arrow_button, snapshot);
}
static void
@ -742,8 +727,7 @@ gtk_toolbar_measure (GtkWidget *widget,
arrow_requisition.width = 0;
if (priv->show_arrow)
gtk_widget_get_preferred_size (priv->arrow_button,
&arrow_requisition, NULL);
gtk_widget_get_preferred_size (priv->arrow_button, &arrow_requisition, NULL);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
@ -1104,15 +1088,6 @@ remove_item (GtkWidget *menu_item,
menu_item);
}
static void
menu_deactivated (GtkWidget *menu,
GtkToolbar *toolbar)
{
GtkToolbarPrivate *priv = toolbar->priv;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
}
static void
button_clicked (GtkWidget *button,
GtkWidget *item)
@ -1123,19 +1098,19 @@ button_clicked (GtkWidget *button,
}
static void
rebuild_menu (GtkToolbar *toolbar)
create_popup_func (GtkMenuButton *menu_button,
gpointer data)
{
GtkToolbar *toolbar = data;
GtkToolbarPrivate *priv = toolbar->priv;
GList *list;
if (!priv->menu)
{
priv->menu = gtk_popover_menu_new (priv->arrow_button);
gtk_menu_button_set_popover (GTK_MENU_BUTTON (priv->arrow_button), priv->menu);
priv->menu_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_popover_menu_add_submenu (GTK_POPOVER_MENU (priv->menu), priv->menu_box, "main");
g_signal_connect (priv->menu, "closed",
G_CALLBACK (menu_deactivated), toolbar);
}
gtk_container_foreach (GTK_CONTAINER (priv->menu_box), remove_item, NULL);
@ -1147,49 +1122,15 @@ rebuild_menu (GtkToolbar *toolbar)
if (toolbar_content_get_state (content) == OVERFLOWN &&
!toolbar_content_is_placeholder (content))
{
GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
if (menu_item)
if (toolbar_content_is_separator (content))
gtk_container_add (GTK_CONTAINER (priv->menu_box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
else if (toolbar_content_has_proxy_menu_item (content))
{
const char *text = toolbar_content_get_overflow_text (content);
GtkButtonRole role = toolbar_content_get_button_role (content);
gboolean active = toolbar_content_get_active (content);
GtkWidget *button, *widget;
const char *text;
GtkButtonRole role;
gboolean active;
g_assert (GTK_IS_MENU_ITEM (menu_item));
text = gtk_menu_item_get_label (GTK_MENU_ITEM (menu_item));
if (text == NULL)
{
GtkWidget *box, *child;
box = gtk_bin_get_child (GTK_BIN (menu_item));
for (child = gtk_widget_get_first_child (box);
child;
child = gtk_widget_get_next_sibling (child))
{
if (GTK_IS_LABEL (child))
{
text = gtk_label_get_label (GTK_LABEL (child));
break;
}
}
}
if (GTK_IS_SEPARATOR_MENU_ITEM (menu_item))
{
gtk_container_add (GTK_CONTAINER (priv->menu_box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
continue;
}
else if (GTK_IS_RADIO_MENU_ITEM (menu_item))
role = GTK_BUTTON_ROLE_RADIO;
else if (GTK_IS_CHECK_MENU_ITEM (menu_item))
role = GTK_BUTTON_ROLE_CHECK;
else
role = GTK_BUTTON_ROLE_NORMAL;
if (GTK_IS_CHECK_MENU_ITEM (menu_item))
active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_item));
else
active = FALSE;
button = gtk_model_button_new ();
g_object_set (button,
@ -1198,8 +1139,7 @@ rebuild_menu (GtkToolbar *toolbar)
"active", active,
NULL);
widget = toolbar_content_get_widget (content);
g_signal_connect (button, "clicked",
G_CALLBACK (button_clicked), widget);
g_signal_connect (button, "clicked", G_CALLBACK (button_clicked), widget);
gtk_container_add (GTK_CONTAINER (priv->menu_box), button);
}
}
@ -1484,7 +1424,7 @@ gtk_toolbar_size_allocate (GtkWidget *widget,
}
if (priv->menu && priv->need_rebuild)
rebuild_menu (toolbar);
create_popup_func (GTK_MENU_BUTTON (priv->arrow_button), toolbar);
if (need_arrow)
{
@ -1494,9 +1434,6 @@ gtk_toolbar_size_allocate (GtkWidget *widget,
else
{
gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
if (priv->menu && gtk_widget_get_visible (GTK_WIDGET (priv->menu)))
gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
}
g_free (allocations);
@ -2116,9 +2053,9 @@ gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
priv->orientation = orientation;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_image_set_from_icon_name (GTK_IMAGE (priv->arrow), "pan-down-symbolic");
gtk_menu_button_set_direction (GTK_MENU_BUTTON (priv->arrow_button), GTK_ARROW_DOWN);
else
gtk_image_set_from_icon_name (GTK_IMAGE (priv->arrow), "pan-end-symbolic");
gtk_menu_button_set_direction (GTK_MENU_BUTTON (priv->arrow_button), GTK_ARROW_RIGHT);
gtk_toolbar_reconfigured (toolbar);
@ -2145,50 +2082,6 @@ gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
}
}
static void
show_menu (GtkToolbar *toolbar,
GdkEventButton *event)
{
GtkToolbarPrivate *priv = toolbar->priv;
rebuild_menu (toolbar);
gtk_popover_popup (GTK_POPOVER (priv->menu));
}
static void
gtk_toolbar_arrow_button_clicked (GtkWidget *button,
GtkToolbar *toolbar)
{
GtkToolbarPrivate *priv = toolbar->priv;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
(!priv->menu || !gtk_widget_get_visible (GTK_WIDGET (priv->menu))))
{
/* We only get here when the button is clicked with the keyboard,
* because mouse button presses result in the menu being shown so
* that priv->menu would be non-NULL and visible.
*/
show_menu (toolbar, NULL);
gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
}
}
static void
gtk_toolbar_arrow_button_press (GtkGesture *gesture,
int n_press,
double x,
double y,
GtkToolbar *toolbar)
{
GtkWidget *button;
button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
show_menu (toolbar, NULL);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
}
static void
gtk_toolbar_pressed_cb (GtkGestureClick *gesture,
int n_press,
@ -2520,14 +2413,6 @@ gtk_toolbar_dispose (GObject *object)
g_clear_pointer (&priv->arrow_button, gtk_widget_unparent);
if (priv->menu)
{
g_signal_handlers_disconnect_by_func (priv->menu,
menu_deactivated, toolbar);
gtk_widget_destroy (GTK_WIDGET (priv->menu));
priv->menu = NULL;
}
if (priv->settings_connection > 0)
{
g_signal_handler_disconnect (priv->settings, priv->settings_connection);
@ -2867,27 +2752,27 @@ toolbar_content_toolbar_reconfigured (ToolbarContent *content,
gtk_tool_item_toolbar_reconfigured (content->item);
}
static GtkWidget *
toolbar_content_retrieve_menu_item (ToolbarContent *content)
static const char *
toolbar_content_get_overflow_text (ToolbarContent *content)
{
return gtk_tool_item_retrieve_proxy_menu_item (content->item);
return gtk_tool_item_get_overflow_text (content->item);
}
static gboolean
toolbar_content_has_proxy_menu_item (ToolbarContent *content)
{
GtkWidget *menu_item;
const char *text;
if (content->has_menu == YES)
return TRUE;
else if (content->has_menu == NO)
return FALSE;
menu_item = toolbar_content_retrieve_menu_item (content);
text = toolbar_content_get_overflow_text (content);
content->has_menu = menu_item? YES : NO;
content->has_menu = text ? YES : NO;
return menu_item != NULL;
return text != NULL;
}
static void
@ -2896,6 +2781,26 @@ toolbar_content_set_unknown_menu_status (ToolbarContent *content)
content->has_menu = UNKNOWN;
}
static GtkButtonRole
toolbar_content_get_button_role (ToolbarContent *content)
{
if (GTK_IS_RADIO_TOOL_BUTTON (content->item))
return GTK_BUTTON_ROLE_RADIO;
else if (GTK_IS_TOGGLE_TOOL_BUTTON (content->item))
return GTK_BUTTON_ROLE_CHECK;
else
return GTK_BUTTON_ROLE_NORMAL;
}
static gboolean
toolbar_content_get_active (ToolbarContent *content)
{
if (GTK_IS_TOGGLE_TOOL_BUTTON (content->item))
return gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (content->item));
else
return FALSE;
}
static gboolean
toolbar_content_is_separator (ToolbarContent *content)
{

View File

@ -95,7 +95,6 @@ static void gtk_tool_button_property_notify (GObject *object,
static void gtk_tool_button_finalize (GObject *object);
static void gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item);
static gboolean gtk_tool_button_create_menu_proxy (GtkToolItem *item);
static void button_clicked (GtkWidget *widget,
GtkToolButton *button);
@ -168,7 +167,6 @@ gtk_tool_button_class_init (GtkToolButtonClass *klass)
object_class->notify = gtk_tool_button_property_notify;
object_class->finalize = gtk_tool_button_finalize;
tool_item_class->create_menu_proxy = gtk_tool_button_create_menu_proxy;
tool_item_class->toolbar_reconfigured = gtk_tool_button_toolbar_reconfigured;
klass->button_type = GTK_TYPE_BUTTON;
@ -706,92 +704,6 @@ gtk_tool_button_finalize (GObject *object)
parent_class->finalize (object);
}
static GtkWidget *
clone_image_menu_size (GtkImage *image)
{
GtkImageType storage_type = gtk_image_get_storage_type (image);
if (storage_type == GTK_IMAGE_ICON_NAME)
{
const gchar *icon_name = gtk_image_get_icon_name (image);
return gtk_image_new_from_icon_name (icon_name);
}
else if (storage_type == GTK_IMAGE_GICON)
{
GIcon *icon = gtk_image_get_gicon (image);
return gtk_image_new_from_gicon (icon);
}
return NULL;
}
static void
click_button (GtkButton *button)
{
g_signal_emit_by_name (button, "clicked");
}
static gboolean
gtk_tool_button_create_menu_proxy (GtkToolItem *item)
{
GtkToolButton *button = GTK_TOOL_BUTTON (item);
GtkWidget *menu_item;
GtkWidget *menu_image = NULL;
gboolean use_mnemonic = TRUE;
const char *label_text;
GtkWidget *box;
GtkWidget *label;
if (_gtk_tool_item_create_menu_proxy (item))
return TRUE;
if (GTK_IS_LABEL (button->priv->label_widget))
{
label_text = gtk_label_get_label (GTK_LABEL (button->priv->label_widget));
use_mnemonic = gtk_label_get_use_underline (GTK_LABEL (button->priv->label_widget));
}
else if (button->priv->label_text)
{
label_text = button->priv->label_text;
use_mnemonic = button->priv->use_underline;
}
else
{
label_text = "";
}
if (GTK_IS_IMAGE (button->priv->icon_widget))
{
menu_image = clone_image_menu_size (GTK_IMAGE (button->priv->icon_widget));
}
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
if (use_mnemonic)
label = gtk_label_new_with_mnemonic (label_text);
else
label = gtk_label_new (label_text);
if (menu_image)
gtk_container_add (GTK_CONTAINER (box), menu_image);
gtk_container_add (GTK_CONTAINER (box), label);
menu_item = gtk_menu_item_new ();
gtk_container_add (GTK_CONTAINER (menu_item), box);
g_signal_connect_closure_by_id (menu_item,
g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
g_cclosure_new_object_swap (G_CALLBACK (click_button),
G_OBJECT (GTK_TOOL_BUTTON (button)->priv->button)),
FALSE);
gtk_tool_item_set_proxy_menu_item (GTK_TOOL_ITEM (button), MENU_ID, menu_item);
return TRUE;
}
static void
button_clicked (GtkWidget *widget,
GtkToolButton *button)
@ -848,6 +760,7 @@ gtk_tool_button_set_label (GtkToolButton *button,
gchar *old_label;
gchar *elided_label;
AtkObject *accessible;
const char *old_overflow_text;
g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
@ -864,6 +777,11 @@ gtk_tool_button_set_label (GtkToolButton *button,
g_free (elided_label);
}
old_overflow_text = gtk_tool_item_get_overflow_text (GTK_TOOL_ITEM (button));
if (old_overflow_text == NULL ||
(old_label && strcmp (old_overflow_text, old_label) == 0))
gtk_tool_item_set_overflow_text (GTK_TOOL_ITEM (button), label);
g_free (old_label);
g_object_notify (G_OBJECT (button), "label");

View File

@ -26,7 +26,6 @@
#include "gtkmarshalers.h"
#include "gtktoolshell.h"
#include "gtkseparatormenuitem.h"
#include "gtksizerequest.h"
#include "gtkintl.h"
#include "gtkprivate.h"
@ -70,6 +69,7 @@ enum {
PROP_IS_IMPORTANT,
PROP_HOMOGENEOUS,
PROP_EXPAND_ITEM,
PROP_OVERFLOW_TEXT
};
@ -84,8 +84,7 @@ struct _GtkToolItemPrivate
guint expand : 1;
guint is_important : 1;
gchar *menu_item_id;
GtkWidget *menu_item;
char *overflow_text;
};
static void gtk_tool_item_finalize (GObject *object);
@ -100,8 +99,6 @@ static void gtk_tool_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gtk_tool_item_property_notify (GObject *object,
GParamSpec *pspec);
static guint toolitem_signals[LAST_SIGNAL] = { 0 };
@ -120,10 +117,7 @@ gtk_tool_item_class_init (GtkToolItemClass *klass)
object_class->set_property = gtk_tool_item_set_property;
object_class->get_property = gtk_tool_item_get_property;
object_class->finalize = gtk_tool_item_finalize;
object_class->notify = gtk_tool_item_property_notify;
klass->create_menu_proxy = _gtk_tool_item_create_menu_proxy;
g_object_class_install_property (object_class,
PROP_VISIBLE_HORIZONTAL,
g_param_spec_boolean ("visible-horizontal",
@ -162,40 +156,21 @@ gtk_tool_item_class_init (GtkToolItemClass *klass)
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkToolItem::create-menu-proxy:
* @tool_item: the object the signal was emitted on
*
* This signal is emitted when the toolbar needs information from @tool_item
* about whether the item should appear in the toolbar overflow menu. In
* response the tool item should either
*
* - call gtk_tool_item_set_proxy_menu_item() with a %NULL
* pointer and return %TRUE to indicate that the item should not appear
* in the overflow menu
*
* - call gtk_tool_item_set_proxy_menu_item() with a new menu
* item and return %TRUE, or
*
* - return %FALSE to indicate that the signal was not handled by the item.
* This means that the item will not appear in the overflow menu unless
* a later handler installs a menu item.
*
* The toolbar may cache the result of this signal. When the tool item changes
* how it will respond to this signal it must call gtk_tool_item_rebuild_menu()
* to invalidate the cache and ensure that the toolbar rebuilds its overflow
* menu.
*
* Returns: %TRUE if the signal was handled, %FALSE if not
**/
toolitem_signals[CREATE_MENU_PROXY] =
g_signal_new (I_("create-menu-proxy"),
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkToolItemClass, create_menu_proxy),
_gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__VOID,
G_TYPE_BOOLEAN, 0);
/**
* GtkToolItem:overflow-text:
*
* The text to use as label in the overflow menu item for this
* toolitem.
*
* If unset, #GtkToolButton:label is used for #GtkToolButtons.
*/
g_object_class_install_property (object_class,
PROP_OVERFLOW_TEXT,
g_param_spec_string ("overflow-text",
P_("Overflow text"),
P_("Label to use in the overflow menu"),
NULL,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkToolItem::toolbar-reconfigured:
@ -239,13 +214,6 @@ gtk_tool_item_init (GtkToolItem *toolitem)
static void
gtk_tool_item_finalize (GObject *object)
{
GtkToolItem *item = GTK_TOOL_ITEM (object);
g_free (item->priv->menu_item_id);
if (item->priv->menu_item)
g_object_unref (item->priv->menu_item);
G_OBJECT_CLASS (gtk_tool_item_parent_class)->finalize (object);
}
@ -285,6 +253,9 @@ gtk_tool_item_set_property (GObject *object,
case PROP_HOMOGENEOUS:
gtk_tool_item_set_homogeneous (toolitem, g_value_get_boolean (value));
break;
case PROP_OVERFLOW_TEXT:
gtk_tool_item_set_overflow_text (toolitem, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -316,32 +287,15 @@ gtk_tool_item_get_property (GObject *object,
case PROP_HOMOGENEOUS:
g_value_set_boolean (value, toolitem->priv->homogeneous);
break;
case PROP_OVERFLOW_TEXT:
g_value_set_string (value, toolitem->priv->overflow_text);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_tool_item_property_notify (GObject *object,
GParamSpec *pspec)
{
GtkToolItem *tool_item = GTK_TOOL_ITEM (object);
if (tool_item->priv->menu_item && strcmp (pspec->name, "sensitive") == 0)
gtk_widget_set_sensitive (tool_item->priv->menu_item,
gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
if (G_OBJECT_CLASS (gtk_tool_item_parent_class)->notify)
G_OBJECT_CLASS (gtk_tool_item_parent_class)->notify (object, pspec);
}
gboolean
_gtk_tool_item_create_menu_proxy (GtkToolItem *item)
{
return FALSE;
}
/**
* gtk_tool_item_new:
*
@ -779,60 +733,6 @@ gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
return toolitem->priv->visible_vertical;
}
/**
* gtk_tool_item_retrieve_proxy_menu_item:
* @tool_item: a #GtkToolItem
*
* Returns the #GtkMenuItem that was last set by
* gtk_tool_item_set_proxy_menu_item(), ie. the #GtkMenuItem
* that is going to appear in the overflow menu.
*
* Returns: (transfer none): The #GtkMenuItem that is going to appear in the
* overflow menu for @tool_item.
**/
GtkWidget *
gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
{
gboolean retval;
g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0,
&retval);
return tool_item->priv->menu_item;
}
/**
* gtk_tool_item_get_proxy_menu_item:
* @tool_item: a #GtkToolItem
* @menu_item_id: a string used to identify the menu item
*
* If @menu_item_id matches the string passed to
* gtk_tool_item_set_proxy_menu_item() return the corresponding #GtkMenuItem.
*
* Custom subclasses of #GtkToolItem should use this function to
* update their menu item when the #GtkToolItem changes. That the
* @menu_item_ids must match ensures that a #GtkToolItem
* will not inadvertently change a menu item that they did not create.
*
* Returns: (transfer none) (nullable): The #GtkMenuItem passed to
* gtk_tool_item_set_proxy_menu_item(), if the @menu_item_ids
* match.
**/
GtkWidget *
gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
const gchar *menu_item_id)
{
g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
g_return_val_if_fail (menu_item_id != NULL, NULL);
if (tool_item->priv->menu_item_id && strcmp (tool_item->priv->menu_item_id, menu_item_id) == 0)
return tool_item->priv->menu_item;
return NULL;
}
/**
* gtk_tool_item_rebuild_menu:
* @tool_item: a #GtkToolItem
@ -860,48 +760,6 @@ gtk_tool_item_rebuild_menu (GtkToolItem *tool_item)
gtk_tool_shell_rebuild_menu (GTK_TOOL_SHELL (parent));
}
/**
* gtk_tool_item_set_proxy_menu_item:
* @tool_item: a #GtkToolItem
* @menu_item_id: a string used to identify @menu_item
* @menu_item: (nullable): a #GtkMenuItem to use in the overflow menu, or %NULL
*
* Sets the #GtkMenuItem used in the toolbar overflow menu. The
* @menu_item_id is used to identify the caller of this function and
* should also be used with gtk_tool_item_get_proxy_menu_item().
*
* See also #GtkToolItem::create-menu-proxy.
**/
void
gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
const gchar *menu_item_id,
GtkWidget *menu_item)
{
g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
g_return_if_fail (menu_item_id != NULL);
g_free (tool_item->priv->menu_item_id);
tool_item->priv->menu_item_id = g_strdup (menu_item_id);
if (tool_item->priv->menu_item != menu_item)
{
if (tool_item->priv->menu_item)
g_object_unref (tool_item->priv->menu_item);
if (menu_item)
{
g_object_ref_sink (menu_item);
gtk_widget_set_sensitive (menu_item,
gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
}
tool_item->priv->menu_item = menu_item;
}
}
/**
* gtk_tool_item_toolbar_reconfigured:
* @tool_item: a #GtkToolItem
@ -926,3 +784,38 @@ gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
gtk_widget_queue_resize (GTK_WIDGET (tool_item));
}
/**
* gtk_tool_item_set_overflow_text:
* @tool_item: a #GtkToolItem
* @overflow_text: (nullable): Label to use in the overflow menu
*
* Sets the label to use for @tool_item in the overflow menu.
*/
void
gtk_tool_item_set_overflow_text (GtkToolItem *tool_item,
const char *overflow_text)
{
g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
g_free (tool_item->priv->overflow_text);
tool_item->priv->overflow_text = g_strdup (overflow_text);
g_object_notify (G_OBJECT (tool_item), "overflow-text");
}
/**
* gtk_tool_item_get_overflow_text:
* @tool_item: a #GtkToolItem
*
* Gets the label that is used for @tool_item in the overflow menu.
*
* Return: the overflow menu label for @tool_item
*/
const char *
gtk_tool_item_get_overflow_text (GtkToolItem *tool_item)
{
g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
return tool_item->priv->overflow_text;
}

View File

@ -26,7 +26,6 @@
#endif
#include <gtk/gtkbin.h>
#include <gtk/gtkmenuitem.h>
#include <gtk/gtksizegroup.h>
G_BEGIN_DECLS
@ -53,9 +52,6 @@ struct _GtkToolItem
/**
* GtkToolItemClass:
* @parent_class: The parent class.
* @create_menu_proxy: Signal emitted when the toolbar needs
* information from tool_item about whether the item should appear in
* the toolbar overflow menu.
* @toolbar_reconfigured: Signal emitted when some property of the
* toolbar that the item is a child of changes.
*/
@ -64,7 +60,6 @@ struct _GtkToolItemClass
GtkBinClass parent_class;
/* signals */
gboolean (* create_menu_proxy) (GtkToolItem *tool_item);
void (* toolbar_reconfigured) (GtkToolItem *tool_item);
/*< private >*/
@ -127,14 +122,10 @@ GDK_AVAILABLE_IN_ALL
GtkSizeGroup * gtk_tool_item_get_text_size_group (GtkToolItem *tool_item);
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item);
const char * gtk_tool_item_get_overflow_text (GtkToolItem *tool_item);
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
const gchar *menu_item_id);
GDK_AVAILABLE_IN_ALL
void gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
const gchar *menu_item_id,
GtkWidget *menu_item);
void gtk_tool_item_set_overflow_text (GtkToolItem *tool_item,
const char *overflow_text);
GDK_AVAILABLE_IN_ALL
void gtk_tool_item_rebuild_menu (GtkToolItem *tool_item);

File diff suppressed because it is too large Load Diff

View File

@ -1,100 +0,0 @@
/* gtktreemenu.h
*
* Copyright (C) 2010 Openismus GmbH
*
* Authors:
* Tristan Van Berkom <tristanvb@openismus.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_TREE_MENU_H__
#define __GTK_TREE_MENU_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkmenuprivate.h>
#include <gtk/gtktreemodel.h>
#include <gtk/gtktreeview.h>
#include <gtk/gtkcellarea.h>
G_BEGIN_DECLS
#define GTK_TYPE_TREE_MENU (_gtk_tree_menu_get_type ())
#define GTK_TREE_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_MENU, GtkTreeMenu))
#define GTK_TREE_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_MENU, GtkTreeMenuClass))
#define GTK_IS_TREE_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_MENU))
#define GTK_IS_TREE_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TREE_MENU))
#define GTK_TREE_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TREE_MENU, GtkTreeMenuClass))
typedef struct _GtkTreeMenu GtkTreeMenu;
typedef struct _GtkTreeMenuClass GtkTreeMenuClass;
typedef struct _GtkTreeMenuPrivate GtkTreeMenuPrivate;
struct _GtkTreeMenu
{
GtkMenu parent_instance;
/*< private >*/
GtkTreeMenuPrivate *priv;
};
struct _GtkTreeMenuClass
{
GtkMenuClass parent_class;
/*< private >*/
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
};
GType _gtk_tree_menu_get_type (void) G_GNUC_CONST;
GtkWidget *_gtk_tree_menu_new (void);
GtkWidget *_gtk_tree_menu_new_with_area (GtkCellArea *area);
GtkWidget *_gtk_tree_menu_new_full (GtkCellArea *area,
GtkTreeModel *model,
GtkTreePath *root);
void _gtk_tree_menu_set_model (GtkTreeMenu *menu,
GtkTreeModel *model);
GtkTreeModel *_gtk_tree_menu_get_model (GtkTreeMenu *menu);
void _gtk_tree_menu_set_root (GtkTreeMenu *menu,
GtkTreePath *path);
GtkTreePath *_gtk_tree_menu_get_root (GtkTreeMenu *menu);
gint _gtk_tree_menu_get_wrap_width (GtkTreeMenu *menu);
void _gtk_tree_menu_set_wrap_width (GtkTreeMenu *menu,
gint width);
gint _gtk_tree_menu_get_row_span_column (GtkTreeMenu *menu);
void _gtk_tree_menu_set_row_span_column (GtkTreeMenu *menu,
gint row_span);
gint _gtk_tree_menu_get_column_span_column (GtkTreeMenu *menu);
void _gtk_tree_menu_set_column_span_column (GtkTreeMenu *menu,
gint column_span);
GtkTreeViewRowSeparatorFunc _gtk_tree_menu_get_row_separator_func (GtkTreeMenu *menu);
void _gtk_tree_menu_set_row_separator_func (GtkTreeMenu *menu,
GtkTreeViewRowSeparatorFunc func,
gpointer data,
GDestroyNotify destroy);
G_END_DECLS
#endif /* __GTK_TREE_MENU_H__ */

Some files were not shown because too many files have changed in this diff Show More