panel-config.c 47.4 KB
Newer Older
1 2 3 4 5 6 7 8 9
/* GNOME panel:   Individual panel configurations
 *
 * (C) 1998 the Free Software Foundation
 * Copyright 2000 Helix Code, Inc.
 *
 * Authors: Jacob Berkman
 *          George Lebl
 */

10
#include <gtk/gtk.h>
11 12

#include <config.h>
13

14 15
#include <string.h>

George Lebl's avatar
George Lebl committed
16
#include <gdk-pixbuf/gdk-pixbuf.h>
17
#include <libart_lgpl/art_misc.h>
George Lebl's avatar
George Lebl committed
18
#include <libart_lgpl/art_affine.h>
19
#include <libart_lgpl/art_filterlevel.h>
George Lebl's avatar
George Lebl committed
20

21 22
#include <libgnome/libgnome.h>
#include <libgnomeui/libgnomeui.h>
23

24
#include "panel-config.h"
Mark McLoughlin's avatar
Mark McLoughlin committed
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

#include "aligned-widget.h"
#include "basep-widget.h"
#include "border-widget.h"
#include "drawer-widget.h"
#include "edge-widget.h"
#include "floating-widget.h"
#include "sliding-widget.h"
#include "panel.h"
#include "multiscreen-stuff.h"

/*
 * FIXME
 */
#include "nothing.cP"

41
static void config_apply (PerPanelConfig *ppc);
42

43 44 45 46 47 48
static GList *ppconfigs = NULL;

/* register changes */
void
panel_config_register_changes (PerPanelConfig *ppc)
{
49
	if (ppc->register_changes) {
50
		config_apply (ppc);
51
		if (ppc->update_function != NULL)
52 53
			ppc->update_function (ppc->update_data);
	}
54
}
55 56

static PerPanelConfig *
57
get_config_struct(GtkWidget *panel)
58 59
{
	GList *list;
60
	for (list = ppconfigs; list != NULL; list = list->next) {
61
		PerPanelConfig *ppc = list->data;
62
		if (ppc->panel == panel)
63 64 65 66
			return ppc;
	}
	return NULL;
}
67

68
void
69
kill_config_dialog (GtkWidget *panel)
70
{
71 72 73 74 75 76 77 78 79
	PerPanelConfig *ppc;

	g_return_if_fail (panel != NULL);
	g_return_if_fail (GTK_IS_WIDGET (panel));

	ppc = get_config_struct (panel);
	if (ppc != NULL &&
	    ppc->config_window != NULL)
		gtk_widget_destroy (ppc->config_window);
80 81
}

82 83 84 85
static void
update_position_toggles (PerPanelConfig *ppc)
{
	GtkWidget *toggle = ppc->toggle[ppc->edge][ppc->align];
86

87
	/* this could happen during type changes */
88 89 90
	if (toggle == NULL)
		return;

91 92 93
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), TRUE);
}

94
void
95
update_config_edge (BasePWidget *panel)
96
{
97 98 99 100 101 102
	PerPanelConfig *ppc;

	g_return_if_fail (panel != NULL);
	g_return_if_fail (GTK_IS_WIDGET (panel));

	ppc = get_config_struct (GTK_WIDGET (panel));
103

104
	if (ppc == NULL ||
105
	    ppc->ppc_origin_change)
106
		return;
107

108
	g_return_if_fail (BORDER_IS_WIDGET (panel));
109

110 111 112
	if (ppc->edge == BORDER_POS (panel->pos)->edge)
		return;

113 114
	ppc->edge = BORDER_POS (panel->pos)->edge;
	update_position_toggles (ppc);
115
}
116

117 118 119
void
update_config_floating_pos (BasePWidget *panel)
{
120 121 122 123 124 125
	PerPanelConfig *ppc;

	g_return_if_fail (panel != NULL);
	g_return_if_fail (GTK_IS_WIDGET (panel));

	ppc = get_config_struct (GTK_WIDGET (panel));
126

127
	if (ppc == NULL ||
128
	    ppc->ppc_origin_change)
129 130 131 132 133 134 135 136 137
		return;

	gtk_spin_button_set_value (GTK_SPIN_BUTTON (ppc->x_spin),
				   FLOATING_POS (panel->pos)->x);

	gtk_spin_button_set_value (GTK_SPIN_BUTTON (ppc->y_spin),
				   FLOATING_POS (panel->pos)->y);
}

138 139 140
void
update_config_floating_pos_limits (BasePWidget *panel)
{
141 142
	GtkWidget *widget;
	PerPanelConfig *ppc;
143 144 145
	int xlimit, ylimit;
	int val;
	GtkAdjustment *adj;
146

147 148 149 150 151 152
	g_return_if_fail (panel != NULL);
	g_return_if_fail (GTK_IS_WIDGET (panel));

	widget = GTK_WIDGET (panel);
	ppc = get_config_struct (widget);

153
	if (ppc == NULL ||
154
	    ppc->ppc_origin_change)
155 156
		return;

157 158
	xlimit = multiscreen_width(panel->screen) - widget->allocation.width;
	ylimit = multiscreen_height(panel->screen) - widget->allocation.height;
159 160 161 162 163 164 165 166 167 168

	adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON (ppc->x_spin));
	if((int)adj->upper == xlimit) {
		adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON (ppc->y_spin));
		if((int)adj->upper == ylimit)
			return;
	}


	val = FLOATING_POS (panel->pos)->x;
