Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

cr-box-view.c

Go to the documentation of this file.
00001 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
00002 
00003 /*
00004  * This file is part of The Croco Library
00005  *
00006  * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org>
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of version 2.1 of 
00010  * the GNU Lesser General Public
00011  * License as published by the Free Software Foundation.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the 
00019  * GNU Lesser General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00022  * USA
00023  */
00024 
00025 /*
00026  *$Id: cr-box-view.c,v 1.13 2003/07/05 21:08:56 dodji Exp $
00027  */
00028 
00029 #include "cr-box-view.h"
00030 #include "cr-lay-eng.h"
00031 #include "cr-om-parser.h"
00032 #include <libxml/tree.h>
00033 
00034 #define PRIVATE(a_this) ((a_this)->priv)
00035 
00036 struct _CRBoxViewPriv
00037 {
00038         CRBoxModel *box_model ;
00039         /*
00040          *The default graphical context
00041          *Function willing to modify this gc
00042          *should save it firts, then modify it,
00043          *draw what they have to draw and then restore it !!
00044          */
00045         GdkGC *gc ;
00046 
00047         CRLayEng *layeng ;
00048 
00049         /**
00050          * a boolean used by some drawing functions.
00051          *greping PRIVATE (a_this)->draw should tell you who uses it :)
00052          */
00053         gboolean draw ;
00054 } ;
00055 
00056 
00057 static GtkLayoutClass *gv_parent_class = NULL ;
00058 
00059 
00060 static void
00061 cr_box_view_class_init (CRBoxViewClass *a_klass) ;
00062 
00063 
00064 static void
00065 cr_box_view_init (CRBoxView *a_this) ;
00066 
00067 
00068 static gboolean
00069 expose_event_cb (GtkWidget *a_this,
00070                  GdkEventExpose *a_event,
00071                  gpointer a_user_data) ;
00072 
00073 static enum CRStatus
00074 draw_box (CRBoxView *a_this,
00075           CRBox *a_box,
00076           GdkRectangle *a_region_to_draw) ;
00077 
00078 static enum CRStatus
00079 draw_borders (CRBoxView *a_bv,
00080               CRBox *a_box) ;
00081 
00082 static enum CRStatus
00083 draw_paddings (CRBoxView *a_bv,
00084                CRBox *a_box) ;
00085 
00086 static enum CRStatus
00087 draw_inner_box (CRBoxView *a_bv,
00088                 CRBox *a_box) ;
00089 
00090 static enum CRStatus
00091 set_border_line_attrs (CRBoxView *a_this,
00092                        CRBox *a_box,
00093                        enum CRBorderStyleProp a_style_prop) ;
00094 
00095 static enum CRStatus
00096 set_color (CRBoxView *a_this, CRRgb *a_rgb_color,
00097            gboolean a_foreground) ;
00098 
00099 static void
00100 cr_box_view_class_init (CRBoxViewClass *a_klass)
00101 {
00102         GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (a_klass) ;
00103 
00104         gv_parent_class = 
00105                 g_type_class_peek_parent (a_klass) ;
00106         
00107         g_return_if_fail (gv_parent_class) ;
00108         g_return_if_fail (gtk_object_class) ;
00109         gtk_object_class->destroy = cr_box_view_destroy ;
00110 }
00111 
00112 static void
00113 cr_box_view_init (CRBoxView *a_this)
00114 {
00115         g_return_if_fail (a_this) ;
00116 
00117         PRIVATE (a_this) = g_try_malloc (sizeof (CRBoxView)) ; 
00118         if (!PRIVATE (a_this))
00119         {
00120                 cr_utils_trace_info ("Out of memory") ;
00121                 return ;
00122         }
00123         memset (PRIVATE (a_this), 0, sizeof (CRBoxView)) ;
00124 }
00125 
00126 
00127 static gboolean
00128 expose_event_cb (GtkWidget *a_this,
00129                  GdkEventExpose *a_event,
00130                  gpointer a_user_data)
00131 {
00132         g_return_val_if_fail (a_event
00133                               && a_this 
00134                               && GTK_IS_LAYOUT (a_this)
00135                               && CR_IS_BOX_VIEW (a_this),
00136                               CR_BAD_PARAM_ERROR) ;
00137 
00138         switch (a_event->type)
00139         {
00140         case GDK_EXPOSE:
00141                 g_return_val_if_fail 
00142                         (PRIVATE (CR_BOX_VIEW (a_this))->box_model
00143                          && ((CRBox*)PRIVATE (CR_BOX_VIEW (a_this))->
00144                          box_model)->children,
00145                          FALSE) ;
00146 
00147                 cr_box_view_layout (CR_BOX_VIEW (a_this)) ;
00148 
00149                 draw_box (CR_BOX_VIEW (a_this),
00150                           ((CRBox*)PRIVATE (CR_BOX_VIEW (a_this))->box_model)->
00151                           children,
00152                           &a_event->area) ;
00153                 break ;
00154 
00155         default:
00156                 cr_utils_trace_info ("Unexpected event received, "
00157                                      "Only GDK_EXPOSE was expected.") ;
00158                 return FALSE ;
00159                 break ;
00160         }
00161 
00162         return FALSE ;
00163         
00164 }
00165 
00166 static enum CRStatus
00167 set_border_line_attrs (CRBoxView *a_this,
00168                        CRBox *a_box,
00169                        enum CRBorderStyleProp a_style_prop)
00170 {
00171         enum CRNumProp border_width_dir ;
00172         GdkGCValues gc_values  ;
00173 
00174         g_return_val_if_fail (a_this && PRIVATE (a_this)
00175                               && a_box
00176                               && a_style_prop < NB_BORDER_STYLE_PROPS,
00177                               CR_BAD_PARAM_ERROR) ;
00178 
00179         memset (&gc_values, 0, sizeof (GdkGCValues)) ;
00180 
00181         gdk_gc_get_values (PRIVATE (a_this)->gc, &gc_values) ;        
00182 
00183         switch (a_style_prop)
00184         {
00185         case BORDER_STYLE_PROP_TOP:
00186                 border_width_dir = NUM_PROP_BORDER_TOP ;
00187                 set_color 
00188                         (a_this, 
00189                          &a_box->style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].cv,
00190                            TRUE /*foreground*/) ;
00191                 break ;
00192 
00193         case BORDER_STYLE_PROP_RIGHT:
00194                 border_width_dir = NUM_PROP_BORDER_RIGHT ;
00195                 set_color (a_this, 
00196                            &a_box->style->
00197                            rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].cv,
00198                            TRUE /*foreground*/) ;
00199                 break ;
00200 
00201         case BORDER_STYLE_PROP_BOTTOM:
00202                 border_width_dir = NUM_PROP_BORDER_BOTTOM ;
00203                 set_color (a_this, 
00204                            &a_box->style->
00205                            rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].cv,
00206                            TRUE /*foreground*/) ;
00207                 break ;
00208 
00209         case BORDER_STYLE_PROP_LEFT:
00210                 border_width_dir = NUM_PROP_BORDER_LEFT ;
00211                 set_color (a_this, 
00212                            &a_box->style->
00213                            rgb_props[RGB_PROP_BORDER_LEFT_COLOR].cv,
00214                            TRUE /*foreground*/) ;
00215                 break ;
00216 
00217         default:
00218                 cr_utils_trace_info ("Bad value of enum CRBorderStyleProp " 
00219                                      "given in parameter") ;
00220                 return CR_BAD_PARAM_ERROR ;
00221 
00222         }
00223 
00224         switch (a_box->style->border_style_props[a_style_prop])
00225         {
00226         case BORDER_STYLE_NONE :
00227         case BORDER_STYLE_HIDDEN:
00228                 PRIVATE (a_this)->draw = FALSE ;
00229                 break ;
00230                         
00231         case BORDER_STYLE_DOTTED:
00232                 gdk_gc_set_line_attributes 
00233                         (PRIVATE (a_this)->gc,
00234                          a_box->style->num_props[border_width_dir].cv.val,
00235                          GDK_LINE_ON_OFF_DASH,
00236                          gc_values.cap_style,
00237                          gc_values.join_style) ;
00238                 PRIVATE (a_this)->draw = TRUE ;
00239                 break ;
00240 
00241         case BORDER_STYLE_DASHED:
00242                 gdk_gc_set_line_attributes 
00243                         (PRIVATE (a_this)->gc,
00244                          a_box->style->num_props[border_width_dir].cv.val,
00245                          GDK_LINE_ON_OFF_DASH,
00246                          gc_values.cap_style,
00247                          gc_values.join_style) ;
00248                 PRIVATE (a_this)->draw = TRUE ;
00249                 break ;
00250 
00251         case BORDER_STYLE_SOLID:
00252         case BORDER_STYLE_DOUBLE:
00253         case BORDER_STYLE_GROOVE:
00254         case BORDER_STYLE_RIDGE:
00255         case BORDER_STYLE_INSET:
00256         case BORDER_STYLE_OUTSET:
00257                 gdk_gc_set_line_attributes 
00258                         (PRIVATE (a_this)->gc,
00259                          a_box->style->num_props[border_width_dir].cv.val,
00260                          GDK_LINE_SOLID,
00261                          gc_values.cap_style,
00262                          gc_values.join_style) ;
00263                 PRIVATE (a_this)->draw = TRUE ;
00264                 break ;
00265         }
00266 
00267         return CR_OK ;
00268 }
00269 
00270 static enum CRStatus
00271 set_color (CRBoxView *a_this, CRRgb *a_rgb_color,
00272            gboolean a_foreground)
00273 {
00274         GdkColor gdk_color = {0} ;
00275         g_return_val_if_fail (a_this && a_rgb_color, 
00276                               CR_BAD_PARAM_ERROR) ;
00277 
00278         gdk_color.red = (a_rgb_color->red << 8)     | a_rgb_color->red ;
00279         gdk_color.green = (a_rgb_color->green << 8) | a_rgb_color->green;
00280         gdk_color.blue = (a_rgb_color->blue << 8)   | a_rgb_color->blue ;
00281 
00282         gdk_rgb_find_color
00283                 (gdk_drawable_get_colormap
00284                  (GDK_DRAWABLE (GTK_LAYOUT (a_this)->bin_window)),
00285                  &gdk_color) ;
00286 
00287         if (a_foreground == FALSE)
00288         {
00289                 gdk_gc_set_background (PRIVATE (a_this)->gc, 
00290                                        &gdk_color) ;
00291         }
00292         else
00293         {
00294                 gdk_gc_set_foreground (PRIVATE (a_this)->gc, 
00295                                        &gdk_color) ;
00296         }
00297 
00298 
00299         return CR_OK ;
00300 }
00301 
00302 static enum CRStatus
00303 draw_borders (CRBoxView *a_this,
00304               CRBox *a_box)
00305 {
00306         GdkWindow * window = NULL ;
00307         GtkWidget *widget = NULL ;
00308         CRBox *box = NULL ;
00309 
00310         gulong x0=0, y0=0, x1=0, y1=0 ;
00311         enum CRStatus status = CR_OK ;
00312 
00313         g_return_val_if_fail (a_this
00314                               && CR_IS_BOX_VIEW (a_this)
00315                               && a_box,
00316                               CR_BAD_PARAM_ERROR) ;
00317 
00318         widget = GTK_WIDGET (a_this) ;
00319         window = GTK_LAYOUT (a_this)->bin_window ;
00320         g_return_val_if_fail (window, CR_ERROR) ;
00321 
00322         box = a_box ;
00323         g_return_val_if_fail (box, CR_ERROR) ;
00324 
00325         /*
00326          *Draw left border.
00327          */
00328         x0 = box->border_edge.x + (box->padding_edge.x - box->border_edge.x)/2 ;
00329         /*x0 = box->border_edge.x ;*/
00330         y0 = box->border_edge.y ;
00331         x1 = x0;
00332         y1 = y0 + box->border_edge.height ;
00333         status = set_border_line_attrs (a_this, a_box,
00334                                         BORDER_STYLE_PROP_LEFT) ;
00335         g_return_val_if_fail (status == CR_OK, status) ;
00336 
00337         if (PRIVATE (a_this)->draw == TRUE)
00338                 gdk_draw_line
00339                         (window,
00340                          PRIVATE (a_this)->gc,
00341                          x0, y0, x1, y1);
00342 
00343         /*
00344          *draw right border
00345          */
00346         x0 = box->padding_edge.x + box->padding_edge.width +
00347                 (box->border_edge.x + box->border_edge.width 
00348                  - box->padding_edge.x - box->padding_edge.width)/2 ;
00349         y0 = box->border_edge.y ;
00350         x1 = x0 ;
00351         /*y1 remains the same as y0*/
00352         status = set_border_line_attrs (a_this, a_box,
00353                                         BORDER_STYLE_PROP_RIGHT) ;
00354         g_return_val_if_fail (status == CR_OK, status) ;
00355 
00356         if (PRIVATE (a_this)->draw == TRUE)
00357                 gdk_draw_line (window, PRIVATE (a_this)->gc,
00358                                x0, y0, x1, y1) ;
00359 
00360         /*
00361          *draw top border.
00362          */
00363         x0 = box->border_edge.x ;
00364         y0 = box->border_edge.y + (box->padding_edge.y - box->border_edge.y)/2 ;
00365         /*y0 = box->border_edge.y ;*/
00366         x1 = x0 + box->border_edge.width ;
00367         y1 = y0 ;
00368         status = set_border_line_attrs (a_this, a_box,
00369                                               BORDER_STYLE_PROP_TOP) ;
00370         g_return_val_if_fail (status == CR_OK, status) ;
00371 
00372         if (PRIVATE (a_this)->draw == TRUE)
00373                 gdk_draw_line (window, PRIVATE (a_this)->gc,
00374                                x0, y0, x1, y1) ;
00375 
00376         /*
00377          *draw bottom border
00378          */
00379         /*x0 remains the same as previous x0 ;*/
00380         
00381         y0 = box->padding_edge.y + box->padding_edge.height +
00382                 (box->border_edge.y + box->border_edge.height 
00383                  - box->padding_edge.y - box->padding_edge.height)/2 ;
00384 
00385         /*y0 = box->padding_edge.y + box->padding_edge.height ;*/
00386         x1 = x0 + box->border_edge.width ;
00387         y1  = y0 ;
00388         status = set_border_line_attrs (a_this, a_box,
00389                                               BORDER_STYLE_PROP_BOTTOM) ;
00390         g_return_val_if_fail (status == CR_OK, status) ;
00391 
00392         if (PRIVATE (a_this)->draw == TRUE)
00393                 gdk_draw_line (window, PRIVATE (a_this)->gc,
00394                                x0, y0, x1, y1) ;
00395 
00396         PRIVATE (a_this)->draw = TRUE ;
00397 
00398         return CR_OK ;
00399 }
00400 
00401 
00402 static enum CRStatus
00403 draw_paddings (CRBoxView *a_this,
00404                CRBox *a_box)
00405 {
00406         GdkWindow * window = NULL ;
00407         GtkWidget *widget = NULL ;
00408         CRBox *box = NULL ;
00409 
00410         g_return_val_if_fail (a_this
00411                               && CR_IS_BOX_VIEW (a_this)
00412                               && a_box,
00413                               CR_BAD_PARAM_ERROR) ;
00414 
00415         widget = GTK_WIDGET (a_this) ;
00416         window = GTK_LAYOUT (a_this)->bin_window ;
00417         g_return_val_if_fail (window, CR_ERROR) ;
00418 
00419         box = a_box ;
00420         g_return_val_if_fail (box, CR_ERROR) ;
00421 
00422         set_color (a_this, 
00423                    &a_box->style->rgb_props[RGB_PROP_BACKGROUND_COLOR].cv,
00424                    TRUE/*foreground*/) ;
00425 
00426         gdk_draw_rectangle 
00427                 (window,
00428                  PRIVATE (a_this)->gc,
00429                  TRUE,
00430                  box->padding_edge.x, box->padding_edge.y,
00431                  box->padding_edge.width, box->padding_edge.height) ;
00432 
00433         return CR_OK ;
00434 }
00435 
00436 
00437 static enum CRStatus
00438 draw_inner_box (CRBoxView *a_this,
00439                 CRBox *a_box)
00440 {
00441         GtkWidget *widget = NULL, *label = NULL ;
00442         CRBox *box = NULL ;
00443    
00444         g_return_val_if_fail (a_this
00445                               && CR_IS_BOX_VIEW (a_this)
00446                               && a_box,
00447                               CR_BAD_PARAM_ERROR) ;
00448 
00449         widget = GTK_WIDGET (a_this) ;        
00450         g_return_val_if_fail (widget, CR_ERROR) ;
00451 
00452         box = a_box ;
00453         g_return_val_if_fail (box, CR_ERROR) ;
00454 
00455         if (!box->content)
00456                 return CR_OK ;
00457 
00458         if (box->content->content_cache)
00459         {
00460                 label = GTK_WIDGET (box->content->content_cache) ;
00461                 g_return_val_if_fail (label, CR_ERROR) ;
00462         }
00463 
00464         g_return_val_if_fail (label, CR_ERROR) ;
00465 
00466         if (label->parent == NULL)                
00467                 gtk_layout_put (GTK_LAYOUT (a_this), label,
00468                                 box->inner_edge.x, 
00469                                 box->inner_edge.y) ;
00470         else
00471                 gtk_layout_move (GTK_LAYOUT (a_this), label,
00472                                  box->inner_edge.x, 
00473                                  box->inner_edge.y) ;
00474 
00475         gtk_widget_show_all (widget) ;
00476 
00477         return CR_OK ;
00478 }
00479 
00480 
00481 static enum CRStatus
00482 draw_box (CRBoxView *a_this,
00483           CRBox *a_box,
00484           GdkRectangle *a_region_to_draw)
00485 {
00486         CRBox *cur_box = NULL ;
00487         GtkWidget *widget = NULL;
00488 
00489         g_return_val_if_fail (a_this
00490                               && CR_IS_BOX_VIEW (a_this)
00491                               && a_box,                              
00492                               CR_BAD_PARAM_ERROR) ;
00493 
00494         widget = GTK_WIDGET (a_this) ;
00495         g_return_val_if_fail (widget, CR_ERROR) ;
00496 
00497         if (!PRIVATE (a_this)->gc)
00498         {
00499                 PRIVATE (a_this)->gc = gdk_gc_new 
00500                         (GDK_DRAWABLE (GTK_LAYOUT (a_this)->bin_window)) ;
00501                 g_return_val_if_fail (PRIVATE (a_this)->gc,
00502                                       CR_ERROR) ;
00503 
00504                 gdk_gc_copy (PRIVATE (a_this)->gc,
00505                              GTK_WIDGET (a_this)->style->base_gc[widget->state]);
00506         }
00507 
00508         for (cur_box = a_box; cur_box ; cur_box = cur_box->next)
00509         {
00510                 /*draw_margins (a_this, cur_box) ;*/
00511                 draw_paddings (a_this, cur_box) ;
00512                 draw_inner_box (a_this, cur_box) ;
00513                 draw_borders (a_this, cur_box) ;                                
00514 
00515                 if (cur_box->children)
00516                 {
00517                         draw_box (a_this,
00518                                   cur_box->children,
00519                                   a_region_to_draw) ;
00520                 }
00521         }
00522 
00523         return CR_OK ;
00524 }
00525 
00526 /**********************************
00527  *Public funtions
00528  **********************************/
00529 
00530 GType
00531 cr_box_view_get_type (void)
00532 {
00533         static GType type = 0 ;
00534 
00535         if (type == 0)
00536         {
00537                 static const GTypeInfo type_info = 
00538                         {
00539                                 sizeof (CRBoxViewClass),
00540                                 NULL,NULL,
00541                                 (GClassInitFunc)cr_box_view_class_init,
00542                                 NULL, NULL,
00543                                 sizeof (CRBoxView),
00544                                 0,
00545                                 (GInstanceInitFunc)cr_box_view_init
00546                         } ;
00547 
00548                 type = g_type_register_static (GTK_TYPE_LAYOUT,
00549                                              "CRBoxView", &type_info, 0) ;
00550         }
00551 
00552         return type ;
00553 }
00554 
00555 
00556 CRBoxView *
00557 cr_box_view_new_from_xml_css_bufs (const guchar *a_xml_buf,
00558                                    const guchar *a_css_buf)
00559 {
00560         enum CRStatus status = CR_OK ;
00561         CRStyleSheet *sheet = NULL;
00562         xmlDoc * xml_doc = NULL;
00563         CRBoxView *result = NULL ;
00564         gulong len = 0 ;
00565         CRCascade *cascade = NULL ;
00566         CRBoxModel *box_model = NULL ;
00567         
00568         result = g_object_new (CR_TYPE_BOX_VIEW, NULL) ;
00569         g_return_val_if_fail (result, NULL) ;
00570 
00571         len = strlen (a_css_buf) ;
00572         status = cr_om_parser_simply_parse_buf (a_css_buf, len, CR_UTF_8,
00573                                                 &sheet) ;
00574         
00575         if (status != CR_OK || !sheet)
00576         {
00577                 cr_utils_trace_info ("Could not parse css buf") ;
00578                 status = CR_ERROR ;
00579                 goto cleanup ;
00580         }
00581                 
00582         len = strlen (a_xml_buf) ;
00583         xml_doc = xmlParseMemory (a_xml_buf, len) ;
00584         if (!xml_doc)
00585         {
00586                 cr_utils_trace_info ("Could not parse xml buf") ;
00587                 status = CR_ERROR ;
00588                 goto cleanup ;
00589         }
00590 
00591         PRIVATE (result)->layeng = cr_lay_eng_new (GTK_LAYOUT (result)) ;
00592         if (!PRIVATE (result)->layeng)
00593         {       
00594                 cr_utils_trace_info ("Could not instanciate the layout engine. "
00595                                      "The system may be out of memory") ;
00596                 cr_box_view_destroy (GTK_OBJECT (result)) ;
00597                 return NULL ;
00598         }
00599 
00600         cascade = cr_cascade_new (sheet, NULL, NULL) ;
00601         
00602         if (!cascade)
00603         {
00604                 cr_utils_trace_info ("could not create the cascade") ;
00605                 cr_utils_trace_info 
00606                         ("The system is possibly out of memory") ;
00607                 goto cleanup ;
00608         }
00609         sheet = NULL ;
00610 
00611         status = cr_lay_eng_create_box_model (PRIVATE (result)->layeng,
00612                                               xml_doc, cascade,
00613                                               &box_model) ;
00614         if (status != CR_OK)
00615         {
00616                 cr_utils_trace_info ("could not build the annotated doc") ;
00617                 goto cleanup ;
00618         }
00619         
00620         if (box_model)
00621         {
00622                 box_model->box.inner_edge.width = 800 ;
00623                 box_model->box.inner_edge.max_width = 800 ;
00624                 box_model->box.inner_edge.width = 600 ;
00625 
00626                 cr_box_view_set_box_model (result, box_model) ;
00627                 gtk_layout_set_size (GTK_LAYOUT (result), 1024, 768) ;
00628                 g_signal_connect (G_OBJECT (result),
00629                                   "expose-event",
00630                                   (GCallback)expose_event_cb,
00631                                   NULL) ;
00632 
00633                 return result ;
00634         }
00635 
00636  cleanup:
00637         if (sheet)
00638         {
00639                 cr_stylesheet_destroy (sheet) ;
00640                 sheet = NULL ;
00641         }
00642         
00643         if (xml_doc)
00644         {
00645                 xmlFreeDoc (xml_doc) ;
00646                 xml_doc = NULL ;
00647         }
00648 
00649         if (cascade)
00650         {
00651                 cr_cascade_destroy (cascade) ;
00652                 cascade = NULL ;
00653         }
00654 
00655         if (box_model)
00656         {
00657                 cr_box_destroy ((CRBox*)box_model) ;
00658                 box_model = NULL ;
00659         }
00660         
00661         if (result)
00662         {
00663                 gtk_object_destroy (GTK_OBJECT (result)) ;
00664         }
00665 
00666         return NULL ;
00667 }
00668 
00669 
00670 CRBoxView *
00671 cr_box_view_new_from_bm (CRBoxModel *a_box_root)
00672 {
00673         CRBoxView *result = NULL ;
00674 
00675         result = g_object_new (CR_TYPE_BOX_VIEW, NULL) ;
00676         g_return_val_if_fail (result, NULL) ;
00677 
00678         cr_box_view_set_box_model (result, a_box_root) ;
00679         gtk_layout_set_size (GTK_LAYOUT (result), 1024, 768) ;
00680         g_signal_connect (G_OBJECT (result),
00681                           "expose-event",
00682                           (GCallback)expose_event_cb,
00683                           NULL) ;
00684 
00685         PRIVATE (result)->layeng = cr_lay_eng_new (GTK_LAYOUT (result)) ;
00686         if (!PRIVATE (result)->layeng)
00687         {       
00688                 cr_utils_trace_info ("Could not instanciate the layout engine. "
00689                                      "The system may be out of memory") ;
00690                 cr_box_view_destroy (GTK_OBJECT (result)) ;
00691 
00692                 return NULL ;
00693         }
00694         return result ;
00695 }
00696 
00697 
00698 enum CRStatus
00699 cr_box_view_set_box_model (CRBoxView *a_this,
00700                            CRBoxModel *a_box_model)
00701 {
00702         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
00703 
00704         if (PRIVATE (a_this)->box_model)
00705         {
00706                 if (cr_box_unref ((CRBox*)PRIVATE (a_this)->box_model) == TRUE)
00707                         PRIVATE (a_this) = NULL ;
00708         }
00709 
00710         PRIVATE (a_this)->box_model = a_box_model ;
00711         if (a_box_model)
00712                 cr_box_ref ((CRBox*)a_box_model) ;
00713 
00714         return TRUE ;
00715 }
00716 
00717 enum CRStatus
00718 cr_box_view_layout (CRBoxView *a_this)
00719 {
00720         
00721         g_return_val_if_fail (a_this 
00722                               && CR_IS_BOX_VIEW (a_this)
00723                               && PRIVATE (a_this)->box_model, 
00724                               CR_BAD_PARAM_ERROR) ;
00725 
00726         cr_lay_eng_layout_box_tree (PRIVATE (a_this)->layeng,
00727                                     PRIVATE (a_this)->box_model->box.children) ;
00728         /*cr_box_dump_to_file (PRIVATE (a_this)->box_model->box.children,
00729           0, stdout) ;*/
00730 
00731         return CR_OK ;
00732 }
00733 
00734 enum CRStatus
00735 cr_box_view_get_box_model (CRBoxView *a_this, CRBoxModel **a_box_model)
00736 {
00737         g_return_val_if_fail (a_this
00738                               && PRIVATE (a_this), 
00739                               CR_BAD_PARAM_ERROR) ;
00740 
00741         *a_box_model = PRIVATE (a_this)->box_model ;
00742         return TRUE ;
00743 }
00744 
00745 void
00746 cr_box_view_destroy (GtkObject *a_this)
00747 {
00748         CRBoxView *self = NULL ;
00749 
00750         g_return_if_fail (a_this && CR_IS_BOX_VIEW (a_this)) ;
00751 
00752         self = CR_BOX_VIEW (a_this) ;
00753         g_return_if_fail (self && PRIVATE (self) ) ;
00754 
00755         if (PRIVATE (self)->box_model)
00756         {
00757                 cr_box_unref ((CRBox*)PRIVATE (self)->box_model) ;
00758                 PRIVATE (self)->box_model = NULL ;
00759         }
00760 
00761         if (PRIVATE (self)->gc)
00762         {
00763                 gdk_gc_unref (PRIVATE (self)->gc) ;
00764                 PRIVATE (self)->gc = NULL ;
00765         }
00766 
00767         if (PRIVATE (self))
00768         {
00769                 g_free (PRIVATE (self)) ;
00770                 PRIVATE (self) = NULL ;
00771         }
00772 
00773         if (gv_parent_class
00774             && GTK_OBJECT_CLASS (gv_parent_class)->destroy)
00775         {
00776                 GTK_OBJECT_CLASS (gv_parent_class)->destroy (a_this) ;
00777         }
00778 }

Generated on Wed Oct 1 01:36:44 2003 for Libcroco by doxygen 1.3.3