Drop references held by any GUI Lua script after execution
[ardour.git] / gtk2_ardour / note_base.h
1 /*
2  * Copyright (C) 2013-2018 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2014-2015 David Robillard <d@drobilla.net>
4  * Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #ifndef __gtk_ardour_note_base_h__
22 #define __gtk_ardour_note_base_h__
23
24 #include <boost/shared_ptr.hpp>
25
26 #include "temporal/beats.h"
27 #include "canvas/types.h"
28 #include "gtkmm2ext/colors.h"
29
30 #include "rgb_macros.h"
31 #include "ui_config.h"
32
33 class Editor;
34 class MidiRegionView;
35
36 namespace Evoral {
37         template<typename T> class Note;
38         class Beats;
39 }
40
41 namespace ArdourCanvas {
42         class Item;
43         class Text;
44 }
45
46 /** Base class for canvas notes (sustained note rectangles and hit diamonds).
47  *
48  * This is not actually a canvas item itself to avoid the dreaded diamond
49  * inheritance pattern, since various types of canvas items (Note (rect), Hit
50  * (diamond), etc) need to share this functionality but can't share an
51  * ancestor.
52  *
53  * Note: Because of this, derived classes need to manually bounce events to
54  * on_event, it won't happen automatically.
55  */
56 class NoteBase : public sigc::trackable
57 {
58 public:
59         typedef Evoral::Note<Temporal::Beats> NoteType;
60
61         NoteBase (MidiRegionView& region, bool, const boost::shared_ptr<NoteType> note = boost::shared_ptr<NoteType>());
62         virtual ~NoteBase ();
63
64         void set_item (ArdourCanvas::Item *);
65         ArdourCanvas::Item* item() const { return _item; }
66
67         virtual void show() = 0;
68         virtual void hide() = 0;
69
70         bool valid() const { return _valid; }
71         void invalidate ();
72         void validate ();
73
74         bool selected() const { return _selected; }
75         void set_selected(bool yn);
76
77         virtual void move_event(double dx, double dy) = 0;
78
79         uint32_t base_color();
80
81         void show_velocity();
82         void hide_velocity();
83
84         /** Channel changed for this specific event */
85         void on_channel_change(uint8_t channel);
86
87         /** Channel selection changed */
88         void on_channel_selection_change(uint16_t selection);
89
90         virtual void set_outline_color(uint32_t c) = 0;
91         virtual void set_fill_color(uint32_t c) = 0;
92
93         virtual void set_ignore_events(bool ignore) = 0;
94
95         virtual ArdourCanvas::Coord x0 () const = 0;
96         virtual ArdourCanvas::Coord y0 () const = 0;
97         virtual ArdourCanvas::Coord x1 () const = 0;
98         virtual ArdourCanvas::Coord y1 () const = 0;
99
100         float mouse_x_fraction() const { return _mouse_x_fraction; }
101         float mouse_y_fraction() const { return _mouse_y_fraction; }
102
103         const boost::shared_ptr<NoteType> note() const { return _note; }
104         MidiRegionView& region_view() const { return _region; }
105
106         static void set_colors ();
107
108         static Gtkmm2ext::Color meter_style_fill_color(uint8_t vel, bool selected);
109
110         /// calculate outline colors from fill colors of notes
111         inline static uint32_t calculate_outline(uint32_t color, bool selected=false) {
112                 if (selected) {
113                         return _selected_col;
114                 } else {
115                         return UINT_INTERPOLATE(color, 0x000000ff, 0.5);
116                 }
117         }
118
119         /// hue circle divided into 16 equal-looking parts, courtesy Thorsten Wilms
120         static const uint32_t midi_channel_colors[16];
121
122         bool mouse_near_ends () const;
123         virtual bool big_enough_to_trim () const;
124
125 protected:
126         enum State { None, Pressed, Dragging };
127
128         MidiRegionView&                   _region;
129         ArdourCanvas::Item*               _item;
130         ArdourCanvas::Text*               _text;
131         State                             _state;
132         const boost::shared_ptr<NoteType> _note;
133         bool                              _with_events;
134         bool                              _own_note;
135         bool                              _selected;
136         bool                              _valid;
137         float                             _mouse_x_fraction;
138         float                             _mouse_y_fraction;
139
140         void set_mouse_fractions (GdkEvent*);
141
142 private:
143         bool event_handler (GdkEvent *);
144
145         static Gtkmm2ext::Color _selected_col;
146         static Gtkmm2ext::SVAModifier color_modifier;
147         static Gtkmm2ext::Color velocity_color_table[128];
148         static bool _color_init;
149 };
150
151 #endif /* __gtk_ardour_note_h__ */