169 170
	if(val > xlimit)
		val = xlimit;
171 172 173 174 175
	adj = GTK_ADJUSTMENT(gtk_adjustment_new (val, 0, xlimit, 1, 10, 10));
	gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (ppc->x_spin), adj);
	gtk_adjustment_value_changed(adj);

	val = FLOATING_POS (panel->pos)->y;
176 177
	if(val > ylimit)
		val = ylimit;
178 179 180 181 182
	adj = GTK_ADJUSTMENT(gtk_adjustment_new (val, 0, ylimit, 1, 10, 10));
	gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (ppc->y_spin), adj);
	gtk_adjustment_value_changed(adj);
}

183 184 185 186 187
void
update_config_floating_orient (BasePWidget *panel)
{
	PerPanelConfig *ppc = get_config_struct (GTK_WIDGET (panel));
	GtkWidget *toggle;
188

189
	if (ppc == NULL ||
190
	    ppc->ppc_origin_change)
191 192
		return;

193
	toggle = (PANEL_WIDGET (panel->panel)->orient == GTK_ORIENTATION_HORIZONTAL)
194 195 196 197 198 199
		? ppc->h_orient : ppc->v_orient;

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
				      TRUE);
}

200 201 202 203 204 205 206 207 208 209 210
void
update_config_screen (BasePWidget *w)
{
	PerPanelConfig *ppc = get_config_struct (GTK_WIDGET (w));

	if (ppc == NULL ||
	    ppc->ppc_origin_change)
		return;

	gtk_spin_button_set_value (GTK_SPIN_BUTTON (ppc->screen_spin),
				   w->screen);
211

212
	if (FLOATING_IS_WIDGET (w))
213
		update_config_floating_pos_limits (w);
214
	else if (SLIDING_IS_WIDGET (w))
215
		update_config_offset_limit (w);
216 217
}

218 219
void
update_config_size (GtkWidget *panel)
220 221
{
	PerPanelConfig *ppc = get_config_struct(panel);
222
	int i;
223
	PanelWidget *p;
224 225
	GtkWidget *menuitem;

226
	if (ppc == NULL ||
227
	    ppc->ppc_origin_change)
228
		return;
229

230 231
	p = PANEL_WIDGET(BASEP_WIDGET(panel)->panel);
	switch(p->sz) {
Mark McLoughlin's avatar
Mark McLoughlin committed
232
	case PANEL_SIZE_XX_SMALL:
233
		i = 0;
234
		break;
Mark McLoughlin's avatar
Mark McLoughlin committed
235
	case PANEL_SIZE_X_SMALL:
236
		i = 1;
237
		break;
Mark McLoughlin's avatar
Mark McLoughlin committed
238
	case PANEL_SIZE_SMALL:
239 240
		i = 2;
		break;
241
	default:
Mark McLoughlin's avatar
Mark McLoughlin committed
242
	case PANEL_SIZE_MEDIUM:
243
		i = 3;
244
		break;
Mark McLoughlin's avatar
Mark McLoughlin committed
245
	case PANEL_SIZE_LARGE:
246
		i = 4;
247
		break;
Mark McLoughlin's avatar
Mark McLoughlin committed
248
	case PANEL_SIZE_X_LARGE:
249 250
		i = 5;
		break;
Mark McLoughlin's avatar
Mark McLoughlin committed
251
	case PANEL_SIZE_XX_LARGE:
252
		i = 6;
253 254
		break;
	}
255
	
256
	gtk_option_menu_set_history (GTK_OPTION_MENU (ppc->size_menu), i);
257 258
	menuitem = g_list_nth_data(GTK_MENU_SHELL(GTK_OPTION_MENU(ppc->size_menu)->menu)->children, i);
	gtk_menu_item_activate(GTK_MENU_ITEM(menuitem));
259 260
}

261 262
void
update_config_back (PanelWidget *pw)
263
{
264
	GtkWidget *item = NULL;
265
	int history = 0;
266 267
	PerPanelConfig *ppc;
	
268
	g_return_if_fail (pw);
269
	g_return_if_fail (PANEL_IS_WIDGET(pw));
270
	g_return_if_fail (pw->panel_parent);
271

272
	ppc = get_config_struct (pw->panel_parent);
273

274
	if (ppc == NULL ||
275
	    ppc->ppc_origin_change)
276
		return;
277

278
	switch(pw->back_type) {
279
	default:
280
	case PANEL_BACK_NONE:
281 282
		item = ppc->non;
		history = 0;
283 284
		break;
	case PANEL_BACK_COLOR:
Jiri (George) Lebl's avatar
Jiri (George) Lebl committed
285 286 287 288 289
		gnome_color_picker_set_i16(GNOME_COLOR_PICKER(ppc->backsel),
					   pw->back_color.red,
					   pw->back_color.green,
					   pw->back_color.blue,
					   65535);
290 291
		item = ppc->col;
		history = 1;
292
		break;
293
	case PANEL_BACK_PIXMAP: {
294 295
		GtkWidget   *t;
		const gchar *text;
296 297 298

		t = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (ppc->pix_entry));

299
		text = gtk_entry_get_text (GTK_ENTRY (t));
300 301

		if (strcmp (sure_string (pw->back_pixmap), text))
302 303
			gtk_entry_set_text (GTK_ENTRY (t),
					    sure_string (pw->back_pixmap));
304

305 306
		item = ppc->pix;
		history = 2;
307
		}
308 309
		break;
	}
