first compilable version of tabbable design.

I would have loved to split this apart, but there are just so many interrelated changes,
it makes little sense and would be a huge effort that would break future git bisect
use because so many intermediate commits would not compile
This commit is contained in:
Paul Davis 2015-07-07 22:12:21 -04:00
parent 85eee3b09d
commit 9010262bed
42 changed files with 1007 additions and 1117 deletions

View file

@ -48,6 +48,7 @@
#include "pbd/error.h"
#include "pbd/basename.h"
#include "pbd/compose.h"
#include "pbd/convert.h"
#include "pbd/failed_constructor.h"
#include "pbd/enumwriter.h"
#include "pbd/memento_command.h"
@ -110,6 +111,7 @@ typedef uint64_t microseconds_t;
#include "audio_clock.h"
#include "audio_region_view.h"
#include "big_clock_window.h"
#include "binding_owners.h"
#include "bundle_manager.h"
#include "duplicate_routes_dialog.h"
#include "engine_dialog.h"
@ -224,8 +226,12 @@ libxml_structured_error_func (void* /* parsing_context*/,
ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
<<<<<<< HEAD
: Gtkmm2ext::UI (PROGRAM_NAME, X_("gui"), argcp, argvp)
=======
: Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp)
>>>>>>> first compilable version of tabbable design.
, session_loaded (false)
, gui_object_state (new GUIObjectState)
, primary_clock (new MainClock (X_("primary"), X_("transport"), true ))
@ -262,13 +268,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
, save_as_dialog (0)
, meterbridge (0)
, rc_option_editor (0)
, open_session_selector (0)
, _numpad_locate_happening (false)
, _session_is_new (false)
, last_key_press_time (0)
, save_as_dialog (0)
, meterbridge (0)
, rc_option_editor (0)
, speaker_config_window (X_("speaker-config"), _("Speaker Configuration"))
, key_editor (X_("key-editor"), _("Key Bindings"))
, add_route_dialog (X_("add-routes"), _("Add Tracks/Busses"))
@ -414,20 +413,24 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
const XMLNode* ui_xml = Config->extra_xml (X_("UI"));
if (ui_xml) {
key_editor.set_state (*ui_xml);
// rc_option_editor.set_state (*ui_xml);
session_option_editor.set_state (*ui_xml);
speaker_config_window.set_state (*ui_xml);
about.set_state (*ui_xml);
add_route_dialog.set_state (*ui_xml);
add_video_dialog.set_state (*ui_xml);
route_params.set_state (*ui_xml);
bundle_manager.set_state (*ui_xml);
location_ui.set_state (*ui_xml);
big_clock_window.set_state (*ui_xml);
audio_port_matrix.set_state (*ui_xml);
midi_port_matrix.set_state (*ui_xml);
export_video_dialog.set_state (*ui_xml);
key_editor.set_state (*ui_xml, 0);
session_option_editor.set_state (*ui_xml, 0);
speaker_config_window.set_state (*ui_xml, 0);
about.set_state (*ui_xml, 0);
add_route_dialog.set_state (*ui_xml, 0);
add_video_dialog.set_state (*ui_xml, 0);
route_params.set_state (*ui_xml, 0);
bundle_manager.set_state (*ui_xml, 0);
location_ui.set_state (*ui_xml, 0);
big_clock_window.set_state (*ui_xml, 0);
audio_port_matrix.set_state (*ui_xml, 0);
midi_port_matrix.set_state (*ui_xml, 0);
export_video_dialog.set_state (*ui_xml, 0);
/* tabbables */
// rc_option_editor->set_state (*ui_xml, 0);
// editor->set_state (*ui_xml, 0);
// mixer->set_state (*ui_xml, 0);
}
WM::Manager::instance().register_window (&key_editor);
@ -540,7 +543,7 @@ was not fast enough. Try to restart\n\
the audio backend and save the session."), PROGRAM_NAME);
}
MessageDialog msg (*editor, msgstr);
MessageDialog msg (_main_window, msgstr);
pop_back_splash (msg);
msg.run ();
@ -1104,7 +1107,6 @@ ARDOUR_UI::check_memory_locking ()
pop_back_splash (msg);
editor->ensure_float (msg);
msg.run ();
if (cb.get_active()) {
@ -1150,7 +1152,7 @@ ARDOUR_UI::finish()
/* use the default name */
if (save_state_canfail ("")) {
/* failed - don't quit */
MessageDialog msg (*editor,
MessageDialog msg (_main_window,
string_compose (_("\
%1 was unable to save your session.\n\n\
If you still wish to quit, please use the\n\n\
@ -1765,7 +1767,7 @@ ARDOUR_UI::session_add_mixed_track (const ChanCount& input, const ChanCount& out
}
catch (...) {
MessageDialog msg (*editor,
MessageDialog msg (_main_window,
string_compose (_("There are insufficient ports available\n\
to create a new track or bus.\n\
You should save %1, exit and\n\
@ -1826,7 +1828,7 @@ ARDOUR_UI::session_add_audio_route (
}
catch (...) {
MessageDialog msg (*editor,
MessageDialog msg (_main_window,
string_compose (_("There are insufficient ports available\n\
to create a new track or bus.\n\
You should save %1, exit and\n\
@ -1972,7 +1974,7 @@ ARDOUR_UI::transport_record (bool roll)
switch (_session->record_status()) {
case Session::Disabled:
if (_session->ntracks() == 0) {
MessageDialog msg (*editor, _("Please create one or more tracks before trying to record.\nYou can do this with the \"Add Track or Bus\" option in the Session menu."));
MessageDialog msg (_main_window, _("Please create one or more tracks before trying to record.\nYou can do this with the \"Add Track or Bus\" option in the Session menu."));
msg.run ();
return;
}
@ -3522,7 +3524,7 @@ ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* lis
removed = rep.paths.size();
if (removed == 0) {
MessageDialog msgd (*editor,
MessageDialog msgd (_main_window,
_("No files were ready for clean-up"),
true,
Gtk::MESSAGE_INFO,
@ -4344,7 +4346,7 @@ void
ARDOUR_UI::halt_on_xrun_message ()
{
cerr << "HALT on xrun\n";
MessageDialog msg (*editor, _("Recording was stopped because your system could not keep up."));
MessageDialog msg (_main_window, _("Recording was stopped because your system could not keep up."));
msg.run ();
}
@ -4373,7 +4375,7 @@ ARDOUR_UI::disk_overrun_handler ()
if (!have_disk_speed_dialog_displayed) {
have_disk_speed_dialog_displayed = true;
MessageDialog* msg = new MessageDialog (*editor, string_compose (_("\
MessageDialog* msg = new MessageDialog (_main_window, string_compose (_("\
The disk system on your computer\n\
was not able to keep up with %1.\n\
\n\
@ -4508,7 +4510,7 @@ ARDOUR_UI::disk_underrun_handler ()
if (!have_disk_speed_dialog_displayed) {
have_disk_speed_dialog_displayed = true;
MessageDialog* msg = new MessageDialog (
*editor, string_compose (_("The disk system on your computer\n\
_main_window, string_compose (_("The disk system on your computer\n\
was not able to keep up with %1.\n\
\n\
Specifically, it failed to read data from disk\n\
@ -4532,12 +4534,7 @@ ARDOUR_UI::session_dialog (std::string msg)
MessageDialog* d;
if (editor) {
d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
} else {
d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
}
d->show_all ();
d->run ();
delete d;
@ -5063,15 +5060,110 @@ ARDOUR_UI::hide_application ()
}
void
ARDOUR_UI::cancel_solo ()
ARDOUR_UI::setup_toplevel_window (Gtk::Window& window, const string& name, void* owner)
{
if (_session) {
if (_session->soloing()) {
_session->set_solo (_session->get_routes(), false);
} else if (_session->listening()) {
_session->set_listen (_session->get_routes(), false);
/* icons, titles, WM stuff */
static list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
if (window_icons.empty()) {
Glib::RefPtr<Gdk::Pixbuf> icon;
if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
window_icons.push_back (icon);
}
if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
window_icons.push_back (icon);
}
if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
window_icons.push_back (icon);
}
if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
window_icons.push_back (icon);
}
}
_session->clear_all_solo_state (_session->get_routes()); // safeguard, ideally this won't do anything, check the log-window
if (!window_icons.empty()) {
window.set_default_icon_list (window_icons);
}
Gtkmm2ext::WindowTitle title (Glib::get_application_name());
title += name;
window.set_title (title.get_string());
window.set_wmclass (string_compose (X_("%1_%1"), downcase (PROGRAM_NAME), downcase (name)), PROGRAM_NAME);
window.set_flags (CAN_FOCUS);
window.add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
window.signal_configure_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::configure_handler));
window.signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::tabbed_window_state_event_handler), owner));
window.signal_key_press_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_event_handler), &window), false);
window.signal_key_release_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_event_handler), &window), false);
}
bool
ARDOUR_UI::key_event_handler (GdkEventKey* ev, Gtk::Window* window)
{
switch (ev->type) {
case GDK_KEY_PRESS:
return key_press_handler (ev, window);
default:
break;
}
return key_release_handler (ev, window);
}
bool
ARDOUR_UI::key_press_handler (GdkEventKey* ev, Gtk::Window* event_window)
{
if (event_window == &_main_window) {
/* find current tab contents */
Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page());
/* see if it uses the ardour binding system */
HasBindings* bindable;
if ((bindable = dynamic_cast<HasBindings*> (w)) != 0) {
KeyboardKey k (ev->state, ev->keyval);
return bindable->bindings().activate (k, Bindings::Press);
} else {
/* no bindings in current tab, use baroque GTK mechanism */
return key_press_focus_accelerator_handler (_main_window, ev);
}
} else {
/* no window supplied, try our own bindings */
KeyboardKey k (ev->state, ev->keyval);
return _global_bindings.activate (k, Bindings::Press);
}
}
bool
ARDOUR_UI::key_release_handler (GdkEventKey* ev, Gtk::Window* event_window)
{
if (event_window == &_main_window) {
/* find current tab contents */
Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page());
/* see if it uses the ardour binding system */
HasBindings* bindable;
if ((bindable = dynamic_cast<HasBindings*> (w)) != 0) {
KeyboardKey k (ev->state, ev->keyval);
return bindable->bindings().activate (k, Bindings::Release);
} else {
/* no bindings in current tab, use baroque GTK mechanism */
return key_press_focus_accelerator_handler (_main_window, ev);
}
} else {
/* no window supplied, try our own bindings */
KeyboardKey k (ev->state, ev->keyval);
return _global_bindings.activate (k, Bindings::Release);
>>>>>>> first compilable version of tabbable design.
}
}

View file

@ -53,10 +53,12 @@
#include <gtkmm/menubar.h>
#include <gtkmm/textbuffer.h>
#include <gtkmm/adjustment.h>
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/click_box.h>
#include <gtkmm2ext/stateful_button.h>
#include <gtkmm2ext/bindable_button.h>
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/click_box.h"
#include "gtkmm2ext/stateful_button.h"
#include "gtkmm2ext/bindable_button.h"
#include "gtkmm2ext/bindings.h"
#include "ardour/ardour.h"
#include "ardour/types.h"
@ -321,14 +323,23 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void hide_application ();
Gtk::Notebook& tabs();
Gtk::Window& main_window () { return _main_window; }
void setup_toplevel_window (Gtk::Window&, const std::string& name, void* owner);
/* called from a static C function */
Gtk::Notebook* tab_window_root_drop (GtkNotebook* src,
GtkNotebook* tab_window_root_drop (GtkNotebook* src,
GtkWidget* w,
gint x,
gint y,
gpointer user_data);
bool tabbed_window_state_event_handler (GdkEventWindowState*, void* object);
bool key_press_handler (GdkEventKey*, Gtk::Window* event_window);
bool key_release_handler (GdkEventKey*, Gtk::Window* event_window);
protected:
friend class PublicEditor;
@ -349,13 +360,21 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void toggle_session_options_window ();
private:
Gtk::Window _main_window;
Gtk::VBox main_vpacker;
Gtk::HBox status_bar_hpacker;
Gtk::Notebook _tabs;
PublicEditor* editor;
Mixer_UI* mixer;
Gtk::Tooltips _tooltips;
NSM_Client* nsm;
bool _was_dirty;
bool _mixer_on_top;
bool _initial_verbose_plugin_scan;
bool first_time_engine_run;
Gtkmm2ext::Bindings _global_bindings;
void goto_editor_window ();
void goto_mixer_window ();
void toggle_mixer_window ();
@ -397,8 +416,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void start_clocking ();
void stop_clocking ();
bool main_window_state_event_handler (GdkEventWindowState*, bool window_was_editor);
void update_transport_clocks (framepos_t pos);
void record_state_changed ();
@ -627,17 +644,16 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void setup_order_hint (AddRouteDialog::InsertAt);
int create_mixer ();
PublicEditor *editor;
int create_editor ();
Meterbridge *meterbridge;
int create_meterbridge ();
/* Dialogs that can be created via new<T> */
RCOptionEditor* rc_option_editor;
Gtk::HBox rc_option_editor_placeholder;
/* Dialogs that can be created via new<T> */
WM::Proxy<SpeakerDialog> speaker_config_window;
WM::Proxy<KeyEditor> key_editor;
WM::Proxy<AddRouteDialog> add_route_dialog;
@ -811,6 +827,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void grab_focus_after_dialog ();
void tabs_switch (GtkNotebookPage*, guint page_number);
bool key_event_handler (GdkEventKey*, Gtk::Window* window);
};
#endif /* __ardour_gui_h__ */

View file

@ -74,12 +74,7 @@ tab_window_root_drop (GtkNotebook* src,
gint y,
gpointer user_data)
{
Gtk::Notebook* nb = ARDOUR_UI::instance()->tab_window_root_drop (src, w, x, y, user_data);
if (nb) {
return nb->gobj();
} else {
return 0;
}
return ARDOUR_UI::instance()->tab_window_root_drop (src, w, x, y, user_data);
}
int
@ -125,24 +120,39 @@ ARDOUR_UI::setup_windows ()
top_packer.pack_start (menu_bar_base, false, false);
#endif
editor->add_toplevel_menu (top_packer);
main_vpacker.pack_start (top_packer);
editor->add_transport_frame (transport_frame);
editor->tabs().append_page (rc_option_editor_placeholder, _("Preferences"));
/* now add the transport frame to the top of main window */
editor->tabs().signal_switch_page().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_switch));
main_vpacker.pack_start (transport_frame, false, false);
main_vpacker.pack_start (_tabs, true, true);
#ifdef TOP_MENUBAR
main_vpacker.pack_start (status_bar_hpacker, false, false);
#endif
setup_transport();
build_menu_bar ();
setup_tooltips ();
/* pack the main vpacker into the main window and show everything
*/
_main_window.add (main_vpacker);
transport_frame.show_all ();
_main_window.show_all ();
setup_toplevel_window (_main_window, "", this);
rc_option_editor = new RCOptionEditor;
rc_option_editor->add_to_notebook (_tabs, _("Preferences"), 2);
_tabs.signal_switch_page().connect (sigc::mem_fun (*this, &ARDOUR_UI::tabs_switch));
/* It would be nice if Gtkmm had wrapped this rather than just
* deprecating the old set_window_creation_hook() method, but oh well...
*/
g_signal_connect (editor->tabs().gobj(), "create-window",
(GCallback) ::tab_window_root_drop, this);
setup_transport();
build_menu_bar ();
setup_tooltips ();
g_signal_connect (_tabs.gobj(), "create-window", (GCallback) ::tab_window_root_drop, this);
return 0;
}
@ -517,7 +527,6 @@ ARDOUR_UI::setup_transport ()
void
ARDOUR_UI::detach_tearoff (Box* b, Widget* w)
{
// editor->ensure_float (transport_tearoff->tearoff_window());
b->remove (*w);
}

View file

@ -61,8 +61,8 @@ ARDOUR_UI::we_have_dependents ()
editor->setup_tooltips ();
editor->UpdateAllTransportClocks.connect (sigc::mem_fun (*this, &ARDOUR_UI::update_transport_clocks));
std::cerr << "Mixer page = " << editor->tabs().append_page (*mixer, _("Mixer")) << std::endl;
editor->tabs().set_tab_detachable (*mixer);
editor->add_to_notebook (_tabs, _("Editor"), 1);
mixer->add_to_notebook (_tabs, _("Mixer"), 1);
/* all actions are defined */
@ -104,7 +104,7 @@ ARDOUR_UI::exit_on_main_window_close (GdkEventAny * /*ev*/)
#endif
}
Gtk::Notebook*
GtkNotebook*
ARDOUR_UI::tab_window_root_drop (GtkNotebook* src,
GtkWidget* w,
gint x,
@ -112,20 +112,34 @@ ARDOUR_UI::tab_window_root_drop (GtkNotebook* src,
gpointer)
{
using namespace std;
Gtk::Notebook* nb = 0;
Gtk::Window* win = 0;
if (w == GTK_WIDGET(mixer->gobj())) {
if (w == GTK_WIDGET(mixer->contents().gobj())) {
/* Mixer */
cerr << "Call use own window\n";
cerr << "Call use own window, mixer\n";
Gtk::Notebook* nb = mixer->use_own_window ();
Gtk::Window* win = (Gtk::Window*) nb->get_toplevel ();
nb = mixer->tab_root_drop ();
win = mixer->own_window ();
win->move (x, y);
win->present ();
} else if (w == GTK_WIDGET(editor->contents().gobj())) {
/* Editor */
cerr << "Call use own window, editor\n";
nb = editor->tab_root_drop ();
win = editor->own_window ();
return nb;
}
return 0;
if (nb) {
win->move (x, y);
win->show_all ();
win->present ();
return nb->gobj();
}
return 0; /* what was that? */
}

View file

@ -334,11 +334,18 @@ ARDOUR_UI::goto_editor_window ()
Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 2000);
}
if (!editor->window_visible()) {
/* goto tab */
editor->show_tab ();
return;
}
editor->show_window ();
editor->present ();
/* mixer should now be on top */
if (UIConfiguration::instance().get_transients_follow_front()) {
WM::Manager::instance().set_transient_for (editor);
/* editor should now be on top */
if (UIConfiguration::instance()->get_transients_follow_front()) {
WM::Manager::instance().set_transient_for (editor->own_window());
}
_mixer_on_top = false;
}
@ -349,8 +356,8 @@ ARDOUR_UI::goto_mixer_window ()
Glib::RefPtr<Gdk::Window> win;
Glib::RefPtr<Gdk::Screen> screen;
if (editor) {
win = editor->get_window ();
if (editor && editor->own_window()) {
win = editor->own_window ()->get_window();
}
if (win) {
@ -387,23 +394,28 @@ ARDOUR_UI::toggle_mixer_window ()
bool show = false;
bool obscuring = false;
if (mixer->not_visible ()) {
show = true;
if (!mixer->window_visible() || editor->window_visible()) {
return;
}
else if ( (!editor->not_visible () && ARDOUR_UI_UTILS::windows_overlap (editor, mixer))
|| (!meterbridge->not_visible () && ARDOUR_UI_UTILS::windows_overlap (meterbridge, mixer))
if (!mixer->window_visible ()) {
show = true;
} else if ( (!editor->not_visible () && ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), mixer->own_window()))
|| (!meterbridge->not_visible () && ARDOUR_UI_UTILS::windows_overlap (meterbridge, mixer->own_window()))
) {
obscuring = true;
}
if (obscuring && (editor->property_has_toplevel_focus() || meterbridge->property_has_toplevel_focus())) {
if (obscuring && (editor->own_window()->property_has_toplevel_focus() || meterbridge->property_has_toplevel_focus())) {
show = true;
}
if (show) {
goto_mixer_window ();
} else {
mixer->hide_window ((GdkEventAny*)0);
mixer->own_window()->hide ();
}
}
@ -417,14 +429,12 @@ ARDOUR_UI::toggle_meterbridge ()
if (meterbridge->not_visible ()) {
show = true;
}
else if ( (!editor->not_visible() && ARDOUR_UI_UTILS::windows_overlap (editor, meterbridge))
|| (!mixer->not_visible () && ARDOUR_UI_UTILS::windows_overlap (meterbridge, mixer))
) {
} else if ((editor->window_visible() && ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), meterbridge)) ||
(mixer->window_visible () && ARDOUR_UI_UTILS::windows_overlap (mixer->own_window(), meterbridge))) {
obscuring = true;
}
if (obscuring && (editor->property_has_toplevel_focus() || mixer->property_has_toplevel_focus())) {
if (obscuring && (editor->own_window()->property_has_toplevel_focus() || (mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()))) {
show = true;
}
@ -442,25 +452,29 @@ ARDOUR_UI::toggle_editor_mixer ()
{
bool obscuring = false;
if (editor && mixer) {
if (ARDOUR_UI_UTILS::windows_overlap (editor, mixer)) {
if (!mixer->window_visible() || !editor->window_visible()) {
return;
}
if (editor && mixer && mixer->own_window()) {
if (ARDOUR_UI_UTILS::windows_overlap (editor->own_window(), mixer->own_window())) {
obscuring = true;
}
}
if (mixer && !mixer->not_visible() && mixer->property_has_toplevel_focus()) {
if (mixer && !mixer->not_visible() && mixer->own_window() && mixer->own_window()->property_has_toplevel_focus()) {
if (obscuring) {
goto_editor_window();
}
} else if (editor && !editor->not_visible() && editor->property_has_toplevel_focus()) {
} else if (editor && editor->window_visible() && editor->own_window()->property_has_toplevel_focus()) {
if (obscuring) {
goto_mixer_window();
}
} else if (mixer && mixer->not_visible()) {
} else if (mixer) {
if (obscuring) {
goto_mixer_window ();
}
} else if (editor && editor->not_visible()) {
} else if (editor) {
if (obscuring) {
goto_editor_window ();
}
@ -535,23 +549,23 @@ ARDOUR_UI::handle_locations_change (Location *)
}
bool
ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
ARDOUR_UI::tabbed_window_state_event_handler (GdkEventWindowState* ev, void* object)
{
if (window_was_editor) {
if (object == editor) {
if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
(ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
if (big_clock_window) {
big_clock_window->set_transient_for (*editor);
big_clock_window->set_transient_for (*editor->own_window());
}
}
} else {
} else if (object == mixer) {
if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
(ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
if (big_clock_window) {
// big_clock_window->set_transient_for (*mixer);
big_clock_window->set_transient_for (*mixer->own_window());
}
}
}

View file

@ -86,7 +86,6 @@ ARDOUR_UI::create_editor ()
}
editor->Realized.connect (sigc::mem_fun (*this, &ARDOUR_UI::editor_realized));
editor->signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), true));
editor->signal_event().connect (sigc::bind (sigc::ptr_fun (&Keyboard::catch_user_event_for_pre_dialog_focus), editor));
return 0;
@ -730,5 +729,5 @@ ARDOUR_UI::xrun_button_release (GdkEventButton* ev)
Gtk::Notebook&
ARDOUR_UI::tabs()
{
return editor->tabs();
return _tabs;
}

View file

@ -47,7 +47,6 @@ ARDOUR_UI::create_mixer ()
return -1;
}
mixer->signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), false));
mixer->signal_event().connect (sigc::bind (sigc::ptr_fun (&Gtkmm2ext::Keyboard::catch_user_event_for_pre_dialog_focus), mixer));
return 0;
@ -66,8 +65,6 @@ ARDOUR_UI::create_meterbridge ()
return -1;
}
meterbridge->signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::main_window_state_event_handler), false));
return 0;
}

