add required virtual method for SrcFileSource
[ardour.git] / libs / gtkmm2ext / tearoff.cc
index 28fb5ba4ef60f37e987c8d79886a73de654eae12..f0bacb593b5e79ea09ad28b9140ffe497300f88d 100644 (file)
@@ -35,14 +35,16 @@ using namespace Glib;
 using namespace std;
 
 TearOff::TearOff (Widget& c, bool allow_resize)
-       : contents (c),
-         own_window (Gtk::WINDOW_TOPLEVEL),
-         tearoff_arrow (ARROW_DOWN, SHADOW_OUT),
-         close_arrow (ARROW_UP, SHADOW_OUT)
+       : contents (c)
+        , own_window (Gtk::WINDOW_TOPLEVEL)
+        , tearoff_arrow (ARROW_DOWN, SHADOW_OUT)
+        , close_arrow (ARROW_UP, SHADOW_OUT)
+        , dragging (false)
+        , _visible (true)
+        , _torn (false)
+        , _can_be_torn_off (true)
+         
 {
-       dragging = false;
-       _visible = true;
-       _can_be_torn_off = true;
         own_window_width = 0;
         own_window_height = 0;
         own_window_xpos = 0;
@@ -52,38 +54,42 @@ TearOff::TearOff (Widget& c, bool allow_resize)
        tearoff_event_box.set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK);
        tearoff_event_box.signal_button_release_event().connect (mem_fun (*this, &TearOff::tearoff_click));
 
+       tearoff_event_box.set_tooltip_text (_("Click to tear this into its own window"));
+        
        close_event_box.add (close_arrow);
        close_event_box.set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK);
        close_event_box.signal_button_release_event().connect (mem_fun (*this, &TearOff::close_click));
-       
-       own_window.add_events (KEY_PRESS_MASK|KEY_RELEASE_MASK|BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK|POINTER_MOTION_MASK|POINTER_MOTION_HINT_MASK);
-       own_window.set_resizable (allow_resize);
-       own_window.set_type_hint (WINDOW_TYPE_HINT_TOOLBAR);
-        own_window.signal_realize().connect (sigc::mem_fun (*this, &TearOff::own_window_realized));
-        own_window.signal_configure_event().connect (sigc::mem_fun (*this, &TearOff::own_window_configured), false);
+
+        close_event_box.set_tooltip_text (_("Click to put this back in the main window"));
 
        VBox* box1;
        box1 = manage (new VBox);
        box1->pack_start (close_event_box, false, false, 2);
        
        window_box.pack_end (*box1, false, false, 2);
+
+       own_window.add_events (KEY_PRESS_MASK|KEY_RELEASE_MASK|BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK|POINTER_MOTION_MASK|POINTER_MOTION_HINT_MASK);
+       own_window.set_resizable (allow_resize);
+       own_window.set_type_hint (WINDOW_TYPE_HINT_TOOLBAR);
+
        own_window.add (window_box);
        
        own_window.signal_button_press_event().connect (mem_fun (*this, &TearOff::window_button_press));
        own_window.signal_button_release_event().connect (mem_fun (*this, &TearOff::window_button_release));
        own_window.signal_motion_notify_event().connect (mem_fun (*this, &TearOff::window_motion));
        own_window.signal_delete_event().connect (mem_fun (*this, &TearOff::window_delete_event));
-       own_window.signal_realize().connect (bind (sigc::ptr_fun (Gtkmm2ext::set_decoration), &own_window, WMDecoration (DECOR_BORDER|DECOR_RESIZEH)));
+        own_window.signal_realize().connect (sigc::mem_fun (*this, &TearOff::own_window_realized));
+        own_window.signal_configure_event().connect (sigc::mem_fun (*this, &TearOff::own_window_configured), false);
 
        tearoff_arrow.set_name ("TearOffArrow");
        close_arrow.set_name ("TearOffArrow");
 
        VBox* box2;
        box2 = manage (new VBox);
-       box2->pack_start (tearoff_event_box, false, false, 2);
+       box2->pack_start (tearoff_event_box, false, false);
 
        pack_start (contents);
-       pack_start (*box2, false, false, 2);
+       pack_start (*box2, false, false);
 }
 
 TearOff::~TearOff ()
@@ -106,15 +112,15 @@ TearOff::set_can_be_torn_off (bool yn)
 }
 
 void
-TearOff::set_visible (bool yn)
+TearOff::set_visible (bool yn, bool force)
 {
        /* don't change visibility if torn off */
 
-       if (own_window.is_visible()) {
+       if (_torn) {
                return;
        }
 
-       if (_visible != yn) {
+       if (_visible != yn || force) {
                _visible = yn;
                if (yn) {
                        show_all();
@@ -148,9 +154,15 @@ TearOff::tear_it_off ()
         window_box.pack_start (contents);
         own_window.set_name (get_name());
         close_event_box.set_name (get_name());
+        if (own_window_width == 0) {
+                own_window.set_position (WIN_POS_MOUSE);
+        }
         own_window.show_all ();
         own_window.present ();
         hide ();
+
+        _torn = true;
+
         Detach ();
 }        
 
@@ -173,6 +185,9 @@ TearOff::put_it_back ()
        reorder_child (contents, 0);
        own_window.hide ();
        show_all ();
+
+        _torn = false;
+
        Attach ();
 }
 
@@ -245,13 +260,13 @@ TearOff::window_motion (GdkEventMotion* ev)
 bool
 TearOff::torn_off() const
 {
-       return own_window.is_visible();
+       return _torn;
 }
 
 void
-TearOff::add_tornoff_state (XMLNode& node) const
+TearOff::add_state (XMLNode& node) const
 {
-        node.add_property ("tornoff", (own_window.is_visible() ? "yes" : "no"));
+        node.add_property ("tornoff", (_torn ? "yes" : "no"));
 
         if (own_window_width > 0) {
                 char buf[32];
@@ -268,7 +283,7 @@ TearOff::add_tornoff_state (XMLNode& node) const
 }        
 
 void
-TearOff::set_tornoff_state (const XMLNode& node)
+TearOff::set_state (const XMLNode& node)
 {
         Glib::RefPtr<Gdk::Window> win;
         const XMLProperty* prop;
@@ -296,13 +311,18 @@ TearOff::set_tornoff_state (const XMLNode& node)
                 sscanf (prop->value().c_str(), "%d", &own_window_ypos);
         }
 
-        own_window.set_default_size (own_window_width, own_window_height);
-        own_window.move (own_window_xpos, own_window_ypos);
+        if (own_window.is_realized()) {
+                own_window.set_default_size (own_window_width, own_window_height);
+                own_window.move (own_window_xpos, own_window_ypos);
+        }
+        /* otherwise do it once the window is realized, see below */
 }        
 
 void
 TearOff::own_window_realized ()
 {
+       own_window.get_window()->set_decorations (WMDecoration (DECOR_BORDER|DECOR_RESIZEH));
+
         if (own_window_width > 0) {
                 own_window.set_default_size (own_window_width, own_window_height);
                 own_window.move (own_window_xpos, own_window_ypos);
@@ -323,3 +343,15 @@ TearOff::own_window_configured (GdkEventConfigure*)
 
         return false;
 }
+
+void
+TearOff::hide_visible ()
+{
+        if (torn_off()) {
+                own_window.hide ();
+        }
+
+        hide ();
+}
+
+