From 8fc032f2f64f4b7eb022adb0b1255a5a68df109f Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Sun, 22 Oct 2017 19:09:22 -0400 Subject: Merge branch 'gobjectification' --- (limited to 'src/toolbars/navigation/main-menu.c') diff --git a/src/toolbars/navigation/main-menu.c b/src/toolbars/navigation/main-menu.c new file mode 100644 index 0000000..055f489 --- /dev/null +++ b/src/toolbars/navigation/main-menu.c @@ -0,0 +1,301 @@ +/* + * Main menu and button + * + * Copyright (C) 2017 Patrick McDermott + * + * This file is part of Marquee. + * + * Marquee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Marquee 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Marquee. If not, see . + */ + +#include "main-menu.h" + +#include +#include +#include + +#include "../../tab-page.h" +#include "../../web-view.h" +#include "../find-toolbar.h" + +struct _MqMainMenu { + GtkToolButton parent_instance; + MqTabPage *tab_page; + MqFindToolbar *find_toolbar; + MqWebView *web_view; + GtkWidget *popover; +}; + +enum { + PROP_TAB_PAGE = 1, + PROP_FIND_TOOLBAR, + PROP_WEB_VIEW, + N_PROPERTIES +}; + +static GParamSpec *obj_properties[N_PROPERTIES] = {NULL,}; + +struct _MqMainMenuClass { + GtkToolButtonClass parent_class; +}; + +G_DEFINE_TYPE(MqMainMenu, mq_main_menu, GTK_TYPE_TOOL_BUTTON) + +static void +zoom_out_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + mq_web_view_zoom_out(main_menu->web_view); +} + +static void +zoom_reset_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + mq_web_view_zoom_reset(main_menu->web_view); +} + +static void +zoom_in_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + mq_web_view_zoom_in(main_menu->web_view); +} + +static void +find_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + gtk_widget_hide(main_menu->popover); + mq_find_toolbar_reveal(main_menu->find_toolbar); +} + +static void +fullscreen_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + gtk_widget_hide(main_menu->popover); + mq_window_toggle_fullscreen(mq_tab_page_get_window(main_menu->tab_page)); +} + +static void +developer_tools_clicked_cb(GtkButton G_GNUC_UNUSED *button, + MqMainMenu *main_menu) +{ + gtk_widget_hide(main_menu->popover); + webkit_web_inspector_show(webkit_web_view_get_inspector( + WEBKIT_WEB_VIEW(main_menu->web_view))); +} + +static void +preferences_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + gtk_widget_hide(main_menu->popover); + mq_tab_page_new("about:preferences", main_menu->tab_page); + /* TODO: Hack: */ + gtk_notebook_next_page(GTK_NOTEBOOK(gtk_widget_get_parent( + GTK_WIDGET(main_menu->tab_page)))); +} + +static void +about_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + gtk_widget_hide(main_menu->popover); + mq_tab_page_new("about:", main_menu->tab_page); + /* TODO: Hack: */ + gtk_notebook_next_page(GTK_NOTEBOOK(gtk_widget_get_parent( + GTK_WIDGET(main_menu->tab_page)))); +} + +static void +quit_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + /* mq_tab_page_quit() just calls mq_window_quit(), which just calls + * mq_application_quit(), which is asynchronous. So close the menu. */ + gtk_widget_hide(main_menu->popover); + mq_tab_page_quit(main_menu->tab_page); +} + +#define BUTTON_ROWS 6 +#define BUTTON_COLS 3 +#define NEW_BUTTON(Y, X, ICON, TOOLTIP) \ + do { \ + buttons[Y * BUTTON_COLS + X] = gtk_button_new_from_icon_name(\ + ICON, GTK_ICON_SIZE_BUTTON); \ + gtk_widget_set_tooltip_text(buttons[Y * BUTTON_COLS + X], \ + TOOLTIP); \ + gtk_grid_attach(GTK_GRID(grid), buttons[Y * BUTTON_COLS + X], \ + X, Y, 1, 1); \ + } while (0) +#define CLICKED_CB(Y, X, CB) \ + g_signal_connect(buttons[Y * BUTTON_COLS + X], "clicked", \ + G_CALLBACK(CB), main_menu) + +static void +menu_clicked_cb(MqMainMenu *main_menu) +{ + GtkWidget *grid; + GtkWidget *buttons[BUTTON_ROWS * BUTTON_COLS]; + + /* Set up the grid. */ + grid = gtk_grid_new(); + + NEW_BUTTON(0, 0, "zoom-out", "Zoom out"); + NEW_BUTTON(0, 1, "zoom-original", "Reset zoom"); + NEW_BUTTON(0, 2, "zoom-in", "Zoom in"); + NEW_BUTTON(1, 0, "document-open", "Open file"); + NEW_BUTTON(1, 1, "document-save-as", "Save page"); + NEW_BUTTON(1, 2, "mail-message-new", "E-mail link"); + NEW_BUTTON(2, 0, "edit-find", "Find"); + NEW_BUTTON(2, 1, "document-print-preview", "Print preview"); + NEW_BUTTON(2, 2, "document-print", "Print"); + NEW_BUTTON(3, 0, "bookmark-new", "Bookmarks"); + NEW_BUTTON(3, 1, "document-open-recent", "History"); + NEW_BUTTON(3, 2, "document-save", "Downloads"); + NEW_BUTTON(4, 0, "view-fullscreen", "Full screen"); + NEW_BUTTON(4, 1, "document-properties", "Developer tools"); + NEW_BUTTON(4, 2, "system-run", "Preferences"); + NEW_BUTTON(5, 0, "help-about", "About Marquee"); + NEW_BUTTON(5, 2, "application-exit", "Quit"); + + CLICKED_CB(0, 0, zoom_out_clicked_cb); + CLICKED_CB(0, 1, zoom_reset_clicked_cb); + CLICKED_CB(0, 2, zoom_in_clicked_cb); + /* TODO: 1, 0: Open file */ + /* TODO: 1, 1: Save page */ + /* TODO: 1, 2: E-mail link */ + CLICKED_CB(2, 0, find_clicked_cb); + /* TODO: 2, 1: Print preview */ + /* TODO: 2, 2: Print */ + /* TODO: 3, 0: Bookmarks */ + /* TODO: 3, 1: History */ + /* TODO: 3, 2: Downloads */ + CLICKED_CB(4, 0, fullscreen_clicked_cb); + CLICKED_CB(4, 1, developer_tools_clicked_cb); + CLICKED_CB(4, 2, preferences_clicked_cb); + CLICKED_CB(5, 0, about_clicked_cb); + CLICKED_CB(5, 2, quit_clicked_cb); + + /* Set up the popover. */ + main_menu->popover = gtk_popover_new(GTK_WIDGET(main_menu)); + gtk_container_add(GTK_CONTAINER(main_menu->popover), grid); + + /* NB: gtk_popover_popup() is new in GTK+ 3.22. */ + gtk_widget_show_all(main_menu->popover); +} + +#undef BUTTON_ROWS +#undef BUTTON_COLS +#undef NEW_BUTTON + +static void +get_property(GObject *object, guint property_id, GValue *value, + GParamSpec *param_spec) +{ + MqMainMenu *main_menu; + + main_menu = MQ_MAIN_MENU(object); + + switch (property_id) { + case PROP_TAB_PAGE: + g_value_set_object(value, main_menu->tab_page); + break; + case PROP_FIND_TOOLBAR: + g_value_set_object(value, main_menu->find_toolbar); + break; + case PROP_WEB_VIEW: + g_value_set_object(value, main_menu->web_view); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, + param_spec); + break; + } +} + +static void +set_property(GObject *object, guint property_id, const GValue *value, + GParamSpec *param_spec) +{ + MqMainMenu *main_menu; + + main_menu = MQ_MAIN_MENU(object); + + switch (property_id) { + case PROP_TAB_PAGE: + main_menu->tab_page = g_value_get_object(value); + break; + case PROP_FIND_TOOLBAR: + main_menu->find_toolbar = g_value_get_object(value); + break; + case PROP_WEB_VIEW: + main_menu->web_view = g_value_get_object(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, + param_spec); + break; + } +} + +static void +mq_main_menu_class_init(MqMainMenuClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->get_property = get_property; + object_class->set_property = set_property; + + obj_properties[PROP_TAB_PAGE] = g_param_spec_object( + "tab-page", + "MqTabPage", + "The ancestral MqTabPage instance", + MQ_TYPE_TAB_PAGE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); + obj_properties[PROP_FIND_TOOLBAR] = g_param_spec_object( + "find-toolbar", + "MqFindToolbar", + "The associated MqFindToolbar instance", + MQ_TYPE_FIND_TOOLBAR, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); + obj_properties[PROP_WEB_VIEW] = g_param_spec_object( + "web-view", + "MqWebView", + "The associated MqWebView instance", + MQ_TYPE_WEB_VIEW, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); + g_object_class_install_properties(object_class, N_PROPERTIES, + obj_properties); +} + +static void +mq_main_menu_init(MqMainMenu *main_menu) +{ + gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(main_menu), + gtk_image_new_from_icon_name("open-menu-symbolic", + GTK_ICON_SIZE_SMALL_TOOLBAR)); + gtk_tool_button_set_label(GTK_TOOL_BUTTON(main_menu), "Menu"); + gtk_widget_set_tooltip_text(GTK_WIDGET(main_menu), "Open menu"); + g_signal_connect(main_menu, "clicked", + G_CALLBACK(menu_clicked_cb), NULL); +} + +GtkToolItem * +mq_main_menu_new(MqTabPage *tab_page, MqFindToolbar *find_toolbar, + MqWebView *web_view) +{ + return g_object_new(MQ_TYPE_MAIN_MENU, + "tab-page", tab_page, + "find-toolbar", find_toolbar, + "web-view", web_view, + NULL); +} -- cgit v0.9.1