View file

@ -0,0 +1,43 @@
/*
Copyright (C) 2015 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 __gtk_ardour_binding_owners_h__
#define __gtk_ardour_binding_owners_h__
#include <gtkmm/box.h>
#include "gtkmm2ext/bindings.h"
class HasBindings {
public:
HasBindings (Gtkmm2ext::Bindings& b) : _bindings (b) {}
Gtkmm2ext::Bindings bindings() const { return _bindings; }
protected:
Gtkmm2ext::Bindings& _bindings;
};
class VBoxWithBindings : public Gtk::VBox, public HasBindings
{
public:
VBoxWithBindings (Gtkmm2ext::Bindings& b) : HasBindings (b) {}
};
#endif /* __gtk_ardour_binding_owners_h__ */

View file

@ -252,10 +252,86 @@ pane_size_watcher (Paned* pane)
}
Editor::Editor ()
: _join_object_range_state (JOIN_OBJECT_RANGE_NONE)
: PublicEditor (global_hpacker)
, editor_mixer_strip_width (Wide)
, constructed (false)
, _playlist_selector (0)
, no_save_visual (false)
, leftmost_frame (0)
, samples_per_pixel (2048)
, zoom_focus (ZoomFocusPlayhead)
, mouse_mode (MouseObject)
, pre_internal_snap_type (SnapToBeat)
, pre_internal_snap_mode (SnapOff)
, internal_snap_type (SnapToBeat)
, internal_snap_mode (SnapOff)
, _join_object_range_state (JOIN_OBJECT_RANGE_NONE)
, _notebook_shrunk (false)
, location_marker_color (0)
, location_range_color (0)
, location_loop_color (0)
, location_punch_color (0)
, location_cd_marker_color (0)
, entered_marker (0)
, _show_marker_lines (false)
, clicked_axisview (0)
, clicked_routeview (0)
, clicked_regionview (0)
, clicked_selection (0)
, clicked_control_point (0)
, button_release_can_deselect (true)
, _mouse_changed_selection (false)
/* time display buttons */
, region_edit_menu_split_item (0)
, region_edit_menu_split_multichannel_item (0)
, track_region_edit_playlist_menu (0)
, track_edit_playlist_submenu (0)
, track_selection_edit_playlist_submenu (0)
, _popup_region_menu_item (0)
, global_vpacker (key_bindings)
, _track_canvas (0)
, _track_canvas_viewport (0)
, within_track_canvas (false)
, _verbose_cursor (0)
, logo_item (0)
, tempo_group (0)
, meter_group (0)
, marker_group (0)
, range_marker_group (0)
, transport_marker_group (0)
, cd_marker_group (0)
, _time_markers_group (0)
, hv_scroll_group (0)
, h_scroll_group (0)
, cursor_scroll_group (0)
, no_scroll_group (0)
, _trackview_group (0)
, _drag_motion_group (0)
, _canvas_drop_zone (0)
, no_ruler_shown_update (false)
, ruler_grabbed_widget (0)
, ruler_dialog (0)
, minsec_mark_interval (0)
, minsec_mark_modulo (0)
, minsec_nmarks (0)
, timecode_mark_modulo (0)
, timecode_nmarks (0)
, _samples_ruler_interval (0)
, bbt_bars (0)
, bbt_nmarks (0)
, bbt_bar_helper_on (0)
, bbt_accent_modulo (0)
, timecode_ruler (0)
, bbt_ruler (0)
, samples_ruler (0)
, minsec_ruler (0)
, visible_timebars (0)
, editor_ruler_menu (0)
, tempo_bar (0)
, meter_bar (0)
, marker_bar (0)
, range_marker_bar (0)
, transport_marker_bar (0)
, cd_marker_bar (0)
, minsec_label (_("Mins:Secs"))
, bbt_label (_("Bars:Beats"))
, timecode_label (_("Timecode"))
@ -267,73 +343,139 @@ Editor::Editor ()
, transport_mark_label (_("Loop/Punch Ranges"))
, cd_mark_label (_("CD Markers"))
, videotl_label (_("Video Timeline"))
, videotl_group (0)
, playhead_cursor (0)
, edit_packer (4, 4, true)
/* the values here don't matter: layout widgets
reset them as needed.
*/
, vertical_adjustment (0.0, 0.0, 10.0, 400.0)
, horizontal_adjustment (0.0, 0.0, 1e16)
, unused_adjustment (0.0, 0.0, 10.0, 400.0)
, controls_layout (unused_adjustment, vertical_adjustment)
/* tool bar related */
, _scroll_callbacks (0)
, _visible_canvas_width (0)
, _visible_canvas_height (0)
, _full_canvas_height (0)
, edit_controls_left_menu (0)
, edit_controls_right_menu (0)
, last_update_frame (0)
, cut_buffer_start (0)
, cut_buffer_length (0)
, button_bindings (0)
, last_paste_pos (0)
, paste_count (0)
, sfbrowser (0)
, current_interthread_info (0)
, analysis_window (0)
, select_new_marker (false)
, last_scrub_x (0)
, scrubbing_direction (0)
, scrub_reversals (0)
, scrub_reverse_distance (0)
, have_pending_keyboard_selection (false)
, pending_keyboard_selection_start (0)
, _snap_type (SnapToBeat)
, _snap_mode (SnapOff)
, snap_threshold (5.0)
, ignore_gui_changes (false)
, _drags (new DragManager (this))
, lock_dialog (0)
, last_event_time { 0, 0 }
, _dragging_playhead (false)
, _dragging_edit_point (false)
, _show_measures (true)
, _follow_playhead (true)
, _stationary_playhead (false)
, _maximised (false)
, tempo_lines (0)
, global_rect_group (0)
, time_line_group (0)
, tempo_or_meter_marker_menu (0)
, marker_menu (0)
, range_marker_menu (0)
, transport_marker_menu (0)
, new_transport_marker_menu (0)
, cd_marker_menu (0)
, marker_menu_item (0)
, bbt_beat_subdivision (4)
, _visible_track_count (-1)
, toolbar_selection_clock_table (2,3)
, _mouse_mode_tearoff (0)
, automation_mode_button (_("mode"))
, _zoom_tearoff (0)
, _tools_tearoff (0)
, _toolbar_viewport (*manage (new Gtk::Adjustment (0, 0, 1e10)), *manage (new Gtk::Adjustment (0, 0, 1e10)))
, selection (new Selection (this))
, cut_buffer (new Selection (this))
, _selection_memento (new SelectionMemento())
, _all_region_actions_sensitized (false)
, _ignore_region_action (false)
, _last_region_menu_was_main (false)
, _ignore_follow_edits (false)
, cd_marker_bar_drag_rect (0)
, range_bar_drag_rect (0)
, transport_bar_drag_rect (0)
, transport_bar_range_rect (0)
, transport_bar_preroll_rect (0)
, transport_bar_postroll_rect (0)
, transport_loop_range_rect (0)
, transport_punch_range_rect (0)
, transport_punchin_line (0)
, transport_punchout_line (0)
, transport_preroll_rect (0)
, transport_postroll_rect (0)
, temp_location (0)
, rubberband_rect (0)
, _route_groups (0)
, _routes (0)
, _regions (0)
, _snapshots (0)
, _locations (0)
, autoscroll_horizontal_allowed (false)
, autoscroll_vertical_allowed (false)
, autoscroll_cnt (0)
, autoscroll_widget (0)
, show_gain_after_trim (false)
, selection_op_cmd_depth (0)
, selection_op_history_it (0)
/* nudge */
, current_timefx (0)
, current_mixer_strip (0)
, show_editor_mixer_when_tracks_arrive (false)
, nudge_clock (new AudioClock (X_("nudge"), false, X_("nudge"), true, false, true))
, meters_running(false)
, current_stepping_trackview (0)
, last_track_height_step_timestamp (0)
, entered_track (0)
, entered_regionview (0)
, clear_entered_track (false)
, _edit_point (EditAtMouse)
, meters_running (false)
, rhythm_ferret (0)
, _have_idled (false)
, resize_idle_id (-1)
, _pending_resize_amount (0)
, _pending_resize_view (0)
, _pending_locate_request (false)
, _pending_initial_locate (false)
, _summary (0)
, _group_tabs (0)
, _last_motion_y (0)
, layering_order_editor (0)
, _last_cut_copy_source_track (0)
, _region_selection_change_updates_region_list (true)
, _cursors (0)
, _following_mixer_selection (false)
, _control_point_toggled_on_press (false)
, _stepping_axis_view (0)
, quantize_dialog (0)
, _main_menu_disabler (0)
{
constructed = false;
/* we are a singleton */
PublicEditor::_instance = this;
_have_idled = false;
selection = new Selection (this);
cut_buffer = new Selection (this);
_selection_memento = new SelectionMemento ();
selection_op_history.clear();
before.clear();
clicked_regionview = 0;
clicked_axisview = 0;
clicked_routeview = 0;
clicked_selection = 0;
clicked_control_point = 0;
last_update_frame = 0;
last_paste_pos = 0;
paste_count = 0;
_drags = new DragManager (this);
lock_dialog = 0;
ruler_dialog = 0;
current_mixer_strip = 0;
tempo_lines = 0;
snap_type_strings = I18N (_snap_type_strings);
snap_mode_strings = I18N (_snap_mode_strings);
zoom_focus_strings = I18N (_zoom_focus_strings);
@ -351,78 +493,17 @@ Editor::Editor ()
build_snap_type_menu();
build_edit_point_menu();
snap_threshold = 5.0;
bbt_beat_subdivision = 4;
_visible_canvas_width = 0;
_visible_canvas_height = 0;
autoscroll_horizontal_allowed = false;
autoscroll_vertical_allowed = false;
logo_item = 0;
location_marker_color = ARDOUR_UI::config()->color ("location marker");
location_range_color = ARDOUR_UI::config()->color ("location range");
location_cd_marker_color = ARDOUR_UI::config()->color ("location cd marker");
location_loop_color = ARDOUR_UI::config()->color ("location loop");
location_punch_color = ARDOUR_UI::config()->color ("location punch");
analysis_window = 0;
timebar_height = std::max(12., ceil (15. * ARDOUR_UI::ui_scale));
current_interthread_info = 0;
_show_measures = true;
_maximised = false;
show_gain_after_trim = false;
have_pending_keyboard_selection = false;
_follow_playhead = true;
_stationary_playhead = false;
editor_ruler_menu = 0;
no_ruler_shown_update = false;
marker_menu = 0;
range_marker_menu = 0;
marker_menu_item = 0;
tempo_or_meter_marker_menu = 0;
transport_marker_menu = 0;
new_transport_marker_menu = 0;
editor_mixer_strip_width = Wide;
show_editor_mixer_when_tracks_arrive = false;
region_edit_menu_split_multichannel_item = 0;
region_edit_menu_split_item = 0;
temp_location = 0;
leftmost_frame = 0;
mouse_mode = MouseObject;
current_stepping_trackview = 0;
entered_track = 0;
entered_regionview = 0;
entered_marker = 0;
clear_entered_track = false;
current_timefx = 0;
playhead_cursor = 0;
button_release_can_deselect = true;
_dragging_playhead = false;
_dragging_edit_point = false;
select_new_marker = false;
rhythm_ferret = 0;
layering_order_editor = 0;
no_save_visual = false;
resize_idle_id = -1;
within_track_canvas = false;
scrubbing_direction = 0;
sfbrowser = 0;
location_marker_color = UIConfiguration::instance().color ("location marker");
location_range_color = UIConfiguration::instance().color ("location range");
location_cd_marker_color = UIConfiguration::instance().color ("location cd marker");
location_loop_color = UIConfiguration::instance().color ("location loop");
location_punch_color = UIConfiguration::instance().color ("location punch");
zoom_focus = ZoomFocusPlayhead;
_edit_point = EditAtMouse;
_visible_track_count = -1;
samples_per_pixel = 2048; /* too early to use reset_zoom () */
timebar_height = std::max(12., ceil (15. * UIConfiguration::instance().get_ui_scale()));
TimeAxisView::setup_sizes ();
ArdourMarker::setup_sizes (timebar_height);
_scroll_callbacks = 0;
bbt_label.set_name ("EditorRulerLabel");
bbt_label.set_size_request (-1, (int)timebar_height);
bbt_label.set_alignment (1.0, 0.5);
@ -660,20 +741,8 @@ Editor::Editor ()
global_vpacker.pack_start (top_hbox, false, false);
global_vpacker.pack_start (*hbox, true, true);
global_hpacker.pack_start (global_vpacker, true, true);
set_name ("EditorWindow");
add_accel_group (ActionManager::ui_manager->get_accel_group());
status_bar_hpacker.show ();
_tabs.append_page (global_hpacker, _("Editor"));
_tabs.show ();
vpacker.pack_end (status_bar_hpacker, false, false);
vpacker.pack_end (_tabs, true, true);
/* register actions now so that set_state() can find them and set toggles/checks etc */
register_actions ();
@ -684,19 +753,6 @@ Editor::Editor ()
setup_toolbar ();
set_zoom_focus (zoom_focus);
set_visible_track_count (_visible_track_count);
_snap_type = SnapToBeat;
set_snap_to (_snap_type);
_snap_mode = SnapOff;
set_snap_mode (_snap_mode);
set_mouse_mode (MouseObject, true);
pre_internal_snap_type = _snap_type;
pre_internal_snap_mode = _snap_mode;
internal_snap_type = _snap_type;
internal_snap_mode = _snap_mode;
set_edit_point_preference (EditAtMouse, true);
_playlist_selector = new PlaylistSelector();
_playlist_selector->signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector)));
@ -712,39 +768,6 @@ Editor::Editor ()
fade_context_menu.set_name ("ArdourContextMenu");
/* icons, titles, WM stuff */
list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
Glib::RefPtr<Gdk::Pixbuf> icon;
if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
window_icons.push_back (icon);
}
if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
window_icons.push_back (icon);
}
if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
window_icons.push_back (icon);
}
if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
window_icons.push_back (icon);
}
if (!window_icons.empty()) {
// set_icon_list (window_icons);
set_default_icon_list (window_icons);
}
WindowTitle title(Glib::get_application_name());
title += _("Editor");
set_title (title.get_string());
set_wmclass (X_("ardour_editor"), PROGRAM_NAME);
add (vpacker);
add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
signal_configure_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
signal_delete_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::exit_on_main_window_close));
Gtkmm2ext::Keyboard::the_keyboard().ZoomVerticalModifierReleased.connect (sigc::mem_fun (*this, &Editor::zoom_vertical_modifier_released));
/* allow external control surfaces/protocols to do various things */
@ -845,21 +868,6 @@ Editor::button_settings () const
return node;
}
void
Editor::add_toplevel_menu (Container& cont)
{
vpacker.pack_start (cont, false, false);
cont.show_all ();
}
void
Editor::add_transport_frame (Container& cont)
{
global_vpacker.pack_start (cont, false, false);
global_vpacker.reorder_child (cont, 0);
cont.show_all ();
}
bool
Editor::get_smart_mode () const
{
@ -929,44 +937,6 @@ Editor::set_entered_track (TimeAxisView* tav)
}
}
void
Editor::show_window ()
{
if (!is_visible ()) {
DisplaySuspender ds;
show_all ();
/* XXX: this is a bit unfortunate; it would probably
be nicer if we could just call show () above rather
than needing the show_all ()
*/
/* re-hide stuff if necessary */
editor_list_button_toggled ();
parameter_changed ("show-summary");
parameter_changed ("show-group-tabs");
parameter_changed ("show-zoom-tools");
/* now reset all audio_time_axis heights, because widgets might need
to be re-hidden
*/
TimeAxisView *tv;
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
tv = (static_cast<TimeAxisView*>(*i));
tv->reset_height ();
}
if (current_mixer_strip) {
current_mixer_strip->hide_things ();
current_mixer_strip->parameter_changed ("mixer-element-visibility");
}
}
present ();
}
void
Editor::instant_save ()
{
@ -1159,14 +1129,11 @@ Editor::access_action (std::string action_group, std::string action_item)
void
Editor::on_realize ()
{
Window::on_realize ();
Realized ();
if (UIConfiguration::instance().get_lock_gui_after_seconds()) {
start_lock_event_timing ();
}
signal_event().connect (sigc::mem_fun (*this, &Editor::generic_event_handler));
}
void
@ -1186,7 +1153,9 @@ Editor::generic_event_handler (GdkEvent* ev)
case GDK_MOTION_NOTIFY:
case GDK_KEY_PRESS:
case GDK_KEY_RELEASE:
if (contents().is_mapped()) {
gettimeofday (&last_event_time, 0);
}
break;
case GDK_LEAVE_NOTIFY:
@ -1283,7 +1252,11 @@ Editor::center_screen_internal (framepos_t frame, float page)
void
Editor::update_title ()
{
ENSURE_GUI_THREAD (*this, &Editor::update_title)
ENSURE_GUI_THREAD (*this, &Editor::update_title);
if (!own_window()) {
return;
}
if (_session) {
bool dirty = _session->dirty();
@ -1302,7 +1275,7 @@ Editor::update_title ()
WindowTitle title(session_name);
title += Glib::get_application_name();
set_title (title.get_string());
own_window()->set_title (title.get_string());
} else {
/* ::session_going_away() will have taken care of it */
}
@ -2203,54 +2176,13 @@ Editor::set_edit_point_preference (EditPoint ep, bool force)
}
int
Editor::set_state (const XMLNode& node, int /*version*/)
Editor::set_state (const XMLNode& node, int version)
{
const XMLProperty* prop;
XMLNode* geometry;
int x, y;
Gdk::Geometry g;
set_id (node);
g.base_width = default_width;
g.base_height = default_height;
x = 1;
y = 1;
if ((geometry = find_named_node (node, "geometry")) != 0) {
XMLProperty* prop;
if ((prop = geometry->property("x_size")) == 0) {
prop = geometry->property ("x-size");
}
if (prop) {
g.base_width = atoi(prop->value());
}
if ((prop = geometry->property("y_size")) == 0) {
prop = geometry->property ("y-size");
}
if (prop) {
g.base_height = atoi(prop->value());
}
if ((prop = geometry->property ("x_pos")) == 0) {
prop = geometry->property ("x-pos");
}
if (prop) {
x = atoi (prop->value());
}
if ((prop = geometry->property ("y_pos")) == 0) {
prop = geometry->property ("y-pos");
}
if (prop) {
y = atoi (prop->value());
}
}
set_default_size (g.base_width, g.base_height);
move (x, y);
Tabbable::set_state (node, version);
if (_session && (prop = node.property ("playhead"))) {
framepos_t pos;
@ -2475,99 +2407,82 @@ Editor::set_state (const XMLNode& node, int /*version*/)
XMLNode&
Editor::get_state ()
{
XMLNode* node = new XMLNode ("Editor");
XMLNode& node (Tabbable::get_state());
char buf[32];
id().print (buf, sizeof (buf));
node->add_property ("id", buf);
node.add_property ("id", buf);
if (is_realized()) {
Glib::RefPtr<Gdk::Window> win = get_window();
int x, y, width, height;
win->get_root_origin(x, y);
win->get_size(width, height);
XMLNode* geometry = new XMLNode ("geometry");
snprintf(buf, sizeof(buf), "%d", width);
geometry->add_property("x-size", string(buf));
snprintf(buf, sizeof(buf), "%d", height);
geometry->add_property("y-size", string(buf));
snprintf(buf, sizeof(buf), "%d", x);
geometry->add_property("x-pos", string(buf));
snprintf(buf, sizeof(buf), "%d", y);
geometry->add_property("y-pos", string(buf));
#if 0
// need to save this somehow
snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (static_cast<Paned*>(&edit_pane)->gobj()));
geometry->add_property("edit-horizontal-pane-pos", string(buf));
geometry->add_property("notebook-shrunk", _notebook_shrunk ? "1" : "0");
snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (static_cast<Paned*>(&editor_summary_pane)->gobj()));
geometry->add_property("edit-vertical-pane-pos", string(buf));
#endif
node->add_child_nocopy (*geometry);
}
maybe_add_mixer_strip_width (node);
maybe_add_mixer_strip_width (*node);
node->add_property ("zoom-focus", enum_2_string (zoom_focus));
node.add_property ("zoom-focus", enum_2_string (zoom_focus));
snprintf (buf, sizeof(buf), "%" PRId64, samples_per_pixel);
node->add_property ("zoom", buf);
node->add_property ("snap-to", enum_2_string (_snap_type));
node->add_property ("snap-mode", enum_2_string (_snap_mode));
node->add_property ("internal-snap-to", enum_2_string (internal_snap_type));
node->add_property ("internal-snap-mode", enum_2_string (internal_snap_mode));
node->add_property ("pre-internal-snap-to", enum_2_string (pre_internal_snap_type));
node->add_property ("pre-internal-snap-mode", enum_2_string (pre_internal_snap_mode));
node->add_property ("edit-point", enum_2_string (_edit_point));
node.add_property ("zoom", buf);
node.add_property ("snap-to", enum_2_string (_snap_type));
node.add_property ("snap-mode", enum_2_string (_snap_mode));
node.add_property ("internal-snap-to", enum_2_string (internal_snap_type));
node.add_property ("internal-snap-mode", enum_2_string (internal_snap_mode));
node.add_property ("pre-internal-snap-to", enum_2_string (pre_internal_snap_type));
node.add_property ("pre-internal-snap-mode", enum_2_string (pre_internal_snap_mode));
node.add_property ("edit-point", enum_2_string (_edit_point));
snprintf (buf, sizeof(buf), "%d", _visible_track_count);
node->add_property ("visible-track-count", buf);
node.add_property ("visible-track-count", buf);
snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame ());
node->add_property ("playhead", buf);
node.add_property ("playhead", buf);
snprintf (buf, sizeof (buf), "%" PRIi64, leftmost_frame);
node->add_property ("left-frame", buf);
node.add_property ("left-frame", buf);
snprintf (buf, sizeof (buf), "%f", vertical_adjustment.get_value ());
node->add_property ("y-origin", buf);
node.add_property ("y-origin", buf);
node->add_property ("show-measures", _show_measures ? "yes" : "no");
node->add_property ("maximised", _maximised ? "yes" : "no");
node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
node->add_property ("stationary-playhead", _stationary_playhead ? "yes" : "no");
node->add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
node->add_property ("mouse-mode", enum2str(mouse_mode));
node->add_property ("join-object-range", smart_mode_action->get_active () ? "yes" : "no");
node.add_property ("show-measures", _show_measures ? "yes" : "no");
node.add_property ("maximised", _maximised ? "yes" : "no");
node.add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
node.add_property ("stationary-playhead", _stationary_playhead ? "yes" : "no");
node.add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
node.add_property ("mouse-mode", enum2str(mouse_mode));
node.add_property ("join-object-range", smart_mode_action->get_active () ? "yes" : "no");
Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("show-editor-mixer"));
if (act) {
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
node->add_property (X_("show-editor-mixer"), tact->get_active() ? "yes" : "no");
node.add_property (X_("show-editor-mixer"), tact->get_active() ? "yes" : "no");
}
act = ActionManager::get_action (X_("Editor"), X_("show-editor-list"));
if (act) {
Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
node->add_property (X_("show-editor-list"), tact->get_active() ? "yes" : "no");
node.add_property (X_("show-editor-list"), tact->get_active() ? "yes" : "no");
}
snprintf (buf, sizeof (buf), "%d", _the_notebook.get_current_page ());
node->add_property (X_("editor-list-page"), buf);
node.add_property (X_("editor-list-page"), buf);
if (button_bindings) {
XMLNode* bb = new XMLNode (X_("Buttons"));
button_bindings->save (*bb);
node->add_child_nocopy (*bb);
node.add_child_nocopy (*bb);
}
node->add_property (X_("show-marker-lines"), _show_marker_lines ? "yes" : "no");
node.add_property (X_("show-marker-lines"), _show_marker_lines ? "yes" : "no");
node->add_child_nocopy (selection->get_state ());
node->add_child_nocopy (_regions->get_state ());
node.add_child_nocopy (selection->get_state ());
node.add_child_nocopy (_regions->get_state ());
snprintf (buf, sizeof (buf), "%" PRId64, nudge_clock->current_duration());
node->add_property ("nudge-clock-value", buf);
node.add_property ("nudge-clock-value", buf);
return *node;
return node;
}
/** if @param trackview_relative_offset is true, @param y y is an offset into the trackview area, in pixel units
@ -3835,7 +3750,7 @@ bool
Editor::edit_controls_button_release (GdkEventButton* ev)
{
if (Keyboard::is_context_menu_event (ev)) {
ARDOUR_UI::instance()->add_route (this);
ARDOUR_UI::instance()->add_route (current_toplevel());
} else if (ev->button == 1) {
selection->clear_tracks ();
}
@ -3895,12 +3810,6 @@ Editor::cycle_zoom_focus ()
}
}
void
Editor::ensure_float (Window& win)
{
win.set_transient_for (*this);
}
void
Editor::pane_allocation_handler (Allocation &alloc, Paned* which)
{
@ -4292,7 +4201,7 @@ Editor::maximise_editing_space ()
return;
}
fullscreen ();
current_toplevel()->fullscreen ();
_maximised = true;
}
@ -4304,7 +4213,7 @@ Editor::restore_editing_space ()
return;
}
unfullscreen();
current_toplevel()->unfullscreen();
_maximised = false;
}
@ -4377,13 +4286,14 @@ Editor::mapped_clear_playlist (RouteTimeAxisView& atv, uint32_t /*sz*/)
bool
Editor::on_key_press_event (GdkEventKey* ev)
{
return key_press_focus_accelerator_handler (*this, ev);
return key_press_focus_accelerator_handler (*current_toplevel(), ev);
}
bool
Editor::on_key_release_event (GdkEventKey* ev)
{
return Gtk::Window::on_key_release_event (ev);
return false;
// return Gtk::Window::on_key_release_event (ev);
// return key_press_focus_accelerator_handler (*this, ev);
}
@ -5091,7 +5001,7 @@ Editor::first_idle ()
if (track_views.size() > 1) {
Timers::TimerSuspender t;
dialog = new MessageDialog (
*this,
*current_toplevel(),
string_compose (_("Please wait while %1 loads visual data."), PROGRAM_NAME),
true
);
@ -5664,7 +5574,7 @@ Editor::super_rapid_screen_update ()
/* METERING / MIXER STRIPS */
/* update track meters, if required */
if (is_mapped() && meters_running) {
if (contents().is_mapped() && meters_running) {
RouteTimeAxisView* rtv;
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
if ((rtv = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
@ -5794,12 +5704,15 @@ Editor::session_going_away ()
stop_step_editing ();
if (own_window()) {
/* get rid of any existing editor mixer strip */
WindowTitle title(Glib::get_application_name());
title += _("Editor");
set_title (title.get_string());
own_window()->set_title (title.get_string());
}
SessionHandlePtr::session_going_away ();
}
@ -6031,3 +5944,55 @@ Editor::ui_parameter_changed (string parameter)
}
}
}
Gtk::Window*
Editor::use_own_window ()
{
bool new_window = !own_window();
Gtk::Window* win = Tabbable::use_own_window ();
if (win && new_window) {
win->set_name ("EditorWindow");
win->add_accel_group (ActionManager::ui_manager->get_accel_group());
ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Editor"), this);
// win->signal_realize().connect (*this, &Editor::on_realize);
win->signal_event().connect (sigc::mem_fun (*this, &Editor::generic_event_handler));
update_title ();
}
DisplaySuspender ds;
contents().show_all ();
/* XXX: this is a bit unfortunate; it would probably
be nicer if we could just call show () above rather
than needing the show_all ()
*/
/* re-hide stuff if necessary */
editor_list_button_toggled ();
parameter_changed ("show-summary");
parameter_changed ("show-group-tabs");
parameter_changed ("show-zoom-tools");
/* now reset all audio_time_axis heights, because widgets might need
to be re-hidden
*/
TimeAxisView *tv;
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
tv = (static_cast<TimeAxisView*>(*i));
tv->reset_height ();
}
if (current_mixer_strip) {
current_mixer_strip->hide_things ();
current_mixer_strip->parameter_changed ("mixer-element-visibility");
}
return win;
}

