⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dw_table.c

📁 嵌入式浏览器Dillo源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * File: dw_table.c * * Copyright (C) 2001 Sebastian Geerken <sgeerken@users.sourceforge.net> * * 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. */#include <string.h>#include "dw_table.h"#include "list.h"#include "prefs.h"#include "dw_gtk_viewport.h"#define DEBUG_CALC_LEVEL   0#define DEBUG_EXTR_LEVEL   0#define DEBUG_WIDTH_LEVEL 10//#define DEBUG_LEVEL 10#include "debug.h"/* * Some notes: * *    - table->num_children always has the value table->num_cols * *      table->num_rows, and shows the minimal size of *      table->children, *not* the number of children. * *    - table->children[i] may be NULL (unused cells), or a pointer to *      DwTableChild. A DwTableChild may be a span space (blocked by *      COLSPAN or ROWSPAN of another cell), or a cell starting at *      this position. In the last case, the macro CHILD_DEFINED *      returns TRUE. *//*#define BORDERS*/#define CHILD_DEFINED(table, n) ((n) < (table)->num_children && \                                 (table)->children[(n)] != NULL && \                                 (table)->children[(n)]->type != \                                    DW_TABLE_SPAN_SPACE)static void Dw_table_init          (DwTable *table);static void Dw_table_class_init    (DwTableClass *klass);static void Dw_table_destroy       (GtkObject *object);static void Dw_table_size_request  (DwWidget *widget,                                    DwRequisition *requisition);static void Dw_table_get_extremes  (DwWidget *widget,                                    DwExtremes *extremes);static void Dw_table_size_allocate (DwWidget *widget,                                    DwAllocation *allocation);static void Dw_table_set_width     (DwWidget *widget,                                    gint32 width);static void Dw_table_set_ascent    (DwWidget *widget,                                    gint32 ascent);static void Dw_table_set_descent   (DwWidget *widget,                                    gint32 descent);static void Dw_table_draw          (DwWidget *widget,                                    DwRectangle *area,                                    GdkEventExpose *event);static void Dw_table_add           (DwContainer *container,                                    DwWidget *widget);static void Dw_table_remove        (DwContainer *container,                                    DwWidget *widget);static void Dw_table_forall        (DwContainer *container,                                    DwCallback callback,                                    gpointer callback_data);static gint Dw_table_findtext      (DwContainer *container,                                    gpointer FP, gpointer KP,                                    gchar *NewKey);static void Dw_table_realloc_children (DwTable *table);static void Dw_table_sub_create          (DwTable *table);static void Dw_table_sub_free            (DwTableSub *sub);static void Dw_table_sub_get_extremes    (DwTableSub *sub);static void Dw_table_sub_calc_col_widths (DwTableSub *sub,                                          gint32 width,                                          gint32 total_width);static DwContainerClass *parent_class;enum {   /* values of use_percentage */   USE_PERCENTAGE_NO,    /* No percentage in subtable, and USE_PERCENTAGE_NO                          * in all sub-subtables.                          */   USE_PERCENTAGE_SOME,  /* None of the other cases. This affects the minimal,                          * but not the maximal width of the subtable.                          */   USE_PERCENTAGE_ALL    /* Percentage in subtable, or USE_PERCENTAGE_ALL in                          * all sub-subtables. This affects the minimal and                          * the maximal width of the subtable.                          */};/* * Standard Gtk+ function. */GtkType a_Dw_table_get_type (void){   static GtkType type = 0;   if (!type) {      GtkTypeInfo info = {         "DwTable",         sizeof (DwTable),         sizeof (DwTableClass),         (GtkClassInitFunc) Dw_table_class_init,         (GtkObjectInitFunc) Dw_table_init,         (GtkArgSetFunc) NULL,         (GtkArgGetFunc) NULL,         (GtkClassInitFunc) NULL      };      type = gtk_type_unique (DW_TYPE_CONTAINER, &info);   }   return type;}/* * Standard Gtk+ function. */DwWidget* a_Dw_table_new (void){   GtkObject *object;   object = gtk_object_new (DW_TYPE_TABLE, NULL);   return DW_WIDGET (object);}/* * Standard Gtk+ function. */static void Dw_table_init (DwTable *table){   DW_WIDGET_SET_FLAGS (table, DW_USES_HINTS);   /* random value */   table->avail_width = 100;   table->cur_row = -1;   table->cur_col = 0;   table->num_children_max = 1;  /* 16 */   table->num_children = 0;   table->children = NULL;   table->num_col_width_max = 1; /* 8 */   table->num_cols = 0;   table->col_width = NULL;   table->cum_height_max = 1;   /* row cumulative height array */   table->num_rows = 0;         /* num_cum_height is (num_rows + 1) */   table->cum_height = g_new(gint32, table->cum_height_max);   table->row_style_max = 1;   table->row_style = g_new(DwStyle*, table->row_style_max);   table->sub = NULL;}/* * Standard Gtk+ function. */static void Dw_table_class_init (DwTableClass *klass){   GtkObjectClass *object_class;   DwWidgetClass *widget_class;   DwContainerClass *container_class;   object_class = (GtkObjectClass*) klass;   widget_class = (DwWidgetClass*) klass;   container_class = (DwContainerClass*) klass;   parent_class = gtk_type_class (DW_TYPE_CONTAINER);   object_class->destroy = Dw_table_destroy;   widget_class->size_request = Dw_table_size_request;   widget_class->get_extremes = Dw_table_get_extremes;   widget_class->size_allocate = Dw_table_size_allocate;   widget_class->set_width = Dw_table_set_width;   widget_class->set_ascent = Dw_table_set_ascent;   widget_class->set_descent = Dw_table_set_descent;   widget_class->draw = Dw_table_draw;   container_class->add = Dw_table_add;   container_class->remove = Dw_table_remove;   container_class->forall = Dw_table_forall;   container_class->findtext = Dw_table_findtext;}/* * Standard Gtk+ function. */static void Dw_table_destroy (GtkObject *object){   DwTable *table = DW_TABLE (object);   gint i;   for (i = 0; i < table->num_children; i++)      if (table->children[i]) {         if (table->children[i]->type == DW_TABLE_CELL)            gtk_object_unref(GTK_OBJECT(table->children[i]->data.cell.widget));         g_free (table->children[i]);      }   g_free (table->children);   table->num_children = 0;   g_free (table->col_width);   g_free (table->cum_height);   for (i = 0; i < table->num_rows; i++)      if (table->row_style[i])         a_Dw_style_unref (table->row_style[i]);   g_free (table->row_style);   if (table->sub)      Dw_table_sub_free (table->sub);   (* GTK_OBJECT_CLASS(parent_class)->destroy) (object);}/* * Standard Dw function. * Furthermore, table->width and table->cum_height are filled. */static void Dw_table_size_request (DwWidget *widget,                                   DwRequisition *requisition){   DwExtremes extremes;   gint32 avail_width;   DwTable *table = DW_TABLE (widget);   gint row, row2, col, col2, n;   gint32 child_height, set_width;   DwWidget *child;   DwRequisition child_requisition;   /* Calculate the widths of the columns, and store it in table->col_width. */   if (table->num_cols > 0) {      a_Dw_widget_get_extremes (DW_WIDGET (table), &extremes);      if (DW_STYLE_IS_LENGTH (widget->style->width))         avail_width = DW_STYLE_GET_LENGTH (widget->style->width,                                            widget->style->font);      else if (DW_STYLE_IS_PERCENTAGE (widget->style->width))         /*          * If the width is > 100%, we use 100%, this prevents ugly          * results. (May be changed in future, when a more powerful          * rendering is implemented, to handle fixed positions etc.,          * as defined by CSS2.)          */         avail_width = table->avail_width *            MIN (DW_STYLE_GET_PERCENTAGE (widget->style->width), 1.0);      else         avail_width = table->avail_width;      if (avail_width < extremes.min_width)         avail_width = extremes.min_width;      if (widget->style->width == DW_STYLE_UNDEF_LENGTH &&          avail_width > extremes.max_width)         avail_width = extremes.max_width;      DEBUG_MSG (DEBUG_WIDTH_LEVEL + 3,                 "--> Calculating column widths for (%d x %d) table.\n",                 table->num_cols, table->num_rows);      DEBUG_MSG (DEBUG_WIDTH_LEVEL + 3,                 "    [ %d --(%d, %d)--> %d ]\n",                 table->avail_width, extremes.min_width, extremes.max_width,                 avail_width);      avail_width -= (2 * widget->style->border_spacing +                      p_Dw_style_box_diff_width (widget->style));      Dw_table_sub_calc_col_widths         (table->sub, avail_width,          avail_width - (table->num_cols - 1) * widget->style->border_spacing);      DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "<-- END\n");   }   /* Calculate the total width. */   requisition->width = p_Dw_style_box_diff_width (widget->style) +      (table->num_cols + 1) * widget->style->border_spacing;   for (col = 0; col < table->num_cols; col++)      requisition->width += table->col_width[col];   /* Calculate the height. */   for (row = 0; row <= table->num_rows; row++)      table->cum_height[row] = widget->style->border_spacing;   for (row = 0; row < table->num_rows; row++) {      for (col = 0; col < table->num_cols; col++) {         n = col + row * table->num_cols;         if (CHILD_DEFINED (table, n)) {            child = table->children[n]->data.cell.widget;            set_width = 0;            for (col2 = col;                 col2 < col + table->children[n]->data.cell.colspan;                 col2++)               set_width += table->col_width[col2];            a_Dw_widget_set_width (child, set_width);            a_Dw_widget_set_ascent (child, table->avail_ascent);            a_Dw_widget_set_descent (child, table->avail_descent);            a_Dw_widget_size_request (child, &child_requisition);            child_height =               child_requisition.ascent + child_requisition.descent;            row2 = row + table->children[n]->data.cell.rowspan;            /* row2 is the row directly forced downward by the child */            if (table->cum_height[row2] <                table->cum_height[row] + child_height                + widget->style->border_spacing ) {               table->cum_height[row2] =                  table->cum_height[row] + child_height                  + widget->style->border_spacing;               DEBUG_MSG (1, "Row %d starts at %d.\n",                          row2, table->cum_height[row + table->children[n]                          ->data.cell.rowspan]);               /* todo: column widths should be adjusted a bit. */            }         }      }      /* if we've hit a row that contains no defined children, we need         to force cumulative heights to trickle down to lower rows */      if (table->cum_height[row + 1] < table->cum_height[row])         table->cum_height[row + 1] = table->cum_height[row];   }   requisition->ascent = table->cum_height[table->num_rows] +                         p_Dw_style_box_diff_height (widget->style);   requisition->descent = 0;   DEBUG_MSG (2, "Dw_table_size_request: %d x %d x %d\n",              requisition->width, requisition->ascent, requisition->descent);}/* * Standard Dw function. */static void Dw_table_get_extremes (DwWidget *widget,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -