static void LayoutCell(txt_table_t *table, int x, int y, int draw_x, int draw_y) { txt_widget_t *widget; int col_width; widget = table->widgets[y * table->columns + x]; col_width = widget->w; // Adjust x position based on alignment property switch (widget->align) { case TXT_HORIZ_LEFT: widget->w = col_width; break; case TXT_HORIZ_CENTER: TXT_CalcWidgetSize(widget); // Separators are always drawn left-aligned. if (widget->widget_class != &txt_separator_class) { draw_x += (col_width - widget->w) / 2; } break; case TXT_HORIZ_RIGHT: TXT_CalcWidgetSize(widget); if (widget->widget_class != &txt_separator_class) { draw_x += col_width - widget->w; } break; } // Set the position for this widget widget->x = draw_x; widget->y = draw_y; // Recursively lay out any widgets contained in the widget TXT_LayoutWidget(widget); }
static void CalcActionAreaSize(txt_window_t *window, unsigned int *w, unsigned int *h) { txt_widget_t *widget; int i; *w = 0; *h = 0; // Calculate the width of all the action widgets and use this // to create an overall min. width of the action area for (i=0; i<3; ++i) { widget = (txt_widget_t *) window->actions[i]; if (widget != NULL) { TXT_CalcWidgetSize(widget); *w += widget->w; if (widget->h > *h) { *h = widget->h; } } } }
static void TXT_FileSelectSizeCalc(TXT_UNCAST_ARG(fileselect)) { TXT_CAST_ARG(txt_fileselect_t, fileselect); // Calculate widget size, but override the width to always // be the configured size. TXT_CalcWidgetSize(fileselect->inputbox); fileselect->widget.w = fileselect->size; fileselect->widget.h = fileselect->inputbox->widget.h; }
static void LayoutActionArea(txt_window_t *window) { txt_widget_t *widget; // Left action if (window->actions[TXT_HORIZ_LEFT] != NULL) { widget = (txt_widget_t *) window->actions[TXT_HORIZ_LEFT]; TXT_CalcWidgetSize(widget); widget->x = window->window_x + 2; widget->y = window->window_y + window->window_h - widget->h - 1; } // Draw the center action if (window->actions[TXT_HORIZ_CENTER] != NULL) { widget = (txt_widget_t *) window->actions[TXT_HORIZ_CENTER]; TXT_CalcWidgetSize(widget); widget->x = window->window_x + (window->window_w - widget->w - 2) / 2; widget->y = window->window_y + window->window_h - widget->h - 1; } // Draw the right action if (window->actions[TXT_HORIZ_RIGHT] != NULL) { widget = (txt_widget_t *) window->actions[TXT_HORIZ_RIGHT]; TXT_CalcWidgetSize(widget); widget->x = window->window_x + window->window_w - 2 - widget->w; widget->y = window->window_y + window->window_h - widget->h - 1; } }
static void TXT_ScrollPaneSizeCalc(TXT_UNCAST_ARG(scrollpane)) { TXT_CAST_ARG(txt_scrollpane_t, scrollpane); int scrollbars; if (scrollpane->child != NULL) { TXT_CalcWidgetSize(scrollpane->child); } // Expand as necessary (to ensure that no scrollbars are needed)? if (scrollpane->expand_w) { scrollpane->w = FullWidth(scrollpane); } if (scrollpane->expand_h) { scrollpane->h = FullHeight(scrollpane); } scrollpane->widget.w = scrollpane->w; scrollpane->widget.h = scrollpane->h; // If we have scroll bars, we need to expand slightly to // accomodate them. Eg. if we have a vertical scrollbar, we // need to be an extra character wide. scrollbars = NeedsScrollbars(scrollpane); if (scrollbars & SCROLLBAR_HORIZONTAL) { ++scrollpane->widget.h; } if (scrollbars & SCROLLBAR_VERTICAL) { ++scrollpane->widget.w; } if (scrollpane->child != NULL) { if (scrollpane->child->w < scrollpane->w) { scrollpane->child->w = scrollpane->w; } if (scrollpane->child->h < scrollpane->h) { scrollpane->child->h = scrollpane->h; } } }
static void CalcRowColSizes(txt_table_t *table, unsigned int *row_heights, unsigned int *col_widths) { int x, y; int rows; txt_widget_t *widget; rows = TableRows(table); memset(col_widths, 0, sizeof(int) * table->columns); for (y=0; y<rows; ++y) { row_heights[y] = 0; for (x=0; x<table->columns; ++x) { if (y * table->columns + x >= table->num_widgets) break; widget = table->widgets[y * table->columns + x]; // NULL represents an empty spacer if (widget != NULL) { TXT_CalcWidgetSize(widget); if (widget->h > row_heights[y]) row_heights[y] = widget->h; if (widget->w > col_widths[x]) col_widths[x] = widget->w; } } } }
void TXT_LayoutWindow(txt_window_t *window) { txt_widget_t *widgets = (txt_widget_t *) window; unsigned int widgets_w; unsigned int actionarea_w, actionarea_h; // Calculate size of table TXT_CalcWidgetSize(window); // Widgets area: add one character of padding on each side widgets_w = widgets->w + 2; // Calculate the size of the action area // Make window wide enough to action area CalcActionAreaSize(window, &actionarea_w, &actionarea_h); if (actionarea_w > widgets_w) widgets_w = actionarea_w; // Set the window size based on widgets_w window->window_w = widgets_w + 2; window->window_h = widgets->h + 1; // If the window has a title, add an extra two lines if (window->title != NULL) { window->window_h += 2; } // If the window has an action area, add extra lines if (actionarea_h > 0) { window->window_h += actionarea_h + 1; } // Use the x,y position as the centerpoint and find the location to // draw the window. CalcWindowPosition(window); // Set the table size and position widgets->w = widgets_w - 2; // widgets->h (already set) widgets->x = window->window_x + 2; widgets->y = window->window_y; if (window->title != NULL) { widgets->y += 2; } // Layout the table and action area LayoutActionArea(window); TXT_LayoutWidget(widgets); }
static void LayoutActionArea(txt_window_t *window) { txt_widget_t *widget; int space_available; int space_left_offset; // We need to calculate the available horizontal space for the center // action widget, so that we can center it within it. // To start with, we have the entire action area available. space_available = window->window_w; space_left_offset = 0; // Left action if (window->actions[TXT_HORIZ_LEFT] != NULL) { widget = (txt_widget_t *) window->actions[TXT_HORIZ_LEFT]; TXT_CalcWidgetSize(widget); widget->x = window->window_x + 1; widget->y = window->window_y + window->window_h - widget->h - 1; // Adjust available space: space_available -= widget->w; space_left_offset += widget->w; } // Draw the right action if (window->actions[TXT_HORIZ_RIGHT] != NULL) { widget = (txt_widget_t *) window->actions[TXT_HORIZ_RIGHT]; TXT_CalcWidgetSize(widget); widget->x = window->window_x + window->window_w - 1 - widget->w; widget->y = window->window_y + window->window_h - widget->h - 1; // Adjust available space: space_available -= widget->w; } // Draw the center action if (window->actions[TXT_HORIZ_CENTER] != NULL) { widget = (txt_widget_t *) window->actions[TXT_HORIZ_CENTER]; TXT_CalcWidgetSize(widget); // The left and right widgets have left a space sandwiched between // them. Center this widget within that space. widget->x = window->window_x + space_left_offset + (space_available - widget->w) / 2; widget->y = window->window_y + window->window_h - widget->h - 1; } }
static void CalcRowColSizes(txt_table_t *table, unsigned int *row_heights, unsigned int *col_widths) { int x, y; int rows; txt_widget_t *widget; rows = TableRows(table); memset(col_widths, 0, sizeof(int) * table->columns); for (y = 0; y < rows; ++y) { row_heights[y] = 0; for (x = 0; x < table->columns; ++x) { if (y * table->columns + x >= table->num_widgets) break; widget = table->widgets[y * table->columns + x]; if (IsActualWidget(widget)) { TXT_CalcWidgetSize(widget); } // In the first pass we ignore overflowing cells. if (IsOverflowingCell(table, x, y)) { continue; } // NULL represents an empty spacer if (IsActualWidget(widget)) { if (widget->h > row_heights[y]) row_heights[y] = widget->h; if (widget->w > col_widths[x]) col_widths[x] = widget->w; } } } // In the second pass, we go through again and process overflowing // widgets, to ensure that they will fit. for (y = 0; y < rows; ++y) { for (x = 0; x < table->columns; ++x) { unsigned int w, h; if (y * table->columns + x >= table->num_widgets) break; widget = table->widgets[y * table->columns + x]; if (!IsActualWidget(widget)) { continue; } // Expand column width and row heights as needed. CalculateWidgetDimensions(table, x, y, col_widths, row_heights, &w, &h); if (w < widget->w) { col_widths[x] += widget->w - w; } if (h < widget->h) { row_heights[y] += widget->h - h; } } } }