Ejemplo n.º 1
0
/**
 * Shows a text dropdown menu.
 *  rct2: 0x006ECFB9, although 0x006ECE50 is real version
 *
 * @param x (cx)
 * @param y (dx)
 * @param extray (di)
 * @param flags (bh)
 * @param num_items (bx)
 * @param colour (al)
 * @param custom_height (ah) requires flag set as well
 */
void window_dropdown_show_text_custom_width(
    int32_t x, int32_t y, int32_t extray, uint8_t colour, uint8_t custom_height, uint8_t flags, size_t num_items, int32_t width)
{
    rct_window* w;

    input_set_flag((INPUT_FLAGS)(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP), false);
    if (flags & DROPDOWN_FLAG_STAY_OPEN)
        input_set_flag(INPUT_FLAG_DROPDOWN_STAY_OPEN, true);

    window_dropdown_close();

    // Set and calculate num items, rows and columns
    _dropdown_item_width = width;
    _dropdown_item_height = (flags & DROPDOWN_FLAG_CUSTOM_HEIGHT) ? custom_height : DROPDOWN_ITEM_HEIGHT;
    gDropdownNumItems = (int32_t)num_items;
    // There must always be at least one column to prevent dividing by zero
    if (gDropdownNumItems == 0)
    {
        _dropdown_num_columns = 1;
        _dropdown_num_rows = 0;
    }
    else
    {
        _dropdown_num_columns = (gDropdownNumItems + DROPDOWN_TEXT_MAX_ROWS - 1) / DROPDOWN_TEXT_MAX_ROWS;
        _dropdown_num_rows = (gDropdownNumItems + _dropdown_num_columns - 1) / _dropdown_num_columns;
    }

    // Text dropdowns are listed horizontally
    _dropdown_list_vertically = true;

    width = _dropdown_item_width * _dropdown_num_columns + 3;
    int32_t height = _dropdown_item_height * _dropdown_num_rows + 3;
    int32_t screenWidth = context_get_width();
    int32_t screenHeight = context_get_height();
    if (x + width > screenWidth)
        x = std::max(0, screenWidth - width);
    if (y + height > screenHeight)
        y = std::max(0, screenHeight - height);

    window_dropdown_widgets[WIDX_BACKGROUND].right = width;
    window_dropdown_widgets[WIDX_BACKGROUND].bottom = height;

    // Create the window
    w = window_create(
        x, y + extray, window_dropdown_widgets[WIDX_BACKGROUND].right + 1, window_dropdown_widgets[WIDX_BACKGROUND].bottom + 1,
        &window_dropdown_events, WC_DROPDOWN, WF_STICK_TO_FRONT);
    w->widgets = window_dropdown_widgets;
    if (colour & COLOUR_FLAG_TRANSLUCENT)
        w->flags |= WF_TRANSPARENT;
    w->colours[0] = colour;

    // Input state
    gDropdownHighlightedIndex = -1;
    std::fill_n(_dropdownItemsDisabled, sizeof(_dropdownItemsDisabled), false);
    std::fill_n(_dropdownItemsChecked, sizeof(_dropdownItemsChecked), false);
    gDropdownIsColour = false;
    gDropdownDefaultIndex = -1;
    input_set_state(INPUT_STATE_DROPDOWN_ACTIVE);
}
Ejemplo n.º 2
0
void window_tooltip_show(rct_string_id id, int32_t x, int32_t y)
{
    rct_window* w;
    int32_t width, height;

    w = window_find_by_class(WC_ERROR);
    if (w != nullptr)
        return;

    char* buffer = gCommonStringFormatBuffer;

    format_string(buffer, sizeof(gCommonStringFormatBuffer), id, gCommonFormatArgs);
    gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;

    int32_t tooltip_text_width;
    tooltip_text_width = gfx_get_string_width_new_lined(buffer);
    buffer = gCommonStringFormatBuffer;
    tooltip_text_width = std::min(tooltip_text_width, 196);

    gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM;

    int32_t numLines, fontSpriteBase;
    tooltip_text_width = gfx_wrap_string(buffer, tooltip_text_width + 1, &numLines, &fontSpriteBase);

    _tooltipNumLines = numLines;
    width = tooltip_text_width + 3;
    height = ((numLines + 1) * font_get_line_height(gCurrentFontSpriteBase)) + 4;
    window_tooltip_widgets[WIDX_BACKGROUND].right = width;
    window_tooltip_widgets[WIDX_BACKGROUND].bottom = height;

    std::memcpy(_tooltipText, buffer, sizeof(_tooltipText));

    int32_t screenWidth = context_get_width();
    int32_t screenHeight = context_get_height();
    x = std::clamp(x - (width / 2), 0, screenWidth - width);

    // TODO The cursor size will be relative to the window DPI.
    //      The amount to offset the y should be adjusted.

    int32_t max_y = screenHeight - height;
    y += 26; // Normally, we'd display the tooltip 26 lower
    if (y > max_y)
        // If y is too large, the tooltip could be forced below the cursor if we'd just clamped y,
        // so we'll subtract a bit more
        y -= height + 40;
    y = std::clamp(y, 22, max_y);

    w = window_create(x, y, width, height, &window_tooltip_events, WC_TOOLTIP, WF_TRANSPARENT | WF_STICK_TO_FRONT);
    w->widgets = window_tooltip_widgets;

    reset_tooltip_not_shown();
}
Ejemplo n.º 3
0
/**
 * Creates the window containing the exit button on the title screen.
 *  rct2: 0x0066B624 (part of 0x0066B3E8)
 */
rct_window* window_title_exit_open()
{
    rct_window* window;

    window = window_create(
        context_get_width() - 40, context_get_height() - 64, 40, 64, &window_title_exit_events, WC_TITLE_EXIT,
        WF_STICK_TO_BACK | WF_TRANSPARENT);
    window->widgets = window_title_exit_widgets;
    window->enabled_widgets |= (1ULL << WIDX_EXIT);
    window_init_scroll_widgets(window);

    return window;
}
Ejemplo n.º 4
0
/**
 *
 *  rct2: 0x006D386D
 */
rct_window* window_install_track_open(const utf8* path)
{
    _trackDesign = track_design_open(path);
    if (_trackDesign == nullptr)
    {
        context_show_error(STR_UNABLE_TO_LOAD_FILE, STR_NONE);
        return nullptr;
    }

    object_manager_unload_all_objects();
    if (_trackDesign->type == RIDE_TYPE_NULL)
    {
        log_error("Failed to load track (ride type null): %s", path);
        return nullptr;
    }
    if (object_manager_load_object(&_trackDesign->vehicle_object) == nullptr)
    {
        log_error("Failed to load track (vehicle load fail): %s", path);
        return nullptr;
    }

    window_close_by_class(WC_EDITOR_OBJECT_SELECTION);
    window_close_construction_windows();

    gTrackDesignSceneryToggle = false;
    _currentTrackPieceDirection = 2;

    int32_t screenWidth = context_get_width();
    int32_t screenHeight = context_get_height();
    int32_t x = screenWidth / 2 - 201;
    int32_t y = std::max(TOP_TOOLBAR_HEIGHT + 1, screenHeight / 2 - 200);

    rct_window* w = window_create(x, y, WW, WH, &window_install_track_events, WC_INSTALL_TRACK, 0);
    w->widgets = window_install_track_widgets;
    w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_ROTATE) | (1 << WIDX_TOGGLE_SCENERY) | (1 << WIDX_INSTALL)
        | (1 << WIDX_CANCEL);
    window_init_scroll_widgets(w);
    w->track_list.track_list_being_updated = false;
    window_push_others_right(w);

    _trackPath = path;
    _trackName = GetNameFromTrackPath(path);
    _trackDesignPreviewPixels.resize(4 * TRACK_PREVIEW_IMAGE_SIZE);

    window_install_track_update_preview();
    window_invalidate(w);

    return w;
}
Ejemplo n.º 5
0
/**
* Creates the main editor top toolbar window.
* rct2: 0x0066F052 (part of 0x0066EF38)
*/
void window_editor_bottom_toolbar_open()
{
    rct_window * window = window_create(0, context_get_height() - 32,
        context_get_width(), 32,
        &window_editor_bottom_toolbar_events,
        WC_BOTTOM_TOOLBAR, WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_NO_BACKGROUND);
    window->widgets = window_editor_bottom_toolbar_widgets;

    window->enabled_widgets |=
        (1 << WIDX_PREVIOUS_STEP_BUTTON) |
        (1 << WIDX_NEXT_STEP_BUTTON) |
        (1 << WIDX_PREVIOUS_IMAGE) |
        (1 << WIDX_NEXT_IMAGE);

    window_init_scroll_widgets(window);
    reset_researched_scenery_items();
}
Ejemplo n.º 6
0
/**
 *
 *  rct2: 0x006CF1A2
 */
