void TXT_AddWidget(TXT_UNCAST_ARG(table), TXT_UNCAST_ARG(widget)) { TXT_CAST_ARG(txt_table_t, table); TXT_CAST_ARG(txt_widget_t, widget); if (table->num_widgets > 0) { txt_widget_t *last_widget; last_widget = table->widgets[table->num_widgets - 1]; if (widget != NULL && last_widget != NULL && widget->widget_class == &txt_separator_class && last_widget->widget_class == &txt_separator_class) { // The previous widget added was a separator; replace // it with this one. // // This way, if the first widget added to a window is // a separator, it replaces the "default" separator that // the window itself adds on creation. table->widgets[table->num_widgets - 1] = widget; TXT_DestroyWidget(last_widget); return; } } table->widgets = realloc(table->widgets, sizeof(txt_widget_t *) * (table->num_widgets + 1)); table->widgets[table->num_widgets] = widget; ++table->num_widgets; }
void TXT_SetTableColumns(TXT_UNCAST_ARG(table), int new_columns) { TXT_CAST_ARG(txt_table_t, table); txt_widget_t **new_widgets; txt_widget_t *widget; int new_num_widgets; int i, j, x; // We need as many full rows as are in the current list, plus the // remainder from the last row. new_num_widgets = (table->num_widgets / table->columns) * new_columns + (table->num_widgets % table->columns); new_widgets = calloc(new_num_widgets, sizeof(txt_widget_t *)); // Reset and add one by one from the old table. new_num_widgets = 0; for (i = 0; i < table->num_widgets; ++i) { widget = table->widgets[i]; x = i % table->columns; if (x < new_columns) { new_widgets[new_num_widgets] = widget; ++new_num_widgets; } else if (IsActualWidget(widget)) { TXT_DestroyWidget(widget); } // When we reach the last column of a row, we must pad it out with // extra widgets to reach the next row. if (x == table->columns - 1) { for (j = table->columns; j < new_columns; ++j) { // First row? We need to add struts that are used to apply // the column widths. if (i < table->columns) { widget = &TXT_NewStrut(0, 0)->widget; } else { widget = &txt_table_overflow_right; } new_widgets[new_num_widgets] = widget; ++new_num_widgets; } } } free(table->widgets); table->widgets = new_widgets; table->num_widgets = new_num_widgets; table->columns = new_columns; }
static void TXT_ScrollPaneDestructor(TXT_UNCAST_ARG(scrollpane)) { TXT_CAST_ARG(txt_scrollpane_t, scrollpane); if (scrollpane->child != NULL) { TXT_DestroyWidget(scrollpane->child); } }
void TXT_SetWindowAction(txt_window_t *window, txt_horiz_align_t position, txt_window_action_t *action) { if (window->actions[position] != NULL) { TXT_DestroyWidget(window->actions[position]); } window->actions[position] = action; }
void TXT_CloseWindow(txt_window_t *window) { int i; TXT_EmitSignal(window, "closed"); TXT_RemoveDesktopWindow(window); free(window->title); // Destroy all actions for (i=0; i<3; ++i) { if (window->actions[i] != NULL) { TXT_DestroyWidget(window->actions[i]); } } // Destroy table and window TXT_DestroyWidget(window); }
void TXT_SetWindowAction(txt_window_t *window, txt_horiz_align_t position, txt_window_action_t *action) { if (window->actions[position] != NULL) { TXT_DestroyWidget(window->actions[position]); } window->actions[position] = action; // Maintain parent pointer. if (action != NULL) { action->widget.parent = &window->table.widget; } }
void TXT_ClearTable(TXT_UNCAST_ARG(table)) { TXT_CAST_ARG(txt_table_t, table); int i; // Free all widgets // Skip over the first (num_columns) widgets in the array, as these // are the column struts used to control column width for (i=table->columns; i<table->num_widgets; ++i) { if (table->widgets[i] != NULL) { TXT_DestroyWidget(table->widgets[i]); } } // Shrink the table to just the column strut widgets table->num_widgets = table->columns; }
static void TXT_FileSelectDestructor(TXT_UNCAST_ARG(fileselect)) { TXT_CAST_ARG(txt_fileselect_t, fileselect); TXT_DestroyWidget(fileselect->inputbox); }
void TXT_AddWidget(TXT_UNCAST_ARG(table), TXT_UNCAST_ARG(widget)) { TXT_CAST_ARG(txt_table_t, table); TXT_CAST_ARG(txt_widget_t, widget); int is_separator; int i; // Convenience alias for NULL: if (widget == &txt_table_empty) { widget = NULL; } else if (widget == &txt_table_eol) { FillRowToEnd(table); return; } // We have special handling for the separator widget: is_separator = IsActualWidget(widget) && widget->widget_class == &txt_separator_class; // If we add two separators consecutively, the new separator replaces the // first. This allows us to override the "implicit" separator that is // added at the top of a window when it is created. if (is_separator) { for (i = table->num_widgets - 1; i >= 0; --i) { txt_widget_t *last_widget; last_widget = table->widgets[i]; if (IsActualWidget(last_widget) && widget->widget_class == &txt_separator_class && last_widget->widget_class == &txt_separator_class) { table->widgets[i] = widget; TXT_DestroyWidget(last_widget); return; } else if (last_widget != &txt_table_overflow_right) { break; } } } // Separators begin on a new line. if (is_separator) { FillRowToEnd(table); } table->widgets = realloc(table->widgets, sizeof(txt_widget_t *) * (table->num_widgets + 1)); table->widgets[table->num_widgets] = widget; ++table->num_widgets; // Maintain parent pointer. if (IsActualWidget(widget)) { widget->parent = &table->widget; } // Separators always take up the entire line. if (is_separator) { FillRowToEnd(table); } }