View file

@ -54,6 +54,7 @@
#include "ardour_button.h"
#include "ardour_dialog.h"
#include "ardour_dropdown.h"
#include "binding_owners.h"
#include "public_editor.h"
#include "editing.h"
#include "enums.h"
@ -143,6 +144,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void set_session (ARDOUR::Session *);
ARDOUR::Session* session() const { return _session; }
Gtk::Window* use_own_window ();
void first_idle ();
virtual bool have_idled () const { return _have_idled; }
@ -286,10 +289,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
bool process_midi_export_dialog (MidiExportDialog& dialog, boost::shared_ptr<ARDOUR::MidiRegion> midi_region);
void add_transport_frame (Gtk::Container&);
void add_toplevel_menu (Gtk::Container&);
Gtk::HBox& get_status_bar_packer() { return status_bar_hpacker; }
void set_zoom_focus (Editing::ZoomFocus);
Editing::ZoomFocus get_zoom_focus () const { return zoom_focus; }
framecnt_t get_current_zoom () const { return samples_per_pixel; }
@ -367,8 +366,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void ensure_float (Gtk::Window&);
void show_window ();
void scroll_tracks_down_line ();
void scroll_tracks_up_line ();
@ -561,6 +558,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void color_handler ();
bool constructed;
Gtkmm2ext::Bindings key_bindings;
// to keep track of the playhead position for control_scroll
boost::optional<framepos_t> _control_scroll_target;
@ -783,8 +781,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void timeaxisview_deleted (TimeAxisView *);
Gtk::HBox global_hpacker;
Gtk::VBox global_vpacker;
Gtk::VBox vpacker;
VBoxWithBindings global_vpacker;
/* Cursor stuff. Do not use directly, use via CursorContext. */
friend class CursorContext;
@ -820,13 +817,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Gtk::VBox time_bars_vbox;
ArdourCanvas::Pixbuf *logo_item;
#if 0
/* these will be needed when we have canvas rulers */
ArdourCanvas::Container *minsec_group;
ArdourCanvas::Container *bbt_group;
ArdourCanvas::Container *timecode_group;
ArdourCanvas::Container *frame_group;
#endif
ArdourCanvas::Container *tempo_group;
ArdourCanvas::Container *meter_group;
@ -1193,7 +1183,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void load_bindings ();
Gtkmm2ext::ActionMap editor_action_map;
Gtkmm2ext::Bindings key_bindings;
/* CUT/COPY/PASTE */
@ -1867,10 +1856,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
ArdourCanvas::Rectangle* cd_marker_bar_drag_rect;
ArdourCanvas::Rectangle* range_bar_drag_rect;
ArdourCanvas::Rectangle* transport_bar_drag_rect;
#ifdef GTKOSX
ArdourCanvas::Rectangle *bogus_background_rect;
#endif
ArdourCanvas::Rectangle *transport_bar_range_rect;
ArdourCanvas::Rectangle *transport_bar_preroll_rect;
ArdourCanvas::Rectangle *transport_bar_postroll_rect;
@ -2128,8 +2113,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void history_changed ();
Gtk::HBox status_bar_hpacker;
Editing::EditPoint _edit_point;
ArdourDropdown edit_point_selector;

