/*
* Main window
*
* 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 "window.h"
#include "tab.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
add_tab(MqWindow *window, gchar *uri, gint position)
{
GtkWidget *tab_label_image;
GtkWidget *tab_label_label;
GtkWidget *tab_label;
MqTab *tab;
GtkWidget *tab_label_event_box;
GtkWidget *tab_widget;
tab_label_image = gtk_image_new_from_icon_name("text-x-generic",
GTK_ICON_SIZE_BUTTON);
tab_label_label = gtk_label_new("New tab");
gtk_label_set_ellipsize(GTK_LABEL(tab_label_label),
PANGO_ELLIPSIZE_END);
gtk_widget_set_hexpand(tab_label_label, TRUE);
gtk_widget_set_size_request(tab_label_label, 50, 1);
tab_label = gtk_grid_new();
gtk_grid_attach(GTK_GRID(tab_label), tab_label_image,
0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(tab_label), tab_label_label,
1, 0, 1, 1);
gtk_grid_attach(GTK_GRID(tab_label), gtk_button_new_from_icon_name(
"window-close", GTK_ICON_SIZE_BUTTON), 2, 0, 1, 1);
gtk_widget_show_all(tab_label);
tab = mq_tab_new(uri, tab_label_image, tab_label_label);
tab_label_event_box = gtk_event_box_new();
g_signal_connect(tab_label_event_box, "button-press-event",
G_CALLBACK(tab_label_button_press_cb), tab);
gtk_event_box_set_visible_window(GTK_EVENT_BOX(tab_label_event_box),
FALSE);
gtk_container_add(GTK_CONTAINER(tab_label_event_box), tab_label);
tab_widget = mq_tab_get_container(tab);
position = gtk_notebook_insert_page(GTK_NOTEBOOK(window->notebook),
tab_widget, tab_label_event_box, position);
gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(window->notebook),
tab_widget, TRUE);
gtk_notebook_set_tab_detachable(GTK_NOTEBOOK(window->notebook),
tab_widget, TRUE);
mq_tab_update_position(tab, position);
}
static void
update_positions(GtkNotebook __attribute__((unused)) *notebook,
GtkWidget __attribute__((unused)) *child,
guint __attribute__((unused)) page_num, MqWindow *window)
{
/* TODO: Once MqWindow has a data structure for tabs, loop through them
* all and call mq_tab_update_position(). */
/* TODO: Should this also update the tabs data structure? Probably. */
/* Temporarily "use" window. */
window = window;
}
MqWindow *
mq_window_new(gchar **uris)
{
MqWindow *window;
guint i;
window = malloc(sizeof(*window));
window->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window->window), 1024, 768);
/* TODO: Don't quit on window close */
g_signal_connect(window->window, "destroy",
G_CALLBACK(gtk_main_quit), NULL);
window->notebook = gtk_notebook_new();
gtk_notebook_set_scrollable(GTK_NOTEBOOK(window->notebook), TRUE);
gtk_notebook_set_group_name(GTK_NOTEBOOK(window->notebook), "mq-tabs");
gtk_widget_set_can_focus(window->notebook, FALSE);
gtk_container_add(GTK_CONTAINER(window->window),
window->notebook);
g_signal_connect(window->notebook, "page-reordered",
G_CALLBACK(update_positions), window);
if (uris && uris[0]) {
for (i = 0; uris && uris[i]; ++i) {
add_tab(window, uris[i], -1);
}
} else {
add_tab(window, "about:new", -1);
}
gtk_widget_show_all(window->window);
return window;
}