File: image_view.cpp

package info (click to toggle)
btanks 0.9.8083-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 43,616 kB
  • sloc: cpp: 46,425; ansic: 12,005; xml: 4,262; python: 313; sh: 13; makefile: 13
file content (94 lines) | stat: -rw-r--r-- 2,386 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "image_view.h"
#include "math/binary.h"
#include "sdlx/rect.h"
#include "sdlx/surface.h"
#include "box.h"

ImageView::ImageView(int w, int h) : 
_w(w), _h(h), _image(NULL), _overlay(NULL), 
_box(new Box("menu/background_box.png", _w, _h)) {
	add(0, 0, _box);
}

void ImageView::setOverlay(const sdlx::Surface *overlay, const v2<int> &dpos) {
	_overlay = overlay; 
	_overlay_dpos = dpos;
}


void ImageView::init(const sdlx::Surface *image) {
	_image = image;
}

void ImageView::render(sdlx::Surface &surface, const int x, const int y) const {
	Container::render(surface, x, y);
	if (_image == NULL)
		return;
	int mx, my;
	_box->getMargins(mx, my);
	sdlx::Rect clip;

	surface.get_clip_rect(clip);
	surface.set_clip_rect(sdlx::Rect(mx + x, my + y, _w - 2 * mx, _h - 2 * my));
	surface.blit(*_image, x + mx - (int)position.x, y + my - (int)position.y);
	if (_overlay != NULL) 
		surface.blit(*_overlay, x + mx - (int)position.x + _overlay_dpos.x, y + my - (int)position.y + _overlay_dpos.y);
	surface.set_clip_rect(clip);
}

void ImageView::validate(v2<float> & pos) {
	if (_image == NULL)
		return;
	if (pos.x < 0) 
		pos.x = 0;
		
	if (pos.y < 0)
		pos.y = 0;
	
	int mx, my;
	_box->getMargins(mx, my);
		
	int w = _w - 2 * mx, h = _h - 2 * my;
	if (pos.x + w > _image->get_width())
		pos.x = _image->get_width() - w;
	if (pos.y + h > _image->get_height())
		pos.y = _image->get_height() - h;
}

void ImageView::tick(const float dt) {
	Container::tick(dt);
	validate(destination);
	validate(position);
	
	v2<float> map_vel = destination - position;
	if (map_vel.quick_length() < 1) {
		position = destination;
	} else {
		map_vel.normalize();
		float dist = destination.distance(position);
		position += math::min(dist, map_vel.length() * (dist > 300?600:(dist < 25?50:dist * 2)) * dt) * map_vel;
	}
}

void ImageView::set_position(const v2<float> &pos) { 
	setDestination(pos);
	position = destination;
}

void ImageView::setDestination(const v2<float> &pos) {
	v2<float> p = pos - v2<float>(_w, _h) / 2;
	if (_overlay)
		p += v2<float>(_overlay->get_width(), _overlay->get_height()) / 2;
	destination = p;
}

bool ImageView::onMouseMotion(const int state, const int x, const int y, const int xrel, const int yrel) {
	if ((state & SDL_BUTTON(1)) == 0)
		return false;
	
	position.x -= xrel; 
	position.y -= yrel; 
	validate(position);
	destination = position;
	return true;
}