fixes for 98% of all the warnings/errors reported by OS X gcc on tiger
[ardour.git] / gtk2_ardour / audio_clock.cc
index 15b3131b4ce8d3a3ba8b4bdc3b80782fb2ae4f1e..aff72fbf6e0d063976ba34db070f635ca7e98b06 100644 (file)
@@ -55,6 +55,7 @@ sigc::signal<void> AudioClock::ModeChanged;
 vector<AudioClock*> AudioClock::clocks;
 
 uint32_t AudioClock::field_length[] = {
+       1, /* Timecode_Sign */
        2, /* Timecode_Hours */
        2, /* Timecode_Minutes */
        2, /* Timecode_Seconds */
@@ -76,6 +77,7 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string&
        , is_duration (duration)
        , editable (allow_edit)
        , _follows_playhead (follows_playhead)
+       , _off (false)
        , supplemental_left (0)
        , supplemental_right (0)
        , last_when(0)
@@ -107,15 +109,16 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string&
        /* basic per-mode editable text "arrays" */
 
        display = new CairoEditableText ();
+       display->set_corner_radius (0);
 
-       _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);
+       _fixed_cells[Colon1] = new CairoCharCell (Colon1, ':');
+       _fixed_cells[Colon2] = new CairoCharCell (Colon2, ':');
+       _fixed_cells[Colon3] = new CairoCharCell (Colon3, ':');
+       _fixed_cells[Bar1] = new CairoCharCell (Bar1, '|');
+       _fixed_cells[Bar2] = new CairoCharCell (Bar2, '|');
        
-       // 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_Sign] = new CairoTextCell (Timecode_Sign, field_length[Timecode_Sign]);
+       _text_cells[Timecode_Hours] = new CairoTextCell (Timecode_Hours, field_length[Timecode_Hours]);
        _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]);
@@ -137,13 +140,16 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string&
        
        _text_cells[AudioFrames] = new CairoTextCell (AudioFrames, field_length[AudioFrames]);
 
-       packer.set_homogeneous (false);
+       set_homogeneous (false);
 
        if (with_info) {
 
                supplemental_left = new CairoEditableText ();
                supplemental_right = new CairoEditableText ();
 
+               supplemental_left->set_corner_radius (0);
+               supplemental_right->set_corner_radius (0);
+
                /* field lengths of these cells will be set dynamically by ::set_mode()
                 */
 
@@ -159,14 +165,14 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string&
 
                top.pack_start (*display, true, true);
                
-               packer.set_spacing (1);
-               packer.pack_start (top, true, true);
-               packer.pack_start (bottom, false, false);
+               set_spacing (1);
+               
+               pack_start (top, true, true);
+               pack_start (bottom, true, true);
        } else {
-               packer.pack_start (*display, true, true);
+               pack_start (*display, true, true);
        }
 
-       add (packer);
        show_all ();
 
        set_widget_name (widget_name);
@@ -175,6 +181,8 @@ AudioClock::AudioClock (const string& clock_name, bool transient, const string&
        set_mode (Timecode);
        set (last_when, true);
 
+       connect_signals ();
+
        if (!is_transient) {
                clocks.push_back (this);
        }
@@ -185,17 +193,18 @@ AudioClock::~AudioClock ()
        /* these are not manage()'d, so that we can add/remove
           them from containers as necessary.
        */
+
        delete display;
        delete supplemental_left;
        delete supplemental_right;
-       /* XXX need to delete all cells too */
-}
 
-void
-AudioClock::set_font (const string& font)
-{
-       display->set_font (font);
-       /* XXX supplemental ...  */
+       for (std::map<Field,CairoCell*>::iterator i = _fixed_cells.begin(); i != _fixed_cells.end(); ++i) {
+               delete i->second;
+       }
+
+       for (std::map<Field,CairoTextCell*>::iterator i = _text_cells.begin(); i != _text_cells.end(); ++i) {
+               delete i->second;
+       }
 }
 
 void
@@ -226,9 +235,12 @@ AudioClock::set_theme ()
 
        display->set_font (font);
 