void window_track_list_open(ride_list_item item)
{
    window_close_construction_windows();
    _window_track_list_item = item;
    track_list_load_designs(item);

    sint32 x, y;
    if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) {
        sint32 screenWidth = context_get_width();
        sint32 screenHeight = context_get_height();
        x = screenWidth / 2 - 300;
        y = max(TOP_TOOLBAR_HEIGHT + 1, screenHeight / 2 - 200);
    } else {
        x = 0;
        y = TOP_TOOLBAR_HEIGHT + 2;
    }
    rct_window *w = window_create(
        x,
        y,
        600,
        400,
        &window_track_list_events,
        WC_TRACK_DESIGN_LIST,
        0
    );
    w->widgets = window_track_list_widgets;
    w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_ROTATE) | (1 << WIDX_TOGGLE_SCENERY) | (1 << WIDX_BACK);
    window_init_scroll_widgets(w);
    w->track_list.var_480 = 0xFFFF;
    w->track_list.var_484 = 0;
    w->track_list.reload_track_designs = false;
    w->selected_list_item = 0;
    if (_trackDesignsCount != 0 && !(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) {
        w->selected_list_item = 1;
    }
    gTrackDesignSceneryToggle = false;
    window_push_others_right(w);
    _currentTrackPieceDirection = 2;

    _trackDesignPreviewPixels = calloc(4, TRACK_PREVIEW_IMAGE_SIZE);

    _loadedTrackDesign = NULL;
    _loadedTrackDesignIndex = TRACK_DESIGN_INDEX_UNLOADED;
}
Ejemplo n.º 7
0
/**
 * Creates the window containing the menu buttons on the title screen.
 *  rct2: 0x0066B5C0 (part of 0x0066B3E8)
 */
rct_window * window_title_menu_open()
{
    rct_window* window;

    window = window_create(
        0, context_get_height() - 142,
        0, 100,
        &window_title_menu_events,
        WC_TITLE_MENU,
        WF_STICK_TO_BACK | WF_TRANSPARENT | WF_NO_BACKGROUND
    );
    window->widgets = window_title_menu_widgets;
    window->enabled_widgets = (
        (1 << WIDX_START_NEW_GAME) |
        (1 << WIDX_CONTINUE_SAVED_GAME) |
#ifndef DISABLE_NETWORK
        (1 << WIDX_MULTIPLAYER) |
#endif
        (1 << WIDX_GAME_TOOLS)
    );

    rct_widgetindex i = 0;
    sint32 x = 0;
    for (rct_widget *widget = window->widgets; widget->type != WWT_LAST; widget++) {
        if (widget_is_enabled(window, i)) {
            widget->left = x;
            widget->right = x + 81;

            x += 82;
        } else {
            widget->type = WWT_EMPTY;
        }
        i++;
    }
    window->width = x;
    window->x = (context_get_width() - window->width) / 2;

    window_init_scroll_widgets(window);

    return window;
}
Ejemplo n.º 8
0
/**
 * Creates the main window that holds the main viewport.
 *  rct2: 0x0066B3E8
 */