View file

@ -2062,11 +2062,8 @@ Editor::register_region_actions ()
sigc::bind (sigc::mem_fun (*this, &Editor::align_regions_relative), ARDOUR::SyncPoint)
);
Glib::RefPtr<Action> a = reg_sens (_region_actions, "choose-top-region", _("Choose Top..."), sigc::bind (sigc::mem_fun (*this, &Editor::change_region_layering_order), false));
a->set_accel_group (get_accel_group ());
a = reg_sens (_region_actions, "choose-top-region-context-menu", _("Choose Top..."), sigc::bind (sigc::mem_fun (*this, &Editor::change_region_layering_order), true));
a->set_accel_group (get_accel_group ());
reg_sens (_region_actions, "choose-top-region", _("Choose Top..."), sigc::bind (sigc::mem_fun (*this, &Editor::change_region_layering_order), false));
reg_sens (_region_actions, "choose-top-region-context-menu", _("Choose Top..."), sigc::bind (sigc::mem_fun (*this, &Editor::change_region_layering_order), true));
_all_region_actions_sensitized = true;

View file

@ -39,7 +39,7 @@ Editor::start_updating_meters ()
{
RouteTimeAxisView* rtv;
if (is_mapped() && _session) {
if (contents().is_mapped() && _session) {
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
if ((rtv = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
rtv->reset_meter ();
@ -57,7 +57,7 @@ Editor::stop_updating_meters ()
meters_running = false;
if (is_mapped() && _session) {
if (contents().is_mapped() && _session) {
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
if ((rtv = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
rtv->hide_meter ();

View file

@ -500,7 +500,13 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
void
Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers)
{
if (!UIConfiguration::instance().get_autoscroll_editor () || autoscroll_active ()) {
Gtk::Window* toplevel = dynamic_cast<Gtk::Window*>(contents().get_toplevel());
if (!toplevel) {
return;
}
if (!UIConfiguration::instance()->get_autoscroll_editor () || autoscroll_active ()) {
return;
}
@ -557,7 +563,7 @@ Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool from_headers)
int x, y;
Gdk::ModifierType mask;
get_window()->get_pointer (x, y, mask);
toplevel->get_window()->get_pointer (x, y, mask);
if ((allow_horiz && ((x < scrolling_boundary.x0 && leftmost_frame > 0) || x >= scrolling_boundary.x1)) ||
(allow_vert && ((y < scrolling_boundary.y0 && vertical_adjustment.get_value() > 0)|| y >= scrolling_boundary.y1))) {
@ -578,8 +584,13 @@ Editor::autoscroll_canvas ()
Gdk::ModifierType mask;
frameoffset_t dx = 0;
bool no_stop = false;
Gtk::Window* toplevel = dynamic_cast<Gtk::Window*>(contents().get_toplevel());
get_window()->get_pointer (x, y, mask);
if (!toplevel) {
return false;
}
toplevel->get_window()->get_pointer (x, y, mask);
VisualChange vc;
bool vertical_motion = false;
@ -682,7 +693,7 @@ Editor::autoscroll_canvas ()
int cx;
int cy;
translate_coordinates (*_track_canvas, x, y, cx, cy);
toplevel->translate_coordinates (*_track_canvas, x, y, cx, cy);
/* clamp x and y to remain within the autoscroll boundary,
* which is defined in window coordinates
@ -734,7 +745,7 @@ Editor::autoscroll_canvas ()
}
y = min (max ((ArdourCanvas::Coord) y, autoscroll_boundary.y0), autoscroll_boundary.y1);
translate_coordinates (*_track_canvas_viewport, x, y, cx, cy);
toplevel->translate_coordinates (*_track_canvas_viewport, x, y, cx, cy);
ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (cx, cy));
ev.x = d.x;

View file

@ -3767,7 +3767,7 @@ MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i)
assert (_marker);
_points.push_back (ArdourCanvas::Duple (0, 0));
_points.push_back (ArdourCanvas::Duple (0, physical_screen_height (_editor->get_window())));
_points.push_back (ArdourCanvas::Duple (0, physical_screen_height (_editor->current_toplevel()->get_window())));
}
MarkerDrag::~MarkerDrag ()
@ -5139,7 +5139,7 @@ RangeMarkerBarDrag::RangeMarkerBarDrag (Editor* e, ArdourCanvas::Item* i, Operat
_drag_rect = new ArdourCanvas::Rectangle (_editor->time_line_group,
ArdourCanvas::Rect (0.0, 0.0, 0.0,
physical_screen_height (_editor->get_window())));
physical_screen_height (_editor->current_toplevel()->get_window())));
_drag_rect->hide ();
_drag_rect->set_fill_color (UIConfiguration::instance().color ("range drag rect"));

View file

@ -78,7 +78,7 @@ Editor::show_editor_mixer (bool yn)
show_editor_mixer_when_tracks_arrive = false;
if (yn) {
Glib::RefPtr<Gdk::Window> win = get_window ();
Glib::RefPtr<Gdk::Window> win = current_toplevel()->get_window ();
Glib::RefPtr<Gdk::Screen> screen;
if (win) {

View file

@ -2782,7 +2782,7 @@ Editor::rename_region ()
return;
}
ArdourDialog d (*this, _("Rename Region"), true, false);
ArdourDialog d (*current_toplevel(), _("Rename Region"), true, false);
Entry entry;
Label label (_("New name:"));
HBox hbox;
@ -7597,7 +7597,7 @@ Editor::fit_tracks (TrackViewList & tracks)
double first_y_pos = DBL_MAX;
if (h < TimeAxisView::preset_height (HeightSmall)) {
MessageDialog msg (*this, _("There are too many tracks to fit in the current window"));
MessageDialog msg (*current_toplevel(), _("There are too many tracks to fit in the current window"));
/* too small to be displayed */
return;
}

View file

@ -27,7 +27,7 @@
#include "i18n.h"
FloatingTextEntry::FloatingTextEntry (const std::string& initial_contents)
FloatingTextEntry::FloatingTextEntry (Gtk::Window* parent, const std::string& initial_contents)
: Gtk::Window (Gtk::WINDOW_POPUP)
, entry_changed (false)
{
@ -44,7 +44,10 @@ FloatingTextEntry::FloatingTextEntry (const std::string& initial_contents)
entry.signal_activate().connect (sigc::mem_fun (*this, &FloatingTextEntry::activated));
entry.signal_key_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_press));
entry.signal_button_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::button_press));
PublicEditor::instance ().signal_focus_out_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::entry_focus_out));
if (parent) {
parent->signal_focus_out_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::entry_focus_out));
}
add (entry);
}

View file

@ -26,7 +26,7 @@
class FloatingTextEntry : public Gtk::Window
{
public:
FloatingTextEntry (const std::string& initial_contents);
FloatingTextEntry (Gtk::Window* parent, const std::string& initial_contents);
sigc::signal1<void,std::string> use_text;

View file

@ -256,7 +256,7 @@ Meterbridge::on_key_press_event (GdkEventKey* ev)
if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
return true;
}
return forward_key_press (ev);
return relay_key_press (ev);
}
bool

View file

@ -89,8 +89,7 @@ Mixer_UI::instance ()
}
Mixer_UI::Mixer_UI ()
: _parent_window (0)
, _visible (false)
: Tabbable (_content, _("Mixer"))
, no_track_list_redisplay (false)
, in_group_row_change (false)
, track_menu (0)
@ -237,19 +236,16 @@ Mixer_UI::Mixer_UI ()
list_hpane.signal_size_allocate().connect (sigc::bind (sigc::mem_fun(*this, &Mixer_UI::pane_allocation_handler),
static_cast<Gtk::Paned*> (&list_hpane)));
pack_start (list_hpane, true, true);
set_name ("MixerWindow");
_content.pack_start (list_hpane, true, true);
update_title ();
add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
route_group_display_button_box->show();
route_group_add_button->show();
route_group_remove_button->show();
show ();
_content.show ();
_content.set_name ("MixerWindow");
global_hpacker.show();
scroller.show();
@ -299,15 +295,6 @@ Mixer_UI::track_editor_selection ()
PublicEditor::instance().get_selection().TracksChanged.connect (sigc::mem_fun (*this, &Mixer_UI::follow_editor_selection));
}
void
Mixer_UI::ensure_float (Window& win)
{
if (_parent_window) {
win.set_transient_for (*_parent_window);
}
}
Gtk::Notebook*
Mixer_UI::use_own_window ()
{
@ -418,7 +405,6 @@ Mixer_UI::hide_window (GdkEventAny *ev)
return true;
}
void
Mixer_UI::add_strips (RouteList& routes)
{
@ -871,7 +857,7 @@ Mixer_UI::set_session (Session* sess)
refill_favorite_plugins();
XMLNode* node = ARDOUR_UI::instance()->mixer_settings();
set_state (*node);
set_state (*node, 0);
update_title ();
@ -1022,13 +1008,38 @@ Mixer_UI::stop_updating ()
void
Mixer_UI::fast_update_strips ()
{
if (is_mapped () && _session) {
if (_content.is_mapped () && _session) {
for (list<MixerStrip *>::iterator i = strips.begin(); i != strips.end(); ++i) {
(*i)->fast_update ();
}
}
}
void
Mixer_UI::show_window ()
{
Tabbable::show_window ();
/* show/hide group tabs as required */
parameter_changed ("show-group-tabs");
/* now reset each strips width so the right widgets are shown */
MixerStrip* ms;
TreeModel::Children rows = track_model->children();
TreeModel::Children::iterator ri;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
ms = (*ri)[track_columns.strip];
ms->set_width_enum (ms->get_width_enum (), ms->width_owner());
/* Fix visibility of mixer strip stuff */
ms->parameter_changed (X_("mixer-element-visibility"));
}
/* force focus into main area */
scroller_base.grab_focus ();
}
void
Mixer_UI::set_all_strips_visibility (bool yn)
{
@ -1699,23 +1710,6 @@ Mixer_UI::set_strip_width (Width w, bool save)
}
}
void
Mixer_UI::set_window_pos_and_size ()
{
if (_parent_window) {
_parent_window->resize (m_width, m_height);
_parent_window->move (m_root_x, m_root_y);
}
}
void
Mixer_UI::get_window_pos_and_size ()
{
if (_parent_window) {
_parent_window->get_position(m_root_x, m_root_y);
_parent_window->get_size(m_width, m_height);
}
}
struct PluginStateSorter {
public:
@ -1740,7 +1734,7 @@ private:
};
int
Mixer_UI::set_state (const XMLNode& node)
Mixer_UI::set_state (const XMLNode& node, int version)
{
const XMLProperty* prop;
XMLNode* geometry;
@ -1792,8 +1786,6 @@ Mixer_UI::set_state (const XMLNode& node)
}
}
set_window_pos_and_size ();
if ((prop = node.property ("narrow-strips"))) {
if (string_is_affirmative (prop->value())) {
set_strip_width (Narrow);
@ -1854,7 +1846,7 @@ Mixer_UI::set_state (const XMLNode& node)
}
XMLNode&
Mixer_UI::get_state (void)
Mixer_UI::get_state ()
{
XMLNode* node = new XMLNode ("Mixer");
@ -1891,11 +1883,8 @@ Mixer_UI::get_state (void)
}
node->add_property ("narrow-strips", _strip_width == Narrow ? "yes" : "no");
node->add_property ("show-mixer", _visible ? "yes" : "no");
node->add_property ("show-mixer-list", _show_mixer_list ? "yes" : "no");
node->add_property ("maximised", _maximised ? "yes" : "no");
store_current_favorite_order ();
@ -2171,6 +2160,10 @@ Mixer_UI::new_track_or_bus ()
void
Mixer_UI::update_title ()
{
if (!own_window()) {
return;
}
if (_session) {
string n;
@ -2207,7 +2200,7 @@ Mixer_UI::strip_by_x (int x)
for (list<MixerStrip*>::iterator i = strips.begin(); i != strips.end(); ++i) {
int x1, x2, y;
(*i)->translate_coordinates (*this, 0, 0, x1, y);
(*i)->translate_coordinates (_content, 0, 0, x1, y);
x2 = x1 + (*i)->get_width();
if (x >= x1 && x <= x2) {
@ -2267,7 +2260,7 @@ Mixer_UI::toggle_midi_input_active (bool flip_others)
void
Mixer_UI::maximise_mixer_space ()
{
if (_maximised) {
if (!own_window()) {
return;
}
@ -2277,12 +2270,15 @@ Mixer_UI::maximise_mixer_space ()
win->fullscreen ();
_maximised = true;
}
_window->fullscreen ();
_maximised = true;
}
void
Mixer_UI::restore_mixer_space ()
{
if (!_maximised) {
if (!own_window()) {
return;
}
@ -2292,6 +2288,9 @@ Mixer_UI::restore_mixer_space ()
win->unfullscreen();
_maximised = false;
}
own_window()->unfullscreen();
_maximised = false;
}
void

View file

@ -42,13 +42,13 @@
#include "ardour/plugin.h"
#include "ardour/plugin_manager.h"
<<<<<<< HEAD
#include "gtkmm2ext/visibility_tracker.h"
#include "gtkmm2ext/dndtreeview.h"
#include "gtkmm2ext/treeutils.h"
=======
>>>>>>> the basics of tabbed
#include "gtkmm2ext/tabbable.h"
#include "enums.h"
#include "mixer_actor.h"
@ -62,7 +62,6 @@ class PluginSelector;
class MixerGroupTabs;
class MonitorSection;
<<<<<<< HEAD
class PluginTreeStore : public Gtk::TreeStore
{
public:
@ -76,19 +75,14 @@ protected:
virtual bool row_drop_possible_vfunc (const Gtk::TreeModel::Path&, const Gtk::SelectionData&) const;
};
class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr, public MixerActor, public Gtkmm2ext::VisibilityTracker
=======
class Mixer_UI : public Gtk::VBox, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr, public MixerActor
>>>>>>> the basics of tabbed
class Mixer_UI : public Gtkmm2ext::Tabbable, public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr, public MixerActor, public Gtkmm2ext::VisibilityTracker
{
public:
static Mixer_UI* instance();
~Mixer_UI();
Gtk::Window* own_window() const { return _parent_window; }
Gtk::Notebook* use_own_window();
bool visible() const { return _visible; }
Gtk::Window* use_own_window ();
void show_window ();
void set_session (ARDOUR::Session *);
void track_editor_selection ();
@ -101,22 +95,18 @@ class Mixer_UI : public Gtk::VBox, public PBD::ScopedConnectionList, public ARDO
void unselect_strip_in_display (MixerStrip*);
void select_strip_in_display (MixerStrip*);
XMLNode& get_state (void);
int set_state (const XMLNode& );
XMLNode& get_state ();
int set_state (const XMLNode&, int /* version */);
void show_mixer_list (bool yn);
void show_monitor_section (bool);
void show_window ();
bool hide_window (GdkEventAny *ev);
void show_strip (MixerStrip *);
void hide_strip (MixerStrip *);
void maximise_mixer_space();
void restore_mixer_space();
void ensure_float (Gtk::Window&);
MonitorSection* monitor_section() const { return _monitor_section; }
void deselect_all_strip_processors();
@ -124,16 +114,15 @@ class Mixer_UI : public Gtk::VBox, public PBD::ScopedConnectionList, public ARDO
void select_none ();
bool window_not_visible () const;
protected:
void set_route_targets_for_operation ();
private:
Mixer_UI ();
static Mixer_UI* _instance;
Gtk::Window* _parent_window;
bool _visible;
Gtk::VBox _content;
Gtk::HBox global_hpacker;
Gtk::VBox global_vpacker;
Gtk::ScrolledWindow scroller;
@ -383,5 +372,3 @@ class Mixer_UI : public Gtk::VBox, public PBD::ScopedConnectionList, public ARDO
};
#endif /* __ardour_mixer_ui_h__ */

View file

@ -466,7 +466,7 @@ MonitorSection::MonitorSection (Session* s)
_tearoff->tearoff_window().set_type_hint (Gdk::WINDOW_TYPE_HINT_NORMAL);
}
_tearoff->tearoff_window().set_title (X_("Monitor"));
_tearoff->tearoff_window().signal_key_press_event().connect (sigc::ptr_fun (forward_key_press), false);
_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), (Gtk::Window*) 0), false);
update_output_display ();
update_processor_box ();

View file

@ -1013,7 +1013,7 @@ Panner2dWindow::set_width ()
bool
Panner2dWindow::on_key_press_event (GdkEventKey* event)
{
return relay_key_press (event, &PublicEditor::instance());
return relay_key_press (event, 0);
}
bool

View file

@ -374,7 +374,7 @@ PluginUIWindow::on_key_press_event (GdkEventKey* event)
no widgets in this window that we want to have
key focus.
*/
return relay_key_press (event, &PublicEditor::instance());
return relay_key_press (event, 0);
} else {
return relay_key_press (event, this);
}

View file

@ -2002,7 +2002,7 @@ ProcessorBox::maybe_add_processor_to_ui_list (boost::weak_ptr<Processor> w)
const XMLNode* ui_xml = _session->extra_xml (X_("UI"));
if (ui_xml) {
wp->set_state (*ui_xml);
wp->set_state (*ui_xml, 0);
}
void* existing_ui = p->get_ui ();
@ -3305,7 +3305,7 @@ ProcessorWindowProxy::session_handle()
}
XMLNode&
ProcessorWindowProxy::get_state () const
ProcessorWindowProxy::get_state ()
{
XMLNode *node;
node = &ProxyBase::get_state();
@ -3313,8 +3313,8 @@ ProcessorWindowProxy::get_state () const
return *node;
}
void
ProcessorWindowProxy::set_state (const XMLNode& node)
int
ProcessorWindowProxy::set_state (const XMLNode& node, int /*version*/)
{
XMLNodeList children = node.children ();
XMLNodeList::const_iterator i = children.begin ();
@ -3333,7 +3333,7 @@ ProcessorWindowProxy::set_state (const XMLNode& node)
}
}
ProxyBase::set_state(node);
return ProxyBase::set_state (node, 0);
}
Gtk::Window*

View file

@ -91,8 +91,8 @@ class ProcessorWindowProxy : public WM::ProxyBase
void toggle();
void set_custom_ui_mode(bool use_custom) { want_custom = use_custom; }
void set_state (const XMLNode&);
XMLNode& get_state () const;
int set_state (const XMLNode&, int);
XMLNode& get_state ();
private:
ProcessorBox* _processor_box;

View file

@ -19,6 +19,8 @@
#include "public_editor.h"
#include "i18n.h"
PublicEditor* PublicEditor::_instance = 0;
const int PublicEditor::window_border_width = 12;
@ -28,9 +30,8 @@ const int PublicEditor::horizontal_spacing = 6;
sigc::signal<void> PublicEditor::DropDownKeys;
PublicEditor::PublicEditor ()
: Window (Gtk::WINDOW_TOPLEVEL)
, VisibilityTracker (*((Gtk::Window*)this))
PublicEditor::PublicEditor (Gtk::Widget& content)
: Tabbable (content, _("Editor"))
, _suspend_route_redisplay_counter (0)
{
}

View file

@ -43,6 +43,7 @@
#include "canvas/fwd.h"
#include "gtkmm2ext/actions.h"
#include "gtkmm2ext/tabbable.h"
#include "gtkmm2ext/visibility_tracker.h"
#include "editing.h"
@ -105,9 +106,9 @@ using ARDOUR::framecnt_t;
* of PublicEditor need not be recompiled if private methods or member variables
* change.
*/
class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, public Gtkmm2ext::VisibilityTracker {
class PublicEditor : public Gtkmm2ext::Tabbable {
public:
PublicEditor ();
PublicEditor (Gtk::Widget& content);
virtual ~PublicEditor ();
/** @return Singleton PublicEditor instance */
@ -232,8 +233,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual void export_range () = 0;
virtual void register_actions () = 0;
virtual void add_transport_frame (Gtk::Container&) = 0;
virtual void add_toplevel_menu (Gtk::Container&) = 0;
virtual void set_zoom_focus (Editing::ZoomFocus) = 0;
virtual Editing::ZoomFocus get_zoom_focus () const = 0;
virtual framecnt_t get_current_zoom () const = 0;
@ -267,8 +266,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
/** @return true if the playhead is currently being dragged, otherwise false */
virtual bool dragging_playhead () const = 0;
virtual void ensure_float (Gtk::Window&) = 0;
virtual void show_window () = 0;
virtual framepos_t leftmost_sample() const = 0;
virtual framecnt_t current_page_samples() const = 0;
virtual double visible_canvas_height () const = 0;
@ -442,11 +439,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
PBD::Signal0<void> SnapChanged;
PBD::Signal0<void> MouseModeChanged;
Gtk::Notebook& tabs() { return _tabs; }
protected:
Gtk::Notebook _tabs;
friend class DisplaySuspender;
virtual void suspend_route_redisplay () = 0;
virtual void resume_route_redisplay () = 0;

View file

@ -1720,6 +1720,7 @@ private:
RCOptionEditor::RCOptionEditor ()
: OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
, Tabbable (*this, _("Preferences"))
, _rc_config (Config)
, _mixer_strip_visibility ("mixer-element-visibility")
{
@ -1831,6 +1832,7 @@ RCOptionEditor::RCOptionEditor ()
/* TRANSPORT */
add_option (_("Transport"), new OptionEditorHeading (S_("Playhead Behaviour")));
add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
BoolOption* tsf;

View file

@ -20,6 +20,8 @@
#ifndef __gtk_ardour_rc_option_editor_h__
#define __gtk_ardour_rc_option_editor_h__
#include "gtkmm2ext/tabbable.h"
#include "option_editor.h"
#include "visibility_group.h"
@ -32,7 +34,7 @@
*/
/** Editor for options which are obtained from and written back to one of the .rc files. */
class RCOptionEditor : public OptionEditor
class RCOptionEditor : public OptionEditor, public Gtkmm2ext::Tabbable
{
public:
RCOptionEditor ();

View file

@ -222,7 +222,7 @@ RegionLayeringOrderEditor::on_key_press_event (GdkEventKey* ev)
}
if (!handled) {
handled = key_press_focus_accelerator_handler (editor, ev);
handled = relay_key_press (ev, 0);
}
if (!handled) {

View file

@ -504,7 +504,7 @@ StepEntry::on_key_press_event (GdkEventKey* ev)
}
}
return forward_key_press (ev);
return relay_key_press (ev);
}
bool

View file

@ -297,29 +297,18 @@ ARDOUR_UI_UTILS::gdk_color_to_rgba (Gdk::Color const& c)
bool
ARDOUR_UI_UTILS::relay_key_press (GdkEventKey* ev, Gtk::Window* win)
{
if (!key_press_focus_accelerator_handler (*win, ev)) {
if (!PublicEditor::_instance) {
/* early key press in pre-main-window-dialogs, no editor yet */
return false;
}
PublicEditor& ed (PublicEditor::instance());
return ed.on_key_press_event(ev);
} else {
return true;
switch (ev->type) {
case GDK_KEY_PRESS:
return ARDOUR_UI::instance()->key_press_handler (ev, win);
default:
return ARDOUR_UI::instance()->key_release_handler (ev, win);
}
}
bool
ARDOUR_UI_UTILS::forward_key_press (GdkEventKey* ev)
ARDOUR_UI_UTILS::emulate_key_event (unsigned int keyval)
{
return PublicEditor::instance().on_key_press_event(ev);
}
bool
ARDOUR_UI_UTILS::emulate_key_event (Gtk::Widget* w, unsigned int keyval)
{
GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET(w->gobj()));
GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET(ARDOUR_UI::instance()->main_window().gobj()));
GdkKeymap *keymap = gdk_keymap_get_for_display (display);
GdkKeymapKey *keymapkey = NULL;
gint n_keys;
@ -329,7 +318,7 @@ ARDOUR_UI_UTILS::emulate_key_event (Gtk::Widget* w, unsigned int keyval)
GdkEventKey ev;
ev.type = GDK_KEY_PRESS;
ev.window = gtk_widget_get_window(GTK_WIDGET(w->gobj()));
ev.window = ARDOUR_UI::instance()->main_window().get_window()->gobj();
ev.send_event = FALSE;
ev.time = 0;
ev.state = 0;
@ -340,9 +329,9 @@ ARDOUR_UI_UTILS::emulate_key_event (Gtk::Widget* w, unsigned int keyval)
ev.group = keymapkey[0].group;
g_free(keymapkey);
forward_key_press(&ev);
relay_key_press(&ev);
ev.type = GDK_KEY_RELEASE;
return forward_key_press(&ev);
return relay_key_press(&ev);
}
static string

View file

@ -67,10 +67,9 @@ void set_color_from_rgba (Gdk::Color&, uint32_t);
uint32_t gdk_color_to_rgba (Gdk::Color const&);
uint32_t contrasting_text_color (uint32_t c);
bool relay_key_press (GdkEventKey* ev, Gtk::Window* win);
bool forward_key_press (GdkEventKey* ev);
bool relay_key_press (GdkEventKey* ev, Gtk::Window* win = 0);
bool key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev);
bool emulate_key_event (Gtk::Widget*, unsigned int);
bool emulate_key_event (unsigned int);
Glib::RefPtr<Gdk::Pixbuf> get_xpm (std::string);
std::vector<std::string> get_icon_sets ();

View file

@ -255,9 +255,7 @@ VideoMonitor::is_started ()
void
VideoMonitor::forward_keyevent (unsigned int keyval)
{
Editor* ed = dynamic_cast<Editor*>(&PublicEditor::instance());
if (!ed) return;
emulate_key_event(ed, keyval);
emulate_key_event (keyval);
}
void

View file

@ -170,269 +170,23 @@ Manager::set_transient_for (Gtk::Window* parent)
/*-------------------------*/
ProxyBase::ProxyBase (const string& name, const std::string& menu_name)
: _name (name)
, _menu_name (menu_name)
, _window (0)
, _visible (false)
, _x_off (-1)
, _y_off (-1)
, _width (-1)
, _height (-1)
, vistracker (0)
ProxyBase::ProxyBase (const std::string& name, const std::string& menu_name)
: WindowProxy (name, menu_name)
{
}
ProxyBase::ProxyBase (const string& name, const std::string& menu_name, const XMLNode& node)
: _name (name)
, _menu_name (menu_name)
, _window (0)
, _visible (false)
, _x_off (-1)
, _y_off (-1)
, _width (-1)
, _height (-1)
, vistracker (0)
ProxyBase::ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode& node)
: WindowProxy (name, menu_name, node)
{
set_state (node);
}
ProxyBase::~ProxyBase ()
{
delete vistracker;
delete _window;
}
void
ProxyBase::set_state (const XMLNode& node)
{
XMLNodeList children = node.children ();
XMLNodeList::const_iterator i = children.begin ();
while (i != children.end()) {
XMLProperty* prop = (*i)->property (X_("name"));
if ((*i)->name() == X_("Window") && prop && prop->value() == _name) {
break;
}
++i;
}
if (i != children.end()) {
XMLProperty* prop;
if ((prop = (*i)->property (X_("visible"))) != 0) {
_visible = PBD::string_is_affirmative (prop->value ());
}
if ((prop = (*i)->property (X_("x-off"))) != 0) {
_x_off = atoi (prop->value());
}
if ((prop = (*i)->property (X_("y-off"))) != 0) {
_y_off = atoi (prop->value());
}
if ((prop = (*i)->property (X_("x-size"))) != 0) {
_width = atoi (prop->value());
}
if ((prop = (*i)->property (X_("y-size"))) != 0) {
_height = atoi (prop->value());
}
}
/* if we have a window already, reset its properties */
if (_window) {
setup ();
}
}
void
ProxyBase::set_action (Glib::RefPtr<Gtk::Action> act)
{
_action = act;
}
std::string
ProxyBase::action_name() const
{
return string_compose (X_("toggle-%1"), _name);
}
void
ProxyBase::toggle()
{
if (!_window) {
(void) get (true);
assert (_window);
/* XXX this is a hack - the window object should really
ensure its components are all visible. sigh.
*/
_window->show_all();
/* we'd like to just call this and nothing else */
_window->present ();
if (_width != -1 && _height != -1) {
_window->set_default_size (_width, _height);
}
if (_x_off != -1 && _y_off != -1) {
_window->move (_x_off, _y_off);
}
} else {
if (_window->is_mapped()) {
save_pos_and_size();
}
vistracker->cycle_visibility ();
if (_window->is_mapped()) {
if (_width != -1 && _height != -1) {
_window->set_default_size (_width, _height);
}
if (_x_off != -1 && _y_off != -1) {
_window->move (_x_off, _y_off);
}
}
}
}
XMLNode&
ProxyBase::get_state () const
{
XMLNode* node = new XMLNode (X_("Window"));
char buf[32];
node->add_property (X_("name"), _name);
if (_window && vistracker) {
/* we have a window, so use current state */
_visible = vistracker->partially_visible ();
if (_visible) {
_window->get_position (_x_off, _y_off);
_window->get_size (_width, _height);
}
}
node->add_property (X_("visible"), _visible? X_("yes") : X_("no"));
snprintf (buf, sizeof (buf), "%d", _x_off);
node->add_property (X_("x-off"), buf);
snprintf (buf, sizeof (buf), "%d", _y_off);
node->add_property (X_("y-off"), buf);
snprintf (buf, sizeof (buf), "%d", _width);
node->add_property (X_("x-size"), buf);
snprintf (buf, sizeof (buf), "%d", _height);
node->add_property (X_("y-size"), buf);
return *node;
}
void
ProxyBase::drop_window ()
{
if (_window) {
_window->hide ();
delete _window;
_window = 0;
delete vistracker;
vistracker = 0;
}
}
void
ProxyBase::use_window (Gtk::Window& win)
{
drop_window ();
_window = &win;
setup ();
}
void
ProxyBase::setup ()
{
assert (_window);
vistracker = new Gtkmm2ext::VisibilityTracker (*_window);
_window->signal_delete_event().connect (sigc::mem_fun (*this, &ProxyBase::delete_event_handler));
if (_width != -1 || _height != -1 || _x_off != -1 || _y_off != -1) {
/* cancel any mouse-based positioning */
_window->set_position (Gtk::WIN_POS_NONE);
}
if (_width != -1 && _height != -1) {
_window->set_default_size (_width, _height);
}
if (_x_off != -1 && _y_off != -1) {
_window->move (_x_off, _y_off);
}
WindowProxy::setup ();
set_session(_session);
}
void
ProxyBase::show ()
{
get (true);
assert (_window);
_window->show ();
}
void
ProxyBase::maybe_show ()
{
if (_visible) {
show ();
}
}
void
ProxyBase::show_all ()
{
get (true);
assert (_window);
_window->show_all ();
}
void
ProxyBase::present ()
{
get (true);
assert (_window);
_window->show_all ();
_window->present ();
/* turn off any mouse-based positioning */
_window->set_position (Gtk::WIN_POS_NONE);
}
void
ProxyBase::hide ()
{
if (_window) {
save_pos_and_size();
_window->hide ();
}
}
bool
ProxyBase::delete_event_handler (GdkEventAny* /*ev*/)
{
hide();
return true;
}
void
ProxyBase::save_pos_and_size ()
{
if (_window) {
_window->get_position (_x_off, _y_off);
_window->get_size (_width, _height);
}
}
/*-----------------------*/
ProxyTemporary::ProxyTemporary (const string& name, Gtk::Window* win)

View file

@ -27,20 +27,22 @@
#include <glibmm/refptr.h>
#include <sigc++/trackable.h>
#include "gtkmm2ext/window_proxy.h"
class XMLNode;
namespace Gtk {
class Window;
class Action;
class Window;
class Action;
}
namespace Gtkmm2ext {
class VisibilityTracker;
class VisibilityTracker;
}
namespace ARDOUR {
class Session;
class SessionHandlePtr;
class Session;
class SessionHandlePtr;
}
namespace WM {
@ -75,59 +77,20 @@ class Manager : public ARDOUR::SessionHandlePtr
static Manager* _instance;
};
class ProxyBase : public ARDOUR::SessionHandlePtr, public sigc::trackable {
class ProxyBase : public ARDOUR::SessionHandlePtr, public Gtkmm2ext::WindowProxy
{
public:
ProxyBase (const std::string& name, const std::string& menu_name);
ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&);
virtual ~ProxyBase();
void show ();
void show_all ();
void hide ();
void present ();
void maybe_show ();
bool visible() const { return _visible; }
const std::string& name() const { return _name; }
const std::string& menu_name() const { return _menu_name; }
std::string action_name() const;
void set_action (Glib::RefPtr<Gtk::Action>);
Glib::RefPtr<Gtk::Action> action() const { return _action; };
void drop_window ();
void use_window (Gtk::Window&);
virtual Gtk::Window* get (bool create = false) = 0;
virtual void toggle ();
void set_state (const XMLNode&);
XMLNode& get_state () const;
virtual ARDOUR::SessionHandlePtr* session_handle () = 0;
operator bool() const { return _window != 0; }
protected:
std::string _name;
std::string _menu_name;
Glib::RefPtr<Gtk::Action> _action;
Gtk::Window* _window;
mutable bool _visible; ///< true if the window should be visible on startup
mutable int _x_off; ///< x position
mutable int _y_off; ///< y position
mutable int _width; ///< width
mutable int _height; ///< height
Gtkmm2ext::VisibilityTracker* vistracker;
void save_pos_and_size ();
bool delete_event_handler (GdkEventAny *ev);
void setup ();
};
class ProxyTemporary: public ProxyBase {
class ProxyTemporary: public ProxyBase
{
public:
ProxyTemporary (const std::string& name, Gtk::Window* win);
~ProxyTemporary();
@ -145,7 +108,8 @@ class ProxyTemporary: public ProxyBase {
};
template<typename T>
class ProxyWithConstructor: public ProxyBase {
class ProxyWithConstructor: public ProxyBase
{
public:
ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c)
: ProxyBase (name, menu_name) , creator (c) {}
@ -189,10 +153,12 @@ class ProxyWithConstructor: public ProxyBase {
private:
boost::function<T*()> creator;
>>>>>>> first compilable version of tabbable design.
};
template<typename T>
class Proxy : public ProxyBase {
class Proxy : public ProxyBase
{
public:
Proxy (const std::string& name, const std::string& menu_name)
: ProxyBase (name, menu_name) {}

View file

@ -36,10 +36,13 @@ class VisibilityTracker;
class LIBGTKMM2EXT_API Tabbable : public WindowProxy {
public:
Tabbable (Gtk::Widget&);
Tabbable (Gtk::Widget&, const std::string&);
~Tabbable ();
void add_to_notebook (Gtk::Notebook& notebook, const std::string& tab_title, int position);
void show_tab ();
Gtk::Widget& contents() const { return _contents; }
Gtk::Window* get (bool create = false);
Gtk::Window* own_window () { return get (false); }
@ -53,11 +56,16 @@ class LIBGTKMM2EXT_API Tabbable : public WindowProxy {
bool window_visible ();
Gtk::Window* current_toplevel () const;
Gtk::Notebook* tab_root_drop ();
protected:
bool delete_event_handler (GdkEventAny *ev);
private:
Gtk::Widget& _contents;
Gtk::Notebook _own_notebook;
Gtk::Notebook* _parent_notebook;
std::string _tab_title;
int _notebook_position;

View file

@ -25,7 +25,7 @@
#include <glibmm/refptr.h>
#include <sigc++/trackable.h>
class XMLNode;
#include "pbd/statefuldestructible.h"
#include "gtkmm2ext/visibility.h"
@ -38,10 +38,10 @@ namespace Gtkmm2ext {
class VisibilityTracker;
class LIBGTKMM2EXT_API WindowProxy : public virtual sigc::trackable
class LIBGTKMM2EXT_API WindowProxy : public PBD::StatefulDestructible, public virtual sigc::trackable
{
public:
WindowProxy ();
WindowProxy (const std::string& name);
WindowProxy (const std::string& name, const std::string& menu_name);
WindowProxy (const std::string& name, const std::string& menu_name, const XMLNode&);
virtual ~WindowProxy();
@ -68,8 +68,8 @@ class LIBGTKMM2EXT_API WindowProxy : public virtual sigc::trackable
virtual void toggle ();
virtual int set_state (const XMLNode&);
virtual XMLNode& get_state () const;
virtual int set_state (const XMLNode&, int version);
virtual XMLNode& get_state ();
operator bool() const { return _window != 0; }

View file

@ -28,8 +28,9 @@ using namespace Gtkmm2ext;
using namespace Gtk;
using std::string;
Tabbable::Tabbable (Widget& w)
: _contents (w)
Tabbable::Tabbable (Widget& w, const string& name)
: WindowProxy (name)
, _contents (w)
{
}
@ -79,16 +80,44 @@ Tabbable::get (bool create)
return 0;
}
/* From here on, we're creating the window
*/
if ((_window = new Window (WINDOW_TOPLEVEL)) == 0) {
return 0;
}
/* allow parent window to become the key focus window */
_window->set_flags (CAN_FOCUS);
_window->add (_own_notebook);
_own_notebook.show ();
_own_notebook.set_show_tabs (false);
/* do other window-related setup */
setup ();
/* window should be ready for derived classes to do something with it */
return _window;
}
Gtk::Notebook*
Tabbable::tab_root_drop ()
{
(void) use_own_window ();
/* This is called after a drop of a tab onto the root window. Its
* responsibility is to return the notebook that this Tabbable's
* contents should be packed into before the drop handling is
* completed. It is not responsible for actually taking care of this
* packing.
*/
_window->show_all ();
_window->present ();
return &_own_notebook;
}
void
Tabbable::show_window ()
{
@ -119,6 +148,8 @@ Tabbable::delete_event_handler (GdkEventAny *ev)
if (_window == toplevel) {
std::cerr << " delete event for own window\n";
/* unpack Tabbable from parent, put it back in the main tabbed
* notebook
*/
@ -133,12 +164,12 @@ Tabbable::delete_event_handler (GdkEventAny *ev)
if (_parent_notebook) {
std::cerr << "repack into parent notebook\n";
_parent_notebook->insert_page (_contents, _tab_title, _notebook_position);
_parent_notebook->set_tab_detachable (_contents);
}
show_all ();
/* don't let anything else handle this */
return true;
@ -163,3 +194,17 @@ Tabbable::is_tabbed () const
return false;
}
void
Tabbable::show_tab ()
{
if (!window_visible() && _parent_notebook) {
_parent_notebook->set_current_page (_parent_notebook->page_num (_contents));
}
}
Gtk::Window*
Tabbable::current_toplevel () const
{
return dynamic_cast<Gtk::Window*> (contents().get_toplevel());
}

View file

@ -32,8 +32,9 @@ using namespace Gtk;
using namespace Gtkmm2ext;
using namespace PBD;
WindowProxy::WindowProxy ()
: _window (0)
WindowProxy::WindowProxy (const std::string& name)
: _name (name)
, _window (0)
, _visible (false)
, _x_off (-1)
, _y_off (-1)
@ -67,7 +68,7 @@ WindowProxy::WindowProxy (const std::string& name, const std::string& menu_name,
, _height (-1)
, vistracker (0)
{
set_state (node);
set_state (node, 0);
}
WindowProxy::~WindowProxy ()
@ -77,7 +78,7 @@ WindowProxy::~WindowProxy ()
}
int
WindowProxy::set_state (const XMLNode& node)
WindowProxy::set_state (const XMLNode& node, int /* version */)
{
XMLNodeList children = node.children ();
@ -171,7 +172,7 @@ WindowProxy::toggle()
}
XMLNode&
WindowProxy::get_state () const
WindowProxy::get_state ()
{
XMLNode* node = new XMLNode (X_("Window"));
char buf[32];

View file

@ -57,11 +57,13 @@ gtkmm2ext_sources = [
'selector.cc',
'slider_controller.cc',
'stateful_button.cc',
'tabbable.cc',
'tearoff.cc',
'textviewer.cc',
'treeutils.cc',
'utils.cc',
'visibility_tracker.cc',
'window_proxy.cc'
'window_title.cc'
]