1 #include "image_view.h"
2 #include "math/binary.h"
3 #include "sdlx/rect.h"
4 #include "sdlx/surface.h"
5 #include "box.h"
6
ImageView(int w,int h)7 ImageView::ImageView(int w, int h) :
8 _w(w), _h(h), _image(NULL), _overlay(NULL),
9 _box(new Box("menu/background_box.png", _w, _h)) {
10 add(0, 0, _box);
11 }
12
setOverlay(const sdlx::Surface * overlay,const v2<int> & dpos)13 void ImageView::setOverlay(const sdlx::Surface *overlay, const v2<int> &dpos) {
14 _overlay = overlay;
15 _overlay_dpos = dpos;
16 }
17
18
init(const sdlx::Surface * image)19 void ImageView::init(const sdlx::Surface *image) {
20 _image = image;
21 }
22
render(sdlx::Surface & surface,const int x,const int y) const23 void ImageView::render(sdlx::Surface &surface, const int x, const int y) const {
24 Container::render(surface, x, y);
25 if (_image == NULL)
26 return;
27 int mx, my;
28 _box->getMargins(mx, my);
29 sdlx::Rect clip;
30
31 surface.get_clip_rect(clip);
32 surface.set_clip_rect(sdlx::Rect(mx + x, my + y, _w - 2 * mx, _h - 2 * my));
33 surface.blit(*_image, x + mx - (int)position.x, y + my - (int)position.y);
34 if (_overlay != NULL)
35 surface.blit(*_overlay, x + mx - (int)position.x + _overlay_dpos.x, y + my - (int)position.y + _overlay_dpos.y);
36 surface.set_clip_rect(clip);
37 }
38
validate(v2<float> & pos)39 void ImageView::validate(v2<float> & pos) {
40 if (_image == NULL)
41 return;
42 if (pos.x < 0)
43 pos.x = 0;
44
45 if (pos.y < 0)
46 pos.y = 0;
47
48 int mx, my;
49 _box->getMargins(mx, my);
50
51 int w = _w - 2 * mx, h = _h - 2 * my;
52 if (pos.x + w > _image->get_width())
53 pos.x = _image->get_width() - w;
54 if (pos.y + h > _image->get_height())
55 pos.y = _image->get_height() - h;
56 }
57
tick(const float dt)58 void ImageView::tick(const float dt) {
59 Container::tick(dt);
60 validate(destination);
61 validate(position);
62
63 v2<float> map_vel = destination - position;
64 if (map_vel.quick_length() < 1) {
65 position = destination;
66 } else {
67 map_vel.normalize();
68 float dist = destination.distance(position);
69 position += math::min(dist, map_vel.length() * (dist > 300?600:(dist < 25?50:dist * 2)) * dt) * map_vel;
70 }
71 }
72
set_position(const v2<float> & pos)73 void ImageView::set_position(const v2<float> &pos) {
74 setDestination(pos);
75 position = destination;
76 }
77
setDestination(const v2<float> & pos)78 void ImageView::setDestination(const v2<float> &pos) {
79 v2<float> p = pos - v2<float>(_w, _h) / 2;
80 if (_overlay)
81 p += v2<float>(_overlay->get_width(), _overlay->get_height()) / 2;
82 destination = p;
83 }
84
onMouseMotion(const int state,const int x,const int y,const int xrel,const int yrel)85 bool ImageView::onMouseMotion(const int state, const int x, const int y, const int xrel, const int yrel) {
86 if ((state & SDL_BUTTON(1)) == 0)
87 return false;
88
89 position.x -= xrel;
90 position.y -= yrel;
91 validate(position);
92 destination = position;
93 return true;
94 }
95