From b3be0969b3dc2277f02c40dfc66adf53e706b962 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Thu, 28 Sep 2023 13:26:22 +0300 Subject: [PATCH 38/38] gtk4: Add full view zoom support With bigger number of zoom levels See osdn #48740 Signed-off-by: Marko Lindqvist --- client/editor.c | 8 +- client/gui-gtk-3.22/gui_main.c | 4 +- client/gui-gtk-3.22/mapctrl.c | 15 +-- client/gui-gtk-3.22/mapview.c | 14 ++- client/gui-gtk-4.0/gui_main.c | 10 +- client/gui-gtk-4.0/mapctrl.c | 17 ++-- client/gui-gtk-4.0/mapview.c | 22 ++++- client/gui-qt/mapctrl.cpp | 15 +-- client/gui-qt/mapview.cpp | 21 +++- client/gui-qt/qtg_cxxside.cpp | 2 + client/gui-qt/qtg_cxxside.h | 2 + client/gui-sdl2/dialogs.c | 3 +- client/gui-sdl2/finddlg.c | 5 +- client/gui-sdl2/gui_main.c | 12 ++- client/gui-sdl2/mapctrl.c | 15 ++- client/gui-sdl2/mapview.c | 10 ++ client/gui-stub/mapview.c | 10 ++ client/gui_cbsetter.c | 2 + client/gui_interface.c | 8 ++ client/gui_interface.h | 2 + client/include/mapview_g.h | 4 +- client/mapctrl_common.c | 58 +++++------ client/mapview_common.c | 170 +++++++++++++++++---------------- client/mapview_common.h | 13 +-- client/packhand.c | 4 +- client/zoom.c | 39 ++++++-- client/zoom.h | 2 + 27 files changed, 310 insertions(+), 177 deletions(-) diff --git a/client/editor.c b/client/editor.c index b869885539..bcc1e7e882 100644 --- a/client/editor.c +++ b/client/editor.c @@ -667,7 +667,7 @@ void editor_mouse_button_press(int canvas_x, int canvas_y, return; } - ptile = canvas_pos_to_tile(canvas_x, canvas_y); + ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (ptile == NULL) { return; } @@ -731,8 +731,8 @@ static void editor_end_selection_rectangle(int canvas_x, int canvas_y) if (editor->selrect_width <= 0 || editor->selrect_height <= 0) { struct tile *ptile; - - ptile = canvas_pos_to_tile(canvas_x, canvas_y); + + ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (ptile && editor->selection_mode == SELECTION_MODE_ADD) { editor_selection_add(ptile); } else if (ptile && editor->selection_mode == SELECTION_MODE_REMOVE) { @@ -872,7 +872,7 @@ void editor_mouse_move(int canvas_x, int canvas_y, int modifiers) } old = editor_get_current_tile(); - ptile = canvas_pos_to_tile(canvas_x, canvas_y); + ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (!ptile) { return; diff --git a/client/gui-gtk-3.22/gui_main.c b/client/gui-gtk-3.22/gui_main.c index 6d053f86fb..62a6d18044 100644 --- a/client/gui-gtk-3.22/gui_main.c +++ b/client/gui-gtk-3.22/gui_main.c @@ -696,7 +696,7 @@ static gboolean mouse_scroll_mapcanvas(GtkWidget *w, GdkEventScroll *ev) return FALSE; }; - set_mapview_scroll_pos(scroll_x, scroll_y); + set_mapview_scroll_pos(scroll_x, scroll_y, mouse_zoom); /* Emulating mouse move now */ if (!gtk_widget_has_focus(map_canvas)) { @@ -712,7 +712,7 @@ static gboolean mouse_scroll_mapcanvas(GtkWidget *w, GdkEventScroll *ev) maybe_activate_keyboardless_goto(cur_x, cur_y); } - control_mouse_cursor(canvas_pos_to_tile(cur_x, cur_y)); + control_mouse_cursor(canvas_pos_to_tile(cur_x, cur_y, mouse_zoom)); return TRUE; } diff --git a/client/gui-gtk-3.22/mapctrl.c b/client/gui-gtk-3.22/mapctrl.c index d1a0b70339..eefb8878a9 100644 --- a/client/gui-gtk-3.22/mapctrl.c +++ b/client/gui-gtk-3.22/mapctrl.c @@ -38,6 +38,7 @@ #include "editor.h" #include "tilespec.h" #include "text.h" +#include "zoom.h" /* client/agents */ #include "cma_core.h" @@ -86,14 +87,14 @@ static void popupinfo_positioning_callback(GtkWidget *w, GtkAllocation *alloc, float x, y; struct tile *ptile; - ptile = canvas_pos_to_tile(mousepos->x, mousepos->y); - if (tile_to_canvas_pos(&x, &y, ptile)) { + ptile = canvas_pos_to_tile(mousepos->x, mousepos->y, map_zoom); + if (tile_to_canvas_pos(&x, &y, map_zoom, ptile)) { gint minx, miny, maxy; gdk_window_get_origin(gtk_widget_get_window(map_canvas), &minx, &miny); maxy = miny + gtk_widget_get_allocated_height(map_canvas); - if (x > mapview.width/2) { + if (x > mapview.width / 2) { /* right part of the map */ x += minx; y += miny + (tileset_tile_height(tileset) - alloc->height)/2; @@ -252,7 +253,7 @@ gboolean butt_down_mapcanvas(GtkWidget *w, GdkEventButton *ev, gpointer data) } gtk_widget_grab_focus(map_canvas); - ptile = canvas_pos_to_tile(ev->x, ev->y); + ptile = canvas_pos_to_tile(ev->x, ev->y, mouse_zoom); pcity = ptile ? tile_city(ptile) : NULL; switch (ev->button) { @@ -423,7 +424,7 @@ gboolean move_mapcanvas(GtkWidget *w, GdkEventMotion *ev, gpointer data) if (keyboardless_goto_button_down && hover_state == HOVER_NONE) { maybe_activate_keyboardless_goto(ev->x, ev->y); } - control_mouse_cursor(canvas_pos_to_tile(ev->x, ev->y)); + control_mouse_cursor(canvas_pos_to_tile(ev->x, ev->y, mouse_zoom)); return TRUE; } @@ -446,7 +447,8 @@ gboolean leave_mapcanvas(GtkWidget *widget, GdkEventCrossing *event) if (!map_is_empty() && event->x >= 0 && event->y >= 0 && event->x < mapview.width && event->y < mapview.height) { - control_mouse_cursor(canvas_pos_to_tile(event->x, event->y)); + control_mouse_cursor(canvas_pos_to_tile(event->x, event->y, + mouse_zoom)); } else { update_mouse_cursor(CURSOR_DEFAULT); } @@ -461,6 +463,7 @@ gboolean leave_mapcanvas(GtkWidget *widget, GdkEventCrossing *event) gboolean move_overviewcanvas(GtkWidget *w, GdkEventMotion *ev, gpointer data) { overview_update_line(ev->x, ev->y); + return TRUE; } diff --git a/client/gui-gtk-3.22/mapview.c b/client/gui-gtk-3.22/mapview.c index 59425828f2..09869f81b9 100644 --- a/client/gui-gtk-3.22/mapview.c +++ b/client/gui-gtk-3.22/mapview.c @@ -407,6 +407,16 @@ gboolean map_canvas_configure(GtkWidget *w, GdkEventConfigure *ev, return TRUE; } +/**********************************************************************//** + Refresh map canvas size information +**************************************************************************/ +void map_canvas_size_refresh(void) +{ + /* Needed only with full screen zoom mode. + * Not needed, nor implemented, in this client. */ + fc_assert(FALSE); +} + /**********************************************************************//** Redraw map canvas. **************************************************************************/ @@ -633,7 +643,7 @@ void put_cross_overlay_tile(struct tile *ptile) { float canvas_x, canvas_y; - if (tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) { + if (tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile)) { pixmap_put_overlay_tile(gtk_widget_get_window(map_canvas), map_zoom, canvas_x / map_zoom, canvas_y / map_zoom, get_attention_crosshair_sprite(tileset)); @@ -723,7 +733,7 @@ void scrollbar_jump_callback(GtkAdjustment *adj, gpointer hscrollbar) scroll_y = gtk_adjustment_get_value(adj); } - set_mapview_scroll_pos(scroll_x, scroll_y); + set_mapview_scroll_pos(scroll_x, scroll_y, mouse_zoom); } /**********************************************************************//** diff --git a/client/gui-gtk-4.0/gui_main.c b/client/gui-gtk-4.0/gui_main.c index 9aceb95c64..63b98ef7db 100644 --- a/client/gui-gtk-4.0/gui_main.c +++ b/client/gui-gtk-4.0/gui_main.c @@ -220,6 +220,10 @@ static void free_unit_table(void); static void adjust_default_options(void); +static float zoom_steps_custom[] = { + -1.0, 0.13, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0, -1.0 +}; + /**********************************************************************//** Callback for freelog **************************************************************************/ @@ -648,7 +652,7 @@ static gboolean mouse_scroll_mapcanvas(GtkEventControllerScroll *controller, scroll_y += ystep * dy; scroll_x += xstep * dx; - set_mapview_scroll_pos(scroll_x, scroll_y); + set_mapview_scroll_pos(scroll_x, scroll_y, mouse_zoom); /* Emulating mouse move now */ if (!gtk_widget_has_focus(map_canvas)) { @@ -669,7 +673,7 @@ static gboolean mouse_scroll_mapcanvas(GtkEventControllerScroll *controller, maybe_activate_keyboardless_goto(cur_x, cur_y); } - control_mouse_cursor(canvas_pos_to_tile(cur_x, cur_y)); + control_mouse_cursor(canvas_pos_to_tile(cur_x, cur_y, mouse_zoom)); return TRUE; } @@ -1662,6 +1666,8 @@ void ui_init(void) log_set_callback(log_callback_utf8); set_g_log_callbacks(); set_frame_by_frame_animation(); + zoom_phase_set(FALSE); + zoom_set_steps(zoom_steps_custom); } /**********************************************************************//** diff --git a/client/gui-gtk-4.0/mapctrl.c b/client/gui-gtk-4.0/mapctrl.c index 4aa59bf385..99692739b2 100644 --- a/client/gui-gtk-4.0/mapctrl.c +++ b/client/gui-gtk-4.0/mapctrl.c @@ -38,6 +38,7 @@ #include "editor.h" #include "tilespec.h" #include "text.h" +#include "zoom.h" /* client/agents */ #include "cma_core.h" @@ -73,10 +74,10 @@ static void popit(struct tile *ptile) GtkAllocation alloc; float canvas_x, canvas_y; - tile_to_canvas_pos(&canvas_x, &canvas_y, ptile); + tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile); gtk_widget_get_allocation(map_canvas, &alloc); - rect.x = canvas_x - alloc.x; - rect.y = canvas_y - alloc.y; + rect.x = (canvas_x * mouse_zoom / map_zoom) - alloc.x; + rect.y = (canvas_y * mouse_zoom / map_zoom) - alloc.y; rect.width = tileset_full_tile_width(tileset); rect.height = tileset_tile_height(tileset); @@ -218,7 +219,7 @@ gboolean left_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, } gtk_widget_grab_focus(map_canvas); - ptile = canvas_pos_to_tile(x, y); + ptile = canvas_pos_to_tile(x, y, mouse_zoom); state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture)); @@ -274,7 +275,7 @@ gboolean right_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, } gtk_widget_grab_focus(map_canvas); - ptile = canvas_pos_to_tile(x, y); + ptile = canvas_pos_to_tile(x, y, mouse_zoom); pcity = ptile ? tile_city(ptile) : NULL; state = gtk_event_controller_get_current_event_state( @@ -315,7 +316,7 @@ gboolean right_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, } if (hover_state == HOVER_NONE) { anchor_selection_rectangle(x, y); - rbutton_down = TRUE; /* causes rectangle updates */ + rbutton_down = TRUE; /* Causes rectangle updates */ } } @@ -342,7 +343,7 @@ gboolean middle_butt_down_mapcanvas(GtkGestureClick *gesture, int n_press, } gtk_widget_grab_focus(map_canvas); - ptile = canvas_pos_to_tile(x, y); + ptile = canvas_pos_to_tile(x, y, mouse_zoom); state = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture)); @@ -439,7 +440,7 @@ gboolean move_mapcanvas(GtkEventControllerMotion *controller, if (keyboardless_goto_button_down && hover_state == HOVER_NONE) { maybe_activate_keyboardless_goto(x, y); } - control_mouse_cursor(canvas_pos_to_tile(x, y)); + control_mouse_cursor(canvas_pos_to_tile(x, y, mouse_zoom)); return TRUE; } diff --git a/client/gui-gtk-4.0/mapview.c b/client/gui-gtk-4.0/mapview.c index e407ef6d0b..7e0d0037cd 100644 --- a/client/gui-gtk-4.0/mapview.c +++ b/client/gui-gtk-4.0/mapview.c @@ -66,6 +66,9 @@ static GtkAdjustment *map_hadj, *map_vadj; static int cursor_timer_id = 0, cursor_type = -1, cursor_frame = 0; static int mapview_frozen_level = 0; +static int mc_actual_width = -1; +static int mc_actual_height = -1; + /**********************************************************************//** If do_restore is FALSE it will invert the turn done button style. If called regularly from a timer this will give a blinking turn done @@ -403,7 +406,19 @@ bool mapview_is_frozen(void) void map_canvas_resize(GtkWidget *w, int width, int height, gpointer data) { - map_canvas_resized(width, height); + mc_actual_width = width; + mc_actual_height = height; + + map_canvas_size_refresh(); +} + +/**********************************************************************//** + Refresh map canvas size information +**************************************************************************/ +void map_canvas_size_refresh(void) +{ + map_canvas_resized(mc_actual_width / mouse_zoom, + mc_actual_height / mouse_zoom); } /**********************************************************************//** @@ -419,6 +434,7 @@ void map_canvas_draw(GtkDrawingArea *w, cairo_t *cr, * to screen). Then we draw all changed areas to the screen. */ update_animation(); unqueue_mapview_updates(FALSE); + cairo_scale(cr, mouse_zoom, mouse_zoom); cairo_set_source_surface(cr, mapview.store->surface, 0, 0); cairo_paint(cr); } @@ -627,7 +643,7 @@ void put_cross_overlay_tile(struct tile *ptile) { float canvas_x, canvas_y; - if (tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) { + if (tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile)) { GtkNative *nat = gtk_widget_get_native(map_canvas); pixmap_put_overlay_tile(gtk_native_get_surface(nat), map_zoom, @@ -721,7 +737,7 @@ void scrollbar_jump_callback(GtkAdjustment *adj, gpointer hscrollbar) scroll_y = gtk_adjustment_get_value(adj); } - set_mapview_scroll_pos(scroll_x, scroll_y); + set_mapview_scroll_pos(scroll_x, scroll_y, mouse_zoom); } /**********************************************************************//** diff --git a/client/gui-qt/mapctrl.cpp b/client/gui-qt/mapctrl.cpp index b9ff0af1ac..697a084d7b 100644 --- a/client/gui-qt/mapctrl.cpp +++ b/client/gui-qt/mapctrl.cpp @@ -33,6 +33,7 @@ #include "themes_common.h" #include "tile.h" #include "unit.h" +#include "zoom.h" // gui-qt #include "citydlg.h" @@ -225,7 +226,7 @@ void map_view::shortcut_pressed(int key) bt = QApplication::mouseButtons(); pos = mapFromGlobal(QCursor::pos()); - ctile = canvas_pos_to_tile(pos.x(), pos.y()); + ctile = canvas_pos_to_tile(pos.x(), pos.y(), map_zoom); pcity = ctile ? tile_city(ctile) : nullptr; if (pcity && pcity->owner != client_player()) { @@ -236,7 +237,7 @@ void map_view::shortcut_pressed(int key) sc = fc_shortcuts::sc()->get_shortcut(SC_SELECT_BUTTON); if (bt == sc->mouse && md == sc->mod && gui()->trade_gen.hover_city) { - ctile = canvas_pos_to_tile(pos.x(), pos.y()); + ctile = canvas_pos_to_tile(pos.x(), pos.y(), map_zoom); gui()->trade_gen.add_tile(ctile); gui()->mapview_wdg->repaint(); @@ -249,7 +250,7 @@ void map_view::shortcut_pressed(int key) char text[1024]; struct city *rcity; - ctile = canvas_pos_to_tile(pos.x(), pos.y()); + ctile = canvas_pos_to_tile(pos.x(), pos.y(), map_zoom); rcity = tile_city(ctile); if (rcity) { gui()->rallies.hover_tile = true; @@ -292,7 +293,7 @@ void map_view::shortcut_pressed(int key) } if (bt == Qt::LeftButton && gui()->menu_bar->delayed_order) { - ctile = canvas_pos_to_tile(pos.x(), pos.y()); + ctile = canvas_pos_to_tile(pos.x(), pos.y(), map_zoom); gui()->menu_bar->set_tile_for_order(ctile); clear_hover_state(); exit_goto_state(); @@ -307,7 +308,7 @@ void map_view::shortcut_pressed(int key) if (bt == Qt::LeftButton && gui()->menu_bar->quick_airlifting) { struct city *acity; - ctile = canvas_pos_to_tile(pos.x(), pos.y()); + ctile = canvas_pos_to_tile(pos.x(), pos.y(), map_zoom); acity = tile_city(ctile); if (acity) { multiairlift(acity, gui()->menu_bar->airlift_type_id); @@ -536,11 +537,13 @@ void map_view::mouseReleaseEvent(QMouseEvent *event) void map_view::mouseMoveEvent(QMouseEvent *event) { update_line(event->pos().x(), event->pos().y()); + if (keyboardless_goto_button_down && hover_state == HOVER_NONE) { maybe_activate_keyboardless_goto(event->pos().x(), event->pos().y()); } control_mouse_cursor(canvas_pos_to_tile(event->pos().x(), - event->pos().y())); + event->pos().y(), + map_zoom)); } /**********************************************************************//** diff --git a/client/gui-qt/mapview.cpp b/client/gui-qt/mapview.cpp index 2c087918ac..5f2300b5a6 100644 --- a/client/gui-qt/mapview.cpp +++ b/client/gui-qt/mapview.cpp @@ -41,6 +41,7 @@ #include "sprite.h" #include "repodlgs.h" #include "text.h" +#include "zoom.h" // gui-qt #include "colors.h" @@ -100,8 +101,8 @@ void draw_calculated_trade_routes(QPainter *painter) TILE_XY(qgilles.t2)); map_to_gui_vector(tileset, 1.0, &w, &h, dx, dy); - tile_to_canvas_pos(&x1, &y1, qgilles.t1); - tile_to_canvas_pos(&x2, &y2, qgilles.t2); + tile_to_canvas_pos(&x1, &y1, map_zoom, qgilles.t1); + tile_to_canvas_pos(&x2, &y2, map_zoom, qgilles.t2); /* Dont draw if route was already established */ if (tile_city(qgilles.t1) && tile_city(qgilles.t2) @@ -136,7 +137,7 @@ void draw_calculated_trade_routes(QPainter *painter) foreach (pcity, gui()->trade_gen.virtual_cities) { float canvas_x, canvas_y; if (pcity->tile != nullptr - && tile_to_canvas_pos(&canvas_x, &canvas_y, pcity->tile)) { + && tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, pcity->tile)) { painter->drawPixmap(static_cast(canvas_x), static_cast(canvas_y), *get_attention_crosshair_sprite(tileset)->pm); @@ -1236,7 +1237,7 @@ void put_cross_overlay_tile(struct tile *ptile) { float canvas_x, canvas_y; - if (tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) { + if (tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile)) { pixmap_put_overlay_tile(canvas_x, canvas_y, get_attention_crosshair_sprite(tileset)); } @@ -1373,7 +1374,7 @@ void info_tile::calc_size() setFixedHeight(str_list.count() * (fm.height() + 5)); setFixedWidth(w + 10); - if (tile_to_canvas_pos(&x, &y, itile)) { + if (tile_to_canvas_pos(&x, &y, map_zoom, itile)) { int fin_x; int fin_y; int wh = height(); @@ -1445,3 +1446,13 @@ void qtg_start_turn() last_center_player_city = 0; last_center_enemy_city = 0; } + +/**********************************************************************//** + Refresh map canvas size information +**************************************************************************/ +void qtg_map_canvas_size_refresh(void) +{ + /* Needed only with full screen zoom mode. + * Not needed, nor implemented, in this client. */ + fc_assert(false); +} diff --git a/client/gui-qt/qtg_cxxside.cpp b/client/gui-qt/qtg_cxxside.cpp index 62518a0193..8c65ffbb3c 100644 --- a/client/gui-qt/qtg_cxxside.cpp +++ b/client/gui-qt/qtg_cxxside.cpp @@ -68,6 +68,8 @@ void setup_gui_funcs() funcs->get_text_size = qtg_get_text_size; funcs->canvas_put_text = qtg_canvas_put_text; + funcs->map_canvas_size_refresh = qtg_map_canvas_size_refresh; + funcs->set_rulesets = qtg_set_rulesets; funcs->options_extra_init = qtg_options_extra_init; funcs->server_connect = qtg_server_connect; diff --git a/client/gui-qt/qtg_cxxside.h b/client/gui-qt/qtg_cxxside.h index c4f73e1f95..9daaa4f723 100644 --- a/client/gui-qt/qtg_cxxside.h +++ b/client/gui-qt/qtg_cxxside.h @@ -93,6 +93,8 @@ void qtg_canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y, enum client_font font, struct color *pcolor, const char *text); +void qtg_map_canvas_size_refresh(void); + void qtg_set_rulesets(int num_rulesets, char **rulesets); void qtg_options_extra_init(); void qtg_server_connect(); diff --git a/client/gui-sdl2/dialogs.c b/client/gui-sdl2/dialogs.c index 81dfd186a1..5d90cdbca2 100644 --- a/client/gui-sdl2/dialogs.c +++ b/client/gui-sdl2/dialogs.c @@ -51,6 +51,7 @@ #include "helpdata.h" /* for helptext_nation() */ #include "packhand.h" #include "text.h" +#include "zoom.h" /* gui-sdl2 */ #include "chatline.h" @@ -111,7 +112,7 @@ void put_window_near_map_tile(struct widget *pwindow, float canvas_x, canvas_y; int window_x = 0, window_y = 0; - if (tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) { + if (tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile)) { if (canvas_x + tileset_tile_width(tileset) + window_width >= main_window_width()) { if (canvas_x - window_width < 0) { window_x = (main_window_width() - window_width) / 2; diff --git a/client/gui-sdl2/finddlg.c b/client/gui-sdl2/finddlg.c index 8103a0498e..42103c0d3d 100644 --- a/client/gui-sdl2/finddlg.c +++ b/client/gui-sdl2/finddlg.c @@ -31,6 +31,9 @@ /* common */ #include "game.h" +/* client */ +#include "zoom.h" + /* gui-sdl2 */ #include "colors.h" #include "graphics.h" @@ -142,7 +145,7 @@ void popup_find_dialog(void) return; } - original = canvas_pos_to_tile(main_data.map->w / 2, main_data.map->h / 2); + original = canvas_pos_to_tile(main_data.map->w / 2, main_data.map->h / 2, map_zoom); find_city_dlg = fc_calloc(1, sizeof(struct advanced_dialog)); diff --git a/client/gui-sdl2/gui_main.c b/client/gui-sdl2/gui_main.c index 9249e37ce0..6448372717 100644 --- a/client/gui-sdl2/gui_main.c +++ b/client/gui-sdl2/gui_main.c @@ -59,6 +59,7 @@ #include "editgui_g.h" #include "tilespec.h" #include "update_queue.h" +#include "zoom.h" /* gui-sdl2 */ #include "chatline.h" @@ -336,7 +337,7 @@ static Uint16 main_finger_down_handler(SDL_TouchFingerEvent *touch_event, finger_behavior.finger_down_ticks = SDL_GetTicks(); finger_behavior.event = *touch_event; finger_behavior.hold_state = MB_HOLD_SHORT; - finger_behavior.ptile = canvas_pos_to_tile(x, y); + finger_behavior.ptile = canvas_pos_to_tile(x, y, mouse_zoom); } } return ID_ERROR; @@ -390,7 +391,8 @@ static Uint16 main_mouse_button_down_handler(SDL_MouseButtonEvent *button_event, button_behavior.button_down_ticks = SDL_GetTicks(); *button_behavior.event = *button_event; button_behavior.hold_state = MB_HOLD_SHORT; - button_behavior.ptile = canvas_pos_to_tile(button_event->x, button_event->y); + button_behavior.ptile = canvas_pos_to_tile(button_event->x, button_event->y, + mouse_zoom); } #ifdef UNDER_CE } @@ -438,7 +440,8 @@ static Uint16 main_mouse_motion_handler(SDL_MouseMotionEvent *motion_event, /* stop evaluating button hold time when moving to another tile in medium * hold state or above */ if (button_behavior.counting && (button_behavior.hold_state >= MB_HOLD_MEDIUM)) { - ptile = canvas_pos_to_tile(motion_event->x, motion_event->y); + ptile = canvas_pos_to_tile(motion_event->x, motion_event->y, + mouse_zoom); if (tile_index(ptile) != tile_index(button_behavior.ptile)) { button_behavior.counting = FALSE; } @@ -465,7 +468,8 @@ static Uint16 main_mouse_motion_handler(SDL_MouseMotionEvent *motion_event, if (selected_widget) { unselect_widget_action(); } else { - control_mouse_cursor(canvas_pos_to_tile(motion_event->x, motion_event->y)); + control_mouse_cursor(canvas_pos_to_tile(motion_event->x, motion_event->y, + mouse_zoom)); } } diff --git a/client/gui-sdl2/mapctrl.c b/client/gui-sdl2/mapctrl.c index 67457727ef..53c2b15ed0 100644 --- a/client/gui-sdl2/mapctrl.c +++ b/client/gui-sdl2/mapctrl.c @@ -43,6 +43,7 @@ #include "climisc.h" #include "overview_common.h" #include "update_queue.h" +#include "zoom.h" /* client/gui-sdl2 */ #include "citydlg.h" @@ -2302,7 +2303,8 @@ void button_down_on_map(struct mouse_button_behavior *button_behavior) update_mouse_cursor(CURSOR_DEFAULT); /* popup context menu */ if ((ptile = canvas_pos_to_tile((int) button_behavior->event->x, - (int) button_behavior->event->y))) { + (int) button_behavior->event->y, + mouse_zoom))) { popup_advanced_terrain_dialog(ptile, button_behavior->event->x, button_behavior->event->y); } @@ -2329,7 +2331,8 @@ void button_down_on_map(struct mouse_button_behavior *button_behavior) case MB_HOLD_MEDIUM: /* popup context menu */ if ((ptile = canvas_pos_to_tile((int) button_behavior->event->x, - (int) button_behavior->event->y))) { + (int) button_behavior->event->y, + mouse_zoom))) { popup_advanced_terrain_dialog(ptile, button_behavior->event->x, button_behavior->event->y); } @@ -2361,7 +2364,8 @@ void button_up_on_map(struct mouse_button_behavior *button_behavior) case MB_HOLD_SHORT: if (LSHIFT || LALT || LCTRL) { if ((ptile = canvas_pos_to_tile((int) button_behavior->event->x, - (int) button_behavior->event->y))) { + (int) button_behavior->event->y, + mouse_zoom))) { if (LSHIFT) { popup_advanced_terrain_dialog(ptile, button_behavior->event->x, button_behavior->event->y); @@ -2409,9 +2413,10 @@ void button_up_on_map(struct mouse_button_behavior *button_behavior) case MB_HOLD_LONG: /* break;*/ default: - /* popup context menu */ + /* Popup context menu */ if ((ptile = canvas_pos_to_tile((int) button_behavior->event->x, - (int) button_behavior->event->y))) { + (int) button_behavior->event->y, + mouse_zoom))) { popup_advanced_terrain_dialog(ptile, button_behavior->event->x, button_behavior->event->y); } diff --git a/client/gui-sdl2/mapview.c b/client/gui-sdl2/mapview.c index 017a149924..dba7897dc0 100644 --- a/client/gui-sdl2/mapview.c +++ b/client/gui-sdl2/mapview.c @@ -1238,3 +1238,13 @@ void update_overview_scroll_window_pos(int x, int y) **************************************************************************/ void start_turn(void) {} + +/**********************************************************************//** + Refresh map canvas size information +**************************************************************************/ +void map_canvas_size_refresh(void) +{ + /* Needed only with full screen zoom mode. + * Not needed, nor implemented, in this client. */ + fc_assert(FALSE); +} diff --git a/client/gui-stub/mapview.c b/client/gui-stub/mapview.c index 48dd903e0b..61767554d1 100644 --- a/client/gui-stub/mapview.c +++ b/client/gui-stub/mapview.c @@ -217,6 +217,16 @@ void draw_selection_rectangle(int canvas_x, int canvas_y, int w, int h) /* PORTME */ } +/**********************************************************************//** + Refresh map canvas size information +**************************************************************************/ +void gui_map_canvas_size_refresh(void) +{ + /* Needed only with full screen zoom mode. + * Not needed, nor implemented, in this client. */ + fc_assert(FALSE); +} + /************************************************************************//** This function is called when the tileset is changed. ****************************************************************************/ diff --git a/client/gui_cbsetter.c b/client/gui_cbsetter.c index a7eed4c38e..5837e5867c 100644 --- a/client/gui_cbsetter.c +++ b/client/gui_cbsetter.c @@ -78,6 +78,8 @@ void setup_gui_funcs(void) funcs->get_text_size = gui_get_text_size; funcs->canvas_put_text = gui_canvas_put_text; + funcs->map_canvas_size_refresh = gui_map_canvas_size_refresh; + funcs->set_rulesets = gui_set_rulesets; funcs->options_extra_init = gui_options_extra_init; funcs->server_connect = gui_server_connect; diff --git a/client/gui_interface.c b/client/gui_interface.c index fcc077b56a..773a4559f0 100644 --- a/client/gui_interface.c +++ b/client/gui_interface.c @@ -330,6 +330,14 @@ void canvas_put_text(struct canvas *pcanvas, int canvas_x, int canvas_y, funcs.canvas_put_text(pcanvas, canvas_x, canvas_y, font, pcolor, text); } +/**********************************************************************//** + Call map_canvas_size_refresh callback +**************************************************************************/ +void map_canvas_size_refresh(void) +{ + funcs.map_canvas_size_refresh(); +} + /**********************************************************************//** Call set_rulesets callback **************************************************************************/ diff --git a/client/gui_interface.h b/client/gui_interface.h index e1e58454e1..76ce99695c 100644 --- a/client/gui_interface.h +++ b/client/gui_interface.h @@ -97,6 +97,8 @@ struct gui_funcs { enum client_font font, struct color *pcolor, const char *text); + void (*map_canvas_size_refresh)(void); + void (*set_rulesets)(int num_rulesets, char **rulesets); void (*options_extra_init)(void); void (*server_connect)(void); diff --git a/client/include/mapview_g.h b/client/include/mapview_g.h index 1a9c8508d8..98f4c8a709 100644 --- a/client/include/mapview_g.h +++ b/client/include/mapview_g.h @@ -53,10 +53,12 @@ GUI_FUNC_PROTO(void, gui_flush, void) GUI_FUNC_PROTO(void, update_map_canvas_scrollbars, void) GUI_FUNC_PROTO(void, update_map_canvas_scrollbars_size, void) +GUI_FUNC_PROTO(void, map_canvas_size_refresh, void) + GUI_FUNC_PROTO(void, put_cross_overlay_tile, struct tile *ptile) GUI_FUNC_PROTO(void, draw_selection_rectangle, int canvas_x, int canvas_y, int w, int h) GUI_FUNC_PROTO(void, tileset_changed, void) -#endif /* FC__MAPVIEW_G_H */ +#endif /* FC__MAPVIEW_G_H */ diff --git a/client/mapctrl_common.c b/client/mapctrl_common.c index 545e9d1ebf..284d301b0d 100644 --- a/client/mapctrl_common.c +++ b/client/mapctrl_common.c @@ -44,6 +44,7 @@ #include "options.h" #include "overview_common.h" #include "tilespec.h" +#include "zoom.h" /* Selection Rectangle */ static float rec_anchor_x, rec_anchor_y; /* canvas coordinates for anchor */ @@ -79,15 +80,16 @@ static void define_tiles_within_rectangle(bool append); /**********************************************************************//** Called when Right Mouse Button is depressed. Record the canvas - coordinates of the center of the tile, which may be unreal. This - anchor is not the drawing start point, but is used to calculate + coordinates of the center of the tile, which may be unreal. + This anchor is not the drawing start point, but is used to calculate width, height. Also record the current mapview centering. **************************************************************************/ void anchor_selection_rectangle(int canvas_x, int canvas_y) { - struct tile *ptile = canvas_pos_to_nearest_tile(canvas_x, canvas_y); + struct tile *ptile = canvas_pos_to_nearest_tile(canvas_x, canvas_y, + mouse_zoom); - tile_to_canvas_pos(&rec_anchor_x, &rec_anchor_y, ptile); + tile_to_canvas_pos(&rec_anchor_x, &rec_anchor_y, map_zoom, ptile); rec_anchor_x += tileset_tile_width(tileset) / 2; rec_anchor_y += tileset_tile_height(tileset) / 2; /* FIXME: This may be off-by-one. */ @@ -98,7 +100,7 @@ void anchor_selection_rectangle(int canvas_x, int canvas_y) /**********************************************************************//** Iterate over the pixel boundaries of the rectangle and pick the tiles whose center falls within. Axis pixel incrementation is half tile size to - accomodate tilesets with varying tile shapes and proportions of X/Y. + accomodate tilesets with varying tile shapes and proportions of X / Y. These operations are performed on the tiles: - Make tiles that contain owned cities hilited @@ -141,7 +143,7 @@ static void define_tiles_within_rectangle(bool append) continue; } - ptile = canvas_pos_to_tile(x, y); + ptile = canvas_pos_to_tile(x, y, map_zoom); if (!ptile) { continue; } @@ -149,7 +151,7 @@ static void define_tiles_within_rectangle(bool append) /* "Half-tile" indentation must match, or we'll process * some tiles twice in the case of rectangular shape tiles. */ - tile_to_canvas_pos(&x2, &y2, ptile); + tile_to_canvas_pos(&x2, &y2, map_zoom, ptile); if ((yy % 2) != 0 && ((rec_corner_x % W) ^ abs((int)x2 % W)) != 0) { continue; @@ -198,14 +200,14 @@ static void define_tiles_within_rectangle(bool append) **************************************************************************/ void update_selection_rectangle(float canvas_x, float canvas_y) { - const int W = tileset_tile_width(tileset), half_W = W / 2; - const int H = tileset_tile_height(tileset), half_H = H / 2; + const int W = tileset_tile_width(tileset), half_W = W / 2; + const int H = tileset_tile_height(tileset), half_H = H / 2; static struct tile *rec_tile = NULL; int diff_x, diff_y; struct tile *center_tile; struct tile *ptile; - ptile = canvas_pos_to_nearest_tile(canvas_x, canvas_y); + ptile = canvas_pos_to_nearest_tile(canvas_x, canvas_y, mouse_zoom); /* Did mouse pointer move beyond the current tile's * boundaries? Avoid macros; tile may be unreal! @@ -218,9 +220,8 @@ void update_selection_rectangle(float canvas_x, float canvas_y) /* Clear previous rectangle. */ draw_selection_rectangle(rec_corner_x, rec_corner_y, rec_w, rec_h); - /* Fix canvas coords to the center of the tile. - */ - tile_to_canvas_pos(&canvas_x, &canvas_y, ptile); + /* Fix canvas coords to the center of the tile. */ + tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile); canvas_x += half_W; canvas_y += half_H; @@ -358,7 +359,7 @@ void toggle_tile_hilite(struct tile *ptile) **************************************************************************/ void key_city_overlay(int canvas_x, int canvas_y) { - struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y); + struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (can_client_change_view() && ptile) { struct unit *punit; @@ -482,7 +483,7 @@ void upgrade_canvas_clipboard(void) **************************************************************************/ void release_goto_button(int canvas_x, int canvas_y) { - struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y); + struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (keyboardless_goto_active && (hover_state == HOVER_GOTO || hover_state == HOVER_GOTO_SEL_TGT) @@ -497,12 +498,12 @@ void release_goto_button(int canvas_x, int canvas_y) } /**********************************************************************//** - The goto hover state is only activated when the mouse pointer moves - beyond the tile where the button was depressed, to avoid mouse typos. + The goto hover state is only activated when the mouse pointer moves + beyond the tile where the button was depressed, to avoid mouse typos. **************************************************************************/ void maybe_activate_keyboardless_goto(int canvas_x, int canvas_y) { - struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y); + struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (ptile && get_num_units_in_focus() > 0 && !same_pos(keyboardless_goto_start_tile, ptile) @@ -542,7 +543,7 @@ bool can_end_turn(void) } /**********************************************************************//** - Scroll the mapview half a screen in the given direction. This is a GUI + Scroll the mapview half a screen in the given direction. This is a GUI direction; i.e., DIR8_NORTH is "up" on the mapview. **************************************************************************/ void scroll_mapview(enum direction8 gui_dir) @@ -555,18 +556,18 @@ void scroll_mapview(enum direction8 gui_dir) gui_x += DIR_DX[gui_dir] * mapview.width / 2; gui_y += DIR_DY[gui_dir] * mapview.height / 2; - set_mapview_origin(gui_x, gui_y); + set_mapview_origin(gui_x, gui_y, map_zoom); } /**********************************************************************//** Do some appropriate action when the "main" mouse button (usually - left-click) is pressed. For more sophisticated user control use (or - write) a different xxx_button_pressed function. + left-click) is pressed. For more sophisticated user control use + (or write) a different xxx_button_pressed function. **************************************************************************/ void action_button_pressed(int canvas_x, int canvas_y, enum quickselect_type qtype) { - struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y); + struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (can_client_change_view() && ptile) { /* FIXME: Some actions here will need to check can_client_issue_orders. @@ -580,7 +581,7 @@ void action_button_pressed(int canvas_x, int canvas_y, **************************************************************************/ void wakeup_button_pressed(int canvas_x, int canvas_y) { - struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y); + struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (can_client_issue_orders() && ptile) { wakeup_sentried_units(ptile); @@ -592,7 +593,7 @@ void wakeup_button_pressed(int canvas_x, int canvas_y) **************************************************************************/ void adjust_workers_button_pressed(int canvas_x, int canvas_y) { - struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y); + struct tile *ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); if (NULL != ptile && can_client_issue_orders()) { struct city *pcity = find_city_near_tile(ptile); @@ -629,7 +630,8 @@ void adjust_workers_button_pressed(int canvas_x, int canvas_y) void recenter_button_pressed(int canvas_x, int canvas_y) { /* We use the "nearest" tile here so off-map clicks will still work. */ - struct tile *ptile = canvas_pos_to_nearest_tile(canvas_x, canvas_y); + struct tile *ptile = canvas_pos_to_nearest_tile(canvas_x, canvas_y, + mouse_zoom); if (can_client_change_view() && ptile) { center_tile_mapcanvas(ptile); @@ -666,12 +668,12 @@ void update_line(int canvas_x, int canvas_y) case HOVER_GOTO: case HOVER_PATROL: case HOVER_CONNECT: - ptile = canvas_pos_to_tile(canvas_x, canvas_y); + ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); is_valid_goto_draw_line(ptile); break; case HOVER_GOTO_SEL_TGT: - ptile = canvas_pos_to_tile(canvas_x, canvas_y); + ptile = canvas_pos_to_tile(canvas_x, canvas_y, mouse_zoom); punits = get_units_in_focus(); set_hover_state(punits, hover_state, connect_activity, connect_tgt, diff --git a/client/mapview_common.c b/client/mapview_common.c index 59c46311c4..7231e9a911 100644 --- a/client/mapview_common.c +++ b/client/mapview_common.c @@ -80,7 +80,7 @@ const struct tile *center_tile = NULL; struct tile *infratile = NULL; -static void base_canvas_to_map_pos(int *map_x, int *map_y, +static void base_canvas_to_map_pos(float zoom, int *map_x, int *map_y, float canvas_x, float canvas_y); static void show_full_citybar(struct canvas *pcanvas, @@ -240,7 +240,7 @@ static bool movement_animation(struct animation *anim, double time_gone) struct unit *punit = anim->movement.mover; if (punit != NULL) { - tile_to_canvas_pos(&start_x, &start_y, anim->movement.src); + tile_to_canvas_pos(&start_x, &start_y, map_zoom, anim->movement.src); if (tileset_is_isometric(tileset) && tileset_hex_height(tileset) == 0) { start_y -= tileset_tile_height(tileset) / 2 * map_zoom; start_y -= (tileset_unit_height(tileset) - tileset_full_tile_height(tileset)) * map_zoom; @@ -295,7 +295,7 @@ static bool battle_animation(struct animation *anim, double time_gone) time_per_step = timing_sec / anim->battle.steps; step = time_gone / time_per_step; - if (tile_to_canvas_pos(&canvas_x, &canvas_y, anim->battle.loser_tile)) { + if (tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, anim->battle.loser_tile)) { anim->battle.virt_loser->hp = anim->battle.loser_hp_start - (anim->battle.loser_hp_start * step / anim->battle.steps); @@ -312,7 +312,7 @@ static bool battle_animation(struct animation *anim, double time_gone) tileset_tile_height(tileset)); } - if (tile_to_canvas_pos(&canvas_x, &canvas_y, anim->battle.winner_tile)) { + if (tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, anim->battle.winner_tile)) { anim->battle.virt_winner->hp = anim->battle.winner_hp_start - ((anim->battle.winner_hp_start - anim->battle.winner_hp_end) @@ -347,7 +347,7 @@ static bool explosion_animation(struct animation *anim, double time_gone) timing_sec = (double)gui_options.smooth_combat_step_msec * anim->expl.sprite_count / 1000.0; - if (tile_to_canvas_pos(&canvas_x, &canvas_y, anim->expl.tile)) { + if (tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, anim->expl.tile)) { double time_per_frame = timing_sec / anim->expl.sprite_count; int frame = time_gone / time_per_frame; struct sprite *spr; @@ -394,7 +394,7 @@ static bool nuke_animation(struct animation *anim, double time_gone) struct sprite *nuke_spr = get_nuke_explode_sprite(tileset); int w, h; - (void) tile_to_canvas_pos(&canvas_x, &canvas_y, anim->nuke.nuke_tile); + (void) tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, anim->nuke.nuke_tile); get_sprite_dimensions(nuke_spr, &w, &h); canvas_put_sprite_full(mapview.store, @@ -580,26 +580,26 @@ void map_to_gui_vector(const struct tileset *t, float zoom, GUI coordinates are comparable to canvas coordinates but extend in all directions. gui(0,0) == map(0,0). ****************************************************************************/ -static void map_to_gui_pos(const struct tileset *t, +static void map_to_gui_pos(const struct tileset *t, float zoom, float *gui_x, float *gui_y, int map_x, int map_y) { /* Since the GUI origin is the same as the map origin we can just do a * vector conversion. */ - map_to_gui_vector(t, map_zoom, gui_x, gui_y, map_x, map_y); + map_to_gui_vector(t, zoom, gui_x, gui_y, map_x, map_y); } /************************************************************************//** - Translate from gui to map coordinate systems. See map_to_gui_pos(). + Translate from gui to map coordinate systems. See map_to_gui_pos(). - Note that you lose some information in this conversion. If you convert + Note that you lose some information in this conversion. If you convert from a gui position to a map position and back, you will probably not get the same value you started with. ****************************************************************************/ -static void gui_to_map_pos(const struct tileset *t, +static void gui_to_map_pos(const struct tileset *t, float zoom, int *map_x, int *map_y, float gui_x, float gui_y) { - const float W = tileset_tile_width(t) * map_zoom, H = tileset_tile_height(t) * map_zoom; - const float HH = tileset_hex_height(t) * map_zoom, HW = tileset_hex_width(t) * map_zoom; + const float W = tileset_tile_width(t) * zoom, H = tileset_tile_height(t) * zoom; + const float HH = tileset_hex_height(t) * zoom, HW = tileset_hex_width(t) * zoom; if (HH > 0 || HW > 0) { /* To handle hexagonal cases we have to revert to a less elegant method @@ -614,8 +614,6 @@ static void gui_to_map_pos(const struct tileset *t, y = DIVIDE((int)gui_y, (int)H); dx = gui_x - x * W; dy = gui_y - y * H; - fc_assert(dx >= 0 && dx < W); - fc_assert(dy >= 0 && dy < H); /* Now fold so we consider only one-quarter tile. */ xmult = (dx >= W / 2) ? -1 : 1; @@ -684,7 +682,7 @@ static void gui_to_map_pos(const struct tileset *t, The center of a tile is defined as: { - tile_to_canvas_pos(&canvas_x, &canvas_y, ptile); + tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile); canvas_x += tileset_tile_width(tileset) * map_zoom / 2; canvas_y += tileset_tile_height(tileset) * map_zoom / 2; } @@ -694,7 +692,7 @@ static void gui_to_map_pos(const struct tileset *t, Other parts of the code assume tileset_tile_width(tileset) and tileset_tile_height(tileset) to be even numbers. ****************************************************************************/ -bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, +bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, float zoom, const struct tile *ptile) { int center_map_x, center_map_y, dx, dy, tile_x, tile_y; @@ -705,14 +703,14 @@ bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, * of the window. */ /* TODO: Cache the value of this position */ - base_canvas_to_map_pos(¢er_map_x, ¢er_map_y, + base_canvas_to_map_pos(zoom, ¢er_map_x, ¢er_map_y, mapview.width / 2, mapview.height / 2); index_to_map_pos(&tile_x, &tile_y, tile_index(ptile)); base_map_distance_vector(&dx, &dy, center_map_x, center_map_y, tile_x, tile_y); - map_to_gui_pos(tileset, + map_to_gui_pos(tileset, map_zoom, canvas_x, canvas_y, center_map_x + dx, center_map_y + dy); *canvas_x -= mapview.gui_x0; *canvas_y -= mapview.gui_y0; @@ -720,8 +718,8 @@ bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, /* * Finally we clip. * - * This check is tailored to work for both iso-view and classic view. Note - * that (canvas_x, canvas_y) need not be aligned to a tile boundary, and + * This check is tailored to work for both iso-view and classic view. + * Note that (canvas_x, canvas_y) need not be aligned to a tile boundary, and * that the position is at the top-left of the NORMAL (not UNIT) tile. * This checks to see if _any part_ of the tile is present on the backing * store. Even if it's not visible on the canvas, if it's present on the @@ -739,23 +737,24 @@ bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, Finds the map coordinates corresponding to pixel coordinates. The resulting position is unwrapped and may be unreal. ****************************************************************************/ -static void base_canvas_to_map_pos(int *map_x, int *map_y, +static void base_canvas_to_map_pos(float zoom, int *map_x, int *map_y, float canvas_x, float canvas_y) { - gui_to_map_pos(tileset, map_x, map_y, - canvas_x + mapview.gui_x0, - canvas_y + mapview.gui_y0); + gui_to_map_pos(tileset, zoom, map_x, map_y, + canvas_x + mapview.gui_x0 / map_zoom * zoom, + canvas_y + mapview.gui_y0 / map_zoom * zoom); } /************************************************************************//** Finds the tile corresponding to pixel coordinates. Returns that tile, or NULL if the position is off the map. ****************************************************************************/ -struct tile *canvas_pos_to_tile(float canvas_x, float canvas_y) +struct tile *canvas_pos_to_tile(float canvas_x, float canvas_y, + float zoom) { int map_x, map_y; - base_canvas_to_map_pos(&map_x, &map_y, canvas_x, canvas_y); + base_canvas_to_map_pos(zoom, &map_x, &map_y, canvas_x, canvas_y); if (normalize_map_pos(&(wld.map), &map_x, &map_y)) { return map_pos_to_tile(&(wld.map), map_x, map_y); } else { @@ -764,14 +763,15 @@ struct tile *canvas_pos_to_tile(float canvas_x, float canvas_y) } /************************************************************************//** - Finds the tile corresponding to pixel coordinates. Returns that tile, - or the one nearest is the position is off the map. Will never return NULL. + Finds the tile corresponding to pixel coordinates. Returns that tile, + or the one nearest is the position is off the map. Will never return NULL. ****************************************************************************/ -struct tile *canvas_pos_to_nearest_tile(float canvas_x, float canvas_y) +struct tile *canvas_pos_to_nearest_tile(float canvas_x, float canvas_y, + float zoom) { int map_x, map_y; - base_canvas_to_map_pos(&map_x, &map_y, canvas_x, canvas_y); + base_canvas_to_map_pos(zoom, &map_x, &map_y, canvas_x, canvas_y); return nearest_real_tile(&(wld.map), map_x, map_y); } @@ -779,7 +779,7 @@ struct tile *canvas_pos_to_nearest_tile(float canvas_x, float canvas_y) Normalize (wrap) the GUI position. This is equivalent to a map wrapping, but in GUI coordinates so that pixel accuracy is preserved. ****************************************************************************/ -static void normalize_gui_pos(const struct tileset *t, +static void normalize_gui_pos(const struct tileset *t, float zoom, float *gui_x, float *gui_y) { int map_x, map_y, nat_x, nat_y, diff_x, diff_y; @@ -787,8 +787,8 @@ static void normalize_gui_pos(const struct tileset *t, /* Convert the (gui_x, gui_y) into a (map_x, map_y) plus a GUI offset * from this tile. */ - gui_to_map_pos(t, &map_x, &map_y, *gui_x, *gui_y); - map_to_gui_pos(t, &gui_x0, &gui_y0, map_x, map_y); + gui_to_map_pos(t, zoom, &map_x, &map_y, *gui_x, *gui_y); + map_to_gui_pos(t, zoom, &gui_x0, &gui_y0, map_x, map_y); diff_x = *gui_x - gui_x0; diff_y = *gui_y - gui_y0; @@ -806,7 +806,7 @@ static void normalize_gui_pos(const struct tileset *t, /* Now convert the wrapped map position back to a GUI position and add the * offset back on. */ - map_to_gui_pos(t, gui_x, gui_y, map_x, map_y); + map_to_gui_pos(t, zoom, gui_x, gui_y, map_x, map_y); *gui_x += diff_x; *gui_y += diff_y; } @@ -815,7 +815,7 @@ static void normalize_gui_pos(const struct tileset *t, Find the vector with minimum "real" distance between two GUI positions. This corresponds to map_to_distance_vector but works for GUI coordinates. ****************************************************************************/ -static void gui_distance_vector(const struct tileset *t, +static void gui_distance_vector(const struct tileset *t, float zoom, float *gui_dx, float *gui_dy, float gui_x0, float gui_y0, float gui_x1, float gui_y1) @@ -826,18 +826,18 @@ static void gui_distance_vector(const struct tileset *t, int map_dx, map_dy; /* Make sure positions are canonical. Yes, this is the only way. */ - normalize_gui_pos(t, &gui_x0, &gui_y0); - normalize_gui_pos(t, &gui_x1, &gui_y1); + normalize_gui_pos(t, zoom, &gui_x0, &gui_y0); + normalize_gui_pos(t, zoom, &gui_x1, &gui_y1); /* Now we have to find the offset of each GUI position from its tile * origin. This is complicated: it means converting to a map position and * then back to the GUI position to find the tile origin, then subtracting * to get the offset. */ - gui_to_map_pos(t, &map_x0, &map_y0, gui_x0, gui_y0); - gui_to_map_pos(t, &map_x1, &map_y1, gui_x1, gui_y1); + gui_to_map_pos(t, zoom, &map_x0, &map_y0, gui_x0, gui_y0); + gui_to_map_pos(t, zoom, &map_x1, &map_y1, gui_x1, gui_y1); - map_to_gui_pos(t, &gui_x0_base, &gui_y0_base, map_x0, map_y0); - map_to_gui_pos(t, &gui_x1_base, &gui_y1_base, map_x1, map_y1); + map_to_gui_pos(t, zoom, &gui_x0_base, &gui_y0_base, map_x0, map_y0); + map_to_gui_pos(t, zoom, &gui_x1_base, &gui_y1_base, map_x1, map_y1); gui_x0_diff = gui_x0 - gui_x0_base; gui_y0_diff = gui_y0 - gui_y0_base; @@ -847,7 +847,7 @@ static void gui_distance_vector(const struct tileset *t, /* Next we find the map distance vector and convert this into a GUI * vector. */ base_map_distance_vector(&map_dx, &map_dy, map_x0, map_y0, map_x1, map_y1); - map_to_gui_pos(t, gui_dx, gui_dy, map_dx, map_dy); + map_to_gui_pos(t, zoom, gui_dx, gui_dy, map_dx, map_dy); /* Finally we add on the difference in offsets to retain pixel * resolution. */ @@ -859,7 +859,7 @@ static void gui_distance_vector(const struct tileset *t, Move the GUI origin to the given normalized, clipped origin. This may be called many times when sliding the mapview. ****************************************************************************/ -static void base_set_mapview_origin(float gui_x0, float gui_y0) +static void base_set_mapview_origin(float gui_x0, float gui_y0, float zoom) { float old_gui_x0, old_gui_y0; float dx, dy; @@ -867,17 +867,17 @@ static void base_set_mapview_origin(float gui_x0, float gui_y0) int common_x0, common_x1, common_y0, common_y1; int update_x0, update_x1, update_y0, update_y1; - /* Then update everything. This does some tricky math to avoid having - * to do unnecessary redraws in update_map_canvas. This makes for ugly + /* Then update everything. This does some tricky math to avoid having + * to do unnecessary redraws in update_map_canvas(). This makes for ugly * code but speeds up the mapview by a large factor. */ - /* We need to calculate the vector of movement of the mapview. So + /* We need to calculate the vector of movement of the mapview. So * we find the GUI distance vector and then use this to calculate - * the original mapview origin relative to the current position. Thus + * the original mapview origin relative to the current position. Thus * if we move one tile to the left, even if this causes GUI positions * to wrap the distance vector is only one tile. */ - normalize_gui_pos(tileset, &gui_x0, &gui_y0); - gui_distance_vector(tileset, &dx, &dy, + normalize_gui_pos(tileset, zoom, &gui_x0, &gui_y0); + gui_distance_vector(tileset, zoom, &dx, &dy, mapview.gui_x0, mapview.gui_y0, gui_x0, gui_y0); old_gui_x0 = gui_x0 - dx; @@ -959,13 +959,13 @@ static void base_set_mapview_origin(float gui_x0, float gui_y0) Adjust mapview origin values. Returns TRUE iff values are different from current mapview. ****************************************************************************/ -static bool calc_mapview_origin(float *gui_x0, float *gui_y0) +static bool calc_mapview_origin(float *gui_x0, float *gui_y0, float zoom) { float xmin, ymin, xmax, ymax; int xsize, ysize; /* Normalize (wrap) the mapview origin. */ - normalize_gui_pos(tileset, gui_x0, gui_y0); + normalize_gui_pos(tileset, zoom, gui_x0, gui_y0); /* First wrap/clip the position. Wrapping is done in native positions * while clipping is done in scroll (native) positions. */ @@ -989,16 +989,16 @@ static bool calc_mapview_origin(float *gui_x0, float *gui_y0) /************************************************************************//** Change the mapview origin, clip it, and update everything. ****************************************************************************/ -void set_mapview_origin(float gui_x0, float gui_y0) +void set_mapview_origin(float gui_x0, float gui_y0, float zoom) { - if (!calc_mapview_origin(&gui_x0, &gui_y0)) { + if (!calc_mapview_origin(&gui_x0, &gui_y0, zoom)) { return; } if (can_slide && gui_options.smooth_center_slide_msec > 0) { if (frame_by_frame_animation) { /* TODO: Implement animation */ - base_set_mapview_origin(gui_x0, gui_y0); + base_set_mapview_origin(gui_x0, gui_y0, zoom); } else { int start_x = mapview.gui_x0, start_y = mapview.gui_y0; float diff_x, diff_y; @@ -1018,7 +1018,7 @@ void set_mapview_origin(float gui_x0, float gui_y0) static double total_frames = 0.01; static double total_time = 0.0001; - gui_distance_vector(tileset, + gui_distance_vector(tileset, zoom, &diff_x, &diff_y, start_x, start_y, gui_x0, gui_y0); anim_timer = timer_renew(anim_timer, TIMER_USER, TIMER_ACTIVE); timer_start(anim_timer); @@ -1038,7 +1038,8 @@ void set_mapview_origin(float gui_x0, float gui_y0) mytime = MIN(currtime, timing_sec); base_set_mapview_origin(start_x + diff_x * (mytime / timing_sec), - start_y + diff_y * (mytime / timing_sec)); + start_y + diff_y * (mytime / timing_sec), + zoom); flush_dirty(); gui_flush(); frames++; @@ -1058,7 +1059,7 @@ void set_mapview_origin(float gui_x0, float gui_y0) total_time *= 0.99; } } else { - base_set_mapview_origin(gui_x0, gui_y0); + base_set_mapview_origin(gui_x0, gui_y0, zoom); } update_map_canvas_scrollbars(); @@ -1101,10 +1102,10 @@ void get_mapview_scroll_window(float *xmin, float *ymin, if (MAP_IS_ISOMETRIC == tileset_is_isometric(tileset)) { /* If the map and view line up, it's easy. */ NATIVE_TO_MAP_POS(xmin, ymin, 0, 0); - map_to_gui_pos(tileset, xmin, ymin, *xmin, *ymin); + map_to_gui_pos(tileset, map_zoom, xmin, ymin, *xmin, *ymin); NATIVE_TO_MAP_POS(xmax, ymax, wld.map.xsize - 1, wld.map.ysize - 1); - map_to_gui_pos(tileset, xmax, ymax, *xmax, *ymax); + map_to_gui_pos(tileset, map_zoom, xmax, ymax, *xmax, *ymax); *xmax += tileset_tile_width(tileset) * map_zoom; *ymax += tileset_tile_height(tileset) * map_zoom; @@ -1133,16 +1134,16 @@ void get_mapview_scroll_window(float *xmin, float *ymin, int map_x, map_y; NATIVE_TO_MAP_POS(&map_x, &map_y, 0, 0); - map_to_gui_pos(tileset, &gui_x1, &gui_y1, map_x, map_y); + map_to_gui_pos(tileset, map_zoom, &gui_x1, &gui_y1, map_x, map_y); NATIVE_TO_MAP_POS(&map_x, &map_y, wld.map.xsize - 1, 0); - map_to_gui_pos(tileset, &gui_x2, &gui_y2, map_x, map_y); + map_to_gui_pos(tileset, map_zoom, &gui_x2, &gui_y2, map_x, map_y); NATIVE_TO_MAP_POS(&map_x, &map_y, 0, wld.map.ysize - 1); - map_to_gui_pos(tileset, &gui_x3, &gui_y3, map_x, map_y); + map_to_gui_pos(tileset, map_zoom, &gui_x3, &gui_y3, map_x, map_y); NATIVE_TO_MAP_POS(&map_x, &map_y, wld.map.xsize - 1, wld.map.ysize - 1); - map_to_gui_pos(tileset, &gui_x4, &gui_y4, map_x, map_y); + map_to_gui_pos(tileset, map_zoom, &gui_x4, &gui_y4, map_x, map_y); *xmin = MIN(gui_x1, MIN(gui_x2, gui_x3)) - mapview.width / 2; *ymin = MIN(gui_y1, MIN(gui_y2, gui_y3)) - mapview.height / 2; @@ -1196,12 +1197,12 @@ void get_mapview_scroll_pos(int *scroll_x, int *scroll_y) /************************************************************************//** Set the scroll position (origin) of the mapview, and update the GUI. ****************************************************************************/ -void set_mapview_scroll_pos(int scroll_x, int scroll_y) +void set_mapview_scroll_pos(int scroll_x, int scroll_y, float zoom) { int gui_x0 = scroll_x, gui_y0 = scroll_y; can_slide = FALSE; - set_mapview_origin(gui_x0, gui_y0); + set_mapview_origin(gui_x0, gui_y0, zoom); can_slide = TRUE; } @@ -1211,7 +1212,8 @@ void set_mapview_scroll_pos(int scroll_x, int scroll_y) struct tile *get_center_tile_mapcanvas(void) { return canvas_pos_to_nearest_tile(mapview.width / 2, - mapview.height / 2); + mapview.height / 2, + map_zoom); } /************************************************************************//** @@ -1229,13 +1231,13 @@ void center_tile_mapcanvas(const struct tile *ptile) first = FALSE; index_to_map_pos(&tile_x, &tile_y, tile_index(ptile)); - map_to_gui_pos(tileset, &gui_x, &gui_y, tile_x, tile_y); + map_to_gui_pos(tileset, map_zoom, &gui_x, &gui_y, tile_x, tile_y); /* Put the center pixel of the tile at the exact center of the mapview. */ gui_x -= (mapview.width - tileset_tile_width(tileset) * map_zoom) / 2; gui_y -= (mapview.height - tileset_tile_height(tileset) * map_zoom) / 2; - set_mapview_origin(gui_x, gui_y); + set_mapview_origin(gui_x, gui_y, map_zoom); center_tile = ptile; } @@ -1248,7 +1250,7 @@ bool tile_visible_mapcanvas(struct tile *ptile) { float dummy_x, dummy_y; /* well, it needs two pointers... */ - return tile_to_canvas_pos(&dummy_x, &dummy_y, ptile); + return tile_to_canvas_pos(&dummy_x, &dummy_y, map_zoom, ptile); } /************************************************************************//** @@ -1276,7 +1278,7 @@ bool tile_visible_and_not_on_border_mapcanvas(struct tile *ptile) get_mapview_scroll_window(&xmin, &ymin, &xmax, &ymax, &xsize, &ysize); get_mapview_scroll_pos(&scroll_x, &scroll_y); - if (!tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) { + if (!tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile)) { /* The tile isn't visible at all. */ return FALSE; } @@ -1521,7 +1523,7 @@ void put_nuke_mushroom_pixmaps(struct tile *ptile) anim->nuke.shown = FALSE; anim->nuke.nuke_tile = ptile; - (void) tile_to_canvas_pos(&canvas_x, &canvas_y, ptile); + (void) tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile); get_sprite_dimensions(mysprite, &width, &height); anim->width = width * map_zoom; @@ -1530,7 +1532,7 @@ void put_nuke_mushroom_pixmaps(struct tile *ptile) } else { /* We can't count on the return value of tile_to_canvas_pos since the * sprite may span multiple tiles. */ - (void) tile_to_canvas_pos(&canvas_x, &canvas_y, ptile); + (void) tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile); canvas_x += (tileset_tile_width(tileset) - width) / 2 * map_zoom; canvas_y += (tileset_tile_height(tileset) - height) / 2 * map_zoom; @@ -1601,11 +1603,11 @@ static int trade_route_to_canvas_lines(const struct tile *ptile1, } base_map_distance_vector(&dx, &dy, TILE_XY(ptile1), TILE_XY(ptile2)); - map_to_gui_pos(tileset, &lines[0].width, &lines[0].height, dx, dy); + map_to_gui_pos(tileset, map_zoom, &lines[0].width, &lines[0].height, dx, dy); /* FIXME: Remove these casts. */ - tile_to_canvas_pos(&lines[0].x, &lines[0].y, (struct tile *)ptile1); - tile_to_canvas_pos(&lines[1].x, &lines[1].y, (struct tile *)ptile2); + tile_to_canvas_pos(&lines[0].x, &lines[0].y, map_zoom, (struct tile *)ptile1); + tile_to_canvas_pos(&lines[1].x, &lines[1].y, map_zoom, (struct tile *)ptile2); if (lines[1].x - lines[0].x == lines[0].width && lines[1].y - lines[0].y == lines[0].height) { @@ -2509,7 +2511,7 @@ void draw_segment(struct tile *src_tile, enum direction8 dir) float canvas_x, canvas_y, canvas_dx, canvas_dy; /* Determine the source position of the segment. */ - (void) tile_to_canvas_pos(&canvas_x, &canvas_y, src_tile); + (void) tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, src_tile); canvas_x += tileset_tile_width(tileset) / 2 * map_zoom; canvas_y += tileset_tile_height(tileset) / 2 * map_zoom; @@ -2629,7 +2631,7 @@ void decrease_unit_hp_smooth(struct unit *punit0, int hp0, } if (num_tiles_explode_unit > 0 - && tile_to_canvas_pos(&canvas_x, &canvas_y, + && tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, unit_tile(losing_unit))) { refresh_unit_mapcanvas(losing_unit, unit_tile(losing_unit), FALSE, FALSE); unqueue_mapview_updates(FALSE); @@ -2677,7 +2679,7 @@ void decrease_unit_hp_smooth(struct unit *punit0, int hp0, } /************************************************************************//** - Animates punit's "smooth" move from (x0, y0) to (x0+dx, y0+dy). + Animates punit's "smooth" move from (x0, y0) to (x0 + dx, y0 + dy). Note: Works only for adjacent-tile moves. ****************************************************************************/ void move_unit_map_canvas(struct unit *punit, @@ -2714,7 +2716,7 @@ void move_unit_map_canvas(struct unit *punit, map_to_gui_vector(tileset, map_zoom, &canvas_dx, &canvas_dy, dx, dy); - tile_to_canvas_pos(&start_x, &start_y, src_tile); + tile_to_canvas_pos(&start_x, &start_y, map_zoom, src_tile); if (tileset_is_isometric(tileset) && tileset_hex_height(tileset) == 0) { start_y -= tileset_tile_height(tileset) / 2 * map_zoom; start_y -= (tileset_unit_height(tileset) - tileset_full_tile_height(tileset)) * map_zoom; @@ -3133,7 +3135,7 @@ void unqueue_mapview_updates(bool write_to_screen) float xl, yt; int xr, yb; - (void) tile_to_canvas_pos(&xl, &yt, ptile); + (void) tile_to_canvas_pos(&xl, &yt, map_zoom, ptile); xl += area[i].dx; yt += area[i].dy; @@ -3640,13 +3642,13 @@ bool map_canvas_resized(int width, int height) float gui_x, gui_y; index_to_map_pos(&x_left, &y_top, tile_index(center_tile)); - map_to_gui_pos(tileset, &gui_x, &gui_y, x_left, y_top); + map_to_gui_pos(tileset, map_zoom, &gui_x, &gui_y, x_left, y_top); /* Put the center pixel of the tile at the exact center of the mapview. */ gui_x -= (mapview.width - tileset_tile_width(tileset) * map_zoom) / 2; gui_y -= (mapview.height - tileset_tile_height(tileset) * map_zoom) / 2; - calc_mapview_origin(&gui_x, &gui_y); + calc_mapview_origin(&gui_x, &gui_y, map_zoom); mapview.gui_x0 = gui_x; mapview.gui_y0 = gui_y; } @@ -3883,7 +3885,7 @@ static void link_mark_draw(const struct link_mark *pmark) struct tile *ptile = link_mark_tile(pmark); struct color *pcolor = link_mark_color(pmark); - if (!ptile || !tile_to_canvas_pos(&canvas_x, &canvas_y, ptile)) { + if (!ptile || !tile_to_canvas_pos(&canvas_x, &canvas_y, map_zoom, ptile)) { return; } diff --git a/client/mapview_common.h b/client/mapview_common.h index ae9db84238..a50d43d6fe 100644 --- a/client/mapview_common.h +++ b/client/mapview_common.h @@ -250,20 +250,21 @@ void unqueue_mapview_updates(bool write_to_screen); void map_to_gui_vector(const struct tileset *t, float zoom, float *gui_dx, float *gui_dy, int map_dx, int map_dy); -bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, +bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, float zoom, const struct tile *ptile) - fc__attribute((nonnull (1, 2, 3))); -struct tile *canvas_pos_to_tile(float canvas_x, float canvas_y); -struct tile *canvas_pos_to_nearest_tile(float canvas_x, float canvas_y); + fc__attribute((nonnull (1, 2, 4))); +struct tile *canvas_pos_to_tile(float canvas_x, float canvas_y, float zoom); +struct tile *canvas_pos_to_nearest_tile(float canvas_x, float canvas_y, + float zoom); void get_mapview_scroll_window(float *xmin, float *ymin, float *xmax, float *ymax, int *xsize, int *ysize); void get_mapview_scroll_step(int *xstep, int *ystep); void get_mapview_scroll_pos(int *scroll_x, int *scroll_y); -void set_mapview_scroll_pos(int scroll_x, int scroll_y); +void set_mapview_scroll_pos(int scroll_x, int scroll_y, float zoom); -void set_mapview_origin(float gui_x0, float gui_y0); +void set_mapview_origin(float gui_x0, float gui_y0, float zoom); struct tile *get_center_tile_mapcanvas(void); void center_tile_mapcanvas(const struct tile *ptile) fc__attribute((nonnull (1))); diff --git a/client/packhand.c b/client/packhand.c index afc2d7357d..7103c366f4 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -555,9 +555,9 @@ void handle_team_name_info(int team_id, const char *team_name) } /************************************************************************//** - A combat packet. The server tells us the attacker and defender as well + A combat packet. The server tells us the attacker and defender as well as both of their hitpoints after the combat is over (in most combat, one - unit always dies and their HP drops to zero). If make_winner_veteran is + unit always dies and their HP drops to zero). If make_winner_veteran is set then the surviving unit becomes veteran. ****************************************************************************/ void handle_unit_combat_info(const struct packet_unit_combat_info *packet) diff --git a/client/zoom.c b/client/zoom.c index c2fe5a7096..f8b17f0875 100644 --- a/client/zoom.c +++ b/client/zoom.c @@ -17,6 +17,7 @@ /* client */ #include "mapview_common.h" +#include "mapview_g.h" #include "zoom.h" @@ -24,6 +25,9 @@ float map_zoom = 1.0; bool zoom_enabled = FALSE; +float mouse_zoom = 1.0; +bool zoom_individual_tiles = TRUE; + static float default_zoom_steps[] = { -1.0, 1.0, 2.0, -1.0 }; @@ -45,9 +49,15 @@ static struct zoom_data void zoom_set(float new_zoom) { zoom_enabled = TRUE; - map_zoom = new_zoom; + mouse_zoom = new_zoom; - map_canvas_resized(mapview.width, mapview.height); + if (zoom_individual_tiles) { + map_zoom = new_zoom; + + map_canvas_resized(mapview.width, mapview.height); + } else { + map_canvas_size_refresh(); + } } /**********************************************************************//** @@ -57,6 +67,7 @@ void zoom_1_0(void) { zoom_enabled = FALSE; map_zoom = 1.0; + mouse_zoom = 1.0; map_canvas_resized(mapview.width, mapview.height); } @@ -75,6 +86,20 @@ void zoom_set_steps(float *steps) } } +/**********************************************************************//** + Set time zooming takes place. Default is to zoom individual tiles. + Gui needs to implement alternatives themselves. +**************************************************************************/ +void zoom_phase_set(bool individual_tiles) +{ + zoom_individual_tiles = individual_tiles; + + if (!individual_tiles) { + map_zoom = 1.0; + zoom_enabled = FALSE; + } +} + /**********************************************************************//** Zoom level one step up **************************************************************************/ @@ -85,7 +110,7 @@ void zoom_step_up(void) /* Even if below previous step, close enough is considered to be in * previous step so that change is not miniscule */ for (i = 1 ; - zoom_steps[i] < map_zoom * 1.05 && zoom_steps[i] > 0.0 ; + zoom_steps[i] < mouse_zoom * 1.05 && zoom_steps[i] > 0.0 ; i++ ) { /* Empty */ } @@ -109,7 +134,7 @@ void zoom_step_down(void) /* Even if above previous step, close enough is considered to be in * previous step so that change is not miniscule */ for (i = 1; - zoom_steps[i] < map_zoom * 1.05 && zoom_steps[i] > 0.0 ; + zoom_steps[i] < mouse_zoom * 1.05 && zoom_steps[i] > 0.0 ; i++) { } @@ -131,8 +156,8 @@ void zoom_step_down(void) void zoom_start(float tgt, bool tgt_1_0, float factor, float interval) { zdata.tgt = tgt; - if ((tgt < map_zoom && factor > 1.0) - || (tgt > map_zoom && factor < 1.0)) { + if ((tgt < mouse_zoom && factor > 1.0) + || (tgt > mouse_zoom && factor < 1.0)) { factor = 1.0 / factor; } zdata.factor = factor; @@ -147,7 +172,7 @@ void zoom_start(float tgt, bool tgt_1_0, float factor, float interval) bool zoom_update(double time_until_next_call) { if (zdata.active) { - float new_zoom = map_zoom * zdata.factor; + float new_zoom = mouse_zoom * zdata.factor; if ((zdata.factor > 1.0 && new_zoom > zdata.tgt) || (zdata.factor < 1.0 && new_zoom < zdata.tgt)) { diff --git a/client/zoom.h b/client/zoom.h index d5b8f77078..4b1f38dbb4 100644 --- a/client/zoom.h +++ b/client/zoom.h @@ -20,6 +20,7 @@ extern "C" { void zoom_set(float new_zoom); void zoom_1_0(void); void zoom_set_steps(float *steps); +void zoom_phase_set(bool individual_tiles); #define zoom_get_level() map_zoom #define zoom_is_enabled() zoom_enabled @@ -32,6 +33,7 @@ bool zoom_update(double time_until_next_call); extern bool zoom_enabled; extern float map_zoom; +extern float mouse_zoom; #ifdef __cplusplus } -- 2.40.1