mirror of
https://github.com/OpenRCT2/OpenRCT2.git
synced 2025-01-22 10:21:57 -05:00
Merge pull request #4146 from AaronVanGeffen/reposition-mouse
Change mouse scroll zooming behaviour to zoom towards the cursor keeping the map position under the cursor consistent. This new behaviour is opt-out.
This commit is contained in:
commit
349684b7ce
10 changed files with 100 additions and 20 deletions
|
@ -4214,6 +4214,8 @@ STR_5902 :Show bounding boxes
|
|||
STR_5903 :Show paint debug window
|
||||
STR_5904 :Reset date
|
||||
STR_5905 :{SMALLFONT}{BLACK}A map generation tool that automatically creates a custom landscape
|
||||
STR_5906 :Zoom to cursor position
|
||||
STR_5907 :{SMALLFONT}{BLACK}When enabled, zooming in will centre around the cursor, as opposed to the screen centre.
|
||||
|
||||
#############
|
||||
# Scenarios #
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
- Feature: Add console command to set scenario initial cash.
|
||||
- Feature: Objects are scanned from the user directory as well as the RCT2 directory.
|
||||
- Feature: Objects directory is scanned recursively.
|
||||
- Feature: Optionally zoom in towards the cursor rather than the screen centre.
|
||||
- Improve: Performance and reliability of loading objects.
|
||||
- Improve: Screenshots are now saved with the name of the park and the current date and time.
|
||||
- Improve: More accurate frame rate calculation
|
||||
|
|
|
@ -227,7 +227,7 @@ config_property_definition _generalDefinitions[] = {
|
|||
{ offsetof(general_configuration, last_save_scenario_directory), "last_scenario_directory", CONFIG_VALUE_TYPE_STRING, { .value_string = NULL }, NULL },
|
||||
{ offsetof(general_configuration, last_save_track_directory), "last_track_directory", CONFIG_VALUE_TYPE_STRING, { .value_string = NULL }, NULL },
|
||||
{ offsetof(general_configuration, window_limit), "window_limit", CONFIG_VALUE_TYPE_UINT8, WINDOW_LIMIT_MAX, NULL },
|
||||
|
||||
{ offsetof(general_configuration, zoom_to_cursor), "zoom_to_cursor", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL },
|
||||
};
|
||||
|
||||
config_property_definition _interfaceDefinitions[] = {
|
||||
|
|
|
@ -198,6 +198,7 @@ typedef struct general_configuration {
|
|||
utf8string last_save_scenario_directory;
|
||||
utf8string last_save_track_directory;
|
||||
uint8 window_limit;
|
||||
uint8 zoom_to_cursor;
|
||||
} general_configuration;
|
||||
|
||||
typedef struct interface_configuration {
|
||||
|
|
|
@ -374,7 +374,7 @@ static void window_close_surplus(int cap, sint8 avoid_classification)
|
|||
/*
|
||||
* Changes the maximum amount of windows allowed
|
||||
*/
|
||||
void window_set_window_limit(int value)
|
||||
void window_set_window_limit(int value)
|
||||
{
|
||||
int prev = gConfigGeneral.window_limit;
|
||||
int val = clamp(value, WINDOW_LIMIT_MIN, WINDOW_LIMIT_MAX);
|
||||
|
@ -1445,6 +1445,49 @@ void window_rotate_camera(rct_window *w, int direction)
|
|||
reset_all_sprite_quadrant_placements();
|
||||
}
|
||||
|
||||
void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y, sint16 *offset_x, sint16 *offset_y)
|
||||
{
|
||||
// Get mouse position to offset against.
|
||||
int mouse_x, mouse_y;
|
||||
platform_get_cursor_position_scaled(&mouse_x, &mouse_y);
|
||||
|
||||
// Compute map coordinate by mouse position.
|
||||
get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, NULL, NULL, NULL);
|
||||
|
||||
// Get viewport coordinates centring around the tile.
|
||||
int base_height = map_element_height(*map_x, *map_y);
|
||||
int dest_x, dest_y;
|
||||
center_2d_coordinates(*map_x, *map_y, base_height, &dest_x, &dest_y, w->viewport);
|
||||
|
||||
// Rebase mouse position onto centre of window, and compensate for zoom level.
|
||||
int rebased_x = ((w->width >> 1) - mouse_x) << w->viewport->zoom,
|
||||
rebased_y = ((w->height >> 1) - mouse_y) << w->viewport->zoom;
|
||||
|
||||
// Compute cursor offset relative to tile.
|
||||
*offset_x = (w->saved_view_x - (dest_x + rebased_x)) << w->viewport->zoom;
|
||||
*offset_y = (w->saved_view_y - (dest_y + rebased_y)) << w->viewport->zoom;
|
||||
}
|
||||
|
||||
void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y, sint16 offset_x, sint16 offset_y)
|
||||
{
|
||||
// Get viewport coordinates centring around the tile.
|
||||
int dest_x, dest_y;
|
||||
int base_height = map_element_height(map_x, map_y);
|
||||
center_2d_coordinates(map_x, map_y, base_height, &dest_x, &dest_y, w->viewport);
|
||||
|
||||
// Get mouse position to offset against.
|
||||
int mouse_x, mouse_y;
|
||||
platform_get_cursor_position_scaled(&mouse_x, &mouse_y);
|
||||
|
||||
// Rebase mouse position onto centre of window, and compensate for zoom level.
|
||||
int rebased_x = ((w->width >> 1) - mouse_x) << w->viewport->zoom,
|
||||
rebased_y = ((w->height >> 1) - mouse_y) << w->viewport->zoom;
|
||||
|
||||
// Apply offset to the viewport.
|
||||
w->saved_view_x = dest_x + rebased_x + (offset_x >> w->viewport->zoom);
|
||||
w->saved_view_y = dest_y + rebased_y + (offset_y >> w->viewport->zoom);
|
||||
}
|
||||
|
||||
void window_zoom_set(rct_window *w, int zoomLevel)
|
||||
{
|
||||
rct_viewport* v = w->viewport;
|
||||
|
@ -1453,12 +1496,18 @@ void window_zoom_set(rct_window *w, int zoomLevel)
|
|||
if (v->zoom == zoomLevel)
|
||||
return;
|
||||
|
||||
// Zooming to cursor? Remember where we're pointing at the moment.
|
||||
sint16 saved_map_x, saved_map_y, offset_x, offset_y;
|
||||
if (gConfigGeneral.zoom_to_cursor) {
|
||||
window_viewport_get_map_coords_by_cursor(w, &saved_map_x, &saved_map_y, &offset_x, &offset_y);
|
||||
}
|
||||
|
||||
// Zoom in
|
||||
while (v->zoom > zoomLevel) {
|
||||
v->zoom--;
|
||||
w->saved_view_x += v->view_width / 4;
|
||||
w->saved_view_y += v->view_height / 4;
|
||||
v->view_width /= 2;
|
||||
v->view_width /= 2;
|
||||
v->view_height /= 2;
|
||||
}
|
||||
|
||||
|
@ -1467,10 +1516,15 @@ void window_zoom_set(rct_window *w, int zoomLevel)
|
|||
v->zoom++;
|
||||
w->saved_view_x -= v->view_width / 2;
|
||||
w->saved_view_y -= v->view_height / 2;
|
||||
v->view_width *= 2;
|
||||
v->view_width *= 2;
|
||||
v->view_height *= 2;
|
||||
}
|
||||
|
||||
// Zooming to cursor? Centre around the tile we were hovering over just now.
|
||||
if (gConfigGeneral.zoom_to_cursor) {
|
||||
window_viewport_centre_tile_around_cursor(w, saved_map_x, saved_map_y, offset_x, offset_y);
|
||||
}
|
||||
|
||||
// HACK: Prevents the redraw from failing when there is
|
||||
// a window on top of the viewport.
|
||||
window_bring_to_front(w);
|
||||
|
|
|
@ -574,6 +574,8 @@ rct_window *window_get_main();
|
|||
void window_scroll_to_viewport(rct_window *w);
|
||||
void window_scroll_to_location(rct_window *w, int x, int y, int z);
|
||||
void window_rotate_camera(rct_window *w, int direction);
|
||||
void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint16 *map_y, sint16 *offset_x, sint16 *offset_y);
|
||||
void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint16 map_y, sint16 offset_x, sint16 offset_y);
|
||||
void window_zoom_set(rct_window *w, int zoomLevel);
|
||||
void window_zoom_in(rct_window *w);
|
||||
void window_zoom_out(rct_window *w);
|
||||
|
|
|
@ -3336,8 +3336,9 @@ enum {
|
|||
STR_DEBUG_PAINT_SHOW_BOUND_BOXES = 5902,
|
||||
STR_DEBUG_DROPDOWN_DEBUG_PAINT = 5903,
|
||||
STR_CHEAT_RESET_DATE = 5904,
|
||||
|
||||
STR_MAP_GENERATOR_TIP = 5905,
|
||||
STR_ZOOM_TO_CURSOR = 5906,
|
||||
STR_ZOOM_TO_CURSOR_TIP = 5907,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
STR_COUNT = 32768
|
||||
|
|
|
@ -166,6 +166,7 @@ bool platform_file_delete(const utf8 *path);
|
|||
void platform_hide_cursor();
|
||||
void platform_show_cursor();
|
||||
void platform_get_cursor_position(int *x, int *y);
|
||||
void platform_get_cursor_position_scaled(int *x, int *y);
|
||||
void platform_set_cursor_position(int x, int y);
|
||||
unsigned int platform_get_ticks();
|
||||
void platform_resolve_user_data_path();
|
||||
|
|
|
@ -783,6 +783,15 @@ void platform_get_cursor_position(int *x, int *y)
|
|||
SDL_GetMouseState(x, y);
|
||||
}
|
||||
|
||||
void platform_get_cursor_position_scaled(int *x, int *y)
|
||||
{
|
||||
platform_get_cursor_position(x, y);
|
||||
|
||||
// Compensate for window scaling.
|
||||
*x = (int) ceilf(*x / gConfigGeneral.window_scale);
|
||||
*y = (int) ceilf(*y / gConfigGeneral.window_scale);
|
||||
}
|
||||
|
||||
void platform_set_cursor_position(int x, int y)
|
||||
{
|
||||
SDL_WarpMouseInWindow(NULL, x, y);
|
||||
|
|
|
@ -129,6 +129,7 @@ enum WINDOW_OPTIONS_WIDGET_IDX {
|
|||
WIDX_SCREEN_EDGE_SCROLLING,
|
||||
WIDX_TRAP_CURSOR,
|
||||
WIDX_INVERT_DRAG,
|
||||
WIDX_ZOOM_TO_CURSOR,
|
||||
WIDX_HOTKEY_DROPDOWN,
|
||||
WIDX_THEMES_GROUP,
|
||||
WIDX_THEMES,
|
||||
|
@ -269,27 +270,28 @@ static rct_widget window_options_audio_widgets[] = {
|
|||
|
||||
static rct_widget window_options_controls_and_interface_widgets[] = {
|
||||
MAIN_OPTIONS_WIDGETS,
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 53, 129, STR_CONTROLS_GROUP, STR_NONE }, // Controls group
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 53, 144, STR_CONTROLS_GROUP, STR_NONE }, // Controls group
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 68, 79, STR_SCREEN_EDGE_SCROLLING, STR_SCREEN_EDGE_SCROLLING_TIP }, // Edge scrolling
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 83, 94, STR_TRAP_MOUSE, STR_TRAP_MOUSE_TIP }, // Trap mouse
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 98, 109, STR_INVERT_RIGHT_MOUSE_DRAG, STR_INVERT_RIGHT_MOUSE_DRAG_TIP }, // Invert right mouse dragging
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 26, 185, 113, 124, STR_HOTKEY, STR_HOTKEY_TIP }, // Set hotkeys buttons
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 113, 124, STR_ZOOM_TO_CURSOR, STR_ZOOM_TO_CURSOR_TIP }, // Zoom to cursor
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 26, 185, 128, 139, STR_HOTKEY, STR_HOTKEY_TIP }, // Set hotkeys buttons
|
||||
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 133, 179, STR_THEMES_GROUP, STR_NONE }, // Toolbar buttons group
|
||||
{ WWT_DROPDOWN, 1, 155, 299, 147, 158, STR_NONE, STR_NONE }, // Themes
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 288, 298, 148, 157, STR_DROPDOWN_GLYPH, STR_CURRENT_THEME_TIP },
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 10, 145, 163, 174, STR_EDIT_THEMES_BUTTON, STR_EDIT_THEMES_BUTTON_TIP }, // Themes button
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 148, 194, STR_THEMES_GROUP, STR_NONE }, // Toolbar buttons group
|
||||
{ WWT_DROPDOWN, 1, 155, 299, 162, 173, STR_NONE, STR_NONE }, // Themes
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 288, 298, 163, 172, STR_DROPDOWN_GLYPH, STR_CURRENT_THEME_TIP },
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 10, 145, 178, 189, STR_EDIT_THEMES_BUTTON, STR_EDIT_THEMES_BUTTON_TIP }, // Themes button
|
||||
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 183, 245, STR_TOOLBAR_BUTTONS_GROUP, STR_NONE }, // Toolbar buttons group
|
||||
{ WWT_CHECKBOX, 2, 10, 145, 214, 225, STR_FINANCES_BUTTON_ON_TOOLBAR, STR_FINANCES_BUTTON_ON_TOOLBAR_TIP }, // Finances
|
||||
{ WWT_CHECKBOX, 2, 10, 145, 229, 240, STR_RESEARCH_BUTTON_ON_TOOLBAR, STR_RESEARCH_BUTTON_ON_TOOLBAR_TIP }, // Research
|
||||
{ WWT_CHECKBOX, 2, 155, 299, 214, 225, STR_CHEATS_BUTTON_ON_TOOLBAR, STR_CHEATS_BUTTON_ON_TOOLBAR_TIP }, // Cheats
|
||||
{ WWT_CHECKBOX, 2, 155, 299, 229, 240, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR_TIP }, // Recent messages
|
||||
{ WWT_GROUPBOX, 1, 5, 304, 198, 260, STR_TOOLBAR_BUTTONS_GROUP, STR_NONE }, // Toolbar buttons group
|
||||
{ WWT_CHECKBOX, 2, 10, 145, 229, 240, STR_FINANCES_BUTTON_ON_TOOLBAR, STR_FINANCES_BUTTON_ON_TOOLBAR_TIP }, // Finances
|
||||
{ WWT_CHECKBOX, 2, 10, 145, 244, 255, STR_RESEARCH_BUTTON_ON_TOOLBAR, STR_RESEARCH_BUTTON_ON_TOOLBAR_TIP }, // Research
|
||||
{ WWT_CHECKBOX, 2, 155, 299, 229, 240, STR_CHEATS_BUTTON_ON_TOOLBAR, STR_CHEATS_BUTTON_ON_TOOLBAR_TIP }, // Cheats
|
||||
{ WWT_CHECKBOX, 2, 155, 299, 244, 255, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR, STR_SHOW_RECENT_MESSAGES_ON_TOOLBAR_TIP }, // Recent messages
|
||||
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 254, 265, STR_SELECT_BY_TRACK_TYPE, STR_SELECT_BY_TRACK_TYPE_TIP }, // Select by track type
|
||||
{ WWT_DROPDOWN, 2, 155, 299, 269, 280, STR_NONE, STR_NONE }, // Scenario select mode
|
||||
{ WWT_DROPDOWN_BUTTON, 2, 288, 298, 270, 279, STR_DROPDOWN_GLYPH, STR_SCENARIO_GROUPING_TIP },
|
||||
{ WWT_CHECKBOX, 2, 18, 299, 284, 295, STR_OPTIONS_SCENARIO_UNLOCKING, STR_SCENARIO_UNLOCKING_TIP }, // Unlocking of scenarios
|
||||
{ WWT_CHECKBOX, 2, 10, 299, 269, 280, STR_SELECT_BY_TRACK_TYPE, STR_SELECT_BY_TRACK_TYPE_TIP }, // Select by track type
|
||||
{ WWT_DROPDOWN, 2, 155, 299, 284, 295, STR_NONE, STR_NONE }, // Scenario select mode
|
||||
{ WWT_DROPDOWN_BUTTON, 2, 288, 298, 285, 294, STR_DROPDOWN_GLYPH, STR_SCENARIO_GROUPING_TIP },
|
||||
{ WWT_CHECKBOX, 2, 18, 299, 299, 310, STR_OPTIONS_SCENARIO_UNLOCKING, STR_SCENARIO_UNLOCKING_TIP }, // Unlocking of scenarios
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
|
@ -491,6 +493,7 @@ static uint32 window_options_page_enabled_widgets[] = {
|
|||
(1 << WIDX_SCREEN_EDGE_SCROLLING) |
|
||||
(1 << WIDX_TRAP_CURSOR) |
|
||||
(1 << WIDX_INVERT_DRAG) |
|
||||
(1 << WIDX_ZOOM_TO_CURSOR) |
|
||||
(1 << WIDX_HOTKEY_DROPDOWN) |
|
||||
(1 << WIDX_TOOLBAR_SHOW_FINANCES) |
|
||||
(1 << WIDX_TOOLBAR_SHOW_RESEARCH) |
|
||||
|
@ -694,6 +697,11 @@ static void window_options_mouseup(rct_window *w, int widgetIndex)
|
|||
SDL_SetWindowGrab(gWindow, gConfigGeneral.trap_cursor ? SDL_TRUE : SDL_FALSE);
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_ZOOM_TO_CURSOR:
|
||||
gConfigGeneral.zoom_to_cursor ^= 1;
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_TOOLBAR_SHOW_FINANCES:
|
||||
gConfigInterface.toolbar_show_finances ^= 1;
|
||||
config_save_default();
|
||||
|
@ -1556,6 +1564,7 @@ static void window_options_invalidate(rct_window *w)
|
|||
widget_set_checkbox_value(w, WIDX_SCREEN_EDGE_SCROLLING, gConfigGeneral.edge_scrolling);
|
||||
widget_set_checkbox_value(w, WIDX_TRAP_CURSOR, gConfigGeneral.trap_cursor);
|
||||
widget_set_checkbox_value(w, WIDX_INVERT_DRAG, gConfigGeneral.invert_viewport_drag);
|
||||
widget_set_checkbox_value(w, WIDX_ZOOM_TO_CURSOR, gConfigGeneral.zoom_to_cursor);
|
||||
widget_set_checkbox_value(w, WIDX_TOOLBAR_SHOW_FINANCES, gConfigInterface.toolbar_show_finances);
|
||||
widget_set_checkbox_value(w, WIDX_TOOLBAR_SHOW_RESEARCH, gConfigInterface.toolbar_show_research);
|
||||
widget_set_checkbox_value(w, WIDX_TOOLBAR_SHOW_CHEATS, gConfigInterface.toolbar_show_cheats);
|
||||
|
|
Loading…
Reference in a new issue