rct_window * window_main_open()
{
    window_main_widgets[0].right = context_get_width();
    window_main_widgets[0].bottom = context_get_height();
    rct_window * window = window_create(
        0, 0,
        window_main_widgets[0].right, window_main_widgets[0].bottom,
        &window_main_events,
        WC_MAIN_WINDOW,
        WF_STICK_TO_BACK
    );
    window->widgets = window_main_widgets;

    viewport_create(window, window->x, window->y, window->width, window->height, 0,0x0FFF,0x0FFF, 0, 0x1, -1);
    window->viewport->flags |= VIEWPORT_FLAG_SOUND_ON;
    gCurrentRotation = 0;
    gShowGridLinesRefCount = 0;
    gShowLandRightsRefCount = 0;
    gShowConstuctionRightsRefCount = 0;
    gFootpathSelectedType = 0;

    return window;
}
Ejemplo n.º 9
0
void chat_draw(rct_drawpixelinfo* dpi, uint8_t chatBackgroundColor)
{
    if (!chat_available())
    {
        gChatOpen = false;
        return;
    }

    _chatLeft = 10;
    _chatRight = std::min((context_get_width() - 10), CHAT_MAX_WINDOW_WIDTH);
    _chatWidth = _chatRight - _chatLeft;
    _chatBottom = context_get_height() - 45;
    _chatTop = _chatBottom - 10;

    char lineBuffer[CHAT_INPUT_SIZE + 10];
    char* lineCh = lineBuffer;
    char* inputLine = _chatCurrentLine;
    int32_t inputLineHeight = 10;

    // Draw chat window
    if (gChatOpen)
    {
        inputLineHeight = chat_string_wrapped_get_height((void*)&inputLine, _chatWidth - 10);
        _chatTop -= inputLineHeight;

        for (int32_t i = 0; i < CHAT_HISTORY_SIZE; i++)
        {
            if (strlen(chat_history_get(i)) == 0)
            {
                continue;
            }

            safe_strcpy(lineBuffer, chat_history_get(i), sizeof(lineBuffer));

            int32_t lineHeight = chat_string_wrapped_get_height((void*)&lineCh, _chatWidth - 10);
            _chatTop -= (lineHeight + 5);
        }

        _chatHeight = _chatBottom - _chatTop;

        if (_chatTop < 50)
        {
            _chatTop = 50;
        }
        else if (_chatHeight < 150)
        { // Min height
            _chatTop = _chatBottom - 150;
            _chatHeight = 150;
        }

        gfx_set_dirty_blocks(_chatLeft, _chatTop - 5, _chatRight, _chatBottom + 5);             // Background area + Textbox
        gfx_filter_rect(dpi, _chatLeft, _chatTop - 5, _chatRight, _chatBottom + 5, PALETTE_51); // Opaque gray background
        gfx_fill_rect_inset(
            dpi, _chatLeft, _chatTop - 5, _chatRight, _chatBottom + 5, chatBackgroundColor, INSET_RECT_FLAG_FILL_NONE);
        gfx_fill_rect_inset(
            dpi, _chatLeft + 1, _chatTop - 4, _chatRight - 1, _chatBottom - inputLineHeight - 6, chatBackgroundColor,
            INSET_RECT_FLAG_BORDER_INSET);
        gfx_fill_rect_inset(
            dpi, _chatLeft + 1, _chatBottom - inputLineHeight - 5, _chatRight - 1, _chatBottom + 4, chatBackgroundColor,
            INSET_RECT_FLAG_BORDER_INSET); // Textbox
    }

    int32_t x = _chatLeft + 5;
    int32_t y = _chatBottom - inputLineHeight - 20;
    int32_t stringHeight = 0;

    // Draw chat history
    for (int32_t i = 0; i < CHAT_HISTORY_SIZE; i++, y -= stringHeight)
    {
        uint32_t expireTime = chat_history_get_time(i) + 10000;
        if (!gChatOpen && platform_get_ticks() > expireTime)
        {
            break;
        }

        safe_strcpy(lineBuffer, chat_history_get(i), sizeof(lineBuffer));

        stringHeight = chat_history_draw_string(dpi, (void*)&lineCh, x, y, _chatWidth - 10) + 5;
        gfx_set_dirty_blocks(x, y - stringHeight, x + _chatWidth, y + 20);

        if ((y - stringHeight) < 50)
        {
            break;
        }
    }

    // Draw current chat input
    if (gChatOpen)
    {
        lineCh = utf8_write_codepoint(lineCh, FORMAT_OUTLINE);
        lineCh = utf8_write_codepoint(lineCh, FORMAT_CELADON);

        safe_strcpy(lineCh, _chatCurrentLine, sizeof(_chatCurrentLine));
        y = _chatBottom - inputLineHeight - 5;

        lineCh = lineBuffer;
        inputLineHeight = gfx_draw_string_left_wrapped(
            dpi, (void*)&lineCh, x, y + 3, _chatWidth - 10, STR_STRING, TEXT_COLOUR_255);
        gfx_set_dirty_blocks(x, y, x + _chatWidth, y + inputLineHeight + 15);

        // TODO: Show caret if the input text has multiple lines
        if (_chatCaretTicks < 15 && gfx_get_string_width(lineBuffer) < (_chatWidth - 10))
        {
            std::memcpy(lineBuffer, _chatCurrentLine, _chatTextInputSession->SelectionStart);
            lineBuffer[_chatTextInputSession->SelectionStart] = 0;
            int32_t caretX = x + gfx_get_string_width(lineBuffer);
            int32_t caretY = y + 14;

            gfx_fill_rect(dpi, caretX, caretY, caretX + 6, caretY + 1, PALETTE_INDEX_56);
        }
    }
}