/* Gnome panel: border widget
* (C) 1999 the Free Software Foundation
*
* Authors: Jacob Berkman
* George Lebl
*/
#include "config.h"
#include "border-widget.h"
#include "panel-marshal.h"
#include "panel-config-global.h"
#include "multiscreen-stuff.h"
#include "panel-typebuiltins.h"
#undef BORDER_WIDGET_DEBUG
extern GlobalConfig global_config;
static void border_pos_class_init (BorderPosClass *klass);
static void border_pos_instance_init (BorderPos *pos);
static void border_pos_set_hidebuttons (BasePWidget *basep);
static PanelOrient border_pos_get_applet_orient (BasePWidget *basep);
static PanelOrient border_pos_get_hide_orient (BasePWidget *basep);
static void border_pos_get_menu_pos (BasePWidget *basep,
GtkWidget *widget,
GtkRequisition *mreq,
int *x, int *y,
int wx, int wy,
int ww, int wh);
static void border_pos_show_hide_left (BasePWidget *basep);
static void border_pos_show_hide_right (BasePWidget *basep);
static void border_pos_pre_convert_hook (BasePWidget *basep);
static BasePPosClass *border_pos_parent_class;
GType
border_pos_get_type (void)
{
static GType object_type = 0;
if (object_type == 0) {
static const GTypeInfo object_info = {
sizeof (BorderPosClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) border_pos_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (BorderPos),
0, /* n_preallocs */
(GInstanceInitFunc) border_pos_instance_init
};
object_type = g_type_register_static (BASEP_TYPE_POS,
"BorderPos", &object_info, 0);
border_pos_parent_class = g_type_class_ref (BASEP_TYPE_POS);
}
return object_type;
}
enum {
EDGE_CHANGE_SIGNAL,
LAST_SIGNAL
};
static guint border_pos_signals[LAST_SIGNAL] = { 0 };
static void
border_pos_class_init (BorderPosClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
BasePPosClass *pos_class = BASEP_POS_CLASS(klass);
/* set up signals */
border_pos_signals[EDGE_CHANGE_SIGNAL] =
g_signal_new ("edge_change",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (BorderPosClass, edge_change),
NULL,
NULL,
panel_marshal_VOID__ENUM,
G_TYPE_NONE,
1,
PANEL_TYPE_BORDER_EDGE);
/* fill out the virtual funcs */
pos_class->set_hidebuttons = border_pos_set_hidebuttons;
pos_class->get_applet_orient = border_pos_get_applet_orient;
pos_class->get_hide_orient = border_pos_get_hide_orient;
pos_class->get_menu_pos = border_pos_get_menu_pos;
pos_class->north_clicked = pos_class->west_clicked =
border_pos_show_hide_left;
pos_class->south_clicked = pos_class->east_clicked =
border_pos_show_hide_right;
pos_class->pre_convert_hook = border_pos_pre_convert_hook;
}
static void
border_pos_instance_init (BorderPos *pos)
{
pos->edge = BORDER_TOP;
}
static void
border_pos_set_hidebuttons (BasePWidget *basep)
{
if (PANEL_WIDGET(basep->panel)->orient == GTK_ORIENTATION_HORIZONTAL) {
gtk_widget_hide(basep->hidebutton_n);
gtk_widget_show(basep->hidebutton_e);
gtk_widget_show(basep->hidebutton_w);
gtk_widget_hide(basep->hidebutton_s);
} else { /*vertical*/
gtk_widget_show(basep->hidebutton_n);
gtk_widget_hide(basep->hidebutton_e);
gtk_widget_hide(basep->hidebutton_w);
gtk_widget_show(basep->hidebutton_s);
}
}
static PanelOrient
border_pos_get_applet_orient (BasePWidget *basep)
{
BorderPos *pos = BORDER_POS(basep->pos);
switch (pos->edge) {
case BORDER_TOP: return PANEL_ORIENT_DOWN;
case BORDER_RIGHT: return PANEL_ORIENT_LEFT;
case BORDER_BOTTOM: return PANEL_ORIENT_UP;
case BORDER_LEFT: return PANEL_ORIENT_RIGHT;
default: return PANEL_ORIENT_UP;
}
}
static PanelOrient
border_pos_get_hide_orient (BasePWidget *basep)
{
BorderPos *pos = BORDER_POS (basep->pos);
PanelWidget *panel = PANEL_WIDGET (basep->panel);
switch (basep->state) {
case BASEP_AUTO_HIDDEN:
switch (pos->edge) {
case BORDER_TOP: return PANEL_ORIENT_UP;
case BORDER_RIGHT: return PANEL_ORIENT_RIGHT;
case BORDER_LEFT: return PANEL_ORIENT_LEFT;
case BORDER_BOTTOM: return PANEL_ORIENT_DOWN;
}
g_assert_not_reached ();
break;
case BASEP_HIDDEN_LEFT:
return (panel->orient == GTK_ORIENTATION_HORIZONTAL)
? PANEL_ORIENT_LEFT : PANEL_ORIENT_UP;
case BASEP_HIDDEN_RIGHT:
return (panel->orient == GTK_ORIENTATION_HORIZONTAL)
? PANEL_ORIENT_RIGHT : PANEL_ORIENT_DOWN;
default:
g_assert_not_reached ();
break;
}
g_assert_not_reached ();
return PANEL_ORIENT_LEFT;
}
#ifdef BORDER_WIDGET_DEBUG
static void
border_pos_debug_print_edge (BorderEdge edge)
{
g_print ("BorderEdge = ");
switch (edge) {
case BORDER_TOP:
g_print ("(top)\n");
break;
case BORDER_RIGHT:
g_print ("(right)\n");
break;
case BORDER_BOTTOM:
g_print ("(bottom)\n");
break;
case BORDER_LEFT:
g_print ("(left)\n");
break;
default:
g_assert_not_reached ();
break;
}
}
#endif /* BORDER_WIDGET_DEBUG */
static void
border_pos_get_menu_pos (BasePWidget *basep,
GtkWidget *widget,
GtkRequisition *mreq,
int *x, int *y,
int wx, int wy,
int ww, int wh)
{
#ifdef BORDER_WIDGET_DEBUG
border_pos_debug_print_edge (BORDER_POS(basep->pos)->edge);
#endif /* BORDER_WIDGET_DEBUG */
switch (BORDER_POS(basep->pos)->edge) {
case BORDER_TOP:
*x += wx;
*y = wy + wh;
break;
case BORDER_RIGHT:
*x = wx - mreq->width;
*y += wy;
break;
case BORDER_BOTTOM:
*x += wx;
*y = wy - mreq->height;
break;
case BORDER_LEFT:
*x = wx + ww;
*y += wy;
break;
default:
g_assert_not_reached ();
break;
}
}
void
border_widget_change_params (BorderWidget *border,
int screen,
BorderEdge edge,
int sz,
BasePMode mode,
BasePState state,
gboolean hidebuttons_enabled,
gboolean hidebutton_pixmaps_enabled,
PanelBackType back_type,
char *pixmap_name,
gboolean fit_pixmap_bg,
gboolean stretch_pixmap_bg,
gboolean rotate_pixmap_bg,
GdkColor *back_color)
{
GtkOrientation new_orient;
g_return_if_fail (GTK_WIDGET_REALIZED (GTK_WIDGET (border)));
new_orient = (edge == BORDER_TOP ||
edge == BORDER_BOTTOM)
? GTK_ORIENTATION_HORIZONTAL
: GTK_ORIENTATION_VERTICAL;
if (edge != BORDER_POS (border->pos)->edge) {
BORDER_POS(border->pos)->edge = edge;
g_signal_emit (G_OBJECT (border->pos),
border_pos_signals[EDGE_CHANGE_SIGNAL],
0, edge);
}
basep_widget_change_params (BASEP_WIDGET (border),
screen,
new_orient,
sz,
mode,
state,
hidebuttons_enabled,
hidebutton_pixmaps_enabled,
back_type,
pixmap_name,
fit_pixmap_bg,
stretch_pixmap_bg,
rotate_pixmap_bg,
back_color);
}
static void
border_pos_show_hide_left (BasePWidget *basep)
{
switch (basep->state) {
case BASEP_SHOWN:
basep_widget_explicit_hide (basep, BASEP_HIDDEN_LEFT);
break;
case BASEP_HIDDEN_RIGHT:
basep_widget_explicit_show (basep);
break;
default:
break;
}
}
static void
border_pos_show_hide_right (BasePWidget *basep)
{
switch (basep->state) {
case BASEP_SHOWN:
basep_widget_explicit_hide (basep, BASEP_HIDDEN_RIGHT);
break;
case BASEP_HIDDEN_LEFT:
basep_widget_explicit_show (basep);
break;
default:
break;
}
}
static void
border_pos_pre_convert_hook (BasePWidget *basep)
{
basep->keep_in_screen = TRUE;
PANEL_WIDGET (basep->panel)->packed = TRUE;
}
void
border_widget_change_edge (BorderWidget *border, BorderEdge edge)
{
BasePWidget *basep = BASEP_WIDGET (border);
PanelWidget *panel = PANEL_WIDGET (basep->panel);
if (BORDER_POS (border->pos)->edge == edge)
return;
border_widget_change_params (border,
basep->screen,
edge,
panel->sz,
basep->mode,
basep->state,
basep->hidebuttons_enabled,
basep->hidebutton_pixmaps_enabled,
panel->back_type,
panel->back_pixmap,
panel->fit_pixmap_bg,
panel->stretch_pixmap_bg,
panel->rotate_pixmap_bg,
&panel->back_color);
}
GtkWidget *
border_widget_construct (gchar *panel_id,
BorderWidget *border,
int screen,
BorderEdge edge,
gboolean packed,
gboolean reverse_arrows,
int sz,
BasePMode mode,
BasePState state,
gboolean hidebuttons_enabled,
gboolean hidebutton_pixmaps_enabled,
PanelBackType back_type,
char *back_pixmap,
gboolean fit_pixmap_bg,
gboolean stretch_pixmap_bg,
gboolean rotate_pixmap_bg,
GdkColor *back_color)
{
BasePWidget *basep = BASEP_WIDGET (border);
GtkOrientation orient;
if (edge == BORDER_TOP ||
edge == BORDER_BOTTOM)
orient = GTK_ORIENTATION_HORIZONTAL;
else
orient = GTK_ORIENTATION_VERTICAL;
BORDER_POS (basep->pos)->edge = edge;
basep->keep_in_screen = TRUE;
basep_widget_construct (panel_id,
basep,
packed,
reverse_arrows,
screen,
orient,
sz,
mode,
state,
hidebuttons_enabled,
hidebutton_pixmaps_enabled,
back_type,
back_pixmap,
fit_pixmap_bg,
stretch_pixmap_bg,
rotate_pixmap_bg,
back_color);
return GTK_WIDGET (basep);
}