310

311 312
	gtk_option_menu_set_history(GTK_OPTION_MENU(ppc->back_om), history);
	gtk_menu_item_activate(GTK_MENU_ITEM(item));
313 314 315 316 317 318
}

void
update_config_anchor (BasePWidget *w)
{
	PerPanelConfig *ppc = get_config_struct (GTK_WIDGET (w));
319
	g_return_if_fail (SLIDING_IS_WIDGET (w));
320

321
	if (ppc == NULL ||
322
	    ppc->ppc_origin_change)
323
		return;
324 325 326
	
	ppc->align = SLIDING_POS (w->pos)->anchor;
	update_position_toggles (ppc);
327 328 329 330 331 332 333
}

void
update_config_offset (BasePWidget *w)
{
	PerPanelConfig *ppc = get_config_struct (GTK_WIDGET (w));

334
	g_return_if_fail (SLIDING_IS_WIDGET (w));
335

336
	if (ppc == NULL ||
337
	    ppc->ppc_origin_change)
338 339 340 341 342 343
		return;

	gtk_spin_button_set_value (GTK_SPIN_BUTTON (ppc->offset_spin),
				   SLIDING_POS (w->pos)->offset);
}

344 345 346 347 348 349 350
void
update_config_offset_limit (BasePWidget *panel)
{
	GtkWidget *widget = GTK_WIDGET(panel);
	PerPanelConfig *ppc = get_config_struct (widget);
	int range, val;
	GtkAdjustment *adj;
351 352

	if (ppc == NULL ||
353
	    ppc->ppc_origin_change)
354 355 356
		return;

	if(ppc->edge == BORDER_LEFT || ppc->edge == BORDER_RIGHT)
357 358
		range = multiscreen_height (panel->screen)
			- widget->allocation.height;
359
	else
360 361
		range = multiscreen_width (panel->screen)
			- widget->allocation.width;
362 363 364 365 366 367 368 369 370 371 372 373 374

	adj = gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON (ppc->offset_spin));
	if((int)adj->upper == range)
		return;

	val = SLIDING_POS (panel->pos)->offset;
	if(val > range) val = range;
	adj = GTK_ADJUSTMENT(gtk_adjustment_new (val, 0, range, 1, 10, 10));
	gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON (ppc->offset_spin), adj);
	gtk_adjustment_value_changed(adj);
}


375 376 377 378
void
update_config_align (BasePWidget *w)
{
	PerPanelConfig *ppc = get_config_struct (GTK_WIDGET (w));
379
	g_return_if_fail (ALIGNED_IS_WIDGET (w));
380

381
	if (ppc == NULL ||
382
	    ppc->ppc_origin_change)
383 384
		return;

385 386 387
	if (ppc->align == ALIGNED_POS (w->pos)->align)
		return;

388 389
	ppc->align = ALIGNED_POS (w->pos)->align;
	update_position_toggles (ppc);
390 391
}

392

393
static void
394 395
config_destroy(GtkWidget *widget, gpointer data)
{
396 397
	PerPanelConfig *ppc = data;
	
398
	ppconfigs = g_list_remove (ppconfigs, ppc);
399
	
400 401 402
	g_free (ppc->back_pixmap);
	ppc->back_pixmap = NULL;
	g_free (ppc);
403 404 405
}

static void
406
config_apply (PerPanelConfig *ppc)
407
{
408 409 410
	/* don't update selves, all changes coming from ME */
	ppc->ppc_origin_change = TRUE;

411
	if(EDGE_IS_WIDGET(ppc->panel))
412
		border_widget_change_params(BORDER_WIDGET(ppc->panel),
413
					    ppc->screen,
414
					    ppc->edge,
415
					    ppc->sz,
416 417
					    ppc->mode,
					    BASEP_WIDGET(ppc->panel)->state,
418 419
					    ppc->hidebuttons,
					    ppc->hidebutton_pixmaps,
420 421 422
					    ppc->back_type,
					    ppc->back_pixmap,
					    ppc->fit_pixmap_bg,
423
					    ppc->stretch_pixmap_bg,
424
					    ppc->rotate_pixmap_bg,
425
					    &ppc->back_color);
426
	else if(SLIDING_IS_WIDGET(ppc->panel))
427
		sliding_widget_change_params(SLIDING_WIDGET(ppc->panel),
428
					     ppc->screen,
429
					     ppc->align,
430 431 432 433 434 435 436 437 438 439
					     ppc->offset,
					     ppc->edge,
					     ppc->sz,
					     ppc->mode,
					     BASEP_WIDGET(ppc->panel)->state,
					     ppc->hidebuttons,
					     ppc->hidebutton_pixmaps,
					     ppc->back_type,
					     ppc->back_pixmap,
					     ppc->fit_pixmap_bg,
440
					     ppc->stretch_pixmap_bg,
441
					     ppc->rotate_pixmap_bg,
442
					     &ppc->back_color);
443
	else if (ALIGNED_IS_WIDGET (ppc->panel))
444
		aligned_widget_change_params (ALIGNED_WIDGET (ppc->panel),
445
					      ppc->screen,
446 447 448 449 450 451 452 453 454 455
					      ppc->align,
					      ppc->edge,
					      ppc->sz,
					      ppc->mode,
					      BASEP_WIDGET(ppc->panel)->state,
					      ppc->hidebuttons,
					      ppc->hidebutton_pixmaps,
					      ppc->back_type,
					      ppc->back_pixmap,
					      ppc->fit_pixmap_bg,
456
					      ppc->stretch_pixmap_bg,
457
					      ppc->rotate_pixmap_bg,
458
					      &ppc->back_color);
459
	else if (FLOATING_IS_WIDGET (ppc->panel))
460
		floating_widget_change_params (FLOATING_WIDGET (ppc->panel), 
461 462 463
					       ppc->screen,
					       ppc->x,
					       ppc->y,
464 465 466 467 468 469 470 471 472
					       ppc->orient,
					       ppc->mode,
					       BASEP_WIDGET (ppc->panel)->state,
					       ppc->sz,
					       ppc->hidebuttons,
					       ppc->hidebutton_pixmaps,
					       ppc->back_type,
					       ppc->back_pixmap,
					       ppc->fit_pixmap_bg,
473
					       ppc->stretch_pixmap_bg,
474
					       ppc->rotate_pixmap_bg,
475
					       &ppc->back_color);
476
	else if(DRAWER_IS_WIDGET(ppc->panel)) {
477 478 479 480 481
	        DrawerPos *dp = DRAWER_POS (BASEP_WIDGET (ppc->panel)->pos);
		drawer_widget_change_params(DRAWER_WIDGET (ppc->panel),
					    dp->orient,
					    ppc->mode,
					    BASEP_WIDGET (ppc->panel)->state, 
482
					    ppc->sz,
483 484
					    ppc->hidebuttons,
					    ppc->hidebutton_pixmaps,
485 486 487
					    ppc->back_type,
					    ppc->back_pixmap,
					    ppc->fit_pixmap_bg,
488
					    ppc->stretch_pixmap_bg,
489
					    ppc->rotate_pixmap_bg,
490
					    &ppc->back_color);
491
	}
492

493 494 495
	/* start registering changes again */
	ppc->ppc_origin_change = FALSE;

496
	gtk_widget_queue_draw (ppc->panel);
497 498
}

