~gunchleoc/widelands/bug-1818494-ingame-zoom-freezes

« back to all changes in this revision

Viewing changes to src/wui/mapview.cc

  • Committer: sirver
  • Date: 2009-05-05 21:29:34 UTC
  • Revision ID: git-v1:057a819fa084560347a34a1079137522020ebbb8
Moved more UserInterface classes to WUI. Started logic sublibrary (with currently only one member file).

git-svn-id: https://widelands.svn.sourceforge.net/svnroot/widelands/trunk@4024 37b2a8de-5219-0410-9f54-a31bc463ab9c

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002-2004, 2006-2008 by the Widelands Development Team
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 *
 
18
 */
 
19
 
 
20
#include "mapview.h"
 
21
 
 
22
#include "graphic/graphic.h"
 
23
#include "interactive_base.h"
 
24
#include "interactive_player.h"
 
25
#include "map.h"
 
26
#include "mapviewpixelfunctions.h"
 
27
#include "graphic/overlay_manager.h"
 
28
#include "player.h"
 
29
#include "graphic/rendertarget.h"
 
30
#include "wlapplication.h"
 
31
 
 
32
#include "upcast.h"
 
33
 
 
34
Map_View::Map_View
 
35
        (UI::Panel * parent,
 
36
         int32_t x, int32_t y, uint32_t w, uint32_t h,
 
37
         Interactive_Base & player)
 
38
:
 
39
UI::Panel               (parent, x, y, w, h),
 
40
m_intbase               (player),
 
41
m_viewpoint             (Point(0, 0)),
 
42
m_dragging              (false),
 
43
m_complete_redraw_needed(true)
 
44
{}
 
45
 
 
46
 
 
47
/// Moves the mouse cursor so that it is directly above the given node
 
48
void Map_View::warp_mouse_to_node(Widelands::Coords const c) {
 
49
        Widelands::Map const & map = intbase().egbase().map();
 
50
        Point p;
 
51
        MapviewPixelFunctions::get_save_pix(map, c, p.x, p.y);
 
52
        p -= m_viewpoint;
 
53
 
 
54
        //  If the user has scrolled the field outside the viewable area, he most
 
55
        //  surely doesn't want to jump there.
 
56
        if (p.x < get_w() and p.y < get_h()) {
 
57
                if      (p.x <= 0)
 
58
                        warp_mouse_to_node(Widelands::Coords(c.x + map.get_width (), c.y));
 
59
                else if (p.y <= 0)
 
60
                        warp_mouse_to_node(Widelands::Coords(c.x, c.y + map.get_height()));
 
61
                else
 
62
                        set_mouse_pos(p);
 
63
        }
 
64
}
 
65
 
 
66
 
 
67
/*
 
68
===============
 
69
Map_View::draw
 
70
 
 
71
This is the guts!! this function draws the whole
 
72
map the user can see. we spend a lot of time
 
73
in this function
 
74
===============
 
75
*/
 
76
void Map_View::draw(RenderTarget & dst)
 
77
{
 
78
        Widelands::Editor_Game_Base & egbase = intbase().egbase();
 
79
 
 
80
        if (upcast(Widelands::Game, game, &egbase)) {
 
81
                // Bail out if the game isn't actually loaded.
 
82
                // This fixes a crash with displaying an error dialog during loading.
 
83
                if (!game->is_loaded())
 
84
                        return;
 
85
 
 
86
                // Check if the view has changed in a game
 
87
                if (intbase().get_player() && intbase().get_player()->has_view_changed())
 
88
                        m_complete_redraw_needed = true;
 
89
        }
 
90
 
 
91
        egbase.map().overlay_manager().load_graphics();
 
92
 
 
93
        if (upcast(Interactive_Player const, interactive_player, &intbase()))
 
94
                dst.rendermap(egbase, interactive_player->player(), m_viewpoint);
 
95
        else
 
96
                dst.rendermap(egbase, m_viewpoint);
 
97
 
 
98
        m_complete_redraw_needed = false;
 
99
}
 
