Ardour  8.7-14-g57a6773833
m2_button.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
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 2 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 along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef _ardour_surfaces_m2button_h_
20 #define _ardour_surfaces_m2button_h_
21 
22 #include <stdint.h>
23 #include "gtkmm2ext/colors.h"
24 #include "pbd/signals.h"
25 
26 namespace ArdourSurface {
27 
29 {
30  public:
32  virtual ~M2ButtonInterface () {}
33 
34  /* user API */
35  PBD::Signal1<void, bool> changed;
36  PBD::Signal0<void> pressed;
37  PBD::Signal0<void> released;
38 
39  virtual void set_blinking (bool) {}
40  virtual void set_color (uint32_t rgba) {}
41 
42  virtual bool is_pressed () const { return false; }
43  virtual bool active () const { return is_pressed (); }
44 
45  virtual void ignore_release () {}
46 
47  // TODO allow to suspend *next* release signal
48  // e.g. press + hold "grid", move encoder -> release "grid" -> noop
49 
50  /* internal API - called from device thread */
51  virtual bool set_active (bool a) { return false; }
52  virtual uint8_t lightness (float) const { return 0; }
53  virtual uint32_t color (float) const { return 0; }
54 };
55 
57 {
58  public:
61  , _pressed (false)
62  , _blink (false)
63  , _ignore_release (false)
64  , _lightness (0)
65  , _rgba (0)
66  {}
67 
68  /* user API */
69  void set_blinking (bool en) {
70  _blink = en;
71  }
72 
73  virtual void set_color (uint32_t rgba) {
74  _rgba = rgba;
75  /* 7 bit color */
76  const uint8_t r = ((rgba >> 24) & 0xff) >> 1;
77  const uint8_t g = ((rgba >> 16) & 0xff) >> 1;
78  const uint8_t b = ((rgba >> 8) & 0xff) >> 1;
79  _lightness = std::max (r, std::max (g, b));
80  }
81 
82  bool is_pressed () const { return _pressed; }
83 
84  void ignore_release () {
85  if (_pressed) {
86  _ignore_release = true;
87  }
88  }
89 
90  /* internal API - called from device thread */
91  virtual bool set_active (bool a) {
92  if (a == _pressed) {
93  return false;
94  }
95  _pressed = a;
96 
97  if (a) {
98  pressed (); /* EMIT SIGNAL */
99  } else {
100  if (_ignore_release) {
101  _ignore_release = false;
102  } else {
103  released (); /* EMIT SIGNAL */
104  }
105  }
106  changed (a); /* EMIT SIGNAL */
107  return true;
108  }
109 
110  uint8_t lightness (float blink) const {
111  if (_blink && blink >= 0.f && blink <= 1.f) {
112  return (uint8_t) floorf(blink * _lightness);
113  }
114  return _lightness;
115  }
116 
117  uint32_t color (float blink) const {
118  if (_blink && blink >= 0.f && blink <= 1.f) {
119  Gtkmm2ext::HSV hsv (_rgba);
120  Gtkmm2ext::HSV s (hsv.shade (blink));
121  return s.color();
122  }
123  return _rgba;
124  }
125 
126  protected:
127  bool _pressed;
128  bool _blink;
130  uint8_t _lightness;
131  uint32_t _rgba;
132 };
133 
135 {
136  public:
138 
139  bool set_active (bool a) {
140  if (a == _pressed) {
141  return false;
142  }
143  if (a) {
144  set_color (0xffffffff);
145  } else {
146  set_color (0x000000ff);
147  }
148  return M2Button::set_active (a);
149  }
150 };
151 
152 class M2ToggleButton : public M2Button
153 {
154  public:
156  : M2Button ()
157  , _active (false)
158  {
159  changed.connect_same_thread (changed_connection, boost::bind (&M2ToggleButton::change_event, this, _1));
160  }
161 
162  PBD::Signal1<void, bool> toggled;
163  bool active () const { return _active; }
164 
165  protected:
166  void change_event (bool down) {
167  if (down) { return; }
168  _active = !_active;
169  set_color (_active ? 0xffffffff : 0x000000ff);
170  toggled (_active);
171  }
172 
174  bool _active;
175 };
176 
178 {
179  public:
181  : M2Button ()
182  , _active (false)
183  , _active_on_release (false)
184  {
185  changed.connect_same_thread (changed_connection, boost::bind (&M2ToggleHoldButton::change_event, this, _1));
186  }
187 
188  PBD::Signal1<void, bool> toggled;
189  bool active () const { return _active; }
190  void unset_active_on_release () { if (is_pressed ()) { _active_on_release = false; } }
191 
192  protected:
193  void change_event (bool down) {
194  if (down) {
195  if (_active) {
196  _active_on_release = false;
197  return;
198  }
199  _active = true;
200  _active_on_release = true;
201  } else {
202  if (_active == _active_on_release) {
203  return;
204  }
206  }
207 
208  set_color (_active ? 0xffffffff : 0x000000ff);
209  toggled (_active);
210  }
211 
213  bool _active;
215 };
216 
217 
218 } /* namespace */
219 #endif /* _ardour_surfaces_m2button_h_ */
220 
PBD::Signal0< void > pressed
Definition: m2_button.h:36
PBD::Signal1< void, bool > changed
Definition: m2_button.h:35
virtual uint32_t color(float) const
Definition: m2_button.h:53
virtual uint8_t lightness(float) const
Definition: m2_button.h:52
virtual bool set_active(bool a)
Definition: m2_button.h:51
virtual bool active() const
Definition: m2_button.h:43
virtual bool is_pressed() const
Definition: m2_button.h:42
virtual void set_blinking(bool)
Definition: m2_button.h:39
virtual void set_color(uint32_t rgba)
Definition: m2_button.h:40
PBD::Signal0< void > released
Definition: m2_button.h:37
uint8_t lightness(float blink) const
Definition: m2_button.h:110
uint32_t color(float blink) const
Definition: m2_button.h:117
virtual void set_color(uint32_t rgba)
Definition: m2_button.h:73
void set_blinking(bool en)
Definition: m2_button.h:69
bool is_pressed() const
Definition: m2_button.h:82
virtual bool set_active(bool a)
Definition: m2_button.h:91
PBD::ScopedConnection changed_connection
Definition: m2_button.h:173
void change_event(bool down)
Definition: m2_button.h:166
PBD::Signal1< void, bool > toggled
Definition: m2_button.h:162
PBD::Signal1< void, bool > toggled
Definition: m2_button.h:188
PBD::ScopedConnection changed_connection
Definition: m2_button.h:212
Color color() const
Definition: colors.h:110
HSV shade(double factor) const