-       if (supplemental_right) {
-               Pango::FontDescription smaller_font ("Sans 8");
-               
+
+       if (supplemental_left) {
+               /* propagate font style, sort of, into supplemental text */
+               boost::shared_ptr<CairoFontDescription> smaller_font (new CairoFontDescription (*display->font().get()));
+               smaller_font->set_size (12);
+               smaller_font->set_weight (Cairo::FONT_WEIGHT_NORMAL);
                supplemental_right->set_font (smaller_font);
                supplemental_left->set_font (smaller_font);
        }
@@ -303,7 +315,7 @@ AudioClock::end_edit ()
 void
 AudioClock::on_realize ()
 {
-       Alignment::on_realize ();
+       VBox::on_realize ();
 
        /* styles are not available until the widgets are bound to a window */
        
@@ -360,9 +372,6 @@ AudioClock::set (framepos_t when, bool force, framecnt_t offset, char which)
        case Frames:
                set_frames (when, force);
                break;
-
-       case Off:
-               break;
        }
 
        last_when = when;
@@ -400,6 +409,18 @@ AudioClock::set_frames (framepos_t when, bool /*force*/)
 {
        char buf[32];
        snprintf (buf, sizeof (buf), "%" PRId64, when);
+
+       if (_off) {
+               display->set_text (_text_cells[AudioFrames], "-----------");
+
+               if (supplemental_left) {
+                       supplemental_left->set_text (_text_cells[LowerLeft2], "");
+                       supplemental_right->set_text (_text_cells[LowerRight2], "");
+               }
+               
+               return;
+       }
+
        
        display->set_text (_text_cells[AudioFrames], buf);
 
@@ -435,6 +456,20 @@ AudioClock::set_minsec (framepos_t when, bool force)
        int secs;
        int millisecs;
 
+       if (_off) {
+               display->set_text (_text_cells[MS_Hours], "--");
+               display->set_text (_text_cells[MS_Minutes], "--");
+               display->set_text (_text_cells[MS_Seconds], "--");
+               display->set_text (_text_cells[MS_Milliseconds], "--");
+
+               if (supplemental_left) {
+                       supplemental_left->set_text (_text_cells[LowerLeft2], "");
+                       supplemental_right->set_text (_text_cells[LowerRight2], "");
+               }
+               
+               return;
+       }       
+
        left = when;
        hrs = (int) floor (left / (_session->frame_rate() * 60.0f * 60.0f));
        left -= (framecnt_t) floor (hrs * _session->frame_rate() * 60.0f * 60.0f);
@@ -475,6 +510,21 @@ AudioClock::set_timecode (framepos_t when, bool force)
        char buf[32];
        Timecode::Time TC;
 
+       if (_off) {
+               display->set_text (_text_cells[Timecode_Sign], "");
+               display->set_text (_text_cells[Timecode_Hours], "--");
+               display->set_text (_text_cells[Timecode_Minutes], "--");
+               display->set_text (_text_cells[Timecode_Seconds], "--");
+               display->set_text (_text_cells[Timecode_Frames], "--");
+
+               if (supplemental_left) {
+                       supplemental_left->set_text (_text_cells[LowerLeft2], "");
+                       supplemental_right->set_text (_text_cells[LowerRight2], "");
+               }
+               
+               return;
+       }
+
        if (is_duration) {
                _session->timecode_duration (when, TC);
        } else {
@@ -483,9 +533,11 @@ AudioClock::set_timecode (framepos_t when, bool force)
 
        if (force || TC.hours != last_hrs || TC.negative != last_negative) {
                if (TC.negative) {
-                       sprintf (buf, "-%0*" PRIu32, field_length[Timecode_Hours], TC.hours);
+                       display->set_text (_text_cells[Timecode_Sign], "-");
+                       sprintf (buf, "%0*" PRIu32, field_length[Timecode_Hours], TC.hours);
                } else {
-                       sprintf (buf, " %0*" PRIu32, field_length[Timecode_Hours], TC.hours);
+                       display->set_text (_text_cells[Timecode_Sign], " ");
+                       sprintf (buf, "%0*" PRIu32, field_length[Timecode_Hours], TC.hours);
                }
                display->set_text (_text_cells[Timecode_Hours], buf);
                last_hrs = TC.hours;
@@ -512,20 +564,11 @@ AudioClock::set_timecode (framepos_t when, bool force)
 
        if (supplemental_right) {
                double timecode_frames = _session->timecode_frames_per_second();
-               bool drop;
-
-               if ((fabs(timecode_frames - 29.97) < 0.0001) || timecode_frames == 30) {
-                       if (_session->timecode_drop_frames()) {
-                               drop = true;
-                       } else {
-                               drop = false;
-                       }
-               } 
        
                if (fmod(timecode_frames, 1.0) == 0.0) {
-                       sprintf (buf, "%u %s", int (timecode_frames), (drop ? "D" : ""));
+                       sprintf (buf, "%u %s", int (timecode_frames), (_session->timecode_drop_frames() ? "D" : ""));
                } else {
-                       sprintf (buf, "%.2f %s", timecode_frames, (drop ? "D" : ""));
+                       sprintf (buf, "%.2f %s", timecode_frames, (_session->timecode_drop_frames() ? "D" : ""));
                }
 
                supplemental_right->set_text (_text_cells[LowerRight2], buf);
@@ -538,6 +581,19 @@ AudioClock::set_bbt (framepos_t when, bool force)
        char buf[16];
        Timecode::BBT_Time BBT;
 
+       if (_off) {
+               display->set_text (_text_cells[Bars], "--");
+               display->set_text (_text_cells[Beats], "--");
+               display->set_text (_text_cells[Ticks], "--");
+
+               if (supplemental_left) {
+                       supplemental_left->set_text (_text_cells[LowerLeft2], "");
+                       supplemental_right->set_text (_text_cells[LowerRight2], "");
+               }
+               
+               return;
+       }
+
        /* handle a common case */
        if (is_duration) {
                if (when == 0) {
@@ -594,14 +650,23 @@ AudioClock::set_session (Session *s)
 
                _session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&AudioClock::session_configuration_changed, this, _1), gui_context());
 
-               XMLProperty* prop;
+               const XMLProperty* prop;
                XMLNode* node = _session->extra_xml (X_("ClockModes"));
                AudioClock::Mode amode;
 
                if (node) {
-                       if ((prop = node->property (_name)) != 0) {
-                               amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
-                               set_mode (amode);
+                       for (XMLNodeList::const_iterator i = node->children().begin(); i != node->children().end(); ++i) {
+                               if ((prop = (*i)->property (X_("name"))) && prop->value() == _name) {
+
+                                       if ((prop = (*i)->property (X_("mode"))) != 0) {
+                                               amode = AudioClock::Mode (string_2_enum (prop->value(), amode));
+                                               set_mode (amode);
+                                       }
+                                       if ((prop = (*i)->property (X_("on"))) != 0) {
+                                               set_off (!string_is_affirmative (prop->value()));
+                                       }
+                                       break;
+                               }
                        }
                }
 
@@ -895,21 +960,41 @@ AudioClock::button_press (GdkEventButton *ev, CairoCell* cell)
 {
        switch (ev->button) {
        case 1:
-               if (cell) {
-                       editing_field = (Field) cell->id ();
-                       display->start_editing (cell);
+               if (editable) {
+                       if (cell) {
+                               Field f = (Field) cell->id ();
+                               switch (f) {
+                               case Timecode_Hours:
+                               case Timecode_Minutes:
+                               case Timecode_Seconds:
+                               case Timecode_Frames:
+                               case MS_Hours:
+                               case MS_Minutes:
+                               case MS_Seconds:
+                               case MS_Milliseconds:
+                               case Bars:
+                               case Beats:
+                               case Ticks:
+                               case AudioFrames:
+                                       editing_field = f;
+                                       display->start_editing (cell);
+                                       break;
+                               default:
+                                       return false;
+                               }
+                       }
+                       
+                       Keyboard::magic_widget_grab_focus ();
+                       
+                       /* make absolutely sure that the pointer is grabbed */
+                       gdk_pointer_grab(ev->window,false ,
+                                        GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
+                                        NULL,NULL,ev->time);
+                       dragging = true;
+                       drag_accum = 0;
+                       drag_start_y = ev->y;
+                       drag_y = ev->y;
                }
-
-               Keyboard::magic_widget_grab_focus ();
-
-               /* make absolutely sure that the pointer is grabbed */
-               gdk_pointer_grab(ev->window,false ,
-                                GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
-                                NULL,NULL,ev->time);
-               dragging = true;
-               drag_accum = 0;
-               drag_start_y = ev->y;
-               drag_y = ev->y;
                break;
                
        default:
@@ -923,21 +1008,15 @@ AudioClock::button_press (GdkEventButton *ev, CairoCell* cell)
 bool
 AudioClock::button_release (GdkEventButton *ev, CairoCell*)
 {
-       if (dragging) {
-               gdk_pointer_ungrab (GDK_CURRENT_TIME);
-               dragging = false;
-               if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){
-                       // we actually dragged so return without setting editing focus, or we shift clicked
-                       return true;
-               }
-       }
-
-       if (!editable) {
-               if (ops_menu == 0) {
-                       build_ops_menu ();
+       if (editable) {
+               if (dragging) {
+                       gdk_pointer_ungrab (GDK_CURRENT_TIME);
+                       dragging = false;
+                       if (ev->y > drag_start_y+1 || ev->y < drag_start_y-1 || Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)){
+                               // we actually dragged so return without setting editing focus, or we shift clicked
+                               return true;
+                       }
                }
-               ops_menu->popup (1, ev->time);
-               return true;
        }
 
        if (Keyboard::is_context_menu_event (ev)) {
@@ -948,16 +1027,37 @@ AudioClock::button_release (GdkEventButton *ev, CairoCell*)
                return true;
        }
 
-       return true;
+       return false;
 }
 
 bool
 AudioClock::scroll (GdkEventScroll *ev, CairoCell* cell)
 {
-       if (_session == 0) {
+       if (_session == 0 || !editable) {
                return false;
        }
 
+       if (cell) {
+               Field f = (Field) cell->id ();
+               switch (f) {
+               case Timecode_Hours:
+               case Timecode_Minutes:
+               case Timecode_Seconds:
+               case Timecode_Frames:
+               case MS_Hours:
+               case MS_Minutes:
+               case MS_Seconds:
+               case MS_Milliseconds:
+               case Bars:
+               case Beats:
+               case Ticks:
+               case AudioFrames:
+                       break;
+               default:
+                       return false;
+               }
+       }
+                       
        framepos_t frames = 0;
 
        switch (ev->direction) {
@@ -1139,9 +1239,6 @@ AudioClock::current_time (framepos_t pos) const
        case Frames:
                ret = audio_frame_from_display ();
                break;
-
-       case Off:
-               break;
        }
 
        return ret;
@@ -1167,9 +1264,6 @@ AudioClock::current_duration (framepos_t pos) const
        case Frames:
                ret = audio_frame_from_display ();
                break;
-
-       case Off:
-               break;
        }
 
        return ret;
@@ -1243,7 +1337,12 @@ AudioClock::timecode_frame_from_display () const
        Timecode::Time TC;
        framepos_t sample;
 
-       TC.hours = atoi (label (Timecode_Hours)->get_text());
+       if (!label (Timecode_Sign)->get_text().empty()) {
+               TC.hours = atoi (label (Timecode_Hours)->get_text());
+       } else {
+               TC.hours = -atoi (label (Timecode_Hours)->get_text());
+       }
+
        TC.minutes = atoi (label (Timecode_Minutes)->get_text());
        TC.seconds = atoi (label (Timecode_Seconds)->get_text());
        TC.frames = atoi (label (Timecode_Frames)->get_text());
@@ -1706,7 +1805,6 @@ AudioClock::build_ops_menu ()
        ops_items.push_back (MenuElem (_("Bars:Beats"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), BBT)));
        ops_items.push_back (MenuElem (_("Minutes:Seconds"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), MinSec)));
        ops_items.push_back (MenuElem (_("Samples"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Frames)));
-       ops_items.push_back (MenuElem (_("Off"), sigc::bind (sigc::mem_fun(*this, &AudioClock::set_mode), Off)));
 
        if (editable && !is_duration && !_follows_playhead) {
                ops_items.push_back (SeparatorElem());
@@ -1736,24 +1834,12 @@ AudioClock::locate ()
        _session->request_locate (current_time(), _session->transport_rolling ());
 }
 
-void
-AudioClock::disconnect_signals ()
-{
-       scroll_connection.disconnect ();
-       button_press_connection.disconnect ();
-       button_release_connection.disconnect ();
-}
-
 void
 AudioClock::connect_signals ()
 {
-       disconnect_signals ();
-
-       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));
-       }       
+       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
@@ -1774,6 +1860,7 @@ AudioClock::set_mode (Mode m)
 
        switch (_mode) {
        case Timecode:
+               display->add_cell (_text_cells[Timecode_Sign]);
                display->add_cell (_text_cells[Timecode_Hours]);
                display->add_cell (_fixed_cells[Colon1]);
                display->add_cell (_text_cells[Timecode_Minutes]);
@@ -1811,14 +1898,14 @@ AudioClock::set_mode (Mode m)
                        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[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[LowerRight1], 2); // why not 1? M is too wide
                        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"));
+                       supplemental_left->set_text (_text_cells[LowerLeft1], _("T")); 
+                       supplemental_right->set_text (_text_cells[LowerRight1], _("M"));
                }
                break;
 
@@ -1830,6 +1917,23 @@ AudioClock::set_mode (Mode m)
                display->add_cell (_text_cells[MS_Seconds]);
                display->add_cell (_fixed_cells[Colon3]);
                display->add_cell (_text_cells[MS_Milliseconds]);
+               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]);
+
+                       /* These are going to remain empty */
+
+                       supplemental_left->set_width_chars (_text_cells[LowerLeft1], 1);
+                       supplemental_left->set_width_chars (_text_cells[LowerLeft2], 5);
+                       
+                       supplemental_right->set_width_chars (_text_cells[LowerRight1], 1);
+                       supplemental_right->set_width_chars (_text_cells[LowerRight2], 1);
+
+                       supplemental_left->set_text (_text_cells[LowerLeft1], _(" "));
+                       supplemental_right->set_text (_text_cells[LowerRight1], _(" "));
+               }
                break;
 
        case Frames:
@@ -1850,9 +1954,6 @@ AudioClock::set_mode (Mode m)
                        supplemental_right->set_text (_text_cells[LowerRight1], _("Pull"));
                }
                break;
-
-       case Off:
-               break;
        }
 
        if (supplemental_left) {
@@ -1861,12 +1962,6 @@ AudioClock::set_mode (Mode m)
                supplemental_right->set_text (_text_cells[LowerRight2], _(""));
        }
 
-       if (_mode != Off) {
-               connect_signals ();
-       } else {
-               disconnect_signals  ();
-       }
-
        set (last_when, true);
 
         if (!is_transient) {
@@ -1885,7 +1980,7 @@ AudioClock::set_bbt_reference (framepos_t pos)
 void
 AudioClock::on_style_changed (const Glib::RefPtr<Gtk::Style>& old_style)
 {
-       Alignment::on_style_changed (old_style);
+       VBox::on_style_changed (old_style);
        set_theme ();
 }
 
@@ -1900,3 +1995,24 @@ AudioClock::set_is_duration (bool yn)
        set (last_when, true, 0, 's');
 }
 
+void
+AudioClock::set_off (bool yn) 
+{
+       if (_off == yn) {
+               return;
+       }
+
+       _off = yn;
+
+       if (_off) {
+               _canonical_time = current_time ();
+               _canonical_time_is_displayed = false;
+       } else {
+               _canonical_time_is_displayed = true;
+       }
+
+       /* force a possible redraw */
+       
+       set (_canonical_time, true);
+}
+