mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 00:34:59 +01:00
next iteration of clock work. still far from complete, and probably waiting on a rethink of text rendering+layout. but it has the info block now, and it semi-works
git-svn-id: svn://localhost/ardour2/branches/3.0@9676 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
11bcfd8429
commit
e77b5261d2
11 changed files with 696 additions and 525 deletions
|
|
@ -942,7 +942,7 @@ style "recording_big_clock_display" = "non_recording_big_clock_display"
|
|||
|
||||
style "transport_clock_display"
|
||||
{
|
||||
font_name = "@FONT_BOLD_BIG@"
|
||||
font_name = "monospace @FONT_BOLD_BIG@"
|
||||
|
||||
fg[ACTIVE] = darker(@@COLPREFIX@_bright_indicator)
|
||||
fg[SELECTED] = darker(@@COLPREFIX@_bright_indicator)
|
||||
|
|
@ -989,6 +989,35 @@ style "default_clock_display" = "medium_text"
|
|||
bg[ACTIVE] = @@COLPREFIX@_darkest
|
||||
}
|
||||
|
||||
style "selection_clock_display"
|
||||
{
|
||||
font_name = "monospace @FONT_SMALLER@"
|
||||
|
||||
text[NORMAL] = @@COLPREFIX@_contrasting_indicator
|
||||
text[ACTIVE] = @@COLPREFIX@_bright_indicator
|
||||
fg[NORMAL] = @@COLPREFIX@_contrasting_indicator
|
||||
fg[ACTIVE] = @@COLPREFIX@_bright_indicator
|
||||
fg[SELECTED] = @@COLPREFIX@_bright_indicator
|
||||
base[NORMAL] = @@COLPREFIX@_darkest
|
||||
base[ACTIVE] = @@COLPREFIX@_darkest
|
||||
bg[NORMAL] = @@COLPREFIX@_darkest
|
||||
bg[ACTIVE] = @@COLPREFIX@_darkest
|
||||
}
|
||||
|
||||
style "punch_clock_display" = "very_small_text"
|
||||
{
|
||||
font_name = "monospace @FONT_SMALLER@"
|
||||
|
||||
text[NORMAL] = @@COLPREFIX@_contrasting_indicator
|
||||
text[ACTIVE] = @@COLPREFIX@_bright_indicator
|
||||
fg[NORMAL] = @@COLPREFIX@_contrasting_indicator
|
||||
fg[ACTIVE] = @@COLPREFIX@_bright_indicator
|
||||
fg[SELECTED] = @@COLPREFIX@_bright_indicator
|
||||
base[NORMAL] = @@COLPREFIX@_darkest
|
||||
base[ACTIVE] = @@COLPREFIX@_darkest
|
||||
bg[NORMAL] = @@COLPREFIX@_darkest
|
||||
bg[ACTIVE] = @@COLPREFIX@_darkest
|
||||
}
|
||||
|
||||
style "white_on_black_clock_display" = "medium_text"
|
||||
{
|
||||
|
|
@ -1599,6 +1628,8 @@ widget "*InfoMessage" style:highest "info_message"
|
|||
widget "*WarningMessage" style:highest "warning_message"
|
||||
widget "*BigClockNonRecording" style:highest "non_recording_big_clock_display"
|
||||
widget "*BigClockRecording" style:highest "recording_big_clock_display"
|
||||
widget "*SelectionClockDisplay" style:highest "selection_clock_display"
|
||||
widget "*PunchClockDisplay" style:highest "punch_clock_display"
|
||||
widget "*TransportClockDisplay" style:highest "transport_clock_display"
|
||||
widget "*SecondaryClockDisplay" style:highest "transport_clock_display"
|
||||
widget "*TransportClockDisplayDelta" style:highest "transport_clock_display_delta"
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class ShuttleControl;
|
|||
class Splash;
|
||||
class SpeakerDialog;
|
||||
class ThemeManager;
|
||||
class TimeInfoBox;
|
||||
class MidiTracer;
|
||||
class WindowProxyBase;
|
||||
class GlobalPortMatrixWindow;
|
||||
|
|
@ -197,6 +198,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
|||
AudioClock* preroll_clock;
|
||||
AudioClock* postroll_clock;
|
||||
|
||||
TimeInfoBox* time_info_box;
|
||||
|
||||
void store_clock_modes ();
|
||||
void restore_clock_modes ();
|
||||
void reset_main_clocks ();
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "pbd/error.h"
|
||||
#include "pbd/basename.h"
|
||||
#include "pbd/fastlog.h"
|
||||
#include <gtkmm2ext/cairocell.h>
|
||||
#include <gtkmm2ext/utils.h>
|
||||
#include <gtkmm2ext/click_box.h>
|
||||
#include <gtkmm2ext/tearoff.h>
|
||||
|
|
@ -54,6 +55,7 @@
|
|||
#include "global_port_matrix.h"
|
||||
#include "location_ui.h"
|
||||
#include "rc_option_editor.h"
|
||||
#include "time_info_box.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -385,8 +387,13 @@ ARDOUR_UI::setup_transport ()
|
|||
transport_hbox->pack_start (rec_button, false, false, 6);
|
||||
|
||||
HBox* clock_box = manage (new HBox);
|
||||
clock_box->set_border_width (2);
|
||||
primary_clock->main_display().set_ypad (2);
|
||||
primary_clock->set_border_width (2);
|
||||
clock_box->pack_start (*primary_clock, false, false);
|
||||
if (!ARDOUR::Profile->get_small_screen()) {
|
||||
secondary_clock->set_border_width (2);
|
||||
secondary_clock->main_display().set_ypad (2);
|
||||
clock_box->pack_start (*secondary_clock, false, false);
|
||||
}
|
||||
|
||||
|
|
@ -410,6 +417,9 @@ ARDOUR_UI::setup_transport ()
|
|||
transport_tearoff_hbox.pack_start (*transport_vbox, false, false, 0);
|
||||
transport_tearoff_hbox.pack_start (*clock_box, false, false, 0);
|
||||
|
||||
time_info_box = manage (new TimeInfoBox);
|
||||
transport_tearoff_hbox.pack_start (*time_info_box, false, false);
|
||||
|
||||
HBox* toggle_box = manage(new HBox);
|
||||
|
||||
VBox* punch_box = manage (new VBox);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "speaker_dialog.h"
|
||||
#include "sfdb_ui.h"
|
||||
#include "theme_manager.h"
|
||||
#include "time_info_box.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
@ -97,6 +98,7 @@ ARDOUR_UI::set_session (Session *s)
|
|||
big_clock->set_session (s);
|
||||
preroll_clock->set_session (s);
|
||||
postroll_clock->set_session (s);
|
||||
time_info_box->set_session (s);
|
||||
|
||||
/* sensitize menu bar options that are now valid */
|
||||
|
||||
|
|
|
|||
|
|
@ -54,34 +54,19 @@ using PBD::atof;
|
|||
sigc::signal<void> AudioClock::ModeChanged;
|
||||
vector<AudioClock*> AudioClock::clocks;
|
||||
|
||||
std::map<AudioClock::Field,uint32_t> AudioClock::field_length;
|
||||
|
||||
void
|
||||
AudioClock::fill_field_lengths()
|
||||
{
|
||||
field_length[Timecode_Hours] = 2;
|
||||
field_length[Timecode_Minutes] = 2;
|
||||
field_length[Timecode_Seconds] = 2;
|
||||
field_length[Timecode_Frames] = 2;
|
||||
field_length[MS_Hours] = 2;
|
||||
field_length[MS_Minutes] = 2;
|
||||
field_length[MS_Seconds] = 2;
|
||||
field_length[MS_Milliseconds] = 3;
|
||||
field_length[Bars] = 4;
|
||||
field_length[Beats] = 2;
|
||||
field_length[Ticks] = 4;
|
||||
field_length[AudioFrames] = 10;
|
||||
|
||||
field_length[Timecode_LowerLeft1] = 4;
|
||||
field_length[Timecode_LowerLeft2] = 4;
|
||||
field_length[Timecode_LowerRight1] = 3;
|
||||
field_length[Timecode_LowerRight2] = 6; // 29.97 D
|
||||
|
||||
field_length[BBT_LowerLeft1] = 1;
|
||||
field_length[BBT_LowerLeft2] = 7;
|
||||
field_length[BBT_LowerRight1] = 1;
|
||||
field_length[BBT_LowerRight2] = 3;
|
||||
|
||||
uint32_t AudioClock::field_length[] = {
|
||||
2, /* Timecode_Hours */
|
||||
2, /* Timecode_Minutes */
|
||||
2, /* Timecode_Seconds */
|
||||
2, /* Timecode_Frames */
|
||||
2, /* MS_Hours */
|
||||
2, /* MS_Minutes */
|
||||
2, /* MS_Seconds */
|
||||
3, /* MS_Milliseconds */
|
||||
4, /* Bars */
|
||||
2, /* Beats */
|
||||
4, /* Ticks */
|
||||
10, /* AudioFrames */
|
||||
};
|
||||
|
||||
AudioClock::AudioClock (const string& clock_name, bool transient, const string& widget_name,
|
||||
|
|
@ -91,22 +76,12 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string&
|
|||
, is_duration (duration)
|
||||
, editable (allow_edit)
|
||||
, _follows_playhead (follows_playhead)
|
||||
, timecode_supplemental_left (0)
|
||||
, timecode_supplemental_right (0)
|
||||
, bbt_supplemental_left (0)
|
||||
, bbt_supplemental_right (0)
|
||||
, supplemental_left (0)
|
||||
, supplemental_right (0)
|
||||
, last_when(0)
|
||||
, _canonical_time_is_displayed (true)
|
||||
, _canonical_time (0)
|
||||
{
|
||||
CairoTextCell* tc;
|
||||
CairoBarCell* bc;
|
||||
CairoColonCell* cc;
|
||||
|
||||
if (field_length.empty()) {
|
||||
fill_field_lengths ();
|
||||
}
|
||||
|
||||
last_when = 0;
|
||||
|
||||
last_hrs = 9999;
|
||||
|
|
@ -128,193 +103,71 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string&
|
|||
dragging = false;
|
||||
bbt_reference_time = -1;
|
||||
editing_field = (Field) 0;
|
||||
current_cet = 0;
|
||||
|
||||
frames_upper_info_label = 0;
|
||||
frames_lower_info_label = 0;
|
||||
|
||||
/* basic per-mode editable text "arrays" */
|
||||
|
||||
timecode = new CairoEditableText ();
|
||||
minsec = new CairoEditableText ();
|
||||
bbt = new CairoEditableText ();
|
||||
frames = new CairoEditableText ();
|
||||
display = new CairoEditableText ();
|
||||
|
||||
// add an extra 0.6 "average char width" for the negative sign
|
||||
tc = new CairoTextCell (field_length[Timecode_Hours] + 0.6);
|
||||
_text_cells[Timecode_Hours] = tc;
|
||||
timecode->add_cell (Timecode_Hours, tc);
|
||||
|
||||
cc = new CairoColonCell ();
|
||||
_fixed_cells[Timecode_Colon1] = cc;
|
||||
timecode->add_cell (Timecode_Colon1, cc);
|
||||
|
||||
tc = new CairoTextCell (field_length[Timecode_Minutes]);
|
||||
_text_cells[Timecode_Minutes] = tc;
|
||||
timecode->add_cell (Timecode_Minutes, tc);
|
||||
_fixed_cells[Colon1] = new CairoColonCell (Colon1);
|
||||
_fixed_cells[Colon2] = new CairoColonCell (Colon2);
|
||||
_fixed_cells[Colon3] = new CairoColonCell (Colon3);
|
||||
_fixed_cells[Bar1] = new CairoBarCell (Bar1);
|
||||
_fixed_cells[Bar2] = new CairoBarCell (Bar2);
|
||||
|
||||
cc = new CairoColonCell ();
|
||||
_fixed_cells[Timecode_Colon2] = cc;
|
||||
timecode->add_cell (Timecode_Colon2, cc);
|
||||
|
||||
tc = new CairoTextCell (field_length[Timecode_Seconds]);
|
||||
_text_cells[Timecode_Seconds] = tc;
|
||||
timecode->add_cell (Timecode_Seconds, tc);
|
||||
|
||||
cc = new CairoColonCell ();
|
||||
_fixed_cells[Timecode_Colon3] = cc;
|
||||
timecode->add_cell (Timecode_Colon3, cc);
|
||||
|
||||
tc = new CairoTextCell (field_length[Timecode_Frames]);
|
||||
_text_cells[Timecode_Frames] = tc;
|
||||
timecode->add_cell (Timecode_Frames, tc);
|
||||
// add an extra 0.6 "average char width" for the negative sign
|
||||
_text_cells[Timecode_Hours] = new CairoTextCell (Timecode_Hours, field_length[Timecode_Hours] + 0.6);
|
||||
_text_cells[Timecode_Minutes] = new CairoTextCell (Timecode_Minutes, field_length[Timecode_Minutes]);
|
||||
_text_cells[Timecode_Seconds] = new CairoTextCell (Timecode_Seconds, field_length[Timecode_Seconds]);
|
||||
_text_cells[Timecode_Frames] = new CairoTextCell (Timecode_Frames, field_length[Timecode_Frames]);
|
||||
|
||||
/* Minutes/Seconds */
|
||||
|
||||
tc = new CairoTextCell (field_length[MS_Hours]);
|
||||
_text_cells[MS_Hours] = tc;
|
||||
minsec->add_cell (MS_Hours, tc);
|
||||
|
||||
cc = new CairoColonCell ();
|
||||
_fixed_cells[MS_Colon1] = cc;
|
||||
minsec->add_cell (MS_Colon1, cc);
|
||||
|
||||
tc = new CairoTextCell (field_length[MS_Minutes]);
|
||||
_text_cells[MS_Minutes] = tc;
|
||||
minsec->add_cell (MS_Minutes, tc);
|
||||
|
||||
cc = new CairoColonCell ();
|
||||
_fixed_cells[MS_Colon2] = cc;
|
||||
minsec->add_cell (MS_Colon2, cc);
|
||||
|
||||
tc = new CairoTextCell (field_length[MS_Seconds]);
|
||||
_text_cells[MS_Seconds] = tc;
|
||||
minsec->add_cell (MS_Seconds, tc);
|
||||
|
||||
cc = new CairoColonCell ();
|
||||
_fixed_cells[MS_Colon3] = cc;
|
||||
minsec->add_cell (MS_Colon3, cc);
|
||||
|
||||
tc = new CairoTextCell (field_length[MS_Milliseconds]);
|
||||
_text_cells[MS_Milliseconds] = tc;
|
||||
minsec->add_cell (MS_Milliseconds, tc);
|
||||
_text_cells[MS_Hours] = new CairoTextCell (MS_Hours, field_length[MS_Hours]);
|
||||
_text_cells[MS_Minutes] = new CairoTextCell (MS_Minutes, field_length[MS_Minutes]);
|
||||
_text_cells[MS_Seconds] = new CairoTextCell (MS_Seconds, field_length[MS_Seconds]);
|
||||
_text_cells[MS_Milliseconds] = new CairoTextCell (MS_Milliseconds, field_length[MS_Milliseconds]);
|
||||
|
||||
/* Beats/Bars/Ticks */
|
||||
|
||||
tc = new CairoTextCell (field_length[Bars]);
|
||||
_text_cells[Bars] = tc;
|
||||
bbt->add_cell (Bars, tc);
|
||||
|
||||
bc = new CairoBarCell ();
|
||||
_fixed_cells[BBT_Bar1] = bc;
|
||||
bbt->add_cell (BBT_Bar1, bc);
|
||||
|
||||
tc = new CairoTextCell (field_length[Beats]);
|
||||
_text_cells[Beats] = tc;
|
||||
bbt->add_cell (Beats, tc);
|
||||
|
||||
bc = new CairoBarCell ();
|
||||
_fixed_cells[BBT_Bar2] = bc;
|
||||
bbt->add_cell (BBT_Bar2, bc);
|
||||
|
||||
tc = new CairoTextCell (field_length[Ticks]);
|
||||
_text_cells[Ticks] = tc;
|
||||
bbt->add_cell (Ticks, tc);
|
||||
_text_cells[Bars] = new CairoTextCell (Bars, field_length[Bars]);
|
||||
_text_cells[Beats] = new CairoTextCell (Beats, field_length[Beats]);
|
||||
_text_cells[Ticks] = new CairoTextCell (Ticks, field_length[Ticks]);
|
||||
|
||||
/* Audio Frames */
|
||||
|
||||
tc = new CairoTextCell (field_length[AudioFrames]);
|
||||
_text_cells[AudioFrames] = tc;
|
||||
frames->add_cell (AudioFrames, tc);
|
||||
_text_cells[AudioFrames] = new CairoTextCell (AudioFrames, field_length[AudioFrames]);
|
||||
|
||||
frames_packer.set_homogeneous (false);
|
||||
frames_packer.set_border_width (2);
|
||||
frames_packer.pack_start (*frames);
|
||||
|
||||
/* Timecode */
|
||||
|
||||
timecode_packer.set_homogeneous (false);
|
||||
timecode_packer.set_border_width (2);
|
||||
packer.set_homogeneous (false);
|
||||
|
||||
if (with_info) {
|
||||
timecode_supplemental_left = new CairoEditableText ();
|
||||
tc = new CairoTextCell (field_length[Timecode_LowerLeft1]);
|
||||
_text_cells[Timecode_LowerLeft1] = tc;
|
||||
timecode_supplemental_left->add_cell (Timecode_LowerLeft1, tc);
|
||||
tc = new CairoTextCell (field_length[Timecode_LowerLeft2]);
|
||||
_text_cells[Timecode_LowerLeft2] = tc;
|
||||
timecode_supplemental_left->add_cell (Timecode_LowerLeft2, tc);
|
||||
|
||||
timecode_supplemental_right = new CairoEditableText ();
|
||||
tc = new CairoTextCell (field_length[Timecode_LowerRight1]);
|
||||
_text_cells[Timecode_LowerRight1] = tc;
|
||||
timecode_supplemental_right->add_cell (Timecode_LowerRight1, tc);
|
||||
tc = new CairoTextCell (field_length[Timecode_LowerRight2]);
|
||||
_text_cells[Timecode_LowerRight2] = tc;
|
||||
timecode_supplemental_right->add_cell (Timecode_LowerRight2, tc);
|
||||
|
||||
timecode_supplemental_right->set_text (Timecode_LowerRight1, "FPS");
|
||||
/* LowerRight2 is set dynamically */
|
||||
|
||||
timecode_bottom.set_spacing (1);
|
||||
timecode_bottom.set_homogeneous (false);
|
||||
timecode_bottom.pack_start (*timecode_supplemental_left, true, true);
|
||||
timecode_bottom.pack_start (*timecode_supplemental_right, true, true);
|
||||
supplemental_left = new CairoEditableText ();
|
||||
supplemental_right = new CairoEditableText ();
|
||||
|
||||
timecode_top.pack_start (*timecode, true, true);
|
||||
/* field lengths of these cells will be set dynamically by ::set_mode()
|
||||
*/
|
||||
|
||||
_text_cells[LowerLeft1] = new CairoTextCell (LowerLeft1, 0);
|
||||
_text_cells[LowerLeft2] = new CairoTextCell (LowerLeft2, 0);
|
||||
_text_cells[LowerRight1] = new CairoTextCell (LowerRight1, 0);
|
||||
_text_cells[LowerRight2] = new CairoTextCell (LowerRight2, 0);
|
||||
|
||||
timecode_packer.set_spacing (1);
|
||||
timecode_packer.pack_start (timecode_top, true, true);
|
||||
timecode_packer.pack_start (timecode_bottom, false, false);
|
||||
bottom.set_spacing (1);
|
||||
bottom.set_homogeneous (false);
|
||||
bottom.pack_start (*supplemental_left, true, true);
|
||||
bottom.pack_start (*supplemental_right, true, true);
|
||||
|
||||
top.pack_start (*display, true, true);
|
||||
|
||||
packer.set_spacing (1);
|
||||
packer.pack_start (top, true, true);
|
||||
packer.pack_start (bottom, false, false);
|
||||
} else {
|
||||
timecode_packer.pack_start (*timecode, true, true);
|
||||
packer.pack_start (*display, true, true);
|
||||
}
|
||||
|
||||
/* BBT */
|
||||
|
||||
bbt_packer.set_homogeneous (false);
|
||||
bbt_packer.set_border_width (2);
|
||||
|
||||
if (with_info) {
|
||||
bbt_supplemental_left = new CairoEditableText ();
|
||||
tc = new CairoTextCell (field_length[BBT_LowerLeft1]);
|
||||
_text_cells[BBT_LowerLeft1] = tc;
|
||||
bbt_supplemental_left->add_cell (BBT_LowerLeft1, tc);
|
||||
tc = new CairoTextCell (field_length[BBT_LowerLeft2]);
|
||||
_text_cells[BBT_LowerLeft2] = tc;
|
||||
bbt_supplemental_left->add_cell (BBT_LowerLeft2, tc);
|
||||
|
||||
bbt_supplemental_right = new CairoEditableText ();
|
||||
tc = new CairoTextCell (field_length[BBT_LowerRight1]);
|
||||
_text_cells[BBT_LowerRight1] = tc;
|
||||
bbt_supplemental_right->add_cell (BBT_LowerRight1, tc);
|
||||
tc = new CairoTextCell (field_length[BBT_LowerRight2]);
|
||||
_text_cells[BBT_LowerRight2] = tc;
|
||||
bbt_supplemental_right->add_cell (BBT_LowerRight2, tc);
|
||||
|
||||
bbt_supplemental_left->set_text (BBT_LowerLeft1, _("M")); // M is for meter
|
||||
bbt_supplemental_right->set_text (BBT_LowerRight1, _("T")); // T is for tempo
|
||||
|
||||
/* LowerLeft2 and LowerRight2 are set dynamically */
|
||||
|
||||
bbt_bottom.set_spacing (1);
|
||||
bbt_bottom.set_homogeneous (false);
|
||||
bbt_bottom.pack_start (*bbt_supplemental_left, true, true);
|
||||
bbt_bottom.pack_start (*bbt_supplemental_right, true, true);
|
||||
|
||||
bbt_top.pack_start (*bbt, true, true);
|
||||
|
||||
bbt_packer.set_spacing (1);
|
||||
bbt_packer.pack_start (bbt_top, true, true);
|
||||
bbt_packer.pack_start (bbt_bottom, false, false);
|
||||
|
||||
} else {
|
||||
bbt_packer.pack_start (*bbt);
|
||||
}
|
||||
|
||||
minsec_packer.set_homogeneous (false);
|
||||
minsec_packer.set_border_width (2);
|
||||
minsec_packer.pack_start (*minsec);
|
||||
add (packer);
|
||||
show_all ();
|
||||
|
||||
set_widget_name (widget_name);
|
||||
|
||||
|
|
@ -332,16 +185,21 @@ AudioClock::~AudioClock ()
|
|||
/* these are not manage()'d, so that we can add/remove
|
||||
them from containers as necessary.
|
||||
*/
|
||||
delete timecode;
|
||||
delete minsec;
|
||||
delete bbt;
|
||||
delete frames;
|
||||
delete timecode_supplemental_left;
|
||||
delete timecode_supplemental_right;
|
||||
delete display;
|
||||
delete supplemental_left;
|
||||
delete supplemental_right;
|
||||
/* XXX need to delete all cells too */
|
||||
}
|
||||
|
||||
void
|
||||
AudioClock::set_widget_name (string name)
|
||||
AudioClock::set_font (const string& font)
|
||||
{
|
||||
display->set_font (font);
|
||||
/* XXX supplemental ... */
|
||||
}
|
||||
|
||||
void
|
||||
AudioClock::set_widget_name (const string& name)
|
||||
{
|
||||
Widget::set_name (name);
|
||||
|
||||
|
|
@ -366,18 +224,13 @@ AudioClock::set_theme ()
|
|||
font = style->get_font();
|
||||
}
|
||||
|
||||
timecode->set_font (font);
|
||||
minsec->set_font (font);
|
||||
bbt->set_font (font);
|
||||
frames->set_font (font);
|
||||
display->set_font (font);
|
||||
|
||||
if (timecode_supplemental_right) {
|
||||
if (supplemental_right) {
|
||||
Pango::FontDescription smaller_font ("Sans 8");
|
||||
|
||||
timecode_supplemental_right->set_font (smaller_font);
|
||||
timecode_supplemental_left->set_font (smaller_font);
|
||||
bbt_supplemental_right->set_font (smaller_font);
|
||||
bbt_supplemental_left->set_font (smaller_font);
|
||||
supplemental_right->set_font (smaller_font);
|
||||
supplemental_left->set_font (smaller_font);
|
||||
}
|
||||
|
||||
Gdk::Color bg = style->get_base (Gtk::STATE_NORMAL);
|
||||
|
|
@ -389,16 +242,11 @@ AudioClock::set_theme ()
|
|||
b = bg.get_blue_p ();
|
||||
a = 1.0;
|
||||
|
||||
timecode->set_bg (r, g, b, a);
|
||||
minsec->set_bg (r, g, b, a);
|
||||
bbt->set_bg (r, g, b, a);
|
||||
frames->set_bg (r, g, b, a);
|
||||
display->set_bg (r, g, b, a);
|
||||
|
||||
if (timecode_supplemental_right) {
|
||||
timecode_supplemental_right->set_bg (r,g,b,a);
|
||||
timecode_supplemental_left->set_bg (r,g,b,a);
|
||||
bbt_supplemental_right->set_bg (r,g,b,a);
|
||||
bbt_supplemental_left->set_bg (r,g,b,a);
|
||||
if (supplemental_right) {
|
||||
supplemental_right->set_bg (r,g,b,a);
|
||||
supplemental_left->set_bg (r,g,b,a);
|
||||
}
|
||||
|
||||
r = fg.get_red_p ();
|
||||
|
|
@ -406,16 +254,11 @@ AudioClock::set_theme ()
|
|||
b = fg.get_blue_p ();
|
||||
a = 1.0;
|
||||
|
||||
timecode->set_colors (r, g, b, a);
|
||||
minsec->set_colors (r, g, b, a);
|
||||
bbt->set_colors (r, g, b, a);
|
||||
frames->set_colors (r, g, b, a);
|
||||
display->set_colors (r, g, b, a);
|
||||
|
||||
if (timecode_supplemental_right) {
|
||||
timecode_supplemental_right->set_colors (r,g,b,a);
|
||||
timecode_supplemental_left->set_colors (r,g,b,a);
|
||||
bbt_supplemental_right->set_colors (r,g,b,a);
|
||||
bbt_supplemental_left->set_colors (r,g,b,a);
|
||||
if (supplemental_right) {
|
||||
supplemental_right->set_colors (r,g,b,a);
|
||||
supplemental_left->set_colors (r,g,b,a);
|
||||
}
|
||||
|
||||
r = eg.get_red_p ();
|
||||
|
|
@ -423,16 +266,11 @@ AudioClock::set_theme ()
|
|||
b = eg.get_blue_p ();
|
||||
a = 1.0;
|
||||
|
||||
timecode->set_edit_colors (r, g, b, a);
|
||||
minsec->set_edit_colors (r, g, b, a);
|
||||
bbt->set_edit_colors (r, g, b, a);
|
||||
frames->set_edit_colors (r, g, b, a);
|
||||
display->set_edit_colors (r, g, b, a);
|
||||
|
||||
if (timecode_supplemental_right) {
|
||||
timecode_supplemental_right->set_edit_colors (r,g,b,a);
|
||||
timecode_supplemental_left->set_edit_colors (r,g,b,a);
|
||||
bbt_supplemental_right->set_edit_colors (r,g,b,a);
|
||||
bbt_supplemental_left->set_edit_colors (r,g,b,a);
|
||||
if (supplemental_right) {
|
||||
supplemental_right->set_edit_colors (r,g,b,a);
|
||||
supplemental_left->set_edit_colors (r,g,b,a);
|
||||
}
|
||||
|
||||
queue_draw ();
|
||||
|
|
@ -446,7 +284,7 @@ AudioClock::focus ()
|
|||
void
|
||||
AudioClock::end_edit ()
|
||||
{
|
||||
current_cet->stop_editing ();
|
||||
display->stop_editing ();
|
||||
editing_field = (Field) 0;
|
||||
key_entry_state = 0;
|
||||
|
||||
|
|
@ -563,32 +401,26 @@ AudioClock::set_frames (framepos_t when, bool /*force*/)
|
|||
char buf[32];
|
||||
snprintf (buf, sizeof (buf), "%" PRId64, when);
|
||||
|
||||
frames->set_text (AudioFrames, buf);
|
||||
display->set_text (_text_cells[AudioFrames], buf);
|
||||
|
||||
if (frames_upper_info_label) {
|
||||
if (supplemental_left) {
|
||||
framecnt_t rate = _session->frame_rate();
|
||||
|
||||
if (fmod (rate, 1000.0) == 0.000) {
|
||||
sprintf (buf, "%" PRId64 "K", rate/1000);
|
||||
} else {
|
||||
sprintf (buf, "%.3fK", rate/1000.0f);
|
||||
sprintf (buf, "%" PRId64, rate);
|
||||
}
|
||||
|
||||
if (frames_upper_info_label->get_text() != buf) {
|
||||
frames_upper_info_label->set_text (buf);
|
||||
}
|
||||
supplemental_left->set_text (_text_cells[LowerLeft2], buf);
|
||||
|
||||
float vid_pullup = _session->config.get_video_pullup();
|
||||
|
||||
if (vid_pullup == 0.0) {
|
||||
if (frames_lower_info_label->get_text () != _("none")) {
|
||||
frames_lower_info_label->set_text(_("none"));
|
||||
}
|
||||
supplemental_right->set_text (_text_cells[LowerRight2], _("none"));
|
||||
} else {
|
||||
sprintf (buf, "%-6.4f", vid_pullup);
|
||||
if (frames_lower_info_label->get_text() != buf) {
|
||||
frames_lower_info_label->set_text (buf);
|
||||
}
|
||||
supplemental_right->set_text (_text_cells[LowerRight2], buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -614,25 +446,25 @@ AudioClock::set_minsec (framepos_t when, bool force)
|
|||
|
||||
if (force || hrs != ms_last_hrs) {
|
||||
sprintf (buf, "%02d", hrs);
|
||||
minsec->set_text (MS_Hours, buf);
|
||||
display->set_text (_text_cells[MS_Hours], buf);
|
||||
ms_last_hrs = hrs;
|
||||
}
|
||||
|
||||
if (force || mins != ms_last_mins) {
|
||||
sprintf (buf, "%02d", mins);
|
||||
minsec->set_text (MS_Minutes, buf);
|
||||
display->set_text (_text_cells[MS_Minutes], buf);
|
||||
ms_last_mins = mins;
|
||||
}
|
||||
|
||||
if (force || secs != ms_last_secs) {
|
||||
sprintf (buf, "%02d", secs);
|
||||
minsec->set_text (MS_Seconds, buf);
|
||||
display->set_text (_text_cells[MS_Seconds], buf);
|
||||
ms_last_secs = secs;
|
||||
}
|
||||
|
||||
if (force || millisecs != ms_last_millisecs) {
|
||||
sprintf (buf, "%03d", millisecs);
|
||||
minsec->set_text (MS_Milliseconds, buf);
|
||||
display->set_text (_text_cells[MS_Milliseconds], buf);
|
||||
ms_last_millisecs = millisecs;
|
||||
}
|
||||
}
|
||||
|
|
@ -655,30 +487,30 @@ AudioClock::set_timecode (framepos_t when, bool force)
|
|||
} else {
|
||||
sprintf (buf, " %0*" PRIu32, field_length[Timecode_Hours], TC.hours);
|
||||
}
|
||||
timecode->set_text (Timecode_Hours, buf);
|
||||
display->set_text (_text_cells[Timecode_Hours], buf);
|
||||
last_hrs = TC.hours;
|
||||
last_negative = TC.negative;
|
||||
}
|
||||
|
||||
if (force || TC.minutes != last_mins) {
|
||||
sprintf (buf, "%0*" PRIu32, field_length[Timecode_Minutes], TC.minutes);
|
||||
timecode->set_text (Timecode_Minutes, buf);
|
||||
display->set_text (_text_cells[Timecode_Minutes], buf);
|
||||
last_mins = TC.minutes;
|
||||
}
|
||||
|
||||
if (force || TC.seconds != last_secs) {
|
||||
sprintf (buf, "%0*" PRIu32, field_length[Timecode_Seconds], TC.seconds);
|
||||
timecode->set_text (Timecode_Seconds, buf);
|
||||
display->set_text (_text_cells[Timecode_Seconds], buf);
|
||||
last_secs = TC.seconds;
|
||||
}
|
||||
|
||||
if (force || TC.frames != last_frames) {
|
||||
sprintf (buf, "%0*" PRIu32, field_length[Timecode_Frames], TC.frames);
|
||||
timecode->set_text (Timecode_Frames, buf);
|
||||
display->set_text (_text_cells[Timecode_Frames], buf);
|
||||
last_frames = TC.frames;
|
||||
}
|
||||
|
||||
if (timecode_supplemental_right) {
|
||||
if (supplemental_right) {
|
||||
double timecode_frames = _session->timecode_frames_per_second();
|
||||
bool drop;
|
||||
|
||||
|
|
@ -696,7 +528,7 @@ AudioClock::set_timecode (framepos_t when, bool force)
|
|||
sprintf (buf, "%.2f %s", timecode_frames, (drop ? "D" : ""));
|
||||
}
|
||||
|
||||
timecode_supplemental_right->set_text (Timecode_LowerRight2, buf);
|
||||
supplemental_right->set_text (_text_cells[LowerRight2], buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -723,19 +555,18 @@ AudioClock::set_bbt (framepos_t when, bool force)
|
|||
|
||||
sprintf (buf, "%0*" PRIu32, field_length[Bars], BBT.bars);
|
||||
if (force || _text_cells[Bars]->get_text () != buf) {
|
||||
bbt->set_text (Bars, buf);
|
||||
_text_cells[Bars]->set_text (buf);
|
||||
display->set_text (_text_cells[Bars], buf);
|
||||
}
|
||||
sprintf (buf, "%0*" PRIu32, field_length[Beats], BBT.beats);
|
||||
if (force || _text_cells[Beats]->get_text () != buf) {
|
||||
bbt->set_text (Beats, buf);
|
||||
display->set_text (_text_cells[Beats], buf);
|
||||
}
|
||||
sprintf (buf, "%0*" PRIu32, field_length[Ticks], BBT.ticks);
|
||||
if (force || _text_cells[Ticks]->get_text () != buf) {
|
||||
bbt->set_text (Ticks, buf);
|
||||
display->set_text (_text_cells[Ticks], buf);
|
||||
}
|
||||
|
||||
if (bbt_supplemental_right) {
|
||||
if (supplemental_right) {
|
||||
framepos_t pos;
|
||||
|
||||
if (bbt_reference_time < 0) {
|
||||
|
|
@ -747,10 +578,10 @@ AudioClock::set_bbt (framepos_t when, bool force)
|
|||
TempoMetric m (_session->tempo_map().metric_at (pos));
|
||||
|
||||
sprintf (buf, "%-5.2f", m.tempo().beats_per_minute());
|
||||
bbt_supplemental_left->set_text (BBT_LowerLeft2, buf);
|
||||
supplemental_left->set_text (_text_cells[LowerLeft2], buf);
|
||||
|
||||
sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor());
|
||||
bbt_supplemental_right->set_text (BBT_LowerRight2, buf);
|
||||
supplemental_right->set_text (_text_cells[LowerRight2], buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -790,15 +621,15 @@ AudioClock::edit_next_field ()
|
|||
|
||||
case Timecode_Hours:
|
||||
editing_field = Timecode_Minutes;
|
||||
timecode->start_editing (Timecode_Minutes);
|
||||
display->start_editing (_text_cells[Timecode_Minutes]);
|
||||
break;
|
||||
case Timecode_Minutes:
|
||||
editing_field = Timecode_Seconds;
|
||||
timecode->start_editing (Timecode_Seconds);
|
||||
display->start_editing (_text_cells[Timecode_Seconds]);
|
||||
break;
|
||||
case Timecode_Seconds:
|
||||
editing_field = Timecode_Frames;
|
||||
timecode->start_editing (Timecode_Frames);
|
||||
display->start_editing (_text_cells[Timecode_Frames]);
|
||||
break;
|
||||
case Timecode_Frames:
|
||||
end_edit ();
|
||||
|
|
@ -808,15 +639,15 @@ AudioClock::edit_next_field ()
|
|||
|
||||
case MS_Hours:
|
||||
editing_field = MS_Minutes;
|
||||
minsec->start_editing (MS_Minutes);
|
||||
display->start_editing (_text_cells[MS_Minutes]);
|
||||
break;
|
||||
case MS_Minutes:
|
||||
editing_field = MS_Seconds;
|
||||
minsec->start_editing (MS_Seconds);
|
||||
display->start_editing (_text_cells[MS_Seconds]);
|
||||
break;
|
||||
case MS_Seconds:
|
||||
editing_field = MS_Milliseconds;
|
||||
minsec->start_editing (MS_Milliseconds);
|
||||
display->start_editing (_text_cells[MS_Milliseconds]);
|
||||
break;
|
||||
case MS_Milliseconds:
|
||||
end_edit ();
|
||||
|
|
@ -826,11 +657,11 @@ AudioClock::edit_next_field ()
|
|||
|
||||
case Bars:
|
||||
editing_field = Beats;
|
||||
bbt->start_editing (Beats);
|
||||
display->start_editing (_text_cells[Beats]);
|
||||
break;
|
||||
case Beats:
|
||||
editing_field = Ticks;
|
||||
bbt->start_editing (Ticks);
|
||||
display->start_editing (_text_cells[Ticks]);
|
||||
break;
|
||||
case Ticks:
|
||||
end_edit ();
|
||||
|
|
@ -997,11 +828,7 @@ AudioClock::on_key_release_event (GdkEventKey *ev)
|
|||
}
|
||||
|
||||
new_text += new_char;
|
||||
|
||||
if (current_cet) {
|
||||
current_cet->set_text (editing_field, new_text);
|
||||
}
|
||||
|
||||
display->set_text (cell, new_text);
|
||||
_canonical_time_is_displayed = true;
|
||||
key_entry_state++;
|
||||
}
|
||||
|
|
@ -1033,13 +860,13 @@ AudioClock::on_key_release_event (GdkEventKey *ev)
|
|||
// Bars should never be zero, unless this clock is for a duration
|
||||
if (atoi (_text_cells[Bars]->get_text()) == 0 && !is_duration) {
|
||||
snprintf (buf, sizeof (buf), "%0*" PRIu32, field_length[Bars], 1);
|
||||
_text_cells[Bars]->set_text (buf);
|
||||
display->set_text (_text_cells[Bars], buf);
|
||||
_canonical_time_is_displayed = true;
|
||||
}
|
||||
// beats should never be zero, unless this clock is for a duration
|
||||
if (atoi (_text_cells[Beats]->get_text()) == 0 && !is_duration) {
|
||||
snprintf (buf, sizeof (buf), "%0*" PRIu32, field_length[Beats], 1);
|
||||
_text_cells[Beats]->set_text (buf);
|
||||
display->set_text (_text_cells[Beats], buf);
|
||||
_canonical_time_is_displayed = true;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1064,14 +891,14 @@ AudioClock::on_key_release_event (GdkEventKey *ev)
|
|||
}
|
||||
|
||||
bool
|
||||
AudioClock::button_press (GdkEventButton *ev, uint32_t id)
|
||||
AudioClock::button_press (GdkEventButton *ev, CairoCell* cell)
|
||||
{
|
||||
Field field = (Field) id;
|
||||
|
||||
switch (ev->button) {
|
||||
case 1:
|
||||
editing_field = field;
|
||||
current_cet->start_editing (field);
|
||||
if (cell) {
|
||||
editing_field = (Field) cell->id ();
|
||||
display->start_editing (cell);
|
||||
}
|
||||
|
||||
Keyboard::magic_widget_grab_focus ();
|
||||
|
||||
|
|
@ -1094,7 +921,7 @@ AudioClock::button_press (GdkEventButton *ev, uint32_t id)
|
|||
}
|
||||
|
||||
bool
|
||||
AudioClock::button_release (GdkEventButton *ev, uint32_t id)
|
||||
AudioClock::button_release (GdkEventButton *ev, CairoCell*)
|
||||
{
|
||||
if (dragging) {
|
||||
gdk_pointer_ungrab (GDK_CURRENT_TIME);
|
||||
|
|
@ -1125,10 +952,8 @@ AudioClock::button_release (GdkEventButton *ev, uint32_t id)
|
|||
}
|
||||
|
||||
bool
|
||||
AudioClock::scroll (GdkEventScroll *ev, uint32_t id)
|
||||
AudioClock::scroll (GdkEventScroll *ev, CairoCell* cell)
|
||||
{
|
||||
Field field = (Field) id;
|
||||
|
||||
if (_session == 0) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1138,38 +963,38 @@ AudioClock::scroll (GdkEventScroll *ev, uint32_t id)
|
|||
switch (ev->direction) {
|
||||
|
||||
case GDK_SCROLL_UP:
|
||||
frames = get_frames (field);
|
||||
if (frames != 0) {
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
frames *= 10;
|
||||
}
|
||||
set (current_time() + frames, true);
|
||||
ValueChanged (); /* EMIT_SIGNAL */
|
||||
}
|
||||
break;
|
||||
|
||||
frames = get_frames ((Field) cell->id());
|
||||
if (frames != 0) {
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
frames *= 10;
|
||||
}
|
||||
set (current_time() + frames, true);
|
||||
ValueChanged (); /* EMIT_SIGNAL */
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_SCROLL_DOWN:
|
||||
frames = get_frames (field);
|
||||
if (frames != 0) {
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
frames *= 10;
|
||||
}
|
||||
|
||||
if ((double)current_time() - (double)frames < 0.0) {
|
||||
set (0, true);
|
||||
} else {
|
||||
set (current_time() - frames, true);
|
||||
}
|
||||
|
||||
ValueChanged (); /* EMIT_SIGNAL */
|
||||
}
|
||||
break;
|
||||
|
||||
frames = get_frames ((Field) cell->id());
|
||||
if (frames != 0) {
|
||||
if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
frames *= 10;
|
||||
}
|
||||
|
||||
if ((double)current_time() - (double)frames < 0.0) {
|
||||
set (0, true);
|
||||
} else {
|
||||
set (current_time() - frames, true);
|
||||
}
|
||||
|
||||
ValueChanged (); /* EMIT_SIGNAL */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1355,31 +1180,31 @@ AudioClock::timecode_sanitize_display()
|
|||
{
|
||||
// Check Timecode fields for sanity, possibly adjusting values
|
||||
if (atoi (_text_cells[Timecode_Minutes]->get_text()) > 59) {
|
||||
_text_cells[Timecode_Minutes]->set_text("59");
|
||||
display->set_text (_text_cells[Timecode_Minutes], "59");
|
||||
_canonical_time_is_displayed = true;
|
||||
}
|
||||
|
||||
if (atoi (_text_cells[Timecode_Seconds]->get_text()) > 59) {
|
||||
_text_cells[Timecode_Seconds]->set_text("59");
|
||||
display->set_text (_text_cells[Timecode_Seconds], "59");
|
||||
_canonical_time_is_displayed = true;
|
||||
}
|
||||
|
||||
switch ((long)rint(_session->timecode_frames_per_second())) {
|
||||
case 24:
|
||||
if (atoi (_text_cells[Timecode_Frames]->get_text()) > 23) {
|
||||
_text_cells[Timecode_Frames]->set_text("23");
|
||||
display->set_text (_text_cells[Timecode_Frames], "23");
|
||||
_canonical_time_is_displayed = true;
|
||||
}
|
||||
break;
|
||||
case 25:
|
||||
if (atoi (_text_cells[Timecode_Frames]->get_text()) > 24) {
|
||||
_text_cells[Timecode_Frames]->set_text("24");
|
||||
display->set_text (_text_cells[Timecode_Frames], "24");
|
||||
_canonical_time_is_displayed = true;
|
||||
}
|
||||
break;
|
||||
case 30:
|
||||
if (atoi (_text_cells[Timecode_Frames]->get_text()) > 29) {
|
||||
_text_cells[Timecode_Frames]->set_text("29");
|
||||
display->set_text (_text_cells[Timecode_Frames], "29");
|
||||
_canonical_time_is_displayed = true;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1389,7 +1214,7 @@ AudioClock::timecode_sanitize_display()
|
|||
|
||||
if (_session->timecode_drop_frames()) {
|
||||
if ((atoi (_text_cells[Timecode_Minutes]->get_text()) % 10) && (atoi (_text_cells[Timecode_Seconds]->get_text()) == 0) && (atoi (_text_cells[Timecode_Frames]->get_text()) < 2)) {
|
||||
_text_cells[Timecode_Frames]->set_text("02");
|
||||
display->set_text (_text_cells[Timecode_Frames], "02");
|
||||
_canonical_time_is_displayed = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1924,67 +1749,124 @@ AudioClock::connect_signals ()
|
|||
{
|
||||
disconnect_signals ();
|
||||
|
||||
if (editable && current_cet) {
|
||||
scroll_connection = current_cet->scroll.connect (sigc::mem_fun (*this, &AudioClock::scroll));
|
||||
button_press_connection = current_cet->button_press.connect (sigc::mem_fun (*this, &AudioClock::button_press));
|
||||
button_release_connection = current_cet->button_release.connect (sigc::mem_fun (*this, &AudioClock::button_release));
|
||||
if (editable) {
|
||||
scroll_connection = display->scroll.connect (sigc::mem_fun (*this, &AudioClock::scroll));
|
||||
button_press_connection = display->button_press.connect (sigc::mem_fun (*this, &AudioClock::button_press));
|
||||
button_release_connection = display->button_release.connect (sigc::mem_fun (*this, &AudioClock::button_release));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioClock::set_mode (Mode m)
|
||||
{
|
||||
/* slightly tricky: this is called from within the ARDOUR_UI
|
||||
constructor by some of its clock members. at that time
|
||||
the instance pointer is unset, so we have to be careful.
|
||||
the main idea is to drop keyboard focus in case we had
|
||||
started editing the clock and then we switch clock mode.
|
||||
*/
|
||||
|
||||
// clock_base.grab_focus ();
|
||||
|
||||
if (_mode == m) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove ();
|
||||
_mode = m;
|
||||
|
||||
display->clear_cells ();
|
||||
|
||||
if (supplemental_left) {
|
||||
supplemental_left->clear_cells ();
|
||||
supplemental_right->clear_cells ();
|
||||
}
|
||||
|
||||
switch (_mode) {
|
||||
case Timecode:
|
||||
current_cet = timecode;
|
||||
add (timecode_packer);
|
||||
display->add_cell (_text_cells[Timecode_Hours]);
|
||||
display->add_cell (_fixed_cells[Colon1]);
|
||||
display->add_cell (_text_cells[Timecode_Minutes]);
|
||||
display->add_cell (_fixed_cells[Colon2]);
|
||||
display->add_cell (_text_cells[Timecode_Seconds]);
|
||||
display->add_cell (_fixed_cells[Colon3]);
|
||||
display->add_cell (_text_cells[Timecode_Frames]);
|
||||
|
||||
if (supplemental_left) {
|
||||
supplemental_left->add_cell (_text_cells[LowerLeft1]);
|
||||
supplemental_left->add_cell (_text_cells[LowerLeft2]);
|
||||
supplemental_right->add_cell (_text_cells[LowerRight1]);
|
||||
supplemental_right->add_cell (_text_cells[LowerRight2]);
|
||||
|
||||
supplemental_left->set_width_chars (_text_cells[LowerLeft1], 4);
|
||||
supplemental_left->set_width_chars (_text_cells[LowerLeft2], 8);
|
||||
|
||||
supplemental_right->set_width_chars (_text_cells[LowerRight1], 4);
|
||||
supplemental_right->set_width_chars (_text_cells[LowerRight2], 6.25);
|
||||
|
||||
supplemental_left->set_text (_text_cells[LowerLeft1], _("EXT"));
|
||||
supplemental_right->set_text (_text_cells[LowerRight1], _("FPS"));
|
||||
}
|
||||
break;
|
||||
|
||||
case BBT:
|
||||
current_cet = bbt;
|
||||
add (bbt_packer);
|
||||
display->add_cell (_text_cells[Bars]);
|
||||
display->add_cell (_fixed_cells[Bar1]);
|
||||
display->add_cell (_text_cells[Beats]);
|
||||
display->add_cell (_fixed_cells[Bar2]);
|
||||
display->add_cell (_text_cells[Ticks]);
|
||||
if (supplemental_left) {
|
||||
supplemental_left->add_cell (_text_cells[LowerLeft1]);
|
||||
supplemental_left->add_cell (_text_cells[LowerLeft2]);
|
||||
supplemental_right->add_cell (_text_cells[LowerRight1]);
|
||||
supplemental_right->add_cell (_text_cells[LowerRight2]);
|
||||
|
||||
supplemental_left->set_width_chars (_text_cells[LowerLeft1], 1);
|
||||
supplemental_left->set_width_chars (_text_cells[LowerLeft2], 5.25);
|
||||
|
||||
supplemental_right->set_width_chars (_text_cells[LowerRight1], 1);
|
||||
supplemental_right->set_width_chars (_text_cells[LowerRight2], 5);
|
||||
|
||||
supplemental_left->set_text (_text_cells[LowerLeft1], _("M"));
|
||||
supplemental_right->set_text (_text_cells[LowerRight1], _("T"));
|
||||
}
|
||||
break;
|
||||
|
||||
case MinSec:
|
||||
current_cet = minsec;
|
||||
add (minsec_packer);
|
||||
display->add_cell (_text_cells[MS_Hours]);
|
||||
display->add_cell (_fixed_cells[Colon1]);
|
||||
display->add_cell (_text_cells[MS_Minutes]);
|
||||
display->add_cell (_fixed_cells[Colon2]);
|
||||
display->add_cell (_text_cells[MS_Seconds]);
|
||||
display->add_cell (_fixed_cells[Colon3]);
|
||||
display->add_cell (_text_cells[MS_Milliseconds]);
|
||||
break;
|
||||
|
||||
case Frames:
|
||||
current_cet = frames;
|
||||
add (frames_packer);
|
||||
display->add_cell (_text_cells[AudioFrames]);
|
||||
if (supplemental_left) {
|
||||
supplemental_left->add_cell (_text_cells[LowerLeft1]);
|
||||
supplemental_left->add_cell (_text_cells[LowerLeft2]);
|
||||
supplemental_right->add_cell (_text_cells[LowerRight1]);
|
||||
supplemental_right->add_cell (_text_cells[LowerRight2]);
|
||||
|
||||
supplemental_left->set_width_chars (_text_cells[LowerLeft1], 3);
|
||||
supplemental_left->set_width_chars (_text_cells[LowerLeft2], 5);
|
||||
|
||||
supplemental_right->set_width_chars (_text_cells[LowerRight1], 5);
|
||||
supplemental_right->set_width_chars (_text_cells[LowerRight2], 5);
|
||||
|
||||
supplemental_left->set_text (_text_cells[LowerLeft1], _("SR"));
|
||||
supplemental_right->set_text (_text_cells[LowerRight1], _("Pull"));
|
||||
}
|
||||
break;
|
||||
|
||||
case Off:
|
||||
current_cet = 0;
|
||||
add (off_hbox);
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_cet) {
|
||||
if (supplemental_left) {
|
||||
/* clear information cells */
|
||||
supplemental_left->set_text (_text_cells[LowerLeft2], _(""));
|
||||
supplemental_right->set_text (_text_cells[LowerRight2], _(""));
|
||||
}
|
||||
|
||||
if (_mode != Off) {
|
||||
connect_signals ();
|
||||
} else {
|
||||
disconnect_signals ();
|
||||
}
|
||||
|
||||
get_child()->show_all ();
|
||||
|
||||
set (last_when, true);
|
||||
|
||||
if (!is_transient) {
|
||||
|
|
@ -2017,3 +1899,4 @@ AudioClock::set_is_duration (bool yn)
|
|||
is_duration = yn;
|
||||
set (last_when, true, 0, 's');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,7 @@
|
|||
#include <gtkmm/alignment.h>
|
||||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/menu.h>
|
||||
#include <gtkmm/eventbox.h>
|
||||
#include <gtkmm/label.h>
|
||||
#include <gtkmm/frame.h>
|
||||
|
||||
#include "ardour/ardour.h"
|
||||
#include "ardour/session_handle.h"
|
||||
|
|
@ -66,7 +64,8 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr
|
|||
void set_bbt_reference (framepos_t);
|
||||
void set_is_duration (bool);
|
||||
|
||||
void set_widget_name (std::string);
|
||||
void set_widget_name (const std::string&);
|
||||
void set_font (const std::string&);
|
||||
|
||||
std::string name() const { return _name; }
|
||||
|
||||
|
|
@ -83,6 +82,10 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr
|
|||
|
||||
static bool has_focus() { return _has_focus; }
|
||||
|
||||
CairoEditableText& main_display () const { return *display; }
|
||||
CairoEditableText* supplemental_left_display () const { return supplemental_left; }
|
||||
CairoEditableText* supplemental_right_display () const { return supplemental_right; }
|
||||
|
||||
private:
|
||||
Mode _mode;
|
||||
uint32_t key_entry_state;
|
||||
|
|
@ -95,46 +98,32 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr
|
|||
|
||||
Gtk::Menu *ops_menu;
|
||||
|
||||
CairoEditableText* timecode;
|
||||
CairoEditableText* minsec;
|
||||
CairoEditableText* bbt;
|
||||
CairoEditableText* frames;
|
||||
CairoEditableText* display;
|
||||
|
||||
enum Field {
|
||||
/* Field IDs must start at 1. Cell ID zero
|
||||
is reserved in CairoEditableText
|
||||
*/
|
||||
|
||||
Timecode_Hours = 1,
|
||||
Timecode_Colon1,
|
||||
Timecode_Hours,
|
||||
Timecode_Minutes,
|
||||
Timecode_Colon2,
|
||||
Timecode_Seconds,
|
||||
Timecode_Colon3,
|
||||
Timecode_Frames,
|
||||
MS_Hours,
|
||||
MS_Colon1,
|
||||
MS_Minutes,
|
||||
MS_Colon2,
|
||||
MS_Colon3, // to become a dot cell
|
||||
MS_Seconds,
|
||||
MS_Milliseconds,
|
||||
Bars,
|
||||
BBT_Bar1,
|
||||
Beats,
|
||||
BBT_Bar2,
|
||||
Ticks,
|
||||
AudioFrames,
|
||||
|
||||
Timecode_LowerLeft1,
|
||||
Timecode_LowerLeft2,
|
||||
Timecode_LowerRight1,
|
||||
Timecode_LowerRight2,
|
||||
Colon1,
|
||||
Colon2,
|
||||
Colon3,
|
||||
Bar1,
|
||||
Bar2,
|
||||
|
||||
BBT_LowerLeft1,
|
||||
BBT_LowerLeft2,
|
||||
BBT_LowerRight1,
|
||||
BBT_LowerRight2,
|
||||
LowerLeft1,
|
||||
LowerLeft2,
|
||||
LowerRight1,
|
||||
LowerRight2,
|
||||
};
|
||||
|
||||
/** CairoCells of various kinds for each of our non-text Fields */
|
||||
|
|
@ -145,25 +134,13 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr
|
|||
|
||||
Gtk::HBox off_hbox;
|
||||
|
||||
CairoEditableText* timecode_supplemental_left;
|
||||
CairoEditableText* timecode_supplemental_right;
|
||||
CairoEditableText* bbt_supplemental_left;
|
||||
CairoEditableText* bbt_supplemental_right;
|
||||
CairoEditableText* supplemental_left;
|
||||
CairoEditableText* supplemental_right;
|
||||
|
||||
Gtk::VBox timecode_packer;
|
||||
Gtk::HBox timecode_top;
|
||||
Gtk::HBox timecode_bottom;
|
||||
Gtk::HBox minsec_packer;
|
||||
Gtk::HBox bbt_top;
|
||||
Gtk::HBox bbt_bottom;
|
||||
Gtk::VBox bbt_packer;
|
||||
Gtk::HBox frames_packer;
|
||||
Gtk::VBox packer;
|
||||
Gtk::HBox top;
|
||||
Gtk::HBox bottom;
|
||||
|
||||
Gtk::Label* frames_upper_info_label;
|
||||
Gtk::Label* frames_lower_info_label;
|
||||
Gtk::VBox frames_info_box;
|
||||
|
||||
CairoEditableText* current_cet;
|
||||
Field editing_field;
|
||||
framepos_t bbt_reference_time;
|
||||
framepos_t last_when;
|
||||
|
|
@ -200,9 +177,9 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr
|
|||
|
||||
/* proxied from CairoEditableText */
|
||||
|
||||
bool scroll (GdkEventScroll *ev, uint32_t);
|
||||
bool button_press (GdkEventButton *ev, uint32_t);
|
||||
bool button_release (GdkEventButton *ev, uint32_t);
|
||||
bool scroll (GdkEventScroll *ev, CairoCell*);
|
||||
bool button_press (GdkEventButton *ev, CairoCell*);
|
||||
bool button_release (GdkEventButton *ev, CairoCell*);
|
||||
sigc::connection scroll_connection;
|
||||
sigc::connection button_press_connection;
|
||||
sigc::connection button_release_connection;
|
||||
|
|
@ -230,8 +207,7 @@ class AudioClock : public Gtk::Alignment, public ARDOUR::SessionHandlePtr
|
|||
|
||||
void session_configuration_changed (std::string);
|
||||
|
||||
static std::map<AudioClock::Field,uint32_t> field_length;
|
||||
static void fill_field_lengths();
|
||||
static uint32_t field_length[];
|
||||
static bool _has_focus;
|
||||
|
||||
void on_style_changed (const Glib::RefPtr<Gtk::Style>&);
|
||||
|
|
|
|||
206
gtk2_ardour/time_info_box.cc
Normal file
206
gtk2_ardour/time_info_box.cc
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
Copyright (C) 2011 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "pbd/compose.h"
|
||||
|
||||
#include "gtkmm2ext/cairocell.h"
|
||||
#include "gtkmm2ext/gui_thread.h"
|
||||
#include "gtkmm2ext/utils.h"
|
||||
|
||||
#include "ardour/location.h"
|
||||
#include "ardour/session.h"
|
||||
|
||||
#include "time_info_box.h"
|
||||
#include "audio_clock.h"
|
||||
#include "editor.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace Gtk;
|
||||
using namespace ARDOUR;
|
||||
|
||||
TimeInfoBox::TimeInfoBox ()
|
||||
: Table (4, 4)
|
||||
{
|
||||
selection_start = new AudioClock ("selection-start", false, "SelectionClockDisplay", false, false, false, false);
|
||||
selection_end = new AudioClock ("selection-end", false, "SelectionClockDisplay", false, false, false, false);
|
||||
selection_length = new AudioClock ("selection-length", false, "SelectionClockDisplay", false, false, true, false);
|
||||
|
||||
punch_start = new AudioClock ("punch-start", false, "PunchClockDisplay", false, false, false, false);
|
||||
punch_end = new AudioClock ("punch-end", false, "PunchClockDisplay", false, false, false, false);
|
||||
|
||||
CairoEditableText& ss (selection_start->main_display());
|
||||
ss.set_ypad (1);
|
||||
ss.set_xpad (1);
|
||||
ss.set_corner_radius (0);
|
||||
ss.set_draw_background (false);
|
||||
|
||||
CairoEditableText& se (selection_end->main_display());
|
||||
se.set_ypad (1);
|
||||
se.set_xpad (1);
|
||||
se.set_corner_radius (0);
|
||||
se.set_draw_background (false);
|
||||
|
||||
CairoEditableText& sl (selection_length->main_display());
|
||||
sl.set_ypad (1);
|
||||
sl.set_xpad (2);
|
||||
sl.set_corner_radius (0);
|
||||
sl.set_draw_background (false);
|
||||
|
||||
CairoEditableText& ps (punch_start->main_display());
|
||||
ps.set_ypad (1);
|
||||
ps.set_xpad (2);
|
||||
ps.set_corner_radius (0);
|
||||
ps.set_draw_background (false);
|
||||
|
||||
CairoEditableText& pe (punch_end->main_display());
|
||||
pe.set_ypad (1);
|
||||
pe.set_xpad (2);
|
||||
pe.set_corner_radius (0);
|
||||
pe.set_draw_background (false);
|
||||
|
||||
selection_title.set_markup (string_compose ("<span size=\"x-small\">%1</span>", _("Selection")));
|
||||
punch_title.set_markup (string_compose ("<span size=\"x-small\">%1</span>", _("Punch")));
|
||||
|
||||
set_homogeneous (false);
|
||||
set_spacings (0);
|
||||
|
||||
Gtk::Label* l;
|
||||
|
||||
attach (selection_title, 0, 2, 0, 1);
|
||||
l = manage (new Label);
|
||||
l->set_markup (string_compose ("<span size=\"x-small\">%1</span>", _("Start")));
|
||||
attach (*l, 0, 1, 1, 2);
|
||||
attach (*selection_start, 1, 2, 1, 2);
|
||||
l = manage (new Label);
|
||||
l->set_markup (string_compose ("<span size=\"x-small\">%1</span>", _("End")));
|
||||
attach (*l, 0, 1, 2, 3);
|
||||
attach (*selection_end, 1, 2, 2, 3);
|
||||
l = manage (new Label);
|
||||
l->set_markup (string_compose ("<span size=\"x-small\">%1</span>", _("Length")));
|
||||
attach (*l, 0, 1, 3, 4);
|
||||
attach (*selection_length, 1, 2, 3, 4);
|
||||
|
||||
attach (punch_title, 2, 4, 0, 1);
|
||||
l = manage (new Label);
|
||||
l->set_markup (string_compose ("<span size=\"x-small\">%1</span>", _("Start")));
|
||||
attach (*l, 2, 3, 1, 2);
|
||||
attach (*punch_start, 3, 4, 1, 2);
|
||||
l = manage (new Label);
|
||||
l->set_markup (string_compose ("<span size=\"x-small\">%1</span>", _("End")));
|
||||
attach (*l, 2, 3, 2, 3);
|
||||
attach (*punch_end, 3, 4, 2, 3);
|
||||
|
||||
show_all ();
|
||||
|
||||
Editor::instance().get_selection().TimeChanged.connect (sigc::mem_fun (*this, &TimeInfoBox::selection_changed));
|
||||
}
|
||||
|
||||
TimeInfoBox::~TimeInfoBox ()
|
||||
{
|
||||
delete selection_length;
|
||||
delete selection_end;
|
||||
delete selection_start;
|
||||
|
||||
delete punch_start;
|
||||
delete punch_end;
|
||||
}
|
||||
|
||||
void
|
||||
TimeInfoBox::set_session (Session* s)
|
||||
{
|
||||
SessionHandlePtr::set_session (s);
|
||||
|
||||
selection_start->set_session (s);
|
||||
selection_end->set_session (s);
|
||||
selection_length->set_session (s);
|
||||
|
||||
punch_start->set_session (s);
|
||||
punch_end->set_session (s);
|
||||
|
||||
if (s) {
|
||||
Location* punch = s->locations()->auto_punch_location ();
|
||||
|
||||
if (punch) {
|
||||
watch_punch (punch);
|
||||
}
|
||||
|
||||
_session->auto_punch_location_changed.connect (_session_connections, MISSING_INVALIDATOR,
|
||||
boost::bind (&TimeInfoBox::punch_location_changed, this, _1), gui_context());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimeInfoBox::selection_changed ()
|
||||
{
|
||||
selection_start->set (Editor::instance().get_selection().time.start());
|
||||
selection_end->set (Editor::instance().get_selection().time.end_frame());
|
||||
selection_length->set (Editor::instance().get_selection().time.length());
|
||||
}
|
||||
|
||||
void
|
||||
TimeInfoBox::punch_location_changed (Location* loc)
|
||||
{
|
||||
if (loc) {
|
||||
watch_punch (loc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimeInfoBox::watch_punch (Location* punch)
|
||||
{
|
||||
punch_connections.drop_connections ();
|
||||
|
||||
punch->start_changed.connect (punch_connections, MISSING_INVALIDATOR, boost::bind (&TimeInfoBox::punch_changed, this, _1), gui_context());
|
||||
punch->end_changed.connect (punch_connections, MISSING_INVALIDATOR, boost::bind (&TimeInfoBox::punch_changed, this, _1), gui_context());
|
||||
|
||||
punch_changed (punch);
|
||||
}
|
||||
|
||||
void
|
||||
TimeInfoBox::punch_changed (Location* loc)
|
||||
{
|
||||
if (!loc) {
|
||||
punch_start->set (99999999);
|
||||
punch_end->set (999999999);
|
||||
return;
|
||||
}
|
||||
|
||||
punch_start->set (loc->start());
|
||||
punch_end->set (loc->end());
|
||||
}
|
||||
|
||||
bool
|
||||
TimeInfoBox::on_expose_event (GdkEventExpose* ev)
|
||||
{
|
||||
Table::on_expose_event (ev);
|
||||
|
||||
{
|
||||
Cairo::RefPtr<Cairo::Context> context = get_window()->create_cairo_context();
|
||||
|
||||
context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
|
||||
context->clip ();
|
||||
|
||||
context->set_source_rgba (0.01, 0.02, 0.21, 1.0);
|
||||
Gtkmm2ext::rounded_rectangle (context, 0, 0, get_allocation().get_width(), get_allocation().get_height(), 5);
|
||||
context->fill ();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
73
gtk2_ardour/time_info_box.h
Normal file
73
gtk2_ardour/time_info_box.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright (C) 2011 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __time_info_box_h__
|
||||
#define __time_info_box_h__
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <gtkmm/box.h>
|
||||
#include <gtkmm/label.h>
|
||||
|
||||
#include "ardour/ardour.h"
|
||||
#include "ardour/session_handle.h"
|
||||
|
||||
class CairoEditableText;
|
||||
class CairoCell;
|
||||
class CairoTextCell;
|
||||
|
||||
namespace ARDOUR {
|
||||
class Session;
|
||||
class Location;
|
||||
}
|
||||
|
||||
class AudioClock;
|
||||
|
||||
class TimeInfoBox : public Gtk::Table, public ARDOUR::SessionHandlePtr
|
||||
{
|
||||
public:
|
||||
TimeInfoBox ();
|
||||
~TimeInfoBox ();
|
||||
|
||||
void set_session (ARDOUR::Session*);
|
||||
|
||||
protected:
|
||||
bool on_expose_event (GdkEventExpose*);
|
||||
|
||||
private:
|
||||
AudioClock* selection_start;
|
||||
AudioClock* selection_end;
|
||||
AudioClock* selection_length;
|
||||
|
||||
AudioClock* punch_start;
|
||||
AudioClock* punch_end;
|
||||
|
||||
Gtk::Label selection_title;
|
||||
Gtk::Label punch_title;
|
||||
|
||||
void punch_changed (ARDOUR::Location*);
|
||||
void punch_location_changed (ARDOUR::Location*);
|
||||
void watch_punch (ARDOUR::Location*);
|
||||
PBD::ScopedConnectionList punch_connections;
|
||||
|
||||
void selection_changed ();
|
||||
};
|
||||
|
||||
|
||||
#endif /* __time_info_box_h__ */
|
||||
|
|
@ -217,6 +217,7 @@ gtk2_ardour_sources = [
|
|||
'time_axis_view.cc',
|
||||
'time_axis_view_item.cc',
|
||||
'time_fx_dialog.cc',
|
||||
'time_info_box.cc',
|
||||
'time_selection.cc',
|
||||
'track_selection.cc',
|
||||
'track_view_list.cc',
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@ using std::cerr;
|
|||
using std::endl;
|
||||
using namespace Gtkmm2ext;
|
||||
|
||||
CairoCell::CairoCell ()
|
||||
: _visible (true)
|
||||
, _xpad (5)
|
||||
CairoCell::CairoCell (int32_t id)
|
||||
: _id (id)
|
||||
, _visible (true)
|
||||
, _xpad (2)
|
||||
{
|
||||
bbox.x = 0;
|
||||
bbox.y = 0;
|
||||
|
|
@ -58,8 +59,9 @@ CairoColonCell::set_size (Glib::RefPtr<Pango::Context>& context, const Pango::Fo
|
|||
bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
|
||||
}
|
||||
|
||||
CairoTextCell::CairoTextCell (double wc)
|
||||
: _width_chars (wc)
|
||||
CairoTextCell::CairoTextCell (int32_t id, double wc)
|
||||
: CairoCell (id)
|
||||
, _width_chars (wc)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -96,18 +98,9 @@ CairoTextCell::set_size (Glib::RefPtr<Pango::Context>& context, const Pango::Fon
|
|||
bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
|
||||
}
|
||||
|
||||
CairoCell*
|
||||
CairoEditableText::get_cell (uint32_t id)
|
||||
{
|
||||
CellMap::iterator i = cells.find (id);
|
||||
if (i == cells.end()) {
|
||||
return 0;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
CairoEditableText::CairoEditableText ()
|
||||
: editing_id (0)
|
||||
: editing_cell (0)
|
||||
, _draw_bg (true)
|
||||
, width (0)
|
||||
, max_cell_height (0)
|
||||
, height (0)
|
||||
|
|
@ -125,19 +118,16 @@ CairoEditableText::CairoEditableText ()
|
|||
|
||||
CairoEditableText::~CairoEditableText ()
|
||||
{
|
||||
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
|
||||
delete i->second;
|
||||
}
|
||||
/* we don't own cells */
|
||||
}
|
||||
|
||||
bool
|
||||
CairoEditableText::on_scroll_event (GdkEventScroll* ev)
|
||||
{
|
||||
uint32_t id;
|
||||
CairoCell* cell = find_cell (ev->x, ev->y, id);
|
||||
CairoCell* cell = find_cell (ev->x, ev->y);
|
||||
|
||||
if (cell) {
|
||||
return scroll (ev, id);
|
||||
return scroll (ev, cell);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -152,38 +142,37 @@ CairoEditableText::on_focus_in_event (GdkEventFocus* ev)
|
|||
bool
|
||||
CairoEditableText::on_focus_out_event (GdkEventFocus* ev)
|
||||
{
|
||||
if (editing_id) {
|
||||
CairoCell* cell = get_cell (editing_id);
|
||||
queue_draw_cell (cell);
|
||||
editing_id = 0;
|
||||
if (editing_cell) {
|
||||
queue_draw_cell (editing_cell);
|
||||
editing_cell = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CairoEditableText::add_cell (uint32_t id, CairoCell* cell)
|
||||
CairoEditableText::add_cell (CairoCell* cell)
|
||||
{
|
||||
if (id > 0) {
|
||||
Glib::RefPtr<Pango::Context> context = get_pango_context ();
|
||||
cell->set_size (context, font);
|
||||
|
||||
cells[id] = cell; /* we own it */
|
||||
}
|
||||
Glib::RefPtr<Pango::Context> context = get_pango_context ();
|
||||
cell->set_size (context, _font);
|
||||
cells.push_back (cell);
|
||||
queue_resize ();
|
||||
queue_draw ();
|
||||
}
|
||||
|
||||
void
|
||||
CairoEditableText::set_text (uint32_t id, const string& text)
|
||||
CairoEditableText::clear_cells ()
|
||||
{
|
||||
CellMap::iterator i = cells.find (id);
|
||||
cells.clear ();
|
||||
queue_resize ();
|
||||
queue_draw ();
|
||||
}
|
||||
|
||||
if (i == cells.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CairoTextCell* textcell = dynamic_cast<CairoTextCell*> (i->second);
|
||||
|
||||
if (textcell) {
|
||||
set_text (textcell, text);
|
||||
void
|
||||
CairoEditableText::set_width_chars (CairoTextCell* cell, uint32_t wc)
|
||||
{
|
||||
if (cell) {
|
||||
cell->set_width_chars (wc);
|
||||
queue_resize ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -206,24 +195,25 @@ CairoEditableText::on_expose_event (GdkEventExpose* ev)
|
|||
context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
|
||||
context->clip ();
|
||||
|
||||
context->set_source_rgba (bg_r, bg_g, bg_b, bg_a);
|
||||
if (_corner_radius) {
|
||||
rounded_rectangle (context, 0, 0, width, height, _corner_radius);
|
||||
} else {
|
||||
context->rectangle (0, 0, width, height);
|
||||
if (_draw_bg) {
|
||||
context->set_source_rgba (bg_r, bg_g, bg_b, bg_a);
|
||||
if (_corner_radius) {
|
||||
rounded_rectangle (context, 0, 0, width, height, _corner_radius);
|
||||
} else {
|
||||
context->rectangle (0, 0, width, height);
|
||||
}
|
||||
context->fill ();
|
||||
}
|
||||
context->fill ();
|
||||
|
||||
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
|
||||
|
||||
uint32_t id = i->first;
|
||||
CairoCell* cell = i->second;
|
||||
CairoCell* cell = (*i);
|
||||
|
||||
/* is cell inside the expose area?
|
||||
*/
|
||||
|
||||
if (cell->intersects (ev->area)) {
|
||||
if (id == editing_id) {
|
||||
if (cell == editing_cell) {
|
||||
context->set_source_rgba (edit_r, edit_b, edit_g, edit_a);
|
||||
} else {
|
||||
context->set_source_rgba (r, g, b, a);
|
||||
|
|
@ -257,12 +247,11 @@ CairoEditableText::queue_draw_cell (CairoCell* cell)
|
|||
}
|
||||
|
||||
CairoCell*
|
||||
CairoEditableText::find_cell (uint32_t x, uint32_t y, uint32_t& id)
|
||||
CairoEditableText::find_cell (uint32_t x, uint32_t y)
|
||||
{
|
||||
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
|
||||
if (i->second->covers (x, y)) {
|
||||
id = i->first;
|
||||
return i->second;
|
||||
if ((*i)->covers (x, y)) {
|
||||
return (*i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,38 +261,24 @@ CairoEditableText::find_cell (uint32_t x, uint32_t y, uint32_t& id)
|
|||
bool
|
||||
CairoEditableText::on_button_press_event (GdkEventButton* ev)
|
||||
{
|
||||
uint32_t id;
|
||||
CairoCell* cell = find_cell (ev->x, ev->y, id);
|
||||
|
||||
if (!cell) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return button_press (ev, id);
|
||||
CairoCell* cell = find_cell (ev->x, ev->y);
|
||||
return button_press (ev, cell);
|
||||
}
|
||||
|
||||
bool
|
||||
CairoEditableText::on_button_release_event (GdkEventButton* ev)
|
||||
{
|
||||
uint32_t id;
|
||||
CairoCell* cell = find_cell (ev->x, ev->y, id);
|
||||
|
||||
if (!cell) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return button_release (ev, id);
|
||||
CairoCell* cell = find_cell (ev->x, ev->y);
|
||||
return button_release (ev, cell);
|
||||
}
|
||||
|
||||
void
|
||||
CairoEditableText::start_editing (uint32_t id)
|
||||
CairoEditableText::start_editing (CairoCell* cell)
|
||||
{
|
||||
CairoCell* cell = get_cell (id);
|
||||
|
||||
stop_editing ();
|
||||
|
||||
if (cell) {
|
||||
editing_id = id;
|
||||
editing_cell = cell;
|
||||
queue_draw_cell (cell);
|
||||
grab_focus ();
|
||||
}
|
||||
|
|
@ -312,12 +287,9 @@ CairoEditableText::start_editing (uint32_t id)
|
|||
void
|
||||
CairoEditableText::stop_editing ()
|
||||
{
|
||||
if (editing_id) {
|
||||
CairoCell* cell;
|
||||
if ((cell = get_cell (editing_id))) {
|
||||
queue_draw_cell (cell);
|
||||
}
|
||||
editing_id = 0;
|
||||
if (editing_cell) {
|
||||
queue_draw_cell (editing_cell);
|
||||
editing_cell = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -333,7 +305,7 @@ CairoEditableText::on_size_request (GtkRequisition* req)
|
|||
CellMap::iterator i = cells.begin();
|
||||
|
||||
while (i != cells.end()) {
|
||||
CairoCell* cell = i->second;
|
||||
CairoCell* cell = (*i);
|
||||
|
||||
if (cell->visible()) {
|
||||
cell->set_position (x, _ypad);
|
||||
|
|
@ -378,8 +350,10 @@ CairoEditableText::set_font (const Pango::FontDescription& fd)
|
|||
{
|
||||
Glib::RefPtr<Pango::Context> context = get_pango_context ();
|
||||
|
||||
_font = fd;
|
||||
|
||||
for (CellMap::iterator i = cells.begin(); i != cells.end(); ++i) {
|
||||
i->second->set_size (context, fd);
|
||||
(*i)->set_size (context, _font);
|
||||
}
|
||||
|
||||
queue_resize ();
|
||||
|
|
|
|||
|
|
@ -28,9 +28,11 @@
|
|||
|
||||
class CairoCell
|
||||
{
|
||||
public:
|
||||
CairoCell();
|
||||
public:
|
||||
CairoCell(int32_t id);
|
||||
virtual ~CairoCell() {}
|
||||
|
||||
int32_t id() const { return _id; }
|
||||
|
||||
virtual void render (Cairo::RefPtr<Cairo::Context>&) = 0;
|
||||
|
||||
|
|
@ -61,7 +63,8 @@ public:
|
|||
virtual void set_size (Glib::RefPtr<Pango::Context>&,
|
||||
const Pango::FontDescription&) {}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
int32_t _id;
|
||||
GdkRectangle bbox;
|
||||
bool _visible;
|
||||
uint32_t _xpad;
|
||||
|
|
@ -69,30 +72,32 @@ protected:
|
|||
|
||||
class CairoBarCell : public CairoCell
|
||||
{
|
||||
public:
|
||||
CairoBarCell() {};
|
||||
public:
|
||||
CairoBarCell(int32_t id) : CairoCell (id) {};
|
||||
|
||||
void render (Cairo::RefPtr<Cairo::Context>& context) {
|
||||
context->move_to (bbox.x, bbox.y);
|
||||
context->set_line_width (bbox.width);
|
||||
context->rel_line_to (0, bbox.height);
|
||||
context->stroke ();
|
||||
if (bbox.height > 4) {
|
||||
context->move_to (bbox.x, bbox.y + 2);
|
||||
context->set_line_width (bbox.width);
|
||||
context->rel_line_to (0, bbox.height - 2);
|
||||
context->stroke ();
|
||||
}
|
||||
}
|
||||
|
||||
void set_size (Glib::RefPtr<Pango::Context>& context,
|
||||
const Pango::FontDescription& font) {
|
||||
Pango::FontMetrics metrics = context->get_metrics (font);
|
||||
bbox.width = 2;
|
||||
bbox.width = std::max (1.5, (0.1 * metrics.get_approximate_digit_width() / PANGO_SCALE));
|
||||
bbox.height = (metrics.get_ascent() + metrics.get_descent()) / PANGO_SCALE;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
};
|
||||
|
||||
class CairoColonCell : public CairoCell
|
||||
{
|
||||
public:
|
||||
CairoColonCell() {};
|
||||
public:
|
||||
CairoColonCell (int32_t id) : CairoCell (id) {};
|
||||
|
||||
void render (Cairo::RefPtr<Cairo::Context>& context);
|
||||
void set_size (Glib::RefPtr<Pango::Context>& context,
|
||||
|
|
@ -101,19 +106,23 @@ public:
|
|||
|
||||
class CairoTextCell : public CairoCell
|
||||
{
|
||||
public:
|
||||
CairoTextCell (double width_chars);
|
||||
public:
|
||||
CairoTextCell (int32_t id, double width_chars);
|
||||
void set_size (Glib::RefPtr<Pango::Context>&, const Pango::FontDescription&);
|
||||
|
||||
void set_text (const std::string& txt);
|
||||
|
||||
std::string get_text() const {
|
||||
return layout->get_text ();
|
||||
}
|
||||
double width_chars() const { return _width_chars; }
|
||||
|
||||
void render (Cairo::RefPtr<Cairo::Context>&);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
friend class CairoEditableText;
|
||||
void set_width_chars (double wc) { _width_chars = wc; }
|
||||
void set_text (const std::string& txt);
|
||||
|
||||
private:
|
||||
double _width_chars;
|
||||
Glib::RefPtr<Pango::Layout> layout;
|
||||
};
|
||||
|
|
@ -124,15 +133,17 @@ public:
|
|||
CairoEditableText ();
|
||||
~CairoEditableText ();
|
||||
|
||||
void add_cell (uint32_t id, CairoCell*);
|
||||
CairoCell* get_cell (uint32_t id);
|
||||
void add_cell (CairoCell*);
|
||||
void clear_cells ();
|
||||
|
||||
void start_editing (uint32_t id);
|
||||
void start_editing (CairoCell*);
|
||||
void stop_editing ();
|
||||
|
||||
void set_text (uint32_t id, const std::string& text);
|
||||
void set_text (CairoTextCell* cell, const std::string&);
|
||||
void set_width_chars (CairoTextCell* cell, uint32_t);
|
||||
|
||||
void set_draw_background (bool yn) { _draw_bg = yn; }
|
||||
|
||||
void set_colors (double cr, double cg, double cb, double ca) {
|
||||
r = cr;
|
||||
g = cg;
|
||||
|
|
@ -168,9 +179,9 @@ public:
|
|||
double corner_radius() const { return _corner_radius; }
|
||||
void set_corner_radius (double r) { _corner_radius = r; queue_draw (); }
|
||||
|
||||
sigc::signal<bool,GdkEventScroll*,uint32_t> scroll;
|
||||
sigc::signal<bool,GdkEventButton*,uint32_t> button_press;
|
||||
sigc::signal<bool,GdkEventButton*,uint32_t> button_release;
|
||||
sigc::signal<bool,GdkEventScroll*,CairoCell*> scroll;
|
||||
sigc::signal<bool,GdkEventButton*,CairoCell*> button_press;
|
||||
sigc::signal<bool,GdkEventButton*,CairoCell*> button_release;
|
||||
|
||||
protected:
|
||||
bool on_expose_event (GdkEventExpose*);
|
||||
|
|
@ -183,11 +194,12 @@ protected:
|
|||
bool on_scroll_event (GdkEventScroll*);
|
||||
|
||||
private:
|
||||
typedef std::map<uint32_t,CairoCell*> CellMap;
|
||||
typedef std::vector<CairoCell*> CellMap;
|
||||
|
||||
CellMap cells;
|
||||
Pango::FontDescription font;
|
||||
uint32_t editing_id;
|
||||
Pango::FontDescription _font;
|
||||
CairoCell* editing_cell;
|
||||
bool _draw_bg;
|
||||
double width;
|
||||
double max_cell_height;
|
||||
double height;
|
||||
|
|
@ -207,7 +219,7 @@ private:
|
|||
double bg_b;
|
||||
double bg_a;
|
||||
|
||||
CairoCell* find_cell (uint32_t x, uint32_t y, uint32_t& cell_id);
|
||||
CairoCell* find_cell (uint32_t x, uint32_t y);
|
||||
void queue_draw_cell (CairoCell* target);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue