/* This is -*- C -*- */ /* vim: set sw=2: */ /* $Id: guppi-compass-box-view.c,v 1.2 2001/11/26 20:00:11 trow Exp $ */ /* * guppi-compass-box-view.c * * Copyright (C) 2001 The Free Software Foundation * * Developed by Jon Trowbridge * * This program 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 2 of the * License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include "guppi-compass-box-view.h" #include #include static GtkObjectClass *parent_class = NULL; static void position_floating (GuppiCompassBoxView *view) { GuppiGroupView *grp = GUPPI_GROUP_VIEW (view); GuppiGeometry *geom_fixed, *geom_floating; GuppiLayoutEngine *engine; guppi_compass_t pos; double mleft, mright, mtop, mbottom, minner; guppi_element_state_get (guppi_element_view_state ((GuppiElementView *) view), "position", &pos, "margin_left", &mleft, "margin_right", &mright, "margin_top", &mtop, "margin_bottom", &mbottom, "margin_inner", &minner, NULL); if (pos == view->current_pos) { return; } if (view->fixed == NULL || view->floating == NULL) return; geom_fixed = guppi_element_view_geometry (view->fixed); geom_floating = guppi_element_view_geometry (view->floating); /* Tear down existing layout */ engine = guppi_group_view_layout (grp); guppi_layout_engine_remove_geometry_rules (engine, geom_fixed); guppi_layout_engine_remove_geometry_rules (engine, geom_floating); /* Build up new layout based on the current position */ switch (pos) { case GUPPI_COMPASS_INVALID: guppi_group_view_layout_fill (grp, view->fixed, mleft, mright, mtop, mbottom); break; case GUPPI_NORTH: case GUPPI_SOUTH: { GuppiElementView *view_top; GuppiElementView *view_bot; view_top = pos == GUPPI_NORTH ? view->floating : view->fixed; view_bot = pos == GUPPI_NORTH ? view->fixed : view->floating; guppi_group_view_layout_flush_top (grp, view_top, mtop); guppi_group_view_layout_vertically_adjacent (grp, view_top, view_bot, minner); guppi_group_view_layout_flush_bottom (grp, view_bot, mbottom); if (guppi_geometry_has_natural_width (geom_fixed)) guppi_group_view_layout_center_horizontally (grp, view->fixed); else guppi_group_view_layout_fill_horizontally (grp, view->fixed, mleft, mright); if (guppi_geometry_has_natural_width (geom_floating)) guppi_group_view_layout_center_horizontally (grp, view->floating); else guppi_group_view_layout_fill_horizontally (grp, view->floating, mleft, mright); break; } case GUPPI_EAST: case GUPPI_WEST: { GuppiElementView *view_left; GuppiElementView *view_right; view_left = pos == GUPPI_WEST ? view->floating : view->fixed; view_right = pos == GUPPI_WEST ? view->fixed : view->floating; guppi_group_view_layout_flush_left (grp, view_left, mleft); guppi_group_view_layout_horizontally_adjacent (grp, view_left, view_right, minner); guppi_group_view_layout_flush_right (grp, view_right, mright); if (guppi_geometry_has_natural_height (geom_fixed)) guppi_group_view_layout_center_vertically (grp, view->fixed); else guppi_group_view_layout_fill_vertically (grp, view->fixed, mtop, mbottom); if (guppi_geometry_has_natural_height (geom_floating)) guppi_group_view_layout_center_vertically (grp, view->floating); else guppi_group_view_layout_fill_vertically (grp, view->floating, mtop, mbottom); break; } default: g_assert_not_reached (); } view->current_pos = pos; } static void add_hook (GuppiGroupView *grp, GuppiElementView *view) { GuppiCompassBoxView *box_view = GUPPI_COMPASS_BOX_VIEW (grp); if (box_view->floating == NULL) { box_view->floating = view; } else if (box_view->fixed == NULL) { box_view->fixed = view; } else { g_warning ("Can't add more than two views to GuppiCompassBoxView."); return; } guppi_ref (view); if (box_view->fixed && box_view->floating) { position_floating (box_view); } if (GUPPI_GROUP_VIEW_CLASS (parent_class)->add_hook) GUPPI_GROUP_VIEW_CLASS (parent_class)->add_hook (grp, view); } static void changed_state (GuppiElementView *view) { position_floating (GUPPI_COMPASS_BOX_VIEW (view)); if (GUPPI_ELEMENT_VIEW_CLASS (parent_class)->changed_state) GUPPI_ELEMENT_VIEW_CLASS (parent_class)->changed_state (view); } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ static void guppi_compass_box_view_finalize (GtkObject *obj) { GuppiCompassBoxView *x = GUPPI_COMPASS_BOX_VIEW(obj); guppi_unref (x->floating); guppi_unref (x->fixed); guppi_finalized (obj); if (parent_class->finalize) parent_class->finalize (obj); } static void guppi_compass_box_view_class_init (GuppiCompassBoxViewClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *)klass; GuppiGroupViewClass *group_view_class = GUPPI_GROUP_VIEW_CLASS (klass); GuppiElementViewClass *element_view_class = GUPPI_ELEMENT_VIEW_CLASS (klass); parent_class = gtk_type_class (GUPPI_TYPE_GROUP_VIEW); object_class->finalize = guppi_compass_box_view_finalize; group_view_class->add_hook = add_hook; element_view_class->changed_state = changed_state; } static void guppi_compass_box_view_init (GuppiCompassBoxView *obj) { obj->current_pos = -1; } GtkType guppi_compass_box_view_get_type (void) { static GtkType guppi_compass_box_view_type = 0; if (!guppi_compass_box_view_type) { static const GtkTypeInfo guppi_compass_box_view_info = { "GuppiCompassBoxView", sizeof (GuppiCompassBoxView), sizeof (GuppiCompassBoxViewClass), (GtkClassInitFunc)guppi_compass_box_view_class_init, (GtkObjectInitFunc)guppi_compass_box_view_init, NULL, NULL, (GtkClassInitFunc)NULL }; guppi_compass_box_view_type = gtk_type_unique (GUPPI_TYPE_GROUP_VIEW, &guppi_compass_box_view_info); } return guppi_compass_box_view_type; }