From 3962132f9f079897cafa444d9fde5d9eca4dacdf Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Thu, 12 Oct 2017 23:51:22 -0400 Subject: MqMainMenu: New class --- diff --git a/src/local.mk b/src/local.mk index 3968277..f21f2d0 100644 --- a/src/local.mk +++ b/src/local.mk @@ -7,6 +7,7 @@ marquee_SOURCES += \ %reldir%/tab.c \ %reldir%/tab-chrome.c \ %reldir%/back-forward-button-box.c \ + %reldir%/main-menu.c \ %reldir%/find-toolbar.c \ %reldir%/web-view.c \ %reldir%/html.c \ diff --git a/src/main-menu.c b/src/main-menu.c new file mode 100644 index 0000000..e4cdf1a --- /dev/null +++ b/src/main-menu.c @@ -0,0 +1,296 @@ +/* + * 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 +#include +#include + +#include "main-menu.h" +#include "tab.h" +#include "find-toolbar.h" +#include "web-view.h" + +struct _MqMainMenu { + GtkToolButton parent_instance; + MqTab *tab; + MqFindToolbar *find_toolbar; + MqWebView *web_view; + GtkWidget *popover; +}; + +enum { + PROP_TAB = 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_get_window(main_menu->tab)); +} + +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_new("about:preferences", main_menu->tab); + /* TODO: Hack: */ + gtk_notebook_next_page(GTK_NOTEBOOK(main_menu->tab->window->notebook)); +} + +static void +about_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + gtk_widget_hide(main_menu->popover); + mq_tab_new("about:", main_menu->tab); + /* TODO: Hack: */ + gtk_notebook_next_page(GTK_NOTEBOOK(main_menu->tab->window->notebook)); +} + +static void +quit_clicked_cb(GtkButton G_GNUC_UNUSED *button, MqMainMenu *main_menu) +{ + /* mq_tab_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_quit(main_menu->tab); +} + +#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 *pspec) +{ + MqMainMenu *main_menu; + + main_menu = MQ_MAIN_MENU(object); + + switch (property_id) { + case PROP_TAB: + g_value_set_pointer(value, main_menu->tab); + 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, + pspec); + break; + } +} + +static void +set_property(GObject *object, guint property_id, const GValue *value, + GParamSpec *pspec) +{ + MqMainMenu *main_menu; + + main_menu = MQ_MAIN_MENU(object); + + switch (property_id) { + case PROP_TAB: + main_menu->tab = g_value_get_pointer(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, + pspec); + 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] = g_param_spec_pointer( + "tab", + "MqTab", + "The ancestral MqTab instance", + 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); +} + +GtkWidget * +mq_main_menu_new(MqTab *tab, MqFindToolbar *find_toolbar, MqWebView *web_view) +{ + return g_object_new(MQ_TYPE_MAIN_MENU, + "tab", tab, + "find-toolbar", find_toolbar, + "web-view", web_view, + NULL); +} diff --git a/src/main-menu.h b/src/main-menu.h new file mode 100644 index 0000000..5b9d76c --- /dev/null +++ b/src/main-menu.h @@ -0,0 +1,56 @@ +/* + * 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 . + */ + +typedef struct _MqMainMenu MqMainMenu; +typedef struct _MqMainMenuClass MqMainMenuClass; + +#ifndef MQ_MAIN_MENU_H +#define MQ_MAIN_MENU_H + +#include + +#include "tab.h" +#include "find-toolbar.h" +#include "web-view.h" + +G_BEGIN_DECLS + +#define MQ_TYPE_MAIN_MENU (mq_main_menu_get_type()) +#define MQ_MAIN_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + MQ_TYPE_MAIN_MENU, MqMainMenu)) +#define MQ_IS_MAIN_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + MQ_TYPE_MAIN_MENU)) +#define MQ_MAIN_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \ + MQ_TYPE_MAIN_MENU, MqMainMenuClass)) +#define MQ_IS_MAIN_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE( (klass), \ + MQ_TYPE_MAIN_MENU)) +#define MQ_MAIN_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \ + MQ_TYPE_MAIN_MENU, MqMainMenuClass)) + +GType +mq_main_menu_get_type(void); + +GtkWidget * +mq_main_menu_new(MqTab *tab, MqFindToolbar *find_toolbar, MqWebView *web_view); + +G_END_DECLS + +#endif /* MQ_MAIN_MENU_H */ -- cgit v0.9.1