499
static void
500
set_toggle (GtkWidget *widget, gpointer data)
501
{
502
	PerPanelConfig *ppc = g_object_get_data (G_OBJECT (widget), "PerPanelConfig");
George Lebl's avatar
George Lebl committed
503
	int *the_toggle = data;
504

505
	*the_toggle = GTK_TOGGLE_BUTTON(widget)->active;
506

507
	panel_config_register_changes (ppc);
508 509
}

510 511 512 513 514 515
static void
set_sensitive_toggle (GtkWidget *widget, GtkWidget *widget2)
{
	gtk_widget_set_sensitive(widget2,GTK_TOGGLE_BUTTON(widget)->active);
}

516
static void
517
basep_set_auto_hide (GtkWidget *widget, gpointer data)
518
{
519
	PerPanelConfig *ppc = g_object_get_data (G_OBJECT (widget), "PerPanelConfig");
520 521 522 523
	
	ppc->mode = (GTK_TOGGLE_BUTTON (widget)->active)
		? BASEP_AUTO_HIDE
		: BASEP_EXPLICIT_HIDE;
524

525

526
	panel_config_register_changes (ppc);
527 528 529 530 531 532 533 534 535 536
}

static GtkWidget *
make_hidebuttons_widget (PerPanelConfig *ppc)
{
	GtkWidget *frame;
	GtkWidget *box;
	GtkWidget *button;
	GtkWidget *w;

537
	frame = gtk_frame_new (_("Hiding"));
538 539 540 541 542
	gtk_container_set_border_width (GTK_CONTAINER (frame), GNOME_PAD_SMALL);

	box = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	gtk_container_set_border_width (GTK_CONTAINER (box), GNOME_PAD_SMALL);
	gtk_container_add (GTK_CONTAINER (frame), box);
George Lebl's avatar
George Lebl committed
543
	
544
	/* Auto-hide */
545
	button = gtk_check_button_new_with_label(_("Enable Auto-hide"));
546
	ppc->autohide_button = button;
547
	g_object_set_data (G_OBJECT (button), "PerPanelConfig", ppc);
548 549
	if (ppc->mode == BASEP_AUTO_HIDE)
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
550 551 552
	g_signal_connect (G_OBJECT (button), "toggled", 
			  G_CALLBACK (basep_set_auto_hide), 
			  NULL);
553 554 555
	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE,0);

	/* Hidebuttons enable */
556
	w = button = gtk_check_button_new_with_label (_("Show hide buttons"));
557
	ppc->hidebuttons_button = button;
558
	g_object_set_data (G_OBJECT (button), "PerPanelConfig", ppc);
559 560
	if (ppc->hidebuttons)
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
561 562 563
	g_signal_connect (G_OBJECT (button), "toggled", 
			  G_CALLBACK (set_toggle),
			  &ppc->hidebuttons);
564 565 566
	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE,0);

	/* Arrow enable */
567
	button = gtk_check_button_new_with_label (_("Show arrows on hide button"));
568
	ppc->hidebutton_pixmaps_button = button;
569 570 571
	g_signal_connect (G_OBJECT (w), "toggled", 
			  G_CALLBACK (set_sensitive_toggle),
			  button);
572 573
	if (!ppc->hidebuttons)
		gtk_widget_set_sensitive(button,FALSE);
574
	g_object_set_data (G_OBJECT (button), "PerPanelConfig", ppc);
