File: number_control.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 (125 lines) | stat: -rw-r--r-- 3,227 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "number_control.h"
#include "sdlx/font.h"
#include "sdlx/surface.h"
#include "math/binary.h"
#include "resource_manager.h"


NumberControl::NumberControl(const std::string &font, const int min, const int max, const int step) : 
	min(min), max(max), step(step), value(min), 
	mouse_pressed(0), mouse_button(0), direction(false), 
	_number(ResourceManager->load_surface("menu/number.png")), 
	_font(ResourceManager->loadFont(font, true)), 
	r_up(0, 0, _number->get_width(), _number->get_height() / 2), 
	r_down(0, _number->get_height() / 2, _number->get_width(), _number->get_height() - _number->get_height() / 2) {}

const int NumberControl::get() const {
	const_cast<NumberControl *>(this)->validate();
	return value;
}

void NumberControl::validate() {
	if (value < min)
		value = min;
	if (value > max)
		value = max;
}

void NumberControl::set(const int v) {
	if (v > max || v < min)
		return;
	value = min + (v - min) / step * step;
	validate();
}

void NumberControl::render(sdlx::Surface &surface, const int x, const int y) const {
	surface.blit(*_number, x, y);
	_font->render(surface, x + _number->get_width(), y + _number->get_height() - _font->get_height(), mrt::format_string(min < 0?"%+d":"%d", value));
}

void NumberControl::get_size(int &w, int &h) const {
	w =	_font->render(NULL, 0, 0, mrt::format_string(min < 0?"%+d":"%d", value)) + _number->get_width();
	h = math::max(_number->get_height(), _font->get_height());
}

void NumberControl::up(const int v) {
	value += v * step;
	validate();
}

void NumberControl::down(const int v) {
	value -= v * step;
	validate();
}

bool NumberControl::onKey(const SDL_keysym sym) {
	switch(sym.sym) {
		case SDLK_UP: up(); return true;
		case SDLK_DOWN: down(); return true;
		case SDLK_PAGEUP: up(10); return true;
		case SDLK_PAGEDOWN: down(10); return true;

		case SDLK_BACKSPACE: value /= 10;
			return true;
		default: 
			if (sym.unicode >= '0' && sym.unicode <= '9') {
				value = sym.unicode - '0' + 10 * value;
				if (value > max)
					value = max;
				return true;
			}
		
			return false;
	}
}

bool NumberControl::onMouse(const int button, const bool pressed, const int x, const int y) {
	if (r_up.in(x, y) && pressed) {
		up(button == SDL_BUTTON_RIGHT? 10: 1);
		mouse_button = button;
		direction = true;
		mouse_pressed = 0.0;
		return true;
	}
	if (r_down.in(x, y) && pressed) {
		down(button == SDL_BUTTON_RIGHT? 10: 1);
		mouse_button = button;
		direction = false;
		mouse_pressed = 0.0;
		return true;
	}
	if (!pressed) {
		mouse_pressed = 0;
		mouse_button = 0;
	}
	return false;
}

void NumberControl::tick(const float dt) {
	Control::tick(dt);
	if (mouse_button != 0) {
		mouse_pressed += dt;
		const float guard = 0.5f;
		if (mouse_pressed < guard)
			return;
		
		const int speed = 20;
		int n = (int)((mouse_pressed - guard) * speed); //10 - speed
		mouse_pressed -= 1.0f * n / speed;

		//don't blame me, i am an indian programmer :)))
		if (direction) {
			up(mouse_button == SDL_BUTTON_RIGHT? 10 * n: n);
		} else {
			down(mouse_button == SDL_BUTTON_RIGHT? 10 * n: n);
		}
	}

}

void NumberControl::setMinMax(const int m1, const int m2) { 
	LOG_DEBUG(("setting min: %d, max: %d", m1, m2));
	min = m1; 
	max = m2; 
	validate(); 
}