1// SuperTux
2// Copyright (C) 2015 Hume2 <teratux.mail@gmail.com>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (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, see <http://www.gnu.org/licenses/>.
16
17#include "gui/item_colorchannel.hpp"
18
19#include <sstream>
20
21#include "math/util.hpp"
22#include "supertux/resources.hpp"
23#include "video/drawing_context.hpp"
24
25namespace {
26
27std::string colour_value_to_string(float v, bool is_linear)
28{
29 if (!is_linear)
30 v = Color::remove_gamma(v);
31 v *= 100.0f;
32 // not using std::to_string() as it padds the end with '0's
33 v = 0.01f * floorf(v * 100.0f + 0.5f);
34 std::ostringstream os;
35 os << v << " %";
36 return os.str();
37}
38
39} // namespace
40
41ItemColorChannel::ItemColorChannel(float* input, Color channel, int id,
42 bool is_linear) :
43 MenuItem(colour_value_to_string(*input, is_linear), id),
44 m_number(input),
45 m_is_linear(is_linear),
46 m_flickw(static_cast<int>(Resources::normal_font->get_text_width("_"))),
47 m_channel(channel)
48{
49}
50
51void
52ItemColorChannel::draw(DrawingContext& context, const Vector& pos, int menu_width, bool active)
53{
54 MenuItem::draw(context, pos, menu_width, active);
55 const float lw = float(menu_width - 32) * (*m_number);
56 context.color().draw_filled_rect(Rectf(pos + Vector(16, -4),
57 pos + Vector(16 + lw, 4)),
58 m_channel, 0.0f, LAYER_GUI-1);
59}
60
61int
62ItemColorChannel::get_width() const
63{
64 return static_cast<int>(Resources::normal_font->get_text_width(get_text()) + 16 + static_cast<float>(m_flickw));
65}
66
67void
68ItemColorChannel::event(const SDL_Event& ev)
69{
70 if (ev.type == SDL_TEXTINPUT) {
71 std::string txt = ev.text.text;
72 for (auto& c : txt) {
73 add_char(c);
74 }
75 }
76}
77
78void
79ItemColorChannel::add_char(char c)
80{
81 std::string text = get_text();
82
83 if (c == '.' || c == ',')
84 {
85 const bool has_comma = (text.find('.') != std::string::npos);
86 if (!has_comma)
87 {
88 if (text.empty()) {
89 text = "0.";
90 } else {
91 text.push_back('.');
92 }
93 }
94 }
95 else if (isdigit(c))
96 {
97 text.push_back(c);
98 }
99 else
100 {
101 return;
102 }
103
104 float number = std::stof(text);
105 if (0.0f <= number && number <= 1.0f) {
106 *m_number = number;
107 set_text(text);
108 }
109}
110
111void
112ItemColorChannel::remove_char()
113{
114 std::string text = get_text();
115
116 if (text.empty())
117 {
118 *m_number = 0.0f;
119 }
120 else
121 {
122 text.pop_back();
123
124 if (!text.empty()) {
125 *m_number = std::stof(text);
126 } else {
127 *m_number = 0.0f;
128 }
129 }
130
131 set_text(text);
132}
133
134void
135ItemColorChannel::process_action(const MenuAction& action)
136{
137 switch (action)
138 {
139 case MenuAction::REMOVE:
140 remove_char();
141 break;
142
143 case MenuAction::LEFT:
144 *m_number = roundf(*m_number * 10.0f) / 10.0f;
145 *m_number -= 0.1f;
146 *m_number = math::clamp(*m_number, 0.0f, 1.0f);
147 set_text(colour_value_to_string(*m_number, m_is_linear));
148 break;
149
150
151 case MenuAction::RIGHT:
152 *m_number = roundf(*m_number * 10.0f) / 10.0f;
153 *m_number += 0.1f;
154 *m_number = math::clamp(*m_number, 0.0f, 1.0f);
155 set_text(colour_value_to_string(*m_number, m_is_linear));
156 break;
157
158 default:
159 break;
160 }
161}
162
163Color
164ItemColorChannel::get_color() const
165{
166 return m_channel;
167}
168
169/* EOF */
170