cgv
Loading...
Searching...
No Matches
key_control.cxx
1#define _USE_MATH_DEFINES
2#include <cmath>
3#include "key_control.h"
4#include "key_event.h"
5#include "trigger.h"
6#include <cgv/type/variant.h>
7#include <cgv/type/info/type_name.h>
8#include <cgv/utils/convert.h>
9
10using namespace cgv::utils;
11
12namespace cgv {
13 namespace gui {
14
15template <typename T>
17{
19}
20
21template <typename T>
23{
24 return
25 srh.reflect_member("speed", speed) &&
26 srh.reflect_member("min", min_value) &&
27 srh.reflect_member("max", max_value) &&
28 srh.reflect_member("log", log_scale) &&
29 srh.reflect_member("no_limits", no_limits);
30}
31
32template <typename T>
34{
35 return cgv::base::base::get_property_declarations()+";more:shortcut;less:shortcut";
36}
37
38template <typename T>
39bool key_control<T>::set_void(const std::string& property, const std::string& value_type, const void* value_ptr)
40{
41 if (cgv::base::base::set_void(property, value_type, value_ptr))
42 return true;
43 if (property == "more") {
44 if (value_type == "cgv::gui::shortcut")
45 more = *((const shortcut*)value_ptr);
46 else if (value_type == "string")
47 return from_string(more, *((const std::string*)value_ptr));
48 else
49 return false;
50 return true;
51 }
52 if (property == "less") {
53 if (value_type == "cgv::gui::shortcut")
54 less = *((const shortcut*)value_ptr);
55 else if (value_type == "string")
56 return from_string(less, *((const std::string*)value_ptr));
57 else
58 return false;
59 return true;
60 }
61 return false;
62}
63
64template <typename T>
65bool key_control<T>::get_void(const std::string& property, const std::string& value_type, void* value_ptr)
66{
67 return cgv::base::base::get_void(property, value_type, value_ptr);
68}
69
70template <typename T>
71void key_control<T>::on_set(void* member_ptr)
72{
73 if (member_ptr == &min_value || member_ptr == &max_value)
74 no_limits = false;
75}
76
77template <typename T>
78key_control<T>::key_control(const std::string& _name, T& _value, const std::string& options) : control<T>(_name,_value)
79{
80 speed = 1;
81 min_value = 0;
82 max_value = 1;
83 log_scale = false;
84 no_limits = true;
86
87 increase_pressed_time = 0;
88 decrease_pressed_time = 0;
89
90 this->multi_set(options, true);
91}
92
93template <typename T>
94void key_control<T>::change_value(double dt)
95{
96 if (no_limits || (dt > 0 && control<T>::get_value() < max_value) || (dt < 0 && control<T>::get_value() > min_value)) {
97 T nv = control<T>::get_value();
98 if (log_scale)
99 nv *= (T)exp(speed*dt);
100 else
101 nv += (T)(speed*dt);
102 if (!no_limits) {
103 if (nv > max_value)
104 nv = max_value;
105 else if (nv < min_value)
106 nv = min_value;
107 }
108 if (nv != control<T>::get_value())
109 this->check_and_set_value(nv);
110 }
111}
112
113template <typename T>
115{
116 if (e.get_kind() != EID_KEY)
117 return false;
118 key_event& ke = static_cast<key_event&>(e);
119 if (ke.get_action() == KA_PRESS) {
120 if (ke.get_key() == more.get_key() && ke.get_modifiers() == more.get_modifiers()) {
121 if (increase_pressed_time == 0)
122 increase_pressed_time = e.get_time();
123 return true;
124 }
125 if (ke.get_key() == less.get_key() && ke.get_modifiers() == less.get_modifiers()) {
126 if (decrease_pressed_time == 0)
127 decrease_pressed_time = e.get_time();
128 return true;
129 }
130 }
131 else {
132 if (ke.get_key() == more.get_key() && increase_pressed_time != 0) {
133 change_value(ke.get_time()-increase_pressed_time);
134 increase_pressed_time = 0;
135 return true;
136 }
137 if (ke.get_key() == less.get_key() && decrease_pressed_time != 0) {
138 change_value(decrease_pressed_time-ke.get_time());
139 decrease_pressed_time = 0;
140 return true;
141 }
142 }
143 return false;
144}
145
146
147template <typename T>
148void key_control<T>::stream_help(std::ostream& os)
149{
150 os << this->get_name() << ": <" << less << "," << more << ">" << std::endl;
151}
152
153template <typename T>
154void key_control<T>::timer_event(double time, double dt)
155{
156 if (increase_pressed_time != 0) {
158 change_value(time-increase_pressed_time);
159 increase_pressed_time = time;
160 }
161 if (decrease_pressed_time != 0) {
163 change_value(decrease_pressed_time-time);
164 decrease_pressed_time = time;
165 }
166}
167
169{
170 return "key_control<bool>";
171}
172
174{
175 return "toggle:shortcut";
176}
177
178bool key_control<bool>::set_void(const std::string& property, const std::string& value_type, const void* value_ptr)
179{
180 if (property == "toggle") {
181 if (value_type == "shortcut")
182 toggle = *((const shortcut*)value_ptr);
183 else if (value_type == "string")
184 return from_string(toggle, *((const std::string*)value_ptr));
185 else
186 return false;
187 return true;
188 }
189 return false;
190}
191
192bool key_control<bool>::get_void(const std::string& property, const std::string& value_type, void* value_ptr)
193{
194 return cgv::base::base::get_void(property, value_type, value_ptr);
195}
196
197key_control<bool>::key_control(const std::string& _name, bool& _value, const std::string& options): control<bool>(_name,_value)
198{
199 multi_set(options, true);
200}
201
203{
204 if (e.get_kind() != EID_KEY)
205 return false;
206 key_event& ke = static_cast<key_event&>(e);
207 if (ke.get_action() != KA_PRESS)
208 return false;
209 if (ke.get_key() == toggle.get_key() && ke.get_modifiers() == toggle.get_modifiers()) {
210 check_and_set_value(!get_value());
211 return true;
212 }
213 return false;
214}
215
216void key_control<bool>::stream_help(std::ostream& os)
217{
218 os << "toggle " << get_name() << ": <" << toggle << ">" << std::endl;
219}
220
221
222#include "lib_begin.h"
223template class CGV_API key_control<double>;
224template class CGV_API key_control<float>;
225#include <cgv/config/lib_end.h>
226
227
228 }
229}
virtual std::string get_property_declarations()
return a semicolon separated list of property declarations
Definition base.cxx:264
virtual bool set_void(const std::string &property, const std::string &value_type, const void *value_ptr)
abstract interface for the setter of a dynamic property.
Definition base.cxx:181
virtual bool get_void(const std::string &property, const std::string &value_type, void *value_ptr)
abstract interface for the getter of a dynamic property.
Definition base.cxx:215
void multi_set(const std::string &property_assignments, bool report_error=true)
set several properties
Definition base.cxx:287
const T get_value() const
return a reference to the current value
Definition control.h:138
double get_time() const
return the time of the event in seconds
Definition event.cxx:247
unsigned get_kind() const
return, what kind of event this is, typically a value from the EventId enum
Definition event.cxx:202
unsigned char get_modifiers() const
return the active modifiers as values from EventModifier combined with a logical or-operation
Definition event.cxx:237
std::string get_property_declarations()
return a semicolon separated list of property declarations
void stream_help(std::ostream &os)
overload to stream help information to the given output stream
bool self_reflect(cgv::reflect::reflection_handler &rh)
used for simple self reflection
void on_set(void *member_ptr)
this callback is called when the set_void method has changed a member and can be overloaded in derive...
bool set_void(const std::string &property, const std::string &value_type, const void *value_ptr)
abstract interface for the setter of a dynamic property.
std::string get_type_name() const
overload to return the type name of this object
bool handle(event &e)
overload and implement this method to handle events
bool get_void(const std::string &property, const std::string &value_type, void *value_ptr)
abstract interface for the getter of a dynamic property.
class to represent all possible keyboard events with the EID_KEY
Definition key_event.h:23
unsigned short get_key() const
return the key being a capital letter, digit or a value from the Keys enum
Definition key_event.cxx:51
KeyAction get_action() const
return the key event action
Definition key_event.cxx:71
the shortcut class encapsulates a key with modifiers
Definition shortcut.h:84
static double get_current_time()
return the current time
Definition trigger.cxx:70
the self reflection handler is passed to the virtual self_reflect() method of cgv::base::base.
bool reflect_member(const std::string &member_name, T &member_ref, bool hard_cast=false)
call this to reflect a member by member name and reference to the member.
@ KA_PRESS
key press action
Definition key_event.h:14
@ EID_KEY
id for key event
Definition event.h:17
trigger & get_animation_trigger()
return the global trigger used for animation, which runs by default with 60 Hz
Definition trigger.cxx:81
namespace that holds tools that dont fit any other namespace
bool from_string(std::string &v, const std::string &s)
specialization to extract string value from string
the cgv namespace
Definition print.h:11
traits class with a static function get_name() of type const char* that returns the type name of the ...
Definition type_name.h:54