/*
* 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"
#define NEW_BUTTON(BOX, I, NAME, TOOLTIP) \
do { \
buttons[I] = gtk_button_new_from_icon_name(NAME, \
GTK_ICON_SIZE_BUTTON); \
gtk_widget_set_tooltip_text(buttons[I], TOOLTIP); \
gtk_widget_set_can_focus(buttons[I], FALSE); \
gtk_box_pack_start(GTK_BOX(BOX ? all_tabs_button_box : \
current_tab_button_box), buttons[I], \
TRUE, FALSE, 0); \
} while (0)
static gboolean
tab_label_button_press_cb(GtkWidget *widget, GdkEvent *event, MqTab *tab)
{
GtkWidget *current_tab_button_box;
GtkWidget *all_tabs_button_box;
GtkWidget *buttons[7];
GtkWidget *button_rows_box;
GtkWidget *stack;
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 boxes. */
current_tab_button_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
all_tabs_button_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_halign(current_tab_button_box, GTK_ALIGN_CENTER);
gtk_widget_set_halign(all_tabs_button_box, 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, 4, "tab-new-symbolic", "New Tab");
NEW_BUTTON(1, 5, "edit-undo", "Undo Close Tab");
NEW_BUTTON(1, 6, "view-list-symbolic", "Tab List...");
/* Set up the button rows box. */
button_rows_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(button_rows_box), current_tab_button_box,
TRUE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(button_rows_box), all_tabs_button_box,
TRUE, FALSE, 0);
/* Set up the stack. */
stack = gtk_stack_new();
gtk_stack_add_named(GTK_STACK(stack), button_rows_box, "buttons");
gtk_stack_add_named(GTK_STACK(stack), gtk_label_new("Tab list"),
"tab_list");
/* Set up the popover. */
popover = gtk_popover_new(widget);
gtk_container_add(GTK_CONTAINER(popover), stack);
/* NB: gtk_popover_popup() is new in GTK+ 3.22. */
gtk_widget_show_all(popover);
/* TODO: gtk_widget_hide() tab list */
return FALSE;
}
#undef NEW_BUTTON
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_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_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;
}