[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: xchat 1.9.4 (devel) (scrolled tabs)
On Tue, 5 Nov 2002 17:54:27 +1100
Peter Zelezny <zed@linux.com> wrote:
> ...
> * tabs can't scroll when filling the whole window
> (use a ScrolledWindow or multiple rows?) May need help with this
> one.
> ...
Attached is a sort of concept patch. It contains the tabs box within a
Viewport, and uses two buttons to jump left and right within the
Viewport. It's a less than ideal solution, but I think it's tidier
than a ScrolledWindow.
diff -rNu xchat-1.9.4-orig/src/fe-gtk/maingui.c xchat-1.9.4-scrolled-tabs/src/fe-gtk/maingui.c
--- xchat-1.9.4-orig/src/fe-gtk/maingui.c 2002-10-23 12:52:56.000000000 +0100
+++ xchat-1.9.4-scrolled-tabs/src/fe-gtk/maingui.c 2002-11-06 18:26:55.000000000 +0000
@@ -40,6 +40,7 @@
#include <gtk/gtkimage.h>
#include <gtk/gtkmessagedialog.h>
#include <gtk/gtkradiomenuitem.h>
+#include <gtk/gtkobject.h>
#include "../common/xchat.h"
#include "../common/fe.h"
@@ -1620,25 +1621,82 @@
mg_show_generic_tab (active_tab);
}
+/*
+ * GtkViewports request at least as much space as their children do.
+ * If we don't intervene here, the GtkViewport will be granted its
+ * request, even at the expense of resizing the top-level window.
+ */
+static void
+mg_tab_viewport_size_request (GtkWidget *widget, GtkRequisition *requisition, gpointer user_data)
+{
+ requisition->width = 10;
+}
+
+static void
+mg_tab_scroll_left_clicked (GtkWidget *widget, gpointer user_data)
+{
+ session_gui *gui = user_data;
+ GtkAdjustment *adjustment;
+ gint viewport_width;
+ gfloat new_value;
+
+ adjustment = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gui->tabs_box->parent));
+ gdk_window_get_geometry (gui->tabs_box->parent->window, 0, 0, &viewport_width, 0, 0);
+ new_value = tab_search_offset (gui->tabs_box, adjustment->value, 0);
+
+ if (new_value + viewport_width > adjustment->upper)
+ new_value = adjustment->upper - viewport_width;
+
+ gtk_adjustment_set_value (adjustment, new_value);
+}
+
+static void
+mg_tab_scroll_right_clicked (GtkWidget *widget, gpointer user_data)
+{
+ session_gui *gui = user_data;
+ GtkAdjustment *adjustment;
+ gint viewport_width;
+ gfloat new_value;
+
+ adjustment = gtk_viewport_get_hadjustment (GTK_VIEWPORT (gui->tabs_box->parent));
+ gdk_window_get_geometry (gui->tabs_hbox->parent->window, 0, 0, &viewport_width, 0, 0);
+ new_value = tab_search_offset (gui->tabs_box, adjustment->value, 1);
+
+ if (new_value == 0 || new_value + viewport_width > adjustment->upper)
+ new_value = adjustment->upper - viewport_width;
+
+ gtk_adjustment_set_value (adjustment, new_value);
+}
+
static void
mg_create_tabs (session_gui *gui, GtkWidget *box)
{
-/* GtkWidget *sc;
- GtkWidget *frame;
+ GtkWidget *hbox;
+ GtkWidget *viewport;
+ GtkWidget *button;
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- gtk_box_pack_start (GTK_BOX (box), frame, 0, 0, 0);*/
+ hbox = gtk_hbox_new (0, 0);
+ gtk_widget_show (hbox);
+ gtk_box_pack_start (GTK_BOX (box), 0, 0, 0);
- gui->tabs_box = tab_group_new (mg_switch_tab_cb);
+ viewport = gtk_viewport_new (0, 0);
+ gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
+ gtk_signal_connect (GTK_OBJECT (viewport), "size_request", GTK_SIGNAL_FUNC (mg_tab_viewport_size_request), 0);
+ gtk_widget_show (viewport);
+ gtk_box_pack_start (GTK_BOX (hbox), viewport, 1, 1, 0);
-/* sc = gtk_scrolled_window_new (0, 0);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sc),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
- gtk_scrolled_window_add_with_viewport (sc, gui->tabs_box);*/
+ gui->tabs_box = tab_group_new (mg_switch_tab_cb);
+ gtk_container_add (GTK_CONTAINER (viewport), gui->tabs_box);
- gtk_box_pack_start (GTK_BOX (box), gui->tabs_box, 0, 0, 0);
-/* gtk_container_add (GTK_CONTAINER (frame), gui->tabs_box);*/
+ button = gtk_button_new_with_label ("<");
+ gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (mg_tab_scroll_left_clicked), gui);
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (hbox), button, 0, 0, 0);
+
+ button = gtk_button_new_with_label (">");
+ gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (mg_tab_scroll_right_clicked), gui);
+ gtk_widget_show (button);
+ gtk_box_pack_start (GTK_BOX (hbox), button, 0, 0, 0);
}
static gboolean
diff -rNu xchat-1.9.4-orig/src/fe-gtk/tabs.c xchat-1.9.4-scrolled-tabs/src/fe-gtk/tabs.c
--- xchat-1.9.4-orig/src/fe-gtk/tabs.c 2002-10-23 12:42:45.000000000 +0100
+++ xchat-1.9.4-scrolled-tabs/src/fe-gtk/tabs.c 2002-11-06 18:20:29.000000000 +0000
@@ -335,3 +335,41 @@
tab_group_switch (group, 0, FALSE);
}
}
+
+gint
+tab_search_offset (GtkWidget *group, gint start_offset, gboolean forward)
+{
+ GList *boxes;
+ GList *tabs;
+ GtkWidget *box;
+ GtkWidget *button;
+
+ boxes = GTK_BOX (group)->children;
+ if (!forward && boxes)
+ boxes = g_list_last (boxes);
+
+ while (boxes)
+ {
+ box = ((GtkBoxChild *)boxes->data)->widget;
+ boxes = (forward ? boxes->next : boxes->prev);
+
+ tabs = GTK_BOX (box)->children;
+ if (!forward && tabs)
+ tabs = g_list_last (tabs);
+
+ while (tabs)
+ {
+ button = ((GtkBoxChild *)tabs->data)->widget;
+ tabs = (forward ? tabs->next : tabs->prev);
+
+ if (!GTK_IS_TOGGLE_BUTTON (button))
+ continue;
+
+ if ((forward && button->allocation.x > start_offset) ||
+ (!forward && button->allocation.x < start_offset))
+ return button->allocation.x;
+ }
+ }
+
+ return 0;
+}
diff -rNu xchat-1.9.4-orig/src/fe-gtk/tabs.h xchat-1.9.4-scrolled-tabs/src/fe-gtk/tabs.h
--- xchat-1.9.4-orig/src/fe-gtk/tabs.h 2002-05-04 07:44:48.000000000 +0100
+++ xchat-1.9.4-scrolled-tabs/src/fe-gtk/tabs.h 2002-11-06 18:27:18.000000000 +0000
@@ -5,3 +5,4 @@
void tab_rename (GtkWidget *tab, char *new_name);
void tab_remove (GtkWidget *tab);
void tab_style (GtkWidget *tab, GtkStyle *style);
+gint tab_search_offset (GtkWidget *group, gint start_offset, gboolean forward);