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