home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- #include "xp.h"
- #include "shist.h"
- #include "pa_parse.h"
- #include "layout.h"
- #include "libmocha.h"
-
-
- #define TOP_EDGE 0
- #define BOTTOM_EDGE 1
- #define LEFT_EDGE 2
- #define RIGHT_EDGE 3
-
-
- static lo_GridPercent *
- lo_parse_percent_list(MWContext *context, char *str, int32 *rows)
- {
- char *tptr;
- int32 i, cnt;
- lo_GridPercent *percent_list;
-
- if ((str == NULL)||(*str == '\0'))
- {
- return((lo_GridPercent *)NULL);
- }
-
- cnt = 0;
- tptr = strchr(str, ',');
- while (tptr != NULL)
- {
- cnt++;
- tptr++;
- tptr = strchr(tptr, ',');
- }
- cnt++;
- *rows = cnt;
-
- percent_list = (lo_GridPercent *)XP_ALLOC(cnt * sizeof(lo_GridPercent));
- if (percent_list == NULL)
- {
- return((lo_GridPercent *)NULL);
- }
-
- tptr = str;
- for (i=0; i<cnt; i++)
- {
- char *ptr;
- char *end_ptr;
-
- ptr = strchr(tptr, ',');
- if (ptr != NULL)
- {
- *ptr = '\0';
- }
-
- /*
- * Need the end of the string to check if the number
- * ends in '%', '*', or 'p'.
- */
- if (ptr != NULL)
- {
- end_ptr = (char *)(ptr - 1);
- if (end_ptr < tptr)
- {
- end_ptr = tptr;
- }
- }
- else
- {
- end_ptr = (char *)(str + XP_STRLEN(str) - 1);
- }
-
- if (*end_ptr == '*')
- {
- percent_list[i].type = LO_PERCENT_FREE;
- percent_list[i].original_value = (int32)XP_ATOI(tptr);
- if (percent_list[i].original_value < 1)
- {
- percent_list[i].original_value = 1;
- }
- }
- else if (*end_ptr == '%')
- {
- percent_list[i].type = LO_PERCENT_NORMAL;
- percent_list[i].original_value = (int32)XP_ATOI(tptr);
- if (percent_list[i].original_value <= 0)
- {
- percent_list[i].original_value = 100 / cnt;
- if (percent_list[i].original_value == 0)
- {
- percent_list[i].original_value = 1;
- }
- }
- }
- /*
- * Default is in "pixels"
- */
- else
- {
- int32 val;
-
- percent_list[i].type = LO_PERCENT_FIXED;
- val = (int32)XP_ATOI(tptr);
- val = FEUNITS_X(val, context);
- if (val < 1)
- {
- val = 1;
- }
- percent_list[i].original_value = val;
- }
-
- if (ptr != NULL)
- {
- *ptr = ',';
- tptr = (char *)(ptr + 1);
- }
- }
- return(percent_list);
- }
-
-
- void
- lo_FreeGridEdge(lo_GridEdge *edge)
- {
- if (edge->cell_array != NULL)
- {
- XP_FREE(edge->cell_array);
- }
- XP_DELETE(edge);
- }
-
-
- void
- lo_FreeGridRec(lo_GridRec *grid)
- {
- if (grid == NULL)
- {
- return;
- }
-
- if (grid->row_percents != NULL)
- {
- XP_FREE(grid->row_percents);
- }
- if (grid->col_percents != NULL)
- {
- XP_FREE(grid->col_percents);
- }
-
- if (grid->edge_list != NULL)
- {
- lo_GridEdge *tmp_edge;
- lo_GridEdge *edge_list;
-
- edge_list = grid->edge_list;
- while (edge_list != NULL)
- {
- tmp_edge = edge_list;
- edge_list = edge_list->next;
- lo_FreeGridEdge(tmp_edge);
- }
- }
-
- XP_DELETE(grid);
- }
-
-
- void
- lo_FreeGridCellRec(MWContext *context, lo_GridRec *grid, lo_GridCellRec *cell)
- {
- History_entry *hist;
-
- if (cell == NULL)
- {
- return;
- }
-
- if (cell->url != NULL)
- {
- XP_FREE(cell->url);
- }
- if (cell->name != NULL)
- {
- XP_FREE(cell->name);
- }
- if (cell->context != NULL)
- {
- /*
- * If the cell has a context, use it instead of the
- * parent's context. Otherwise use the parent context.
- * This is bogus but needed to keep the winfe from
- * dumping because it blindly dereferences the context
- * even though it doesn't use it.
- */
- context = cell->context;
- }
- if (cell->hist_list != NULL)
- {
- XP_List *list_ptr;
-
- list_ptr = (XP_List *)cell->hist_list;
- hist = (History_entry *)XP_ListRemoveTopObject(list_ptr);
- while (hist != NULL)
- {
- SHIST_DropEntry(context, hist);
- hist =(History_entry *)XP_ListRemoveTopObject(list_ptr);
- }
- XP_ListDestroy(list_ptr);
- }
- if (cell->hist_array != NULL)
- {
- int32 i;
-
- for (i = 0; i < grid->hist_size; i++)
- {
- hist = (History_entry *)cell->hist_array[i].hist;
- SHIST_DropEntry(context, hist);
- }
- XP_FREE(cell->hist_array);
- }
- XP_DELETE(cell);
- }
-
-
- static lo_GridEdge *
- lo_new_horizontal_edge(MWContext *context, lo_DocState *state,
- int32 cols, int32 x, int32 y, int32 width, int32 height)
- {
- lo_GridEdge *edge;
- LO_EdgeStruct *fe_edge;
-
- edge = XP_NEW(lo_GridEdge);
- if (edge == NULL)
- {
- return(NULL);
- }
-
- fe_edge = (LO_EdgeStruct *)lo_NewElement(context, state, LO_EDGE, NULL, 0);
- if (fe_edge == NULL)
- {
- XP_DELETE(edge);
- return(NULL);
- }
-
- edge->x = x;
- edge->y = y;
- edge->width = width;
- edge->height = height;
- edge->is_vertical = FALSE;
- edge->left_top_bound = 0;
- edge->right_bottom_bound = 0;
- edge->cell_cnt = 0;
- edge->cell_max = 0;
- edge->cell_array = NULL;
- edge->next = NULL;
-
- if (cols > 0)
- {
- int32 cells;
-
- cells = 2 * cols;
- edge->cell_array = (lo_GridCellRec **)XP_ALLOC(cells *
- sizeof(lo_GridCellRec *));
- if (edge->cell_array != NULL)
- {
- edge->cell_max = cells;
- }
- }
-
- fe_edge->type = LO_EDGE;
- fe_edge->ele_id = NEXT_ELEMENT;
- fe_edge->x = x;
- fe_edge->x_offset = 0;
- fe_edge->y = y;
- fe_edge->y_offset = 0;
- fe_edge->width = edge->width;
- fe_edge->height = edge->height;
- fe_edge->line_height = 0;
- fe_edge->next = NULL;
- fe_edge->prev = NULL;
-
- fe_edge->FE_Data = NULL;
- fe_edge->lo_edge_info = (void *)edge;
- fe_edge->is_vertical = edge->is_vertical;
- fe_edge->visible = TRUE;
- fe_edge->movable = TRUE;
- fe_edge->left_top_bound = 0;
- fe_edge->right_bottom_bound = 0;
-
- edge->fe_edge = fe_edge;
-
- return(edge);
- }
-
-
- static lo_GridEdge *
- lo_new_vertical_edge(MWContext *context, lo_DocState *state,
- int32 rows, int32 x, int32 y, int32 width, int32 height)
- {
- lo_GridEdge *edge;
- LO_EdgeStruct *fe_edge;
-
- edge = XP_NEW(lo_GridEdge);
- if (edge == NULL)
- {
- return(NULL);
- }
-
- fe_edge = (LO_EdgeStruct *)lo_NewElement(context, state, LO_EDGE, NULL, 0);
- if (fe_edge == NULL)
- {
- XP_DELETE(edge);
- return(NULL);
- }
-
- edge->x = x;
- edge->y = y;
- edge->width = width;
- edge->height = height;
- edge->is_vertical = TRUE;
- edge->left_top_bound = 0;
- edge->right_bottom_bound = 0;
- edge->cell_cnt = 0;
- edge->cell_max = 0;
- edge->cell_array = NULL;
- edge->next = NULL;
-
- if (rows > 0)
- {
- int32 cells;
-
- cells = 2 * rows;
- edge->cell_array = (lo_GridCellRec **)XP_ALLOC(cells *
- sizeof(lo_GridCellRec *));
- if (edge->cell_array != NULL)
- {
- edge->cell_max = cells;
- }
- }
-
- fe_edge->type = LO_EDGE;
- fe_edge->ele_id = NEXT_ELEMENT;
- fe_edge->x = x;
- fe_edge->x_offset = 0;
- fe_edge->y = y;
- fe_edge->y_offset = 0;
- fe_edge->width = edge->width;
- fe_edge->height = edge->height;
- fe_edge->line_height = 0;
- fe_edge->next = NULL;
- fe_edge->prev = NULL;
-
- fe_edge->FE_Data = NULL;
- fe_edge->lo_edge_info = (void *)edge;
- fe_edge->is_vertical = edge->is_vertical;
- fe_edge->visible = TRUE;
- fe_edge->movable = TRUE;
- fe_edge->left_top_bound = 0;
- fe_edge->right_bottom_bound = 0;
-
- edge->fe_edge = fe_edge;
-
- return(edge);
- }
-
-
- static void
- lo_grow_edge_cell_array(lo_GridEdge *edge, int32 more)
- {
- lo_GridCellRec **old_array;
- lo_GridCellRec **new_array;
- int32 new_size;
-
- /*
- * Error condition, punt.
- */
- if (more <= 0)
- {
- return;
- }
-
- /*
- * If we are not growing the array, but instead allocating a new
- * array.
- */
- if (edge->cell_max == 0)
- {
- edge->cell_array = (lo_GridCellRec **)XP_ALLOC(more *
- sizeof(lo_GridCellRec *));
- if (edge->cell_array != NULL)
- {
- edge->cell_max = more;
- }
- return;
- }
-
- /*
- * Attempt to grow the old array.
- */
- new_size = edge->cell_max + more;
- old_array = edge->cell_array;
- new_array = (lo_GridCellRec **)XP_REALLOC(old_array, (new_size *
- sizeof(lo_GridCellRec *)));
- /*
- * If realloc fails, punt.
- */
- if (new_array == NULL)
- {
- return;
- }
-
- edge->cell_array = new_array;
- edge->cell_max = new_size;
- }
-
-
- static void
- lo_add_cell_to_edge(lo_GridEdge *edge, lo_GridCellRec *cell)
- {
- /*
- * Error.
- */
- if ((cell == NULL)||(edge == NULL))
- {
- return;
- }
-
- /*
- * If I did my math right earlier, this will never happen.
- */
- if (edge->cell_cnt >= edge->cell_max)
- {
- lo_grow_edge_cell_array(edge, 1);
- /*
- * This may fail
- */
- if (edge->cell_cnt >= edge->cell_max)
- {
- return;
- }
- }
-
- edge->cell_array[edge->cell_cnt] = cell;
- edge->cell_cnt++;
- }
-
-
- static void
- lo_adjust_percents(int32 count, lo_GridPercent *percents, int32 max)
- {
- int32 i;
- int32 fixed_percent;
- int32 free_percent;
- int32 total;
-
- if (max == 0)
- max = 1;
-
- /*
- * Total up the three different type of grid cell percentages.
- */
- fixed_percent = 0;
- free_percent = 0;
- total = 0;
- for (i=0; i < count; i++)
- {
- if (percents[i].type == LO_PERCENT_FIXED)
- {
- /*
- * Now that we know the max dimension turn
- * fixed pixel dimensions into percents.
- */
- percents[i].value = 100 * percents[i].original_value / max;
- if (percents[i].value < 1)
- {
- percents[i].value = 1;
- }
- fixed_percent += percents[i].value;
- }
- else if (percents[i].type == LO_PERCENT_FREE)
- {
- percents[i].value = percents[i].original_value;
- free_percent += percents[i].original_value;
- }
- else
- {
- percents[i].value = percents[i].original_value;
- total += percents[i].original_value;
- }
- }
-
- /*
- * If the user didn't explicitly use up all the space.
- */
- if ((total + fixed_percent) < 100)
- {
- int32 val;
-
- /*
- * We have some free percentage cells that want to
- * soak up the excess space.
- */
- if (free_percent > 0)
- {
- int32 used;
- int32 last_i;
-
- last_i = -1;
- used = 0;
- val = 100 - (total + fixed_percent);
- for (i=0; i < count; i++)
- {
- if (percents[i].type == LO_PERCENT_FREE)
- {
- percents[i].value *= val;
- percents[i].value /= free_percent;
- if (percents[i].value < 1)
- {
- percents[i].value = 1;
- }
- used += percents[i].value;
- last_i = i;
- }
- }
- /*
- * Slop the extra into the last qualifying cell.
- */
- if (((used + total + fixed_percent) < 100)&&
- (last_i >= 0))
- {
- percents[last_i].value +=
- (100 - total - fixed_percent - used);
- }
- }
- /*
- * Else we have no free cells, but have some normal
- * percentage cells, distribute the extra space among them.
- */
- else if (total > 0)
- {
- int32 used;
- int32 last_i;
-
- last_i = -1;
- used = 0;
- val = (100 - fixed_percent);
- for (i=0; i < count; i++)
- {
- if (percents[i].type == LO_PERCENT_NORMAL)
- {
- percents[i].value *= val;
- percents[i].value /= total;
- used += percents[i].value;
- last_i = i;
- }
- }
- /*
- * Slop the extra into the last qualifying cell.
- */
- if ((used < val)&&(last_i >= 0))
- {
- percents[last_i].value += (val - used);
- }
- }
- /*
- * Else all we have are fixed percentage cells, we will
- * have to grow them.
- */
- else
- {
- int32 used;
-
- used = 0;
- for (i=0; i < count; i++)
- {
- percents[i].value *= 100;
- percents[i].value /= (total + fixed_percent);
- used += percents[i].value;
- }
- /*
- * Slop the extra into the last cell.
- */
- if ((used < 100)&&(count > 0))
- {
- percents[count - 1].value += (100 - used);
- }
- }
- }
- /*
- * Else if the user allocated too much space, we need to shrink
- * something.
- */
- else if ((total + fixed_percent) > 100)
- {
- int32 val;
-
- /*
- * If there is not too much fixed percentage
- * added, we can just shrink the normal percentage
- * cells to make things fit.
- */
- if (fixed_percent <= 100)
- {
- int32 used;
- int32 last_i;
-
- last_i = -1;
- used = 0;
- val = (100 - fixed_percent);
- for (i=0; i < count; i++)
- {
- if (percents[i].type == LO_PERCENT_NORMAL)
- {
- percents[i].value *= val;
- percents[i].value /= total;
- used += percents[i].value;
- }
- }
- /*
- * Since integer division always truncates, we either
- * made it fit exactly, or overcompensated and made
- * it too small.
- */
- if ((used < val)&&(last_i >= 0))
- {
- percents[last_i].value += (val - used);
- }
- }
- /*
- * Else there is too much fixed percentage as well, we will
- * just shrink all the cells.
- */
- else
- {
- int32 used;
-
- used = 0;
- for (i=0; i < count; i++)
- {
- if (percents[i].type == LO_PERCENT_FREE)
- {
- percents[i].value = 0;
- }
- else
- {
- percents[i].value *= 100;
- percents[i].value /=
- (total + fixed_percent);
- }
- used += percents[i].value;
- }
- /*
- * Since integer division always truncates, we either
- * made it fit exactly, or overcompensated and made
- * it too small.
- */
- if (used < 100)
- {
- percents[count - 1].value += (100 - used);
- }
- }
- }
- }
-
-
- PRIVATE
- void
- lo_LayoutGridCells(MWContext *context, lo_DocState *state,
- int32 x, int32 y, int32 width, int32 height,
- lo_GridRec *grid, lo_GridEdge **edges)
- {
- int32 cols, rows;
- int32 col_cnt, row_cnt;
- int32 orig_x, orig_y;
- lo_GridCellRec *cell_parent;
- lo_GridCellRec *cell_list;
- lo_GridEdge **col_edges;
- lo_GridEdge *top_edge;
- lo_GridEdge *new_edges[4]; /* top, bottom, left, right */
-
- new_edges[TOP_EDGE] = NULL;
- new_edges[BOTTOM_EDGE] = NULL;
- new_edges[LEFT_EDGE] = NULL;
- new_edges[RIGHT_EDGE] = NULL;
-
- if (grid == NULL)
- {
- return;
- }
-
- cols = grid->cols;
- rows = grid->rows;
- cell_list = grid->cell_list;
-
- /*
- * Allocate space for the temporary array of column
- * edge pointer we will need here.
- */
- col_edges = (lo_GridEdge **)XP_ALLOC(sizeof(lo_GridEdge *) * cols);
- if (col_edges == NULL)
- {
- return;
- }
- top_edge = NULL;
-
- /*
- * If we came in with bounding edges, we are a sub-grid, and we need
- * to increase the size of the cell arrays in those edges to reflect
- * the extra cells now bordering them.
- */
- if (edges[TOP_EDGE] != NULL)
- {
- int32 more;
-
- more = (cols * 2) - 1;
- lo_grow_edge_cell_array(edges[TOP_EDGE], more);
- }
- if (edges[BOTTOM_EDGE] != NULL)
- {
- int32 more;
-
- more = (cols * 2) - 1;
- lo_grow_edge_cell_array(edges[BOTTOM_EDGE], more);
- }
- if (edges[LEFT_EDGE] != NULL)
- {
- int32 more;
-
- more = (rows * 2) - 1;
- lo_grow_edge_cell_array(edges[LEFT_EDGE], more);
- }
- if (edges[RIGHT_EDGE] != NULL)
- {
- int32 more;
-
- more = (rows * 2) - 1;
- lo_grow_edge_cell_array(edges[RIGHT_EDGE], more);
- }
-
- orig_x = x;
- orig_y = y;
- col_cnt = 0;
- row_cnt = 0;
- cell_parent = NULL;
- while (cell_list != NULL)
- {
- lo_GridEdge *tmp_edge;
-
- tmp_edge = NULL; /* make gcc happy */
-
- cell_list->width_percent =
- (intn)grid->col_percents[col_cnt].value;
- cell_list->height_percent =
- (intn)grid->row_percents[row_cnt].value;
-
- cell_list->x = x;
- if (col_cnt != 0)
- {
- cell_list->x += grid->grid_cell_border;
- }
- cell_list->y = y;
- if (row_cnt != 0)
- {
- cell_list->y += grid->grid_cell_border;
- }
-
- cell_list->width = width * cell_list->width_percent / 100;
- if (cell_list->width < grid->grid_cell_min_dim)
- {
- cell_list->width = grid->grid_cell_min_dim;
- }
- if (col_cnt > 0)
- {
- cell_list->width -= grid->grid_cell_border;
- }
- if (col_cnt < (cols - 1))
- {
- cell_list->width -= grid->grid_cell_border;
- }
-
- /*
- * Make sure the last column uses all the remaining space.
- * We subtract orig_x to get cell_list->x into the same coord
- * space as width.
- */
- if (col_cnt == (cols - 1))
- {
- cell_list->width = width - (cell_list->x - orig_x);
- }
-
- cell_list->height = height * cell_list->height_percent / 100;
- if (cell_list->height < grid->grid_cell_min_dim)
- {
- cell_list->height = grid->grid_cell_min_dim;
- }
- if (row_cnt > 0)
- {
- cell_list->height -= grid->grid_cell_border;
- }
- if (row_cnt < (rows - 1))
- {
- cell_list->height -= grid->grid_cell_border;
- }
-
- /*
- * Make sure the last row uses all the remaining space.
- * We subtract orig_y to get cell_list->y into the same coord
- * space as height.
- */
- if (row_cnt == (rows - 1))
- {
- cell_list->height = height - (cell_list->y - orig_y);
- }
-
- /*
- * If this is the first column, for any row but the
- * last row, create a new edge to be the bottom of this
- * row.
- */
- if ((col_cnt == 0)&&(row_cnt < (rows - 1)))
- {
- tmp_edge = lo_new_horizontal_edge(context, state,
- cols, x, (cell_list->y + cell_list->height),
- width, (2 * grid->grid_cell_border));
- if (tmp_edge != NULL)
- {
- tmp_edge->next = grid->edge_list;
- grid->edge_list = tmp_edge;
- }
- }
-
- /*
- * When in the first row, create a new side edge on
- * each column but the last one.
- */
- if ((row_cnt == 0)&&(col_cnt < (cols - 1)))
- {
- lo_GridEdge *v_edge;
-
- v_edge = lo_new_vertical_edge(context, state,
- rows, (cell_list->x + cell_list->width), y,
- (2 * grid->grid_cell_border), height);
- if (v_edge != NULL)
- {
- v_edge->next = grid->edge_list;
- grid->edge_list = v_edge;
- }
- col_edges[col_cnt] = v_edge;
- }
-
- /*
- * If this is the first column in the row, we need to
- * set top and bottom edges, for later columns in
- * the same row, they remain unchanged.
- */
- if (col_cnt == 0)
- {
- new_edges[TOP_EDGE] = top_edge;
- if (row_cnt == 0)
- {
- new_edges[TOP_EDGE] = edges[TOP_EDGE];
- }
- new_edges[BOTTOM_EDGE] = tmp_edge;
- if (row_cnt == (rows - 1))
- {
- new_edges[BOTTOM_EDGE] = edges[BOTTOM_EDGE];
- }
- /*
- * Set top_edge for next time around.
- */
- top_edge = tmp_edge;
- }
-
- /*
- * Set the left and right edges for this column.
- */
- if (col_cnt == 0)
- {
- new_edges[LEFT_EDGE] = edges[LEFT_EDGE];
- }
- else
- {
- new_edges[LEFT_EDGE] = col_edges[(col_cnt - 1)];
- }
- if (col_cnt == (cols - 1))
- {
- new_edges[RIGHT_EDGE] = edges[RIGHT_EDGE];
- }
- else
- {
- new_edges[RIGHT_EDGE] = col_edges[col_cnt];
- }
-
- x += cell_list->width;
- if (col_cnt > 0)
- {
- x += grid->grid_cell_border;
- }
- if (col_cnt < (cols - 1))
- {
- x += grid->grid_cell_border;
- }
- col_cnt++;
- if (col_cnt >= cols)
- {
- x = orig_x;
- y += cell_list->height;
- if (row_cnt > 0)
- {
- y += grid->grid_cell_border;
- }
- if (row_cnt < (rows - 1))
- {
- y += grid->grid_cell_border;
- }
- col_cnt = 0;
- row_cnt++;
- }
-
- if (cell_list->subgrid != NULL)
- {
- lo_GridRec *subgrid;
- lo_GridCellRec *dummy_cell;
-
- subgrid = cell_list->subgrid;
- dummy_cell = cell_list;
-
- subgrid->grid_cell_border = grid->grid_cell_border;
- subgrid->grid_cell_min_dim = grid->grid_cell_min_dim;
-
- /*
- * Make sure all the row percentages total up
- * to 100%
- */
- lo_adjust_percents(subgrid->rows, subgrid->row_percents,
- cell_list->height);
-
- /*
- * Make sure all the col percentages total up
- * to 100%
- */
- lo_adjust_percents(subgrid->cols, subgrid->col_percents,
- cell_list->width);
-
- lo_LayoutGridCells(context, state,
- cell_list->x, cell_list->y,
- cell_list->width, cell_list->height,
- subgrid, new_edges);
-
- /*
- * Merge the edge list of the sub-grid with that of
- * the parent grid.
- */
- if (subgrid->edge_list != NULL)
- {
- lo_GridEdge *a_edge;
-
- a_edge = subgrid->edge_list;
- while (a_edge->next != NULL)
- {
- a_edge = a_edge->next;
- }
- a_edge->next = grid->edge_list;
- grid->edge_list = subgrid->edge_list;
- subgrid->edge_list = NULL;
- }
-
- /*
- * Replace the subgrid cell in the list with its
- * own list of member cells.
- */
- /*
- * If the cell to be replace is not the head of the
- * list.
- */
- if (cell_parent != NULL)
- {
- /*
- * If the cell is being replaced with a list
- * of one or more cells.
- */
- if (subgrid->cell_list != NULL)
- {
- cell_parent->next = subgrid->cell_list;
- subgrid->cell_list_last->next = cell_list->next;
- /*
- * If the cell being replaced was the end of
- * the list, set the new end properly.
- */
- if (grid->cell_list_last == cell_list)
- {
- grid->cell_list_last =
- subgrid->cell_list_last;
- }
- cell_parent = subgrid->cell_list_last;
- cell_list = cell_list->next;
- }
- /*
- * If the cell is being replaced with
- * no cells (just remove it.)
- */
- else
- {
- cell_parent->next = cell_list->next;
- /*
- * If the cell being replaced was the end of
- * the list, set the new end properly.
- */
- if (grid->cell_list_last == cell_list)
- {
- grid->cell_list_last = cell_parent;
- }
- cell_parent = cell_parent;
- cell_list = cell_list->next;
- }
- }
- /*
- * Else we are replacing the head of the list.
- */
- else
- {
- /*
- * If the cell is being replaced with a list
- * of one or more cells.
- */
- if (subgrid->cell_list != NULL)
- {
- grid->cell_list = subgrid->cell_list;
- subgrid->cell_list_last->next = cell_list->next;
- /*
- * If the cell being replaced was the end of
- * the list, set the new end properly.
- */
- if (grid->cell_list_last == cell_list)
- {
- grid->cell_list_last =
- subgrid->cell_list_last;
- }
- cell_parent = subgrid->cell_list_last;
- cell_list = cell_list->next;
- }
- /*
- * If the cell is being replaced with
- * no cells (just remove it.)
- */
- else
- {
- grid->cell_list = cell_list->next;
- /*
- * If the cell being replaced was the end of
- * the list, set the new end properly.
- */
- if (grid->cell_list_last == cell_list)
- {
- grid->cell_list_last = cell_list->next;
- }
- cell_parent = cell_parent;
- cell_list = cell_list->next;
- }
- }
-
- lo_FreeGridRec(subgrid);
- lo_FreeGridCellRec(context, grid, dummy_cell);
- }
- /*
- * Else this was a normal cell.
- */
- else
- {
- /*
- * Add this cell to the cell array for each edge
- * it borders.
- */
- if (new_edges[TOP_EDGE] != NULL)
- {
- lo_add_cell_to_edge(new_edges[TOP_EDGE],
- cell_list);
- }
- if (new_edges[BOTTOM_EDGE] != NULL)
- {
- lo_add_cell_to_edge(new_edges[BOTTOM_EDGE],
- cell_list);
- }
- if (new_edges[LEFT_EDGE] != NULL)
- {
- lo_add_cell_to_edge(new_edges[LEFT_EDGE],
- cell_list);
- }
- if (new_edges[RIGHT_EDGE] != NULL)
- {
- lo_add_cell_to_edge(new_edges[RIGHT_EDGE],
- cell_list);
- }
-
- cell_list->side_edges[TOP_EDGE] =
- new_edges[TOP_EDGE];
- cell_list->side_edges[BOTTOM_EDGE] =
- new_edges[BOTTOM_EDGE];
- cell_list->side_edges[LEFT_EDGE] =
- new_edges[LEFT_EDGE];
- cell_list->side_edges[RIGHT_EDGE] =
- new_edges[RIGHT_EDGE];
-
- cell_parent = cell_list;
- cell_list = cell_list->next;
- }
-
- }
-
- if (col_edges != NULL)
- {
- XP_FREE(col_edges);
- }
- }
-
- static void
- lo_set_edge_bounds(lo_GridEdge *edge)
- {
- int32 i;
- int32 min, max;
- Bool visible;
- Bool movable;
- int16 size;
- int8 color_priority;
- LO_Color *bg_color;
-
- if (edge == NULL)
- {
- return;
- }
-
- visible = FALSE;
- movable = TRUE;
- size = -1;
- color_priority = 0;
- bg_color = NULL;
-
- min = -1;
- max = -1;
- /*
- * For horizontal edges
- */
- if (edge->is_vertical == FALSE)
- {
- for (i=0; i < edge->cell_cnt; i++)
- {
- lo_GridCellRec *cell;
-
- cell = edge->cell_array[i];
- if (cell == NULL)
- {
- continue;
- }
-
- /*
- * If a cell on this edge is not resizable,
- * this edge is not movable.
- */
- if (cell->resizable == FALSE)
- {
- movable = FALSE;
- }
-
- /*
- * If a cell on this edge has visible edges,
- * this edge is visible.
- */
- if (cell->no_edges == FALSE)
- {
- visible = TRUE;
- }
-
- /*
- * A cell's size is the max of the edge_size
- * of all cells next to it.
- */
- if (cell->edge_size > size)
- {
- size = cell->edge_size;
- }
-
- /*
- * A cell sets a color on an edge that doesn't
- * already have a color, or has a lower
- * priority, it wins.
- */
- if ((cell->border_color != NULL)&&
- ((bg_color == NULL)||
- (cell->color_priority > color_priority)))
- {
- bg_color = XP_NEW(LO_Color);
- if (bg_color != NULL)
- {
- bg_color->red = cell->border_color->red;
- bg_color->green = cell->border_color->green;
- bg_color->blue = cell->border_color->blue;
- color_priority = cell->color_priority;
- }
- }
-
- /*
- * If the cell is above the edge.
- */
- if (cell->y < edge->y)
- {
- if ((cell->y > min)||(min == -1))
- {
- min = cell->y;
- }
- }
- /*
- * Else the cell is below the edge.
- */
- else
- {
- int32 bottom;
-
- bottom = cell->y + cell->height - 1;
- if ((bottom < max)||(max == -1))
- {
- max = bottom;
- }
- }
- }
-
- /*
- * Make min and max be the inclusive bounds through
- * which edge->y can move.
- * We should never move an edge so that cell->y
- * becomes equal to edge->y or else in the future we
- * will thing that cell is on the wrong side of the
- * edge. To prevent this, it min is set by a cell's
- * bounds, we increment it by one.
- */
- if (min == -1)
- {
- min = edge->y;
- }
- else
- {
- min = min + 1;
- }
- if (max == -1)
- {
- max = edge->y + edge->height - 1;
- }
- else
- {
- max = max - edge->height + 1;
- }
- /*
- * Sanity check bounds
- */
- if (max < min)
- {
- max = min;
- }
- edge->left_top_bound = min;
- edge->right_bottom_bound = max;
- }
- /*
- * Else for vertical edges.
- */
- else
- {
- for (i=0; i < edge->cell_cnt; i++)
- {
- lo_GridCellRec *cell;
-
- cell = edge->cell_array[i];
- if (cell == NULL)
- {
- continue;
- }
-
- /*
- * If a cell on this edge is not resizable,
- * this edge is not movable.
- */
- if (cell->resizable == FALSE)
- {
- movable = FALSE;
- }
-
- /*
- * If a cell on this edge has visible edges,
- * this edge is visible.
- */
- if (cell->no_edges == FALSE)
- {
- visible = TRUE;
- }
-
- /*
- * A cells size is the max of the edge_size
- * of all cells next to it.
- */
- if (cell->edge_size > size)
- {
- size = cell->edge_size;
- }
-
- /*
- * A cell sets a color on an edge that doesn't
- * already have a color, or has a lower
- * priority, it wins.
- */
- if ((cell->border_color != NULL)&&
- ((bg_color == NULL)||
- (cell->color_priority > color_priority)))
- {
- bg_color = XP_NEW(LO_Color);
- if (bg_color != NULL)
- {
- bg_color->red = cell->border_color->red;
- bg_color->green = cell->border_color->green;
- bg_color->blue = cell->border_color->blue;
- color_priority = cell->color_priority;
- }
- }
-
- /*
- * If the cell is left of the edge.
- */
- if (cell->x < edge->x)
- {
- if ((cell->x > min)||(min == -1))
- {
- min = cell->x;
- }
- }
- /*
- * Else the cell is right of the edge.
- */
- else
- {
- int32 right;
-
- right = cell->x + cell->width - 1;
- if ((right < max)||(max == -1))
- {
- max = right;
- }
- }
- }
-
- /*
- * Make min and max be the inclusive bounds through
- * which edge->x can move.
- * We should never move an edge so that cell->x
- * becomes equal to edge->x or else in the future we
- * will thing that cell is on the wrong side of the
- * edge. To prevent this, it min is set by a cell's
- * bounds, we increment it by one.
- */
- if (min == -1)
- {
- min = edge->x;
- }
- else
- {
- min = min + 1;
- }
- if (max == -1)
- {
- max = edge->x + edge->width - 1;
- }
- else
- {
- max = max - edge->width + 1;
- }
- /*
- * Sanity check bounds
- */
- if (max < min)
- {
- max = min;
- }
- edge->left_top_bound = min;
- edge->right_bottom_bound = max;
- }
-
- edge->fe_edge->left_top_bound = edge->left_top_bound;
- edge->fe_edge->right_bottom_bound = edge->right_bottom_bound;
- edge->fe_edge->visible = visible;
- edge->fe_edge->movable = movable;
- edge->fe_edge->size = size;
- edge->fe_edge->bg_color = bg_color;
- }
-
-
- static void
- lo_set_all_edge_bounds(MWContext *context, lo_DocState *state, lo_GridRec *grid)
- {
- lo_GridEdge *edge_list;
-
- if ((grid == NULL)||(grid->edge_list == NULL))
- {
- return;
- }
-
- edge_list = grid->edge_list;
- while (edge_list != NULL)
- {
- lo_set_edge_bounds(edge_list);
-
- /*
- * Insert this edge into the float list.
- */
- edge_list->fe_edge->next = state->float_list;
- state->float_list = (LO_Element *)edge_list->fe_edge;
-
- lo_DisplayEdge(context, edge_list->fe_edge);
- edge_list = edge_list->next;
- }
- }
-
-
- /*
- * Use the cell's history index to reload the document
- * it should now be currently displaying.
- * (Note, history index starts at 1, and array starts at 0).
- */
- static void
- lo_reload_cell_from_history(lo_GridCellRec *cell_ptr,
- NET_ReloadMethod force_reload)
- {
- void *hist;
-
- hist = cell_ptr->hist_array[cell_ptr->hist_indx - 1].hist;
-
- /*
- * If we have a history entry, and a context to load
- * it into, have the FE load it now.
- */
- if ((hist != NULL)&&(cell_ptr->context != NULL))
- {
- FE_LoadGridCellFromHistory(cell_ptr->context, hist,
- force_reload);
- }
- }
-
-
- static lo_GridCellRec *reconnecting_cell = NULL;
-
-
- PRIVATE
- void
- lo_MakeGrid(MWContext *context, lo_DocState *state, lo_GridRec *grid)
- {
- int32 x, y;
- int32 edge_size;
- int32 width, height;
- lo_GridCellRec *cell_ptr;
- lo_GridEdge *edges[4]; /* top, bottom, left, right */
-
- width = state->win_width;
- height = state->win_height;
- FE_GetFullWindowSize(context, &width, &height);
-
- if (width <= 0)
- width = 1;
-
- if (height <= 0)
- height = 1;
-
- grid->main_width = width;
- grid->main_height = height;
-
- #ifdef NO_FRAMESET_BORDER
- edge_size = 1;
- FE_GetEdgeMinSize(context, &edge_size);
- if (edge_size < 1)
- {
- edge_size = 1;
- }
- #else
- if (grid->edge_size < 0)
- {
- edge_size = 1;
- FE_GetEdgeMinSize(context, &edge_size
- #if defined(XP_WIN) || defined(XP_OS2)
- /* need this information here under windows */
- , grid->no_edges
- #endif
- );
- }
- else
- {
- edge_size = grid->edge_size;
- }
- if (edge_size < 0)
- {
- edge_size = 0;
- }
- #endif /* NO_FRAMESET_BORDER */
- grid->grid_cell_border = (edge_size + 1) / 2;
- grid->grid_cell_min_dim = (2 * grid->grid_cell_border) + 1;
-
- x = 0;
- y = 0;
-
- /*
- * Make sure all the row percentages total up
- * to 100%
- */
- lo_adjust_percents(grid->rows, grid->row_percents, height);
-
- /*
- * Make sure all the col percentages total up
- * to 100%
- */
- lo_adjust_percents(grid->cols, grid->col_percents, width);
-
- edges[TOP_EDGE] = NULL;
- edges[BOTTOM_EDGE] = NULL;
- edges[LEFT_EDGE] = NULL;
- edges[RIGHT_EDGE] = NULL;
- lo_LayoutGridCells(context, state, x, y, width, height, grid, edges);
- lo_set_all_edge_bounds(context, state, grid);
-
- /*
- * If there is an old_grid in the top_state, that means we restored
- * from history with the sizes changed. Go through that old_grid
- * now, and put those urls back into the cells, then free the old_grid.
- */
- if (state->top_state->old_grid != NULL)
- {
- lo_GridRec *old_grid;
- lo_GridCellRec *old_cell_ptr;
- lo_SavedGridData tmp_saved_grid;
-
- old_grid = state->top_state->old_grid;
- grid->current_hist = old_grid->current_hist;
- grid->max_hist = old_grid->max_hist;
- grid->hist_size = old_grid->hist_size;
- old_cell_ptr = old_grid->cell_list;
- cell_ptr = grid->cell_list;
- while ((cell_ptr != NULL)&&(old_cell_ptr != NULL))
- {
- /*
- * Free any initial URL loaded, and move the old
- * url in place. Make sure to clear the old URL
- * so we don't accidentally free it later.
- */
- if (cell_ptr->url != NULL)
- {
- XP_FREE(cell_ptr->url);
- cell_ptr->url = NULL;
- }
- cell_ptr->url = old_cell_ptr->url;
- old_cell_ptr->url = NULL;
-
- /*
- * Also copy over the old history.
- */
- cell_ptr->hist_indx = old_cell_ptr->hist_indx;
- cell_ptr->hist_array = old_cell_ptr->hist_array;
- old_cell_ptr->hist_array = NULL;
- cell_ptr->hist_list = old_cell_ptr->hist_list;
- old_cell_ptr->hist_list = NULL;
-
- cell_ptr = cell_ptr->next;
- old_cell_ptr = old_cell_ptr->next;
- }
-
- /*
- * Free up the old saved grid.
- */
- tmp_saved_grid.main_width = 0;
- tmp_saved_grid.main_height = 0;
- tmp_saved_grid.the_grid = state->top_state->old_grid;
- state->top_state->old_grid = NULL;
- lo_FreeDocumentGridData(context, &tmp_saved_grid);
- }
-
- /*
- * Go through all the cells creating them where specified.
- */
- cell_ptr = grid->cell_list;
- while (cell_ptr != NULL)
- {
- /*
- * Have the front end create the grid cell.
- */
- if (cell_ptr->url != NULL)
- {
- void *history;
- void *hist_list;
-
- history = NULL;
- hist_list = NULL;
- if (cell_ptr->hist_list != NULL)
- {
- hist_list = cell_ptr->hist_list;
- cell_ptr->hist_indx = grid->current_hist;
- history = cell_ptr->hist_array[cell_ptr->hist_indx - 1].hist;
- if (history == NULL)
- {
- hist_list = NULL;
- }
- }
- reconnecting_cell = cell_ptr;
- cell_ptr->context = FE_MakeGridWindow (context,
- hist_list,
- history,
- cell_ptr->x, cell_ptr->y,
- cell_ptr->width, cell_ptr->height,
- (char *)cell_ptr->url, (char *)cell_ptr->name,
- cell_ptr->scrolling,
- FORCE_RELOAD_FLAG(state->top_state),
- cell_ptr->no_edges);
- reconnecting_cell = NULL;
- if (cell_ptr->context)
- {
- XP_ASSERT(cell_ptr->context->forceJSEnabled ==
- context->forceJSEnabled);
- if (history)
- {
- cell_ptr->context->hist.cur_doc_ptr = history;
- }
- }
- }
- else
- {
- cell_ptr->context = NULL;
- }
- cell_ptr = cell_ptr->next;
- }
- }
-
-
-
- void
- lo_BeginGrid(MWContext *context, lo_DocState *state, PA_Tag *tag)
- {
- PA_Block buff;
- char *str;
- int32 rows, cols;
- lo_GridPercent *row_percents;
- lo_GridPercent *col_percents;
- lo_GridRec *grid;
-
- rows = 1;
- cols = 1;
-
- grid = XP_NEW(lo_GridRec);
- if (grid == NULL)
- {
- state->top_state->out_of_memory = TRUE;
- return;
- }
-
- grid->no_edges = FALSE;
- grid->edge_size = -1;
- grid->color_priority = 0;
- grid->border_color = NULL;
- grid->edge_list = NULL;
- grid->cell_list = NULL;
- grid->cell_list_last = NULL;
- grid->subgrid = NULL;
-
- buff = lo_FetchParamValue(context, tag, PARAM_FRAMEBORDER);
- if (buff != NULL)
- {
- Bool no_edges;
-
- no_edges = FALSE;
- PA_LOCK(str, char *, buff);
- if (pa_TagEqual("no", str))
- {
- no_edges = TRUE;
- }
- else if (pa_TagEqual("0", str))
- {
- no_edges = TRUE;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- grid->no_edges = no_edges;
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_BORDER);
- if (buff != NULL)
- {
- int32 border;
-
- PA_LOCK(str, char *, buff);
- border = XP_ATOI(str);
- PA_UNLOCK(buff);
- PA_FREE(buff);
- if (border < 0)
- {
- border = 0;
- }
- if (border > 100)
- {
- border = 100;
- }
- grid->edge_size = (int16)border;
- }
-
- /*
- * A borderwidth of zero automatically turns off edges.
- */
- if (grid->edge_size == 0)
- {
- grid->no_edges = TRUE;
- }
-
- /*
- * Check for a border color attribute
- */
- buff = lo_FetchParamValue(context, tag, PARAM_BORDERCOLOR);
- if (buff != NULL)
- {
- uint8 red, green, blue;
-
- PA_LOCK(str, char *, buff);
- LO_ParseRGB(str, &red, &green, &blue);
- PA_UNLOCK(buff);
- PA_FREE(buff);
- grid->border_color = XP_NEW(LO_Color);
- if (grid->border_color != NULL)
- {
- grid->border_color->red = red;
- grid->border_color->green = green;
- grid->border_color->blue = blue;
- grid->color_priority = 1;
- }
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_ROWS);
- if (buff != NULL)
- {
- int32 len;
-
- PA_LOCK(str, char *, buff);
- len = lo_StripTextWhitespace(str, XP_STRLEN(str));
- row_percents = lo_parse_percent_list(context, str, &rows);
- if ((row_percents == NULL)&&(rows >= 1))
- {
- PA_UNLOCK(buff);
- PA_FREE(buff);
- XP_DELETE(grid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- if (rows <= 0)
- {
- row_percents = (lo_GridPercent *)
- XP_ALLOC(sizeof(lo_GridPercent));
- if (row_percents == NULL)
- {
- XP_DELETE(grid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- row_percents[0].type = LO_PERCENT_NORMAL;
- row_percents[0].original_value = 100;
- rows = 1;
- }
- }
- else
- {
- row_percents = (lo_GridPercent *)
- XP_ALLOC(sizeof(lo_GridPercent));
- if (row_percents == NULL)
- {
- XP_DELETE(grid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- row_percents[0].type = LO_PERCENT_NORMAL;
- row_percents[0].original_value = 100;
- rows = 1;
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_COLS);
- if (buff != NULL)
- {
- int32 len;
-
- PA_LOCK(str, char *, buff);
- len = lo_StripTextWhitespace(str, XP_STRLEN(str));
- col_percents = lo_parse_percent_list(context, str, &cols);
- if ((col_percents == NULL)&&(cols >= 1))
- {
- PA_UNLOCK(buff);
- PA_FREE(buff);
- if (row_percents != NULL)
- {
- XP_FREE(row_percents);
- }
- XP_DELETE(grid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- if (cols <= 0)
- {
- col_percents = (lo_GridPercent *)
- XP_ALLOC(sizeof(lo_GridPercent));
- if (col_percents == NULL)
- {
- if (row_percents != NULL)
- {
- XP_FREE(row_percents);
- }
- XP_DELETE(grid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- col_percents[0].type = LO_PERCENT_NORMAL;
- col_percents[0].original_value = 100;
- cols = 1;
- }
- }
- else
- {
- col_percents = (lo_GridPercent *)
- XP_ALLOC(sizeof(lo_GridPercent));
- if (col_percents == NULL)
- {
- if (row_percents != NULL)
- {
- XP_FREE(row_percents);
- }
- XP_DELETE(grid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- col_percents[0].type = LO_PERCENT_NORMAL;
- col_percents[0].original_value = 100;
- cols = 1;
- }
-
- if ((rows == 1)&&(cols == 1))
- {
- if (row_percents != NULL)
- {
- XP_FREE(row_percents);
- }
- if (col_percents != NULL)
- {
- XP_FREE(col_percents);
- }
- XP_DELETE(grid);
- return;
- }
-
- #ifdef MOCHA
- (void)lo_ProcessContextEventHandlers(context, state, tag);
- #endif
-
- grid->rows = rows;
- grid->row_percents = row_percents;
- grid->cols = cols;
- grid->col_percents = col_percents;
- grid->cell_count = 0;
-
- grid->current_hist = 0;
- grid->max_hist = 0;
- grid->hist_size = 10;
-
- grid->main_width = state->win_width;
- grid->main_height = state->win_height;
- grid->current_cell_margin_width = 0;
- grid->current_cell_margin_height = 0;
-
- state->current_grid = grid;
- }
-
-
- void
- lo_EndGrid(MWContext *context, lo_DocState *state, lo_GridRec *grid)
- {
- int32 cell_cnt;
-
- if (grid == NULL)
- {
- return;
- }
-
- cell_cnt = grid->rows * grid->cols;
-
- state->top_state->the_grid = grid;
-
- lo_MakeGrid(context, state, grid);
- }
-
-
- static Bool
- lo_is_grid_recursion(MWContext *context, lo_DocState *state, char *url)
- {
- MWContext *cptr;
-
- /*
- * If this cell has its parent's URL, it is recursion.
- */
- if ((state->top_state->url != NULL)&&
- (XP_STRCMP(url, state->top_state->url) == 0))
- {
- return(TRUE);
- }
-
- cptr = context->grid_parent;
- while (cptr != NULL)
- {
- int32 doc_id;
- lo_TopState *top_state;
- char *anc_url;
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(cptr);
- top_state = lo_FetchTopState(doc_id);
- /*
- * We have to get the ancenstor URL from the state because
- * context->url doesn't seem to be reliable.
- */
- if (top_state == NULL)
- {
- anc_url = NULL;
- }
- else
- {
- anc_url = top_state->url;
- }
-
- /*
- * if this cell has the same URL as any of its ancestors
- * this is recursion.
- */
- if ((anc_url != NULL)&&(XP_STRCMP(url, anc_url) == 0))
- {
- return(TRUE);
- }
- cptr = cptr->grid_parent;
- }
- return(FALSE);
- }
-
-
- void
- lo_BeginGridCell(MWContext *context, lo_DocState *state, PA_Tag *tag)
- {
- PA_Block buff;
- char *str;
- lo_GridRec *grid;
- int32 col_cnt, row_cnt;
- lo_GridCellRec *cell;
-
- /*
- * Get the current grid, if there is none, error out.
- */
- grid = state->current_grid;
- if (grid == NULL)
- {
- return;
- }
-
- /*
- * If we have subgrids, the deepest one is at the TOP of the
- * subgrid stack.
- */
- if (grid->subgrid != NULL)
- {
- grid = grid->subgrid;
- }
-
- /*
- * If this grid has its full complement of cells, ignore
- * this cell.
- */
- if (grid->cell_count >= (grid->rows * grid->cols))
- {
- return;
- }
-
- cell = XP_NEW(lo_GridCellRec);
- if (cell == NULL)
- {
- state->top_state->out_of_memory = TRUE;
- return;
- }
-
- row_cnt = grid->cell_count / grid->cols;
- col_cnt = grid->cell_count - (row_cnt * grid->cols);
-
- cell->x = 0;
- cell->y = 0;
- cell->width = 0;
- cell->height = 0;
- cell->margin_width = 0;
- cell->margin_height = 0;
- cell->width_percent = 0;
- cell->height_percent = 0;
- cell->url = NULL;
- cell->name = NULL;
- cell->context = NULL;
- cell->hist_list = NULL;
- cell->hist_array = (lo_GridHistory *)XP_ALLOC(grid->hist_size *
- sizeof(lo_GridHistory));
- if (cell->hist_array == NULL)
- {
- XP_DELETE(cell);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- XP_MEMSET(cell->hist_array, 0, grid->hist_size *
- sizeof(lo_GridHistory));
- cell->hist_indx = 0;
- cell->next = NULL;
- cell->subgrid = NULL;
- cell->side_edges[TOP_EDGE] = NULL;
- cell->side_edges[BOTTOM_EDGE] = NULL;
- cell->side_edges[LEFT_EDGE] = NULL;
- cell->side_edges[RIGHT_EDGE] = NULL;
- cell->scrolling = LO_SCROLL_AUTO;
- cell->no_edges = grid->no_edges;
- cell->resizable = TRUE;
- cell->edge_size = -1;
- cell->color_priority = 0;
- cell->border_color = NULL;
-
- buff = lo_FetchParamValue(context, tag, PARAM_FRAMEBORDER);
- if (buff != NULL)
- {
- Bool no_edges;
-
- no_edges = FALSE;
- PA_LOCK(str, char *, buff);
- if (pa_TagEqual("no", str))
- {
- no_edges = TRUE;
- }
- else if (pa_TagEqual("0", str))
- {
- no_edges = TRUE;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- cell->no_edges = no_edges;
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_BORDER);
- if (buff != NULL)
- {
- int32 border;
-
- PA_LOCK(str, char *, buff);
- border = XP_ATOI(str);
- PA_UNLOCK(buff);
- PA_FREE(buff);
- if (border < 0)
- {
- border = 0;
- }
- if (border > 100)
- {
- border = 100;
- }
- cell->edge_size = (int16)border;
- }
-
- /*
- * A borderwidth of zero automatically turns off edges.
- */
- if (cell->edge_size == 0)
- {
- cell->no_edges = TRUE;
- }
-
- /*
- * Check for a border color attribute
- */
- buff = lo_FetchParamValue(context, tag, PARAM_BORDERCOLOR);
- if (buff != NULL)
- {
- uint8 red, green, blue;
-
- PA_LOCK(str, char *, buff);
- LO_ParseRGB(str, &red, &green, &blue);
- PA_UNLOCK(buff);
- PA_FREE(buff);
- cell->border_color = XP_NEW(LO_Color);
- if (cell->border_color != NULL)
- {
- cell->border_color->red = red;
- cell->border_color->green = green;
- cell->border_color->blue = blue;
- cell->color_priority = 3;
- }
- }
- /*
- * Else we might inherit a border color from parent.
- */
- else if (grid->border_color != NULL)
- {
- cell->border_color = XP_NEW(LO_Color);
- if (cell->border_color != NULL)
- {
- cell->border_color->red = grid->border_color->red;
- cell->border_color->green = grid->border_color->green;
- cell->border_color->blue = grid->border_color->blue;
- cell->color_priority = grid->color_priority;
- }
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_NORESIZE);
- if (buff != NULL)
- {
- PA_FREE(buff);
- cell->resizable = FALSE;
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_SCROLLING);
- if (buff != NULL)
- {
- int8 scrolling;
-
- scrolling = LO_SCROLL_AUTO;
- PA_LOCK(str, char *, buff);
- if (pa_TagEqual("yes", str))
- {
- scrolling = LO_SCROLL_YES;
- }
- else if (pa_TagEqual("scroll", str))
- {
- scrolling = LO_SCROLL_YES;
- }
- else if (pa_TagEqual("no", str))
- {
- scrolling = LO_SCROLL_NO;
- }
- else if (pa_TagEqual("noscroll", str))
- {
- scrolling = LO_SCROLL_NO;
- }
- else if (pa_TagEqual("on", str))
- {
- scrolling = LO_SCROLL_YES;
- }
- else if (pa_TagEqual("off", str))
- {
- scrolling = LO_SCROLL_NO;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- cell->scrolling = scrolling;
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_SRC);
- if (buff != NULL)
- {
- char *new_str;
-
- PA_LOCK(str, char *, buff);
- if (str != NULL)
- {
- int32 len;
-
- len = lo_StripTextWhitespace(str, XP_STRLEN(str));
- }
- new_str = NET_MakeAbsoluteURL(state->top_state->base_url, str);
-
- PA_UNLOCK(buff);
- PA_FREE(buff);
- cell->url = new_str;
- /*
- * Don't allow cells to have the same URL as their parent
- * or any of their ancestors as that would cause infinite
- * recursion.
- */
- if (lo_is_grid_recursion(context, state, cell->url) != FALSE)
- {
- XP_FREE(new_str);
- cell->url = NULL;
- }
- }
- else
- {
- cell->url = NULL;
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_NAME);
- if (buff != NULL)
- {
- char *name;
-
- PA_LOCK(str, char *, buff);
- if (str != NULL)
- {
- int32 len;
-
- len = lo_StripTextWhitespace(str, XP_STRLEN(str));
- }
- name = (char *)XP_ALLOC(XP_STRLEN(str) + 1);
- if (name == NULL)
- {
- cell->name = NULL;
- }
- else
- {
- XP_STRCPY(name, str);
- cell->name = name;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- }
- else
- {
- cell->name = NULL;
- }
-
- /*
- * Get the margin width.
- */
- buff = lo_FetchParamValue(context, tag, PARAM_MARGINWIDTH);
- if (buff != NULL)
- {
- int32 val;
-
- PA_LOCK(str, char *, buff);
- val = XP_ATOI(str);
- if (val < 1)
- {
- val = 1;
- }
- cell->margin_width = val;
- PA_UNLOCK(buff);
- PA_FREE(buff);
- }
- cell->margin_width = FEUNITS_X(cell->margin_width, context);
-
- /*
- * Get the margin height.
- */
- buff = lo_FetchParamValue(context, tag, PARAM_MARGINHEIGHT);
- if (buff != NULL)
- {
- int32 val;
-
- PA_LOCK(str, char *, buff);
- val = XP_ATOI(str);
- if (val < 1)
- {
- val = 1;
- }
- cell->margin_height = val;
- PA_UNLOCK(buff);
- PA_FREE(buff);
- }
- cell->margin_height = FEUNITS_Y(cell->margin_height, context);
-
- grid->cell_count++;
-
- if (grid->cell_list_last == NULL)
- {
- grid->cell_list = cell;
- grid->cell_list_last = cell;
- }
- else
- {
- grid->cell_list_last->next = cell;
- grid->cell_list_last = cell;
- }
- }
-
-
- void
- lo_BeginSubgrid(MWContext *context, lo_DocState *state, PA_Tag *tag)
- {
- PA_Block buff;
- char *str;
- lo_GridRec *grid;
- int32 col_cnt, row_cnt;
- lo_GridRec *subgrid;
- int32 rows, cols;
- lo_GridPercent *row_percents;
- lo_GridPercent *col_percents;
- lo_GridCellRec *cell;
-
- /*
- * Get the current grid, if there is none, error out.
- */
- grid = state->current_grid;
- if (grid == NULL)
- {
- return;
- }
-
- /*
- * If we have subgrids, the deepest one is at the TOP of the
- * subgrid stack.
- */
- if (grid->subgrid != NULL)
- {
- grid = grid->subgrid;
- }
-
- /*
- * If this grid has its full complement of cells, ignore
- * this subgrid cell.
- */
- if (grid->cell_count >= (grid->rows * grid->cols))
- {
- return;
- }
-
-
- /*
- ********************************
- * Create and parse the subgrid *
- ********************************
- */
- rows = 1;
- cols = 1;
-
- subgrid = XP_NEW(lo_GridRec);
- if (subgrid == NULL)
- {
- state->top_state->out_of_memory = TRUE;
- return;
- }
-
- subgrid->no_edges = grid->no_edges;
- subgrid->edge_size = grid->edge_size;
- subgrid->color_priority = 0;
- subgrid->border_color = NULL;
- subgrid->edge_list = NULL;
- subgrid->cell_list = NULL;
- subgrid->cell_list_last = NULL;
- subgrid->subgrid = NULL;
-
- /*
- * Check for a border color attribute
- */
- buff = lo_FetchParamValue(context, tag, PARAM_BORDERCOLOR);
- if (buff != NULL)
- {
- uint8 red, green, blue;
-
- PA_LOCK(str, char *, buff);
- LO_ParseRGB(str, &red, &green, &blue);
- PA_UNLOCK(buff);
- PA_FREE(buff);
- subgrid->border_color = XP_NEW(LO_Color);
- if (subgrid->border_color != NULL)
- {
- subgrid->border_color->red = red;
- subgrid->border_color->green = green;
- subgrid->border_color->blue = blue;
- subgrid->color_priority = 2;
- }
- }
- /*
- * Else we might inherit a border color from parent.
- */
- else if (grid->border_color != NULL)
- {
- subgrid->border_color = XP_NEW(LO_Color);
- if (subgrid->border_color != NULL)
- {
- subgrid->border_color->red = grid->border_color->red;
- subgrid->border_color->green = grid->border_color->green;
- subgrid->border_color->blue = grid->border_color->blue;
- subgrid->color_priority = grid->color_priority;
- }
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_FRAMEBORDER);
- if (buff != NULL)
- {
- Bool no_edges;
-
- no_edges = FALSE;
- PA_LOCK(str, char *, buff);
- if (pa_TagEqual("no", str))
- {
- no_edges = TRUE;
- }
- else if (pa_TagEqual("0", str))
- {
- no_edges = TRUE;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- subgrid->no_edges = no_edges;
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_ROWS);
- if (buff != NULL)
- {
- int32 len;
-
- PA_LOCK(str, char *, buff);
- len = lo_StripTextWhitespace(str, XP_STRLEN(str));
- row_percents = lo_parse_percent_list(context, str, &rows);
- if ((row_percents == NULL)&&(rows >= 1))
- {
- PA_UNLOCK(buff);
- PA_FREE(buff);
- XP_DELETE(subgrid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- if (rows <= 0)
- {
- row_percents = (lo_GridPercent *)
- XP_ALLOC(sizeof(lo_GridPercent));
- if (row_percents == NULL)
- {
- XP_DELETE(subgrid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- row_percents[0].type = LO_PERCENT_NORMAL;
- row_percents[0].original_value = 100;
- rows = 1;
- }
- }
- else
- {
- row_percents = (lo_GridPercent *)
- XP_ALLOC(sizeof(lo_GridPercent));
- if (row_percents == NULL)
- {
- XP_DELETE(subgrid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- row_percents[0].type = LO_PERCENT_NORMAL;
- row_percents[0].original_value = 100;
- rows = 1;
- }
-
- buff = lo_FetchParamValue(context, tag, PARAM_COLS);
- if (buff != NULL)
- {
- int32 len;
-
- PA_LOCK(str, char *, buff);
- len = lo_StripTextWhitespace(str, XP_STRLEN(str));
- col_percents = lo_parse_percent_list(context, str, &cols);
- if ((col_percents == NULL)&&(cols >= 1))
- {
- PA_UNLOCK(buff);
- PA_FREE(buff);
- if (row_percents != NULL)
- {
- XP_FREE(row_percents);
- }
- XP_DELETE(subgrid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- PA_UNLOCK(buff);
- PA_FREE(buff);
- if (cols <= 0)
- {
- col_percents = (lo_GridPercent *)
- XP_ALLOC(sizeof(lo_GridPercent));
- if (col_percents == NULL)
- {
- if (row_percents != NULL)
- {
- XP_FREE(row_percents);
- }
- XP_DELETE(subgrid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- col_percents[0].type = LO_PERCENT_NORMAL;
- col_percents[0].original_value = 100;
- cols = 1;
- }
- }
- else
- {
- col_percents = (lo_GridPercent *)
- XP_ALLOC(sizeof(lo_GridPercent));
- if (col_percents == NULL)
- {
- if (row_percents != NULL)
- {
- XP_FREE(row_percents);
- }
- XP_DELETE(subgrid);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- col_percents[0].type = LO_PERCENT_NORMAL;
- col_percents[0].original_value = 100;
- cols = 1;
- }
-
- if ((rows == 1)&&(cols == 1))
- {
- if (row_percents != NULL)
- {
- XP_FREE(row_percents);
- }
- if (col_percents != NULL)
- {
- XP_FREE(col_percents);
- }
- XP_DELETE(subgrid);
- return;
- }
-
- #ifdef MOCHA
- (void)lo_ProcessContextEventHandlers(context, state, tag);
- #endif
-
- subgrid->rows = rows;
- subgrid->row_percents = row_percents;
- subgrid->cols = cols;
- subgrid->col_percents = col_percents;
- subgrid->cell_count = 0;
-
- subgrid->current_hist = 0;
- subgrid->max_hist = 0;
- subgrid->hist_size = 10;
-
- subgrid->main_width = state->win_width;
- subgrid->main_height = state->win_height;
- subgrid->current_cell_margin_width = 0;
- subgrid->current_cell_margin_height = 0;
-
- subgrid->subgrid = state->current_grid->subgrid;
- state->current_grid->subgrid = subgrid;
-
- /*
- ******************************************
- * Subgrid parsing done. *
- * Create a dummy cell to hang it off of. *
- ******************************************
- */
-
- cell = XP_NEW(lo_GridCellRec);
- if (cell == NULL)
- {
- state->top_state->out_of_memory = TRUE;
- return;
- }
-
- row_cnt = grid->cell_count / grid->cols;
- col_cnt = grid->cell_count - (row_cnt * grid->cols);
-
- cell->x = 0;
- cell->y = 0;
- cell->width = 0;
- cell->height = 0;
- cell->margin_width = 0;
- cell->margin_height = 0;
- cell->width_percent = 0;
- cell->height_percent = 0;
- cell->url = NULL;
- cell->name = NULL;
- cell->context = NULL;
- cell->hist_list = NULL;
- cell->hist_array = (lo_GridHistory *)XP_ALLOC(grid->hist_size *
- sizeof(lo_GridHistory));
- if (cell->hist_array == NULL)
- {
- XP_DELETE(cell);
- state->top_state->out_of_memory = TRUE;
- return;
- }
- XP_MEMSET(cell->hist_array, 0, grid->hist_size *
- sizeof(lo_GridHistory));
- cell->hist_indx = 0;
- cell->next = NULL;
- cell->subgrid = subgrid;
- cell->side_edges[TOP_EDGE] = NULL;
- cell->side_edges[BOTTOM_EDGE] = NULL;
- cell->side_edges[LEFT_EDGE] = NULL;
- cell->side_edges[RIGHT_EDGE] = NULL;
- cell->scrolling = LO_SCROLL_AUTO;
- cell->no_edges = subgrid->no_edges;
- cell->resizable = TRUE;
- cell->edge_size = -1;
- cell->color_priority = 0;
- cell->border_color = NULL;
-
- grid->cell_count++;
-
- if (grid->cell_list_last == NULL)
- {
- grid->cell_list = cell;
- grid->cell_list_last = cell;
- }
- else
- {
- grid->cell_list_last->next = cell;
- grid->cell_list_last = cell;
- }
- }
-
-
- void
- lo_EndSubgrid(MWContext *context, lo_DocState *state, lo_GridRec *grid)
- {
- lo_GridRec *subgrid;
-
- if ((grid == NULL)||(grid->subgrid == NULL))
- {
- return;
- }
-
- subgrid = grid->subgrid;
- grid->subgrid = grid->subgrid->subgrid;
- subgrid->subgrid = NULL;
- }
-
-
- #ifdef DEBUG_EDGES
- static void
- lo_print_edge_info(lo_GridEdge *edge)
- {
- int32 i;
-
- fprintf(stderr, "\nEdge %ld,%ld %ldx%ld; Range is %ld to %ld\n",
- (long) edge->x, (long) edge->y, (long) edge->width,
- (long) edge->height, (long) edge->left_top_bound,
- (long) edge->right_bottom_bound);
- fprintf(stderr, "\tBounds %ld cells\n", (long) edge->cell_cnt);
- for (i=0; i < edge->cell_cnt; i++)
- {
- lo_GridCellRec *cell;
-
- cell = edge->cell_array[i];
- fprintf(stderr, "\t(%ld) %ld,%ld %ldx%ld\n",
- (long) i, (long) cell->x, (long) cell->y,
- (long) cell->width, (long) cell->height);
- }
- fprintf(stderr, "\n");
- }
- #endif /* DEBUG_EDGES */
-
-
- LO_Element *
- lo_XYToGridEdge(MWContext *context, lo_DocState *state, int32 x, int32 y)
- {
- lo_GridRec *grid;
- lo_GridEdge *edge_list;
-
- if ((state->top_state->is_grid == FALSE)||
- (state->top_state->the_grid == NULL))
- {
- return(NULL);
- }
-
- grid = state->top_state->the_grid;
- edge_list = grid->edge_list;
- while (edge_list != NULL)
- {
- /*
- * You cannot grab invisible edges.
- */
- if (edge_list->fe_edge->visible == FALSE)
- {
- edge_list = edge_list->next;
- continue;
- }
-
- if (edge_list->is_vertical == FALSE)
- {
- if ((y >= edge_list->y)&&
- (y < (edge_list->y + edge_list->height))&&
- (x >= edge_list->x)&&
- (x < (edge_list->x + edge_list->width)))
- {
- break;
- }
- }
- else
- {
- if ((x >= edge_list->x)&&
- (x < (edge_list->x + edge_list->width))&&
- (y >= edge_list->y)&&
- (y < (edge_list->y + edge_list->height)))
- {
- break;
- }
- }
- edge_list = edge_list->next;
- }
-
- if (edge_list != NULL)
- {
- #ifdef DEBUG_EDGES
- lo_print_edge_info(edge_list);
- #endif /* DEBUG_EDGES */
- return((LO_Element *)edge_list->fe_edge);
- }
- else
- {
- return(NULL);
- }
- }
-
-
- /*
- * Edges left of a moved vertical edge may need to be shrunk
- * or grown with the edge.
- */
- static void
- lo_change_left_edges(MWContext *context, lo_GridEdge *edge,
- int32 bound, int32 diff, Bool call_display_edge)
- {
- if (edge != NULL)
- {
- /*
- * If this edge abuts the edge moved,
- * change this edges width just like
- * the cell.
- */
- if ((edge->x + edge->width) == bound)
- {
- edge->width += diff;
- edge->fe_edge->width += diff;
-
- if (call_display_edge)
- /*
- * Display the edge that was just changed.
- */
- lo_DisplayEdge(context, edge->fe_edge);
- }
- }
- }
-
-
- /*
- * Edges right of a moved vertical edge may need to be moved and shrunk
- * or grown with the edge.
- */
- static void
- lo_change_right_edges(MWContext *context, lo_GridEdge *edge,
- int32 bound, int32 diff, Bool call_display_edge)
- {
- if (edge != NULL)
- {
- /*
- * If this edge abuts the edge moved,
- * change this edges position and width just like
- * the cell.
- */
- if ((edge->x - 1) == bound)
- {
- edge->x += diff;
- edge->width -= diff;
- edge->fe_edge->x += diff;
- edge->fe_edge->width -= diff;
- if (call_display_edge)
- /*
- * Display the edge that was just changed.
- */
- lo_DisplayEdge(context, edge->fe_edge);
- }
- }
- }
-
-
- /*
- * Edges above a moved vertical edge may need to be shrunk
- * or grown with the edge.
- */
- static void
- lo_change_top_edges(MWContext *context, lo_GridEdge *edge,
- int32 bound, int32 diff, Bool call_display_edge)
- {
- if (edge != NULL)
- {
- /*
- * If this edge abuts the edge moved,
- * change this edges width just like
- * the cell.
- */
- if ((edge->y + edge->height) == bound)
- {
- edge->height += diff;
- edge->fe_edge->height += diff;
- if (call_display_edge)
- /*
- * Display the edge that was just changed.
- */
- lo_DisplayEdge(context, edge->fe_edge);
- }
- }
- }
-
-
- /*
- * Edges below a moved horizontal edge may need to be moved and shrunk
- * or grown with the edge.
- */
- static void
- lo_change_bottom_edges(MWContext *context, lo_GridEdge *edge,
- int32 bound, int32 diff, Bool call_display_edge)
- {
- if (edge != NULL)
- {
- /*
- * If this edge abuts the edge moved,
- * change this edges position and width just like
- * the cell.
- */
- if ((edge->y - 1) == bound)
- {
- edge->y += diff;
- edge->height -= diff;
- edge->fe_edge->y += diff;
- edge->fe_edge->height -= diff;
- if (call_display_edge)
- /*
- * Display the edge that was just changed.
- */
- lo_DisplayEdge(context, edge->fe_edge);
- }
- }
- }
-
-
- void
- LO_MoveGridEdge(MWContext *context, LO_EdgeStruct *fe_edge, int32 x, int32 y)
- {
- int32 doc_id;
- lo_TopState *top_state;
- lo_DocState *state;
- int32 i;
- lo_GridEdge *edge;
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(context);
- top_state = lo_FetchTopState(doc_id);
- if ((top_state == NULL)||(top_state->doc_state == NULL))
- {
- return;
- }
- state = top_state->doc_state;
-
- edge = (lo_GridEdge *)fe_edge->lo_edge_info;
- if (edge == NULL)
- {
- return;
- }
-
- /*
- * For horizontal edges
- */
- if (edge->is_vertical == FALSE)
- {
- int32 diff;
-
- diff = y - edge->y;
-
- for (i=0; i < edge->cell_cnt; i++)
- {
- lo_GridCellRec *cell;
-
- cell = edge->cell_array[i];
- if (cell == NULL)
- {
- continue;
- }
- /*
- * If the cell is above the edge.
- * Grow the cell and any abutting
- * edges.
- */
- if (cell->y < edge->y)
- {
- cell->height += diff;
- lo_change_top_edges(context,
- cell->side_edges[LEFT_EDGE],
- edge->y, diff, TRUE);
- lo_change_top_edges(context,
- cell->side_edges[RIGHT_EDGE],
- edge->y, diff, TRUE);
- /*
- * The bounds of this edge are effected
- */
- lo_set_edge_bounds(cell->side_edges[TOP_EDGE]);
- }
- /*
- * Else the cell is below the edge.
- * Move and shrink the cell and any abutting
- * edges.
- */
- else
- {
- cell->y += diff;
- cell->height -= diff;
- lo_change_bottom_edges(context,
- cell->side_edges[LEFT_EDGE],
- (edge->y + edge->height - 1), diff, TRUE);
- lo_change_bottom_edges(context,
- cell->side_edges[RIGHT_EDGE],
- (edge->y + edge->height - 1), diff, TRUE);
- /*
- * The bounds of this edge are effected
- */
- lo_set_edge_bounds(cell->side_edges[BOTTOM_EDGE]);
- }
- /*
- * Only restructure cells that have windows(contexts)
- */
- if (cell->context != NULL)
- {
- FE_RestructureGridWindow (cell->context,
- cell->x, cell->y,
- cell->width, cell->height);
- }
- }
- edge->y = y;
- edge->fe_edge->y = y;
- }
- /*
- * Else for vertical edges.
- */
- else
- {
- int32 diff;
-
- diff = x - edge->x;
-
- for (i=0; i < edge->cell_cnt; i++)
- {
- lo_GridCellRec *cell;
-
- cell = edge->cell_array[i];
- if (cell == NULL)
- {
- continue;
- }
- /*
- * If the cell is left of the edge.
- * Grow the cell and any abutting
- * edges.
- */
- if (cell->x < edge->x)
- {
- cell->width += diff;
- lo_change_left_edges(context,
- cell->side_edges[TOP_EDGE],
- edge->x, diff, TRUE);
- lo_change_left_edges(context,
- cell->side_edges[BOTTOM_EDGE],
- edge->x, diff, TRUE);
- /*
- * The bounds of this edge are effected
- */
- lo_set_edge_bounds(cell->side_edges[LEFT_EDGE]);
- }
- /*
- * Else the cell is right of the edge.
- * Move and shrink the cell and any abutting
- * edges.
- */
- else
- {
- cell->x += diff;
- cell->width -= diff;
- lo_change_right_edges(context,
- cell->side_edges[TOP_EDGE],
- (edge->x + edge->width - 1), diff, TRUE);
- lo_change_right_edges(context,
- cell->side_edges[BOTTOM_EDGE],
- (edge->x + edge->width - 1), diff, TRUE);
- /*
- * The bounds of this edge are effected
- */
- lo_set_edge_bounds(cell->side_edges[RIGHT_EDGE]);
- }
- /*
- * Only restructure cells that have windows(contexts)
- */
- if (cell->context != NULL)
- {
- FE_RestructureGridWindow (cell->context,
- cell->x, cell->y,
- cell->width, cell->height);
- }
- }
- edge->x = x;
- edge->fe_edge->x = x;
- }
- /*
- * Display the edge that was just moved.
- */
- lo_DisplayEdge(context, edge->fe_edge);
- }
-
- intn
- lo_GetCurrentGridCellStatus(lo_GridCellRec *cell)
- {
- int32 doc_id;
- lo_TopState *top_state;
-
- /*
- * This is a blank cell, always considered complete.
- */
- if ((cell == NULL)||(cell->context == NULL))
- {
- return(PA_COMPLETE);
- }
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(cell->context);
- top_state = lo_FetchTopState(doc_id);
- if (top_state == NULL)
- {
- return(-1);
- }
- return(top_state->layout_status);
- }
-
-
- char *
- lo_GetCurrentGridCellUrl(lo_GridCellRec *cell)
- {
- int32 doc_id;
- lo_TopState *top_state;
- char *url;
-
- if ((cell == NULL)||(cell->context == NULL))
- {
- return(NULL);
- }
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(cell->context);
- top_state = lo_FetchTopState(doc_id);
- if (top_state == NULL)
- {
- return(NULL);
- }
-
- if (top_state->url == NULL)
- {
- url = NULL;
- }
- else
- {
- url = XP_STRDUP(top_state->url);
- }
- return(url);
- }
-
-
- void
- lo_GetGridCellMargins(MWContext *context,
- int32 *margin_width, int32 *margin_height)
- {
- int32 doc_id;
- lo_TopState *top_state;
- MWContext *parent;
- lo_GridCellRec *cell_ptr;
-
- if ((context == NULL)||(context->grid_parent == NULL))
- {
- return;
- }
-
- parent = context->grid_parent;
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(parent);
- top_state = lo_FetchTopState(doc_id);
- if ((top_state == NULL)||(top_state->the_grid == NULL))
- {
- return;
- }
-
- /*
- * Find the cell whose context matches the passed in context.
- */
- cell_ptr = top_state->the_grid->cell_list;
- while (cell_ptr != NULL)
- {
- if (cell_ptr->context == context)
- {
- break;
- }
- cell_ptr = cell_ptr->next;
- }
-
- /*
- * If we found the cell, set our margins.
- */
- if (cell_ptr != NULL)
- {
- *margin_width = cell_ptr->margin_width;
- *margin_height = cell_ptr->margin_height;
- }
- /*
- * If we didn't find the cell, it is
- * in the middle of creation, get the
- * margins from the parent grid.
- */
- else
- {
- *margin_width = top_state->the_grid->current_cell_margin_width;
- *margin_height = top_state->the_grid->current_cell_margin_height;
- }
- }
-
-
- static void
- lo_reset_all_edge_bounds(MWContext *context, lo_DocState *state,
- lo_GridRec *grid)
- {
- lo_GridEdge *edge_list;
-
- if ((grid == NULL)||(grid->edge_list == NULL))
- {
- return;
- }
-
- edge_list = grid->edge_list;
- while (edge_list != NULL)
- {
- LO_EdgeStruct *fe_edge;
-
- fe_edge = (LO_EdgeStruct *)lo_NewElement(context, state,
- LO_EDGE, NULL, 0);
- if (fe_edge == NULL)
- {
- }
-
- fe_edge->type = LO_EDGE;
- fe_edge->ele_id = NEXT_ELEMENT;
- fe_edge->x = edge_list->x;
- fe_edge->x_offset = 0;
- fe_edge->y = edge_list->y;
- fe_edge->y_offset = 0;
- fe_edge->width = edge_list->width;
- fe_edge->height = edge_list->height;
- fe_edge->line_height = 0;
- fe_edge->next = NULL;
- fe_edge->prev = NULL;
-
- fe_edge->FE_Data = NULL;
- fe_edge->lo_edge_info = (void *)edge_list;
- fe_edge->is_vertical = edge_list->is_vertical;
- fe_edge->movable = TRUE;
- fe_edge->left_top_bound = 0;
- fe_edge->right_bottom_bound = 0;
-
- edge_list->fe_edge = fe_edge;
-
- lo_set_edge_bounds(edge_list);
-
- /*
- * Insert this edge into the float list.
- */
- edge_list->fe_edge->next = state->float_list;
- state->float_list = (LO_Element *)edge_list->fe_edge;
-
- lo_DisplayEdge(context, edge_list->fe_edge);
- edge_list = edge_list->next;
- }
- }
-
-
- void
- lo_RecreateGrid(MWContext *context, lo_DocState *state, lo_GridRec *grid)
- {
- lo_GridCellRec *cell_ptr;
- int32 width, height;
-
- width = state->win_width;
- height = state->win_height;
- FE_GetFullWindowSize(context, &width, &height);
-
- if (width <= 0)
- width = 1;
-
- if (height <= 0)
- height = 1;
-
- /* already set.
- grid->main_width = width;
- grid->main_height = height;
- */
-
- lo_reset_all_edge_bounds(context, state, grid);
-
- state->top_state->the_grid = grid;
-
- /*
- * Go through all the cells creating them where specified.
- */
- cell_ptr = grid->cell_list;
- while (cell_ptr != NULL)
- {
- /*
- * Have the front end create the grid cell.
- */
- if (cell_ptr->url != NULL)
- {
- void *history;
- void *hist_list;
-
- history = NULL;
- hist_list = NULL;
- if (cell_ptr->hist_list != NULL)
- {
- hist_list = cell_ptr->hist_list;
- cell_ptr->hist_indx = grid->current_hist;
- history = cell_ptr->hist_array[cell_ptr->hist_indx - 1].hist;
- if (history == NULL)
- {
- hist_list = NULL;
- }
- }
- grid->current_cell_margin_width = cell_ptr->margin_width;
- grid->current_cell_margin_height = cell_ptr->margin_height;
- reconnecting_cell = cell_ptr;
- cell_ptr->context = FE_MakeGridWindow (context,
- hist_list,
- history,
- cell_ptr->x, cell_ptr->y,
- cell_ptr->width, cell_ptr->height,
- (char *)cell_ptr->url, (char *)cell_ptr->name,
- cell_ptr->scrolling,
- FORCE_RELOAD_FLAG(state->top_state),
- cell_ptr->no_edges);
- reconnecting_cell = NULL;
- grid->current_cell_margin_width = 0;
- grid->current_cell_margin_height = 0;
- if (cell_ptr->context)
- {
- XP_ASSERT(cell_ptr->context->forceJSEnabled ==
- context->forceJSEnabled);
- if (history)
- {
- cell_ptr->context->hist.cur_doc_ptr = history;
- }
- }
- }
- else
- {
- cell_ptr->context = NULL;
- }
- cell_ptr = cell_ptr->next;
- }
- }
-
-
-
- lo_GridCellRec *
- lo_ContextToCell(MWContext *context, Bool reconnect, lo_GridRec **grid_ptr)
- {
- int32 doc_id;
- lo_TopState *top_state;
- MWContext *parent;
- lo_GridCellRec *cell_ptr;
-
- *grid_ptr = NULL;
- if ((context == NULL)||(context->grid_parent == NULL))
- {
- return((lo_GridCellRec *)NULL);
- }
-
- parent = context->grid_parent;
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(parent);
- top_state = lo_FetchTopState(doc_id);
- if ((top_state == NULL)||(top_state->the_grid == NULL))
- {
- return((lo_GridCellRec *)NULL);
- }
-
- *grid_ptr = top_state->the_grid;
-
- /*
- * Find the cell whose context matches the passed in context.
- */
- cell_ptr = top_state->the_grid->cell_list;
- while (cell_ptr != NULL)
- {
- if (cell_ptr->context == context)
- {
- return(cell_ptr);
- }
- cell_ptr = cell_ptr->next;
- }
-
- if (reconnect && (cell_ptr = reconnecting_cell) != NULL)
- {
- cell_ptr->context = context;
- if (context->grid_parent)
- {
- context->forceJSEnabled =
- context->grid_parent->forceJSEnabled;
- }
-
- return(cell_ptr);
- }
- return(NULL);
- }
-
-
- static void
- lo_set_hist(MWContext *context, void **hep, History_entry *hist)
- {
- History_entry *oldhist = *hep;
-
- if (oldhist == hist)
- return;
- *hep = SHIST_HoldEntry(hist);
- SHIST_DropEntry(context, oldhist);
- }
-
-
- PRIVATE
- void
- lo_UpdateOtherCells(lo_GridRec *grid, lo_GridCellRec *the_cell)
- {
- lo_GridCellRec *cell_ptr;
-
- cell_ptr = grid->cell_list;
- while (cell_ptr != NULL)
- {
- if ((cell_ptr != the_cell)&&
- (cell_ptr->hist_indx < grid->current_hist))
- {
- int32 i;
- int32 old;
-
- /*
- * Make sure se don't go backwards off the beginning
- * of the array.
- */
- old = cell_ptr->hist_indx - 1;
- if (old < 0)
- {
- old = 0;
- }
-
- for (i = cell_ptr->hist_indx; i < grid->current_hist; i++)
- {
- lo_set_hist(cell_ptr->context,
- &cell_ptr->hist_array[i].hist,
- cell_ptr->hist_array[old].hist);
- cell_ptr->hist_array[i].position =
- cell_ptr->hist_array[old].position;
- }
-
- /*
- * If we got here and hist_indx is zero, that means
- * we are trying to update this cell, before it ever
- * had its initializing load. In that case, we
- * want to leave hist_indx zero so we will be able to
- * detect that initializing load when it occurs.
- */
- if (cell_ptr->hist_indx > 0)
- {
- cell_ptr->hist_indx = grid->current_hist;
- }
- }
- cell_ptr = cell_ptr->next;
- }
- }
-
-
- static void
- lo_grow_grid_hist_arrays(lo_GridRec *grid)
- {
- int32 new_size;
- lo_GridCellRec *cell_ptr;
-
- if (grid == NULL)
- {
- return;
- }
-
- new_size = grid->hist_size + 10;
- cell_ptr = grid->cell_list;
- while (cell_ptr != NULL)
- {
- lo_GridHistory *new_array;
-
- new_array = (lo_GridHistory *)XP_REALLOC(cell_ptr->hist_array,
- (new_size * sizeof(lo_GridHistory)));
- if (new_array == NULL)
- {
- /* XXX should set top_state->out_of_memory somehow */
- return;
- }
- XP_MEMSET(new_array + grid->hist_size, 0,
- (10 * sizeof(lo_GridHistory)));
- cell_ptr->hist_array = new_array;
- cell_ptr = cell_ptr->next;
- }
- grid->hist_size = new_size;
- }
-
-
- void
- LO_UpdateGridHistory(MWContext *context)
- {
- lo_GridRec *grid;
- lo_GridCellRec *cell_ptr;
- History_entry *hist;
-
- cell_ptr = lo_ContextToCell(context, TRUE, &grid);
- if (cell_ptr == NULL)
- {
- return;
- }
-
- hist = SHIST_GetCurrent(&context->hist);
- if (hist == NULL)
- {
- return;
- }
-
- if (cell_ptr->hist_indx >= grid->current_hist)
- {
- if (grid->current_hist >= grid->hist_size)
- {
- lo_grow_grid_hist_arrays(grid);
- }
- grid->current_hist = cell_ptr->hist_indx + 1;
- if (grid->current_hist > grid->max_hist)
- {
- grid->max_hist = grid->current_hist;
- }
- else if (grid->current_hist < grid->max_hist)
- {
- grid->max_hist = grid->current_hist;
- }
- if (grid->current_hist > 1)
- {
- lo_UpdateOtherCells(grid, cell_ptr);
- if ((context->grid_parent != NULL)&&
- (context->grid_parent->is_grid_cell != FALSE))
- {
- LO_UpdateGridHistory(context->grid_parent);
- }
- }
- }
- lo_set_hist(context,
- &cell_ptr->hist_array[cell_ptr->hist_indx].hist,
- hist);
- if (cell_ptr->hist_indx == 0)
- {
- cell_ptr->hist_array[cell_ptr->hist_indx].position = 1;
- /*
- * This means some other grid cell already progressed before
- * we got our first load, now that we are loaded, catch up.
- */
- if (grid->current_hist > 1)
- {
- int32 i;
-
- for (i = 1; i < grid->current_hist; i++)
- {
- lo_set_hist(context,
- &cell_ptr->hist_array[i].hist,
- cell_ptr->hist_array[0].hist);
- cell_ptr->hist_array[i].position =
- cell_ptr->hist_array[0].position;
- }
- cell_ptr->hist_indx = grid->current_hist - 1;
- }
- }
- else
- {
- /*
- * Drop held MochaDecoder if any, we needed it only during
- * resize-reload and don't now that we've moved forward in
- * this frame context's history.
- */
- hist = cell_ptr->hist_array[cell_ptr->hist_indx - 1].hist;
- if (hist && hist->savedData.Window)
- {
- LM_DropSavedWindow(context, hist->savedData.Window);
- hist->savedData.Window = NULL;
- }
-
- cell_ptr->hist_array[cell_ptr->hist_indx].position =
- cell_ptr->hist_array[cell_ptr->hist_indx - 1].position + 1;
- }
- cell_ptr->hist_indx++;
- }
-
-
- PRIVATE
- void
- lo_BackupGridHistory(lo_GridRec *grid)
- {
- lo_GridCellRec *cell_ptr;
-
- cell_ptr = grid->cell_list;
- while (cell_ptr != NULL)
- {
- if (cell_ptr->hist_indx > 1)
- {
- int32 indx;
-
- cell_ptr->hist_indx--;
- indx = cell_ptr->hist_indx - 1;
-
- if (cell_ptr->hist_array[indx].hist !=
- cell_ptr->hist_array[cell_ptr->hist_indx].hist)
- {
- lo_reload_cell_from_history(cell_ptr,
- NET_DONT_RELOAD);
- }
- else if ((cell_ptr->hist_array[indx].position !=
- cell_ptr->hist_array[cell_ptr->hist_indx].position)&&
- (cell_ptr->context != NULL)&&
- (cell_ptr->context->grid_children != NULL))
- {
- (void)LO_BackInGrid(cell_ptr->context);
- }
- }
- cell_ptr = cell_ptr->next;
- }
- }
-
-
- PRIVATE
- void
- lo_ForwardGridHistory(lo_GridRec *grid)
- {
- lo_GridCellRec *cell_ptr;
-
- cell_ptr = grid->cell_list;
- while (cell_ptr != NULL)
- {
- if (cell_ptr->hist_indx < grid->max_hist)
- {
- int32 indx;
-
- cell_ptr->hist_indx++;
- indx = cell_ptr->hist_indx - 1;
-
- if (cell_ptr->hist_array[indx].hist !=
- cell_ptr->hist_array[indx - 1].hist)
- {
- lo_reload_cell_from_history(cell_ptr,
- NET_DONT_RELOAD);
- }
- else if ((cell_ptr->hist_array[indx].position !=
- cell_ptr->hist_array[indx - 1].position)&&
- (cell_ptr->context != NULL)&&
- (cell_ptr->context->grid_children != NULL))
- {
- (void)LO_ForwardInGrid(cell_ptr->context);
- }
- }
- cell_ptr = cell_ptr->next;
- }
- }
-
-
- Bool
- LO_BackInGrid(MWContext *context)
- {
- int32 doc_id;
- lo_TopState *top_state;
- lo_GridRec *grid;
-
- if ((context == NULL)||(context->grid_children == NULL))
- {
- return(FALSE);
- }
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(context);
- top_state = lo_FetchTopState(doc_id);
- if ((top_state == NULL)||(top_state->the_grid == NULL))
- {
- return(FALSE);
- }
-
- grid = top_state->the_grid;
-
- if (grid->current_hist <= 1)
- {
- return(FALSE);
- }
-
- lo_BackupGridHistory(grid);
- grid->current_hist--;
- return(TRUE);
- }
-
-
- Bool
- LO_ForwardInGrid(MWContext *context)
- {
- int32 doc_id;
- lo_TopState *top_state;
- lo_GridRec *grid;
-
- if ((context == NULL)||(context->grid_children == NULL))
- {
- return(FALSE);
- }
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(context);
- top_state = lo_FetchTopState(doc_id);
- if ((top_state == NULL)||(top_state->the_grid == NULL))
- {
- return(FALSE);
- }
-
- grid = top_state->the_grid;
-
- if (grid->current_hist >= grid->max_hist)
- {
- return(FALSE);
- }
-
- lo_ForwardGridHistory(grid);
- grid->current_hist++;
- return(TRUE);
- }
-
-
- Bool
- LO_GridCanGoForward(MWContext *context)
- {
- int32 doc_id;
- lo_TopState *top_state;
- lo_GridRec *grid;
-
- if ((context == NULL)||(context->grid_children == NULL))
- {
- return(FALSE);
- }
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(context);
- top_state = lo_FetchTopState(doc_id);
- if ((top_state == NULL)||(top_state->the_grid == NULL))
- {
- return(FALSE);
- }
-
- grid = top_state->the_grid;
-
- if (grid->current_hist < grid->max_hist)
- {
- return(TRUE);
- }
- return(FALSE);
- }
-
-
- Bool
- LO_GridCanGoBackward(MWContext *context)
- {
- int32 doc_id;
- lo_TopState *top_state;
- lo_GridRec *grid;
-
- if ((context == NULL)||(context->grid_children == NULL))
- {
- return(FALSE);
- }
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(context);
- top_state = lo_FetchTopState(doc_id);
- if ((top_state == NULL)||(top_state->the_grid == NULL))
- {
- return(FALSE);
- }
-
- grid = top_state->the_grid;
-
- if (grid->current_hist > 1)
- {
- return(TRUE);
- }
- return(FALSE);
- }
-
-
- static void
- lo_cleanup_grid_history(MWContext *context, lo_GridRec *grid)
- {
- lo_GridCellRec *cell_ptr;
-
- if (grid == NULL)
- {
- return;
- }
-
- /*
- * Set the current history to be the new maximum.
- */
- grid->max_hist = grid->current_hist;
-
- /*
- * Go through all the cells, truncating their history lists
- */
- cell_ptr = grid->cell_list;
- while (cell_ptr != NULL)
- {
- int32 indx, count;
- XP_List *list_ptr;
- History_entry *cell_hist;
-
- list_ptr = (XP_List *)cell_ptr->hist_list;
- cell_hist = cell_ptr->hist_array[grid->current_hist - 1].hist;
- if ((list_ptr != NULL)&&(cell_hist != NULL))
- {
- indx = XP_ListGetNumFromObject(list_ptr, cell_hist);
- for (count = XP_ListCount(list_ptr); count > indx; count--)
- {
- History_entry *old_entry;
-
- old_entry =
- (History_entry *)XP_ListRemoveEndObject(list_ptr);
- SHIST_DropEntry(context, old_entry);
- }
- }
-
- /*
- * If the last history entry in the cells chain
- * is itself a grid, it may need to be cleaned
- * up recursively.
- */
- if (cell_hist != NULL)
- {
- lo_SavedGridData *saved_grid;
-
- saved_grid =(lo_SavedGridData *)(cell_hist->savedData.Grid);
- if ((saved_grid != NULL)&&(saved_grid->the_grid != NULL))
- {
- lo_cleanup_grid_history(context, saved_grid->the_grid);
- }
- }
-
- cell_ptr = cell_ptr->next;
- }
- }
-
-
- /*
- * When we have just added a session history after
- * this one, clean up the grid's history chains if
- * it is the parent we just left.
- */
- void
- LO_CleanupGridHistory(MWContext *context)
- {
- History_entry *hist;
- lo_SavedGridData *saved_grid;
- lo_GridRec *grid;
-
- /*
- * Look back one, if the is no back, return.
- */
- hist = SHIST_GetPrevious(context);
- if (hist == NULL)
- {
- return;
- }
-
- /*
- * Is the document back one in history a valid grid,
- * if not, return.
- */
- saved_grid = (lo_SavedGridData *)(hist->savedData.Grid);
- if ((saved_grid == NULL)||(saved_grid->the_grid == NULL))
- {
- return;
- }
-
- /*
- * Since we are appending after this history stage,
- * the current history chains must be
- * clipped so this is the new max.
- */
- grid = saved_grid->the_grid;
- lo_cleanup_grid_history(context, grid);
- }
-
- static void
- lo_MoveGridEdgeForRelayout(MWContext *context, LO_EdgeStruct *fe_edge, int32 x, int32 y)
- {
- int32 doc_id;
- lo_TopState *top_state;
- lo_DocState *state;
- int32 i;
- lo_GridEdge *edge;
-
- /*
- * Get the unique document ID, and retreive this
- * documents layout state.
- */
- doc_id = XP_DOCID(context);
- top_state = lo_FetchTopState(doc_id);
- if ((top_state == NULL)||(top_state->doc_state == NULL))
- {
- return;
- }
- state = top_state->doc_state;
-
- edge = (lo_GridEdge *)fe_edge->lo_edge_info;
- if (edge == NULL)
- {
- return;
- }
-
- /*
- * For horizontal edges
- */
- if (edge->is_vertical == FALSE)
- {
- int32 diff;
-
- diff = y - edge->y;
-
- for (i=0; i < edge->cell_cnt; i++)
- {
- lo_GridCellRec *cell;
-
- cell = edge->cell_array[i];
- if (cell == NULL)
- {
- continue;
- }
- /*
- * If the cell is above the edge.
- * Grow the cell and any abutting
- * edges.
- */
- if (cell->y < edge->y)
- {
- #if 0
- cell->height += diff;
- #endif
- lo_change_top_edges(context,
- cell->side_edges[LEFT_EDGE],
- edge->y, diff, FALSE);
- lo_change_top_edges(context,
- cell->side_edges[RIGHT_EDGE],
- edge->y, diff, FALSE);
- /*
- * The bounds of this edge are effected
- */
- lo_set_edge_bounds(cell->side_edges[TOP_EDGE]);
- }
- /*
- * Else the cell is below the edge.
- * Move and shrink the cell and any abutting
- * edges.
- */
- else
- {
- #if 0
- cell->y += diff;
- cell->height -= diff;
- #endif
- lo_change_bottom_edges(context,
- cell->side_edges[LEFT_EDGE],
- (edge->y + edge->height - 1), diff, FALSE);
- lo_change_bottom_edges(context,
- cell->side_edges[RIGHT_EDGE],
- (edge->y + edge->height - 1), diff, FALSE);
- /*
- * The bounds of this edge are effected
- */
- lo_set_edge_bounds(cell->side_edges[BOTTOM_EDGE]);
- }
- /*
- * Only restructure cells that have windows(contexts)
- */
- if (cell->context != NULL)
- {
- cell->needs_restructuring = TRUE;
- }
- }
- edge->y = y;
- edge->fe_edge->y = y;
- }
- /*
- * Else for vertical edges.
- */
- else
- {
- int32 diff;
-
- diff = x - edge->x;
-
- for (i=0; i < edge->cell_cnt; i++)
- {
- lo_GridCellRec *cell;
-
- cell = edge->cell_array[i];
- if (cell == NULL)
- {
- continue;
- }
- /*
- * If the cell is left of the edge.
- * Grow the cell and any abutting
- * edges.
- */
- if (cell->x < edge->x)
- {
- #if 0
- cell->width += diff;
- #endif
- lo_change_left_edges(context,
- cell->side_edges[TOP_EDGE],
- edge->x, diff, FALSE);
- lo_change_left_edges(context,
- cell->side_edges[BOTTOM_EDGE],
- edge->x, diff, FALSE);
- /*
- * The bounds of this edge are effected
- */
- lo_set_edge_bounds(cell->side_edges[LEFT_EDGE]);
- }
- /*
- * Else the cell is right of the edge.
- * Move and shrink the cell and any abutting
- * edges.
- */
- else
- {
- #if 0
- cell->x += diff;
- cell->width -= diff;
- #endif
- lo_change_right_edges(context,
- cell->side_edges[TOP_EDGE],
- (edge->x + edge->width - 1), diff, FALSE);
- lo_change_right_edges(context,
- cell->side_edges[BOTTOM_EDGE],
- (edge->x + edge->width - 1), diff, FALSE);
- /*
- * The bounds of this edge are effected
- */
- lo_set_edge_bounds(cell->side_edges[RIGHT_EDGE]);
- }
- /*
- * Only restructure cells that have windows(contexts)
- */
- if (cell->context != NULL)
- {
- cell->needs_restructuring = TRUE;
- }
- }
- edge->x = x;
- edge->fe_edge->x = x;
- }
- }
-
- PRIVATE
- void
- lo_ReLayoutGridCells(MWContext *context,
- int32 x, int32 y, int32 width, int32 height,
- lo_GridRec *grid)
- {
- int32 cols, rows;
- int32 col_cnt, row_cnt;
- int32 orig_x, orig_y;
- lo_GridCellRec *cell_list;
- int32 new_cell_width, new_cell_height;
-
- if (grid == NULL)
- {
- return;
- }
-
- /*
- * Make sure all the row percentages total up
- * to 100%
- */
- lo_adjust_percents(grid->rows, grid->row_percents, height);
-
- /*
- * Make sure all the col percentages total up
- * to 100%
- */
- lo_adjust_percents(grid->cols, grid->col_percents, width);
-
- cols = grid->cols;
- rows = grid->rows;
- cell_list = grid->cell_list;
-
- orig_x = x;
- orig_y = y;
- col_cnt = 0;
- row_cnt = 0;
- while (cell_list != NULL)
- {
- cell_list->width_percent =
- (intn)grid->col_percents[col_cnt].value;
- cell_list->height_percent =
- (intn)grid->row_percents[row_cnt].value;
-
- cell_list->x = x;
- if (col_cnt != 0)
- {
- cell_list->x += grid->grid_cell_border;
- }
- cell_list->y = y;
- if (row_cnt != 0)
- {
- cell_list->y += grid->grid_cell_border;
- }
-
- new_cell_width = width * cell_list->width_percent / 100;
- if (new_cell_width < grid->grid_cell_min_dim)
- {
- new_cell_width = grid->grid_cell_min_dim;
- }
- if (col_cnt > 0)
- {
- new_cell_width -= grid->grid_cell_border;
- }
- if (col_cnt < (cols - 1))
- {
- new_cell_width -= grid->grid_cell_border;
- }
-
- /*
- * Make sure the last column uses all the remaining space.
- * We subtract orig_x to get cell_list->x into the same coord
- * space as width.
- */
- if (col_cnt == (cols - 1))
- {
- new_cell_width = width - (cell_list->x - orig_x);
- }
-
- new_cell_height = height * cell_list->height_percent / 100;
- if (new_cell_height < grid->grid_cell_min_dim)
- {
- new_cell_height = grid->grid_cell_min_dim;
- }
- if (row_cnt > 0)
- {
- new_cell_height -= grid->grid_cell_border;
- }
- if (row_cnt < (rows - 1))
- {
- new_cell_height -= grid->grid_cell_border;
- }
-
- /*
- * Make sure the last row uses all the remaining space.
- * We subtract orig_y to get cell_list->y into the same coord
- * space as height.
- */
- if (row_cnt == (rows - 1))
- {
- new_cell_height = height - (cell_list->y - orig_y);
- }
-
- cell_list->width = new_cell_width;
- cell_list->height = new_cell_height;
-
- if (cell_list->side_edges[RIGHT_EDGE])
- {
- if (cell_list->side_edges[RIGHT_EDGE]->dealt_with_in_relayout == FALSE)
- {
- lo_MoveGridEdgeForRelayout(context,
- cell_list->side_edges[RIGHT_EDGE]->fe_edge,
- cell_list->x + cell_list->width,
- cell_list->side_edges[RIGHT_EDGE]->y);
- cell_list->side_edges[RIGHT_EDGE]->dealt_with_in_relayout = TRUE;
- }
- }
-
- if (cell_list->side_edges[BOTTOM_EDGE])
- {
- if (cell_list->side_edges[BOTTOM_EDGE]->dealt_with_in_relayout == FALSE)
- {
- lo_MoveGridEdgeForRelayout(context,
- cell_list->side_edges[BOTTOM_EDGE]->fe_edge,
- cell_list->side_edges[BOTTOM_EDGE]->x,
- cell_list->y + cell_list->height);
- cell_list->side_edges[BOTTOM_EDGE]->dealt_with_in_relayout = TRUE;
- }
- }
-
- x += new_cell_width;
- if (col_cnt > 0)
- {
- x += grid->grid_cell_border;
- }
- if (col_cnt < (cols - 1))
- {
- x += grid->grid_cell_border;
- }
- col_cnt++;
- if (col_cnt >= cols)
- {
- x = orig_x;
- y += new_cell_height;
- if (row_cnt > 0)
- {
- y += grid->grid_cell_border;
- }
- if (row_cnt < (rows - 1))
- {
- y += grid->grid_cell_border;
- }
- col_cnt = 0;
- row_cnt++;
- }
-
- cell_list = cell_list->next;
- }
- }
-
- static void
- lo_PrepareGridForRelayout(MWContext *context,
- lo_GridRec *grid)
- {
- lo_GridEdge *edge_list;
- lo_GridCellRec *cell_list;
-
- cell_list = grid->cell_list;
- while(cell_list)
- {
- cell_list->needs_restructuring = FALSE;
- cell_list = cell_list->next;
- }
-
- edge_list = grid->edge_list;
- while (edge_list != NULL)
- {
- /* FE_HideEdge(context, FE_VIEW, edge_list->fe_edge);*/
- edge_list->dealt_with_in_relayout = FALSE;
- edge_list = edge_list->next;
- }
-
- }
-
- static void
- lo_ResyncEdgeSizes(MWContext *context,
- lo_GridRec *grid)
- {
- lo_GridEdge *edge_list;
-
- edge_list = grid->edge_list;
- while (edge_list != NULL)
- {
- int i;
-
- lo_set_edge_bounds(edge_list);
-
- if (edge_list->is_vertical == FALSE) /* horizontal edge */
- {
- int32 width = 0;
- for (i = 0; i < edge_list->cell_cnt; i ++)
- {
- lo_GridCellRec *cell;
-
- cell = edge_list->cell_array[i];
- if (cell == NULL)
- {
- continue;
- }
-
- if (cell->x + cell->width > edge_list->x + width)
- width = cell->x + cell->width - edge_list->x;
- }
-
- edge_list->width = width;
- edge_list->fe_edge->width = width;
- }
- else /* vertical edge */
- {
- int32 height = 0;
- for (i = 0; i < edge_list->cell_cnt; i ++)
- {
- lo_GridCellRec *cell;
-
- cell = edge_list->cell_array[i];
- if (cell == NULL)
- {
- continue;
- }
-
- if (cell->y + cell->height > edge_list->y + height)
- height = cell->y + cell->height - edge_list->y;
- }
-
- edge_list->height = height;
- edge_list->fe_edge->height = height;
- }
-
- lo_DisplayEdge(context, edge_list->fe_edge);
-
- edge_list = edge_list->next;
- }
- }
-
- static void
- lo_RestructureCells(MWContext *context,
- lo_GridRec *grid)
- {
- lo_GridCellRec *cell_list;
- cell_list = grid->cell_list;
- while(cell_list)
- {
- if (cell_list->needs_restructuring &&
- cell_list->context != NULL)
- {
- FE_RestructureGridWindow (cell_list->context,
- cell_list->x, cell_list->y,
- cell_list->width, cell_list->height);
- }
-
- cell_list = cell_list->next;
- }
- }
-
- void
- lo_RelayoutGridDocumentOnResize(MWContext *context,
- lo_TopState *top_state,
- int32 width, int32 height)
- {
- lo_GridRec *grid = top_state->the_grid;
-
- lo_PrepareGridForRelayout(context, grid);
-
- lo_ReLayoutGridCells(context, 0, 0, width, height, grid);
-
- lo_RestructureCells(context, grid);
-
- lo_ResyncEdgeSizes(context, grid);
- }
-
-