575 576
	if (ppc->hidebutton_pixmaps)
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
577 578 579
	g_signal_connect (G_OBJECT (button), "toggled", 
			  G_CALLBACK (set_toggle),
			  &ppc->hidebutton_pixmaps);
580 581 582
	gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE,0);	

	return frame;
583 584
}

585 586 587
static void
screen_set (GtkWidget *widget, gpointer data)
{
588
	PerPanelConfig *ppc = g_object_get_data (G_OBJECT (widget), "PerPanelConfig");
589 590 591 592 593

	ppc->screen = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
	panel_config_register_changes (ppc);	
}

594
static GtkWidget *
595
make_misc_widget (PerPanelConfig *ppc, gboolean avoiding)
596 597
{
	GtkWidget *frame;
598 599 600 601 602 603 604
	GtkWidget *box, *hbox;
	GtkWidget *button, *label;
	GtkObject *range;

	if ( ! avoiding &&
	    multiscreen_screens () <= 1)
		return NULL;
605 606 607 608 609 610 611 612

	frame = gtk_frame_new (_("Miscellaneous"));
	gtk_container_set_border_width (GTK_CONTAINER (frame), GNOME_PAD_SMALL);

	box = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	gtk_container_set_border_width (GTK_CONTAINER (box), GNOME_PAD_SMALL);
	gtk_container_add (GTK_CONTAINER (frame), box);
	
613 614 615 616 617 618 619 620 621 622 623 624
	if (multiscreen_screens () > 1) {
		hbox = gtk_hbox_new (FALSE, 0);
		gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);

		label = gtk_label_new (_("Current screen:"));
		gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

		range = gtk_adjustment_new (ppc->screen,
					    0, multiscreen_screens () - 1,
					    1, 1, 1);
		ppc->screen_spin = button =
			gtk_spin_button_new (GTK_ADJUSTMENT (range), 1, 0);
625
		gtk_widget_set_size_request (GTK_WIDGET (button), 65, -1);
626
		g_object_set_data (G_OBJECT (button), "PerPanelConfig", ppc);
627
		gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), ppc->screen);
628 629
		g_signal_connect (G_OBJECT (button), "changed",
				  G_CALLBACK (screen_set), NULL);
630 631 632
		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
	}

633 634 635
	return frame;
}

636
static void
637
border_set_edge (GtkWidget *widget, gpointer data)
638
{
639
	int edge = GPOINTER_TO_INT (data);
640
	PerPanelConfig *ppc = g_object_get_data (G_OBJECT (widget), "PerPanelConfig");
641

642 643 644
	if (ppc->edge == edge)
		return;

645
	ppc->edge = edge;
646
	
647
	panel_config_register_changes (ppc);
648 649
}

650 651 652 653
static void
border_set_align (GtkWidget *widget, gpointer data)
{
	int align = GPOINTER_TO_INT (data);
654
	PerPanelConfig *ppc = g_object_get_data (G_OBJECT (widget), "PerPanelConfig");
655

656 657 658
	if (ppc->align == align)
		return;

659 660
	ppc->align = align;
	
661
	panel_config_register_changes (ppc);
662 663
}

664
static GtkWidget *
665
make_position_widget (PerPanelConfig *ppc, int aligns)
666
{
667
	GtkWidget *pos_box;
668
	GtkWidget *table;
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
	GtkWidget *w = NULL;
	int align;

	pos_box = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	gtk_container_set_border_width (GTK_CONTAINER (pos_box),
					GNOME_PAD_SMALL);

	w = gtk_label_new (_("Panel Position"));
	gtk_box_pack_start (GTK_BOX (pos_box), w, FALSE, FALSE, 0);

	w = gtk_alignment_new (0.5, 0.5, 0, 0);	
	gtk_box_pack_start (GTK_BOX (pos_box), w, FALSE, FALSE, 0);

	table = gtk_table_new (2 + aligns, 2 + aligns, FALSE);
	gtk_container_add (GTK_CONTAINER (w), table);

	w = NULL;

	/* LEFT */
	for (align = 0; align < aligns; ++align) {
		w = w 
			? gtk_radio_button_new_from_widget (
				GTK_RADIO_BUTTON (w))
			: gtk_radio_button_new (NULL);
		ppc->toggle[BORDER_LEFT][align] = w;
694
		gtk_widget_set_size_request (w, 18, 18);
695
		gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (w), FALSE);
696
		g_object_set_data (G_OBJECT (w), "PerPanelConfig", ppc);
697 698 699 700
		gtk_table_attach (GTK_TABLE (table), w, 0, 1,
				  1 + align, 2 + align,
				  GTK_FILL,
				  GTK_EXPAND | GTK_FILL, 0, 0);
701 702 703 704 705 706
		g_signal_connect (G_OBJECT (w), "toggled",
				  G_CALLBACK (border_set_edge),
				  GINT_TO_POINTER (BORDER_LEFT));
		g_signal_connect (G_OBJECT (w), "toggled",
				  G_CALLBACK (border_set_align),
				  GINT_TO_POINTER (align));
707
	}
708
	
709

710 711 712 713 714
	/* TOP */
	for (align = 0; align < aligns; ++align) {
		w = gtk_radio_button_new_from_widget (
			GTK_RADIO_BUTTON (w));
		ppc->toggle[BORDER_TOP][align] = w;
715
		gtk_widget_set_size_request (w, 18, 18);
716
		gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (w), FALSE);
717
		g_object_set_data (G_OBJECT (w), "PerPanelConfig", ppc);
718 719 720 721
		gtk_table_attach (GTK_TABLE (table), w,
				  1 + align, 2 + align, 0, 1,
				  GTK_EXPAND | GTK_FILL,
				  0, 0, 0);
722 723 724 725 726 727
		g_signal_connect (G_OBJECT (w), "toggled",
				  G_CALLBACK (border_set_edge),
				  GINT_TO_POINTER (BORDER_TOP));
		g_signal_connect (G_OBJECT (w), "toggled",
				  G_CALLBACK (border_set_align),
				  GINT_TO_POINTER (align));
728
	}
729 730


731 732 733 734 735
	/* RIGHT */
	for (align = 0; align < aligns; ++align) {
		w = gtk_radio_button_new_from_widget (
			GTK_RADIO_BUTTON (w));
		ppc->toggle[BORDER_RIGHT][align] = w;
736
		gtk_widget_set_size_request (w, 18, 18);
737
		gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (w), FALSE);
738
		g_object_set_data (G_OBJECT (w), "PerPanelConfig", ppc);
739 740 741 742 743
		gtk_table_attach (GTK_TABLE (table), w,
				  1 + aligns, 2 + aligns,
				  1 + align, 2 + align,
				  GTK_FILL,
				  GTK_FILL | GTK_EXPAND, 0, 0);
744 745 746 747 748 749
		g_signal_connect (G_OBJECT (w), "toggled",
				  G_CALLBACK (border_set_edge),
				  GINT_TO_POINTER (BORDER_RIGHT));
		g_signal_connect (G_OBJECT (w), "toggled",
				  G_CALLBACK (border_set_align),
				  GINT_TO_POINTER (align));
750
	}
751 752


753 754 755 756 757
	/* BOTTOM */
	for (align = 0; align < aligns; ++align) {
		w = gtk_radio_button_new_from_widget (
			GTK_RADIO_BUTTON (w));
		ppc->toggle[BORDER_BOTTOM][align] = w;
758
		gtk_widget_set_size_request (w, 18, 18);
759
		gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (w), FALSE);
760
		g_object_set_data (G_OBJECT (w), "PerPanelConfig", ppc);
761 762 763 764 765
		gtk_table_attach (GTK_TABLE (table), w,
				  1 + align, 2 + align,
				  1 + aligns, 2 + aligns,
				  GTK_EXPAND | GTK_FILL,
				  0, 0, 0);
766 767 768 769 770 771
		g_signal_connect (G_OBJECT (w), "toggled",
				  G_CALLBACK (border_set_edge),
				  GINT_TO_POINTER (BORDER_BOTTOM));
		g_signal_connect (G_OBJECT (w), "toggled",
				  G_CALLBACK (border_set_align),
				  GINT_TO_POINTER (align));
772
	}
773

774
	update_position_toggles (ppc);
775

776 777
	w = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
778 779 780 781
	gtk_table_attach (GTK_TABLE (table), w, 
			  1, 1 + aligns,
			  1, 1 + aligns,
			  GTK_FILL, GTK_FILL, 0, 0);
782
	gtk_widget_set_size_request (w, 103, 77);
783

784
	return pos_box;
785
}
786 787 788
	
static GtkWidget *
edge_notebook_page (PerPanelConfig *ppc)
789
{
790
	GtkWidget *vbox, *box, *vvbox;
791
	GtkWidget *w, *f;
792

793
	vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
794
	
795
	f = gtk_frame_new (_("Size and Position"));
796
	gtk_container_set_border_width (GTK_CONTAINER (f), GNOME_PAD_SMALL);
797
	gtk_box_pack_start (GTK_BOX (vbox), f, TRUE, TRUE, 0);
798 799 800 801

	vvbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	gtk_container_set_border_width (GTK_CONTAINER (vvbox), GNOME_PAD_SMALL);
	gtk_container_add (GTK_CONTAINER (f), vvbox);
802
	
803
	box = gtk_hbox_new (TRUE, GNOME_PAD_SMALL);
804
	gtk_box_pack_start (GTK_BOX (vvbox), box, TRUE, TRUE, 0);
805 806 807 808 809 810 811 812 813
	
	w = make_size_widget (ppc);
	gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);

	w = make_position_widget (ppc, 1);
	gtk_box_pack_start (GTK_BOX (box), w,  TRUE, TRUE, 0);

	w = make_hidebuttons_widget (ppc);
	gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
814

815 816 817
	w = make_misc_widget (ppc, TRUE);
	if (w != NULL)
		gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
818 819
	
	return vbox;
820 821 822 823 824
}

static GtkWidget *
aligned_notebook_page (PerPanelConfig *ppc)
{
825
	GtkWidget *vbox, *vvbox, *box;
826
	GtkWidget *w, *f;
827

828 829 830
	vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	
	f = gtk_frame_new (_("Size and Position"));
831
	gtk_container_set_border_width (GTK_CONTAINER (f), GNOME_PAD_SMALL);
832
	gtk_box_pack_start (GTK_BOX (vbox), f, FALSE, TRUE, 0);
833 834 835 836

	vvbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	gtk_container_set_border_width (GTK_CONTAINER (vvbox), GNOME_PAD_SMALL);
	gtk_container_add (GTK_CONTAINER (f), vvbox);
837 838
	
	box = gtk_hbox_new (TRUE, GNOME_PAD_SMALL);
839
	gtk_box_pack_start (GTK_BOX (vvbox), box, TRUE, TRUE, 0);
840 841 842
	
	w = make_size_widget (ppc);
	gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
843

844 845
	w = make_position_widget (ppc, 3);
	gtk_box_pack_start (GTK_BOX (box), w,  FALSE, FALSE, 0);
846

847 848
	w = make_hidebuttons_widget (ppc);
	gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
849 850 851 852

	w = make_misc_widget (ppc, TRUE);
	if (w != NULL)
		gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
853
	
854 855 856
	return vbox;
}

857 858 859
static void
floating_set_orient (GtkWidget *widget, gpointer data)
{
860
	GtkOrientation orient = GPOINTER_TO_INT (data);
861
	PerPanelConfig *ppc = g_object_get_data (G_OBJECT (widget), "PerPanelConfig");
862 863 864 865 866 867

	if (!(GTK_TOGGLE_BUTTON (widget)->active))
		return;

	ppc->orient = orient;

868
	panel_config_register_changes (ppc);
869 870 871 872 873 874
}

static void
floating_set_xy (GtkWidget *widget, gpointer data)
{
	gint16 *xy = data;
875
	PerPanelConfig *ppc = g_object_get_data (G_OBJECT (widget), "PerPanelConfig");
876 877

	*xy = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
878
	panel_config_register_changes (ppc);	
879 880 881 882 883
}

static GtkWidget *
floating_notebook_page (PerPanelConfig *ppc)
{
884
	GtkWidget *vbox;
885
	GtkWidget *vvbox;
886
	GtkWidget *box;
887
	GtkWidget *button, *label;
888
	GtkWidget *orientbox;
889
	GtkObject *range;
890
	GtkWidget *f, *w;
891
	GtkWidget *hbox;
892 893
	int xlimit, ylimit;

894 895 896 897
	xlimit = multiscreen_width (ppc->screen)
		- ppc->panel->allocation.width;
	ylimit = multiscreen_height (ppc->screen)
		- ppc->panel->allocation.height;
898 899 900 901
	
	vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	
	f = gtk_frame_new (_("Size and Position"));
902
	gtk_container_set_border_width (GTK_CONTAINER (f), GNOME_PAD_SMALL);
903
	gtk_box_pack_start (GTK_BOX (vbox), f, FALSE, TRUE, 0);
904 905 906 907

	vvbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	gtk_container_set_border_width (GTK_CONTAINER (vvbox), GNOME_PAD_SMALL);
	gtk_container_add (GTK_CONTAINER (f), vvbox);
908 909
	
	box = gtk_hbox_new (TRUE, GNOME_PAD_SMALL);
910
	gtk_box_pack_start (GTK_BOX (vvbox), box, TRUE, TRUE, 0);
911 912 913
	
	w = make_size_widget (ppc);
	gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
914

915
	/****** bleh ********/
916 917
	orientbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	gtk_box_pack_start (GTK_BOX (box), orientbox, FALSE, FALSE, 0);
918

919 920
	ppc->h_orient = button = gtk_radio_button_new_with_label (
		NULL, _("Orient panel horizontally"));
921
	if(ppc->orient == GTK_ORIENTATION_HORIZONTAL)
922
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
923
	g_object_set_data (G_OBJECT (button), "PerPanelConfig", ppc);
924 925
	g_signal_connect (G_OBJECT (button), "toggled",
			  G_CALLBACK (floating_set_orient),
926
			  GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
927
	gtk_box_pack_start (GTK_BOX (orientbox), button, FALSE, FALSE, 0);
928

929 930 931 932
	ppc->v_orient = button = 
		gtk_radio_button_new_with_label_from_widget (
			GTK_RADIO_BUTTON (ppc->h_orient), 
			_("Orient panel vertically"));
933
	if(ppc->orient == GTK_ORIENTATION_VERTICAL)
934
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
935
	g_object_set_data (G_OBJECT (button), "PerPanelConfig", ppc);
936 937
	g_signal_connect (G_OBJECT (button), "toggled",
			  G_CALLBACK (floating_set_orient),
938
			  GINT_TO_POINTER (GTK_ORIENTATION_VERTICAL));
939
	gtk_box_pack_start (GTK_BOX (orientbox), button, FALSE, FALSE, 0);
940

941
	hbox = gtk_hbox_new (FALSE, 0);
942
	gtk_box_pack_start (GTK_BOX (orientbox), hbox, FALSE, FALSE, 0);
943
	
944 945
	label = gtk_label_new (_("Top left corner's position: X"));
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
946

947
	range = gtk_adjustment_new (ppc->x, 0, xlimit, 1, 10, 10);
948 949
	ppc->x_spin = button =
		gtk_spin_button_new (GTK_ADJUSTMENT (range), 1, 0);
950
	gtk_widget_set_size_request (GTK_WIDGET (button), 65, -1);
951
	g_object_set_data (G_OBJECT (button), "PerPanelConfig", ppc);
952
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), ppc->x);
953 954 955
	g_signal_connect (G_OBJECT (button), "changed",
			  G_CALLBACK (floating_set_xy),
			  &ppc->x);
956
	gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
957

958 959
	label = gtk_label_new (_("Y"));
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
960
	
961
	range = gtk_adjustment_new (ppc->y, 0, ylimit, 1, 10, 10);
962 963
	ppc->y_spin = button =
		gtk_spin_button_new (GTK_ADJUSTMENT (range), 1, 0);
964
	gtk_widget_set_size_request (GTK_WIDGET (button), 65, -1);
