/*
* Tab
*
* 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 "tab.h"
#include "tab-chrome.h"
#include "tab-body.h"
static void
tab_list_button_toggled_cb(GtkToggleButton *toggle_button, GtkWidget *tab_list)
{
if (gtk_toggle_button_get_active(toggle_button)) {
gtk_widget_show(tab_list);
} else {
gtk_widget_hide(tab_list);
}
}
#define BUTTON_ROWS 2
#define BUTTON_COLS 4
#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_widget_set_can_focus(buttons[Y * BUTTON_COLS + X], FALSE); \
gtk_grid_attach(GTK_GRID(button_grid), \
buttons[Y * BUTTON_COLS + X], X, Y, 1, 1); \
} while (0)
#define NEW_TOGGLE(Y, X, ICON, TOOLTIP) \
do { \
buttons[Y * BUTTON_COLS + X] = gtk_toggle_button_new(); \
gtk_button_set_image(GTK_BUTTON(buttons[Y * BUTTON_COLS + X]), \
gtk_image_new_from_icon_name(ICON, \
GTK_ICON_SIZE_BUTTON)); \
gtk_widget_set_tooltip_text(buttons[Y * BUTTON_COLS + X], \
TOOLTIP); \
gtk_widget_set_can_focus(buttons[Y * BUTTON_COLS + X], FALSE); \
gtk_grid_attach(GTK_GRID(button_grid), \
buttons[Y * BUTTON_COLS + X], X, Y, 1, 1); \
} while (0)
static gboolean
tab_label_button_press_cb(GtkWidget *widget, GdkEvent *event, MqTab *tab)
{
GtkWidget *button_grid;
GtkWidget *buttons[BUTTON_ROWS * BUTTON_COLS];
GtkWidget *box;
GtkWidget *tab_list;
GtkWidget *popover; /* TODO: Add to MqWindow */
/* Make sure this is a right mouse button press event. */
if (event->type != GDK_BUTTON_PRESS || event->button.button != 3) {
return FALSE;
}
/* Set up button grid. */
button_grid = gtk_grid_new();
gtk_widget_set_halign(button_grid, GTK_ALIGN_CENTER);
/* Set up buttons. */
NEW_BUTTON(0, 0, "view-refresh", "Reload tab");
NEW_BUTTON(0, 1, "edit-copy", "Duplicate tab");
NEW_BUTTON(0, 2, "window-new", "Open tab in new window");
NEW_BUTTON(0, 3, "window-close", "Close tab");
NEW_BUTTON(1, 0, "tab-new-symbolic", "New tab");
NEW_BUTTON(1, 1, "edit-undo", "Undo close tab");
NEW_TOGGLE(1, 3, "view-list-symbolic", "Tab list...");
/* Set up the button rows box. */
box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(box), button_grid,
TRUE, FALSE, 0);
/* Set up the tab list. */
tab_list = gtk_label_new("Tab list");
gtk_box_pack_start(GTK_BOX(box), tab_list,
TRUE, FALSE, 0);
g_signal_connect(buttons[1 * BUTTON_COLS + 3], "toggled",
G_CALLBACK(tab_list_button_toggled_cb), tab_list);
/* Set up the popover. */
popover = gtk_popover_new(widget);
gtk_container_add(GTK_CONTAINER(popover), box);
/* NB: gtk_popover_popup() is new in GTK+ 3.22. */
gtk_widget_show_all(popover);
gtk_widget_hide(tab_list);
return FALSE;
}
#undef BUTTON_ROWS
#undef BUTTON_COLS
#undef NEW_BUTTON
#undef NEW_TOGGLE
static void
mq_tab_populate_tab(MqTab *tab)
{
GtkWidget *box;
tab->tab_image = gtk_image_new_from_icon_name("text-x-generic",
GTK_ICON_SIZE_BUTTON);
tab->tab_label = gtk_label_new("New tab");
gtk_label_set_ellipsize(GTK_LABEL(tab->tab_label),
PANGO_ELLIPSIZE_END);
gtk_widget_set_hexpand(tab->tab_label, TRUE);
gtk_widget_set_size_request(tab->tab_label, 50, 1);
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start(GTK_BOX(box), tab->tab_image, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), tab->tab_label, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), gtk_button_new_from_icon_name(
"window-close", GTK_ICON_SIZE_BUTTON), FALSE, FALSE, 0);
gtk_widget_show_all(box);
tab->tab = gtk_event_box_new();
g_signal_connect(tab->tab, "button-press-event",
G_CALLBACK(tab_label_button_press_cb), tab);
gtk_event_box_set_visible_window(GTK_EVENT_BOX(tab->tab),
FALSE);
gtk_container_add(GTK_CONTAINER(tab->tab), box);
}
static void
update_tab_image(MqTab *tab)
{
gtk_image_set_from_surface(GTK_IMAGE(tab->tab_image),
webkit_web_view_get_favicon(tab->web_view));
}
static void
update_tab_label(MqTab *tab)
{
gtk_label_set_text(GTK_LABEL(tab->tab_label),
g_strdup_printf("%d. %s", tab->tab_position + 1,
webkit_web_view_get_title(tab->web_view)));
}
static void
favicon_cb(WebKitWebView __attribute__((unused)) *web_view,
GParamSpec __attribute__((unused)) *paramspec, MqTab *tab)
{
update_tab_image(tab);
}
static void
title_cb(WebKitWebView __attribute__((unused)) *web_view,
GParamSpec __attribute__((unused)) *paramspec, MqTab *tab)
{
update_tab_label(tab);
}
MqTab *
mq_tab_new(gchar *uri)
{
MqTab *tab;
tab = malloc(sizeof(*tab));
mq_tab_populate_tab(tab);
tab->chrome = mq_tab_chrome_new(uri);
tab->body = mq_tab_body_new(uri);
tab->web_view = mq_tab_body_get_web_view(tab->body);
/* FIXME: Doesn't work? */
g_signal_connect(tab->web_view, "notify::favicon",
G_CALLBACK(favicon_cb), tab);
g_signal_connect(tab->web_view, "notify::title",
G_CALLBACK(title_cb), tab);
mq_tab_chrome_set_web_view(tab->chrome, tab->web_view);
tab->container = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(tab->container),
mq_tab_chrome_get_container(tab->chrome), FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(tab->container),
mq_tab_body_get_container(tab->body), TRUE, TRUE, 0);
return tab;
}
GtkWidget *
mq_tab_get_tab(MqTab *tab)
{
return tab->tab;
}
GtkWidget *
mq_tab_get_container(MqTab *tab)
{
return tab->container;
}
void
mq_tab_update_position(MqTab *tab, guint position)
{
tab->tab_position = position;
update_tab_label(tab);
}