100
 
 
101
 
 
102
/*
 
103
===============
 
104
Set the viewpoint to the given pixel coordinates
 
105
===============
 
106
*/
 
107
void Map_View::set_viewpoint(Point vp)
 
108
{
 
109
        if (vp == m_viewpoint)
 
110
                return;
 
111
 
 
112
        MapviewPixelFunctions::normalize_pix(intbase().egbase().map(), vp);
 
113
        m_viewpoint = vp;
 
114
 
 
115
        warpview.call(m_viewpoint.x, m_viewpoint.y);
 
116
 
 
117
        m_complete_redraw_needed = true;
 
118
}
 
119
 
 
120
 
 
121
void Map_View::stop_dragging() {
 
122
        WLApplication::get()->set_mouse_lock(false);
 
123
        grab_mouse(false);
 
124
        m_dragging = false;
 
125
}
 
126
 
 
127
/**
 
128
 * Mousepressess and -releases on the map:
 
129
 * Right-press:   enable  dragging
 
130
 * Right-release: disable dragging
 
131
 * Left-press:    field action window
 
132
 */
 
133
bool Map_View::handle_mousepress
 
134
        (Uint8 const btn, int32_t const x, int32_t const y)
 
135
{
 
136
#ifdef __APPLE__
 
137
        //  SDL does on Mac hardcoded middle mouse button emulation (alt+left).
 
138
        //  This interferes with the editor, which is using alt+left click for third
 
139
        //  tool.  So just handle middle mouse button like left one.
 
140
        //  TODO This should be handled in a more general way someplace else. What
 
141
        //  TODO kind of stupid idea is it to hardcode something like that in SDL?
 
142
        //  TODO Sometimes, people are funny....
 
143
        if (btn == SDL_BUTTON_MIDDLE || btn == SDL_BUTTON_LEFT)
 
144
#else
 
145
        if (btn == SDL_BUTTON_LEFT)
 
146
#endif
 
147
        {
 
148
                track_sel(Point(x, y));
 
149
 
 
150
                fieldclicked.call();
 
151
        } else if (btn == SDL_BUTTON_RIGHT) {
 
152
                m_dragging = true;
 
153
                grab_mouse(true);
 
154
                WLApplication::get()->set_mouse_lock(true);
 
155
        }
 
156
        return true;
 
157
}
 
158
bool Map_View::handle_mouserelease(const Uint8 btn, int32_t, int32_t)
 
159
{if (btn == SDL_BUTTON_RIGHT and m_dragging) stop_dragging(); return true;}
 
160
 
 
161
 
 
162
/*
 
163
===============
 
164
Map_View::handle_mousemove
 
165
 
 
166
Scroll the view according to mouse movement.
 
167
===============
 
168
*/
 
169
bool Map_View::handle_mousemove
 
170
        (Uint8 const state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff)
 
171
{
 
172
        if (m_dragging)
 
173
        {
 
174
                if (state & SDL_BUTTON(SDL_BUTTON_RIGHT))
 
175
                        set_rel_viewpoint(Point(xdiff, ydiff));
 
176
                else stop_dragging();
 
177
        }
 
178
 
 
179
        if (not intbase().get_sel_freeze()) track_sel(Point(x, y));
 
180
 
 
181
        g_gr->update_fullscreen();
 
182
        return true;
 
183
}
 
184
 
 
185
 
 
186
/*
 
187
===============
 
188
Map_View::track_sel(int32_t mx, int32_t my)
 
189
 
 
190
Move the sel to the given mouse position.
 
191
Does not honour sel freeze.
 
192
===============
 
193
*/
 
194
void Map_View::track_sel(Point m) {
 
195
        m += m_viewpoint;
 
196
        m_intbase.set_sel_pos
 
197
                (MapviewPixelFunctions::calc_node_and_triangle
 
198
                        (intbase().egbase().map(), m.x, m.y));
 
199
}