965
	g_object_set_data (G_OBJECT (button), "PerPanelConfig", ppc);
966
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), ppc->y);
967 968 969
	g_signal_connect (G_OBJECT (button), "changed",
			  G_CALLBACK (floating_set_xy),
			  &ppc->y);
970
	gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
971

972 973
	w = make_hidebuttons_widget (ppc);
	gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
974 975 976 977

	w = make_misc_widget (ppc, FALSE);
	if (w != NULL)
		gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
978 979
	
	return vbox;
980 981
}

982 983 984 985 986 987 988 989 990

static void
sliding_set_offset (GtkWidget *widget, gpointer data)
{
	PerPanelConfig *ppc = data;

	ppc->offset = 
		gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ppc->offset_spin));

991
	panel_config_register_changes (ppc);
992 993 994 995 996 997
}
	

static GtkWidget *
sliding_notebook_page (PerPanelConfig *ppc)
{
998
	GtkWidget *vvbox, *vbox, *box, *hbox;
999
	GtkWidget *w, *f;
1000
	GtkWidget *l;
1001
	GtkWidget *button;
1002
	GtkAdjustment *adj;
1003
	int range;
1004
	
1005 1006 1007
	vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	
	f = gtk_frame_new (_("Size and Position"));
1008
	gtk_container_set_border_width (GTK_CONTAINER (f), GNOME_PAD_SMALL);
1009 1010
	gtk_box_pack_start (GTK_BOX (vbox), f, FALSE, TRUE, 0);
	
1011 1012 1013 1014 1015
	vvbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
	gtk_container_set_border_width (GTK_CONTAINER (vvbox), GNOME_PAD_SMALL);
	gtk_container_add (GTK_CONTAINER (f), vvbox);
	
	box = gtk_hbox_new (TRUE, GNOME_PAD_SMALL);
1016

1017 1018
	w = make_size_widget (ppc);
	gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
1019

1020 1021 1022 1023 1024 1025 1026 1027 1028
	hbox = gtk_hbox_new (TRUE, GNOME_PAD_SMALL);
	gtk_box_pack_start (GTK_BOX (vvbox), hbox, TRUE, TRUE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (hbox), GNOME_PAD_SMALL);

	gtk_box_pack_start (GTK_BOX (hbox), box, FALSE, FALSE, 0);

	w = make_position_widget (ppc, 2);
	gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);

1029
	hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
1030
	gtk_box_pack_start (GTK_BOX (vvbox), hbox, TRUE, TRUE, 0);
1031 1032

	l = gtk_label_new (_("Offset from screen edge:"));
1033
	gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0);
1034

1035
	if(ppc->edge == BORDER_LEFT || ppc->edge == BORDER_RIGHT)
1036 1037
		range = multiscreen_height (ppc->screen)
			- ppc->panel->allocation.height;
1038
	else
1039 1040
		range = multiscreen_width (ppc->screen)
			- ppc->panel->allocation.width;
1041
	adj = GTK_ADJUSTMENT(gtk_adjustment_new (ppc->offset, 0, range, 1, 10, 10));
1042
	ppc->offset_spin = button = 
1043
		gtk_spin_button_new (adj, 1, 0);
1044
	gtk_widget_set_size_request (button, 100, -1);
1045
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), ppc->offset);
1046 1047
	g_signal_connect (G_OBJECT (button), "changed",
			  G_CALLBACK (sliding_set_offset), ppc);
1048
	gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1049

1050 1051 1052
	w = make_hidebuttons_widget (ppc);
	gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
	
1053 1054 1055 1056
	w = make_misc_widget (ppc, TRUE);
	if (w != NULL)
		gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
	
1057 1058 1059 1060 1061 1062
	return vbox;
}

static void
size_set_size (GtkWidget *widget, gpointer data)
{
1063
	int sz = GPOINTER_TO_INT(data);
1064
	PerPanelConfig *ppc = g_object_get_data (G_OBJECT (widget), "PerPanelConfig");
1065

1066
	if (ppc->sz == sz)
1067 1068
		return;

1069
	ppc->sz = sz;
1070
	
1071
	panel_config_register_changes (ppc);
1072 1073
}

1074 1075
/* XXX: until this is fixed in GTK+ */
static void
1076
activate_proper_item (GtkMenuShell *menu)
1077
{
1078
#ifdef FIXME
1079
	GtkWidget *active;
1080
	active = gtk_menu_shell_get_active (menu);
1081 1082
	if (active != NULL)
		gtk_menu_item_activate (GTK_MENU_ITEM (active));
1083
#endif
1084 1085
}

1086
GtkWidget *
1087
make_size_widget (PerPanelConfig *ppc)
1088 1089 1090
{
	GtkWidget *box;
	GtkWidget *vbox;
1091 1092 1093 1094
	GtkWidget *menu;
	GtkWidget *menuitem;
	GtkWidget *w;
	gchar *s;
1095
	int i;
1096 1097

	/* main vbox */
1098
	vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
1099
	
1100
	box = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
1101
	gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0);
1102 1103

	gtk_box_pack_start (GTK_BOX (box),
1104
			    gtk_label_new (_("Panel size:")),
1105
			    FALSE, FALSE, 0);
1106

1107
	
1108
	menu = gtk_menu_new ();
1109 1110 1111
	g_signal_connect (G_OBJECT (menu), "deactivate", 
			  G_CALLBACK (activate_proper_item), 
			  NULL);