'smart qotes' now will replace '<', '>' and '&' inside 'pre' and 'code' tags
[k8lowj.git] / src / about.c
blob29308e344c547ff3279a5128cdab766f11bd131b
1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2003 Evan Martin <evan@livejournal.com>
4 * vim: tabstop=4 shiftwidth=4 noexpandtab :
5 */
7 #include "gtk-all.h"
8 #include "util-gtk.h"
10 #include <stdlib.h>
12 #include "icons.h"
13 #include "thanks.h"
14 #include "spawn.h"
16 /* magic number, defines how long the name will stay centered before scrolling off. */
17 #define COUNTER_DELAY 20
19 typedef struct {
20 GtkWidget *win;
22 GtkWidget *scrollerbox;
23 GtkWidget *scroller;
24 int curcontrib;
25 int timeout;
26 PangoLayout *layout;
27 int x, y, counter;
29 GtkWidget *linkwin;
30 GdkCursor *cursor;
31 } AboutUI;
33 /* randomly permute the list of contributors. */
34 static void
35 rearrange_contribs(void) {
36 int i, j;
37 Contributor t;
39 srand((unsigned int)time(NULL));
40 for (i = 0; i < CONTRIBCOUNT; i++) {
41 j = rand() % CONTRIBCOUNT;
42 t = contribs[i];
43 contribs[i] = contribs[j];
44 contribs[j] = t;
48 static void
49 homepage_cb(GtkWidget *win, GdkEventButton *eb, AboutUI *aui) {
50 spawn_url(GTK_WINDOW(aui->win), "http://logjam.danga.com");
53 static GtkWidget*
54 make_title_box(AboutUI *aui) {
55 GtkWidget *hbox;
56 GtkWidget *image, *label;
57 char *text;
59 image = gtk_image_new_from_stock("logjam-goat", GTK_ICON_SIZE_DIALOG);
61 label = gtk_label_new(NULL);
62 text = g_strdup_printf(_("<b><big>LogJam %s</big></b>\n"
63 "<small>Copyright (C) 2000-2004 Evan Martin</small>"),
64 PACKAGE_VERSION);
65 gtk_label_set_markup(GTK_LABEL(label), text);
66 g_free(text);
67 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
69 aui->linkwin = gtk_event_box_new();
70 g_signal_connect(G_OBJECT(aui->linkwin), "button-press-event",
71 G_CALLBACK(homepage_cb), aui);
72 aui->cursor = gdk_cursor_new(GDK_HAND2);
73 gtk_container_add(GTK_CONTAINER(aui->linkwin), label);
75 hbox = gtk_hbox_new(FALSE, 10);
76 gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
77 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
78 gtk_box_pack_start(GTK_BOX(hbox), aui->linkwin, TRUE, FALSE, 0);
80 return hbox;
83 static gboolean
84 showthanks_cb(AboutUI *aui) {
85 int w, h;
87 if (!aui->layout || aui->y > aui->scroller->allocation.height) {
88 if (aui->layout) {
89 g_object_unref(G_OBJECT(aui->layout));
90 aui->curcontrib = (aui->curcontrib + 1) % CONTRIBCOUNT;
91 gtk_tooltips_set_tip(app.tooltips, aui->scrollerbox,
92 _(contribs[aui->curcontrib].contribution), NULL);
95 aui->layout = gtk_widget_create_pango_layout(aui->scroller, contribs[aui->curcontrib].name);
96 pango_layout_get_pixel_size(aui->layout, &w, &h);
97 gtk_widget_set_size_request(aui->scroller, w, h);
98 gtk_widget_queue_resize(aui->scroller);
99 aui->y = -h;
100 } else {
101 /* advance y, except when we get to zero we cycle through counter once. */
102 if (aui->y == 0) {
103 aui->counter++;
104 } else {
105 aui->y++;
108 if (aui->counter == COUNTER_DELAY) {
109 aui->counter = 0;
110 aui->y++;
113 if (aui->scroller->window)
114 gdk_window_invalidate_rect(aui->scroller->window, NULL, FALSE);
116 return TRUE; /* continue running. */
118 static void
119 button_cb(GtkWidget *widget, GdkEventExpose *event, AboutUI *aui) {
120 /* force advance to next name. */
121 aui->y = aui->scroller->allocation.height+1;
122 showthanks_cb(aui);
123 aui->y = 0;
124 aui->counter = 0;
126 static void
127 expose_cb(GtkWidget *widget, GdkEventExpose *event, AboutUI *aui) {
128 gtk_paint_layout(widget->style, widget->window, GTK_STATE_NORMAL, FALSE,
129 &event->area, widget, "label", aui->x, aui->y, aui->layout);
131 static void
132 configure_cb(GtkWidget *widget, GdkEventConfigure *e, AboutUI *aui) {
133 int w;
134 pango_layout_get_pixel_size(aui->layout, &w, NULL);
135 aui->x = (widget->allocation.width - w) / 2;
136 gdk_window_invalidate_rect(widget->window, NULL, FALSE);
139 static void
140 destroy_cb(GtkWidget *win, AboutUI *aui) {
141 if (aui->layout)
142 g_object_unref(G_OBJECT(aui->layout));
143 if (aui->timeout)
144 g_source_remove(aui->timeout);
145 if (aui->cursor)
146 gdk_cursor_unref(aui->cursor);
147 g_free(aui);
150 void about_dlg(GtkWindow *mainwin) {
151 AboutUI *aui;
152 GtkWidget *mainbox, *fh;
154 aui = g_new0(AboutUI, 1);
156 aui->win = gtk_dialog_new_with_buttons(_("About LogJam"),
157 mainwin, GTK_DIALOG_DESTROY_WITH_PARENT,
158 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
159 NULL);
160 g_signal_connect_swapped(G_OBJECT(aui->win), "response",
161 G_CALLBACK(gtk_widget_destroy), aui->win);
162 g_signal_connect(G_OBJECT(aui->win), "destroy",
163 G_CALLBACK(destroy_cb), aui);
165 /* make the bounding padding box */
166 mainbox = gtk_vbox_new(FALSE, 5);
168 gtk_box_pack_start(GTK_BOX(mainbox), make_title_box(aui), FALSE, FALSE, 0);
170 fh = gtk_label_new(_(
171 "This program is free software; you can redistribute it and/or modify\n"
172 "it under the terms of the GNU General Public License as published by\n"
173 "the Free Software Foundation; either version 2 of the License, or\n"
174 "(at your option) any later version."));
176 gtk_box_pack_start(GTK_BOX(mainbox), fh, TRUE, TRUE, 0);
178 gtk_box_pack_start(GTK_BOX(mainbox),
179 gtk_label_new(_("LogJam was made with the help of many people, including:")),
180 FALSE, FALSE, 0);
182 aui->scrollerbox = gtk_event_box_new();
183 gtk_box_pack_start(GTK_BOX(mainbox), aui->scrollerbox, FALSE, FALSE, 0);
185 aui->scroller = gtk_drawing_area_new();
186 rearrange_contribs();
187 showthanks_cb(aui);
188 gtk_widget_add_events(aui->scroller, GDK_BUTTON_PRESS_MASK);
189 g_signal_connect(G_OBJECT(aui->scroller), "button-press-event",
190 G_CALLBACK(button_cb), aui);
191 g_signal_connect(G_OBJECT(aui->scroller), "expose-event",
192 G_CALLBACK(expose_cb), aui);
193 g_signal_connect(G_OBJECT(aui->scroller), "configure-event",
194 G_CALLBACK(configure_cb), aui);
195 gtk_container_add(GTK_CONTAINER(aui->scrollerbox), aui->scroller);
197 aui->timeout = g_timeout_add(50, (GSourceFunc)showthanks_cb, aui);
199 jam_dialog_set_contents(GTK_DIALOG(aui->win), mainbox);
201 gtk_widget_realize(aui->win);
202 gtk_widget_realize(aui->linkwin);
203 gdk_window_set_cursor(aui->linkwin->window, aui->cursor);
204 gtk_widget_show(aui->win);
205 showthanks_cb(aui);