📄 dw_table.c
字号:
i, EXTR_VALUE (sub_extremes[i])); if (EXTR_VALUE (sub_extremes[i]) > 0) { delta = rest_w * EXTR_VALUE (sub_extremes[i]) / rest_n; rest_w -= delta; rest_n -= EXTR_VALUE (sub_extremes[i]); if (max) sub_extremes[i].max_width += delta; else sub_extremes[i].min_width += delta; } DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "%d\n", EXTR_VALUE (sub_extremes[i])); } } }}/* * Calculate the column widths of a subtable, fill table->width. */static void Dw_table_sub_calc_col_widths (DwTableSub *sub, gint32 width, gint32 total_width){ enum { AT_MIN, AT_MAX, AT_NORM }; /* for sub_status */ gint *sub_status; gint32 avail_width, sub_width, width_norm_cols; gint32 col_width, sum_sub_min_widths, sum_orig_sub_min_widths; gint i, num_cols, cols_per_sub, num_norm_cols, num_nf_subs, num_nf_cols; gint rest_w, rest_n, delta; gboolean success; gint32 border_spacing, diff; DwExtremes extremes, *sub_extremes, sum_nf_sub_extremes; num_cols = sub->end_col - sub->start_col; if (num_cols == 1) { /* single column */ DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " single column at %d: width = %d\n", sub->start_col, width); sub->table->col_width[sub->start_col] = width; } else { /* complex subtable * * The comments "STEP <n>" refer to the documentation in * ../doc/DwTable.txt, "Calculating column widths". Read this * parallel. */ DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " --> complex subtable from %d to %d, width = %d " "(total = %d)\n", sub->start_col, sub->end_col, width, total_width); border_spacing = DW_WIDGET (sub->table)->style->border_spacing; diff = (sub->num_subs - 1) * border_spacing; avail_width = width - diff; extremes = sub->total_extremes; if (width > extremes.max_width) extremes.max_width = width; sub_extremes = g_new (DwExtremes, sub->num_subs); sum_sub_min_widths = 0; /* ---- STEP 1: Calculate relative widths. ---- */ for (i = 0; i < sub->num_subs; i++) { sub_extremes[i] = sub->subs[i].total_extremes; if (sub->subs[i].use_percentage != USE_PERCENTAGE_NO) { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " sub %d [%s] has width of %g%% " "-> adjusting: %d/%d -> ", i, sub->subs[i].fixed_width ? "fixed" : "variable", 100 * sub->subs[i].percentage, sub_extremes[i].min_width, sub_extremes[i].max_width); col_width = sub->subs[i].percentage * total_width; if (col_width < sub_extremes[i].min_width) col_width = sub_extremes[i].min_width; sub_extremes[i].min_width = col_width; if (sub->subs[i].use_percentage == USE_PERCENTAGE_ALL) sub_extremes[i].max_width = col_width; DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "%d/%d\n", sub_extremes[i].min_width, sub_extremes[i].max_width); } else { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " sub %d [%s]: %d/%d\n", i, sub->subs[i].fixed_width ? "fixed" : "variable", sub_extremes[i].min_width, sub_extremes[i].max_width); } sum_sub_min_widths += sub_extremes[i].min_width; } /* ---- STEP 2: Eventually, decrease them again. ---- */ if (sum_sub_min_widths > width) { sum_orig_sub_min_widths = 0; for (i = 0; i < sub->num_subs; i++) sum_orig_sub_min_widths += sub->subs[i].total_extremes.min_width; rest_w = sum_sub_min_widths - (width -diff); rest_n = sum_sub_min_widths - sum_orig_sub_min_widths; for (i = 0; i < sub->num_subs; i++) { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " decreasing sub %d: %d -> ", i, sub_extremes[i].min_width); if (sub_extremes[i].min_width != sub->subs[i].total_extremes.min_width) { delta = rest_w * (sub_extremes[i].min_width - sub->subs[i].total_extremes.min_width) / rest_n; rest_w -= delta; rest_n -= (sub_extremes[i].min_width - sub->subs[i].total_extremes.min_width); } else delta = 0; sub_width = sub_extremes[i].min_width - delta; Dw_table_sub_calc_col_widths (&sub->subs[i], sub_width, total_width); DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "%d\n", sub_width); } } else { /* ---- STEP 3: Eventually, increase the sub-subtable extremes ---- */ num_nf_subs = 0; num_nf_cols = 0; sum_nf_sub_extremes.min_width = 0; sum_nf_sub_extremes.max_width = 0; for (i = 0; i < sub->num_subs; i++) if (!(sub->subs[i].fixed_width || sub->subs[i].use_percentage == USE_PERCENTAGE_ALL)) { num_nf_cols += (sub->subs[i].end_col - sub->subs[i].start_col); num_nf_subs++; sum_nf_sub_extremes.min_width += sub_extremes[i].min_width; sum_nf_sub_extremes.max_width += sub_extremes[i].max_width; } /* If all subtables are fixed, unfix them all. */ if (num_nf_subs == 0) { num_nf_subs = -1; num_nf_cols = num_cols; } Dw_table_sub_adjust_col_widths (sub, FALSE, extremes.min_width, sub_extremes, num_nf_subs, num_nf_cols, sum_nf_sub_extremes.min_width); Dw_table_sub_adjust_col_widths (sub, TRUE, extremes.max_width, sub_extremes, num_nf_subs, num_nf_cols, sum_nf_sub_extremes.max_width); /* ---- STEP 4: Finally, calculate the widths. ---- */ sub_status = g_new (gint, sub->num_subs); /* First, assume that all columns have the same width. */ for (i = 0; i < sub->num_subs; i++) sub_status[i] = AT_NORM; do { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 3, " columns: "); /* Calculate the normal width, and the number of columns at this width. */ width_norm_cols = avail_width; num_norm_cols = num_cols; for (i = 0; i < sub->num_subs; i++) { if (sub_status[i] != AT_NORM) { num_norm_cols -= (sub->subs[i].end_col - sub->subs[i].start_col); if (sub_status[i] == AT_MIN) width_norm_cols -= sub_extremes[i].min_width; else width_norm_cols -= sub_extremes[i].max_width; } DEBUG_MSG (DEBUG_WIDTH_LEVEL + 3, "%c", "ian"[sub_status[i]]); } DEBUG_MSG (DEBUG_WIDTH_LEVEL + 3, "\n"); DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " norm: %d, width = %d\n", num_norm_cols, width_norm_cols); /* * Iteratively, test for minimum/maximum, and correct the * status. As soon as one test fails, the status is * changed, and the iteration starts again from the * beginning. */ success = TRUE; for (i = 0; success && i < sub->num_subs; i++) { cols_per_sub = (sub->subs[i].end_col - sub->subs[i].start_col); switch (sub_status[i]) { case AT_NORM: /* Columns at normal width must between min and max. */ if (width_norm_cols * cols_per_sub < num_norm_cols * sub_extremes[i].min_width) { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " sub %d at min\n", i); sub_status[i] = AT_MIN; success = FALSE; } else if (width_norm_cols * cols_per_sub > num_norm_cols * sub_extremes[i].max_width) { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " sub %d at max\n", i); sub_status[i] = AT_MAX; success = FALSE; } break; case AT_MIN: /* If the column is at min, the the normal width (which has been changed), must tested against the min. */ if (width_norm_cols * cols_per_sub > num_norm_cols * sub_extremes[i].min_width) { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " sub %d at norm\n", i); sub_status[i] = AT_NORM; success = FALSE; } break; case AT_MAX: /* If the column is at max, the the normal width (which has been changed), must tested against the max. */ if (width_norm_cols * cols_per_sub < num_norm_cols * sub_extremes[i].max_width) { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " sub %d at norm\n", i); sub_status[i] = AT_NORM; success = FALSE; } break; } } } while (!success); /* ---- STEP 5: Apply calculate the widths. ---- */ rest_n= num_norm_cols; rest_w = width_norm_cols; for (i = 0; i < sub->num_subs; i++) { if (sub_status[i] == AT_MIN) sub_width = sub_extremes[i].min_width; else if (sub_status[i] == AT_MAX) sub_width = sub_extremes[i].max_width; else { cols_per_sub = (sub->subs[i].end_col - sub->subs[i].start_col); sub_width = rest_w * cols_per_sub / rest_n; rest_w -= sub_width; rest_n-= cols_per_sub; } Dw_table_sub_calc_col_widths (&sub->subs[i], sub_width, total_width); } g_free (sub_status); } g_free (sub_extremes); }}static DwIterator *Dw_table_iterator (DwWidget *widget, gint mask, gboolean at_end){ DwIteratorInt *it = g_new (DwIteratorInt, 1); it->it.widget = widget; it->it.mask = mask; it->it.next = Dw_table_iterator_next; it->it.prev = Dw_table_iterator_prev; it->it.clone = p_Dw_iterator_clone_std_int; it->it.compare = p_Dw_iterator_compare_std_int; it->it.free = p_Dw_iterator_free_std; it->it.highlight = p_Dw_iterator_highlight_std; it->it.get_allocation = p_Dw_iterator_get_allocation_std; if (at_end) { it->it.content.type = DW_CONTENT_END; it->pos = DW_TABLE(widget)->num_children; } else { it->it.content.type = DW_CONTENT_START; it->pos = -1; } return (DwIterator*)it;}static gboolean Dw_table_iterator_next (DwIterator *it){ DwTable *table = DW_TABLE (it->widget); DwIteratorInt *ii = (DwIteratorInt*)it; DEBUG_MSG (DEBUG_ITERATOR_LEVEL, "Dw_table_iterator_next: %d of %d\n", ii->pos, table->num_children); if (it->content.type == DW_CONTENT_END) return FALSE; /* tables only contain widgets: */ if ((it->mask & DW_CONTENT_WIDGET) == 0) { it->content.type = DW_CONTENT_END; return FALSE; } do { ii->pos++; if (ii->pos >= table->num_children) { it->content.type = DW_CONTENT_END; return FALSE; } } while (table->children[ii->pos] == NULL || table->children[ii->pos]->type != DW_TABLE_CELL); it->content.type = DW_CONTENT_WIDGET; it->content.data.widget = table->children[ii->pos]->data.cell.widget; return TRUE;}static gboolean Dw_table_iterator_prev (DwIterator *it){ DwTable *table = DW_TABLE (it->widget); DwIteratorInt *ii = (DwIteratorInt*)it; if (it->content.type == DW_CONTENT_START) return FALSE; DEBUG_MSG (DEBUG_ITERATOR_LEVEL, "Dw_table_iterator_prev: %d of %d\n", ii->pos, table->num_children); /* tables only contain widgets: */ if ((it->mask & DW_CONTENT_WIDGET) == 0) { it->content.type = DW_CONTENT_START; return FALSE; } do { ii->pos--; if (ii->pos < 0) { it->content.type = DW_CONTENT_START; return FALSE; } } while (table->children[ii->pos] == NULL || table->children[ii->pos]->type != DW_TABLE_CELL); it->content.type = DW_CONTENT_WIDGET; it->content.data.widget = table->children[ii->pos]->data.cell.widget; return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -