static void TXT_CalcTableSize(TXT_UNCAST_ARG(table)) { TXT_CAST_ARG(txt_table_t, table); unsigned int *column_widths; unsigned int *row_heights; int x, y; int rows; rows = TableRows(table); row_heights = malloc(sizeof(int) * rows); column_widths = malloc(sizeof(int) * table->columns); CalcRowColSizes(table, row_heights, column_widths); table->widget.w = 0; for (x=0; x<table->columns; ++x) { table->widget.w += column_widths[x]; } table->widget.h = 0; for (y=0; y<rows; ++y) { table->widget.h += row_heights[y]; } free(row_heights); free(column_widths); }
static void TXT_KeyInputDrawer(TXT_UNCAST_ARG(key_input)) { TXT_CAST_ARG(txt_key_input_t, key_input); char buf[20]; int i; if (*key_input->variable == 0) { M_StringCopy(buf, "(none)", sizeof(buf)); } else { TXT_GetKeyDescription(*key_input->variable, buf, sizeof(buf)); } TXT_SetWidgetBG(key_input); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); TXT_DrawString(buf); for (i=strlen(buf); i<KEY_INPUT_WIDTH; ++i) { TXT_DrawString(" "); } }
static int KeyPressCallback(txt_window_t *window, int key, TXT_UNCAST_ARG(key_input)) { TXT_CAST_ARG(txt_key_input_t, key_input); if (key != KEY_ESCAPE) { // Got the key press. Save to the variable and close the window. *key_input->variable = key; if (key_input->check_conflicts) { TXT_EmitSignal(key_input, "set"); } TXT_CloseWindow(window); // Re-enable key mappings now that we have the key TXT_EnableKeyMapping(1); return 1; } else { return 0; } }
static void GenerateModesTable(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(modes_table)) { TXT_CAST_ARG(txt_table_t, modes_table); char buf[15]; screen_mode_t *modes; txt_radiobutton_t *rbutton; int i; // Pick which modes list to use if (fullscreen) { if (screen_modes_fullscreen == NULL) { BuildFullscreenModesList(); } modes = screen_modes_fullscreen; } else if (aspect_ratio_correct) { modes = screen_modes_scaled; } else { modes = screen_modes_unscaled; } // Build the table TXT_ClearTable(modes_table); TXT_SetColumnWidths(modes_table, 14, 14, 14, 14, 14); for (i=0; modes[i].w != 0; ++i) { // Skip bad fullscreen modes if (fullscreen && !GoodFullscreenMode(&modes[i])) { continue; } sprintf(buf, "%ix%i", modes[i].w, modes[i].h); rbutton = TXT_NewRadioButton(buf, &vidmode, i); TXT_AddWidget(modes_table, rbutton); TXT_SignalConnect(rbutton, "selected", ModeSelected, &modes[i]); } // Find the nearest mode in the list that matches the current // settings vidmode = FindBestMode(modes); if (vidmode > 0) { screen_width = modes[vidmode].w; screen_height = modes[vidmode].h; } }
static void TXT_LabelSizeCalc(TXT_UNCAST_ARG(label)) { TXT_CAST_ARG(txt_label_t, label); label->widget.w = label->w; label->widget.h = label->h; }
void TXT_EmitSignal(TXT_UNCAST_ARG(widget), char *signal_name) { TXT_CAST_ARG(txt_widget_t, widget); txt_callback_table_t *table; int i; table = widget->callback_table; // Don't destroy the table while we're searching through it // (one of the callbacks may destroy this window) TXT_RefCallbackTable(table); // Search the table for all callbacks with this name and invoke // the functions. for (i=0; i<table->num_callbacks; ++i) { if (!strcmp(table->callbacks[i].signal_name, signal_name)) { table->callbacks[i].func(widget, table->callbacks[i].user_data); } } // Finished using the table TXT_UnrefCallbackTable(table); }
static void TXT_SpinControlSizeCalc(TXT_UNCAST_ARG(spincontrol)) { TXT_CAST_ARG(txt_spincontrol_t, spincontrol); spincontrol->widget.w = SpinControlWidth(spincontrol) + 5; spincontrol->widget.h = 1; }
static void WindowSizeSelected(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(size)) { TXT_CAST_ARG(window_size_t, size); window_width = size->w; window_height = size->h; }
static void AdvancedDisplayConfig(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(sizes_table)) { TXT_CAST_ARG(txt_table_t, sizes_table); txt_window_t *window; txt_checkbox_t *ar_checkbox; window = TXT_NewWindow("Advanced display options"); TXT_SetWindowHelpURL(window, WINDOW_HELP_URL); TXT_SetColumnWidths(window, 40); TXT_AddWidgets(window, ar_checkbox = TXT_NewCheckBox("Force correct aspect ratio", &aspect_ratio_correct), TXT_If(gamemission == heretic || gamemission == hexen || gamemission == strife, TXT_NewCheckBox("Graphical startup", &graphical_startup)), TXT_If(gamemission == doom || gamemission == heretic || gamemission == strife, TXT_NewCheckBox("Show ENDOOM screen on exit", &show_endoom)), #ifdef HAVE_LIBPNG TXT_NewCheckBox("Save screenshots in PNG format", &png_screenshots), #endif NULL); TXT_SignalConnect(ar_checkbox, "changed", GenerateSizesTable, sizes_table); }
static void TXT_InputBoxDestructor(TXT_UNCAST_ARG(inputbox)) { TXT_CAST_ARG(txt_inputbox_t, inputbox); StopEditing(inputbox); free(inputbox->buffer); }
static void TXT_SeparatorDrawer(TXT_UNCAST_ARG(separator)) { TXT_CAST_ARG(txt_separator_t, separator); int x, y; int w; w = separator->widget.w; TXT_GetXY(&x, &y); // Draw separator. Go back one character and draw two extra // to overlap the window borders. TXT_DrawSeparator(x-2, y, w + 4); if (separator->label != NULL) { TXT_GotoXY(x, y); TXT_FGColor(TXT_COLOR_BRIGHT_GREEN); TXT_DrawString(" "); TXT_DrawString(separator->label); TXT_DrawString(" "); } }
static void UpdateVideoDriver(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(modes_table)) { TXT_CAST_ARG(txt_table_t, modes_table); if (use_directx) { video_driver = ""; } else { video_driver = "windib"; } // When the video driver is changed, we need to restart the textscreen // library. RestartTextscreen(); // Rebuild the list of supported pixel depths. IdentifyPixelDepths(); SetSelectedBPP(); // Rebuild the video modes list BuildFullscreenModesList(); GenerateModesTable(NULL, modes_table); }
txt_widget_t *TXT_GetSelectedWidget(TXT_UNCAST_ARG(table)) { TXT_CAST_ARG(txt_table_t, table); txt_widget_t *result; int index; index = table->selected_y * table->columns + table->selected_x; result = NULL; if (index >= 0 && index < table->num_widgets) { result = table->widgets[index]; if (!IsActualWidget(result)) { result = NULL; } } if (result != NULL && result->widget_class == &txt_table_class) { result = TXT_GetSelectedWidget(result); } return result; }
static int TXT_TableSelectable(TXT_UNCAST_ARG(table)) { TXT_CAST_ARG(txt_table_t, table); int i; // Is the currently-selected cell selectable? if (SelectableCell(table, table->selected_x, table->selected_y)) { return 1; } // Find the first selectable cell and set selected_x, selected_y. for (i = 0; i < table->num_widgets; ++i) { if (IsActualWidget(table->widgets[i]) && TXT_SelectableWidget(table->widgets[i])) { ChangeSelection(table, i % table->columns, i / table->columns); return 1; } } // No selectable widgets exist within the table. return 0; }
static int EventCallback(SDL_Event *event, TXT_UNCAST_ARG(joystick_input)) { TXT_CAST_ARG(txt_joystick_input_t, joystick_input); // Got the joystick button press? if (event->type == SDL_JOYBUTTONDOWN) { int vbutton, physbutton; // Before changing anything, remap button configuration into // canonical form, to avoid conflicts. CanonicalizeButtons(); vbutton = VirtualButtonForVariable(joystick_input->variable); physbutton = event->jbutton.button; if (joystick_input->check_conflicts) { ClearVariablesUsingButton(physbutton); } // Set mapping. *joystick_input->variable = vbutton; joystick_physical_buttons[vbutton] = physbutton; TXT_CloseWindow(joystick_input->prompt_window); return 1; } return 0; }
static void GameSelected(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(config)) { TXT_CAST_ARG(mission_config_t, config); SetMission(config); game_selected_callback(); }
static void TXT_JoystickInputDrawer(TXT_UNCAST_ARG(joystick_input)) { TXT_CAST_ARG(txt_joystick_input_t, joystick_input); char buf[20]; int i; if (*joystick_input->variable < 0) { M_StringCopy(buf, "(none)", sizeof(buf)); } else { GetJoystickButtonDescription(*joystick_input->variable, buf, sizeof(buf)); } TXT_SetWidgetBG(joystick_input); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); TXT_DrawString(buf); for (i=strlen(buf); i<JOYSTICK_INPUT_WIDTH; ++i) { TXT_DrawString(" "); } }
static void TXT_JoystickInputDrawer(TXT_UNCAST_ARG(joystick_input), int selected) { TXT_CAST_ARG(txt_joystick_input_t, joystick_input); char buf[20]; int i; if (*joystick_input->variable < 0) { strcpy(buf, "(none)"); } else { GetJoystickButtonDescription(*joystick_input->variable, buf); } if (selected) { TXT_BGColor(TXT_COLOR_GREY, 0); } else { TXT_BGColor(TXT_COLOR_BLUE, 0); } TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); TXT_DrawString(buf); for (i=strlen(buf); i<JOYSTICK_INPUT_WIDTH; ++i) { TXT_DrawString(" "); } }
static void TXT_LabelDestructor(TXT_UNCAST_ARG(label)) { TXT_CAST_ARG(txt_label_t, label); free(label->label); free(label->lines); }
static void TXT_ButtonSizeCalc(TXT_UNCAST_ARG(button)) { TXT_CAST_ARG(txt_button_t, button); button->widget.w = strlen(button->label); button->widget.h = 1; }
static void TXT_WindowActionDrawer(TXT_UNCAST_ARG(action)) { TXT_CAST_ARG(txt_window_action_t, action); char buf[10]; TXT_GetKeyDescription(action->key, buf); if (TXT_HoveringOverWidget(action)) { TXT_BGColor(TXT_COLOR_BLACK, 0); } else { TXT_BGColor(TXT_WINDOW_BACKGROUND, 0); } TXT_DrawString(" "); TXT_FGColor(TXT_COLOR_BRIGHT_GREEN); TXT_DrawString(buf); TXT_FGColor(TXT_COLOR_BRIGHT_CYAN); TXT_DrawString("="); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); TXT_DrawString(action->label); TXT_DrawString(" "); }
static void TXT_DropdownListSizeCalc(TXT_UNCAST_ARG(list)) { TXT_CAST_ARG(txt_dropdown_list_t, list); list->widget.w = DropdownListWidth(list); list->widget.h = 1; }
static void AdvancedDisplayConfig(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(modes_table)) { TXT_CAST_ARG(txt_table_t, modes_table); txt_window_t *window; txt_checkbox_t *ar_checkbox; window = TXT_NewWindow("Advanced display options"); TXT_SetColumnWidths(window, 35); TXT_AddWidgets(window, ar_checkbox = TXT_NewCheckBox("Fix aspect ratio", &aspect_ratio_correct), NULL); if (gamemission == heretic || gamemission == hexen || gamemission == strife) { TXT_AddWidget(window, TXT_NewCheckBox("Graphical startup", &graphical_startup)); } if (gamemission == doom || gamemission == heretic || gamemission == strife) { TXT_AddWidget(window, TXT_NewCheckBox("Show ENDOOM screen on exit", &show_endoom)); } TXT_SignalConnect(ar_checkbox, "changed", GenerateModesTable, modes_table); }
static void TXT_MouseInputDrawer(TXT_UNCAST_ARG(mouse_input)) { TXT_CAST_ARG(txt_mouse_input_t, mouse_input); char buf[20]; int i; if (*mouse_input->variable < 0) { M_StringCopy(buf, "(none)", sizeof(buf)); } else { GetMouseButtonDescription(*mouse_input->variable, buf, sizeof(buf)); } TXT_SetWidgetBG(mouse_input); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); TXT_DrawString(buf); for (i=strlen(buf); i<MOUSE_INPUT_WIDTH; ++i) { TXT_DrawString(" "); } }
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; }
void Operator(TXT_UNCAST_ARG(button), TXT_UNCAST_ARG(op)) { TXT_CAST_ARG(operator_t, op); first_operand = input_value; operator = *op; starting_input = 1; }
int TXT_ContainsWidget(TXT_UNCAST_ARG(haystack), TXT_UNCAST_ARG(needle)) { TXT_CAST_ARG(txt_widget_t, haystack); TXT_CAST_ARG(txt_widget_t, needle); while (needle != NULL) { if (needle == haystack) { return 1; } needle = needle->parent; } return 0; }
void TXT_DestroyWidget(TXT_UNCAST_ARG(widget)) { TXT_CAST_ARG(txt_widget_t, widget); widget->widget_class->destructor(widget); TXT_UnrefCallbackTable(widget->callback_table); free(widget); }
static void TXT_TableLayout(TXT_UNCAST_ARG(table)) { TXT_CAST_ARG(txt_table_t, table); unsigned int *column_widths; unsigned int *row_heights; int draw_x, draw_y; int x, y; int i; int rows; // Work out the column widths and row heights rows = TableRows(table); column_widths = malloc(sizeof(int) * table->columns); row_heights = malloc(sizeof(int) * rows); CalcRowColSizes(table, row_heights, column_widths); // If this table only has one column, expand column size to fit // the display width. Ensures that separators reach the window edges // when drawing windows. if (table->columns == 1) { column_widths[0] = table->widget.w; } // Draw all cells draw_y = table->widget.y; for (y=0; y<rows; ++y) { draw_x = table->widget.x; for (x=0; x<table->columns; ++x) { i = y * table->columns + x; if (i >= table->num_widgets) break; if (table->widgets[i] != NULL) { LayoutCell(table, x, y, column_widths[x], draw_x, draw_y); } draw_x += column_widths[x]; } draw_y += row_heights[y]; } free(row_heights); free(column_widths); }
static void TXT_InputBoxDrawer(TXT_UNCAST_ARG(inputbox)) { TXT_CAST_ARG(txt_inputbox_t, inputbox); int focused; int i; int chars; int w; focused = inputbox->widget.focused; w = inputbox->widget.w; // Select the background color based on whether we are currently // editing, and if not, whether the widget is focused. if (inputbox->editing && focused) { TXT_BGColor(TXT_COLOR_BLACK, 0); } else { TXT_SetWidgetBG(inputbox); } if (!inputbox->editing) { // If not editing, use the current value from inputbox->value. SetBufferFromValue(inputbox); } // If string size exceeds the widget's width, show only the end. if (TXT_UTF8_Strlen(inputbox->buffer) > w - 1) { TXT_DrawString("\xae"); TXT_DrawUTF8String( TXT_UTF8_SkipChars(inputbox->buffer, TXT_UTF8_Strlen(inputbox->buffer) - w + 2)); chars = w - 1; } else { TXT_DrawUTF8String(inputbox->buffer); chars = TXT_UTF8_Strlen(inputbox->buffer); } if (chars < w && inputbox->editing && focused) { TXT_BGColor(TXT_COLOR_BLACK, 1); TXT_DrawString("_"); ++chars; } for (i=chars; i < w; ++i) { TXT_DrawString(" "); } }