2 * Copyright (C) 2005-2006 Taybin Rutkin <taybin@taybin.com>
3 * Copyright (C) 2005-2018 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2007 Doug McLain <doug@nostar.net>
5 * Copyright (C) 2008-2011 David Robillard <d@drobilla.net>
6 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
7 * Copyright (C) 2012-2017 Robin Gareus <robin@gareus.org>
8 * Copyright (C) 2015 Colin Fletcher <colin.m.fletcher@googlemail.com>
9 * Copyright (C) 2016-2017 Nick Mainsbridge <mainsbridge@gmail.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #ifndef __audio_clock_h__
27 #define __audio_clock_h__
34 #include <gtkmm/alignment.h>
35 #include <gtkmm/box.h>
36 #include <gtkmm/menu.h>
37 #include <gtkmm/label.h>
39 #include "ardour/ardour.h"
40 #include "ardour/session_handle.h"
42 #include "gtkmm2ext/cairo_widget.h"
43 #include "widgets/ardour_button.h"
49 class AudioClock : public CairoWidget, public ARDOUR::SessionHandlePtr
60 AudioClock (const std::string& clock_name, bool is_transient, const std::string& widget_name,
61 bool editable, bool follows_playhead, bool duration = false, bool with_info = false,
62 bool accept_on_focus_out = false);
65 Mode mode() const { return _mode; }
66 void set_off (bool yn);
67 bool off() const { return _off; }
68 bool on() const { return !_off; }
69 void set_widget_name (const std::string& name);
70 void set_active_state (Gtkmm2ext::ActiveState s);
71 void set_editable (bool yn);
72 void set_corner_radius (double);
76 virtual void set (samplepos_t, bool force = false, ARDOUR::samplecnt_t offset = 0);
77 void set_from_playhead ();
79 void set_mode (Mode, bool noemit = false);
80 void set_bbt_reference (samplepos_t);
81 void set_is_duration (bool);
83 void copy_text_to_clipboard () const;
85 std::string name() const { return _name; }
87 samplepos_t current_time (samplepos_t position = 0) const;
88 samplepos_t current_duration (samplepos_t position = 0) const;
89 void set_session (ARDOUR::Session *s);
90 void set_negative_allowed (bool yn);
92 ArdourWidgets::ArdourButton* left_btn () { return &_left_btn; }
93 ArdourWidgets::ArdourButton* right_btn () { return &_right_btn; }
95 /** Alter cairo scaling during rendering.
97 * Used by clocks that resize themselves
98 * to fit any given space. Can lead
101 void set_scale (double x, double y);
103 static void print_minsec (samplepos_t, char* buf, size_t bufsize, float sample_rate);
105 sigc::signal<void> ValueChanged;
106 sigc::signal<void> mode_changed;
107 sigc::signal<void> ChangeAborted;
109 static sigc::signal<void> ModeChanged;
110 static std::vector<AudioClock*> clocks;
113 void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
114 bool get_is_duration () const { return is_duration; }
115 ARDOUR::samplecnt_t offset () const { return _offset; }
117 virtual void build_ops_menu ();
120 bool on_button_press_event (GdkEventButton *ev);
121 bool on_button_release_event(GdkEventButton *ev);
123 ArdourWidgets::ArdourButton _left_btn;
124 ArdourWidgets::ArdourButton _right_btn;
132 /** true if this clock follows the playhead, meaning that certain operations are redundant */
133 bool _follows_playhead;
134 bool _accept_on_focus_out;
137 bool _edit_by_click_field;
138 bool _negative_allowed;
139 bool edit_is_negative;
141 samplepos_t _limit_pos;
143 ARDOUR::samplecnt_t _offset;
145 Glib::RefPtr<Pango::Layout> _layout;
149 Pango::AttrColor* editing_attr;
150 Pango::AttrColor* foreground_attr;
152 Pango::AttrList normal_attributes;
153 Pango::AttrList editing_attributes;
157 bool style_resets_first;
160 double corner_radius;
163 static const double info_font_scale_factor;
164 static const double separator_height;
165 static const double x_leading_padding;
184 Field index_to_field (int index) const;
186 /* this maps the number of input characters/digits when editing
187 to a cursor position. insert_map[N] = index of character/digit
188 where the cursor should be after N chars/digits. it is
189 mode specific and so it is filled during set_mode().
192 std::vector<int> insert_map;
195 std::string edit_string;
196 std::string pre_edit_string;
197 std::string input_string;
199 samplepos_t bbt_reference_time;
200 samplepos_t last_when;
211 bool on_key_press_event (GdkEventKey *);
212 bool on_key_release_event (GdkEventKey *);
213 bool on_scroll_event (GdkEventScroll *ev);
214 void on_style_changed (const Glib::RefPtr<Gtk::Style>&);
215 void on_size_request (Gtk::Requisition* req);
216 bool on_motion_notify_event (GdkEventMotion *ev);
217 bool on_focus_out_event (GdkEventFocus*);
219 void set_slave_info ();
220 void set_timecode (samplepos_t, bool);
221 void set_bbt (samplepos_t, ARDOUR::samplecnt_t, bool);
222 void set_minsec (samplepos_t, bool);
223 void set_seconds (samplepos_t, bool);
224 void set_samples (samplepos_t, bool);
225 void set_out_of_bounds (bool negative);
227 void set_clock_dimensions (Gtk::Requisition&);
229 samplepos_t get_sample_step (Field, samplepos_t pos = 0, int dir = 1);
231 bool timecode_validate_edit (const std::string&);
232 bool bbt_validate_edit (std::string&);
233 bool minsec_validate_edit (const std::string&);
235 samplepos_t samples_from_timecode_string (const std::string&) const;
236 samplepos_t samples_from_bbt_string (samplepos_t, const std::string&) const;
237 samplepos_t sample_duration_from_bbt_string (samplepos_t, const std::string&) const;
238 samplepos_t samples_from_minsec_string (const std::string&) const;
239 samplepos_t samples_from_seconds_string (const std::string&) const;
240 samplepos_t samples_from_audiosamples_string (const std::string&) const;
242 void session_configuration_changed (std::string);
243 void session_property_changed (const PBD::PropertyChange&);
245 Field index_to_field () const;
247 void start_edit (Field f = Field (0));
248 void end_edit (bool);
249 void end_edit_relative (bool);
250 void edit_next_field ();
251 ARDOUR::samplecnt_t parse_as_distance (const std::string&);
253 ARDOUR::samplecnt_t parse_as_timecode_distance (const std::string&);
254 ARDOUR::samplecnt_t parse_as_minsec_distance (const std::string&);
255 ARDOUR::samplecnt_t parse_as_bbt_distance (const std::string&);
256 ARDOUR::samplecnt_t parse_as_seconds_distance (const std::string&);
257 ARDOUR::samplecnt_t parse_as_samples_distance (const std::string&);
259 void set_font (Pango::FontDescription);
261 void show_edit_status (int length);
262 int merge_input_and_edit_string ();
263 std::string get_field (Field);
268 double bg_r, bg_g, bg_b, bg_a;
269 double cursor_r, cursor_g, cursor_b, cursor_a;
275 #endif /* __audio_clock_h__ */